Beispiel #1
0
        override public void Visit(AST_binary_operator binary_operator)
        {
            binary_operator.LeftOperand.Accept(this);
            Variable left = this.Value.Copy();

            binary_operator.RightOperand.Accept(this);
            Variable right = this.Value.Copy();

            switch (left.Type)
            {
            case AST_type.AST_type_kind.bool_type:
                EvaluateBooleanBinaryOperator(binary_operator, left, right);
                break;

            case AST_type.AST_type_kind.int_type:
                EvaluateIntegerBinaryOperator(binary_operator, left, right);
                break;

            case AST_type.AST_type_kind.string_type:
                EvaluateStringBinaryOperator(binary_operator, left, right);
                break;

            default:
                break;
            }
        }
Beispiel #2
0
        private void EvaluateIntegerBinaryOperator(AST_binary_operator binary_operator, Variable left, Variable right)
        {
            switch (binary_operator.Kind)
            {
            case AST_binary_operator.OperatorKind.Equal:
                this.value.Set(left.IntValue == right.IntValue);
                break;

            case AST_binary_operator.OperatorKind.Less:
                this.value.Set(left.IntValue < right.IntValue);
                break;

            case AST_binary_operator.OperatorKind.Plus:
                this.value.Set(left.IntValue + right.IntValue);
                break;

            case AST_binary_operator.OperatorKind.Minus:
                this.value.Set(left.IntValue - right.IntValue);
                break;

            case AST_binary_operator.OperatorKind.Asterisk:
                this.value.Set(left.IntValue * right.IntValue);
                break;

            case AST_binary_operator.OperatorKind.Slash:
                this.value.Set(left.IntValue / right.IntValue);
                break;

            default:
                break;
            }
        }
Beispiel #3
0
 public virtual void Visit(AST_binary_operator binary_operator)
 {
     IncrementDepth();
     binary_operator.LeftOperand.Accept(this);
     binary_operator.RightOperand.Accept(this);
     DecrementDepth();
 }
Beispiel #4
0
        private AST_binary_operator Parse_binary_operator(TokenKind followSet)
        {
            IncrementDepth();

            AST_binary_operator binary_operator;

            Token t = GetNextToken();

            DebugPrint("op " + t.Lexeme);
            AST_binary_operator.OperatorKind kind;
            switch (t.Kind)
            {
            case Plus:
                kind = AST_binary_operator.OperatorKind.Plus;
                break;

            case Minus:
                kind = AST_binary_operator.OperatorKind.Minus;
                break;

            case Asterisk:
                kind = AST_binary_operator.OperatorKind.Asterisk;
                break;

            case Slash:
                kind = AST_binary_operator.OperatorKind.Slash;
                break;

            case Less:
                kind = AST_binary_operator.OperatorKind.Less;
                break;

            case Equal:
                kind = AST_binary_operator.OperatorKind.Equal;
                break;

            case Ampersand:
                kind = AST_binary_operator.OperatorKind.Ampersand;
                break;

            default:
                Error("Binary operator expected.", t);
                kind = AST_binary_operator.OperatorKind.Plus;
                SkipUntilFollow(followSet);
                break;
            }

            binary_operator        = new AST_binary_operator(kind);
            binary_operator.Row    = t.Row;
            binary_operator.Column = t.Column;

            DecrementDepth();

            return(binary_operator);
        }
Beispiel #5
0
        private void EvaluateBooleanBinaryOperator(AST_binary_operator binary_operator, Variable left, Variable right)
        {
            switch (binary_operator.Kind)
            {
            case AST_binary_operator.OperatorKind.Ampersand:
                this.value.Set(left.BoolValue & right.BoolValue);
                break;

            case AST_binary_operator.OperatorKind.Equal:
                this.value.Set(left.BoolValue == right.BoolValue);
                break;

            default:
                break;
            }
        }
Beispiel #6
0
        private AST_expression Parse_expression(TokenKind followSet)
        {
            IncrementDepth();
            DebugPrint("expr");

            AST_expression expression;

            Token t = LookAheadToken();

            switch (t.Kind)
            {
            case Exclamation:
                expression = Parse_unary_operator_operand(followSet);
                break;

            default:
                if (isMemberOf(t.Kind, FirstSet_operand))
                {
                    AST_operand left_operand = Parse_operand(followSet | BinaryOperators);
                    if (IsBinaryOperator(LookAheadToken().Kind))
                    {
                        AST_binary_operator binary_operator = Parse_binary_operator(followSet);
                        AST_operand         right_operand   = Parse_operand(followSet);
                        binary_operator.SetLeft(left_operand);
                        binary_operator.SetRight(right_operand);
                        expression = binary_operator;
                    }
                    else
                    {
                        expression = left_operand;
                    }
                }
                else
                {
                    Error("Expression expected. '" + t.ToString() + "' does not start an expression.", t);
                    expression = new ASTDummy_operand();
                    SkipUntilFollow(followSet);
                }

                break;
            }

            DecrementDepth();

            return(expression);
        }
Beispiel #7
0
        private void EvaluateStringBinaryOperator(AST_binary_operator binary_operator, Variable left, Variable right)
        {
            switch (binary_operator.Kind)
            {
            case AST_binary_operator.OperatorKind.Equal:
                this.value.Set(left.StringValue.Equals(right.StringValue));
                break;

            case AST_binary_operator.OperatorKind.Less:
                this.value.Set(left.StringValue.CompareTo(right.StringValue) < 0);
                break;

            case AST_binary_operator.OperatorKind.Plus:
                this.value.Set(string.Concat(left.StringValue, right.StringValue));
                break;

            default:
                break;
            }
        }
Beispiel #8
0
        override public void Visit(AST_binary_operator binary_operator)
        {
            base.Visit(binary_operator);
            if (binary_operator.LeftOperand.DataType != binary_operator.RightOperand.DataType)
            {
                Error("Left and right operands of binary operator must be of same type.", binary_operator);
            }
            else
            {
                AST_type.AST_type_kind t = binary_operator.LeftOperand.DataType;
                switch (binary_operator.Kind)
                {
                case Ampersand:
                    if (t != bool_type)
                    {
                        Error("Binary operator '&' requires bool operands.", binary_operator);
                    }
                    break;

                case Asterisk:
                    if (t != int_type)
                    {
                        Error("Binary operator '*' requires int operands.", binary_operator);
                    }
                    break;

                case Equal:
                    // All types accepted
                    break;

                case Less:
                    // All types accepted
                    break;

                case Minus:
                    if (t != int_type)
                    {
                        Error("Binary operator '-' requires int operands.", binary_operator);
                    }
                    break;

                case Plus:
                    if (t == bool_type)
                    {
                        Error("Binary operator '+' requires int or string operands.", binary_operator);
                    }
                    break;

                case Slash:
                    if (t != int_type)
                    {
                        Error("Binary operator '/' requires int operands.", binary_operator);
                    }
                    break;

                default:
                    break;
                }
            }

            switch (binary_operator.Kind)
            {
            case Equal:
            case Less:
            case Ampersand:
                binary_operator.DataType = bool_type;
                break;

            default:
                binary_operator.DataType = binary_operator.LeftOperand.DataType;
                break;
            }
        }