From c4dbe74a100ab355da80953c8c1288889bd41757 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Fri, 25 Mar 2016 22:05:45 +0100 Subject: fixed rubout and reinsertion of the loop end command (>) * the loop counter wasn't properly restored when rubbing out the loop end command, so when it was reinserted again, it would still be 1 (since that's the abortion criteria) and no additional loop iteration was performed. * simple test case: Try typing 5<%a> then rubout and reinsert ">". * Fixed by saving the loop counter before modifying it. There are arguably more efficient ways to do this like only creating one undo token at the end of the loop -- but that would require storing the initial loop counter in the LoopContext and would generally be more tricky. * The case of infinite loops has been optimized in interactive mode: Since the loop counter never actually changes, we do not have to create an undo token per loop iteration. --- src/parser.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/parser.cpp b/src/parser.cpp index 85d455c..f05f167 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1024,9 +1024,18 @@ StateStart::custom(gchar chr) expressions.brace_close(); LoopStack::undo_push(loop_stack.pop()); } else { - /* repeat loop */ + /* + * Repeat loop: + * NOTE: One undo token per iteration could + * be avoided by saving the original counter + * in the LoopContext. + * We do however optimize the case of infinite loops + * because the loop counter does not have to be + * updated. + */ macro_pc = ctx.pc; - ctx.counter = MAX(ctx.counter - 1, -1); + if (ctx.counter >= 0) + undo.push_var(ctx.counter) = ctx.counter - 1; } } break; -- cgit v1.2.3