public dynamic Factor() { /* Factor: INTEGER | LPAREN expr RPAREN | Variable | STRING | TRUE | FALSE * */ if (currentToken.GetTokenValueType() == TokenValues.LPAREN) { Eat(TokenValues.LPAREN); BinOp result = Expr(); Eat(TokenValues.RPAREN); return(result); } else if (this.currentToken.GetTokenValueType() == TokenValues.INTEGER) { Token token = this.currentToken; Eat(TokenValues.INTEGER); return(new Num(token)); } else if (this.currentToken.GetTokenValueType() == TokenValues.STRING) { Token token = this.currentToken; Eat(TokenValues.STRING); return(new Str(token)); } else if (this.currentToken.GetTokenValueType() == TokenValues.TRUE) { Token token = this.currentToken; Eat(TokenValues.TRUE); return(new BoolNode(token)); } else if (this.currentToken.GetTokenValueType() == TokenValues.FALSE) { Token token = this.currentToken; Eat(TokenValues.FALSE); return(new BoolNode(token)); } else { return(Variable()); } }
public dynamic Expr() { VisitableNode result = Term(); HashSet <TokenValues> values = new HashSet <TokenValues>(); values.Add(TokenValues.PLUS); values.Add(TokenValues.MINUS); values.Add(TokenValues.EQUAL); values.Add(TokenValues.LESSTHAN); /* * expr : Term ((PLUS|MINUS|EQUAL|LESSTHAN) Term) * * Term : Factor ((MUL|DIV) Factor) * * Factor : INTEGER | LPAREN expr RPAREN | Variable | STRING | TRUE | FALSE */ while (values.Contains(this.currentToken.GetTokenValueType())) { TokenValues type = this.currentToken.GetTokenValueType(); Token curr = this.currentToken; switch (type) { case TokenValues.MINUS: Eat(TokenValues.MINUS); break; case TokenValues.PLUS: Eat(TokenValues.PLUS); break; case TokenValues.EQUAL: Eat(TokenValues.EQUAL); break; case TokenValues.LESSTHAN: Eat(TokenValues.LESSTHAN); break; default: throw new InterpreterException("syntax error"); } result = new BinOp(result, curr, this.Term()); } return(result); }
public dynamic Term() { //Term: Factor ((MUL|DIV) factor)* var result = Factor(); while (this.currentToken.GetTokenValueType() == TokenValues.DIVISION || this.currentToken.GetTokenValueType() == TokenValues.MULTIPLY) { Token token = this.currentToken; if (currentToken.GetTokenValueType() == TokenValues.MULTIPLY) { Eat(TokenValues.MULTIPLY); } else { Eat(TokenValues.DIVISION); } result = new BinOp(result, token, this.Factor()); } return(result); }
// A hot mess but gets the return value based on types given left and right public dynamic visit(BinOp binOp) { int left = 0; int right = 0; Type leftType = binOp.getLeft().GetType(); Type rightType = binOp.getRight().GetType(); if (leftType == typeof(Num)) { left = this.visit((Num)binOp.getLeft()); } else if (leftType == typeof(BinOp)) { left = this.visit((BinOp)binOp.getLeft()); } else if (leftType == typeof(Var)) { left = this.visit((Var)binOp.getLeft()); } if (rightType == typeof(Num)) { right = this.visit((Num)binOp.getRight()); } else if (rightType == typeof(BinOp)) { right = this.visit((BinOp)binOp.getRight()); } else if (rightType == typeof(Var)) { right = this.visit((Var)binOp.getRight()); } if (leftType == typeof(Str)) { if (rightType == typeof(Str)) { if (binOp.getOp().GetTokenValueType() == TokenValues.PLUS) { return(this.visit((Str)binOp.getLeft()) + this.visit((Str)binOp.getRight())); } } else { throw new InterpreterException(String.Format("Incompatible types for operation {0}: {1} {2}", binOp.getOp().GetTokenValueType(), leftType, rightType)); } } switch (binOp.getOp().GetTokenValueType()) { case TokenValues.PLUS: return(left + right); case TokenValues.MINUS: return(left - right); case TokenValues.MULTIPLY: return(left * right); case TokenValues.DIVISION: return(left / right); case TokenValues.EQUAL: return(left == right); case TokenValues.LESSTHAN: return(left < right); default: throw(new InterpreterException("Invalid syntax")); } }