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; }
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)); } }
public virtual object VisitBinary(BinaryAstNode node) { return null; }
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; }
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 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; }
public virtual object VisitBinary(BinaryAstNode node) { return(null); }