summaryrefslogtreecommitdiffstatshomepage
path: root/py/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c247
1 files changed, 156 insertions, 91 deletions
diff --git a/py/compile.c b/py/compile.c
index 3ea6dd3a61..4738c0ae55 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -43,10 +43,10 @@ typedef struct _compiler_t {
uint8_t had_error; // try to keep compiler clean from nlr
uint8_t func_arg_is_super; // used to compile special case of super() function call
- int next_label;
+ uint next_label;
- int break_label;
- int continue_label;
+ uint break_label;
+ uint continue_label;
int break_continue_except_level;
uint16_t cur_except_level; // increased for SETUP_EXCEPT, SETUP_FINALLY; decreased for POP_BLOCK, POP_EXCEPT
@@ -78,6 +78,19 @@ STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const cha
comp->had_error = true;
}
+STATIC const mp_map_elem_t mp_constants_table[] = {
+ // Extra constants as defined by a port
+ MICROPY_EXTRA_CONSTANTS
+};
+
+STATIC const mp_map_t mp_constants_map = {
+ .all_keys_are_qstrs = 1,
+ .table_is_fixed_array = 1,
+ .used = sizeof(mp_constants_table) / sizeof(mp_map_elem_t),
+ .alloc = sizeof(mp_constants_table) / sizeof(mp_map_elem_t),
+ .table = (mp_map_elem_t*)mp_constants_table,
+};
+
mp_parse_node_t fold_constants(mp_parse_node_t pn) {
if (MP_PARSE_NODE_IS_STRUCT(pn)) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
@@ -168,10 +181,12 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
}
break;
-#if MICROPY_EMIT_CPYTHON
case PN_power:
- // can overflow; enabled only to compare with CPython
- if (MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_NULL(pns->nodes[1]) && !MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
+ if (0) {
+#if MICROPY_EMIT_CPYTHON
+ } else if (MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_NULL(pns->nodes[1]) && !MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
+ // int**x
+ // can overflow; enabled only to compare with CPython
mp_parse_node_struct_t* pns2 = (mp_parse_node_struct_t*)pns->nodes[2];
if (MP_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
int power = MP_PARSE_NODE_LEAF_SMALL_INT(pns2->nodes[0]);
@@ -184,9 +199,27 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, ans);
}
}
+#endif
+ } else if (MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_trailer_period) && MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
+ // id.id
+ // look it up in constant table, see if it can be replaced with an integer
+ mp_parse_node_struct_t* pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
+ assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
+ qstr q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
+ qstr q_attr = MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]);
+ mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&mp_constants_map, MP_OBJ_NEW_QSTR(q_base), MP_MAP_LOOKUP);
+ if (elem != NULL) {
+ mp_obj_t dest[2];
+ mp_load_method_maybe(elem->value, q_attr, dest);
+ if (MP_OBJ_IS_SMALL_INT(dest[0]) && dest[1] == NULL) {
+ machine_int_t val = MP_OBJ_SMALL_INT_VALUE(dest[0]);
+ if (MP_PARSE_FITS_SMALL_INT(val)) {
+ pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, val);
+ }
+ }
+ }
}
break;
-#endif
}
}
@@ -196,7 +229,7 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_arglist, bool is_method_call, int n_positional_extra);
STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn);
-STATIC int comp_next_label(compiler_t *comp) {
+STATIC uint comp_next_label(compiler_t *comp) {
return comp->next_label++;
}
@@ -467,7 +500,7 @@ STATIC void cpython_c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
if (jump_if == false) {
- int label2 = comp_next_label(comp);
+ uint label2 = comp_next_label(comp);
for (int i = 0; i < n - 1; i++) {
cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
}
@@ -485,7 +518,7 @@ STATIC void cpython_c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if
cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
}
} else {
- int label2 = comp_next_label(comp);
+ uint label2 = comp_next_label(comp);
for (int i = 0; i < n - 1; i++) {
cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
}
@@ -528,7 +561,7 @@ STATIC void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int la
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
if (jump_if == false) {
- int label2 = comp_next_label(comp);
+ uint label2 = comp_next_label(comp);
for (int i = 0; i < n - 1; i++) {
c_if_cond(comp, pns->nodes[i], true, label2);
}
@@ -546,7 +579,7 @@ STATIC void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int la
c_if_cond(comp, pns->nodes[i], false, label);
}
} else {
- int label2 = comp_next_label(comp);
+ uint label2 = comp_next_label(comp);
for (int i = 0; i < n - 1; i++) {
c_if_cond(comp, pns->nodes[i], false, label2);
}
@@ -1202,7 +1235,7 @@ void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
mp_parse_node_struct_t *pns_test_if_expr = (mp_parse_node_struct_t*)pns->nodes[0];
mp_parse_node_struct_t *pns_test_if_else = (mp_parse_node_struct_t*)pns_test_if_expr->nodes[1];
- int l_fail = comp_next_label(comp);
+ uint l_fail = comp_next_label(comp);
c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
compile_node(comp, pns_test_if_expr->nodes[0]); // success value
EMIT(return_value);
@@ -1236,31 +1269,35 @@ void compile_raise_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
}
-// q1 holds the base, q2 the full name
-// eg a -> q1=q2=a
-// a.b.c -> q1=a, q2=a.b.c
-void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
+// q_base holds the base of the name
+// eg a -> q_base=a
+// a.b.c -> q_base=a
+void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
bool is_as = false;
if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
// a name of the form x as y; unwrap it
- *q1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
+ *q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
pn = pns->nodes[0];
is_as = true;
}
- if (MP_PARSE_NODE_IS_ID(pn)) {
+ if (MP_PARSE_NODE_IS_NULL(pn)) {
+ // empty name (eg, from . import x)
+ *q_base = MP_QSTR_;
+ EMIT_ARG(import_name, MP_QSTR_); // import the empty string
+ } else if (MP_PARSE_NODE_IS_ID(pn)) {
// just a simple name
- *q2 = MP_PARSE_NODE_LEAF_ARG(pn);
+ qstr q_full = MP_PARSE_NODE_LEAF_ARG(pn);
if (!is_as) {
- *q1 = *q2;
+ *q_base = q_full;
}
- EMIT_ARG(import_name, *q2);
+ EMIT_ARG(import_name, q_full);
} else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
// a name of the form a.b.c
if (!is_as) {
- *q1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
+ *q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
}
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
int len = n - 1;
@@ -1278,33 +1315,29 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
memcpy(str_dest, str_src, str_src_len);
str_dest += str_src_len;
}
- *q2 = qstr_build_end(q_ptr);
- EMIT_ARG(import_name, *q2);
+ qstr q_full = qstr_build_end(q_ptr);
+ EMIT_ARG(import_name, q_full);
if (is_as) {
for (int i = 1; i < n; i++) {
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
}
}
} else {
- // TODO not implemented
- // This covers relative imports starting with dot(s) like "from .foo import"
- compile_syntax_error(comp, pn, "Relative imports not implemented");
- return;
+ // shouldn't happen
+ assert(0);
}
} else {
- // TODO not implemented
- // This covers relative imports with dots only like "from .. import"
- compile_syntax_error(comp, pn, "Relative imports not implemented");
- return;
+ // shouldn't happen
+ assert(0);
}
}
void compile_dotted_as_name(compiler_t *comp, mp_parse_node_t pn) {
- EMIT_ARG(load_const_small_int, 0); // ??
- EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
- qstr q1, q2;
- do_import_name(comp, pn, &q1, &q2);
- EMIT_ARG(store_id, q1);
+ EMIT_ARG(load_const_small_int, 0); // level 0 import
+ EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); // not importing from anything
+ qstr q_base;
+ do_import_name(comp, pn, &q_base);
+ EMIT_ARG(store_id, q_base);
}
void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) {
@@ -1312,8 +1345,44 @@ void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ mp_parse_node_t pn_import_source = pns->nodes[0];
+
+ // extract the preceeding .'s (if any) for a relative import, to compute the import level
+ uint import_level = 0;
+ do {
+ mp_parse_node_t pn_rel;
+ if (MP_PARSE_NODE_IS_TOKEN(pn_import_source) || MP_PARSE_NODE_IS_STRUCT_KIND(pn_import_source, PN_one_or_more_period_or_ellipsis)) {
+ // This covers relative imports with dots only like "from .. import"
+ pn_rel = pn_import_source;
+ pn_import_source = MP_PARSE_NODE_NULL;
+ } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_import_source, PN_import_from_2b)) {
+ // This covers relative imports starting with dot(s) like "from .foo import"
+ mp_parse_node_struct_t *pns_2b = (mp_parse_node_struct_t*)pn_import_source;
+ pn_rel = pns_2b->nodes[0];
+ pn_import_source = pns_2b->nodes[1];
+ assert(!MP_PARSE_NODE_IS_NULL(pn_import_source)); // should not be
+ } else {
+ // Not a relative import
+ break;
+ }
+
+ // get the list of . and/or ...'s
+ mp_parse_node_t *nodes;
+ int n = list_get(&pn_rel, PN_one_or_more_period_or_ellipsis, &nodes);
+
+ // count the total number of .'s
+ for (int i = 0; i < n; i++) {
+ if (MP_PARSE_NODE_IS_TOKEN_KIND(nodes[i], MP_TOKEN_DEL_PERIOD)) {
+ import_level++;
+ } else {
+ // should be an MP_TOKEN_ELLIPSIS
+ import_level += 3;
+ }
+ }
+ } while (0);
+
if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) {
- EMIT_ARG(load_const_small_int, 0); // level 0 for __import__
+ EMIT_ARG(load_const_small_int, import_level);
// build the "fromlist" tuple
#if MICROPY_EMIT_CPYTHON
@@ -1324,12 +1393,12 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
#endif
// do the import
- qstr dummy_q, id1;
- do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
+ qstr dummy_q;
+ do_import_name(comp, pn_import_source, &dummy_q);
EMIT(import_star);
} else {
- EMIT_ARG(load_const_small_int, 0); // level 0 for __import__
+ EMIT_ARG(load_const_small_int, import_level);
// build the "fromlist" tuple
mp_parse_node_t *pn_nodes;
@@ -1369,8 +1438,8 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
#endif
// do the import
- qstr dummy_q, id1;
- do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
+ qstr dummy_q;
+ do_import_name(comp, pn_import_source, &dummy_q);
for (int i = 0; i < n; i++) {
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pn_nodes[i];
@@ -1415,7 +1484,7 @@ void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
- int l_end = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
c_if_cond(comp, pns->nodes[0], true, l_end);
EMIT_ARG(load_global, MP_QSTR_AssertionError); // we load_global instead of load_id, to be consistent with CPython
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
@@ -1430,9 +1499,9 @@ void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// TODO proper and/or short circuiting
- int l_end = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
- int l_fail = comp_next_label(comp);
+ uint l_fail = comp_next_label(comp);
c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
compile_node(comp, pns->nodes[1]); // if block
@@ -1493,10 +1562,10 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
#define START_BREAK_CONTINUE_BLOCK \
- int old_break_label = comp->break_label; \
- int old_continue_label = comp->continue_label; \
- int break_label = comp_next_label(comp); \
- int continue_label = comp_next_label(comp); \
+ uint old_break_label = comp->break_label; \
+ uint old_continue_label = comp->continue_label; \
+ uint break_label = comp_next_label(comp); \
+ uint continue_label = comp_next_label(comp); \
comp->break_label = break_label; \
comp->continue_label = continue_label; \
comp->break_continue_except_level = comp->cur_except_level;
@@ -1511,7 +1580,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// compared to CPython, we have an optimised version of while loops
#if MICROPY_EMIT_CPYTHON
- int done_label = comp_next_label(comp);
+ uint done_label = comp_next_label(comp);
EMIT_ARG(setup_loop, break_label);
EMIT_ARG(label_assign, continue_label);
c_if_cond(comp, pns->nodes[0], false, done_label); // condition
@@ -1526,7 +1595,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
EMIT(pop_block);
}
#else
- int top_label = comp_next_label(comp);
+ uint top_label = comp_next_label(comp);
EMIT_ARG(jump, continue_label);
EMIT_ARG(label_assign, top_label);
compile_node(comp, pns->nodes[1]); // body
@@ -1548,8 +1617,8 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, mp_parse_node_t pn_start, mp_parse_node_t pn_end, mp_parse_node_t pn_step, mp_parse_node_t pn_body, mp_parse_node_t pn_else) {
START_BREAK_CONTINUE_BLOCK
- int top_label = comp_next_label(comp);
- int entry_label = comp_next_label(comp);
+ uint top_label = comp_next_label(comp);
+ uint entry_label = comp_next_label(comp);
// compile: start, duplicated on stack
compile_node(comp, pn_start);
@@ -1559,7 +1628,7 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
EMIT_ARG(label_assign, top_label);
// at this point we actually have 1 less element on the stack
- EMIT_ARG(set_stack_size, EMIT(get_stack_size) - 1);
+ EMIT_ARG(adjust_stack_size, -1);
// store next value to var
c_assign(comp, pn_var, ASSIGN_STORE);
@@ -1646,8 +1715,8 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
START_BREAK_CONTINUE_BLOCK
- int pop_label = comp_next_label(comp);
- int end_label = comp_next_label(comp);
+ uint pop_label = comp_next_label(comp);
+ uint end_label = comp_next_label(comp);
// I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
#if MICROPY_EMIT_CPYTHON
@@ -1680,29 +1749,28 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_excepts, mp_parse_node_t pn_else) {
- // this function is a bit of a hack at the moment
- // don't understand how the stack works with exceptions, so we force it to return to the correct value
-
// setup code
- int stack_size = EMIT(get_stack_size);
- int l1 = comp_next_label(comp);
- int success_label = comp_next_label(comp);
+ uint l1 = comp_next_label(comp);
+ uint success_label = comp_next_label(comp);
EMIT_ARG(setup_except, l1);
compile_increase_except_level(comp);
compile_node(comp, pn_body); // body
EMIT(pop_block);
- EMIT_ARG(jump, success_label);
- EMIT_ARG(label_assign, l1);
- int l2 = comp_next_label(comp);
+ EMIT_ARG(jump, success_label); // jump over exception handler
+
+ EMIT_ARG(label_assign, l1); // start of exception handler
+ EMIT_ARG(adjust_stack_size, 6); // stack adjust for the 3 exception items, +3 for possible UNWIND_JUMP state
+
+ uint l2 = comp_next_label(comp);
for (int i = 0; i < n_except; i++) {
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
mp_parse_node_struct_t *pns_except = (mp_parse_node_struct_t*)pn_excepts[i];
qstr qstr_exception_local = 0;
- int end_finally_label = comp_next_label(comp);
+ uint end_finally_label = comp_next_label(comp);
if (MP_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
// this is a catch all exception handler
@@ -1737,7 +1805,7 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
EMIT(pop_top);
- int l3 = 0;
+ uint l3 = 0;
if (qstr_exception_local != 0) {
l3 = comp_next_label(comp);
EMIT_ARG(setup_finally, l3);
@@ -1760,28 +1828,29 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
}
EMIT_ARG(jump, l2);
EMIT_ARG(label_assign, end_finally_label);
+ EMIT_ARG(adjust_stack_size, 3); // stack adjust for the 3 exception items
}
compile_decrease_except_level(comp);
EMIT(end_finally);
+ EMIT_ARG(adjust_stack_size, -5); // stack adjust
EMIT_ARG(label_assign, success_label);
compile_node(comp, pn_else); // else block, can be null
EMIT_ARG(label_assign, l2);
- EMIT_ARG(set_stack_size, stack_size);
}
void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_except, mp_parse_node_t pn_else, mp_parse_node_t pn_finally) {
- // don't understand how the stack works with exceptions, so we force it to return to the correct value
- int stack_size = EMIT(get_stack_size);
- int l_finally_block = comp_next_label(comp);
+ uint l_finally_block = comp_next_label(comp);
EMIT_ARG(setup_finally, l_finally_block);
compile_increase_except_level(comp);
if (n_except == 0) {
assert(MP_PARSE_NODE_IS_NULL(pn_else));
+ EMIT_ARG(adjust_stack_size, 3); // stack adjust for possible UNWIND_JUMP state
compile_node(comp, pn_body);
+ EMIT_ARG(adjust_stack_size, -3);
} else {
compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
}
@@ -1792,8 +1861,6 @@ void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except
compile_decrease_except_level(comp);
EMIT(end_finally);
-
- EMIT_ARG(set_stack_size, stack_size);
}
void compile_try_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
@@ -1830,7 +1897,7 @@ void compile_with_stmt_helper(compiler_t *comp, int n, mp_parse_node_t *nodes, m
// no more pre-bits, compile the body of the with
compile_node(comp, body);
} else {
- int l_end = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
// this pre-bit is of the form "a as b"
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)nodes[0];
@@ -1987,14 +2054,13 @@ void compile_test_if_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
mp_parse_node_struct_t *pns_test_if_else = (mp_parse_node_struct_t*)pns->nodes[1];
- int stack_size = EMIT(get_stack_size);
- int l_fail = comp_next_label(comp);
- int l_end = comp_next_label(comp);
+ uint l_fail = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
compile_node(comp, pns->nodes[0]); // success value
EMIT_ARG(jump, l_end);
EMIT_ARG(label_assign, l_fail);
- EMIT_ARG(set_stack_size, stack_size); // force stack size reset
+ EMIT_ARG(adjust_stack_size, -1); // adjust stack size
compile_node(comp, pns_test_if_else->nodes[1]); // failure value
EMIT_ARG(label_assign, l_end);
}
@@ -2019,7 +2085,7 @@ void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
void compile_or_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
- int l_end = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
for (int i = 0; i < n; i += 1) {
compile_node(comp, pns->nodes[i]);
@@ -2031,7 +2097,7 @@ void compile_or_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
void compile_and_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
- int l_end = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
for (int i = 0; i < n; i += 1) {
compile_node(comp, pns->nodes[i]);
@@ -2048,11 +2114,10 @@ void compile_not_test_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
- int stack_size = EMIT(get_stack_size);
int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
compile_node(comp, pns->nodes[0]);
bool multi = (num_nodes > 3);
- int l_fail = 0;
+ uint l_fail = 0;
if (multi) {
l_fail = comp_next_label(comp);
}
@@ -2099,13 +2164,13 @@ void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
}
if (multi) {
- int l_end = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
EMIT_ARG(jump, l_end);
EMIT_ARG(label_assign, l_fail);
+ EMIT_ARG(adjust_stack_size, 1);
EMIT(rot_two);
EMIT(pop_top);
EMIT_ARG(label_assign, l_end);
- EMIT_ARG(set_stack_size, stack_size + 1); // force stack size
}
}
@@ -2799,8 +2864,8 @@ void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_t pn_iter, mp_parse
// for loop
mp_parse_node_struct_t *pns_comp_for2 = (mp_parse_node_struct_t*)pn_iter;
compile_node(comp, pns_comp_for2->nodes[1]);
- int l_end2 = comp_next_label(comp);
- int l_top2 = comp_next_label(comp);
+ uint l_end2 = comp_next_label(comp);
+ uint l_top2 = comp_next_label(comp);
EMIT(get_iter);
EMIT_ARG(label_assign, l_top2);
EMIT_ARG(for_iter, l_end2);
@@ -2946,8 +3011,8 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
EMIT_ARG(build_set, 0);
}
- int l_end = comp_next_label(comp);
- int l_top = comp_next_label(comp);
+ uint l_end = comp_next_label(comp);
+ uint l_top = comp_next_label(comp);
EMIT_ARG(load_id, qstr_arg);
EMIT_ARG(label_assign, l_top);
EMIT_ARG(for_iter, l_end);
@@ -3066,7 +3131,7 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
compile_syntax_error(comp, nodes[i], "inline assembler 'label' requires 1 argument");
return;
}
- int lab = comp_next_label(comp);
+ uint lab = comp_next_label(comp);
if (pass > PASS_1) {
EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]));
}