@@ -1236,31 +1236,35 @@ void compile_raise_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1236
1236
}
1237
1237
}
1238
1238
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 ) {
1243
1243
bool is_as = false;
1244
1244
if (MP_PARSE_NODE_IS_STRUCT_KIND (pn , PN_dotted_as_name )) {
1245
1245
mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
1246
1246
// 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 ]);
1248
1248
pn = pns -> nodes [0 ];
1249
1249
is_as = true;
1250
1250
}
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 )) {
1252
1256
// just a simple name
1253
- * q2 = MP_PARSE_NODE_LEAF_ARG (pn );
1257
+ qstr q_full = MP_PARSE_NODE_LEAF_ARG (pn );
1254
1258
if (!is_as ) {
1255
- * q1 = * q2 ;
1259
+ * q_base = q_full ;
1256
1260
}
1257
- EMIT_ARG (import_name , * q2 );
1261
+ EMIT_ARG (import_name , q_full );
1258
1262
} else if (MP_PARSE_NODE_IS_STRUCT (pn )) {
1259
1263
mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
1260
1264
if (MP_PARSE_NODE_STRUCT_KIND (pns ) == PN_dotted_name ) {
1261
1265
// a name of the form a.b.c
1262
1266
if (!is_as ) {
1263
- * q1 = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
1267
+ * q_base = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
1264
1268
}
1265
1269
int n = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
1266
1270
int len = n - 1 ;
@@ -1278,42 +1282,74 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
1278
1282
memcpy (str_dest , str_src , str_src_len );
1279
1283
str_dest += str_src_len ;
1280
1284
}
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 );
1283
1287
if (is_as ) {
1284
1288
for (int i = 1 ; i < n ; i ++ ) {
1285
1289
EMIT_ARG (load_attr , MP_PARSE_NODE_LEAF_ARG (pns -> nodes [i ]));
1286
1290
}
1287
1291
}
1288
1292
} 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 );
1293
1295
}
1294
1296
} 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 );
1299
1299
}
1300
1300
}
1301
1301
1302
1302
void 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 );
1308
1308
}
1309
1309
1310
1310
void compile_import_name (compiler_t * comp , mp_parse_node_struct_t * pns ) {
1311
1311
apply_to_single_or_list (comp , pns -> nodes [0 ], PN_dotted_as_names , compile_dotted_as_name );
1312
1312
}
1313
1313
1314
1314
void 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
+
1315
1351
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 );
1317
1353
1318
1354
// build the "fromlist" tuple
1319
1355
#if MICROPY_EMIT_CPYTHON
@@ -1324,12 +1360,12 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
1324
1360
#endif
1325
1361
1326
1362
// 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 );
1329
1365
EMIT (import_star );
1330
1366
1331
1367
} else {
1332
- EMIT_ARG (load_const_small_int , 0 ); // level 0 for __import__
1368
+ EMIT_ARG (load_const_small_int , import_level );
1333
1369
1334
1370
// build the "fromlist" tuple
1335
1371
mp_parse_node_t * pn_nodes ;
@@ -1369,8 +1405,8 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
1369
1405
#endif
1370
1406
1371
1407
// 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 );
1374
1410
for (int i = 0 ; i < n ; i ++ ) {
1375
1411
assert (MP_PARSE_NODE_IS_STRUCT_KIND (pn_nodes [i ], PN_import_as_name ));
1376
1412
mp_parse_node_struct_t * pns3 = (mp_parse_node_struct_t * )pn_nodes [i ];
0 commit comments