double primary() { Token t = ts.get(); switch (t.kind) { case '(': { double d = expression(); t = ts.get(); if (t.kind != ')') error("expected ')'"); return d; } case '{': { double d = expression(); t = ts.get(); if (t.kind != '}') error("expected '}'"); return d; } case number: return t.value; case '-': return - primary(); case '+': return primary(); case name: { Token next = ts.get(); if (next.kind == '=') { double d = expression(); sym_table.set(t.name,d); return d; } else { ts.putback(next); return sym_table.get(t.name); } } default: error("primary expected"); } }
double primary() // deal with numbers, square roots, exponents, parentheses, and brackets { Token t = ts.get(); switch (t.kind) { case root: { t = ts.get(); if (t.kind != '(') error("'(' expected"); double d = expression(); if (d < 0) error ("negative argument for sqrt()"); t = ts.get(); if (t.kind != ')') error ("')' expected"); return sqrt(d); } case exponent: { t = ts.get(); if (t.kind != '(') error("'(' expected"); double d = expression(); t = ts.get(); if (t.kind != ',') error("expected two arguments for pow()"); int exp = narrow_cast<int>(expression()); t = ts.get(); if (t.kind != ')') error("')'expected"); return power(d, exp); } case '{': // handle '{' expression '}' { double d = expression(); t = ts.get(); if (t.kind != '}') error("'}' expected"); return d; } case '(': // handle '(' expression ')' { double d = expression(); t = ts.get(); if (t.kind != ')') error("')' expected"); return d; } case number: // we use '8' to represent a number return t.value; // return the number's value case name: return symtable.get(t.name); case '-': return -primary(); case '+': return primary(); default: error("primary expected"); } }
Token Lexer::on_symbol() { Symbol const* sym = symbols.get(str_.take()); return Token(loc_, sym); }