예제 #1
0
        private Expr Term()
        {
            Expr expression = Factor();

            while (Match(TokenType.Minus, TokenType.Plus))
            {
                Token @operator = Previous();
                Expr  right     = Factor();
                expression = new Expr.Binary(expression, @operator, right);
            }

            return(expression);
        }
예제 #2
0
        private Expr Factor()
        {
            Expr expression = Unary();

            while (Match(TokenType.Slash, TokenType.Star, TokenType.Modulus))
            {
                Token @operator = Previous();
                Expr  right     = Unary();
                expression = new Expr.Binary(expression, @operator, right);
            }

            return(expression);
        }
예제 #3
0
        /// <summary>
        /// The grammar rule is virtually identical and so is the code.
        /// The only differences are the token types for the operators we match, and the
        /// method we call for the operands, now term(). The remaining two binary
        /// operator rules follow the same pattern:
        /// </summary>
        /// <returns></returns>
        private Expr Comparison()
        {
            Expr expression = Term();

            while (Match(TokenType.Greater, TokenType.GreaterEqual, TokenType.Less, TokenType.LessEqual))
            {
                Token @operator = Previous();
                Expr  right     = Term();
                expression = new Expr.Binary(expression, @operator, right);
            }

            return(expression);
        }
예제 #4
0
        public Expr Equality()
        {
            Expr expression = Comparison();

            while (Match(TokenType.BangEqual, TokenType.EqualEqual))
            {
                Token @operator = Previous();
                Expr  right     = Comparison();
                expression = new Expr.Binary(expression, @operator, right);
            }

            return(expression);
        }
예제 #5
0
 public object Visit(Expr.Binary _binary)
 {
     Resolve(_binary.lhs);
     Resolve(_binary.rhs);
     return(null);
 }
예제 #6
0
 // Visitors
 string Expr.IVisitor <string> .Visit(Expr.Binary binary)
 {
     return(Parenthesize(binary.opp.lexeme, binary.lhs, binary.rhs));
 }
예제 #7
0
        public object Visit(Expr.Binary binary)
        {
            object right = Evaluate(binary.rhs);
            object left  = Evaluate(binary.lhs);


            switch (binary.opp.type)
            {
            case TokenType.Greater:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left > (double)right);

            case TokenType.GreaterEqual:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left >= (double)right);

            case TokenType.Less:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left < (double)right);

            case TokenType.LessEqual:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left <= (double)right);

            case TokenType.Minus:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left - (double)right);

            case TokenType.Plus:
                if (left is double && right is double)
                {
                    return((double)left + (double)right);
                }
                else if (left is string)
                {
                    return((string)left + Stringify(right));
                }
                // Not valid addition type.
                throw new RuntimeError(binary.opp, "Operands must be two numbers or two strings.");

            case TokenType.Modulus:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left % (double)right);

            case TokenType.Slash:
                ValidateNumberOperand(binary.opp, left, right);
                ValidateDivision(binary.opp, right);
                return((double)left / (double)right);

            case TokenType.Star:
                ValidateNumberOperand(binary.opp, left, right);
                return((double)left * (double)right);

            case TokenType.BangEqual:
                return(!IsEqual(left, right));

            case TokenType.EqualEqual:
                return(IsEqual(left, right));
            }

            // Unreachable.
            return(null);
        }