ParsePrecedence() private method

private ParsePrecedence ( bool allowAssignment, Precedence precedence ) : void
allowAssignment bool
precedence Precedence
return void
Exemplo n.º 1
0
        private static void Conditional(Compiler c, bool allowAssignment)
        {
            // Ignore newline after '?'.
            c.IgnoreNewlines();

            // Jump to the else branch if the condition is false.
            int ifJump = c.EmitJump(Instruction.JUMP_IF);

            // Compile the then branch.
            c.ParsePrecedence(allowAssignment, Precedence.Ternary);

            c.Consume(TokenType.Colon, "Expect ':' after then branch of conditional operator.");
            c.IgnoreNewlines();

            // Jump over the else branch when the if branch is taken.
            int elseJump = c.EmitJump(Instruction.JUMP);

            // Compile the else branch.
            c.PatchJump(ifJump);

            c.ParsePrecedence(allowAssignment, Precedence.Assignment);

            // Patch the jump over the else.
            c.PatchJump(elseJump);
        }
Exemplo n.º 2
0
        private static void InfixOp(Compiler c, bool allowAssignment)
        {
            GrammarRule rule = c.GetRule(c._parser.Previous.Type);

            // An infix operator cannot end an expression.
            c.IgnoreNewlines();

            // Compile the right-hand side.
            c.ParsePrecedence(false, rule.Precedence + 1);

            // Call the operator method on the left-hand side.
            Signature signature = new Signature { Type = SignatureType.Method, Arity = 1, Name = rule.Function, Length = rule.Function.Length };
            c.CallSignature(Instruction.CALL_0, signature);
        }
Exemplo n.º 3
0
        static void or_(Compiler c, bool allowAssignment)
        {
            c.IgnoreNewlines();

            // Skip the right argument if the left is true.
            int jump = c.EmitJump(Instruction.OR);
            c.ParsePrecedence(false, Precedence.LogicalOr);
            c.PatchJump(jump);
        }
Exemplo n.º 4
0
        // Unary operators like `-foo`.
        private static void UnaryOp(Compiler c, bool allowAssignment)
        {
            GrammarRule rule = c.GetRule(c._parser.Previous.Type);

            c.IgnoreNewlines();

            // Compile the argument.
            c.ParsePrecedence(false, Precedence.Unary + 1);

            // Call the operator method on the left-hand side.
            c.CallMethod(0, rule.Function);
        }
Exemplo n.º 5
0
        // A map literal.
        private static void Map(Compiler c, bool allowAssignment)
        {
            // Load the Map class.
            c.LoadCoreVariable("Map");

            // Instantiate a new map.
            c.CallMethod(0, "new()");

            // Compile the map elements. Each one is compiled to just invoke the
            // subscript setter on the map.
            if (c.Peek() != TokenType.RightBrace)
            {
                do
                {
                    c.IgnoreNewlines();

                    if (c.Peek() == TokenType.RightBrace)
                        break;

                    // Push a copy of the map since the subscript call will consume it.
                    c.Emit(Instruction.DUP);

                    // The key.
                    c.ParsePrecedence(false, Precedence.Primary);
                    c.Consume(TokenType.Colon, "Expect ':' after map key.");
                    c.IgnoreNewlines();

                    // The value.
                    c.Expression();
                    c.CallMethod(2, "[_]=(_)");

                    // Discard the result of the setter call.
                    c.Emit(Instruction.POP);
                } while (c.Match(TokenType.Comma));
            }

            // Allow newlines before the closing '}'.
            c.IgnoreNewlines();
            c.Consume(TokenType.RightBrace, "Expect '}' after map entries.");
        }
Exemplo n.º 6
0
        private static void and_(Compiler c, bool allowAssignment)
        {
            c.IgnoreNewlines();

            // Skip the right argument if the left is false.
            int jump = c.EmitJump(Instruction.AND);
            c.ParsePrecedence(false, Precedence.PREC_LOGICAL_AND);
            c.PatchJump(jump);
        }
Exemplo n.º 7
0
        // A map literal.
        private static void Map(Compiler c, bool allowAssignment)
        {
            // Load the Map class.
            int mapClassSymbol = c.parser.module.Variables.FindIndex(v => v.Name == "Map");
            c.EmitShortArg(Instruction.LOAD_MODULE_VAR, mapClassSymbol);

            // Instantiate a new map.
            c.CallMethod(0, "<instantiate>");

            // Compile the map elements. Each one is compiled to just invoke the
            // subscript setter on the map.
            if (c.Peek() != TokenType.TOKEN_RIGHT_BRACE)
            {
                do
                {
                    c.IgnoreNewlines();

                    // Push a copy of the map since the subscript call will consume it.
                    c.Emit(Instruction.DUP);

                    // The key.
                    c.ParsePrecedence(false, Precedence.PREC_PRIMARY);
                    c.Consume(TokenType.TOKEN_COLON, "Expect ':' after map key.");

                    // The value.
                    c.Expression();

                    c.CallMethod(2, "[_]=(_)");

                    // Discard the result of the setter call.
                    c.Emit(Instruction.POP);
                } while (c.Match(TokenType.TOKEN_COMMA));
            }

            // Allow newlines before the closing '}'.
            c.IgnoreNewlines();
            c.Consume(TokenType.TOKEN_RIGHT_BRACE, "Expect '}' after map entries.");
        }