Commit b979122d authored by Damien George's avatar Damien George
Browse files

py: Use C99 way of variable macro arguments.

Addresses Issue #207.
parent 00208ce1
......@@ -29,8 +29,10 @@ typedef enum {
PN_maximum_number_of,
} pn_kind_t;
#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
#define EMIT_INLINE_ASM(fun, arg...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, ##arg))
#define EMIT(fun) (comp->emit_method_table->fun(comp->emit))
#define EMIT_ARG(fun, ...) (comp->emit_method_table->fun(comp->emit, __VA_ARGS__))
#define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
#define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
#define EMIT_OPT_NONE (0)
#define EMIT_OPT_BYTE_CODE (1)
......@@ -373,7 +375,7 @@ static void cpython_c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_
} else {
vstr_printf(vstr, ")");
}
EMIT(load_const_verbatim_str, vstr_str(vstr));
EMIT_ARG(load_const_verbatim_str, vstr_str(vstr));
vstr_free(vstr);
} else {
if (!MP_PARSE_NODE_IS_NULL(pn)) {
......@@ -382,7 +384,7 @@ static void cpython_c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_
for (int i = 0; i < n; i++) {
compile_node(comp, pns_list->nodes[i]);
}
EMIT(build_tuple, total);
EMIT_ARG(build_tuple, total);
}
}
#endif
......@@ -404,7 +406,7 @@ void c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_struct_t *pns_l
}
total += n;
}
EMIT(build_tuple, total);
EMIT_ARG(build_tuple, total);
#endif
}
......@@ -427,12 +429,12 @@ static bool node_is_const_true(mp_parse_node_t pn) {
static void cpython_c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int label, bool is_nested) {
if (node_is_const_false(pn)) {
if (jump_if == false) {
EMIT(jump, label);
EMIT_ARG(jump, label);
}
return;
} else if (node_is_const_true(pn)) {
if (jump_if == true) {
EMIT(jump, label);
EMIT_ARG(jump, label);
}
return;
} else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
......@@ -445,7 +447,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], true, label2, true);
}
cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
EMIT(label_assign, label2);
EMIT_ARG(label_assign, label2);
} else {
for (int i = 0; i < n; i++) {
cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
......@@ -463,7 +465,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, label2, true);
}
cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
EMIT(label_assign, label2);
EMIT_ARG(label_assign, label2);
}
return;
} else if (!is_nested && MP_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
......@@ -475,9 +477,9 @@ static void cpython_c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if
// nothing special, fall back to default compiling for node and jump
compile_node(comp, pn);
if (jump_if == false) {
EMIT(pop_jump_if_false, label);
EMIT_ARG(pop_jump_if_false, label);
} else {
EMIT(pop_jump_if_true, label);
EMIT_ARG(pop_jump_if_true, label);
}
}
#endif
......@@ -488,12 +490,12 @@ static void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int la
#else
if (node_is_const_false(pn)) {
if (jump_if == false) {
EMIT(jump, label);
EMIT_ARG(jump, label);
}
return;
} else if (node_is_const_true(pn)) {
if (jump_if == true) {
EMIT(jump, label);
EMIT_ARG(jump, label);
}
return;
} else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
......@@ -506,7 +508,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], true, label2);
}
c_if_cond(comp, pns->nodes[n - 1], false, label);
EMIT(label_assign, label2);
EMIT_ARG(label_assign, label2);
} else {
for (int i = 0; i < n; i++) {
c_if_cond(comp, pns->nodes[i], true, label);
......@@ -524,7 +526,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, label2);
}
c_if_cond(comp, pns->nodes[n - 1], true, label);
EMIT(label_assign, label2);
EMIT_ARG(label_assign, label2);
}
return;
} else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
......@@ -536,9 +538,9 @@ static void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int la
// nothing special, fall back to default compiling for node and jump
compile_node(comp, pn);
if (jump_if == false) {
EMIT(pop_jump_if_false, label);
EMIT_ARG(pop_jump_if_false, label);
} else {
EMIT(pop_jump_if_true, label);
EMIT_ARG(pop_jump_if_true, label);
}
#endif
}
......@@ -574,7 +576,7 @@ void c_assign_power(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t
compile_node(comp, pns1->nodes[0]);
if (assign_kind == ASSIGN_AUG_LOAD) {
EMIT(dup_top_two);
EMIT(binary_op, RT_BINARY_OP_SUBSCR);
EMIT_ARG(binary_op, RT_BINARY_OP_SUBSCR);
} else {
EMIT(store_subscr);
}
......@@ -583,12 +585,12 @@ void c_assign_power(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t
assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
if (assign_kind == ASSIGN_AUG_LOAD) {
EMIT(dup_top);
EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
} else {
if (assign_kind == ASSIGN_AUG_STORE) {
EMIT(rot_two);
}
EMIT(store_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
EMIT_ARG(store_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
}
} else {
// shouldn't happen
......@@ -611,7 +613,7 @@ void c_assign_tuple(compiler_t *comp, int n, mp_parse_node_t *nodes) {
for (int i = 0; i < n; i++) {
if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
if (have_star_index < 0) {
EMIT(unpack_ex, i, n - i - 1);
EMIT_ARG(unpack_ex, i, n - i - 1);
have_star_index = i;
} else {
printf("SyntaxError: two starred expressions in assignment\n");
......@@ -620,7 +622,7 @@ void c_assign_tuple(compiler_t *comp, int n, mp_parse_node_t *nodes) {
}
}
if (have_star_index < 0) {
EMIT(unpack_sequence, n);
EMIT_ARG(unpack_sequence, n);
}
for (int i = 0; i < n; i++) {
if (i == have_star_index) {
......@@ -642,10 +644,10 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
switch (assign_kind) {
case ASSIGN_STORE:
case ASSIGN_AUG_STORE:
EMIT(store_id, arg);
EMIT_ARG(store_id, arg);
break;
case ASSIGN_AUG_LOAD:
EMIT(load_id, arg);
EMIT_ARG(load_id, arg);
break;
}
} else {
......@@ -720,7 +722,7 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
// sequence of many items
// TODO call c_assign_tuple instead
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns2);
EMIT(unpack_sequence, 1 + n);
EMIT_ARG(unpack_sequence, 1 + n);
c_assign(comp, pns->nodes[0], ASSIGN_STORE);
for (int i = 0; i < n; i++) {
c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
......@@ -758,10 +760,10 @@ void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_
id_info_t *id2 = &this_scope->id_info[j];
if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
#if MICROPY_EMIT_CPYTHON
EMIT(load_closure, id->qstr, id->local_num);
EMIT_ARG(load_closure, id->qstr, id->local_num);
#else
// in Micro Python we load closures using LOAD_FAST
EMIT(load_fast, id->qstr, id->local_num);
EMIT_ARG(load_fast, id->qstr, id->local_num);
#endif
nfree += 1;
}
......@@ -770,14 +772,14 @@ void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_
}
}
if (nfree > 0) {
EMIT(build_tuple, nfree);
EMIT_ARG(build_tuple, nfree);
}
// make the function/closure
if (nfree == 0) {
EMIT(make_function, this_scope, n_dict_params, n_default_params);
EMIT_ARG(make_function, this_scope, n_dict_params, n_default_params);
} else {
EMIT(make_closure, this_scope, n_dict_params, n_default_params);
EMIT_ARG(make_closure, this_scope, n_dict_params, n_default_params);
}
}
......@@ -790,7 +792,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
if (comp->have_bare_star) {
comp->param_pass_num_dict_params += 1;
if (comp->param_pass == 1) {
EMIT(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
EMIT_ARG(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
compile_node(comp, pns->nodes[2]);
}
} else {
......@@ -872,17 +874,17 @@ qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
close_over_variables_etc(comp, cscope, 0, 0);
// get its name
EMIT(load_const_id, cscope->simple_name);
EMIT_ARG(load_const_id, cscope->simple_name);
// nodes[1] has parent classes, if any
if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
// no parent classes
EMIT(call_function, 2, 0, false, false);
EMIT_ARG(call_function, 2, 0, false, false);
} else {
// have a parent class or classes
// TODO what if we have, eg, *a or **a in the parent list?
compile_node(comp, pns->nodes[1]);
EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
EMIT_ARG(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
}
// return its name (the 'C' in class C(...):")
......@@ -950,7 +952,7 @@ void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_node(comp, name_nodes[0]);
for (int i = 1; i < name_len; i++) {
assert(MP_PARSE_NODE_IS_ID(name_nodes[i])); // should be
EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(name_nodes[i]));
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(name_nodes[i]));
}
// nodes[1] contains arguments to the decorator function, if any
......@@ -975,22 +977,22 @@ void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
// call each decorator
for (int i = 0; i < n - num_built_in_decorators; i++) {
EMIT(call_function, 1, 0, false, false);
EMIT_ARG(call_function, 1, 0, false, false);
}
// store func/class object into name
EMIT(store_id, body_name);
EMIT_ARG(store_id, body_name);
}
void compile_funcdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
// store function object into function name
EMIT(store_id, fname);
EMIT_ARG(store_id, fname);
}
void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
if (MP_PARSE_NODE_IS_ID(pn)) {
EMIT(delete_id, MP_PARSE_NODE_LEAF_ARG(pn));
EMIT_ARG(delete_id, MP_PARSE_NODE_LEAF_ARG(pn));
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
......@@ -1014,7 +1016,7 @@ void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
EMIT(delete_subscr);
} else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
EMIT(delete_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
EMIT_ARG(delete_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
} else {
// shouldn't happen
assert(0);
......@@ -1078,7 +1080,7 @@ void compile_break_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (comp->break_label == 0) {
printf("ERROR: cannot break from here\n");
}
EMIT(break_loop, comp->break_label);
EMIT_ARG(break_loop, comp->break_label);
}
void compile_continue_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
......@@ -1086,9 +1088,9 @@ void compile_continue_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
printf("ERROR: cannot continue from here\n");
}
if (comp->except_nest_level > 0) {
EMIT(continue_loop, comp->continue_label);
EMIT_ARG(continue_loop, comp->continue_label);
} else {
EMIT(jump, comp->continue_label);
EMIT_ARG(jump, comp->continue_label);
}
}
......@@ -1100,7 +1102,7 @@ void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
// no argument to 'return', so return None
EMIT(load_const_tok, MP_TOKEN_KW_NONE);
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
// special case when returning an if-expression; to match CPython optimisation
mp_parse_node_struct_t *pns_test_if_expr = (mp_parse_node_struct_t*)pns->nodes[0];
......@@ -1110,7 +1112,7 @@ void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
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);
EMIT(label_assign, l_fail);
EMIT_ARG(label_assign, l_fail);
compile_node(comp, pns_test_if_else->nodes[1]); // failure value
} else {
compile_node(comp, pns->nodes[0]);
......@@ -1126,17 +1128,17 @@ void compile_yield_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
void compile_raise_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
// raise
EMIT(raise_varargs, 0);
EMIT_ARG(raise_varargs, 0);
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
// raise x from y
pns = (mp_parse_node_struct_t*)pns->nodes[0];
compile_node(comp, pns->nodes[0]);
compile_node(comp, pns->nodes[1]);
EMIT(raise_varargs, 2);
EMIT_ARG(raise_varargs, 2);
} else {
// raise x
compile_node(comp, pns->nodes[0]);
EMIT(raise_varargs, 1);
EMIT_ARG(raise_varargs, 1);
}
}
......@@ -1158,7 +1160,7 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
if (!is_as) {
*q1 = *q2;
}
EMIT(import_name, *q2);
EMIT_ARG(import_name, *q2);
} 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) {
......@@ -1183,10 +1185,10 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
str_dest += str_src_len;
}
*q2 = qstr_build_end(q_ptr);
EMIT(import_name, *q2);
EMIT_ARG(import_name, *q2);
if (is_as) {
for (int i = 1; i < n; i++) {
EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
}
}
} else {
......@@ -1200,11 +1202,11 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
}
void compile_dotted_as_name(compiler_t *comp, mp_parse_node_t pn) {
EMIT(load_const_small_int, 0); // ??
EMIT(load_const_tok, MP_TOKEN_KW_NONE);
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(store_id, q1);
EMIT_ARG(store_id, q1);
}
void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) {
......@@ -1213,14 +1215,14 @@ 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) {
if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) {
EMIT(load_const_small_int, 0); // level 0 for __import__
EMIT_ARG(load_const_small_int, 0); // level 0 for __import__
// build the "fromlist" tuple
#if MICROPY_EMIT_CPYTHON
EMIT(load_const_verbatim_str, "('*',)");
EMIT_ARG(load_const_verbatim_str, "('*',)");
#else
EMIT(load_const_str, QSTR_FROM_STR_STATIC("*"), false);
EMIT(build_tuple, 1);
EMIT_ARG(load_const_str, QSTR_FROM_STR_STATIC("*"), false);
EMIT_ARG(build_tuple, 1);
#endif
// do the import
......@@ -1229,7 +1231,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
EMIT(import_star);
} else {
EMIT(load_const_small_int, 0); // level 0 for __import__
EMIT_ARG(load_const_small_int, 0); // level 0 for __import__
// build the "fromlist" tuple
mp_parse_node_t *pn_nodes;
......@@ -1255,7 +1257,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
vstr_printf(vstr, ",");
}
vstr_printf(vstr, ")");
EMIT(load_const_verbatim_str, vstr_str(vstr));
EMIT_ARG(load_const_verbatim_str, vstr_str(vstr));
vstr_free(vstr);
}
#else
......@@ -1263,9 +1265,9 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
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];
qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
EMIT(load_const_str, id2, false);
EMIT_ARG(load_const_str, id2, false);
}
EMIT(build_tuple, n);
EMIT_ARG(build_tuple, n);
#endif
// do the import
......@@ -1275,11 +1277,11 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
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];
qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
EMIT(import_from, id2);
EMIT_ARG(import_from, id2);
if (MP_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
EMIT(store_id, id2);
EMIT_ARG(store_id, id2);
} else {
EMIT(store_id, MP_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
EMIT_ARG(store_id, MP_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
}
}
EMIT(pop_top);
......@@ -1317,14 +1319,14 @@ 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);
c_if_cond(comp, pns->nodes[0], true, l_end);
EMIT(load_global, MP_QSTR_AssertionError); // we load_global instead of load_id, to be consistent with CPython
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])) {
// assertion message
compile_node(comp, pns->nodes[1]);
EMIT(call_function, 1, 0, false, false);
EMIT_ARG(call_function, 1, 0, false, false);
}
EMIT(raise_varargs, 1);
EMIT(label_assign, l_end);
EMIT_ARG(raise_varargs, 1);
EMIT_ARG(label_assign, l_end);
}
void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
......@@ -1339,10 +1341,10 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
//if (!(MP_PARSE_NODE_IS_NULL(pns->nodes[2]) && MP_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
// jump over elif/else blocks if they exist
if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
EMIT(jump, l_end);
EMIT_ARG(jump, l_end);
}
//}
EMIT(label_assign, l_fail);
EMIT_ARG(label_assign, l_fail);
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
// compile elif blocks
......@@ -1360,9 +1362,9 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_node(comp, pns_elif2->nodes[1]); // elif block
if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
EMIT(jump, l_end);
EMIT_ARG(jump, l_end);
}
EMIT(label_assign, l_fail);
EMIT_ARG(label_assign, l_fail);
}
} else {
......@@ -1373,16 +1375,16 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_node(comp, pns_elif->nodes[1]); // elif block
if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
EMIT(jump, l_end);
EMIT_ARG(jump, l_end);
}
EMIT(label_assign, l_fail);
EMIT_ARG(label_assign, l_fail);
}
}
// compile else block
compile_node(comp, pns->nodes[3]); // can be null
EMIT(label_assign, l_end);
EMIT_ARG(label_assign, l_end);
}
void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
......@@ -1398,14 +1400,14 @@ 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);
EMIT(setup_loop, break_label);
EMIT(label_assign, continue_label);
EMIT_ARG(setup_loop, break_label);
EMIT_ARG(label_assign, continue_label);
c_if_cond(comp, pns->nodes[0], false, done_label); // condition
compile_node(comp, pns->nodes[1]); // body
if (!EMIT(last_emit_was_return_value)) {
EMIT(jump, continue_label);
EMIT_ARG(jump, continue_label);
}
EMIT(label_assign, done_label);
EMIT_ARG(label_assign, done_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])) {
......@@ -1413,10 +1415,10 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
#else
int top_label = comp_next_label(comp);
EMIT(jump, continue_label);
EMIT(label_assign, top_label);
EMIT_ARG(jump, continue_label);
EMIT_ARG(label_assign, top_label);
compile_node(comp, pns->nodes[1]); // body
EMIT(label_assign, continue_label);
EMIT_ARG(label_assign, continue_label);
c_if_cond(comp, pns->nodes[0], true, top_label); // condition
#endif
......@@ -1426,7 +1428,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_node(comp, pns->nodes[2]); // else
EMIT(label_assign, break_label);
EMIT_ARG(label_assign, break_label);
}
// TODO preload end and step onto stack if they are not constants
......@@ -1448,31 +1450,31 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
compile_node(comp, pn_start);
c_assign(comp, pn_var, ASSIGN_STORE);
EMIT(jump, entry_label);
EMIT(label_assign, top_label);
EMIT_ARG(jump, entry_label);
EMIT_ARG(label_assign, top_label);
// compile body
compile_node(comp, pn_body);
EMIT(label_assign, continue_label);
EMIT_ARG(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);
EMIT_ARG(binary_op, RT_BINARY_OP_INPLACE_ADD);
c_assign(comp, pn_var, ASSIGN_AUG_STORE);
EMIT(label_assign, entry_label);
EMIT_ARG(label_assign, entry_label);
// compile: if var <cond> end: goto top
compile_node(comp, pn_var);
compile_node(comp, pn_end);
if (MP_PARSE_NODE_LEAF_ARG(pn_step) >= 0) {
EMIT(binary_op, RT_COMPARE_OP_LESS);
EMIT_ARG(binary_op, RT_COMPARE_OP_LESS);
} else {
EMIT(binary_op, RT_COMPARE_OP_MORE);
EMIT_ARG(binary_op, RT_COMPARE_OP_MORE);
}
EMIT(pop_jump_if_true, top_label);
EMIT_ARG(pop_jump_if_true, top_label);
// break/continue apply to outer loop (if any) in the else block
comp->break_label = old_break_label;
......@@ -1480,7 +1482,7 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
compile_node(comp, pn_else);
EMIT(label_assign, break_label);
EMIT_ARG(label_assign, break_label);
}
void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
......@@ -1543,19 +1545,19 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
#if MICROPY_EMIT_CPYTHON
EMIT(setup_loop, end_label);
EMIT_ARG(setup_loop, end_label);
#endif
compile_node(comp, pns->nodes[1]); // iterator
EMIT(get_iter);
EMIT(label_assign, for_label);
EMIT(for_iter, pop_label);
EMIT_ARG(label_assign, for_label);
EMIT_ARG(for_iter, pop_label);
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
compile_node(comp, pns->nodes[2]); // body
if (!EMIT(last_emit_was_return_value)) {
EMIT(jump, for_label);
EMIT_ARG(jump, for_label);
}
EMIT(label_assign, pop_label);
EMIT_ARG(label_assign, pop_label);
EMIT(for_iter_end);
// break/continue apply to outer loop (if any) in the else block
......@@ -1568,8 +1570,8 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_node(comp, pns->nodes[3]); // else (not tested)
EMIT(label_assign, break_label);
EMIT(label_assign, end_label);
EMIT_ARG(label_assign, break_label);
EMIT_ARG(label_assign, end_label);
}