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
e337f1ef
Commit
e337f1ef
authored
Mar 31, 2014
by
Damien George
Browse files
py: Towards default keyword arguments.
These are default arguments after a bare *.
parent
1aa2c102
Changes
5
Hide whitespace changes
Inline
Side-by-side
py/compile.c
View file @
e337f1ef
...
...
@@ -776,17 +776,14 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
}
// stuff for lambda and comprehensions and generators
// if we are not in CPython compatibility mode then:
// if n_pos_defaults > 0 then there is a tuple on the stack with the positional defaults
// if n_kw_defaults > 0 then there is a dictionary on the stack with the keyword defaults
// if both exist, the tuple is above the dictionary (ie the first pop gets the tuple)
void
close_over_variables_etc
(
compiler_t
*
comp
,
scope_t
*
this_scope
,
int
n_pos_defaults
,
int
n_kw_defaults
)
{
assert
(
n_pos_defaults
>=
0
);
assert
(
n_kw_defaults
>=
0
);
#if !MICROPY_EMIT_CPYTHON
// in Micro Python we put the default params into a tuple using the bytecode
if
(
n_pos_defaults
)
{
EMIT_ARG
(
build_tuple
,
n_pos_defaults
);
}
#endif
// make closed over variables, if any
// ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython)
int
nfree
=
0
;
...
...
@@ -870,8 +867,19 @@ 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
)
{
#if !MICROPY_EMIT_CPYTHON
// in Micro Python we put the default dict parameters into a dictionary using the bytecode
if
(
comp
->
param_pass_num_dict_params
==
1
)
{
// first default dict param, so make the map
EMIT_ARG
(
build_map
,
0
);
}
#endif
EMIT_ARG
(
load_const_id
,
MP_PARSE_NODE_LEAF_ARG
(
pn_id
));
compile_node
(
comp
,
pn_equal
);
#if !MICROPY_EMIT_CPYTHON
// in Micro Python we put the default dict parameters into a dictionary using the bytecode
EMIT
(
store_map
);
#endif
}
}
else
{
comp
->
param_pass_num_default_params
+=
1
;
...
...
@@ -922,6 +930,13 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
comp
->
param_pass_num_default_params
=
0
;
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
1
],
PN_typedargslist
,
compile_funcdef_param
);
#if !MICROPY_EMIT_CPYTHON
// in Micro Python we put the default positional parameters into a tuple using the bytecode
if
(
comp
->
param_pass_num_default_params
>
0
)
{
EMIT_ARG
(
build_tuple
,
comp
->
param_pass_num_default_params
);
}
#endif
// get the scope for this function
scope_t
*
fscope
=
(
scope_t
*
)
pns
->
nodes
[
4
];
...
...
@@ -3327,7 +3342,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
#else
// return function that executes the outer module
// we can free the unique_code slot because no-one has reference to this unique_code_id anymore
return
mp_make_function_from_id
(
unique_code_id
,
true
,
MP_OBJ_NULL
);
return
mp_make_function_from_id
(
unique_code_id
,
true
,
MP_OBJ_NULL
,
MP_OBJ_NULL
);
#endif
}
}
py/emitbc.c
View file @
e337f1ef
...
...
@@ -732,23 +732,38 @@ STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
}
STATIC
void
emit_bc_make_function
(
emit_t
*
emit
,
scope_t
*
scope
,
uint
n_pos_defaults
,
uint
n_kw_defaults
)
{
assert
(
n_kw_defaults
==
0
);
if
(
n_pos_defaults
==
0
)
{
if
(
n_pos_defaults
==
0
&&
n_kw_defaults
==
0
)
{
emit_bc_pre
(
emit
,
1
);
emit_write_byte_code_byte_uint
(
emit
,
MP_BC_MAKE_FUNCTION
,
scope
->
unique_code_id
);
}
else
{
emit_bc_pre
(
emit
,
0
);
if
(
n_pos_defaults
==
0
)
{
// load dummy entry for non-existent positional default tuple
emit_bc_load_null
(
emit
);
}
else
if
(
n_kw_defaults
==
0
)
{
// load dummy entry for non-existent keyword default dict
emit_bc_load_null
(
emit
);
emit_bc_rot_two
(
emit
);
}
emit_bc_pre
(
emit
,
-
1
);
emit_write_byte_code_byte_uint
(
emit
,
MP_BC_MAKE_FUNCTION_DEFARGS
,
scope
->
unique_code_id
);
}
}
STATIC
void
emit_bc_make_closure
(
emit_t
*
emit
,
scope_t
*
scope
,
uint
n_pos_defaults
,
uint
n_kw_defaults
)
{
assert
(
n_kw_defaults
==
0
);
if
(
n_pos_defaults
==
0
)
{
if
(
n_pos_defaults
==
0
&&
n_kw_defaults
==
0
)
{
emit_bc_pre
(
emit
,
0
);
emit_write_byte_code_byte_uint
(
emit
,
MP_BC_MAKE_CLOSURE
,
scope
->
unique_code_id
);
}
else
{
emit_bc_pre
(
emit
,
-
1
);
if
(
n_pos_defaults
==
0
)
{
// load dummy entry for non-existent positional default tuple
emit_bc_load_null
(
emit
);
emit_bc_rot_two
(
emit
);
}
else
if
(
n_kw_defaults
==
0
)
{
// load dummy entry for non-existent keyword default dict
emit_bc_load_null
(
emit
);
emit_bc_rot_three
(
emit
);
}
emit_bc_pre
(
emit
,
-
2
);
emit_write_byte_code_byte_uint
(
emit
,
MP_BC_MAKE_CLOSURE_DEFARGS
,
scope
->
unique_code_id
);
}
}
...
...
py/emitglue.c
View file @
e337f1ef
...
...
@@ -190,13 +190,16 @@ void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint le
#endif
}
mp_obj_t
mp_make_function_from_id
(
uint
unique_code_id
,
bool
free_unique_code
,
mp_obj_t
def_args
)
{
mp_obj_t
mp_make_function_from_id
(
uint
unique_code_id
,
bool
free_unique_code
,
mp_obj_t
def_args
,
mp_obj_t
def_kw_args
)
{
DEBUG_OP_printf
(
"make_function_from_id %d
\n
"
,
unique_code_id
);
if
(
unique_code_id
>=
unique_codes_total
)
{
// illegal code id
return
mp_const_none
;
}
// TODO implement default kw args
assert
(
def_kw_args
==
MP_OBJ_NULL
);
// make the function, depending on the code kind
mp_code_t
*
c
=
&
unique_codes
[
unique_code_id
];
mp_obj_t
fun
;
...
...
@@ -231,10 +234,10 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp
return
fun
;
}
mp_obj_t
mp_make_closure_from_id
(
uint
unique_code_id
,
mp_obj_t
closure_tuple
,
mp_obj_t
def_args
)
{
mp_obj_t
mp_make_closure_from_id
(
uint
unique_code_id
,
mp_obj_t
closure_tuple
,
mp_obj_t
def_args
,
mp_obj_t
def_kw_args
)
{
DEBUG_OP_printf
(
"make_closure_from_id %d
\n
"
,
unique_code_id
);
// make function object
mp_obj_t
ffun
=
mp_make_function_from_id
(
unique_code_id
,
false
,
def_args
);
mp_obj_t
ffun
=
mp_make_function_from_id
(
unique_code_id
,
false
,
def_args
,
def_kw_args
);
// wrap function in closure object
return
mp_obj_new_closure
(
ffun
,
closure_tuple
);
}
py/runtime.h
View file @
e337f1ef
...
...
@@ -31,11 +31,11 @@ mp_obj_t mp_load_const_bytes(qstr qstr);
mp_obj_t
mp_get_cell
(
mp_obj_t
cell
);
void
mp_set_cell
(
mp_obj_t
cell
,
mp_obj_t
val
);
mp_obj_t
mp_make_function_from_id
(
uint
unique_code_id
,
bool
free_unique_code
,
mp_obj_t
def_args
);
mp_obj_t
mp_make_function_from_id
(
uint
unique_code_id
,
bool
free_unique_code
,
mp_obj_t
def_args
,
mp_obj_t
def_kw_args
);
mp_obj_t
mp_make_function_n
(
int
n_args
,
void
*
fun
);
// fun must have the correct signature for n_args fixed arguments
mp_obj_t
mp_make_function_var
(
int
n_args_min
,
mp_fun_var_t
fun
);
mp_obj_t
mp_make_function_var_between
(
int
n_args_min
,
int
n_args_max
,
mp_fun_var_t
fun
);
// min and max are inclusive
mp_obj_t
mp_make_closure_from_id
(
uint
unique_code_id
,
mp_obj_t
closure_tuple
,
mp_obj_t
def_args
);
mp_obj_t
mp_make_closure_from_id
(
uint
unique_code_id
,
mp_obj_t
closure_tuple
,
mp_obj_t
def_args
,
mp_obj_t
def_kw_args
);
mp_obj_t
mp_call_function_0
(
mp_obj_t
fun
);
mp_obj_t
mp_call_function_1
(
mp_obj_t
fun
,
mp_obj_t
arg
);
...
...
py/vm.c
View file @
e337f1ef
...
...
@@ -648,23 +648,28 @@ unwind_jump:
case
MP_BC_MAKE_FUNCTION
:
DECODE_UINT
;
PUSH
(
mp_make_function_from_id
(
unum
,
false
,
MP_OBJ_NULL
));
PUSH
(
mp_make_function_from_id
(
unum
,
false
,
MP_OBJ_NULL
,
MP_OBJ_NULL
));
break
;
case
MP_BC_MAKE_FUNCTION_DEFARGS
:
DECODE_UINT
;
SET_TOP
(
mp_make_function_from_id
(
unum
,
false
,
TOP
()));
// Stack layout: def_dict def_tuple <- TOS
obj1
=
POP
();
SET_TOP
(
mp_make_function_from_id
(
unum
,
false
,
obj1
,
TOP
()));
break
;
case
MP_BC_MAKE_CLOSURE
:
DECODE_UINT
;
SET_TOP
(
mp_make_closure_from_id
(
unum
,
TOP
(),
MP_OBJ_NULL
));
// Stack layout: closure_tuple <- TOS
SET_TOP
(
mp_make_closure_from_id
(
unum
,
TOP
(),
MP_OBJ_NULL
,
MP_OBJ_NULL
));
break
;
case
MP_BC_MAKE_CLOSURE_DEFARGS
:
DECODE_UINT
;
// Stack layout: def_dict def_tuple closure_tuple <- TOS
obj1
=
POP
();
SET_TOP
(
mp_make_closure_from_id
(
unum
,
obj1
,
TOP
()));
obj2
=
POP
();
SET_TOP
(
mp_make_closure_from_id
(
unum
,
obj1
,
obj2
,
TOP
()));
break
;
case
MP_BC_CALL_FUNCTION
:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment