Example #1
0
        // Parse multiply/divide operations
        private INode ParseMultiplyDivide()
        {
            // Parse the left hand side
            var lhs = ParseUnary();

            while (_tokensSequence.Current.Type == TokenType.Multiply || _tokensSequence.Current.Type == TokenType.Divide)
            {
                Func <double, double, double> op;
                if (_tokensSequence.Current.Type == TokenType.Multiply)
                {
                    op = (a, b) => a * b;
                }
                else
                {
                    op = (a, b) => a / b;
                }

                // Skip the operator
                _tokensSequence.MoveNext();

                // Parse the right hand side of the expression
                var rhs = ParseUnary();

                lhs = new BinaryOperationNode(lhs, rhs, op);
            }

            return(lhs);
        }
Example #2
0
        void BinaryOperationVisit(BinaryOperationNode node)
        {
            VariableManager.PushVariableCounter();

            int t1 = VariableManager.IncrementVariableCounter();

            VariableManager.PushVariableCounter();
            node.LeftOperand.Accept(this);
            VariableManager.PopVariableCounter();

            int t2 = VariableManager.IncrementVariableCounter();

            VariableManager.PushVariableCounter();
            node.RightOperand.Accept(this);
            VariableManager.PopVariableCounter();

            VariableManager.PopVariableCounter();

            if (node.LeftOperand.StaticType.Text == "String" && node.Symbol == "=")
            {
                IC.Add(new BinaryOperation(VariableManager.PeekVariableCounter(), t1, t2, "=:="));
                return;
            }

            IC.Add(new BinaryOperation(VariableManager.PeekVariableCounter(), t1, t2, node.Symbol));
        }
Example #3
0
        public void Accept(BinaryOperationNode node)
        {
            switch (node.BinaryOperation)
            {
            case BinaryOperation.Assignment:
                node.Right.Visit(this);
                // var = val
                if (node.Left is IdentifierNode)
                {
                    string identifier = ((IdentifierNode)node.Left).Identifier;

                    // Locals are lowercase
                    HassiumWarning.EnforceCasing(module, node.Left.SourceLocation, identifier, HassiumCasingType.Lower);

                    if (table.Scopes.Count == 2)
                    {
                        table.AddGlobalSymbol(identifier);
                    }

                    if (table.ContainsGlobalSymbol(identifier))
                    {
                        emit(node.SourceLocation, InstructionType.StoreGlobal, identifier);
                        emit(node.SourceLocation, InstructionType.LoadGlobal, identifier);
                    }
                    else
                    {
                        table.HandleSymbol(identifier);
                        emit(node.SourceLocation, InstructionType.StoreLocal, table.GetSymbol(identifier));
                        emit(node.SourceLocation, InstructionType.LoadLocal, table.GetSymbol(identifier));
                    }
                }
                // var.attrib = val
                else if (node.Left is AttributeAccessNode)
                {
                    AttributeAccessNode accessor = node.Left as AttributeAccessNode;
                    accessor.Left.Visit(this);
                    emit(node.SourceLocation, InstructionType.StoreAttribute, accessor.Right);
                    accessor.Left.Visit(this);
                }
                // var [index] = val
                else if (node.Left is IterableAccessNode)
                {
                    IterableAccessNode access = node.Left as IterableAccessNode;
                    access.Index.Visit(this);
                    access.Target.Visit(this);
                    emit(node.SourceLocation, InstructionType.StoreIterableElement);
                }
                break;

            case BinaryOperation.Swap:
                emit(node.SourceLocation, InstructionType.Push, table.GetSymbol(((IdentifierNode)node.Left).Identifier));
                emit(node.SourceLocation, InstructionType.Swap, table.GetSymbol(((IdentifierNode)node.Right).Identifier));
                break;

            default:
                node.VisitChildren(this);
                emit(node.SourceLocation, InstructionType.BinaryOperation, (int)node.BinaryOperation);
                break;
            }
        }
Example #4
0
        private string GetExpression(BinaryOperationNode binOp, IDictionary <IFixing, string> fixingRefs)
        {
            var leftExpression  = GetExpressionBase(binOp.Left, fixingRefs);
            var rightExpression = GetExpressionBase(binOp.Right, fixingRefs);

            return("(" + leftExpression + ")" + binOp.OpSymbol + "(" + rightExpression + ")");
        }
        private AstNode LogicalExpression()
        {
            var node  = Comparison();
            var token = Scanner.State.CurrentToken;

            while (_logicalExpressionOperators.Contains(token.Type))
            {
                token = Scanner.State.CurrentToken;

                if (token.Type == TokenType.Or)
                {
                    var line = Match(TokenType.Or);
                    node = new BinaryOperationNode(node, BinaryOperationType.Or, Comparison())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.And)
                {
                    var line = Match(TokenType.And);
                    node = new BinaryOperationNode(node, BinaryOperationType.And, Comparison())
                    {
                        Line = line
                    };
                }
            }

            return(node);
        }
Example #6
0
        private AstNode Term()
        {
            var node  = Factor();
            var token = Scanner.State.CurrentToken;

            while (_termOperators.Contains(token.Type))
            {
                token = Scanner.State.CurrentToken;

                if (token.Type == TokenType.Multiply)
                {
                    var line = Match(TokenType.Multiply);
                    node = new BinaryOperationNode(node, BinaryOperationType.Multiply, Factor())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.Divide)
                {
                    var line = Match(TokenType.Divide);
                    node = new BinaryOperationNode(node, BinaryOperationType.Divide, Factor())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.BitwiseAnd)
                {
                    var line = Match(TokenType.BitwiseAnd);
                    node = new BinaryOperationNode(node, BinaryOperationType.BitwiseAnd, Factor())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.BitwiseOr)
                {
                    var line = Match(TokenType.BitwiseOr);
                    node = new BinaryOperationNode(node, BinaryOperationType.BitwiseOr, Factor())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.BitwiseXor)
                {
                    var line = Match(TokenType.BitwiseXor);
                    node = new BinaryOperationNode(node, BinaryOperationType.BitwiseXor, Factor())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.Modulo)
                {
                    var line = Match(TokenType.Modulo);
                    node = new BinaryOperationNode(node, BinaryOperationType.Modulo, Factor())
                    {
                        Line = line
                    };
                }
            }
            return(node);
        }
Example #7
0
        /// <summary>
        /// Resolves Multiplication and division in PEMDAS order, let <see cref="ParseUnary"/> resolve negatives and such expresions
        /// </summary>
        /// <returns></returns>
        private static Node ParseMultiplyDivide()
        {
            Node lhs = ParseUnary();

            while (true)
            {
                Func <int, int, int> op = null;
                switch (_tokenizer.CurrentToken)
                {
                case Token.Mul:
                {
                    op = (a, b) => a * b;
                    break;
                }

                case Token.Div:
                {
                    op = (a, b) => a / b;
                    break;
                }
                }
                if (op == null)
                {
                    return(lhs);
                }
                _tokenizer.NextToken();

                Node rhs = ParseUnary();
                lhs = new BinaryOperationNode(lhs, rhs, op);
            }
        }
Example #8
0
        private AstNode Expression()
        {
            var node  = Term();
            var token = Scanner.State.CurrentToken;

            while (_expressionOperators.Contains(token.Type))
            {
                token = Scanner.State.CurrentToken;

                if (token.Type == TokenType.Plus)
                {
                    var line = Match(TokenType.Plus);
                    node = new BinaryOperationNode(node, BinaryOperationType.Plus, Term())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.Minus)
                {
                    var line = Match(TokenType.Minus);
                    node = new BinaryOperationNode(node, BinaryOperationType.Minus, Term())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.ShiftLeft)
                {
                    var line = Match(TokenType.ShiftLeft);
                    node = new BinaryOperationNode(node, BinaryOperationType.ShiftLeft, Term())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.ShiftRight)
                {
                    var line = Match(TokenType.ShiftRight);
                    node = new BinaryOperationNode(node, BinaryOperationType.ShiftRight, Term())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.Or)
                {
                    var line = Match(TokenType.Or);
                    node = new BinaryOperationNode(node, BinaryOperationType.Or, Term())
                    {
                        Line = line
                    };
                }
                else if (token.Type == TokenType.And)
                {
                    var line = Match(TokenType.And);
                    node = new BinaryOperationNode(node, BinaryOperationType.And, Term())
                    {
                        Line = line
                    };
                }
            }
            return(node);
        }
Example #9
0
        private object Visit(BinaryOperationNode node)
        {
            bool isLeftInteger  = node.LeftChild.Data.Type == TokenType.Integer;
            bool isRightInteger = node.RightChild.Data.Type == TokenType.Integer;

            switch (node.Data.Type)
            {
            case TokenType.Add:
                return((isLeftInteger ? (int)Visit(node.LeftChild) : (double)Visit(node.LeftChild)) +
                       (isRightInteger ? (int)Visit(node.RightChild) : (double)Visit(node.RightChild)));

            case TokenType.Sub:
                return((isLeftInteger ? (int)Visit(node.LeftChild) : (double)Visit(node.LeftChild)) -
                       (isRightInteger ? (int)Visit(node.RightChild) : (double)Visit(node.RightChild)));

            case TokenType.Mult:
                return((isLeftInteger ? (int)Visit(node.LeftChild) : (double)Visit(node.LeftChild)) *
                       (isRightInteger ? (int)Visit(node.RightChild) : (double)Visit(node.RightChild)));

            case TokenType.Div:
                return((int)Visit(node.LeftChild) / (int)Visit(node.RightChild));

            case TokenType.FloatDiv:
                return((double)Visit(node.LeftChild) / (double)Visit(node.RightChild));

            default:
                throw new InvalidOperationException($"Token type {node.Data.Type} not expected for binary operations.");
            }
        }
        private AstNode Comparison()
        {
            var node  = Expression();
            var token = Scanner.State.CurrentToken;

            if (token.Type == TokenType.CompareLessThan)
            {
                var line = Match(TokenType.CompareLessThan);
                node = new BinaryOperationNode(node, BinaryOperationType.Less, Expression())
                {
                    Line = line
                };
            }
            else if (token.Type == TokenType.CompareGreaterThan)
            {
                var line = Match(TokenType.CompareGreaterThan);
                node = new BinaryOperationNode(node, BinaryOperationType.Greater, Expression())
                {
                    Line = line
                };
            }
            else if (token.Type == TokenType.CompareLessOrEqualTo)
            {
                var line = Match(TokenType.CompareLessOrEqualTo);
                node = new BinaryOperationNode(node, BinaryOperationType.LessOrEqual, Expression())
                {
                    Line = line
                };
            }
            else if (token.Type == TokenType.CompareGreaterOrEqualTo)
            {
                var line = Match(TokenType.CompareGreaterOrEqualTo);
                node = new BinaryOperationNode(node, BinaryOperationType.GreaterOrEqual, Expression())
                {
                    Line = line
                };
            }
            else if (token.Type == TokenType.CompareEqual)
            {
                var line = Match(TokenType.CompareEqual);
                node = new BinaryOperationNode(node, BinaryOperationType.Equal, Expression())
                {
                    Line = line
                };
            }
            else if (token.Type == TokenType.CompareNotEqual)
            {
                var line = Match(TokenType.CompareNotEqual);
                node = new BinaryOperationNode(node, BinaryOperationType.NotEqual, Expression())
                {
                    Line = line
                };
            }

            return(node);
        }
Example #11
0
        private AstNode parseAnd()
        {
            AstNode left = parseBitshift();

            while (acceptToken(TokenType.Operation, "&"))
            {
                left = new BinaryOperationNode(Location, BinaryOperation.BitwiseAnd, left, parseAnd());
            }
            return(left);
        }
Example #12
0
        private AstNode parseXor()
        {
            AstNode left = parseAnd();

            while (acceptToken(TokenType.Operation, "^"))
            {
                left = new BinaryOperationNode(Location, BinaryOperation.Xor, left, parseXor());
            }
            return(left);
        }
Example #13
0
        private AstNode parseLogicalAnd()
        {
            AstNode left = parseEquality();

            while (acceptToken(TokenType.Operation, "&&"))
            {
                left = new BinaryOperationNode(Location, BinaryOperation.LogicalAnd, left, parseLogicalAnd());
            }
            return(left);
        }
Example #14
0
        /// <summary>
        /// 二元操作符
        /// </summary>
        /// <param name="node"></param>
        public void Visit(BinaryOperationNode node)
        {
            var builder = new StringBuilder();

            builder.Append("二元操作符:");
            Console.WriteLine(builder.ToString());
            Visit((Object)node.OperandA);
            Console.Write(node.OperationType);
            Visit((Object)node.OperandB);
        }
Example #15
0
        private AstNode parseLogicalOr()
        {
            var     location = this.location;
            AstNode left     = parseLogicalAnd();

            while (acceptToken(TokenType.Operation, "||"))
            {
                left = new BinaryOperationNode(location, BinaryOperation.LogicalOr, left, parseLogicalOr());
            }
            return(left);
        }
Example #16
0
        private AstNode parseXor()
        {
            var     location = this.location;
            AstNode left     = parseAnd();

            while (acceptToken(TokenType.Operation, "^"))
            {
                left = new BinaryOperationNode(location, BinaryOperation.BitwiseXor, left, parseXor());
            }
            return(left);
        }
Example #17
0
 public void InspectBinaryOperationNode()
 {
     AstNode left = MakeToken(TokenType.Number, "6");
     Token op = MakeToken(TokenType.TimesSign, "*");
     AstNode right = MakeToken(TokenType.Number, "9");
     AstNode node = new BinaryOperationNode(left, op, right);
     Assert.That(node.Inspect(), Is.EqualTo(
         "BinaryOperationNode\r\n" +
         "  LeftNode: Number |6|\r\n" +
         "  OperatorNode: TimesSign |*|\r\n" +
         "  RightNode: Number |9|"));
 }
Example #18
0
        public void ParseRuleSetsParentReferences()
        {
            BinaryOperationNode top = (BinaryOperationNode)_parser.ParseRule(RuleType.Expression);

            Assert.That(top.LeftNode.ParentNode, Is.SameAs(top), "Top.Left");
            Assert.That(top.OperatorNode.ParentNode, Is.SameAs(top), "Top.Operator");
            Assert.That(top.RightNode.ParentNode, Is.SameAs(top), "Top.Right");
            BinaryOperationNode left = (BinaryOperationNode)top.LeftNode;

            Assert.That(left.LeftNode.ParentNode, Is.SameAs(left), "Left.Left");
            Assert.That(left.OperatorNode.ParentNode, Is.SameAs(left), "Left.Operator");
            Assert.That(left.RightNode.ParentNode, Is.SameAs(left), "Left.Right");
        }
Example #19
0
        public void InspectBinaryOperationNode()
        {
            AstNode left  = MakeToken(TokenType.Number, "6");
            Token   op    = MakeToken(TokenType.TimesSign, "*");
            AstNode right = MakeToken(TokenType.Number, "9");
            AstNode node  = new BinaryOperationNode(left, op, right);

            Assert.That(node.Inspect(), Is.EqualTo(
                            "BinaryOperationNode\r\n" +
                            "  LeftNode: Number |6|\r\n" +
                            "  OperatorNode: TimesSign |*|\r\n" +
                            "  RightNode: Number |9|"));
        }
Example #20
0
 public override void VisitBinaryOperationNode(BinaryOperationNode node)
 {
     if (node.OperatorNode.Type == TokenType.ColonEquals)
     {
         base.VisitBinaryOperationNode(node);
         //base.Visit(node.RightNode);
         //AddCode(((Token)node.LeftNode).Text);
         //AddCode(" = ");
         //base.Visit(node.RightNode);
     }
     else
     {
         base.VisitBinaryOperationNode(node);
     }
 }
Example #21
0
        public override void Init(Irony.Parsing.ParsingContext context, Irony.Parsing.ParseTreeNode treeNode)
        {
            base.Init(context, treeNode);
            AddChild("deref", treeNode.ChildNodes[0]);

            var expressionNode = new BinaryOperationNode();

            expressionNode.SetOp("+");
            expressionNode.ChildNodes.Add(Child(0)); //offset
            expressionNode.ChildNodes.Add(Child(1)); //base pointer
            baseNode = Child(1);

            ChildNodes.Clear();
            ChildNodes.Add(expressionNode);
        }
Example #22
0
        private TreeNode <Token> ParseTerm()
        {
            var result = ParseFactor();

            var ops = new List <TokenType> {
                TokenType.Mult, TokenType.Div, TokenType.FloatDiv
            };

            while (ops.Contains(Current.Type))
            {
                var token = Current;
                Eat(TokenType.Mult, TokenType.Div, TokenType.FloatDiv);

                result = new BinaryOperationNode(token, result, ParseFactor());
            }

            return(result);
        }
Example #23
0
 public void InspectNestedBinaryOperationNodes()
 {
     AstNode leftLeft = MakeToken(TokenType.Number, "2");
     Token leftOp = MakeToken(TokenType.TimesSign, "*");
     AstNode leftRight = MakeToken(TokenType.Number, "3");
     Token op = MakeToken(TokenType.TimesSign, "*");
     AstNode right = MakeToken(TokenType.Number, "9");
     AstNode left = new BinaryOperationNode(leftLeft, leftOp, leftRight);
     AstNode node = new BinaryOperationNode(left, op, right);
     Assert.That(node.Inspect(), Is.EqualTo(
         "BinaryOperationNode\r\n" +
         "  LeftNode: BinaryOperationNode\r\n" +
         "    LeftNode: Number |2|\r\n" +
         "    OperatorNode: TimesSign |*|\r\n" +
         "    RightNode: Number |3|\r\n" +
         "  OperatorNode: TimesSign |*|\r\n" +
         "  RightNode: Number |9|"));
 }
Example #24
0
        private SyntaxNode ParseBinaryExpression(int parentPrecedence = 0)
        {
            SyntaxNode left = ParseUnaryOrParenthesisOrValue();

            while (true)
            {
                var precedence = _tokens.Current.Kind.GetBinaryOperationPrecedence();
                if (!_tokens.Current.Kind.IsInTokenGroup(SyntaxTokenGroup.Binary) || precedence <= parentPrecedence)
                {
                    break;
                }
                var op    = _tokens.GetAndMoveNext();
                var right = ParseBinaryExpression(precedence);
                left = BinaryOperationNode.Create(left, op, right);
            }

            return(left);
        }
Example #25
0
        private TreeNode <Token> ParseExpression()
        {
            var result = ParseTerm();

            var ops = new List <TokenType> {
                TokenType.Add, TokenType.Sub
            };

            while (ops.Contains(Current.Type))
            {
                var token = Current;
                Eat(TokenType.Add, TokenType.Sub);

                result = new BinaryOperationNode(token, result, ParseTerm());
            }

            return(result);
        }
Example #26
0
        public void InspectNestedBinaryOperationNodes()
        {
            AstNode leftLeft  = MakeToken(TokenType.Number, "2");
            Token   leftOp    = MakeToken(TokenType.TimesSign, "*");
            AstNode leftRight = MakeToken(TokenType.Number, "3");
            Token   op        = MakeToken(TokenType.TimesSign, "*");
            AstNode right     = MakeToken(TokenType.Number, "9");
            AstNode left      = new BinaryOperationNode(leftLeft, leftOp, leftRight);
            AstNode node      = new BinaryOperationNode(left, op, right);

            Assert.That(node.Inspect(), Is.EqualTo(
                            "BinaryOperationNode\r\n" +
                            "  LeftNode: BinaryOperationNode\r\n" +
                            "    LeftNode: Number |2|\r\n" +
                            "    OperatorNode: TimesSign |*|\r\n" +
                            "    RightNode: Number |3|\r\n" +
                            "  OperatorNode: TimesSign |*|\r\n" +
                            "  RightNode: Number |9|"));
        }
Example #27
0
    public SyntaxNode constructSyntaxNode(VisualNode e)
    {
        Debug.Log("Id of currentl constructing node is " + e.ID);
        SyntaxNode node = SyntaxNodeFactory.produce(e.ID);

        if (node is BlockNode)
        {
            if (node is IfNode)
            {
                //It should still retain while if is while
                IfNode ifBlock = (IfNode)node;
                BinaryOperationNode conditionalStatement = new BinaryOperationNode();

                //Set it's attributes with fields in the operationVisual
                BlockVisual           block     = (BlockVisual)e;
                BinaryOperationVisual condition = (BinaryOperationVisual)block.condition;

                if (condition == null)
                {
                    //Throw an exception
                }

                convertBinaryOperation((BinaryOperationNode)conditionalStatement, (BinaryOperationVisual)condition);
                ifBlock.SetCondition(conditionalStatement);
            }
        }
        else if (e is BinaryOperationVisual)
        {
            if (node is BinaryOperationNode)
            {
                convertBinaryOperation((BinaryOperationNode)node, (BinaryOperationVisual)e);
            }
        }


        //It should hold all it's changes.
        return(node);
    }
        public override DynValue Visit(BinaryOperationNode binaryOperationNode)
        {
            var left  = Visit(binaryOperationNode.LeftOperand);
            var right = Visit(binaryOperationNode.RightOperand);

            switch (binaryOperationNode.Type)
            {
            case BinaryOperationType.Plus:
                return(Addition(left, right, binaryOperationNode));

            case BinaryOperationType.Minus:
                return(Subtraction(left, right, binaryOperationNode));

            case BinaryOperationType.Multiply:
                if (left.Type == DynValueType.Number)
                {
                    return(Multiplication(right, left, binaryOperationNode));
                }
                else
                {
                    return(Multiplication(left, right, binaryOperationNode));
                }

            case BinaryOperationType.Divide:
                return(Division(left, right, binaryOperationNode));

            case BinaryOperationType.Modulo:
                return(Modulus(left, right, binaryOperationNode));

            case BinaryOperationType.ShiftLeft:
                return(ShiftLeft(left, right, binaryOperationNode));

            case BinaryOperationType.ShiftRight:
                return(ShiftRight(left, right, binaryOperationNode));

            case BinaryOperationType.BitwiseAnd:
                return(BitwiseAnd(left, right, binaryOperationNode));

            case BinaryOperationType.BitwiseOr:
                return(BitwiseOr(left, right, binaryOperationNode));

            case BinaryOperationType.BitwiseXor:
                return(BitwiseXor(left, right, binaryOperationNode));

            case BinaryOperationType.Less:
                return(CompareLess(left, right, binaryOperationNode));

            case BinaryOperationType.Greater:
                return(CompareGreater(left, right, binaryOperationNode));

            case BinaryOperationType.LessOrEqual:
                return(CompareLessOrEqual(left, right, binaryOperationNode));

            case BinaryOperationType.GreaterOrEqual:
                return(CompareGreaterOrEqual(left, right, binaryOperationNode));

            case BinaryOperationType.NotEqual:
                return(CompareNotEqual(left, right, binaryOperationNode));

            case BinaryOperationType.Equal:
                return(CompareEqual(left, right, binaryOperationNode));

            case BinaryOperationType.And:
                return(LogicalAnd(left, right));

            case BinaryOperationType.Or:
                return(LogicalOr(left, right));

            default: throw new RuntimeException("Unknown binary operation.", binaryOperationNode.Line);
            }
        }
Example #29
0
        public void Accept(BinaryOperationNode node)
        {
            if (node.BinaryOperation != BinaryOperation.Assignment)
            {
                node.Right.Visit(this);
                node.Left.Visit(this);
                append("pop a");
                append("pop b");
            }

            switch (node.BinaryOperation)
            {
            case BinaryOperation.Assignment:
                node.Right.Visit(this);
                if (node.Left is IdentifierNode)
                {
                    storeLocal(node.Left.SourceLocation, ((IdentifierNode)node.Left).Identifier, "b");
                    append("push b");
                }
                else if (node.Left is IndexerNode)
                {
                    append("pop c");
                    var indexer = node.Left as IndexerNode;
                    indexer.Index.Visit(this);
                    if (indexer.Target is IdentifierNode)
                    {
                        indexer.Target.Visit(this);
                    }
                    append("pop a");
                    append("pop b");
                    append("add a, b");
                    append("stob a, c");
                    append("push c");
                }
                else if (node.Left is StaticAttributeAccessNode)
                {
                    append("pop b");
                    string left    = ((StaticAttributeAccessNode)node.Left).Left;
                    string right   = ((StaticAttributeAccessNode)node.Left).Right;
                    Struct struct_ = structs[left];
                    if (!struct_.IsStatic)
                    {
                        throw new CompilerException(node.SourceLocation, "Static reference to non-static struct {0}!", left);
                    }
                    int location = BP_INITIAL + table.GetGlobalOffset(node.SourceLocation, left, true) + struct_.GetOffset(right);
                    append("li a, {0}", location);
                    switch (struct_.GetSize(right))
                    {
                    case 1:
                        append("stob a, b");
                        break;

                    case 2:
                        append("stow a, b");
                        break;
                    }
                    append("push b");
                }
                break;

            case BinaryOperation.Addition:
                append("add a, b");
                append("push a");
                break;

            case BinaryOperation.Subtraction:
                append("sub a, b");
                append("push a");
                break;

            case BinaryOperation.Multiplication:
                append("mul a, b");
                append("push a");
                break;

            case BinaryOperation.Division:
                append("div a, b");
                append("push a");
                break;

            case BinaryOperation.Modulus:
                append("mod a, b");
                append("push a");
                break;

            case BinaryOperation.BitshiftLeft:
                append("shil a, b");
                append("push a");
                break;

            case BinaryOperation.BitshiftRight:
                append("shir a, b");
                append("push a");
                break;

            case BinaryOperation.BitwiseAnd:
                append("and a, b");
                append("push a");
                break;

            case BinaryOperation.BitwiseOr:
                append("or a, b");
                append("push a");
                break;

            case BinaryOperation.Xor:
                append("xor a, b");
                append("push a");
                break;

            case BinaryOperation.LogicalAnd:
                append("and a, b");
                append("neqi a, 0");
                append("push a");
                break;

            case BinaryOperation.LogicalOr:
                append("or a, b");
                append("neqi a, 0");
                append("push a");
                break;

            case BinaryOperation.Equality:
                append("eq a, b");
                append("push a");
                break;

            case BinaryOperation.Inequality:
                append("neq a, b");
                append("push a");
                break;

            case BinaryOperation.Greater:
                append("gt a, b");
                append("push a");
                break;

            case BinaryOperation.GreaterOrEqual:
                append("gte a, b");
                append("push a");
                break;

            case BinaryOperation.Lesser:
                append("lt a, b");
                append("push a");
                break;

            case BinaryOperation.LesserOrEqual:
                append("lte a, b");
                append("push a");
                break;
            }
        }
Example #30
0
 public virtual void VisitBinaryOperationNode(BinaryOperationNode node)
 {
     Visit(node.LeftNode);
     Visit(node.OperatorNode);
     Visit(node.RightNode);
 }
        public override DynValue Visit(BinaryOperationNode binaryOperationNode)
        {
            var left  = Visit(binaryOperationNode.LeftOperand);
            var right = Visit(binaryOperationNode.RightOperand);

            switch (binaryOperationNode.Type)
            {
            case BinaryOperationType.Plus:
                if (left.Type == DynValueType.String)
                {
                    return(new DynValue(left.String + right.String));
                }
                else
                {
                    return(new DynValue(left.Number + right.Number));
                }

            case BinaryOperationType.Minus:
                return(new DynValue(left.Number - right.Number));

            case BinaryOperationType.Multiply:
                return(new DynValue(left.Number * right.Number));

            case BinaryOperationType.Divide:
                return(new DynValue(left.Number / right.Number));

            case BinaryOperationType.ShiftLeft:
            {
                if (left.Type != DynValueType.Number || right.Type != DynValueType.Number)
                {
                    throw new RuntimeException("Attempt of left shift operation on a non-numerical value.", binaryOperationNode.Line);
                }

                if (left.Number % 1 != 0 || right.Number % 1 != 0)
                {
                    throw new RuntimeException("'<<' operation is only allowed on integers.", binaryOperationNode.Line);
                }

                return(new DynValue((int)left.Number << (int)right.Number));
            }

            case BinaryOperationType.ShiftRight:
            {
                if (left.Type != DynValueType.Number || right.Type != DynValueType.Number)
                {
                    throw new RuntimeException("Attempt of right shift operation on a non-numerical value.", binaryOperationNode.Line);
                }

                if (left.Number % 1 != 0 || right.Number % 1 != 0)
                {
                    throw new RuntimeException("'>>' operation is only allowed on integers.", binaryOperationNode.Line);
                }

                return(new DynValue((int)left.Number >> (int)right.Number));
            }

            case BinaryOperationType.Nand:
            {
                if (left.Type != DynValueType.Number || right.Type != DynValueType.Number)
                {
                    throw new RuntimeException("Attempt of NAND operation on a non-numerical value.", binaryOperationNode.Line);
                }

                if (left.Number % 1 != 0 || right.Number % 1 != 0)
                {
                    throw new RuntimeException("NAND operation is only allowed on integers.", binaryOperationNode.Line);
                }

                return(new DynValue(~((int)left.Number & (int)right.Number)));
            }

            case BinaryOperationType.Modulo:
                return(new DynValue(left.Number % right.Number));

            case BinaryOperationType.Less:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number < right.Number)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else if (left.Type == DynValueType.String)
                {
                    if (left.String.Length < right.String.Length)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'<' operator is only allowed on numbers and strings.", binaryOperationNode.Line);
                }

            case BinaryOperationType.Greater:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number > right.Number)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else if (left.Type == DynValueType.String)
                {
                    if (left.String.Length > right.String.Length)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'>' operator is only allowed on numbers and strings.", binaryOperationNode.Line);
                }

            case BinaryOperationType.LessOrEqual:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number <= right.Number)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else if (left.Type == DynValueType.String)
                {
                    if (left.String.Length <= right.String.Length)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'<=' operator is only allowed on numbers and strings.", binaryOperationNode.Line);
                }

            case BinaryOperationType.GreaterOrEqual:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number >= right.Number)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else if (left.Type == DynValueType.String)
                {
                    if (left.String.Length >= right.String.Length)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'>=' operator is only allowed on numbers and strings.", binaryOperationNode.Line);
                }

            case BinaryOperationType.NotEqual:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number != right.Number)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else if (left.Type == DynValueType.String)
                {
                    if (left.String.Length != right.String.Length && right.String != left.String)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'!=' operator is only allowed on numbers and strings.", binaryOperationNode.Line);
                }

            case BinaryOperationType.Equal:
                if (left.Type != right.Type)
                {
                    throw new RuntimeException("Only values of the same type can be compared.", binaryOperationNode.Line);
                }

                if (left.Type == DynValueType.Number)
                {
                    if (left.Number == right.Number)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else if (left.Type == DynValueType.String)
                {
                    if (left.String.Length == right.String.Length && right.String == left.String)
                    {
                        return(new DynValue(1));
                    }

                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'==' operator is only allowed on numbers and strings.", binaryOperationNode.Line);
                }

            case BinaryOperationType.And:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number != 0 && right.Number != 0)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'and' operator is only allowed on numbers.", binaryOperationNode.Line);
                }

            case BinaryOperationType.Or:
                if (left.Type == DynValueType.Number)
                {
                    if (left.Number != 0 || right.Number != 0)
                    {
                        return(new DynValue(1));
                    }
                    else
                    {
                        return(new DynValue(0));
                    }
                }
                else
                {
                    throw new RuntimeException("'or' operator is only allowed on numbers.", binaryOperationNode.Line);
                }


            default: throw new RuntimeException("Unknown binary operation.", binaryOperationNode.Line);
            }
        }
Example #32
0
 public abstract DynValue Visit(BinaryOperationNode binaryOperationNode);
Example #33
0
 public void Visit(Node node)
 {
     if (node is ArgumentsListNode)
     {
         VisitSubnodes(node);
     }
     else if (node is BinaryOperationNode)
     {
         BinaryOperationNode binop = (BinaryOperationNode)node;
         if (binop.BinaryOperation == BinaryOperation.Assignment)
         {
             if (binop.Left is IdentifierNode)
             {
                 IdentifierNode ident = (IdentifierNode)binop.Left;
                 if (!symbolTable.IsSymbolDefined(ident.Name))
                 {
                     symbolTable.AddSymbol(ident.Name);
                 }
             }
         }
         VisitSubnodes(node);
     }
     else if (node is ClassDeclarationNode)
     {
         throw new System.Exception("Can't define an class inside of an function.");
     }
     else if (node is CodeBlock)
     {
         VisitSubnodes(node);
     }
     else if (node is EnumDeclarationNode)
     {
         symbolTable.AddSymbol(((EnumDeclarationNode)node).Name);
     }
     else if (node is ExpressionNode)
     {
         VisitSubnodes(node);
     }
     else if (node is ForNode)
     {
         VisitSubnodes(node);
     }
     else if (node is FunctionCallNode)
     {
         VisitSubnodes(node);
     }
     else if (node is FunctionDeclarationNode)
     {
         throw new System.Exception("Can't define an function inside of an function.");
     }
     else if (node is GetAttributeNode)
     {
         VisitSubnodes(node);
     }
     else if (node is IfNode)
     {
         VisitSubnodes(node);
     }
     else if (node is IndexerNode)
     {
         VisitSubnodes(node);
     }
     else if (node is ReturnNode)
     {
         VisitSubnodes(node);
     }
     else if (node is ScopeNode)
     {
         symbolTable.BeginScope();
         VisitSubnodes(node);
         symbolTable.EndScope();
     }
     else if (node is FunctionDeclarationNode)
     {
         throw new System.Exception("Using statement is not valid inside function body.");
     }
     else if (node is WhileNode)
     {
         VisitSubnodes(node);
     }
 }
 public static string InvalidUseOfOperator(BinaryOperationNode node, TypeInfo leftOperand, TypeInfo rightOperand)
 {
     return($"({node.Line}, {node.Column}) - Semantic Error:" +
            $" El operador '{node.Symbol}' no se puede aplicar a tipos '{leftOperand.Text}' y '{rightOperand.Text}'."
            );
 }