private Val atom() { Token t = lex.nextToken(); if (t.type == Token.Type.number) { return new Num((Double) t.value); } else if (t.type == Token.Type.string) { return new Str("" + t.value); } else if (t.type == Token.Type.id) { Val res = env.val(t.value.toString()); if (res.getType() == Val.Type.nil) { res = new Id("" + t.value); Val expr = expr(); env.set(t.value.toString(), expr); } return res; } else if (t.matchOperator("(")) { Val v = expr(); t = lex.nextToken(); if (!t.matchOperator(")")) { throw new EvalException("lexical error: ) was expected"); } return v; } else { lex.returnToken(); return Nil.NIL; } }
private Val moreFactors(Val val) { Token t = lex.nextToken(); if (t.matchOperator("*")) { return new Num(val.evalNum(env) * levelFactor().evalNum(env)); } else if (t.matchOperator("/")) { return new Num(val.evalNum(env) / levelFactor().evalNum(env)); } else if (t.matchOperator("%")) { return new Num(val.evalNum(env) % levelFactor().evalNum(env)); } else { lex.returnToken(); return val; } }
private Val moreTerms(Val val) { Token t = lex.nextToken(); if (t.matchOperator("+")) { Val rVal = levelFactor(); Val eval; if (val.getType() == Val.Type.string) { eval = new Str(val.evalStr(env) + rVal.evalStr(env)); } else { eval = new Num(val.evalNum(env) + rVal.evalNum(env)); } return moreTerms(eval); } else if (t.matchOperator("-")) { Val rVal = levelFactor(); Val eval = new Num(val.evalNum(env) - rVal.evalNum(env)); return moreTerms(eval); } else { lex.returnToken(); return val; } }
private Val moreCond(Val val) { Token t = lex.nextToken(); if (t.matchOperator("?")) { Val trueNode = expr(); Token delim = lex.nextToken(); if (delim.matchOperator("!")) { Val falseNode = expr(); if (val.evalNum(env) > 0) { return trueNode; } else { return falseNode; } } else { throw new EvalException("Unrecognized ternary operation " + lex.getLastLine()); } } else { lex.returnToken(); return val; } }
private Val moreComp(Val val) { Token t = lex.nextToken(); if (t.matchOperator("<")) { Val rVal = moreComp(levelTerm()); return val.evalNum(env) < rVal.evalNum(env) ? new Num(1d) : new Num(0d); } else if (t.matchOperator(">")) { Val rVal = moreComp(levelTerm()); return val.evalNum(env) > rVal.evalNum(env) ? new Num(1d) : new Num(0d); } else if (t.matchOperator(">=")) { Val rVal = moreComp(levelTerm()); return val.evalNum(env) >= rVal.evalNum(env) ? new Num(1d) : new Num(0d); } else if (t.matchOperator("<=")) { Val rVal = moreComp(levelTerm()); return val.evalNum(env) <= rVal.evalNum(env) ? new Num(1d) : new Num(0d); } else if (t.matchOperator("=")) { Val rVal = moreComp(levelTerm()); return val.evalNum(env).equals(rVal.evalNum(env)) ? new Num(1d) : new Num(0d); } else if (t.matchOperator("<>")) { Val rVal = moreComp(levelTerm()); return !val.evalNum(env).equals(rVal.evalNum(env)) ? new Num(1d) : new Num(0d); } else { lex.returnToken(); return val; } }