Beispiel #1
0
        private void CompileInstantiate(ParserBlock block, BlockLocal start, BlockLocal tree)
        {
            block.BeginScope();

            Type[] parameterTypes = new Type[1 + Fields.Count];

            parameterTypes[0] = typeof(Source);

            for (int n = 1; n < parameterTypes.Length; n++)
            {
                parameterTypes[n] = typeof(object);
            }

            ConstructorInfo constructor = Type.GetConstructor(parameterTypes);

            if (constructor == null)
            {
                throw new Exception("Couldn't find constructor for " + Type.FullName);
            }

            block.LoadLexer();
            block.LoadLocal(start);
            block.Call(typeof(Lexer).GetMethod("SourceFrom"));

            BlockLocal fields = new BlockLocal(typeof(Dictionary <string, object>));

            block.DeclareLocal(fields);
            block.LoadLocal(tree);
            block.GetProperty(typeof(ParseTree).GetProperty("Fields"));
            block.StoreLocal(fields);

            for (int n = 0; n < Fields.Count; n++)
            {
                block.BeginScope();

                BlockLocal fieldValue = new BlockLocal(typeof(object));
                block.DeclareLocal(fieldValue);

                block.LoadLocal(fields);
                block.Load(Fields[n]);
                block.LoadLocalAddress(fieldValue);
                block.Call(fields.Type.GetMethod("TryGetValue"));
                block.Pop();

                block.LoadLocal(fieldValue);

                block.EndScope();
            }

            block.New(constructor);

            BlockLocal instance = new BlockLocal(typeof(RuntimeObject));

            block.DeclareLocal(instance);
            block.StoreLocal(instance);

            // Call Parsed

            block.Load(0);
            block.NewArray(typeof(object));

            block.BeginScope();

            BlockLocal parsedParameters = new BlockLocal(typeof(object[]));

            block.DeclareLocal(parsedParameters);
            block.StoreLocal(parsedParameters);

            block.LoadLocal(instance);
            block.Load("Parsed");
            block.LoadLocal(parsedParameters);
            block.Load(false);

            block.Call(typeof(MemberNode).GetMethod("GetMember", new Type[] {
                typeof(object), typeof(string), typeof(object[]),
                typeof(bool)
            }));

            BlockLabel noParsedMethod = new BlockLabel("noParsedMethod");

            block.Dup();
            block.BranchIfNull(noParsedMethod);

            BlockLocal parsedMethod = new BlockLocal(typeof(object));

            block.DeclareLocal(parsedMethod);
            block.StoreLocal(parsedMethod);

            block.LoadRuntimeState();
            block.LoadLocal(parsedMethod);
            block.LoadLocal(parsedParameters);
            block.Call(typeof(CallNode).GetMethod("Call", new Type[] {
                typeof(RuntimeState), typeof(object), typeof(object[])
            }));
            block.Pop();

            BlockLabel finishedParsedCall = new BlockLabel("finishedParsedCall");

            block.Branch(finishedParsedCall);

            block.MarkLabel(noParsedMethod);

            block.Pop();

            block.MarkLabel(finishedParsedCall);

            block.EndScope();

            block.LoadLocal(instance);
            block.New(typeof(ParseTree).GetConstructor(new Type[] { typeof(object) }));

            block.StoreLocal(tree);

            block.EndScope();
        }