private static AstNode parseComparison(Parser parser) { AstNode left = parseFunctionCall(parser); while (parser.MatchToken(TokenType.Comparison)) { switch ((string)parser.CurrentToken().Value) { case ">": parser.AcceptToken(TokenType.Comparison); left = new BinaryOpNode(BinaryOperation.GreaterThan, left, parseFunctionCall(parser)); continue; case "<": parser.AcceptToken(TokenType.Comparison); left = new BinaryOpNode(BinaryOperation.LessThan, left, parseFunctionCall(parser)); continue; default: break; } break; } return left; }
private static AstNode parseAdditive(Parser parser) { AstNode left = parseMultiplicitive(parser); while (parser.MatchToken(TokenType.Operation)) { switch ((string)parser.CurrentToken().Value) { case "+": parser.AcceptToken(TokenType.Operation); left = new BinaryOpNode(BinaryOperation.Addition, left, parseMultiplicitive(parser)); continue; case "-": parser.AcceptToken(TokenType.Operation); left = new BinaryOpNode(BinaryOperation.Subtraction, left, parseMultiplicitive(parser)); continue; default: break; } break; } return left; }
private object interpretBinaryOperation(BinaryOpNode node) { switch (node.BinaryOp) { case BinaryOperation.Assignment: if (!(node.Left is IdentifierNode)) throw new Exception("Must be an identifier!"); object right = evaluateNode(node.Right); string left = ((IdentifierNode)node.Left).Identifier.ToUpper(); if (!Variables.ContainsKey(left)) throw new Exception("Variable " + left + " is being used before it is declared!"); Variables.Remove(left); Variables.Add(left, right); return right; case BinaryOperation.Addition: object addLeft = evaluateNode(node.Left); object addRight = evaluateNode(node.Right); if (addLeft is string || addRight is string) return (string)addLeft + (string)addRight; else return Convert.ToDouble(addLeft) + Convert.ToDouble(addRight); case BinaryOperation.Subtraction: return Convert.ToDouble(evaluateNode(node.Left)) - Convert.ToDouble(evaluateNode(node.Right)); case BinaryOperation.Division: return Convert.ToDouble(evaluateNode(node.Left)) / Convert.ToDouble(evaluateNode(node.Right)); case BinaryOperation.Multiplication: return Convert.ToDouble(evaluateNode(node.Left)) * Convert.ToDouble(evaluateNode(node.Right)); case BinaryOperation.Modulus: return Convert.ToDouble(evaluateNode(node.Left)) % Convert.ToDouble(evaluateNode(node.Right)); case BinaryOperation.Equals: return evaluateNode(node.Left).GetHashCode() == evaluateNode(node.Right).GetHashCode(); case BinaryOperation.LessThan: return Convert.ToDouble(evaluateNode(node.Left)) < Convert.ToDouble(evaluateNode(node.Right)); case BinaryOperation.GreaterThan: return Convert.ToDouble(evaluateNode(node.Left)) > Convert.ToDouble(evaluateNode(node.Right)); case BinaryOperation.Not: return !((bool)interpretBinaryOperation(new BinaryOpNode(node.BinaryOp, node.Left, node.Right))); default: throw new NotImplementedException("Unknown binary operation: " + node.Left + " " + node.BinaryOp + " " +node.Right); } }
private static AstNode parseMultiplicitive(Parser parser) { AstNode left = parseComparison(parser); while (parser.MatchToken(TokenType.Operation)) { switch ((string)parser.CurrentToken().Value) { case "*": parser.AcceptToken(TokenType.Operation); left = new BinaryOpNode(BinaryOperation.Multiplication, left, parseComparison(parser)); continue; case "/": parser.AcceptToken(TokenType.Operation); left = new BinaryOpNode(BinaryOperation.Division, left, parseComparison(parser)); continue; case "%": parser.AcceptToken(TokenType.Operation); left = new BinaryOpNode(BinaryOperation.Modulus, left, parseComparison(parser)); continue; case "=": parser.AcceptToken(TokenType.Assignment); left = new BinaryOpNode(BinaryOperation.Assignment, left, parseComparison(parser)); continue; default: break; } break; } return left; }