Example #1
0
        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();
        }
Example #2
0
 void ASTVisitor.Accept(NodeEach value)
 {
     Accept(value);
 }
Example #3
0
        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;
        }