コード例 #1
0
ファイル: Compiler.cs プロジェクト: robotii/sophielang
        // 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.LoadModuleVar, 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.RightBrace)
            {
                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.Primary);
                    c.Consume(TokenType.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.Comma));
            }

            // Allow newlines before the closing '}'.
            c.IgnoreNewlines();
            c.Consume(TokenType.RightBrace, "Expect '}' after map entries.");
        }
コード例 #2
0
ファイル: Compiler.cs プロジェクト: robotii/sophielang
        // 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.Name);
        }
コード例 #3
0
ファイル: Compiler.cs プロジェクト: robotii/sophielang
        // A list literal.
        private static void List(Compiler c, bool allowAssignment)
        {
            // Load the List class.
            int listClassSymbol = c._parser.Module.Variables.FindIndex(v => v.Name == "List");
            //ASSERT(listClassSymbol != -1, "Should have already defined 'List' variable.");
            c.EmitShortArg(Instruction.LoadModuleVar, listClassSymbol);

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

            // Compile the list elements. Each one compiles to a ".add()" call.
            if (c.Peek() != TokenType.RightBracket)
            {
                do
                {
                    c.IgnoreNewlines();

                    // Push a copy of the list since the add() call will consume it.
                    c.Emit(Instruction.Dup);

                    // The element.
                    c.Expression();
                    c.CallMethod(1, "add(_)");

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

            // Allow newlines before the closing ']'.
            c.IgnoreNewlines();
            c.Consume(TokenType.RightBracket, "Expect ']' after list elements.");
        }
コード例 #4
0
ファイル: Compiler.cs プロジェクト: robotii/sophielang
        private static void new_(Compiler c, bool allowAssignment)
        {
            // Allow a dotted name after 'new'.
            c.Consume(TokenType.Name, "Expect name after 'new'.");
            Name(c, false);
            while (c.Match(TokenType.Dot))
            {
                Call(c, false);
            }

            // The angle brackets in the name are to ensure users can't call it directly.
            c.CallMethod(0, "<instantiate>");

            // Invoke the constructor on the new instance.
            c.MethodCall(Instruction.Call0, "new", 3);
        }