예제 #1
0
        public override void EnterForLoop(FlyParser.ForLoopContext context)
        {
            // TODO: Implement in CodeGenerator
            if (context.var != null)
            {
                var indexer = Code.Instructions.AddString("@f" + for_recursion++);
                Code.Instructions.Add(OpCode.LOAD_I64);
                Code.Instructions.AddInt(0);
                Code.Instructions.Add(OpCode.SET_VAR);
                Code.Instructions.AddInt(indexer);

                var start = Code.Instructions.Count;
                EnterExpression(context.expression());
                Code.Instructions.Add(OpCode.GET_VAR);
                Code.Instructions.AddInt(indexer);
                Code.Instructions.Add(OpCode.SMALLER);

                Code.Instructions.Add(OpCode.JMP_FALSE);      // Jump to the end if expression is false
                var endPos = Code.Instructions.FillableInt(); // Set the end position
                Code.Instructions.StartBlock();               // Start a block for context dependent variables
                EnterExpression(context.expression());
                Code.Instructions.Add(OpCode.GET_VAR);
                Code.Instructions.AddInt(indexer);
                Code.Instructions.Add(OpCode.ARRAY_GET);

                Code.Instructions.Add(OpCode.SET_VAR);
                Code.Instructions.AddInt(Code.Instructions.AddString(context.var.Text));
                foreach (var stmt in context.statement())
                {
                    EnterStatement(stmt);
                }

                Code.Instructions.EndBlock(); // Close the current block

                Code.Instructions.Add(OpCode.GET_VAR);
                Code.Instructions.AddInt(indexer);
                Code.Instructions.Add(OpCode.ADD_I1);

                Code.Instructions.Add(OpCode.SET_VAR);
                Code.Instructions.AddInt(indexer);

                Code.Instructions.Add(OpCode.JMP);
                Code.Instructions.AddInt(start);

                Code.Instructions.FillInt(endPos, Code.Instructions.Count);
            }
            else
            {
                var start = Code.Instructions.Count;
                EnterExpression(context.expression());

                Code.Instructions.Add(OpCode.JMP_FALSE);       // Jump to the end if expression is false
                var endPos = Code.Instructions.FillableInt();  // Set the end position
                Code.Instructions.Add(OpCode.START_LOOP);      // Start a block for context dependent variables
                var endPos2 = Code.Instructions.FillableInt(); // Set the end position

                foreach (var stmt in context.statement())
                {
                    EnterStatement(stmt);
                }

                Code.Instructions.EndBlock(); // Close the current block

                Code.Instructions.Add(OpCode.JMP);
                Code.Instructions.AddInt(start);

                Code.Instructions.FillInt(endPos, Code.Instructions.Count);
                Code.Instructions.FillInt(endPos2, Code.Instructions.Count);
            }
        }
예제 #2
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="FlyParser.forLoop"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitForLoop([NotNull] FlyParser.ForLoopContext context)
 {
 }