4848
4949// TODO need to mangle __attr names
5050
51- #define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_THUMB)
52-
5351typedef enum {
5452 PN_none = 0 ,
5553#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) {
17451743 EMIT_ARG (label_assign , break_label );
17461744}
17471745
1746+ #if !MICROPY_EMIT_CPYTHON
17481747// TODO preload end and step onto stack if they are not constants
17491748// Note that, as per semantics of for .. range, the final failing value should not be stored in the loop variable
17501749// 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
18011800
18021801 EMIT_ARG (label_assign , break_label );
18031802}
1803+ #endif
18041804
18051805void compile_for_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
18061806#if !MICROPY_EMIT_CPYTHON
@@ -2902,11 +2902,10 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) {
29022902 }
29032903}
29042904
2905- 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 ) {
2905+ 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 ) {
29062906 // TODO verify that *k and **k are last etc
29072907 qstr param_name = MP_QSTR_NULL ;
29082908 uint param_flag = ID_FLAG_IS_PARAM ;
2909- mp_parse_node_t pn_annotation = MP_PARSE_NODE_NULL ;
29102909 if (MP_PARSE_NODE_IS_ID (pn )) {
29112910 param_name = MP_PARSE_NODE_LEAF_ARG (pn );
29122911 if (comp -> have_star ) {
@@ -2921,24 +2920,6 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
29212920 mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
29222921 if (MP_PARSE_NODE_STRUCT_KIND (pns ) == pn_name ) {
29232922 param_name = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
2924- //int node_index = 1; unused
2925- if (allow_annotations ) {
2926- if (!MP_PARSE_NODE_IS_NULL (pns -> nodes [1 ])) {
2927- // this parameter has an annotation
2928- pn_annotation = pns -> nodes [1 ];
2929- }
2930- //node_index = 2; unused
2931- }
2932- /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2933- if (!MP_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2934- // this parameter has a default value
2935- if (comp->have_star) {
2936- comp->scope_cur->num_dict_params += 1;
2937- } else {
2938- comp->scope_cur->num_default_params += 1;
2939- }
2940- }
2941- */
29422923 if (comp -> have_star ) {
29432924 // comes after a star, so counts as a keyword-only parameter
29442925 comp -> scope_cur -> num_kwonly_args += 1 ;
@@ -2957,23 +2938,18 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
29572938 // named star
29582939 comp -> scope_cur -> scope_flags |= MP_SCOPE_FLAG_VARARGS ;
29592940 param_name = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
2960- } else if (allow_annotations && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [0 ], PN_tfpdef )) {
2941+ } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [0 ], PN_tfpdef )) {
29612942 // named star with possible annotation
29622943 comp -> scope_cur -> scope_flags |= MP_SCOPE_FLAG_VARARGS ;
29632944 pns = (mp_parse_node_struct_t * )pns -> nodes [0 ];
29642945 param_name = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
2965- pn_annotation = pns -> nodes [1 ];
29662946 } else {
29672947 // shouldn't happen
29682948 assert (0 );
29692949 }
29702950 } else if (MP_PARSE_NODE_STRUCT_KIND (pns ) == pn_dbl_star ) {
29712951 param_name = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
29722952 param_flag = ID_FLAG_IS_PARAM | ID_FLAG_IS_DBL_STAR_PARAM ;
2973- if (allow_annotations && !MP_PARSE_NODE_IS_NULL (pns -> nodes [1 ])) {
2974- // this parameter has an annotation
2975- pn_annotation = pns -> nodes [1 ];
2976- }
29772953 comp -> scope_cur -> scope_flags |= MP_SCOPE_FLAG_VARKEYWORDS ;
29782954 } else {
29792955 // TODO anything to implement?
@@ -2982,9 +2958,6 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
29822958 }
29832959
29842960 if (param_name != MP_QSTR_NULL ) {
2985- if (!MP_PARSE_NODE_IS_NULL (pn_annotation )) {
2986- // TODO this parameter has an annotation
2987- }
29882961 bool added ;
29892962 id_info_t * id_info = scope_find_or_add_id (comp -> scope_cur , param_name , & added );
29902963 if (!added ) {
@@ -2997,11 +2970,58 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
29972970}
29982971
29992972STATIC void compile_scope_func_param (compiler_t * comp , mp_parse_node_t pn ) {
3000- compile_scope_func_lambda_param (comp , pn , PN_typedargslist_name , PN_typedargslist_star , PN_typedargslist_dbl_star , true );
2973+ compile_scope_func_lambda_param (comp , pn , PN_typedargslist_name , PN_typedargslist_star , PN_typedargslist_dbl_star );
30012974}
30022975
30032976STATIC void compile_scope_lambda_param (compiler_t * comp , mp_parse_node_t pn ) {
3004- compile_scope_func_lambda_param (comp , pn , PN_varargslist_name , PN_varargslist_star , PN_varargslist_dbl_star , false);
2977+ compile_scope_func_lambda_param (comp , pn , PN_varargslist_name , PN_varargslist_star , PN_varargslist_dbl_star );
2978+ }
2979+
2980+ STATIC void compile_scope_func_annotations (compiler_t * comp , mp_parse_node_t pn ) {
2981+ if (!MP_PARSE_NODE_IS_STRUCT (pn )) {
2982+ // no annotation
2983+ return ;
2984+ }
2985+
2986+ mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
2987+ if (MP_PARSE_NODE_STRUCT_KIND (pns ) == PN_typedargslist_name ) {
2988+ // named parameter with possible annotation
2989+ // fallthrough
2990+ } else if (MP_PARSE_NODE_STRUCT_KIND (pns ) == PN_typedargslist_star ) {
2991+ if (MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [0 ], PN_tfpdef )) {
2992+ // named star with possible annotation
2993+ pns = (mp_parse_node_struct_t * )pns -> nodes [0 ];
2994+ // fallthrough
2995+ } else {
2996+ // no annotation
2997+ return ;
2998+ }
2999+ } else if (MP_PARSE_NODE_STRUCT_KIND (pns ) == PN_typedargslist_dbl_star ) {
3000+ // double star with possible annotation
3001+ // fallthrough
3002+ } else {
3003+ // no annotation
3004+ return ;
3005+ }
3006+
3007+ mp_parse_node_t pn_annotation = pns -> nodes [1 ];
3008+
3009+ if (!MP_PARSE_NODE_IS_NULL (pn_annotation )) {
3010+ #if MICROPY_EMIT_NATIVE
3011+ qstr param_name = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
3012+ id_info_t * id_info = scope_find (comp -> scope_cur , param_name );
3013+ assert (id_info != NULL );
3014+
3015+ if (comp -> scope_cur -> emit_options == MP_EMIT_OPT_VIPER ) {
3016+ if (MP_PARSE_NODE_IS_ID (pn_annotation )) {
3017+ qstr arg_type = MP_PARSE_NODE_LEAF_ARG (pn_annotation );
3018+ EMIT_ARG (set_native_type , MP_EMIT_NATIVE_TYPE_ARG , id_info -> local_num , arg_type );
3019+ } else {
3020+ compile_syntax_error (comp , pn_annotation , "annotation must be an identifier" );
3021+ }
3022+ }
3023+ #endif // MICROPY_EMIT_NATIVE
3024+ }
30053025}
30063026
30073027STATIC 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) {
31283148 if (comp -> pass == MP_PASS_SCOPE ) {
31293149 comp -> have_star = false;
31303150 apply_to_single_or_list (comp , pns -> nodes [1 ], PN_typedargslist , compile_scope_func_param );
3151+ } else {
3152+ // compile annotations; only needed on latter compiler passes
3153+
3154+ // argument annotations
3155+ apply_to_single_or_list (comp , pns -> nodes [1 ], PN_typedargslist , compile_scope_func_annotations );
3156+
3157+ // pns->nodes[2] is return/whole function annotation
3158+ #if MICROPY_EMIT_NATIVE
3159+ if (scope -> emit_options == MP_EMIT_OPT_VIPER ) {
3160+ // nodes[2] can be null or a test-expr
3161+ if (MP_PARSE_NODE_IS_ID (pns -> nodes [2 ])) {
3162+ qstr ret_type = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [2 ]);
3163+ EMIT_ARG (set_native_type , MP_EMIT_NATIVE_TYPE_RETURN , 0 , ret_type );
3164+ } else {
3165+ compile_syntax_error (comp , pns -> nodes [2 ], "annotation must be an identifier" );
3166+ }
3167+ }
3168+ #endif // MICROPY_EMIT_NATIVE
31313169 }
31323170
3133- // pns->nodes[2] is return/whole function annotation
3134-
31353171 compile_node (comp , pns -> nodes [3 ]); // 3 is function body
31363172 // emit return if it wasn't the last opcode
31373173 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
35893625 comp -> emit_method_table = & emit_native_thumb_method_table ;
35903626#endif
35913627 comp -> emit = emit_native ;
3592- comp -> emit_method_table -> set_native_types (comp -> emit , s -> emit_options == MP_EMIT_OPT_VIPER );
3628+ comp -> emit_method_table -> set_native_type (comp -> emit , MP_EMIT_NATIVE_TYPE_ENABLE , s -> emit_options == MP_EMIT_OPT_VIPER , 0 );
35933629
35943630 // native emitters need an extra pass to compute stack size
35953631 compile_scope (comp , s , MP_PASS_STACK_SIZE );
0 commit comments