internal RCMethod Compile(RNode main) { EmitScope es = CreateMethodScope("main"); PushScope(es); state = EmitState.RESOLVING; main.Walk(this); state = EmitState.EMITTING; EmitScopeInitializer(); main.Walk(this); Type main_type = CloseScope(es); if (save) { assembly_builder.Save(filename); } // Call constructor object method = main_type.InvokeMember(null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.CreateInstance, null, null, new object[] {} ); return((RCMethod)method); }
EmitScope CreateScope(string name, Type parent, Type[] args, Type[] cargs) { EmitScope es = new EmitScope(this); TypeBuilder tb = module_builder.DefineType(name + "_" + GetID(), TypeAttributes.Public, parent); MethodInfo mi = parent.GetMethod("Call"); MethodBuilder mb = tb.DefineMethod("Call", MethodAttributes.Public | MethodAttributes.Virtual, typeof(RBasic), args ); tb.DefineMethodOverride(mb, mi); ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, cargs); es.type_builder = tb; es.ig = mb.GetILGenerator(); es.cig = cb.GetILGenerator(); // Parent constructor call for (int i = 0; i <= cargs.Length; i++) { es.cig.Emit(OpCodes.Ldarg_S, (byte)i); } es.cig.Emit(OpCodes.Call, parent.GetConstructor(cargs)); return(es); }
internal void PopScope(EmitScope es) { if (current_scope != es) { throw new Exception("Unexpected scope encountered while popping scope stack"); } current_scope = current_scope.parent; }
internal Type CloseScope(EmitScope es) { es.cig.Emit(OpCodes.Ret); es.ig.Emit(OpCodes.Ret); PopScope(es); return(es.type_builder.CreateType()); }
internal EmitScope CreateMethodScope(string name) { EmitScope es = CreateScope(name, typeof(RCMethod), new Type[] { typeof(RThread), typeof(RBasic), typeof(RBasic[]), typeof(RCBlock) }, new Type[] { } ); return(es); }
internal EmitScope CreateBlockScope(string name) { EmitScope es = CreateScope(name, typeof(RCBlock), new Type[] { typeof(RThread), typeof(RBasic[]), typeof(RCBlock) }, new Type[] { typeof(RBasic), typeof(RBasic[]) } ); es.IsBlock = true; return(es); }
EmitScope scope; // New scope for the block internal override void Walk(EmitContext ec) { if (ec.Resolving) { scope = ec.CreateBlockScope("block"); } ec.PushScope(scope); if (ec.Emitting) { ec.EmitScopeInitializer(); } // The parser should produce a more comfortable format for this if (var is RNDAsgn) { RNDefn.WalkArg(ec, 0, var.vid); } else { RNArray args = var != null ? (RNArray)((RNMAsgn)var).head : null; int i = 0; for (RNode n = args; n != null;) { RNDAsgn a = (RNDAsgn)n.head; RNDefn.WalkArg(ec, i, a.vid); n = n.next; i++; } } body.Walk(ec); if (ec.Emitting) { Type t = ec.CloseScope(scope); RNCall call = (RNCall)iter; call.block = t; call.Walk(ec); } else { ec.PopScope(scope); iter.Walk(ec); } }
// Find the parent method scope for a (possibly nested) block internal EmitScope GetMethodScope() { EmitScope es = this; while (es != null) { if (!es.IsBlock) { break; } es = es.parent; } return(es); }
internal override void Walk(EmitContext ec) { string name = ec.id2name(mid); if (ec.Resolving) { scope = ec.CreateMethodScope(name); } ec.PushScope(scope); if (ec.Emitting) { ec.EmitScopeInitializer(); } RNScope sc = (RNScope)defn; RNode n = sc.next; RNArgs args = (RNArgs)n.head; RNode body = n.next; int argc = args.cnt; for (int i = 0; i < argc; i++) { // First two locals in table are $~ and $_ uint vid = sc.tbl[i + 2]; WalkArg(ec, i, vid); } // Methods can have no body if (body != null) { body.Walk(ec); } if (ec.Emitting) { Type t = ec.CloseScope(scope); ec.EmitDefine(name, t); ec.EmitNil(); // Return value } else { ec.PopScope(scope); } }
internal override void Walk(EmitContext ec) { string name = ec.id2name(mid); if(ec.Resolving) { scope = ec.CreateMethodScope(name); } ec.PushScope(scope); if(ec.Emitting) ec.EmitScopeInitializer(); RNScope sc = (RNScope)defn; RNode n = sc.next; RNArgs args = (RNArgs)n.head; RNode body = n.next; int argc = args.cnt; for(int i = 0; i < argc; i++) { // First two locals in table are $~ and $_ uint vid = sc.tbl[i + 2]; WalkArg(ec, i, vid); } // Methods can have no body if(body != null) body.Walk(ec); if(ec.Emitting) { Type t = ec.CloseScope(scope); ec.EmitDefine(name, t); ec.EmitNil(); // Return value } else { ec.PopScope(scope); } }
EmitScope scope; // New scope for the block internal override void Walk(EmitContext ec) { if(ec.Resolving) { scope = ec.CreateBlockScope("block"); } ec.PushScope(scope); if(ec.Emitting) ec.EmitScopeInitializer(); // The parser should produce a more comfortable format for this if(var is RNDAsgn) { RNDefn.WalkArg(ec, 0, var.vid); } else { RNArray args = var != null ? (RNArray)((RNMAsgn)var).head : null; int i = 0; for(RNode n = args; n != null; ) { RNDAsgn a = (RNDAsgn)n.head; RNDefn.WalkArg(ec, i, a.vid); n = n.next; i++; } } body.Walk(ec); if(ec.Emitting) { Type t = ec.CloseScope(scope); RNCall call = (RNCall)iter; call.block = t; call.Walk(ec); } else { ec.PopScope(scope); iter.Walk(ec); } }
internal void PopScope(EmitScope es) { if(current_scope != es) { throw new Exception("Unexpected scope encountered while popping scope stack"); } current_scope = current_scope.parent; }
internal void PushScope(EmitScope es) { es.parent = current_scope; current_scope = es; }
internal Type CloseScope(EmitScope es) { es.cig.Emit(OpCodes.Ret); es.ig.Emit(OpCodes.Ret); PopScope(es); return es.type_builder.CreateType(); }
EmitScope CreateScope(string name, Type parent, Type[] args, Type[] cargs) { EmitScope es = new EmitScope(this); TypeBuilder tb = module_builder.DefineType(name + "_" + GetID(), TypeAttributes.Public, parent); MethodInfo mi = parent.GetMethod("Call"); MethodBuilder mb = tb.DefineMethod("Call", MethodAttributes.Public | MethodAttributes.Virtual, typeof(RBasic), args ); tb.DefineMethodOverride(mb, mi); ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, cargs); es.type_builder = tb; es.ig = mb.GetILGenerator(); es.cig = cb.GetILGenerator(); // Parent constructor call for(int i = 0; i <= cargs.Length; i++) { es.cig.Emit(OpCodes.Ldarg_S, (byte)i); } es.cig.Emit(OpCodes.Call, parent.GetConstructor(cargs)); return es; }