private AstNode Factor() { // FACTOR = UNARY-OP FACTOR | // INCREMENT-BY-ONE VARIABLE | // DECREMENT-BY-ONE VARIABLE | // NUMBER (INCREMENT-BY-ONE) | // NUMBER (DECREMENT-BY-ONE) | // STRING | CHAR | BOOLEAN | // PARAM-START EXPRESSION PARAM-END | // VARIABLE var token = _currentToken; if (Tokens.IsUnaryOperator(token.Type)) { Eat(token.Type); return(new UnaryOperationNode(token, Factor())); } else if (token.Type == Tokens.IncrementByOne) { Eat(token.Type); return(new PreIncrementNode(Variable())); } else if (token.Type == Tokens.DecrementByOne) { Eat(token.Type); return(new PreDecrementNode(Variable())); } else if (Tokens.IsNumberType(token.Type)) { return(Number()); } else if (token.Type == Tokens.String) { Eat(token.Type); return(new StringNode((string)token.Value)); } else if (token.Type == Tokens.Character) { Eat(token.Type); return(new CharacterNode((char)token.Value)); } else if (token.Type == Tokens.True) { Eat(token.Type); return(new BooleanNode(true)); } else if (token.Type == Tokens.False) { Eat(token.Type); return(new BooleanNode(false)); } else if (token.Type == Tokens.ParamStart) { Eat(Tokens.ParamStart); var expression = Expression(); Eat(Tokens.ParamEnd); return(expression); } else { var variable = Variable(); if (token.Type == Tokens.IncrementByOne) { Eat(token.Type); return(new PostIncrementNode(variable)); } else if (token.Type == Tokens.DecrementByOne) { Eat(token.Type); return(new PostDecrementNode(variable)); } return(variable); } throw new Exception("Factor bad. Very bad. No like it. Stop."); }
private AstNode Statement() { // STATEMENT = BLOCK | // var VARIABLE-DECL | // implicit variable declaration // IDENITIFER VARIABLE-DECL | // explicit variable declaration with user-defined type // TYPE-SPEC VARAIBLE-DECL | // explicit variable declaration with primitive type // IDENTIFIER ASSIGNMENT | // IDENTIFIER INCREMENT-BY EXPRESSION | // IDENTIFIER DECREMENT-BY EXPRESSION | // IDENTIFIER MULTIPLY-BY EXPRESSION | // IDENTIFIER DIVIDE-BY EXPRESSION | // RETURN EXPRESSION | // BRANCH | // NO-OP if (_currentToken.Type == Tokens.BlockStart) { return(Block()); } else if (_currentToken.Type == Tokens.Variable) { Eat(_currentToken.Type); return(VariableDeclaration(TypeNode.Inferred)); } else if (_currentToken.Type == Tokens.Identifier) { var id = _currentToken.Value.ToString(); Eat(Tokens.Identifier); if (_currentToken.Type == Tokens.Assign) { return(Assignment(new VariableNode(id))); } else if (_currentToken.Type == Tokens.Identifier) { return(VariableDeclaration(new TypeNode(id))); } else if (_currentToken.Type == Tokens.IncrementBy) { Eat(Tokens.IncrementBy); return(new IncrementByNode(new VariableNode(id), Expression())); } else if (_currentToken.Type == Tokens.DecrementBy) { Eat(Tokens.DecrementBy); return(new DecrementByNode(new VariableNode(id), Expression())); } else if (_currentToken.Type == Tokens.MultiplyBy) { Eat(Tokens.MultiplyBy); return(new MultiplyByNode(new VariableNode(id), Expression())); } else if (_currentToken.Type == Tokens.DivideBy) { Eat(Tokens.DivideBy); return(new DivideByNode(new VariableNode(id), Expression())); } } else if (Tokens.IsPrimitiveType(_currentToken.Type)) { return(VariableDeclaration(TypeSpec())); } else if (_currentToken.Type == Tokens.Return) { Eat(Tokens.Return); return(new ReturnNode(Expression())); } else if (_currentToken.Type == Tokens.Branch) { Eat(Tokens.Branch); return(Branch()); } else { return(new NoOpNode()); } throw new Exception("bad statement"); }