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(); }