summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/compile.c7
-rw-r--r--py/vm.c14
-rw-r--r--tests/basics/break.py13
-rw-r--r--tests/basics/continue.py16
4 files changed, 47 insertions, 3 deletions
diff --git a/py/compile.c b/py/compile.c
index f61c4580c7..2aa98506d1 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1442,24 +1442,27 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
comp->continue_label = continue_label;
int top_label = comp_next_label(comp);
+ int entry_label = comp_next_label(comp);
// compile: var = start
compile_node(comp, pn_start);
c_assign(comp, pn_var, ASSIGN_STORE);
- EMIT(jump, continue_label);
+ EMIT(jump, entry_label);
EMIT(label_assign, top_label);
// compile body
compile_node(comp, pn_body);
+ EMIT(label_assign, continue_label);
+
// compile: var += step
c_assign(comp, pn_var, ASSIGN_AUG_LOAD);
compile_node(comp, pn_step);
EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD);
c_assign(comp, pn_var, ASSIGN_AUG_STORE);
- EMIT(label_assign, continue_label);
+ EMIT(label_assign, entry_label);
// compile: if var <cond> end: goto top
compile_node(comp, pn_var);
diff --git a/py/vm.c b/py/vm.c
index c41146ac8f..b6db0bb87f 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -326,6 +326,18 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
break;
*/
+ // TODO this might need more sophisticated handling when breaking from within an except
+ case MP_BC_BREAK_LOOP:
+ DECODE_ULABEL;
+ ip += unum;
+ break;
+
+ // TODO this might need more sophisticated handling when breaking from within an except
+ case MP_BC_CONTINUE_LOOP:
+ DECODE_ULABEL;
+ ip += unum;
+ break;
+
// matched against: POP_BLOCK or POP_EXCEPT (anything else?)
case MP_BC_SETUP_EXCEPT:
DECODE_ULABEL; // except labels are always forward
@@ -366,7 +378,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
exc_sp -= 2; // pop back to previous exception handler
break;
- // matched againts: SETUP_EXCEPT
+ // matched against: SETUP_EXCEPT
case MP_BC_POP_EXCEPT:
// TODO need to work out how blocks work etc
// pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
diff --git a/tests/basics/break.py b/tests/basics/break.py
new file mode 100644
index 0000000000..c303ea0b3e
--- /dev/null
+++ b/tests/basics/break.py
@@ -0,0 +1,13 @@
+while True:
+ break
+
+for i in range(4):
+ print('one', i)
+ if i > 2:
+ break
+ print('two', i)
+
+for i in [1, 2, 3, 4]:
+ if i == 3:
+ break
+ print(i)
diff --git a/tests/basics/continue.py b/tests/basics/continue.py
new file mode 100644
index 0000000000..6b388d5cae
--- /dev/null
+++ b/tests/basics/continue.py
@@ -0,0 +1,16 @@
+for i in range(4):
+ print('one', i)
+ if i > 2:
+ continue
+ print('two', i)
+
+for i in range(4):
+ print('one', i)
+ if i < 2:
+ continue
+ print('two', i)
+
+for i in [1, 2, 3, 4]:
+ if i == 3:
+ continue
+ print(i)