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