diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-03-25 22:05:45 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-03-25 22:05:45 +0100 |
commit | c4dbe74a100ab355da80953c8c1288889bd41757 (patch) | |
tree | 64b1f4f4e42dbea641717cbed2fe77c82c1e8945 | |
parent | 39124fd2ad6a3e0bf51d4b7c91fafef6108eacd5 (diff) | |
download | sciteco-c4dbe74a100ab355da80953c8c1288889bd41757.tar.gz |
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.
-rw-r--r-- | src/parser.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
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>(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; |