internal void Accept(NodeEach each) { var isIEach = each.eachIndexName != null; var isResultRequired = each.isResultRequired; if (each.body is NodeBlock) (each.body as NodeBlock).createScope = false; each.body.isResultRequired = isResultRequired; each.body.inTailPosition = each.inTailPosition; builder.StartScope(); uint eachIndexLocal = 0, eachVarLocal; if (isIEach) { if (!builder.AddLocal(each.eachIndexName, out eachIndexLocal)) log.Error(each.location, "Duplicate local variable '{0}'.", each.eachVarName); builder.ReseveLocal(); if (!builder.AddLocal(each.eachVarName, out eachVarLocal)) log.Error(each.location, "Duplicate local variable '{0}'.", each.eachVarName); builder.ReseveLocal(); } else { if (!builder.AddLocal(each.eachVarName, out eachVarLocal)) log.Error(each.location, "Duplicate local variable '{0}'.", each.eachVarName); builder.ReseveLocal(); } each.value.Visit(this); if (isIEach) builder.OpIEachPrep(eachIndexLocal); else builder.OpEachPrep(eachVarLocal); if (isResultRequired) builder.OpList(0); // Handle cont if (isResultRequired) builder.OpJump(builder.InsnCount + 2); builder.StartFlowBlock(each.label); if (isResultRequired) builder.OpPop(false); // END Handle cont uint loopPos; if (isIEach) loopPos = builder.OpIEachLoop(eachIndexLocal, 0); else loopPos = builder.OpEachLoop(eachVarLocal, 0); if (isResultRequired) builder.OpDup(); each.body.Visit(this); if (isResultRequired) { builder.OpOIStore("+"); builder.OpPop(); } builder.OpJump(loopPos); builder.SetOpB(loopPos, builder.InsnCount); // Handle break if (isResultRequired) builder.OpJump(builder.InsnCount + 2); builder.EndFlowBlock(); if (isResultRequired) builder.OpPop(false); // END Handle break builder.EndScope(); }
void ASTVisitor.Accept(NodeEach value) { Accept(value); }
private Node ParseEach() { var loc = Location; Advance(); var each = new NodeEach(loc); if (Check(COLON)) { Advance(); ExpectIdentifier(out each.label, "Expected an identifier for loop label."); } Expect(OPEN_BRACE, "Expected an open brace ('(') to start each initialization."); ExpectIdentifier(out each.eachVarName, "Expected an identifier for each value variable name."); if (Check(COMMA)) { each.eachIndexName = each.eachVarName; Advance(); ExpectIdentifier(out each.eachVarName, "Expected an identifier for each value variable name."); } Expect(IN, "Expected 'in' after each variable declaration to define the enumerator target."); if (TokensRemain) each.value = Expression(); else { log.Error(tokens[-1].location, "Expected expression for each enumerator target, but the end of the file was reached."); return each; } Expect(CLOSE_BRACE, "Expected a close brace (')') to end each initialization."); if (TokensRemain) each.body = Expression(); else log.Error(tokens[-1].location, "Expected expression for each body, but the end of the file was reached."); return each; }