示例#1
0
 // ( argsarr -- argsarr )
 internal static void EmitArgsArray(EmitContext ec, RNArray a)
 {
     int i = 0;
     while(a != null) {
         EmitStoreArg(ec, i, a.head);
         a = (RNArray)a.next;
         i++;
     }
 }
示例#2
0
 internal override void Walk(EmitContext ec)
 {
     next.Walk(ec);
 }
示例#3
0
 internal Type block; // Generated type of the block attached to the call
 
 // ( argsarr -- argsarr )
 internal static void EmitStoreArg(EmitContext ec, int i, RNode val) {
     ec.EmitDup(); // arr
     ec.EmitInt(i); // idx
     val.Walk(ec); // val
     ec.EmitArrayStore();
 }
示例#4
0
        internal override void Walk(EmitContext ec)
        {
            // Due to the slightly weird RNode inheritance hierarchy
            bool is_load = this is RNLVar || this is RNDVar;
            
            if(!(is_load || this is RNDAsgn || this is RNLAsgn)) {
                throw new NotSupportedException("bug: variable type not supported: " + this.GetType().Name);
            }

            if(ec.Resolving) {
                v = ec.scope.MarkVariable(vid);
            }

            if(!is_load)
                val.Walk(ec);
            
            if(ec.Emitting) {
                if(is_load) {
                    Variable v = ec.scope.GetVariable(vid);
                    ec.EmitLoadVar(v);
                } else {
                    ec.EmitDup();
                    ec.EmitStoreVar(v);
                }
            }
        }
示例#5
0
 internal override void Walk(EmitContext ec)
 {
     if(ec.Emitting)
         ec.EmitRString(lit.ToString());
 }
示例#6
0
        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);
            }
        }
示例#7
0
        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);
            }
        }
示例#8
0
 internal override void Walk(EmitContext ec)
 {
     val.Walk(ec);
     if(ec.Emitting) {
         ec.EmitDup();
         ec.EmitSetGlobal(ec.id2name(vid));
     }
 }
示例#9
0
 internal override void Walk(EmitContext ec)
 {
     if(ec.Emitting)
         ec.EmitGetGlobal(ec.id2name(vid));
 }
示例#10
0
 internal override void Walk(EmitContext ec)
 {
     body.Walk(ec);
     if(ec.Emitting)
         ec.EmitNot();
 }
示例#11
0
        internal override void Walk(EmitContext ec)
        {
            if(ec.Emitting) {
                Label skip_label = ec.DefineLabel();

                nd1st.Walk(ec);
                ec.EmitDup();
                LocalBuilder first = ec.EmitStoreTemp();
                ec.EmitBranchIfTrue(skip_label);
                
                nd2nd.Walk(ec);
                ec.EmitDup();
                LocalBuilder second = ec.EmitStoreTemp();
                ec.EmitBranchIfTrue(skip_label);
                
                ec.EmitLoadTemp(second);
                ec.EmitStoreTemp(first);
                
                ec.MarkLabel(skip_label);
                ec.EmitLoadTemp(first);
            } else {
                nd1st.Walk(ec);
                nd2nd.Walk(ec);
            }
        }
示例#12
0
        internal override void Walk(EmitContext ec)
        {
            if(ec.Resolving) {
                cond.Walk(ec);
                body.Walk(ec);
                if(nd_else != null)
                    nd_else.Walk(ec);
            }
            if(ec.Emitting) {
                Label else_label = ec.DefineLabel();
                Label end_label = ec.DefineLabel();
                
                cond.Walk(ec);
                ec.EmitBranchIfFalse(else_label);

                // TODO rearrange the body and else clause in this case
                if(body != null) {
                    body.Walk(ec);
                    ec.EmitDiscard();
                }
                
                if(nd_else != null) {
                    ec.EmitBranch(end_label);
                }
                    
                ec.MarkLabel(else_label);

                if(nd_else != null) {
                    nd_else.Walk(ec);
                    ec.EmitDiscard();
                }

                ec.MarkLabel(end_label);

                ec.EmitNull();
            }
        }
示例#13
0
 internal override void Walk(EmitContext ec)
 {
     if(ec.Emitting)
         ec.EmitNil();
 }
示例#14
0
 internal override void Walk(EmitContext ec)
 {
     if(ec.Emitting) {
         if(lit is int) {
             ec.EmitRNum((int)lit);
         } else {
             throw new NotSupportedException("bug: literal type not supported: " + lit.GetType().Name);
         }
     }
 }
示例#15
0
        internal override void Walk(EmitContext ec)
        {
            if(ec.Resolving) {
                if(recv != null)
                    recv.Walk(ec);
                if(args != null)
                    args.Walk(ec);
            }
            if(ec.Emitting) {
                RNArray a = (RNArray)args;
                // rcver
                if(recv != null) {
                    recv.Walk(ec);
                } else {
                    ec.EmitSelf();
                }
                // name
                ec.EmitString(mid);
                
                // args
                int len = a != null ? a.alen : 0;
                ec.EmitNewArgArray(len);
                
                EmitArgsArray(ec, a);
                
                // block
                if(block != null) {
                    ec.EmitCreateBlock(block);
                } else {
                    ec.EmitNull();
                }

                ec.EmitSend();
            }
        } 
示例#16
0
 public EmitScope(EmitContext c)
 {
     context = c;
 }
示例#17
0
        internal override void Walk(EmitContext ec)
        {
            if(ec.Resolving)
                if(stts != null)
                    stts.Walk(ec);
            if(ec.Emitting) {
                // rcver
                ec.EmitBlockArg();

                // thread
                ec.EmitLoadThread();

                // args
                RNArray a = stts as RNArray;
                int len = a != null ? a.alen : (stts != null ? 1 : 0);
                ec.EmitNewArgArray(len);
                
                if(a != null) {
                    RNCall.EmitArgsArray(ec, a);
                } else if(stts != null) {
                    RNCall.EmitStoreArg(ec, 0, stts);
                }
                
                // block
                ec.EmitNull();
                
                ec.EmitYield();
            }
        }
示例#18
0
 internal virtual void Walk(EmitContext ec)
 {
     throw new NotSupportedException("bug: Walk not supported: " + this.GetType().Name);
 }
示例#19
0
 EmitScope scope; // New scope for the method
 
 internal static void WalkArg(EmitContext ec, int i, uint vid)
 {
     if(ec.Resolving) {
         Variable v = ec.scope.MarkVariable(vid);
         v.IsArgument = true;
     }
     // Move argument from array to locals, required due to the cache used
     if(ec.Emitting) {
         Variable v = ec.scope.GetVariable(vid);
         ec.EmitLoadArg(i);
         ec.EmitStoreVar(v);
     }
 }
示例#20
0
 internal override void Walk(EmitContext ec)
 {
     // Linear scan of linked list for O(1) stack space
     for(RNode n = this; n != null; ) {
         if(n is RNBlock) {
             RNode current = n.head;
             current.Walk(ec);
             n = n.next;
             if(ec.Emitting && n != null) {
                 // Discard previous result, block returns last value generated    
                 ec.EmitDiscard();
             }
         } else {
             throw new NotSupportedException("bug: not supported block tail: " + n.GetType().Name);
         }
         
     }
 }
示例#21
0
 internal override void Walk(EmitContext ec)
 {
     stts.Walk(ec);
     if(ec.Emitting)
         ec.EmitReturn();
 }
示例#22
0
 internal override void Walk(EmitContext ec)
 {
     if(ec.Emitting) {
         ec.EmitRArray(alen);
     }
     
     int i = 0;
     for(RNode n = this; n != null; ) {
         if(n is RNArray) {
             if(n.head != null) {
                 if(ec.Emitting) {
                     ec.EmitDup();
                     ec.EmitInt(i);
                 }
                 n.head.Walk(ec);
                 if(ec.Emitting) {
                     ec.EmitRArraySet();
                 }
             }
             n = n.next;
             i++;
         } else {
             // n.Walk(ec);
             // break;
             throw new NotSupportedException("bug: array has tail of type " + n.GetType().Name);
         }
     }
 }
示例#23
0
        internal override void Walk(EmitContext ec)
        {
            if(ec.Resolving) {
                cond.Walk(ec);
                body.Walk(ec);
            }
            
            if(ec.Emitting) {
                Label end_label = ec.DefineLabel();
                Label start_label = ec.DefineLabel();
                
                ec.MarkLabel(start_label);
                cond.Walk(ec);

                if(this is RNUntil)
                    ec.EmitBranchIfTrue(end_label);
                else
                    ec.EmitBranchIfFalse(end_label);

                body.Walk(ec);
                // TODO return value in local
                ec.EmitDiscard();
                ec.EmitBranch(start_label);

                ec.MarkLabel(end_label);
                
                ec.EmitNull();
            }
        }
示例#24
0
/*        
        internal object Eval(object self, RNode n)
        {
#if EVAL_DEBUG        
            System.Console.WriteLine("Entering Eval");
#endif        
            object o = null;
            for (RNode node = n; node != null; )
            {
#if EVAL_DEBUG
                System.Console.WriteLine("Node:" + node.GetType());
                RNode prev = node;
#endif

                node = node.Eval(this, self, out o);

#if EVAL_DEBUG        
                System.Console.WriteLine("Leaving Eval(" + prev.ToString() + "), result=" + ((o == null) ? "null" : o.ToString()));
#endif
            }
            return o;
        }
        internal object Eval(object self, string src, RBasic scope, string file, int line)
        {
            RThread th = GetCurrentContext();

            object result = null;
            string filesave = th.file;
            int linesave = th.line;
            ITER itr = th.frame.iter;
            Frame frm = null;
            Scope old_scope = null;
            Block old_block = null;
            RVarmap old_dyna_vars = null;
            Scope.ScopeMode old_vmode = th.ScopeMode;
            RNCRef old_cref = null;
            RModule old_wrapper = null;
            Block data = null;
            if (scope != null)
            {
                if (scope is RProc == false)
                    throw new eTypeError(String.Format("wrong argument type {0} (expected Proc/Binding)",
                                                       ClassOf(scope).Name));
                data = ((RProc)scope).block;
                frm = data.frame;
                frm.tmp = th.frame;
                th.frame = frm;
                old_scope = th.scope;
                old_block = th.block;
                th.block = data.prev;
                old_dyna_vars = th.dyna_vars;
                th.dyna_vars = data.dyna_vars;
                old_vmode = th.ScopeMode;
                old_cref = th.cRef;
                th.cRef = frm.cBase;
                old_wrapper = th.wrapper;
                th.wrapper = data.wrapper;
                if ((file == null || file == String.Empty || (line == 1 && file == "(eval)"))
                    && data.body != null && data.body.File != null)
                {
                    file = data.body.File;
                    line = data.body.Line;
                }
                self = data.self;
                th.frame.iter = data.iter;
            }
            else
            {
                if (th.frame.prev != null)
                {
                    th.frame.iter = th.frame.prev.iter;
                }

            }
            if (file == null)
            {
                file = th.file;
                line = th.line;
            }

            RMetaObject cls = th.rClass;
            th.rClass = th.cBase;

            th.EnterEval();
            if (th.rClass is RIncClass)
                th.rClass = th.rClass.klass;
            Tag.TAG state = Tag.TAG.EMPTY;
            th.PushTag(Tag.TAG.PROT_NONE);
            try
            {
                RNode node = CompileFile(file, new StringReader(src), line, th);
                if (th.CompileFailed)
                {
                    compileError(null);
                }

                result = EvalNode(self, node, th);
            }
            catch (eTagJump tj)
            {
#if _DEBUG
                System.Console.WriteLine(tj.Message);
                System.Console.WriteLine(tj.StackTrace);
#endif
                state = tj.state;
            }
            catch (Exception e)
            {
#if _DEBUG
                System.Console.WriteLine(e.Message);
                System.Console.WriteLine(e.StackTrace);
#endif
                state = Tag.TAG.RAISE;
                th.errInfo = new RException(this, e);
            }
            th.PopTag(true);
            th.rClass = cls;
            th.LeaveEval();
        
            if (th.scope != null)
            {
                th.wrapper = old_wrapper;
                th.cRef = old_cref;
                th.frame = frm.tmp;
                th.scope = old_scope;
                th.block = old_block;
                th.dyna_vars = old_dyna_vars;
                th.ScopeSet(old_vmode);
            }
            else
            {
                th.frame.iter = itr;
            }
            th.file = filesave;
            th.line = linesave;

            if (state != Tag.TAG.EMPTY)
            {
                if (state == Tag.TAG.RAISE)
                {
                    RArray errat = null;
                    string msg = th.errInfo.ToString();
                    string err = msg;
                    if (file == "(eval)")
                    {
                        if (th.line > 1)
                        {
                            errat = th.errInfo.Backtrace;
                            if (errat != null)
                            {
                                err = String.Format("{0}: {1}", errat[0], msg);
                            }
                        }
                        ruby_raise((RException)RException.exc_new(ClassOf(th.errInfo), err));
                    }
                    ruby_raise(th.errInfo);
                }
                th.TagJump(state);
            }
            return result;
        }
        
        public object EvalString(string str)
        {
            bool newThread;
            RThread th = GetCurrentContext(out newThread);

            string oldsrc = th.file;
            th.file = "(eval)";
            object o = Eval(topSelf, str, null, null, 0);
            th.file = oldsrc;
            if (newThread)
            {
                ClearContext(th);
            }
            if (th.errInfo != null)
            {
#if _DEBUG
                if (th.errInfo.InnerException != null)
                    System.Console.Error.WriteLine(th.errInfo.InnerException.StackTrace);
#endif
                throw new NetRubyException(th.errInfo);
            }
            return o;
        }
*/        
        void Start(string filename, bool print)
        {
            StreamReader sr = new StreamReader(File.OpenRead(filename));
            
            RNode n = CompileFile(filename, sr, 0, GetCurrentContext());
           
            if(print) {
                BlockPrinter p = new BlockPrinter(this, Console.Out);
                p.Write(n);
                Console.WriteLine("");
            } else {
                RThread th = GetCurrentContext();
                EmitContext ec = new EmitContext(this, "ruby_program", "ruby.out.dll");
                RCMethod m = ec.Compile(n);
                th.PushClassScope(topSelf.klass);
                m.Call(th, topSelf, new RBasic[] {}, null);
            }
            // Flush the console
            Console.WriteLine("");
        }