From 49660c4e6fea84c9bc3f2c55894b9d463cb500a3 Mon Sep 17 00:00:00 2001 From: David Mak Date: Thu, 21 Sep 2023 16:17:29 +0800 Subject: [PATCH] core: Fix restoration of loop target in try statement I am not sure why this occurs either, it only appears that after the assignment, `old_loop_target` and `loop_target` are both referencing the same variable, causing the next line to set both variables as None. --- nac3core/src/codegen/stmt.rs | 8 ++++-- nac3standalone/demo/src/loop_try_break.py | 33 +++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 nac3standalone/demo/src/loop_try_break.py diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index 7c2c833..e88000a 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -789,7 +789,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>( ctx.outer_catch_clauses = old_clauses; ctx.unwind_target = old_unwind; ctx.return_target = old_return; - ctx.loop_target = old_loop_target; + if let Some(old_loop_target) = old_loop_target { + ctx.loop_target.replace(old_loop_target); + } old_loop_target = None; let old_unwind = if !finalbody.is_empty() { @@ -911,7 +913,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>( } ctx.unwind_target = old_unwind; - ctx.loop_target = old_loop_target; + if let Some(old_loop_target) = old_loop_target { + ctx.loop_target.replace(old_loop_target); + } ctx.return_target = old_return; ctx.builder.position_at_end(landingpad); diff --git a/nac3standalone/demo/src/loop_try_break.py b/nac3standalone/demo/src/loop_try_break.py new file mode 100644 index 0000000..2d49124 --- /dev/null +++ b/nac3standalone/demo/src/loop_try_break.py @@ -0,0 +1,33 @@ +# Break within try statement within a loop +# Taken from https://book.pythontips.com/en/latest/for_-_else.html + +@extern +def output_int32(x: int32, newline: bool=True): + ... + +@extern +def output_float64(x: float, newline: bool=True): + ... + +@extern +def output_str(x: str, newline: bool=True): + ... + +def run() -> int32: + for n in range(2, 10): + for x in range(2, n): + try: + if n % x == 0: + output_int32(n, newline=False) + output_str(" equals ", newline=False) + output_int32(x, newline=False) + output_str(" * ", newline=False) + output_float64(n / x) + except: # Assume this is intended to catch x == 0 + break + else: + # loop fell through without finding a factor + output_int32(n, newline=False) + output_str(" is a prime number") + + return 0 \ No newline at end of file