summaryrefslogtreecommitdiffstatshomepage
path: root/py/compile.c
diff options
context:
space:
mode:
authorDamien <damien.p.george@gmail.com>2013-10-15 22:25:17 +0100
committerDamien <damien.p.george@gmail.com>2013-10-15 22:25:17 +0100
commitce89a21ea49e51274d016d9601c462312664271e (patch)
treed9ad69657b6ad313c988ce201a42e97d5cd38a39 /py/compile.c
parent5dd455d06dd3cdda7daf496822776b0c8319f02b (diff)
downloadmicropython-ce89a21ea49e51274d016d9601c462312664271e.tar.gz
micropython-ce89a21ea49e51274d016d9601c462312664271e.zip
Implement basic exception framework, and simple for loop.
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/py/compile.c b/py/compile.c
index c1d49102be..0967c855c4 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -16,6 +16,8 @@
// TODO need to mangle __attr names
+#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_THUMB)
+
typedef enum {
PN_none = 0,
#define DEF_RULE(rule, comp, kind, arg...) PN_##rule,
@@ -853,16 +855,19 @@ static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_
}
qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
- if (attr == comp->qstr_native) {
+ if (0) {
+#if MICROPY_EMIT_NATIVE
+ } else if (attr == comp->qstr_native) {
*emit_options = EMIT_OPT_NATIVE_PYTHON;
} else if (attr == comp->qstr_viper) {
*emit_options = EMIT_OPT_VIPER;
+#endif
#if MICROPY_EMIT_INLINE_THUMB
} else if (attr == comp->qstr_asm_thumb) {
*emit_options = EMIT_OPT_ASM_THUMB;
#endif
} else {
- printf("SyntaxError: invalid micropython decorator\n");
+ printf("SyntaxError: invalid micropython decorator '%s'\n", qstr_str(attr));
}
return true;
@@ -1302,15 +1307,16 @@ void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
int old_break_label = comp->break_label;
int old_continue_label = comp->continue_label;
- int done_label = comp_next_label(comp);
- int end_label = comp_next_label(comp);
int break_label = comp_next_label(comp);
int continue_label = comp_next_label(comp);
comp->break_label = break_label;
comp->continue_label = continue_label;
- EMIT(setup_loop, end_label);
+ // compared to CPython, we have an optimised version of while loops
+#if MICROPY_EMIT_CPYTHON
+ int done_label = comp_next_label(comp);
+ EMIT(setup_loop, break_label);
EMIT(label_assign, continue_label);
c_if_cond(comp, pns->nodes[0], false, done_label); // condition
compile_node(comp, pns->nodes[1]); // body
@@ -1318,21 +1324,27 @@ void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
EMIT(jump, continue_label);
}
EMIT(label_assign, done_label);
-
- // break/continue apply to outer loop (if any) in the else block
- comp->break_label = old_break_label;
- comp->continue_label = old_continue_label;
-
// CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
// this is a small hack to agree with CPython
if (!node_is_const_true(pns->nodes[0])) {
EMIT(pop_block);
}
+#else
+ int top_label = comp_next_label(comp);
+ EMIT(jump, continue_label);
+ EMIT(label_assign, top_label);
+ compile_node(comp, pns->nodes[1]); // body
+ EMIT(label_assign, continue_label);
+ c_if_cond(comp, pns->nodes[0], true, top_label); // condition
+#endif
+
+ // break/continue apply to outer loop (if any) in the else block
+ comp->break_label = old_break_label;
+ comp->continue_label = old_continue_label;
compile_node(comp, pns->nodes[2]); // else
EMIT(label_assign, break_label);
- EMIT(label_assign, end_label);
}
void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
@@ -1348,7 +1360,11 @@ void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
comp->continue_label = for_label;
comp->break_label = break_label;
+ // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
+#if MICROPY_EMIT_CPYTHON
EMIT(setup_loop, end_label);
+#endif
+
compile_node(comp, pns->nodes[1]); // iterator
EMIT(get_iter);
EMIT(label_assign, for_label);
@@ -1365,7 +1381,9 @@ void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
comp->break_label = old_break_label;
comp->continue_label = old_continue_label;
+#if MICROPY_EMIT_CPYTHON
EMIT(pop_block);
+#endif
compile_node(comp, pns->nodes[3]); // else (not tested)