// ( 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++; } }
internal override void Walk(EmitContext ec) { next.Walk(ec); }
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(); }
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); } } }
internal override void Walk(EmitContext ec) { if(ec.Emitting) ec.EmitRString(lit.ToString()); }
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 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) { val.Walk(ec); if(ec.Emitting) { ec.EmitDup(); ec.EmitSetGlobal(ec.id2name(vid)); } }
internal override void Walk(EmitContext ec) { if(ec.Emitting) ec.EmitGetGlobal(ec.id2name(vid)); }
internal override void Walk(EmitContext ec) { body.Walk(ec); if(ec.Emitting) ec.EmitNot(); }
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); } }
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(); } }
internal override void Walk(EmitContext ec) { if(ec.Emitting) ec.EmitNil(); }
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); } } }
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(); } }
public EmitScope(EmitContext c) { context = c; }
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(); } }
internal virtual void Walk(EmitContext ec) { throw new NotSupportedException("bug: Walk not supported: " + this.GetType().Name); }
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); } }
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); } } }
internal override void Walk(EmitContext ec) { stts.Walk(ec); if(ec.Emitting) ec.EmitReturn(); }
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); } } }
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(); } }
/* 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(""); }