예제 #1
0
        private Expr Multiplication()
        {
            Expr expr = Unary();

            while (Match(TokenType.SLASH, TokenType.STAR))
            {
                Token oper  = Previous();
                Expr  right = Unary();
                expr = new Expr.Binary(expr, oper, right);
            }

            return(expr);
        }
예제 #2
0
        private Expr Addition()
        {
            Expr expr = Multiplication();

            while (Match(TokenType.MINUS, TokenType.PLUS))
            {
                Token oper  = Previous();
                Expr  right = Multiplication();
                expr = new Expr.Binary(expr, oper, right);
            }

            return(expr);
        }
예제 #3
0
        private Expr Comparison()
        {
            Expr expr = Addition();

            while (Match(TokenType.GREATER, TokenType.GREATER_EQUAL, TokenType.LESS, TokenType.LESS_EQUAL))
            {
                Token oper  = Previous();
                Expr  right = Addition();
                expr = new Expr.Binary(expr, oper, right);
            }

            return(expr);
        }
예제 #4
0
        private Expr Equality()
        {
            Expr expr = Comparison();

            while (Match(TokenType.BANG_EQUAL, TokenType.EQUAL_EQUAL))
            {
                Token oper  = Previous();
                Expr  right = Comparison();
                expr = new Expr.Binary(expr, oper, right);
            }

            return(expr);
        }
예제 #5
0
 public Void VisitBinaryExpr(Expr.Binary expr)
 {
     Resolve(expr.left);
     Resolve(expr.right);
     return(null);
 }
예제 #6
0
        public object VisitBinaryExpr(Expr.Binary expr)
        {
            object left  = Evaluate(expr.left);
            object right = Evaluate(expr.right);

            switch (expr.oper.Type)
            {
            case TokenType.PLUS:
                if (left is int && right is int)
                {
                    return((int)left + (int)right);
                }

                if (left is float && right is float)
                {
                    return((float)left + (float)right);
                }

                if (left is string && right is string)
                {
                    return((string)left + (string)right);
                }

                throw new RuntimeError(expr.oper, "Operands must be two numbers or two strings.");

            case TokenType.GREATER:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left > (float)right);

            case TokenType.GREATER_EQUAL:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left >= (float)right);

            case TokenType.LESS:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left < (float)right);

            case TokenType.LESS_EQUAL:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left <= (float)right);

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

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

            case TokenType.MINUS:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left - (float)right);

            case TokenType.STAR:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left * (float)right);

            case TokenType.SLASH:
                CheckNumberOperands(expr.oper, left, right);
                return((float)left / (float)right);
            }

            // Unreachable.
            return(null);
        }