From 28c43908844cbf27ca74edf3990084abd73e2c96 Mon Sep 17 00:00:00 2001 From: zinc Date: Wed, 14 Oct 2026 19:56:53 +0330 Subject: defer: any single statement (if/else, loops, switch, unchecked, unbounded), not just an expression or a block --- src/compiler/stmt.zc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/stmt.zc b/src/compiler/stmt.zc index a67b931..622d96a 100644 --- a/src/compiler/stmt.zc +++ b/src/compiler/stmt.zc @@ -432,22 +432,26 @@ int kw_continue() { // happen. a defer a branch never reached is not on the stack at an exit on // another path, because the stack only holds the defers read so far in the // blocks still open. the entries of an exit run newest first. +// a block, or an if, while, for, switch, unchecked or unbounded statement, can end +// at a } (blk); either way an else after the end of an if branch belongs to it. word .u defer_tokens() { - int n = 0, depth = 0, blk = is_op(s_lb), semi, bad = 0; word q; + int n = 0, depth = 0, blk = is_op(s_lb), semi, bad = 0, rb; word q; + if (tk == T_ID && (tv == intern("if") || tv == s_while || tv == intern("for") || tv == intern("switch") || tv == s_unchecked || tv == s_unbounded)) blk = 2; while (1) { if (tk == T_EOF) { bad = 1; break; } - semi = 0; + semi = 0; rb = 0; if (tk == T_OP) { if (tv == s_lb || tv == s_lp || tv == s_lk) depth++; - else if (tv == s_rb || tv == s_rp || tv == s_rk) depth--; + else if (tv == s_rb || tv == s_rp || tv == s_rk) { depth--; rb = tv == s_rb; } else if (tv == s_semi && depth == 0) semi = 1; } if (depth < 0) { bad = 1; break; } reserve_R_QBUF((n + 1) * 3); R_QBUF[n * 3] = tk; R_QBUF[n * 3 + 1] = tv; R_QBUF[n * 3 + 2] = tpack(); n++; next(); + if ((semi || (blk && rb && depth == 0)) && blk == 2 && is_id(s_else)) continue; if (semi) break; - if (blk && depth == 0) { accept(s_semi); break; } + if (blk && rb && depth == 0) { if (blk == 1) accept(s_semi); break; } } if (bad) { die("missing ; after the deferred statement"); n = 0; } q = rt.new(n * 3 + 1); -- cgit v1.2.3