public void VisitNode(AstNode node) { if (node is Statement) VisitStatement(node as Statement); else VisitExpression(node as Expression); }
public void Optimize() { if (Current == null) throw new InvalidOperationException("Statement or expression tree has not yet been parsed."); if (Current is Expression) Current = (Current as Expression).Reduce(); else (Current as Statement).Optimize(); }
public Statement Parse() { // the Game Maker lexer runs before parsing, but we will scan as we are parsing, using l.Scan(), // implemented in move() and peek(). We will, as in Game Maker, parse completely before executing, // to catch all compile errors. I've heard Game Maker compiles to byte code, but we will build // a parse tree of Stmts and Exprs. We return a Stmt node that can be executed by Stmt.Exec(). // Game Maker does all of its parsing during loading, and if there are no errors, caches the // intermediate representation, which is referenced by the events and scripts. Statement s; move(); if (t == TokenKind.OpeningCurlyBrace) { s = block(); if (t != TokenKind.Eof) error(Error.ProgramEnds); return s; } s = Statement.Nop; while (t != TokenKind.Eof) { s = new Sequence(s, stmt(), next.line, next.col); // stmt() throws ProgramError } Current = s; return s; }
/// <summary> /// This will return a constant 0 if the parser parses an empty string. /// </summary> public Expression ParseExpression() { move(); if (t == TokenKind.Eof) return new Constant(0, 0, 0); Expression e = expr(); if (t != TokenKind.Eof) error(Error.UnexpectedSymbol); Current = e; return e; }