Ejemplo n.º 1
0
        /**
         * Function VisitBinaryExpr : it checks :
         *      Right and left operands are the same type
         *      For '+' only INT and STRING are allowed
         *      For '-', '*', '/' only INT are allowed
         * Param : binary expression to check
         * Return : type of the right and left operands or error
         */
        public VALTYPE VisitBinaryExpr(Expr.Binary expr)
        {
            VALTYPE left  = GetType(expr.Left);
            VALTYPE right = GetType(expr.Right);

            /* Case the binary operator is '=' or '<' */
            if (matching.Contains(expr.OperatorToken.Kind))
            {
                /* If left and right are the same type return BOOL */
                if (left.Equals(right))
                {
                    return(VALTYPE.BOOL);
                }
                /* Error not same type */
                else
                {
                    throw new TypeError(expr.OperatorToken, "'" + expr.OperatorToken.Text
                                        + "' arguments should have the same type.");
                }
            }

            /* Case the binary operator is '-', '*' or '/' */
            else if (numbers.Contains(expr.OperatorToken.Kind))
            {
                /* Case left and right are both INT */
                if (left.Equals(right) && left.Equals(VALTYPE.INT))
                {
                    return(VALTYPE.INT);
                }
                /* Error not same type*/
                else
                {
                    throw new TypeError(expr.OperatorToken, "'" + expr.OperatorToken.Text
                                        + "' arguments should both be " + VALTYPE.INT.ToString() + ", got "
                                        + left.ToString() + " and " + right.ToString() + " instead.");
                }
            }

            /* Case the binary operator is '+' */
            else if (expr.OperatorToken.Kind.Equals(TokenKind.Sum))
            {
                /* If left and right are the same type */
                if (left.Equals(right))
                {
                    /* If the type is not bool we return the type they are */
                    if (!left.Equals(VALTYPE.BOOL))
                    {
                        return(left);
                    }
                    /* Error it cannot happen BOOL + BOOL */
                    else
                    {
                        throw new TypeError(expr.OperatorToken, "'" + expr.OperatorToken.Text
                                            + "' arguments should both be " + VALTYPE.INT.ToString()
                                            + ", got twice " + left.ToString() + " instead.");
                    }
                }
                /* Error not same type */
                else
                {
                    throw new TypeError(expr.OperatorToken, "'" + expr.OperatorToken.Text
                                        + "' arguments should both be either " + VALTYPE.INT.ToString()
                                        + " or " + VALTYPE.STRING.ToString() + ", got " + left.ToString()
                                        + " and " + right.ToString() + " instead.");
                }
            }

            throw new TypeError(expr.OperatorToken, "Didn't get the right types."); /* Unreachable */
        }
Ejemplo n.º 2
0
        /*****************************************************************
        *               FUNCTIONS FOR EXPRESSIONS                       *
        *****************************************************************/

        /**
         * Function VisitBinaryExpr : it evaluates both right and left expressions
         * of the binary expression, checking that both operands are the same type
         * and returns the value of them depending on the operator
         * Param : binary expression to evaluate
         * Return : the value of the binary expression
         */
        public Value VisitBinaryExpr(Expr.Binary expr)
        {
            Value left  = Evaluate(expr.Left);
            Value right = Evaluate(expr.Right);

            switch (expr.OperatorToken.Kind)
            {
            /* Case '-' for only numbers */
            case TokenKind.Minus:
                CheckNumberOperand(expr.OperatorToken, left, right);
                return(new Value(VALTYPE.INT, (int)left.Val - (int)right.Val));

            /* Case '*' for only numbers */
            case TokenKind.Mult:
                CheckNumberOperand(expr.OperatorToken, left, right);
                return(new Value(VALTYPE.INT, (int)left.Val * (int)right.Val));

            /* Case '/' for only numbers */
            case TokenKind.Div:
                CheckNumberOperand(expr.OperatorToken, left, right);
                return(new Value(VALTYPE.INT, (int)left.Val / (int)right.Val));

            /* Case '+' for both numbers and strings */
            case TokenKind.Sum:
                if (left.Type.Equals(VALTYPE.INT) && right.Type.Equals(VALTYPE.INT))
                {
                    return(new Value(VALTYPE.INT, (int)left.Val + (int)right.Val));
                }
                else if (left.Type.Equals(VALTYPE.STRING) && right.Type.Equals(VALTYPE.STRING))
                {
                    return(new Value(VALTYPE.STRING, (string)left.Val + (string)right.Val));
                }
                break;

            /* Case '=' for both numbers, strings or bools */
            case TokenKind.Equal:
                if (left.Type.Equals(VALTYPE.INT) && right.Type.Equals(VALTYPE.INT))
                {
                    return(new Value(VALTYPE.BOOL, ((int)left.Val == (int)right.Val)));
                }
                else if (left.Type.Equals(VALTYPE.STRING) && right.Type.Equals(VALTYPE.STRING))
                {
                    return(new Value(VALTYPE.BOOL, ((string)left.Val == (string)right.Val)));
                }
                else if (left.Type.Equals(VALTYPE.BOOL) && right.Type.Equals(VALTYPE.BOOL))
                {
                    return(new Value(VALTYPE.BOOL, ((bool)left.Val == (bool)right.Val)));
                }
                break;

            /* Case '<' for both numbers, strings or bools */
            case TokenKind.Less:
                if (left.Type.Equals(VALTYPE.INT) && right.Type.Equals(VALTYPE.INT))
                {
                    return(new Value(VALTYPE.BOOL, ((int)left.Val < (int)right.Val)));
                }
                else if (left.Type.Equals(VALTYPE.STRING) && right.Type.Equals(VALTYPE.STRING))
                {
                    return(new Value(VALTYPE.BOOL, (string.Compare((string)left.Val, (string)right.Val) == -1)));
                }
                else if (left.Type.Equals(VALTYPE.BOOL) && right.Type.Equals(VALTYPE.BOOL))
                {
                    return(new Value(VALTYPE.BOOL, (((bool)left.Val).CompareTo((bool)right.Val) < 0)));
                }
                break;
            }
            /* Error if the operands are different type */
            throw new RuntimeError(expr.OperatorToken, "Operands must be the same type.");
        }
Ejemplo n.º 3
0
 /**
  * Function VisitBinaryExpression
  * Param : binary expression to visit
  * Return : the parse tree of the left and right with the operator
  */
 public String VisitBinaryExpr(Expr.Binary expr)
 {
     return(Print(expr.Left) + " " + expr.OperatorToken.Text + " " + Print(expr.Right));
 }