Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
b979122d
Commit
b979122d
authored
Jan 23, 2014
by
Damien George
Browse files
py: Use C99 way of variable macro arguments.
Addresses Issue #207.
parent
00208ce1
Changes
1
Hide whitespace changes
Inline
Side-by-side
py/compile.c
View file @
b979122d
...
...
@@ -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
);
}