@@ -1236,31 +1236,35 @@ void compile_raise_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
12361236 }
12371237}
12381238
1239- // q1 holds the base, q2 the full name
1240- // eg a -> q1=q2 =a
1241- // a.b.c -> q1=a, q2=a.b.c
1242- void do_import_name (compiler_t * comp , mp_parse_node_t pn , qstr * q1 , qstr * q2 ) {
1239+ // q_base holds the base of the name
1240+ // eg a -> q_base =a
1241+ // a.b.c -> q_base=a
1242+ void do_import_name (compiler_t * comp , mp_parse_node_t pn , qstr * q_base ) {
12431243 bool is_as = false;
12441244 if (MP_PARSE_NODE_IS_STRUCT_KIND (pn , PN_dotted_as_name )) {
12451245 mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
12461246 // a name of the form x as y; unwrap it
1247- * q1 = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [1 ]);
1247+ * q_base = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [1 ]);
12481248 pn = pns -> nodes [0 ];
12491249 is_as = true;
12501250 }
1251- if (MP_PARSE_NODE_IS_ID (pn )) {
1251+ if (MP_PARSE_NODE_IS_NULL (pn )) {
1252+ // empty name (eg, from . import x)
1253+ * q_base = MP_QSTR_ ;
1254+ EMIT_ARG (import_name , MP_QSTR_ ); // import the empty string
1255+ } else if (MP_PARSE_NODE_IS_ID (pn )) {
12521256 // just a simple name
1253- * q2 = MP_PARSE_NODE_LEAF_ARG (pn );
1257+ qstr q_full = MP_PARSE_NODE_LEAF_ARG (pn );
12541258 if (!is_as ) {
1255- * q1 = * q2 ;
1259+ * q_base = q_full ;
12561260 }
1257- EMIT_ARG (import_name , * q2 );
1261+ EMIT_ARG (import_name , q_full );
12581262 } else if (MP_PARSE_NODE_IS_STRUCT (pn )) {
12591263 mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
12601264 if (MP_PARSE_NODE_STRUCT_KIND (pns ) == PN_dotted_name ) {
12611265 // a name of the form a.b.c
12621266 if (!is_as ) {
1263- * q1 = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
1267+ * q_base = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
12641268 }
12651269 int n = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
12661270 int len = n - 1 ;
@@ -1278,42 +1282,74 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
12781282 memcpy (str_dest , str_src , str_src_len );
12791283 str_dest += str_src_len ;
12801284 }
1281- * q2 = qstr_build_end (q_ptr );
1282- EMIT_ARG (import_name , * q2 );
1285+ qstr q_full = qstr_build_end (q_ptr );
1286+ EMIT_ARG (import_name , q_full );
12831287 if (is_as ) {
12841288 for (int i = 1 ; i < n ; i ++ ) {
12851289 EMIT_ARG (load_attr , MP_PARSE_NODE_LEAF_ARG (pns -> nodes [i ]));
12861290 }
12871291 }
12881292 } else {
1289- // TODO not implemented
1290- // This covers relative imports starting with dot(s) like "from .foo import"
1291- compile_syntax_error (comp , pn , "Relative imports not implemented" );
1292- return ;
1293+ // shouldn't happen
1294+ assert (0 );
12931295 }
12941296 } else {
1295- // TODO not implemented
1296- // This covers relative imports with dots only like "from .. import"
1297- compile_syntax_error (comp , pn , "Relative imports not implemented" );
1298- return ;
1297+ // shouldn't happen
1298+ assert (0 );
12991299 }
13001300}
13011301
13021302void compile_dotted_as_name (compiler_t * comp , mp_parse_node_t pn ) {
1303- EMIT_ARG (load_const_small_int , 0 ); // ??
1304- EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE );
1305- qstr q1 , q2 ;
1306- do_import_name (comp , pn , & q1 , & q2 );
1307- EMIT_ARG (store_id , q1 );
1303+ EMIT_ARG (load_const_small_int , 0 ); // level 0 import
1304+ EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE ); // not importing from anything
1305+ qstr q_base ;
1306+ do_import_name (comp , pn , & q_base );
1307+ EMIT_ARG (store_id , q_base );
13081308}
13091309
13101310void compile_import_name (compiler_t * comp , mp_parse_node_struct_t * pns ) {
13111311 apply_to_single_or_list (comp , pns -> nodes [0 ], PN_dotted_as_names , compile_dotted_as_name );
13121312}
13131313
13141314void compile_import_from (compiler_t * comp , mp_parse_node_struct_t * pns ) {
1315+ mp_parse_node_t pn_import_source = pns -> nodes [0 ];
1316+
1317+ // extract the preceeding .'s (if any) for a relative import, to compute the import level
1318+ uint import_level = 0 ;
1319+ do {
1320+ mp_parse_node_t pn_rel ;
1321+ if (MP_PARSE_NODE_IS_TOKEN (pn_import_source ) || MP_PARSE_NODE_IS_STRUCT_KIND (pn_import_source , PN_one_or_more_period_or_ellipsis )) {
1322+ // This covers relative imports with dots only like "from .. import"
1323+ pn_rel = pn_import_source ;
1324+ pn_import_source = MP_PARSE_NODE_NULL ;
1325+ } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pn_import_source , PN_import_from_2b )) {
1326+ // This covers relative imports starting with dot(s) like "from .foo import"
1327+ mp_parse_node_struct_t * pns_2b = (mp_parse_node_struct_t * )pn_import_source ;
1328+ pn_rel = pns_2b -> nodes [0 ];
1329+ pn_import_source = pns_2b -> nodes [1 ];
1330+ assert (!MP_PARSE_NODE_IS_NULL (pn_import_source )); // should not be
1331+ } else {
1332+ // Not a relative import
1333+ break ;
1334+ }
1335+
1336+ // get the list of . and/or ...'s
1337+ mp_parse_node_t * nodes ;
1338+ int n = list_get (& pn_rel , PN_one_or_more_period_or_ellipsis , & nodes );
1339+
1340+ // count the total number of .'s
1341+ for (int i = 0 ; i < n ; i ++ ) {
1342+ if (MP_PARSE_NODE_IS_TOKEN_KIND (nodes [i ], MP_TOKEN_DEL_PERIOD )) {
1343+ import_level ++ ;
1344+ } else {
1345+ // should be an MP_TOKEN_ELLIPSIS
1346+ import_level += 3 ;
1347+ }
1348+ }
1349+ } while (0 );
1350+
13151351 if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_STAR )) {
1316- EMIT_ARG (load_const_small_int , 0 ); // level 0 for __import__
1352+ EMIT_ARG (load_const_small_int , import_level );
13171353
13181354 // build the "fromlist" tuple
13191355#if MICROPY_EMIT_CPYTHON
@@ -1324,12 +1360,12 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
13241360#endif
13251361
13261362 // do the import
1327- qstr dummy_q , id1 ;
1328- do_import_name (comp , pns -> nodes [ 0 ] , & dummy_q , & id1 );
1363+ qstr dummy_q ;
1364+ do_import_name (comp , pn_import_source , & dummy_q );
13291365 EMIT (import_star );
13301366
13311367 } else {
1332- EMIT_ARG (load_const_small_int , 0 ); // level 0 for __import__
1368+ EMIT_ARG (load_const_small_int , import_level );
13331369
13341370 // build the "fromlist" tuple
13351371 mp_parse_node_t * pn_nodes ;
@@ -1369,8 +1405,8 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
13691405#endif
13701406
13711407 // do the import
1372- qstr dummy_q , id1 ;
1373- do_import_name (comp , pns -> nodes [ 0 ] , & dummy_q , & id1 );
1408+ qstr dummy_q ;
1409+ do_import_name (comp , pn_import_source , & dummy_q );
13741410 for (int i = 0 ; i < n ; i ++ ) {
13751411 assert (MP_PARSE_NODE_IS_STRUCT_KIND (pn_nodes [i ], PN_import_as_name ));
13761412 mp_parse_node_struct_t * pns3 = (mp_parse_node_struct_t * )pn_nodes [i ];
0 commit comments