diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-10-15 01:46:52 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-10-15 01:46:52 +0300 |
commit | 820f716dd16008eef386f6541fa76dcbac793a9b (patch) | |
tree | 3b356d114edbec5315de43a400d6888ed4137759 /src | |
parent | 43924ddb3059a011760346b5b5c65587d80502e9 (diff) | |
download | sciteco-820f716dd16008eef386f6541fa76dcbac793a9b.tar.gz |
improved support for braces within loops: warn about unclosed braces and allow breaking from within braces
For instance, you can now write <23(1;)> without leaving anything on the stack.
Diffstat (limited to 'src')
-rw-r--r-- | src/core-commands.c | 13 | ||||
-rw-r--r-- | src/parser.h | 4 |
2 files changed, 14 insertions, 3 deletions
diff --git a/src/core-commands.c b/src/core-commands.c index abe5604..a390fa4 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -244,6 +244,7 @@ teco_state_start_loop_open(teco_machine_main_t *ctx, GError **error) if (!teco_expressions_eval(FALSE, error) || !teco_expressions_pop_num_calc(&lctx.counter, -1, error)) return; + lctx.brace_level = teco_brace_level; lctx.pass_through = teco_machine_main_eval_colon(ctx); if (lctx.counter) { @@ -283,6 +284,14 @@ teco_state_start_loop_close(teco_machine_main_t *ctx, GError **error) teco_loop_context_t *lctx = &g_array_index(teco_loop_stack, teco_loop_context_t, teco_loop_stack->len-1); + + /* only non-pass-through loops increase the brace level */ + if (teco_brace_level != lctx->brace_level + !lctx->pass_through) { + g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, + "Brace left open at loop end command"); + return; + } + gboolean colon_modified = teco_machine_main_eval_colon(ctx); /* @@ -351,7 +360,7 @@ teco_state_start_break(teco_machine_main_t *ctx, GError **error) { if (teco_loop_stack->len <= ctx->loop_stack_fp) { g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, - "<;> only allowed in iterations"); + "<;> only allowed in loops"); return; } @@ -376,7 +385,7 @@ teco_state_start_break(teco_machine_main_t *ctx, GError **error) if (!teco_expressions_discard_args(error)) return; if (!lctx.pass_through && - !teco_expressions_brace_close(error)) + !teco_expressions_brace_return(lctx.brace_level, 0, error)) return; undo__insert_val__teco_loop_stack(teco_loop_stack->len, lctx); diff --git a/src/parser.h b/src/parser.h index 3bf9050..29b96b6 100644 --- a/src/parser.h +++ b/src/parser.h @@ -36,7 +36,9 @@ typedef struct { /** how many iterations are left */ teco_int_t counter; /** Program counter of loop start command */ - gsize pc : sizeof(gsize)*8 - 1; + gsize pc; + /** Brace level at loop start */ + guint brace_level : sizeof(guint)*8 - 1; /** * Whether the loop represents an argument * barrier or not (it "passes through" |