public override object VisitBinary(BinaryAstNode node) { var left = Evaluate(node.Left); if (left.IsError) { return(left); } var right = Evaluate(node.Right); if (right.IsError) { return(right); } switch (node.Token.Kind) { case TokenKind.Plus: return(EvaluateArithmetic(left, right, (a, b) => Result(a.Int32Value + b.Int32Value))); case TokenKind.Minus: return(EvaluateArithmetic(left, right, (a, b) => Result(a.Int32Value - b.Int32Value))); case TokenKind.Mul: return(EvaluateArithmetic(left, right, (a, b) => Result(a.Int32Value * b.Int32Value))); case TokenKind.Div: return(EvaluateArithmetic(left, right, (a, b) => b.Int32Value == 0 ? Error("Attempted to divide by zero.") : Result(a.Int32Value / b.Int32Value))); case TokenKind.And: case TokenKind.AndSign: return(EvaluateLogicalAnd(left, right)); case TokenKind.Or: case TokenKind.OrSign: return(EvaluateLogicalOr(left, right)); case TokenKind.EqualEqual: return(EvaluateEquality(left, right, v => v)); case TokenKind.NotEqual: return(EvaluateEquality(left, right, v => !v)); case TokenKind.LessThan: return(EvaluateComparison(left, right, v => v < 0)); case TokenKind.LessThanEqual: return(EvaluateComparison(left, right, v => v <= 0)); case TokenKind.GreaterThan: return(EvaluateComparison(left, right, v => v > 0)); case TokenKind.GreaterThanEqual: return(EvaluateComparison(left, right, v => v >= 0)); default: throw new InvalidOperationException(string.Format("Internal error: binary operator '{0}' is not supported.", node.Token.Kind)); } }
private AstNode ParseEqualityExpression() { var expr = ParseComparisonExpression(); var token = IsMatch(TokenKind.EqualEqual, TokenKind.NotEqual); if (token != null) { var right = ParseEqualityExpression(); expr = new BinaryAstNode(expr, token, right); } return(expr); }
private AstNode ParseLogicalAndExpression() { var expr = ParseEqualityExpression(); again: var token = IsMatch(TokenKind.AndSign); if (token != null) { var right = ParseEqualityExpression(); expr = new BinaryAstNode(expr, token, right); goto again; } return(expr); }
private AstNode ParseKeywordLogicalExpression() { var expr = ParseKeywordNotExpression(); again: var token = IsMatch(TokenKind.Or, TokenKind.And); if (token != null) { var right = ParseKeywordNotExpression(); expr = new BinaryAstNode(expr, token, right); goto again; } return(expr); }
private AstNode ParseMultiplicativeExpression() { var expr = ParseUnaryExpression(); again: var token = IsMatch(TokenKind.Mul, TokenKind.Div); if (token != null) { var right = ParseUnaryExpression(); expr = new BinaryAstNode(expr, token, right); goto again; } return(expr); }
private AstNode ParseComparisonExpression() { var expr = ParseAdditiveExpression(); var token = IsMatch(TokenKind.LessThan, TokenKind.LessThanEqual) ?? IsMatch(TokenKind.GreaterThan, TokenKind.GreaterThanEqual); if (token != null) { var right = ParseComparisonExpression(); expr = new BinaryAstNode(expr, token, right); } return(expr); }
public virtual object Visit(BinaryAstNode node) { return(null); }