diff options
Diffstat (limited to 'py/compile.c')
-rw-r--r-- | py/compile.c | 108 |
1 files changed, 72 insertions, 36 deletions
diff --git a/py/compile.c b/py/compile.c index 6ec57adca..eb9cf9a94 100644 --- a/py/compile.c +++ b/py/compile.c @@ -48,8 +48,6 @@ // 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, ...) PN_##rule, @@ -1745,6 +1743,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { EMIT_ARG(label_assign, break_label); } +#if !MICROPY_EMIT_CPYTHON // TODO preload end and step onto stack if they are not constants // Note that, as per semantics of for .. range, the final failing value should not be stored in the loop variable // And, if the loop never runs, the loop variable should never be assigned @@ -1801,6 +1800,7 @@ STATIC void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t p EMIT_ARG(label_assign, break_label); } +#endif void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { #if !MICROPY_EMIT_CPYTHON @@ -2902,11 +2902,10 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { } } -STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star, bool allow_annotations) { +STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star) { // TODO verify that *k and **k are last etc qstr param_name = MP_QSTR_NULL; uint param_flag = ID_FLAG_IS_PARAM; - mp_parse_node_t pn_annotation = MP_PARSE_NODE_NULL; if (MP_PARSE_NODE_IS_ID(pn)) { param_name = MP_PARSE_NODE_LEAF_ARG(pn); if (comp->have_star) { @@ -2921,24 +2920,6 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_name) { param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - //int node_index = 1; unused - if (allow_annotations) { - if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { - // this parameter has an annotation - pn_annotation = pns->nodes[1]; - } - //node_index = 2; unused - } - /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param - if (!MP_PARSE_NODE_IS_NULL(pns->nodes[node_index])) { - // this parameter has a default value - if (comp->have_star) { - comp->scope_cur->num_dict_params += 1; - } else { - comp->scope_cur->num_default_params += 1; - } - } - */ if (comp->have_star) { // comes after a star, so counts as a keyword-only parameter comp->scope_cur->num_kwonly_args += 1; @@ -2957,12 +2938,11 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn // named star comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARARGS; param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - } else if (allow_annotations && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) { // named star with possible annotation comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARARGS; pns = (mp_parse_node_struct_t*)pns->nodes[0]; param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - pn_annotation = pns->nodes[1]; } else { // shouldn't happen assert(0); @@ -2970,10 +2950,6 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) { param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); param_flag = ID_FLAG_IS_PARAM | ID_FLAG_IS_DBL_STAR_PARAM; - if (allow_annotations && !MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { - // this parameter has an annotation - pn_annotation = pns->nodes[1]; - } comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARKEYWORDS; } else { // TODO anything to implement? @@ -2982,9 +2958,6 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn } if (param_name != MP_QSTR_NULL) { - if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) { - // TODO this parameter has an annotation - } bool added; id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added); if (!added) { @@ -2997,11 +2970,58 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn } STATIC void compile_scope_func_param(compiler_t *comp, mp_parse_node_t pn) { - compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true); + compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star); } STATIC void compile_scope_lambda_param(compiler_t *comp, mp_parse_node_t pn) { - compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false); + compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star); +} + +STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn) { + if (!MP_PARSE_NODE_IS_STRUCT(pn)) { + // no annotation + return; + } + + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_name) { + // named parameter with possible annotation + // fallthrough + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_star) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) { + // named star with possible annotation + pns = (mp_parse_node_struct_t*)pns->nodes[0]; + // fallthrough + } else { + // no annotation + return; + } + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star) { + // double star with possible annotation + // fallthrough + } else { + // no annotation + return; + } + + mp_parse_node_t pn_annotation = pns->nodes[1]; + + if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) { + #if MICROPY_EMIT_NATIVE + qstr param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + id_info_t *id_info = scope_find(comp->scope_cur, param_name); + assert(id_info != NULL); + + if (comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER) { + if (MP_PARSE_NODE_IS_ID(pn_annotation)) { + qstr arg_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation); + EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ARG, id_info->local_num, arg_type); + } else { + compile_syntax_error(comp, pn_annotation, "annotation must be an identifier"); + } + } + #endif // MICROPY_EMIT_NATIVE + } } STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_t pn_iter, mp_parse_node_t pn_inner_expr, int l_top, int for_depth) { @@ -3128,10 +3148,26 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { if (comp->pass == MP_PASS_SCOPE) { comp->have_star = false; apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param); + } else { + // compile annotations; only needed on latter compiler passes + + // argument annotations + apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_annotations); + + // pns->nodes[2] is return/whole function annotation + #if MICROPY_EMIT_NATIVE + if (scope->emit_options == MP_EMIT_OPT_VIPER) { + // nodes[2] can be null or a test-expr + if (MP_PARSE_NODE_IS_ID(pns->nodes[2])) { + qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pns->nodes[2]); + EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type); + } else { + compile_syntax_error(comp, pns->nodes[2], "annotation must be an identifier"); + } + } + #endif // MICROPY_EMIT_NATIVE } - // pns->nodes[2] is return/whole function annotation - compile_node(comp, pns->nodes[3]); // 3 is function body // emit return if it wasn't the last opcode if (!EMIT(last_emit_was_return_value)) { @@ -3589,7 +3625,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is comp->emit_method_table = &emit_native_thumb_method_table; #endif comp->emit = emit_native; - comp->emit_method_table->set_native_types(comp->emit, s->emit_options == MP_EMIT_OPT_VIPER); + comp->emit_method_table->set_native_type(comp->emit, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0); // native emitters need an extra pass to compute stack size compile_scope(comp, s, MP_PASS_STACK_SIZE); |