コード例 #1
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        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);
        }
コード例 #2
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        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);
        }
コード例 #3
0
ファイル: codegen.cs プロジェクト: retahc/old-code
 internal void PopScope(EmitScope es)
 {
     if (current_scope != es)
     {
         throw new Exception("Unexpected scope encountered while popping scope stack");
     }
     current_scope = current_scope.parent;
 }
コード例 #4
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        internal Type CloseScope(EmitScope es)
        {
            es.cig.Emit(OpCodes.Ret);
            es.ig.Emit(OpCodes.Ret);

            PopScope(es);

            return(es.type_builder.CreateType());
        }
コード例 #5
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        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);
        }
コード例 #6
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        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);
        }
コード例 #7
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        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);
            }
        }
コード例 #8
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        // 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);
        }
コード例 #9
0
ファイル: codegen.cs プロジェクト: retahc/old-code
        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);
            }
        }
コード例 #10
0
ファイル: codegen.cs プロジェクト: emtees/old-code
        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);
            }
        }
コード例 #11
0
ファイル: codegen.cs プロジェクト: emtees/old-code
        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);
            }
        }
コード例 #12
0
ファイル: codegen.cs プロジェクト: emtees/old-code
 internal void PopScope(EmitScope es)
 {
     if(current_scope != es) {
         throw new Exception("Unexpected scope encountered while popping scope stack");
     }
     current_scope = current_scope.parent;
 }
コード例 #13
0
ファイル: codegen.cs プロジェクト: emtees/old-code
 internal void PushScope(EmitScope es)
 {
     es.parent = current_scope;
     current_scope = es;
 }
コード例 #14
0
ファイル: codegen.cs プロジェクト: emtees/old-code
 internal Type CloseScope(EmitScope es)
 {
     es.cig.Emit(OpCodes.Ret);
     es.ig.Emit(OpCodes.Ret);
     
     PopScope(es);
     
     return es.type_builder.CreateType();
 }
コード例 #15
0
ファイル: codegen.cs プロジェクト: emtees/old-code
        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;
        }
コード例 #16
0
ファイル: codegen.cs プロジェクト: retahc/old-code
 internal void PushScope(EmitScope es)
 {
     es.parent     = current_scope;
     current_scope = es;
 }