/* A little integer expression evaluator in paraFlow. * I must have compilers on my mind if this is the * only test case I can think of! */ include 'stringTo' include 'myTok' dir of int symbols = ("nil" @ 0); string usage = " myExp - evaluate expression in a file. usage: myExp expressionFile The expression can contain integers, +, -, *, /, and parenthesis. "; if (args.size != 1) punt(usage); tokenizer tkz = tokenizerNew(args[0]); while (evalStatement(tkz)) ; to evalStatement(tokenizer tkz) into bit ok { string s = tkz.get(); ok = s; if (!ok) return; if (s == "print") print(evalExp(tkz)); else if (isalpha(s[0])) { string eq = tkz.get(); if (eq != "=") tkz.errAt("Expecting =, got " + eq); symbols[s] = evalExp(tkz); } else tkz.errAt("Not a statement"); } to evalExp(tokenizer tkz) into int val { val = evalTerms(tkz); } to evalTerms(tokenizer tkz) into int val { val = evalFactors(tkz); for (;;) { string s = tkz.get(); if (s == "+") val += evalFactors(tkz); else if (s == "-") val -= evalFactors(tkz); else { tkz.unget(s); break; } } } to evalFactors(tokenizer tkz) into int val { val = evalUnary(tkz); for (;;) { string s = tkz.get(); if (s == "*") val *= evalUnary(tkz); else if (s == "/") val /= evalUnary(tkz); else { tkz.unget(s); break; } } } to evalUnary(tokenizer tkz) into int val { string s = tkz.get(); if (s == "-") val = -evalUnary(tkz); else { tkz.unget(s); val = evalAtom(tkz); } } to evalAtom(tokenizer tkz) into int val { string s = tkz.get(); if (s == "(") { val = evalExp(tkz); s = tkz.get(); if (s != ")") tkz.errAt("Expecting ')' got " + s); } else if (isnum(s[0])) val = stringToInt(s); else if (isalpha(s[0])) val = symbols[s]; else tkz.errAt("I don't understand " + s); }