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