8000 py: add skeletal import functionality. · comfuture/micropython@db4c361 · GitHub
[go: up one dir, main page]

Skip to content

Commit db4c361

Browse files
committed
py: add skeletal import functionality.
1 parent 261dbf8 commit db4c361

File tree

5 files changed

+93
-21
lines changed

5 files changed

+93
-21
lines changed

py/bc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@
9090
#define PYBC_CALL_METHOD_KW (0x98) // uint
9191
#define PYBC_CALL_METHOD_VAR_KW (0x99) // uint
9292

93-
#define PYBC_IMPORT_NAME (0xe0)
94-
#define PYBC_IMPORT_FROM (0xe1)
95-
#define PYBC_IMPORT_STAR (0xe2)
93+
#define PYBC_IMPORT_NAME (0xe0) // qstr
94+
#define PYBC_IMPORT_FROM (0xe1) // qstr
95+
#define PYBC_IMPORT_STAR (0xe2)
9696

9797
py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_args, uint n_state);
9898
bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **sp_in_out);

py/compile.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,18 +1168,30 @@ void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
11681168

11691169
void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
11701170
if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
1171-
EMIT(load_const_small_int, 0); // what's this for??
1171+
EMIT(load_const_small_int, 0); // level 0 for __import__
1172+
1173+
// build the "fromlist" tuple
1174+
#if MICROPY_EMIT_CPYTHON
11721175
EMIT(load_const_verbatim_start);
11731176
EMIT(load_const_verbatim_str, "('*',)");
11741177
EMIT(load_const_verbatim_end);
1178+
#else
1179+
EMIT(load_const_str, qstr_from_str_static("*"), false);
1180+
EMIT(build_tuple, 1);
1181+
#endif
1182+
1183+
// do the import
11751184
qstr dummy_q, id1;
11761185
do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
11771186
EMIT(import_star);
1187+
11781188
} else {
1189+
EMIT(load_const_small_int, 0); // level 0 for __import__
1190+
1191+
// build the "fromlist" tuple
11791192
py_parse_node_t *pn_nodes;
11801193
int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1181-
1182-
EMIT(load_const_small_int, 0); // what's this for??
1194+
#if MICROPY_EMIT_CPYTHON
11831195
EMIT(load_const_verbatim_start);
11841196
EMIT(load_const_verbatim_str, "(");
11851197
for (int i = 0; i < n; i++) {
@@ -1198,6 +1210,17 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
11981210
}
11991211
EMIT(load_const_verbatim_str, ")");
12001212
EMIT(load_const_verbatim_end);
1213+
#else
1214+
for (int i = 0; i < n; i++) {
1215+
assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1216+
py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1217+
qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1218+
EMIT(load_const_str, id2, false);
1219+
}
1220+
EMIT(build_tuple, n);
1221+
#endif
1222+
1223+
// do the import
12011224
qstr dummy_q, id1;
12021225
do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
12031226
for (int i = 0; i < n; i++) {

py/runtime.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,39 @@ py_obj_t rt_iternext(py_obj_t o_in) {
22162216
}
22172217
}
22182218

2219+
py_obj_t py_builtin___import__(int n, py_obj_t *args) {
2220+
printf("import:\n");
2221+
for (int i = 0; i < n; i++) {
2222+
printf(" ");
2223+
py_obj_print(args[i]);
2224+
printf("\n");
2225+
}
2226+
return py_const_none;
2227+
}
2228+
2229+
py_obj_t rt_import_name(qstr name, py_obj_t fromlist, py_obj_t level) {
2230+
// build args array
2231+
py_obj_t args[5];
2232+
args[0] = py_obj_new_str(name);
2233+
args[1] = py_const_none; // TODO should be globals
2234+
args[2] = py_const_none; // TODO should be locals
2235+
args[3] = fromlist;
2236+
args[4] = level; // must be 0; we don't yet support other values
2237+
2238+
// TODO lookup __import__ and call that instead of going straight to builtin implementation
2239+
return py_builtin___import__(5, args);
2240+
}
2241+
2242+
py_obj_t rt_import_from(py_obj_t module, qstr name) {
2243+
py_obj_t x = rt_load_attr(module, name);
2244+
/* TODO convert AttributeError to ImportError
2245+
if (fail) {
2246+
(ImportError, "cannot import name %s", qstr_str(name), NULL)
2247+
}
2248+
*/
2249+
return x;
2250+
}
2251+
22192252
// these must correspond to the respective enum
22202253
void *const rt_fun_table[RT_F_NUMBER_OF] = {
22212254
rt_load_const_dec,

py/runtime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ void rt_store_attr(py_obj_t base, qstr attr, py_obj_t val);
145145
void rt_store_subscr(py_obj_t base, py_obj_t index, py_obj_t val);
146146
py_obj_t rt_getiter(py_obj_t o);
147147
py_obj_t rt_iternext(py_obj_t o);
148+
py_obj_t rt_import_name(qstr name, py_obj_t fromlist, py_obj_t level);
149+
py_obj_t rt_import_from(py_obj_t module, qstr name);
148150

149151
// temporary way of making C modules
150152
py_obj_t py_module_new(void);

py/vm.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define DECODE_QSTR do { qstr = *ip++; if (qstr > 127) { qstr = ((qstr & 0x3f) << 8) | (*ip++); } } while (0)
2020
#define PUSH(val) *--sp = (val)
2121
#define POP() (*sp++)
22+
#define TOP() (*sp)
23+
#define SET_TOP(val) *sp = (val)
2224

2325
// args are in reverse order in array
2426
py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_args, uint n_state) {
@@ -130,7 +132,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
130132

131133
case PYBC_LOAD_ATTR:
132134
DECODE_QSTR;
133-
*sp = rt_load_attr(*sp, qstr);
135+
SET_TOP(rt_load_attr(TOP(), qstr));
134136
break;
135137

136138
case PYBC_LOAD_METHOD:
@@ -182,7 +184,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
182184
break;
183185

184186
case PYBC_DUP_TOP:
185-
obj1 = *sp;
187+
obj1 = TOP();
186188
PUSH(obj1);
187189
break;
188190

@@ -230,7 +232,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
230232

231233
case PYBC_JUMP_IF_TRUE_OR_POP:
232234
DECODE_SLABEL;
233-
if (rt_is_true(*sp)) {
235+
if (rt_is_true(TOP())) {
234236
ip += unum;
235237
} else {
236238
sp++;
@@ -239,7 +241,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
239241

240242
case PYBC_JUMP_IF_FALSE_OR_POP:
241243
DECODE_SLABEL;
242-
if (rt_is_true(*sp)) {
244+
if (rt_is_true(TOP())) {
243245
sp++;
244246
} else {
245247
ip += unum;
@@ -269,12 +271,12 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
269271
break;
270272

271273
case PYBC_GET_ITER:
272-
*sp = rt_getiter(*sp);
274+
SET_TOP(rt_getiter(TOP()));
273275
break;
274276

275277
case PYBC_FOR_ITER:
276278
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
277-
obj1 = rt_iternext(*sp);
279+
obj1 = rt_iternext(TOP());
278280
if (obj1 == py_const_stop_iteration) {
279281
++sp; // pop the exhausted iterator
280282
ip += unum; // jump to after for-block
@@ -300,35 +302,35 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
300302

301303
case PYBC_UNARY_OP:
302304
unum = *ip++;
303-
*sp = rt_unary_op(unum, *sp);
305+
SET_TOP(rt_unary_op(unum, TOP()));
304306
break;
305307

306308
case PYBC_BINARY_OP:
307309
unum = *ip++;
308310
obj2 = POP();
309-
obj1 = *sp;
310-
*sp = rt_binary_op(unum, obj1, obj2);
311+
obj1 = TOP();
312+
SET_TOP(rt_binary_op(unum, obj1, obj2));
311313
break;
312314

313315
case PYBC_COMPARE_OP:
314316
unum = *ip++;
315317
obj2 = POP();
316-
obj1 = *sp;
317-
*sp = rt_compare_op(unum, obj1, obj2);
318+
obj1 = TOP();
319+
SET_TOP(rt_compare_op(unum, obj1, obj2));
318320
break;
319321

320322
case PYBC_BUILD_TUPLE:
321323
DECODE_UINT;
322324
obj1 = rt_build_tuple(unum, sp);
323325
sp += unum - 1;
324-
*sp = obj1;
326+
SET_TOP(obj1);
325327
break;
326328

327329
case PYBC_BUILD_LIST:
328330
DECODE_UINT;
329331
obj1 = rt_build_list(unum, sp);
330332
sp += unum - 1;
331-
*sp = obj1;
333+
SET_TOP(obj1);
332334
break;
333335

334336
case PYBC_LIST_APPEND:
@@ -359,7 +361,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
359361
DECODE_UINT;
360362
obj1 = rt_build_set(unum, sp);
361363
sp += unum - 1;
362-
*sp = obj1;
364+
SET_TOP(obj1);
363365
break;
364366

365367
case PYBC_SET_ADD:
@@ -400,7 +402,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
400402
obj1 = rt_call_method_n_kw(unum & 0xff, (unum >> 8) & 0xff, sp);
401403
sp += (unum & 0xff) + ((unum >> 7) & 0x1fe) + 1;
402404
}
403-
*sp = obj1;
405+
SET_TOP(obj1);
404406
break;
405407

406408
case PYBC_RETURN_VALUE:
@@ -418,6 +420,18 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **
418420
*sp_in_out = sp;
419421
return true;
420422

423+
case PYBC_IMPORT_NAME:
424+
DECODE_QSTR;
425+
obj1 = POP();
426+
SET_TOP(rt_import_name(qstr, obj1, TOP()));
427+
break;
428+
429+
case PYBC_IMPORT_FROM:
430+
DECODE_QSTR;
431+
obj1 = rt_import_from(TOP(), qstr);
432+
PUSH(obj1);
433+
break;
434+
421435
default:
422436
printf("code %p, byte code 0x%02x not implemented\n", ip, op);
423437
assert(0);

0 commit comments

Comments
 (0)
0