Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 2:c89e95946844, committed 2016-04-16
- Comitter:
- Colin Hogben
- Date:
- Sat Apr 16 22:43:41 2016 +0100
- Parent:
- 1:873275b0210d
- Child:
- 3:d8dfbbbd0fc9
- Commit message:
- py: update to upstream master
Changed in this revision
--- a/lib/utils/pyexec.c Sat Apr 16 22:42:43 2016 +0100
+++ b/lib/utils/pyexec.c Sat Apr 16 22:43:41 2016 +0100
@@ -50,22 +50,33 @@
#define EXEC_FLAG_PRINT_EOF (1)
#define EXEC_FLAG_ALLOW_DEBUGGING (2)
#define EXEC_FLAG_IS_REPL (4)
+#define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
// parses, compiles and executes the code in the lexer
// frees the lexer before returning
// EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
// EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
// EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
-STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, int exec_flags) {
+STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
int ret = 0;
uint32_t start = 0;
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
- // parse and compile the script
- qstr source_name = lex->source_name;
- mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
- mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
+ mp_obj_t module_fun;
+ #if MICROPY_MODULE_FROZEN_MPY
+ if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) {
+ // source is a raw_code object, create the function
+ module_fun = mp_make_function_from_raw_code(source, MP_OBJ_NULL, MP_OBJ_NULL);
+ } else
+ #endif
+ {
+ // source is a lexer, parse and compile the script
+ mp_lexer_t *lex = source;
+ qstr source_name = lex->source_name;
+ mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
+ module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
+ }
// execute code
mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us
@@ -488,14 +499,24 @@
#if MICROPY_MODULE_FROZEN
int pyexec_frozen_module(const char *name) {
- mp_lexer_t *lex = mp_find_frozen_module(name, strlen(name));
+ void *frozen_data;
+ int frozen_type = mp_find_frozen_module(name, strlen(name), &frozen_data);
+
+ switch (frozen_type) {
+ #if MICROPY_MODULE_FROZEN_STR
+ case MP_FROZEN_STR:
+ return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0);
+ #endif
- if (lex == NULL) {
- printf("could not find module '%s'\n", name);
- return false;
+ #if MICROPY_MODULE_FROZEN_MPY
+ case MP_FROZEN_MPY:
+ return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE);
+ #endif
+
+ default:
+ printf("could not find module '%s'\n", name);
+ return false;
}
-
- return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
}
#endif
--- a/py/builtin.h Sat Apr 16 22:42:43 2016 +0100 +++ b/py/builtin.h Sat Apr 16 22:43:41 2016 +0100 @@ -71,6 +71,10 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_round_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sorted_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj); +// Defined by a port, but declared here for simplicity +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_help_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_input_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_open_obj); MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); @@ -106,6 +110,7 @@ extern const mp_obj_module_t mp_module_machine; extern const mp_obj_module_t mp_module_lwip; extern const mp_obj_module_t mp_module_websocket; +extern const mp_obj_module_t mp_module_framebuf; // extmod functions MP_DECLARE_CONST_FUN_OBJ(pyb_mount_obj);
--- a/py/builtinimport.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/builtinimport.c Sat Apr 16 22:43:41 2016 +0100
@@ -144,7 +144,7 @@
}
#endif
-#if MICROPY_PERSISTENT_CODE_LOAD
+#if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_MODULE_FROZEN_MPY
STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code) {
#if MICROPY_PY___FILE__
// TODO
@@ -182,8 +182,9 @@
#endif
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
- // create the lexer
+ #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_ENABLE_COMPILER
char *file_str = vstr_null_terminated_str(file);
+ #endif
#if MICROPY_PERSISTENT_CODE_LOAD
if (file_str[file->len - 3] == 'm') {
@@ -340,8 +341,9 @@
DEBUG_printf("Module not yet loaded\n");
#if MICROPY_MODULE_FROZEN
- mp_lexer_t *lex = mp_find_frozen_module(mod_str, mod_len);
- if (lex != NULL) {
+ void *frozen_data;
+ int frozen_type = mp_find_frozen_module(mod_str, mod_len, &frozen_data);
+ if (frozen_type != MP_FROZEN_NONE) {
module_obj = mp_obj_new_module(module_name_qstr);
// if args[3] (fromtuple) has magic value False, set up
// this module for command-line "-m" option (set module's
@@ -351,7 +353,16 @@
mp_obj_module_t *o = MP_OBJ_TO_PTR(module_obj);
mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
}
- do_load_from_lexer(module_obj, lex, mod_str);
+ #if MICROPY_MODULE_FROZEN_STR
+ if (frozen_type == MP_FROZEN_STR) {
+ do_load_from_lexer(module_obj, frozen_data, mod_str);
+ }
+ #endif
+ #if MICROPY_MODULE_FROZEN_MPY
+ if (frozen_type == MP_FROZEN_MPY) {
+ do_execute_raw_code(module_obj, frozen_data);
+ }
+ #endif
return module_obj;
}
#endif
--- a/py/compile.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/compile.c Sat Apr 16 22:43:41 2016 +0100
@@ -318,14 +318,14 @@
typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t kind);
-STATIC void c_assign_power(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t assign_kind) {
+STATIC void c_assign_atom_expr(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t assign_kind) {
if (assign_kind != ASSIGN_AUG_STORE) {
compile_node(comp, pns->nodes[0]);
}
if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
- if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
+ if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_atom_expr_trailers) {
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1);
if (assign_kind != ASSIGN_AUG_STORE) {
for (int i = 0; i < n - 1; i++) {
@@ -366,10 +366,6 @@
goto cannot_assign;
}
- if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
- goto cannot_assign;
- }
-
return;
cannot_assign:
@@ -440,9 +436,9 @@
// pn must be a struct
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
switch (MP_PARSE_NODE_STRUCT_KIND(pns)) {
- case PN_power:
+ case PN_atom_expr_normal:
// lhs is an index or attribute
- c_assign_power(comp, pns, assign_kind);
+ c_assign_atom_expr(comp, pns, assign_kind);
break;
case PN_testlist_star_expr:
@@ -818,11 +814,19 @@
}
}
- // compile the body (funcdef or classdef) and get its name
+ // compile the body (funcdef, async funcdef or classdef) and get its name
mp_parse_node_struct_t *pns_body = (mp_parse_node_struct_t*)pns->nodes[1];
qstr body_name = 0;
if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
body_name = compile_funcdef_helper(comp, pns_body, emit_options);
+ #if MICROPY_PY_ASYNC_AWAIT
+ } else if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_async_funcdef) {
+ assert(MP_PARSE_NODE_IS_STRUCT(pns_body->nodes[0]));
+ mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns_body->nodes[0];
+ body_name = compile_funcdef_helper(comp, pns0, emit_options);
+ scope_t *fscope = (scope_t*)pns0->nodes[4];
+ fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
+ #endif
} else {
assert(MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef); // should be
body_name = compile_classdef_helper(comp, pns_body, emit_options);
@@ -846,14 +850,14 @@
STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
if (MP_PARSE_NODE_IS_ID(pn)) {
compile_delete_id(comp, MP_PARSE_NODE_LEAF_ARG(pn));
- } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
+ } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_expr_normal)) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
- compile_node(comp, pns->nodes[0]); // base of the power node
+ compile_node(comp, pns->nodes[0]); // base of the atom_expr_normal node
if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
- if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
+ if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_atom_expr_trailers) {
int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1);
for (int i = 0; i < n - 1; i++) {
compile_node(comp, pns1->nodes[i]);
@@ -874,9 +878,6 @@
goto cannot_delete;
}
- if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
- goto cannot_delete;
- }
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
pn = ((mp_parse_node_struct_t*)pn)->nodes[0];
if (MP_PARSE_NODE_IS_NULL(pn)) {
@@ -1397,12 +1398,11 @@
// this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
// this is actually slower, but uses no heap memory
// for viper it will be much, much faster
- if (/*comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
+ if (/*comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_atom_expr_normal)) {
mp_parse_node_struct_t *pns_it = (mp_parse_node_struct_t*)pns->nodes[1];
- if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0])
+ if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0])
&& MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == MP_QSTR_range
- && MP_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren)
- && MP_PARSE_NODE_IS_NULL(pns_it->nodes[2])) {
+ && MP_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren)) {
mp_parse_node_t pn_range_args = ((mp_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
mp_parse_node_t *args;
int n_args = mp_parse_node_extract_list(&pn_range_args, PN_arglist, &args);
@@ -1661,6 +1661,177 @@
compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
}
+STATIC void compile_yield_from(compiler_t *comp) {
+ EMIT(get_iter);
+ EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
+ EMIT(yield_from);
+}
+
+#if MICROPY_PY_ASYNC_AWAIT
+STATIC void compile_await_object_method(compiler_t *comp, qstr method) {
+ EMIT_ARG(load_method, method);
+ EMIT_ARG(call_method, 0, 0, 0);
+ compile_yield_from(comp);
+}
+
+STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ // comp->break_label |= MP_EMIT_BREAK_FROM_FOR;
+
+ qstr context = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
+ uint while_else_label = comp_next_label(comp);
+ uint try_exception_label = comp_next_label(comp);
+ uint try_else_label = comp_next_label(comp);
+ uint try_finally_label = comp_next_label(comp);
+
+ compile_node(comp, pns->nodes[1]); // iterator
+ compile_await_object_method(comp, MP_QSTR___aiter__);
+ compile_store_id(comp, context);
+
+ START_BREAK_CONTINUE_BLOCK
+
+ EMIT_ARG(label_assign, continue_label);
+
+ EMIT_ARG(setup_except, try_exception_label);
+ compile_increase_except_level(comp);
+
+ compile_load_id(comp, context);
+ compile_await_object_method(comp, MP_QSTR___anext__);
+ c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
+ EMIT(pop_block);
+ EMIT_ARG(jump, try_else_label);
+
+ EMIT_ARG(label_assign, try_exception_label);
+ EMIT(start_except_handler);
+ EMIT(dup_top);
+ EMIT_LOAD_GLOBAL(MP_QSTR_StopAsyncIteration);
+ EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH);
+ EMIT_ARG(pop_jump_if, false, try_finally_label);
+ EMIT(pop_top);
+ EMIT(pop_top);
+ EMIT(pop_top);
+ EMIT(pop_except);
+ EMIT_ARG(jump, while_else_label);
+
+ EMIT_ARG(label_assign, try_finally_label);
+ EMIT_ARG(adjust_stack_size, 3);
+ compile_decrease_except_level(comp);
+ EMIT(end_finally);
+ EMIT(end_except_handler);
+
+ EMIT_ARG(label_assign, try_else_label);
+ compile_node(comp, pns->nodes[2]); // body
+
+ EMIT_ARG(jump, continue_label);
+ // break/continue apply to outer loop (if any) in the else block
+ END_BREAK_CONTINUE_BLOCK
+
+ EMIT_ARG(label_assign, while_else_label);
+ compile_node(comp, pns->nodes[3]); // else
+
+ EMIT_ARG(label_assign, break_label);
+}
+
+STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_node_t *nodes, mp_parse_node_t body) {
+ if (n == 0) {
+ // no more pre-bits, compile the body of the with
+ compile_node(comp, body);
+ } else {
+ uint try_exception_label = comp_next_label(comp);
+ uint no_reraise_label = comp_next_label(comp);
+ uint try_else_label = comp_next_label(comp);
+ uint end_label = comp_next_label(comp);
+ qstr context;
+
+ if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
+ // this pre-bit is of the form "a as b"
+ mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)nodes[0];
+ compile_node(comp, pns->nodes[0]);
+ context = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
+ compile_store_id(comp, context);
+ compile_load_id(comp, context);
+ compile_await_object_method(comp, MP_QSTR___aenter__);
+ c_assign(comp, pns->nodes[1], ASSIGN_STORE);
+ } else {
+ // this pre-bit is just an expression
+ compile_node(comp, nodes[0]);
+ context = MP_PARSE_NODE_LEAF_ARG(nodes[0]);
+ compile_store_id(comp, context);
+ compile_load_id(comp, context);
+ compile_await_object_method(comp, MP_QSTR___aenter__);
+ EMIT(pop_top);
+ }
+
+ compile_load_id(comp, context);
+ EMIT_ARG(load_method, MP_QSTR___aexit__);
+
+ EMIT_ARG(setup_except, try_exception_label);
+ compile_increase_except_level(comp);
+ // compile additional pre-bits and the body
+ compile_async_with_stmt_helper(comp, n - 1, nodes + 1, body);
+ // finish this with block
+ EMIT(pop_block);
+ EMIT_ARG(jump, try_else_label); // jump over exception handler
+
+ EMIT_ARG(label_assign, try_exception_label); // start of exception handler
+ EMIT(start_except_handler);
+ EMIT(rot_three);
+ EMIT(rot_two);
+ EMIT_ARG(call_method, 3, 0, 0);
+ compile_yield_from(comp);
+ EMIT_ARG(pop_jump_if, true, no_reraise_label);
+ EMIT_ARG(raise_varargs, 0);
+
+ EMIT_ARG(label_assign, no_reraise_label);
+ EMIT(pop_except);
+ EMIT_ARG(jump, end_label);
+
+ EMIT_ARG(adjust_stack_size, 5);
+ compile_decrease_except_level(comp);
+ EMIT(end_finally);
+ EMIT(end_except_handler);
+
+ EMIT_ARG(label_assign, try_else_label); // start of try-else handler
+ EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
+ EMIT(dup_top);
+ EMIT(dup_top);
+ EMIT_ARG(call_method, 3, 0, 0);
+ compile_yield_from(comp);
+ EMIT(pop_top);
+
+ EMIT_ARG(label_assign, end_label);
+
+ }
+}
+
+STATIC void compile_async_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
+ mp_parse_node_t *nodes;
+ int n = mp_parse_node_extract_list(&pns->nodes[0], PN_with_stmt_list, &nodes);
+ assert(n > 0);
+
+ // compile in a nested fashion
+ compile_async_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
+}
+
+STATIC void compile_async_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[0]));
+ mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
+ if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_funcdef) {
+ // async def
+ compile_funcdef(comp, pns0);
+ scope_t *fscope = (scope_t*)pns0->nodes[4];
+ fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
+ } else if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) {
+ // async for
+ compile_async_for_stmt(comp, pns0);
+ } else {
+ // async with
+ assert(MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_with_stmt);
+ compile_async_with_stmt(comp, pns0);
+ }
+}
+#endif
+
STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
@@ -1967,15 +2138,16 @@
}
}
-STATIC void compile_power(compiler_t *comp, mp_parse_node_struct_t *pns) {
+STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *pns) {
// this is to handle special super() call
comp->func_arg_is_super = MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]) == MP_QSTR_super;
compile_generic_all_nodes(comp, pns);
-
- if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) {
- EMIT_ARG(binary_op, MP_BINARY_OP_POWER);
- }
+}
+
+STATIC void compile_power(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ compile_generic_all_nodes(comp, pns); // 2 nodes, arguments of power
+ EMIT_ARG(binary_op, MP_BINARY_OP_POWER);
}
STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_arglist, bool is_method_call, int n_positional_extra) {
@@ -2076,7 +2248,7 @@
}
}
-STATIC void compile_power_trailers(compiler_t *comp, mp_parse_node_struct_t *pns) {
+STATIC void compile_atom_expr_trailers(compiler_t *comp, mp_parse_node_struct_t *pns) {
int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
for (int i = 0; i < num_nodes; i++) {
if (i + 1 < num_nodes && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i], PN_trailer_period) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i + 1], PN_trailer_paren)) {
@@ -2431,15 +2603,24 @@
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
pns = (mp_parse_node_struct_t*)pns->nodes[0];
compile_node(comp, pns->nodes[0]);
- EMIT(get_iter);
- EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
- EMIT(yield_from);
+ compile_yield_from(comp);
} else {
compile_node(comp, pns->nodes[0]);
EMIT(yield_value);
}
}
+#if MICROPY_PY_ASYNC_AWAIT
+STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) {
+ compile_syntax_error(comp, (mp_parse_node_t)pns, "'await' outside function");
+ return;
+ }
+ compile_atom_expr_normal(comp, pns);
+ compile_yield_from(comp);
+}
+#endif
+
STATIC void compile_string(compiler_t *comp, mp_parse_node_struct_t *pns) {
// only create and load the actual str object on the last pass
if (comp->pass != MP_PASS_EMIT) {
@@ -2995,7 +3176,7 @@
goto not_an_instruction;
}
pns2 = (mp_parse_node_struct_t*)pns2->nodes[0];
- if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_power) {
+ if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_atom_expr_normal) {
goto not_an_instruction;
}
if (!MP_PARSE_NODE_IS_ID(pns2->nodes[0])) {
@@ -3004,7 +3185,6 @@
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)) {
goto not_an_instruction;
}
- assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[2]));
// parse node looks like an instruction
// get instruction name and args
--- a/py/emitglue.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/emitglue.c Sat Apr 16 22:43:41 2016 +0100
@@ -49,28 +49,6 @@
mp_uint_t mp_verbose_flag = 0;
#endif
-struct _mp_raw_code_t {
- mp_raw_code_kind_t kind : 3;
- mp_uint_t scope_flags : 7;
- mp_uint_t n_pos_args : 11;
- union {
- struct {
- const byte *bytecode;
- const mp_uint_t *const_table;
- #if MICROPY_PERSISTENT_CODE_SAVE
- mp_uint_t bc_len;
- uint16_t n_obj;
- uint16_t n_raw_code;
- #endif
- } u_byte;
- struct {
- void *fun_data;
- const mp_uint_t *const_table;
- mp_uint_t type_sig; // for viper, compressed as 2-bit types; ret is MSB, then arg0, arg1, etc
- } u_native;
- } data;
-};
-
mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1);
rc->kind = MP_CODE_RESERVED;
@@ -135,7 +113,7 @@
}
#endif
-mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args) {
+mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args) {
DEBUG_OP_printf("make_function_from_raw_code %p\n", rc);
assert(rc != NULL);
@@ -179,7 +157,7 @@
return fun;
}
-mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args) {
+mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args) {
DEBUG_OP_printf("make_closure_from_raw_code %p " UINT_FMT " %p\n", rc, n_closed_over, args);
// make function object
mp_obj_t ffun;
@@ -194,7 +172,7 @@
return mp_obj_new_closure(ffun, n_closed_over & 0xff, args + ((n_closed_over >> 7) & 2));
}
-#if MICROPY_PERSISTENT_CODE
+#if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE
#include "py/smallint.h"
@@ -251,7 +229,7 @@
}
}
-#endif // MICROPY_PERSISTENT_CODE
+#endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE
#if MICROPY_PERSISTENT_CODE_LOAD
--- a/py/emitglue.h Sat Apr 16 22:42:43 2016 +0100
+++ b/py/emitglue.h Sat Apr 16 22:43:41 2016 +0100
@@ -39,7 +39,27 @@
MP_CODE_NATIVE_ASM,
} mp_raw_code_kind_t;
-typedef struct _mp_raw_code_t mp_raw_code_t;
+typedef struct _mp_raw_code_t {
+ mp_raw_code_kind_t kind : 3;
+ mp_uint_t scope_flags : 7;
+ mp_uint_t n_pos_args : 11;
+ union {
+ struct {
+ const byte *bytecode;
+ const mp_uint_t *const_table;
+ #if MICROPY_PERSISTENT_CODE_SAVE
+ mp_uint_t bc_len;
+ uint16_t n_obj;
+ uint16_t n_raw_code;
+ #endif
+ } u_byte;
+ struct {
+ void *fun_data;
+ const mp_uint_t *const_table;
+ mp_uint_t type_sig; // for viper, compressed as 2-bit types; ret is MSB, then arg0, arg1, etc
+ } u_native;
+ } data;
+} mp_raw_code_t;
mp_raw_code_t *mp_emit_glue_new_raw_code(void);
@@ -51,8 +71,8 @@
mp_uint_t scope_flags);
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig);
-mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args);
-mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args);
+mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args);
+mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args);
#if MICROPY_PERSISTENT_CODE_LOAD
typedef struct _mp_reader_t {
--- a/py/frozenmod.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/frozenmod.c Sat Apr 16 22:43:41 2016 +0100
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2015 Paul Sokolovsky
+ * Copyright (c) 2016 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,7 +31,7 @@
#include "py/lexer.h"
#include "py/frozenmod.h"
-#if MICROPY_MODULE_FROZEN
+#if MICROPY_MODULE_FROZEN_STR
#ifndef MICROPY_MODULE_FROZEN_LEXER
#define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str_len
@@ -38,24 +39,67 @@
mp_lexer_t *MICROPY_MODULE_FROZEN_LEXER(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len);
#endif
-extern const char mp_frozen_names[];
-extern const uint32_t mp_frozen_sizes[];
-extern const char mp_frozen_content[];
+extern const char mp_frozen_str_names[];
+extern const uint32_t mp_frozen_str_sizes[];
+extern const char mp_frozen_str_content[];
-mp_lexer_t *mp_find_frozen_module(const char *str, int len) {
- const char *name = mp_frozen_names;
+STATIC mp_lexer_t *mp_find_frozen_str(const char *str, size_t len) {
+ const char *name = mp_frozen_str_names;
size_t offset = 0;
for (int i = 0; *name != 0; i++) {
- int l = strlen(name);
+ size_t l = strlen(name);
if (l == len && !memcmp(str, name, l)) {
- mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(MP_QSTR_, mp_frozen_content + offset, mp_frozen_sizes[i], 0);
+ mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(MP_QSTR_, mp_frozen_str_content + offset, mp_frozen_str_sizes[i], 0);
return lex;
}
name += l + 1;
- offset += mp_frozen_sizes[i] + 1;
+ offset += mp_frozen_str_sizes[i] + 1;
}
return NULL;
}
-#endif // MICROPY_MODULE_FROZEN
+#endif
+
+#if MICROPY_MODULE_FROZEN_MPY
+
+#include "py/emitglue.h"
+
+extern const char mp_frozen_mpy_names[];
+extern const mp_raw_code_t *const mp_frozen_mpy_content[];
+
+STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t len) {
+ const char *name = mp_frozen_mpy_names;
+ for (size_t i = 0; *name != 0; i++) {
+ size_t l = strlen(name);
+ if (l == len && !memcmp(str, name, l)) {
+ return mp_frozen_mpy_content[i];
+ }
+ name += l + 1;
+ }
+ return NULL;
+}
+
+#endif
+
+#if MICROPY_MODULE_FROZEN
+
+int mp_find_frozen_module(const char *str, size_t len, void **data) {
+ #if MICROPY_MODULE_FROZEN_STR
+ mp_lexer_t *lex = mp_find_frozen_str(str, len);
+ if (lex != NULL) {
+ *data = lex;
+ return MP_FROZEN_STR;
+ }
+ #endif
+ #if MICROPY_MODULE_FROZEN_MPY
+ const mp_raw_code_t *rc = mp_find_frozen_mpy(str, len);
+ if (rc != NULL) {
+ *data = (void*)rc;
+ return MP_FROZEN_MPY;
+ }
+ #endif
+ return MP_FROZEN_NONE;
+}
+
+#endif
--- a/py/frozenmod.h Sat Apr 16 22:42:43 2016 +0100
+++ b/py/frozenmod.h Sat Apr 16 22:43:41 2016 +0100
@@ -24,4 +24,10 @@
* THE SOFTWARE.
*/
-mp_lexer_t *mp_find_frozen_module(const char *str, int len);
+enum {
+ MP_FROZEN_NONE,
+ MP_FROZEN_STR,
+ MP_FROZEN_MPY,
+};
+
+int mp_find_frozen_module(const char *str, size_t len, void **data);
--- a/py/grammar.h Sat Apr 16 22:42:43 2016 +0100
+++ b/py/grammar.h Sat Apr 16 22:43:41 2016 +0100
@@ -38,16 +38,17 @@
// eval_input: testlist NEWLINE* ENDMARKER
DEF_RULE(single_input, nc, or(3), tok(NEWLINE), rule(simple_stmt), rule(compound_stmt))
-DEF_RULE(file_input, c(generic_all_nodes), and(1), opt_rule(file_input_2))
+DEF_RULE(file_input, c(generic_all_nodes), and_ident(1), opt_rule(file_input_2))
DEF_RULE(file_input_2, c(generic_all_nodes), one_or_more, rule(file_input_3))
DEF_RULE(file_input_3, nc, or(2), tok(NEWLINE), rule(stmt))
-DEF_RULE(eval_input, nc, and(2), rule(testlist), opt_rule(eval_input_2))
+DEF_RULE(eval_input, nc, and_ident(2), rule(testlist), opt_rule(eval_input_2))
DEF_RULE(eval_input_2, nc, and(1), tok(NEWLINE))
// decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
// decorators: decorator+
-// decorated: decorators (classdef | funcdef)
+// decorated: decorators (classdef | funcdef | async_funcdef)
// funcdef: 'def' NAME parameters ['->' test] ':' suite
+// async_funcdef: 'async' funcdef
// parameters: '(' [typedargslist] ')'
// typedargslist: tfpdef ['=' test] (',' tfpdef ['=' test])* [',' ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef]] | '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef
// tfpdef: NAME [':' test]
@@ -56,27 +57,32 @@
DEF_RULE(decorator, nc, and(4), tok(DEL_AT), rule(dotted_name), opt_rule(trailer_paren), tok(NEWLINE))
DEF_RULE(decorators, nc, one_or_more, rule(decorator))
-DEF_RULE(decorated, c(decorated), and(2), rule(decorators), rule(decorated_body))
+DEF_RULE(decorated, c(decorated), and_ident(2), rule(decorators), rule(decorated_body))
+#if MICROPY_PY_ASYNC_AWAIT
+DEF_RULE(decorated_body, nc, or(3), rule(classdef), rule(funcdef), rule(async_funcdef))
+DEF_RULE(async_funcdef, nc, and(2), tok(KW_ASYNC), rule(funcdef))
+#else
DEF_RULE(decorated_body, nc, or(2), rule(classdef), rule(funcdef))
-DEF_RULE(funcdef, c(funcdef), blank | and(8), tok(KW_DEF), tok(NAME), tok(DEL_PAREN_OPEN), opt_rule(typedargslist), tok(DEL_PAREN_CLOSE), opt_rule(funcdefrettype), tok(DEL_COLON), rule(suite))
-DEF_RULE(funcdefrettype, nc, ident | and(2), tok(DEL_MINUS_MORE), rule(test))
+#endif
+DEF_RULE(funcdef, c(funcdef), and_blank(8), tok(KW_DEF), tok(NAME), tok(DEL_PAREN_OPEN), opt_rule(typedargslist), tok(DEL_PAREN_CLOSE), opt_rule(funcdefrettype), tok(DEL_COLON), rule(suite))
+DEF_RULE(funcdefrettype, nc, and_ident(2), tok(DEL_MINUS_MORE), rule(test))
// note: typedargslist lets through more than is allowed, compiler does further checks
DEF_RULE(typedargslist, nc, list_with_end, rule(typedargslist_item), tok(DEL_COMMA))
DEF_RULE(typedargslist_item, nc, or(3), rule(typedargslist_name), rule(typedargslist_star), rule(typedargslist_dbl_star))
-DEF_RULE(typedargslist_name, nc, ident | and(3), tok(NAME), opt_rule(typedargslist_colon), opt_rule(typedargslist_equal))
+DEF_RULE(typedargslist_name, nc, and_ident(3), tok(NAME), opt_rule(typedargslist_colon), opt_rule(typedargslist_equal))
DEF_RULE(typedargslist_star, nc, and(2), tok(OP_STAR), opt_rule(tfpdef))
DEF_RULE(typedargslist_dbl_star, nc, and(3), tok(OP_DBL_STAR), tok(NAME), opt_rule(typedargslist_colon))
-DEF_RULE(typedargslist_colon, nc, ident | and(2), tok(DEL_COLON), rule(test))
-DEF_RULE(typedargslist_equal, nc, ident | and(2), tok(DEL_EQUAL), rule(test))
+DEF_RULE(typedargslist_colon, nc, and_ident(2), tok(DEL_COLON), rule(test))
+DEF_RULE(typedargslist_equal, nc, and_ident(2), tok(DEL_EQUAL), rule(test))
DEF_RULE(tfpdef, nc, and(2), tok(NAME), opt_rule(typedargslist_colon))
// note: varargslist lets through more than is allowed, compiler does further checks
DEF_RULE(varargslist, nc, list_with_end, rule(varargslist_item), tok(DEL_COMMA))
DEF_RULE(varargslist_item, nc, or(3), rule(varargslist_name), rule(varargslist_star), rule(varargslist_dbl_star))
-DEF_RULE(varargslist_name, nc, ident | and(2), tok(NAME), opt_rule(varargslist_equal))
+DEF_RULE(varargslist_name, nc, and_ident(2), tok(NAME), opt_rule(varargslist_equal))
DEF_RULE(varargslist_star, nc, and(2), tok(OP_STAR), opt_rule(vfpdef))
DEF_RULE(varargslist_dbl_star, nc, and(2), tok(OP_DBL_STAR), tok(NAME))
-DEF_RULE(varargslist_equal, nc, ident | and(2), tok(DEL_EQUAL), rule(test))
-DEF_RULE(vfpdef, nc, ident | and(1), tok(NAME))
+DEF_RULE(varargslist_equal, nc, and_ident(2), tok(DEL_EQUAL), rule(test))
+DEF_RULE(vfpdef, nc, and_ident(1), tok(NAME))
// stmt: compound_stmt | simple_stmt
@@ -84,7 +90,7 @@
// simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
-DEF_RULE(simple_stmt, nc, and(2), rule(simple_stmt_2), tok(NEWLINE))
+DEF_RULE(simple_stmt, nc, and_ident(2), rule(simple_stmt_2), tok(NEWLINE))
DEF_RULE(simple_stmt_2, c(generic_all_nodes), list_with_end, rule(small_stmt), tok(DEL_SEMICOLON))
// small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt
@@ -96,9 +102,9 @@
DEF_RULE(small_stmt, nc, or(8), rule(del_stmt), rule(pass_stmt), rule(flow_stmt), rule(import_stmt), rule(global_stmt), rule(nonlocal_stmt), rule(assert_stmt), rule(expr_stmt))
DEF_RULE(expr_stmt, c(expr_stmt), and(2), rule(testlist_star_expr), opt_rule(expr_stmt_2))
DEF_RULE(expr_stmt_2, nc, or(2), rule(expr_stmt_augassign), rule(expr_stmt_assign_list))
-DEF_RULE(expr_stmt_augassign, nc, and(2), rule(augassign), rule(expr_stmt_6))
+DEF_RULE(expr_stmt_augassign, nc, and_ident(2), rule(augassign), rule(expr_stmt_6))
DEF_RULE(expr_stmt_assign_list, nc, one_or_more, rule(expr_stmt_assign))
-DEF_RULE(expr_stmt_assign, nc, ident | and(2), tok(DEL_EQUAL), rule(expr_stmt_6))
+DEF_RULE(expr_stmt_assign, nc, and_ident(2), tok(DEL_EQUAL), rule(expr_stmt_6))
DEF_RULE(expr_stmt_6, nc, or(2), rule(yield_expr), rule(testlist_star_expr))
DEF_RULE(testlist_star_expr, c(generic_tuple), list_with_end, rule(testlist_star_expr_2), tok(DEL_COMMA))
DEF_RULE(testlist_star_expr_2, nc, or(2), rule(star_expr), rule(test))
@@ -121,8 +127,8 @@
DEF_RULE(return_stmt, c(return_stmt), and(2), tok(KW_RETURN), opt_rule(testlist))
DEF_RULE(yield_stmt, c(yield_stmt), and(1), rule(yield_expr))
DEF_RULE(raise_stmt, c(raise_stmt), and(2), tok(KW_RAISE), opt_rule(raise_stmt_arg))
-DEF_RULE(raise_stmt_arg, nc, and(2), rule(test), opt_rule(raise_stmt_from))
-DEF_RULE(raise_stmt_from, nc, ident | and(2), tok(KW_FROM), rule(test))
+DEF_RULE(raise_stmt_arg, nc, and_ident(2), rule(test), opt_rule(raise_stmt_from))
+DEF_RULE(raise_stmt_from, nc, and_ident(2), tok(KW_FROM), rule(test))
// import_stmt: import_name | import_from
// import_name: 'import' dotted_as_names
@@ -140,14 +146,14 @@
DEF_RULE(import_name, c(import_name), and(2), tok(KW_IMPORT), rule(dotted_as_names))
DEF_RULE(import_from, c(import_from), and(4), tok(KW_FROM), rule(import_from_2), tok(KW_IMPORT), rule(import_from_3))
DEF_RULE(import_from_2, nc, or(2), rule(dotted_name), rule(import_from_2b))
-DEF_RULE(import_from_2b, nc, and(2), rule(one_or_more_period_or_ellipsis), opt_rule(dotted_name))
+DEF_RULE(import_from_2b, nc, and_ident(2), rule(one_or_more_period_or_ellipsis), opt_rule(dotted_name))
DEF_RULE(import_from_3, nc, or(3), tok(OP_STAR), rule(import_as_names_paren), rule(import_as_names))
-DEF_RULE(import_as_names_paren, nc, ident | and(3), tok(DEL_PAREN_OPEN), rule(import_as_names), tok(DEL_PAREN_CLOSE))
+DEF_RULE(import_as_names_paren, nc, and_ident(3), tok(DEL_PAREN_OPEN), rule(import_as_names), tok(DEL_PAREN_CLOSE))
DEF_RULE(one_or_more_period_or_ellipsis, nc, one_or_more, rule(period_or_ellipsis))
DEF_RULE(period_or_ellipsis, nc, or(2), tok(DEL_PERIOD), tok(ELLIPSIS))
DEF_RULE(import_as_name, nc, and(2), tok(NAME), opt_rule(as_name))
-DEF_RULE(dotted_as_name, nc, and(2), rule(dotted_name), opt_rule(as_name))
-DEF_RULE(as_name, nc, ident | and(2), tok(KW_AS), tok(NAME))
+DEF_RULE(dotted_as_name, nc, and_ident(2), rule(dotted_name), opt_rule(as_name))
+DEF_RULE(as_name, nc, and_ident(2), tok(KW_AS), tok(NAME))
DEF_RULE(import_as_names, nc, list_with_end, rule(import_as_name), tok(DEL_COMMA))
DEF_RULE(dotted_as_names, nc, list, rule(dotted_as_name), tok(DEL_COMMA))
DEF_RULE(dotted_name, nc, list, tok(NAME), tok(DEL_PERIOD))
@@ -155,9 +161,9 @@
DEF_RULE(nonlocal_stmt, c(nonlocal_stmt), and(2), tok(KW_NONLOCAL), rule(name_list))
DEF_RULE(name_list, nc, list, tok(NAME), tok(DEL_COMMA))
DEF_RULE(assert_stmt, c(assert_stmt), and(3), tok(KW_ASSERT), rule(test), opt_rule(assert_stmt_extra))
-DEF_RULE(assert_stmt_extra, nc, ident | and(2), tok(DEL_COMMA), rule(test))
+DEF_RULE(assert_stmt_extra, nc, and_ident(2), tok(DEL_COMMA), rule(test))
-// compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
+// compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt
// if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
// while_stmt: 'while' test ':' suite ['else' ':' suite]
// for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
@@ -167,8 +173,15 @@
// with_stmt: 'with' with_item (',' with_item)* ':' suite
// with_item: test ['as' expr]
// suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+// async_stmt: 'async' (funcdef | with_stmt | for_stmt)
+#if MICROPY_PY_ASYNC_AWAIT
+DEF_RULE(compound_stmt, nc, or(9), rule(if_stmt), rule(while_stmt), rule(for_stmt), rule(try_stmt), rule(with_stmt), rule(funcdef), rule(classdef), rule(decorated), rule(async_stmt))
+DEF_RULE(async_stmt, c(async_stmt), and(2), tok(KW_ASYNC), rule(async_stmt_2))
+DEF_RULE(async_stmt_2, nc, or(3), rule(funcdef), rule(with_stmt), rule(for_stmt))
+#else
DEF_RULE(compound_stmt, nc, or(8), rule(if_stmt), rule(while_stmt), rule(for_stmt), rule(try_stmt), rule(with_stmt), rule(funcdef), rule(classdef), rule(decorated))
+#endif
DEF_RULE(if_stmt, c(if_stmt), and(6), tok(KW_IF), rule(test), tok(DEL_COLON), rule(suite), opt_rule(if_stmt_elif_list), opt_rule(else_stmt))
DEF_RULE(if_stmt_elif_list, nc, one_or_more, rule(if_stmt_elif))
DEF_RULE(if_stmt_elif, nc, and(4), tok(KW_ELIF), rule(test), tok(DEL_COLON), rule(suite))
@@ -176,18 +189,18 @@
DEF_RULE(for_stmt, c(for_stmt), and(7), tok(KW_FOR), rule(exprlist), tok(KW_IN), rule(testlist), tok(DEL_COLON), rule(suite), opt_rule(else_stmt))
DEF_RULE(try_stmt, c(try_stmt), and(4), tok(KW_TRY), tok(DEL_COLON), rule(suite), rule(try_stmt_2))
DEF_RULE(try_stmt_2, nc, or(2), rule(try_stmt_except_and_more), rule(try_stmt_finally))
-DEF_RULE(try_stmt_except_and_more, nc, and(3), rule(try_stmt_except_list), opt_rule(else_stmt), opt_rule(try_stmt_finally))
+DEF_RULE(try_stmt_except_and_more, nc, and_ident(3), rule(try_stmt_except_list), opt_rule(else_stmt), opt_rule(try_stmt_finally))
DEF_RULE(try_stmt_except, nc, and(4), tok(KW_EXCEPT), opt_rule(try_stmt_as_name), tok(DEL_COLON), rule(suite))
-DEF_RULE(try_stmt_as_name, nc, and(2), rule(test), opt_rule(as_name))
+DEF_RULE(try_stmt_as_name, nc, and_ident(2), rule(test), opt_rule(as_name))
DEF_RULE(try_stmt_except_list, nc, one_or_more, rule(try_stmt_except))
DEF_RULE(try_stmt_finally, nc, and(3), tok(KW_FINALLY), tok(DEL_COLON), rule(suite))
-DEF_RULE(else_stmt, nc, ident | and(3), tok(KW_ELSE), tok(DEL_COLON), rule(suite))
+DEF_RULE(else_stmt, nc, and_ident(3), tok(KW_ELSE), tok(DEL_COLON), rule(suite))
DEF_RULE(with_stmt, c(with_stmt), and(4), tok(KW_WITH), rule(with_stmt_list), tok(DEL_COLON), rule(suite))
DEF_RULE(with_stmt_list, nc, list, rule(with_item), tok(DEL_COMMA))
-DEF_RULE(with_item, nc, and(2), rule(test), opt_rule(with_item_as))
-DEF_RULE(with_item_as, nc, ident | and(2), tok(KW_AS), rule(expr))
+DEF_RULE(with_item, nc, and_ident(2), rule(test), opt_rule(with_item_as))
+DEF_RULE(with_item_as, nc, and_ident(2), tok(KW_AS), rule(expr))
DEF_RULE(suite, nc, or(2), rule(suite_block), rule(simple_stmt))
-DEF_RULE(suite_block, nc, and(4), tok(NEWLINE), tok(INDENT), rule(suite_block_stmts), tok(DEDENT))
+DEF_RULE(suite_block, nc, and_ident(4), tok(NEWLINE), tok(INDENT), rule(suite_block_stmts), tok(DEDENT))
DEF_RULE(suite_block_stmts, c(generic_all_nodes), one_or_more, rule(stmt))
// test: or_test ['if' or_test 'else' test] | lambdef
@@ -196,11 +209,11 @@
// lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
DEF_RULE(test, nc, or(2), rule(lambdef), rule(test_if_expr))
-DEF_RULE(test_if_expr, c(test_if_expr), and(2), rule(or_test), opt_rule(test_if_else))
+DEF_RULE(test_if_expr, c(test_if_expr), and_ident(2), rule(or_test), opt_rule(test_if_else))
DEF_RULE(test_if_else, nc, and(4), tok(KW_IF), rule(or_test), tok(KW_ELSE), rule(test))
DEF_RULE(test_nocond, nc, or(2), rule(lambdef_nocond), rule(or_test))
-DEF_RULE(lambdef, c(lambdef), blank | and(4), tok(KW_LAMBDA), opt_rule(varargslist), tok(DEL_COLON), rule(test))
-DEF_RULE(lambdef_nocond, c(lambdef), blank | and(4), tok(KW_LAMBDA), opt_rule(varargslist), tok(DEL_COLON), rule(test_nocond))
+DEF_RULE(lambdef, c(lambdef), and_blank(4), tok(KW_LAMBDA), opt_rule(varargslist), tok(DEL_COLON), rule(test))
+DEF_RULE(lambdef_nocond, c(lambdef), and_blank(4), tok(KW_LAMBDA), opt_rule(varargslist), tok(DEL_COLON), rule(test_nocond))
// or_test: and_test ('or' and_test)*
// and_test: not_test ('and' not_test)*
@@ -215,7 +228,8 @@
// arith_expr: term (('+'|'-') term)*
// term: factor (('*'|'/'|'%'|'//') factor)*
// factor: ('+'|'-'|'~') factor | power
-// power: atom trailer* ['**' factor]
+// power: atom_expr ['**' factor]
+// atom_expr: 'await' atom trailer* | atom trailer*
DEF_RULE(or_test, c(or_test), list, rule(and_test), tok(KW_OR))
DEF_RULE(and_test, c(and_test), list, rule(not_test), tok(KW_AND))
@@ -237,11 +251,18 @@
DEF_RULE(term, c(term), list, rule(factor), rule(term_op))
DEF_RULE(term_op, nc, or(4), tok(OP_STAR), tok(OP_SLASH), tok(OP_PERCENT), tok(OP_DBL_SLASH))
DEF_RULE(factor, nc, or(2), rule(factor_2), rule(power))
-DEF_RULE(factor_2, c(factor_2), and(2), rule(factor_op), rule(factor))
+DEF_RULE(factor_2, c(factor_2), and_ident(2), rule(factor_op), rule(factor))
DEF_RULE(factor_op, nc, or(3), tok(OP_PLUS), tok(OP_MINUS), tok(OP_TILDE))
-DEF_RULE(power, c(power), and(3), rule(atom), opt_rule(power_trailers), opt_rule(power_dbl_star))
-DEF_RULE(power_trailers, c(power_trailers), one_or_more, rule(trailer))
-DEF_RULE(power_dbl_star, nc, ident | and(2), tok(OP_DBL_STAR), rule(factor))
+DEF_RULE(power, c(power), and_ident(2), rule(atom_expr), opt_rule(power_dbl_star))
+#if MICROPY_PY_ASYNC_AWAIT
+DEF_RULE(atom_expr, nc, or(2), rule(atom_expr_await), rule(atom_expr_normal))
+DEF_RULE(atom_expr_await, c(atom_expr_await), and(3), tok(KW_AWAIT), rule(atom), opt_rule(atom_expr_trailers))
+#else
+DEF_RULE(atom_expr, nc, or(1), rule(atom_expr_normal))
+#endif
+DEF_RULE(atom_expr_normal, c(atom_expr_normal), and_ident(2), rule(atom), opt_rule(atom_expr_trailers))
+DEF_RULE(atom_expr_trailers, c(atom_expr_trailers), one_or_more, rule(trailer))
+DEF_RULE(power_dbl_star, nc, and_ident(2), tok(OP_DBL_STAR), rule(factor))
// atom: '(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False'
// testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
@@ -254,10 +275,10 @@
DEF_RULE(atom_2b, nc, or(2), rule(yield_expr), rule(testlist_comp))
DEF_RULE(atom_bracket, c(atom_bracket), and(3), tok(DEL_BRACKET_OPEN), opt_rule(testlist_comp), tok(DEL_BRACKET_CLOSE))
DEF_RULE(atom_brace, c(atom_brace), and(3), tok(DEL_BRACE_OPEN), opt_rule(dictorsetmaker), tok(DEL_BRACE_CLOSE))
-DEF_RULE(testlist_comp, nc, and(2), rule(testlist_comp_2), opt_rule(testlist_comp_3))
+DEF_RULE(testlist_comp, nc, and_ident(2), rule(testlist_comp_2), opt_rule(testlist_comp_3))
DEF_RULE(testlist_comp_2, nc, or(2), rule(star_expr), rule(test))
DEF_RULE(testlist_comp_3, nc, or(2), rule(comp_for), rule(testlist_comp_3b))
-DEF_RULE(testlist_comp_3b, nc, ident | and(2), tok(DEL_COMMA), opt_rule(testlist_comp_3c))
+DEF_RULE(testlist_comp_3b, nc, and_ident(2), tok(DEL_COMMA), opt_rule(testlist_comp_3c))
DEF_RULE(testlist_comp_3c, nc, list_with_end, rule(testlist_comp_2), tok(DEL_COMMA))
DEF_RULE(trailer, nc, or(3), rule(trailer_paren), rule(trailer_bracket), rule(trailer_period))
DEF_RULE(trailer_paren, c(trailer_paren), and(3), tok(DEL_PAREN_OPEN), opt_rule(arglist), tok(DEL_PAREN_CLOSE))
@@ -271,11 +292,11 @@
#if MICROPY_PY_BUILTINS_SLICE
DEF_RULE(subscriptlist, c(generic_tuple), list_with_end, rule(subscript), tok(DEL_COMMA))
DEF_RULE(subscript, nc, or(2), rule(subscript_3), rule(subscript_2))
-DEF_RULE(subscript_2, c(subscript_2), and(2), rule(test), opt_rule(subscript_3))
+DEF_RULE(subscript_2, c(subscript_2), and_ident(2), rule(test), opt_rule(subscript_3))
DEF_RULE(subscript_3, c(subscript_3), and(2), tok(DEL_COLON), opt_rule(subscript_3b))
DEF_RULE(subscript_3b, nc, or(2), rule(subscript_3c), rule(subscript_3d))
DEF_RULE(subscript_3c, nc, and(2), tok(DEL_COLON), opt_rule(test))
-DEF_RULE(subscript_3d, nc, and(2), rule(test), opt_rule(sliceop))
+DEF_RULE(subscript_3d, nc, and_ident(2), rule(test), opt_rule(sliceop))
DEF_RULE(sliceop, nc, and(2), tok(DEL_COLON), opt_rule(test))
#else
DEF_RULE(subscriptlist, c(generic_tuple), list_with_end, rule(test), tok(DEL_COMMA))
@@ -289,10 +310,10 @@
DEF_RULE(exprlist_2, nc, or(2), rule(star_expr), rule(expr))
DEF_RULE(testlist, c(generic_tuple), list_with_end, rule(test), tok(DEL_COMMA))
// TODO dictorsetmaker lets through more than is allowed
-DEF_RULE(dictorsetmaker, nc, and(2), rule(dictorsetmaker_item), opt_rule(dictorsetmaker_tail))
+DEF_RULE(dictorsetmaker, nc, and_ident(2), rule(dictorsetmaker_item), opt_rule(dictorsetmaker_tail))
#if MICROPY_PY_BUILTINS_SET
-DEF_RULE(dictorsetmaker_item, c(dictorsetmaker_item), and(2), rule(test), opt_rule(dictorsetmaker_colon))
-DEF_RULE(dictorsetmaker_colon, nc, ident | and(2), tok(DEL_COLON), rule(test))
+DEF_RULE(dictorsetmaker_item, c(dictorsetmaker_item), and_ident(2), rule(test), opt_rule(dictorsetmaker_colon))
+DEF_RULE(dictorsetmaker_colon, nc, and_ident(2), tok(DEL_COLON), rule(test))
#else
DEF_RULE(dictorsetmaker_item, c(dictorsetmaker_item), and(3), rule(test), tok(DEL_COLON), rule(test))
#endif
@@ -302,8 +323,8 @@
// classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
-DEF_RULE(classdef, c(classdef), blank | and(5), tok(KW_CLASS), tok(NAME), opt_rule(classdef_2), tok(DEL_COLON), rule(suite))
-DEF_RULE(classdef_2, nc, ident | and(3), tok(DEL_PAREN_OPEN), opt_rule(arglist), tok(DEL_PAREN_CLOSE))
+DEF_RULE(classdef, c(classdef), and_blank(5), tok(KW_CLASS), tok(NAME), opt_rule(classdef_2), tok(DEL_COLON), rule(suite))
+DEF_RULE(classdef_2, nc, and_ident(3), tok(DEL_PAREN_OPEN), opt_rule(arglist), tok(DEL_PAREN_CLOSE))
// arglist: (argument ',')* (argument [','] | '*' test (',' argument)* [',' '**' test] | '**' test)
@@ -320,11 +341,11 @@
// comp_for: 'for' exprlist 'in' or_test [comp_iter]
// comp_if: 'if' test_nocond [comp_iter]
-DEF_RULE(argument, nc, and(2), rule(test), opt_rule(argument_2))
+DEF_RULE(argument, nc, and_ident(2), rule(test), opt_rule(argument_2))
DEF_RULE(argument_2, nc, or(2), rule(comp_for), rule(argument_3))
-DEF_RULE(argument_3, nc, ident | and(2), tok(DEL_EQUAL), rule(test))
+DEF_RULE(argument_3, nc, and_ident(2), tok(DEL_EQUAL), rule(test))
DEF_RULE(comp_iter, nc, or(2), rule(comp_for), rule(comp_if))
-DEF_RULE(comp_for, nc, blank | and(5), tok(KW_FOR), rule(exprlist), tok(KW_IN), rule(or_test), opt_rule(comp_iter))
+DEF_RULE(comp_for, nc, and_blank(5), tok(KW_FOR), rule(exprlist), tok(KW_IN), rule(or_test), opt_rule(comp_iter))
DEF_RULE(comp_if, nc, and(3), tok(KW_IF), rule(test_nocond), opt_rule(comp_iter))
// # not used in grammar, but may appear in "node" passed from Parser to Compiler
--- a/py/lexer.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/lexer.c Sat Apr 16 22:43:41 2016 +0100
@@ -234,6 +234,10 @@
"and",
"as",
"assert",
+ #if MICROPY_PY_ASYNC_AWAIT
+ "async",
+ "await",
+ #endif
"break",
"class",
"continue",
--- a/py/lexer.h Sat Apr 16 22:42:43 2016 +0100
+++ b/py/lexer.h Sat Apr 16 22:43:41 2016 +0100
@@ -63,6 +63,10 @@
MP_TOKEN_KW_AND,
MP_TOKEN_KW_AS,
MP_TOKEN_KW_ASSERT,
+ #if MICROPY_PY_ASYNC_AWAIT
+ MP_TOKEN_KW_ASYNC,
+ MP_TOKEN_KW_AWAIT,
+ #endif
MP_TOKEN_KW_BREAK,
MP_TOKEN_KW_CLASS,
MP_TOKEN_KW_CONTINUE,
--- a/py/map.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/map.c Sat Apr 16 22:43:41 2016 +0100
@@ -45,19 +45,26 @@
.table = NULL,
};
-// approximatelly doubling primes; made with Mathematica command: Table[Prime[Floor[(1.7)^n]], {n, 3, 24}]
-// prefixed with zero for the empty case.
-STATIC uint32_t doubling_primes[] = {0, 7, 19, 43, 89, 179, 347, 647, 1229, 2297, 4243, 7829, 14347, 26017, 47149, 84947, 152443, 273253, 488399, 869927, 1547173, 2745121, 4861607};
+// This table of sizes is used to control the growth of hash tables.
+// The first set of sizes are chosen so the allocation fits exactly in a
+// 4-word GC block, and it's not so important for these small values to be
+// prime. The latter sizes are prime and increase at an increasing rate.
+STATIC uint16_t hash_allocation_sizes[] = {
+ 0, 2, 4, 6, 8, 10, 12, // +2
+ 17, 23, 29, 37, 47, 59, 73, // *1.25
+ 97, 127, 167, 223, 293, 389, 521, 691, 919, 1223, 1627, 2161, // *1.33
+ 3229, 4831, 7243, 10861, 16273, 24407, 36607, 54907, // *1.5
+};
-STATIC mp_uint_t get_doubling_prime_greater_or_equal_to(mp_uint_t x) {
- for (size_t i = 0; i < MP_ARRAY_SIZE(doubling_primes); i++) {
- if (doubling_primes[i] >= x) {
- return doubling_primes[i];
+STATIC mp_uint_t get_hash_alloc_greater_or_equal_to(mp_uint_t x) {
+ for (size_t i = 0; i < MP_ARRAY_SIZE(hash_allocation_sizes); i++) {
+ if (hash_allocation_sizes[i] >= x) {
+ return hash_allocation_sizes[i];
}
}
// ran out of primes in the table!
// return something sensible, at least make it odd
- return x | 1;
+ return (x + x / 2) | 1;
}
/******************************************************************************/
@@ -118,7 +125,7 @@
STATIC void mp_map_rehash(mp_map_t *map) {
mp_uint_t old_alloc = map->alloc;
- mp_uint_t new_alloc = get_doubling_prime_greater_or_equal_to(map->alloc + 1);
+ mp_uint_t new_alloc = get_hash_alloc_greater_or_equal_to(map->alloc + 1);
mp_map_elem_t *old_table = map->table;
mp_map_elem_t *new_table = m_new0(mp_map_elem_t, new_alloc);
// If we reach this point, table resizing succeeded, now we can edit the old map.
@@ -298,7 +305,7 @@
STATIC void mp_set_rehash(mp_set_t *set) {
mp_uint_t old_alloc = set->alloc;
mp_obj_t *old_table = set->table;
- set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1);
+ set->alloc = get_hash_alloc_greater_or_equal_to(set->alloc + 1);
set->used = 0;
set->table = m_new0(mp_obj_t, set->alloc);
for (mp_uint_t i = 0; i < old_alloc; i++) {
--- a/py/modbuiltins.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/modbuiltins.c Sat Apr 16 22:43:41 2016 +0100
@@ -439,6 +439,7 @@
mp_print_str(&mp_plat_print, "\n");
#endif
#if MICROPY_CAN_OVERRIDE_BUILTINS
+ // Set "_" special variable
mp_obj_t dest[2] = {MP_OBJ_SENTINEL, o};
mp_type_module.attr(MP_OBJ_FROM_PTR(&mp_module_builtins), MP_QSTR__, dest);
#endif
@@ -703,6 +704,9 @@
{ MP_ROM_QSTR(MP_QSTR_OSError), MP_ROM_PTR(&mp_type_OSError) },
{ MP_ROM_QSTR(MP_QSTR_OverflowError), MP_ROM_PTR(&mp_type_OverflowError) },
{ MP_ROM_QSTR(MP_QSTR_RuntimeError), MP_ROM_PTR(&mp_type_RuntimeError) },
+ #if MICROPY_PY_ASYNC_AWAIT
+ { MP_ROM_QSTR(MP_QSTR_StopAsyncIteration), MP_ROM_PTR(&mp_type_StopAsyncIteration) },
+ #endif
{ MP_ROM_QSTR(MP_QSTR_StopIteration), MP_ROM_PTR(&mp_type_StopIteration) },
{ MP_ROM_QSTR(MP_QSTR_SyntaxError), MP_ROM_PTR(&mp_type_SyntaxError) },
{ MP_ROM_QSTR(MP_QSTR_SystemExit), MP_ROM_PTR(&mp_type_SystemExit) },
--- a/py/mpconfig.h Sat Apr 16 22:42:43 2016 +0100 +++ b/py/mpconfig.h Sat Apr 16 22:43:41 2016 +0100 @@ -234,7 +234,7 @@ // Whether generated code can persist independently of the VM/runtime instance // This is enabled automatically when needed by other features #ifndef MICROPY_PERSISTENT_CODE -#define MICROPY_PERSISTENT_CODE (MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE) +#define MICROPY_PERSISTENT_CODE (MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE || MICROPY_MODULE_FROZEN_MPY) #endif // Whether to emit x64 native code @@ -526,9 +526,19 @@ #define MICROPY_MODULE_WEAK_LINKS (0) #endif -// Whether frozen modules are supported +// Whether frozen modules are supported in the form of strings +#ifndef MICROPY_MODULE_FROZEN_STR +#define MICROPY_MODULE_FROZEN_STR (0) +#endif + +// Whether frozen modules are supported in the form of .mpy files +#ifndef MICROPY_MODULE_FROZEN_MPY +#define MICROPY_MODULE_FROZEN_MPY (0) +#endif + +// Convenience macro for whether frozen modules are supported #ifndef MICROPY_MODULE_FROZEN -#define MICROPY_MODULE_FROZEN (0) +#define MICROPY_MODULE_FROZEN (MICROPY_MODULE_FROZEN_STR || MICROPY_MODULE_FROZEN_MPY) #endif // Whether you can override builtins in the builtins module @@ -564,6 +574,11 @@ #define MICROPY_PY_DESCRIPTORS (0) #endif +// Support for async/await/async for/async with +#ifndef MICROPY_PY_ASYNC_AWAIT +#define MICROPY_PY_ASYNC_AWAIT (1) +#endif + // Whether str object is proper unicode #ifndef MICROPY_PY_BUILTINS_STR_UNICODE #define MICROPY_PY_BUILTINS_STR_UNICODE (0) @@ -837,6 +852,10 @@ #define MICROPY_PY_MACHINE (0) #endif +#ifndef MICROPY_PY_MACHINE_I2C +#define MICROPY_PY_MACHINE_I2C (0) +#endif + #ifndef MICROPY_PY_USSL #define MICROPY_PY_USSL (0) #endif @@ -845,6 +864,10 @@ #define MICROPY_PY_WEBSOCKET (0) #endif +#ifndef MICROPY_PY_FRAMEBUF +#define MICROPY_PY_FRAMEBUF (0) +#endif + /*****************************************************************************/ /* Hooks for a port to add builtins */
--- a/py/obj.h Sat Apr 16 22:42:43 2016 +0100 +++ b/py/obj.h Sat Apr 16 22:43:41 2016 +0100 @@ -561,6 +561,7 @@ extern const mp_obj_type_t mp_type_TimeoutError; extern const mp_obj_type_t mp_type_OverflowError; extern const mp_obj_type_t mp_type_RuntimeError; +extern const mp_obj_type_t mp_type_StopAsyncIteration; extern const mp_obj_type_t mp_type_StopIteration; extern const mp_obj_type_t mp_type_SyntaxError; extern const mp_obj_type_t mp_type_SystemExit;
--- a/py/objexcept.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/objexcept.c Sat Apr 16 22:43:41 2016 +0100
@@ -197,6 +197,9 @@
MP_DEFINE_EXCEPTION(GeneratorExit, BaseException)
MP_DEFINE_EXCEPTION(Exception, BaseException)
MP_DEFINE_EXCEPTION_BASE(Exception)
+ #if MICROPY_PY_ASYNC_AWAIT
+ MP_DEFINE_EXCEPTION(StopAsyncIteration, Exception)
+ #endif
MP_DEFINE_EXCEPTION(StopIteration, Exception)
MP_DEFINE_EXCEPTION(ArithmeticError, Exception)
MP_DEFINE_EXCEPTION_BASE(ArithmeticError)
--- a/py/objmodule.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/objmodule.c Sat Apr 16 22:43:41 2016 +0100
@@ -196,6 +196,9 @@
#if MICROPY_PY_WEBSOCKET
{ MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&mp_module_websocket) },
#endif
+#if MICROPY_PY_FRAMEBUF
+ { MP_ROM_QSTR(MP_QSTR_framebuf), MP_ROM_PTR(&mp_module_framebuf) },
+#endif
// extra builtin modules as defined by a port
MICROPY_PORT_BUILTIN_MODULES
--- a/py/objstr.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/objstr.c Sat Apr 16 22:43:41 2016 +0100
@@ -564,7 +564,7 @@
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args);
- mp_obj_t new_args[2] = {pos_args[0], MP_OBJ_NEW_QSTR(MP_QSTR__backslash_n)};
+ mp_obj_t new_args[2] = {pos_args[0], MP_OBJ_NEW_QSTR(MP_QSTR__0x0a_)};
return str_split_internal(2, new_args, SPLITLINES | (args.keepends.u_bool ? KEEP : 0));
}
#endif
--- a/py/parse.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/parse.c Sat Apr 16 22:43:41 2016 +0100
@@ -56,8 +56,6 @@
#define RULE_ARG_RULE (0x2000)
#define RULE_ARG_OPT_RULE (0x3000)
-#define ADD_BLANK_NODE(rule) ((rule->act & RULE_ACT_ADD_BLANK) != 0)
-
// (un)comment to use rule names; for debugging
//#define USE_RULE_NAME (1)
@@ -80,10 +78,10 @@
RULE_const_object, // special node for a constant, generic Python object
};
-#define ident (RULE_ACT_ALLOW_IDENT)
-#define blank (RULE_ACT_ADD_BLANK)
#define or(n) (RULE_ACT_OR | n)
#define and(n) (RULE_ACT_AND | n)
+#define and_ident(n) (RULE_ACT_AND | n | RULE_ACT_ALLOW_IDENT)
+#define and_blank(n) (RULE_ACT_AND | n | RULE_ACT_ADD_BLANK)
#define one_or_more (RULE_ACT_LIST | 2)
#define list (RULE_ACT_LIST | 1)
#define list_with_end (RULE_ACT_LIST | 3)
@@ -563,11 +561,10 @@
// this node is of the form <x> = <y>
mp_parse_node_t pn0 = peek_result(parser, 1);
if (MP_PARSE_NODE_IS_ID(pn0)
- && MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_power)
+ && MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_atom_expr_normal)
&& MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t*)pn1)->nodes[0])
&& MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pn1)->nodes[0]) == MP_QSTR_const
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pn1)->nodes[1], RULE_trailer_paren)
- && MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pn1)->nodes[2])
) {
// code to assign dynamic constants: id = const(value)
@@ -599,13 +596,11 @@
#endif
#if MICROPY_COMP_MODULE_CONST
- } else if (rule->rule_id == RULE_power) {
- mp_parse_node_t pn0 = peek_result(parser, 2);
- mp_parse_node_t pn1 = peek_result(parser, 1);
- mp_parse_node_t pn2 = peek_result(parser, 0);
+ } else if (rule->rule_id == RULE_atom_expr_normal) {
+ mp_parse_node_t pn0 = peek_result(parser, 1);
+ mp_parse_node_t pn1 = peek_result(parser, 0);
if (!(MP_PARSE_NODE_IS_ID(pn0)
- && MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_trailer_period)
- && MP_PARSE_NODE_IS_NULL(pn2))) {
+ && MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_trailer_period))) {
return false;
}
// id1.id2
@@ -833,25 +828,6 @@
// matched the rule, so now build the corresponding parse_node
- // count number of arguments for the parse_node
- i = 0;
- bool emit_rule = false;
- for (size_t x = 0; x < n; ++x) {
- if ((rule->arg[x] & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) {
- mp_token_kind_t tok_kind = rule->arg[x] & RULE_ARG_ARG_MASK;
- if (tok_kind >= MP_TOKEN_NAME) {
- emit_rule = true;
- }
- if (tok_kind == MP_TOKEN_NAME) {
- // only tokens which were names are pushed to stack
- i += 1;
- }
- } else {
- // rules are always pushed
- i += 1;
- }
- }
-
#if !MICROPY_ENABLE_DOC_STRING
// this code discards lonely statements, such as doc strings
if (input_kind != MP_PARSE_SINGLE_INPUT && rule->rule_id == RULE_expr_stmt && peek_result(&parser, 0) == MP_PARSE_NODE_NULL) {
@@ -871,35 +847,29 @@
}
#endif
- // always emit these rules, even if they have only 1 argument
- if (rule->rule_id == RULE_expr_stmt || rule->rule_id == RULE_yield_stmt) {
- emit_rule = true;
- }
-
- // if a rule has the RULE_ACT_ALLOW_IDENT bit set then this
- // rule should not be emitted if it has only 1 argument
- if (rule->act & RULE_ACT_ALLOW_IDENT) {
- emit_rule = false;
+ // count number of arguments for the parse node
+ i = 0;
+ size_t num_not_nil = 0;
+ for (size_t x = n; x > 0;) {
+ --x;
+ if ((rule->arg[x] & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) {
+ mp_token_kind_t tok_kind = rule->arg[x] & RULE_ARG_ARG_MASK;
+ if (tok_kind == MP_TOKEN_NAME) {
+ // only tokens which were names are pushed to stack
+ i += 1;
+ num_not_nil += 1;
+ }
+ } else {
+ // rules are always pushed
+ if (peek_result(&parser, i) != MP_PARSE_NODE_NULL) {
+ num_not_nil += 1;
+ }
+ i += 1;
+ }
}
- // always emit these rules, and add an extra blank node at the end (to be used by the compiler to store data)
- if (ADD_BLANK_NODE(rule)) {
- emit_rule = true;
- push_result_node(&parser, MP_PARSE_NODE_NULL);
- i += 1;
- }
-
- size_t num_not_nil = 0;
- for (size_t x = 0; x < i; ++x) {
- if (peek_result(&parser, x) != MP_PARSE_NODE_NULL) {
- num_not_nil += 1;
- }
- }
- if (emit_rule || num_not_nil != 1) {
- // need to add rule when num_not_nil==0 for, eg, atom_paren, testlist_comp_3b
- push_result_rule(&parser, rule_src_line, rule, i);
- } else {
- // single result, leave it on stack
+ if (num_not_nil == 1 && (rule->act & RULE_ACT_ALLOW_IDENT)) {
+ // this rule has only 1 argument and should not be emitted
mp_parse_node_t pn = MP_PARSE_NODE_NULL;
for (size_t x = 0; x < i; ++x) {
mp_parse_node_t pn2 = pop_result(&parser);
@@ -908,6 +878,16 @@
}
}
push_result_node(&parser, pn);
+ } else {
+ // this rule must be emitted
+
+ if (rule->act & RULE_ACT_ADD_BLANK) {
+ // and add an extra blank node at the end (used by the compiler to store data)
+ push_result_node(&parser, MP_PARSE_NODE_NULL);
+ i += 1;
+ }
+
+ push_result_rule(&parser, rule_src_line, rule, i);
}
break;
}
--- a/py/qstr.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/qstr.c Sat Apr 16 22:43:41 2016 +0100
@@ -87,11 +87,11 @@
return hash;
}
-STATIC const qstr_pool_t const_pool = {
+const qstr_pool_t mp_qstr_const_pool = {
NULL, // no previous pool
0, // no previous pool
10, // set so that the first dynamically allocated pool is twice this size; must be <= the len (just below)
- MP_QSTR_number_of, // corresponds to number of strings in array just below
+ MP_QSTRnumber_of, // corresponds to number of strings in array just below
{
#define QDEF(id, str) str,
#include "genhdr/qstrdefs.generated.h"
@@ -99,8 +99,15 @@
},
};
+#ifdef MICROPY_QSTR_EXTRA_POOL
+extern const qstr_pool_t MICROPY_QSTR_EXTRA_POOL;
+#define CONST_POOL MICROPY_QSTR_EXTRA_POOL
+#else
+#define CONST_POOL mp_qstr_const_pool
+#endif
+
void qstr_init(void) {
- MP_STATE_VM(last_pool) = (qstr_pool_t*)&const_pool; // we won't modify the const_pool since it has no allocated room left
+ MP_STATE_VM(last_pool) = (qstr_pool_t*)&CONST_POOL; // we won't modify the const_pool since it has no allocated room left
MP_STATE_VM(qstr_last_chunk) = NULL;
}
@@ -258,7 +265,7 @@
*n_qstr = 0;
*n_str_data_bytes = 0;
*n_total_bytes = 0;
- for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &const_pool; pool = pool->prev) {
+ for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &CONST_POOL; pool = pool->prev) {
*n_pool += 1;
*n_qstr += pool->len;
for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) {
@@ -275,7 +282,7 @@
#if MICROPY_PY_MICROPYTHON_MEM_INFO
void qstr_dump_data(void) {
- for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &const_pool; pool = pool->prev) {
+ for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &CONST_POOL; pool = pool->prev) {
for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) {
mp_printf(&mp_plat_print, "Q(%s)\n", Q_GET_DATA(*q));
}
--- a/py/qstr.h Sat Apr 16 22:42:43 2016 +0100 +++ b/py/qstr.h Sat Apr 16 22:43:41 2016 +0100 @@ -40,7 +40,7 @@ #define QDEF(id, str) id, #include "genhdr/qstrdefs.generated.h" #undef QDEF - MP_QSTR_number_of, + MP_QSTRnumber_of, // no underscore so it can't clash with any of the above }; typedef size_t qstr;
--- a/py/qstrdefs.h Sat Apr 16 22:42:43 2016 +0100
+++ b/py/qstrdefs.h Sat Apr 16 22:43:41 2016 +0100
@@ -36,461 +36,11 @@
Q()
Q(*)
Q(_)
-Q(__build_class__)
-Q(__class__)
-Q(__doc__)
-Q(__import__)
-Q(__init__)
-Q(__new__)
-Q(__locals__)
-Q(__main__)
-Q(__module__)
-Q(__name__)
-Q(__dict__)
-Q(__hash__)
-Q(__next__)
-Q(__qualname__)
-Q(__path__)
-Q(__repl_print__)
-#if MICROPY_PY___FILE__
-Q(__file__)
-#endif
-
-Q(__bool__)
-Q(__contains__)
-Q(__enter__)
-Q(__exit__)
-Q(__len__)
-Q(__iter__)
-Q(__getitem__)
-Q(__setitem__)
-Q(__delitem__)
-Q(__add__)
-Q(__sub__)
-Q(__repr__)
-Q(__str__)
-#if MICROPY_PY_DESCRIPTORS
-Q(__get__)
-Q(__set__)
-Q(__delete__)
-#endif
-Q(__getattr__)
-Q(__del__)
-Q(__call__)
-Q(__lt__)
-Q(__gt__)
-Q(__eq__)
-Q(__le__)
-Q(__ge__)
-Q(__reversed__)
-#if MICROPY_PY_ALL_SPECIAL_METHODS
-Q(__mul__)
-Q(__truediv__)
-Q(__floordiv__)
-Q(__iadd__)
-Q(__isub__)
-Q(__invert__)
-Q(__neg__)
-Q(__pos__)
-#endif
-
-Q(micropython)
-Q(bytecode)
-Q(const)
-
-#if MICROPY_EMIT_NATIVE
-Q(native)
-Q(viper)
-Q(uint)
-Q(ptr)
-Q(ptr8)
-Q(ptr16)
-Q(ptr32)
-#endif
-
-#if MICROPY_EMIT_INLINE_THUMB
-Q(asm_thumb)
-Q(label)
-Q(align)
-Q(data)
-Q(uint)
-Q(nop)
-Q(mov)
-Q(and_)
-Q(cmp)
-Q(add)
-Q(sub)
-Q(lsl)
-Q(lsr)
-Q(asr)
-Q(ldr)
-Q(ldrb)
-Q(ldrh)
-Q(str)
-Q(strb)
-Q(strh)
-Q(b)
-Q(bl)
-Q(bx)
-Q(push)
-Q(pop)
-Q(cpsid)
-Q(cpsie)
-Q(wfi)
-Q(clz)
-Q(rbit)
-Q(movw)
-Q(movt)
-Q(movwt)
-Q(mrs)
-Q(sdiv)
-Q(udiv)
-Q(ldrex)
-Q(strex)
-#if MICROPY_EMIT_INLINE_THUMB_FLOAT
-Q(vcmp)
-Q(vneg)
-Q(vcvt_f32_s32)
-Q(vcvt_s32_f32)
-Q(vsqrt)
-Q(vmov)
-Q(vmrs)
-Q(vldr)
-Q(vstr)
-#endif
-#endif
-
-Q(builtins)
-
-Q(Ellipsis)
-Q(StopIteration)
-#if MICROPY_PY_BUILTINS_NOTIMPLEMENTED
-Q(NotImplemented)
-#endif
-
-Q(BaseException)
-Q(ArithmeticError)
-Q(AssertionError)
-Q(AttributeError)
-Q(BufferError)
-Q(EOFError)
-Q(Exception)
-Q(FileExistsError)
-Q(FileNotFoundError)
-Q(FloatingPointError)
-Q(GeneratorExit)
-Q(ImportError)
-Q(IndentationError)
-Q(IndexError)
-Q(KeyboardInterrupt)
-Q(KeyError)
-Q(LookupError)
-Q(MemoryError)
-Q(NameError)
-Q(NotImplementedError)
-Q(OSError)
-#if MICROPY_PY_BUILTINS_TIMEOUTERROR
-Q(TimeoutError)
-#endif
-Q(OverflowError)
-Q(RuntimeError)
-Q(SyntaxError)
-Q(SystemExit)
-Q(TypeError)
-Q(UnboundLocalError)
-Q(ValueError)
-#if MICROPY_EMIT_NATIVE
-Q(ViperTypeError)
-#endif
-Q(ZeroDivisionError)
-#if MICROPY_PY_BUILTINS_STR_UNICODE
-Q(UnicodeError)
-#endif
-
-Q(None)
-Q(False)
-Q(True)
-Q(object)
-
-Q(NoneType)
-
-#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
-Q(OrderedDict)
-#endif
-
-Q(abs)
-Q(all)
-Q(any)
-Q(args)
-#if MICROPY_PY_ARRAY
-Q(array)
-#endif
-Q(bin)
+Q(%#o)
+Q(%#x)
Q({:#b})
-Q(bool)
-#if MICROPY_PY_BUILTINS_BYTEARRAY
-Q(bytearray)
-#endif
-#if MICROPY_PY_BUILTINS_MEMORYVIEW
-Q(memoryview)
-#endif
-Q(bytes)
-Q(callable)
-Q(chr)
-Q(classmethod)
-Q(_collections)
-#if MICROPY_PY_BUILTINS_COMPLEX
-Q(complex)
-Q(real)
-Q(imag)
-#endif
-Q(dict)
-Q(dir)
-Q(divmod)
-#if MICROPY_PY_BUILTINS_ENUMERATE
-Q(enumerate)
-#endif
-Q(eval)
-Q(exec)
-#if MICROPY_PY_BUILTINS_EXECFILE
-Q(execfile)
-#endif
-#if MICROPY_PY_BUILTINS_FILTER
-Q(filter)
-#endif
-#if MICROPY_PY_BUILTINS_FLOAT
-Q(float)
-#endif
-Q(from_bytes)
-Q(getattr)
-Q(setattr)
-Q(globals)
-Q(hasattr)
-Q(hash)
-Q(hex)
-Q(%#x)
-Q(id)
-Q(int)
-Q(isinstance)
-Q(issubclass)
-Q(iter)
-Q(len)
-Q(list)
-Q(locals)
-Q(map)
-#if MICROPY_PY_BUILTINS_MIN_MAX
-Q(max)
-Q(min)
-Q(default)
-#endif
-Q(namedtuple)
-Q(next)
-Q(oct)
-Q(%#o)
-Q(open)
-Q(ord)
-Q(path)
-Q(pow)
-Q(print)
-Q(range)
-Q(read)
-Q(repr)
-Q(reversed)
-Q(round)
-Q(sorted)
-Q(staticmethod)
-Q(sum)
-Q(super)
-Q(str)
-Q(sys)
-Q(to_bytes)
-Q(tuple)
-Q(type)
-Q(value)
-Q(write)
-Q(zip)
-
-#if MICROPY_PY_BUILTINS_COMPILE
-Q(compile)
-Q(code)
-Q(single)
-#endif
-
-Q(sep)
-Q(end)
-
-#if MICROPY_PY_BUILTINS_RANGE_ATTRS
-Q(step)
-Q(stop)
-#endif
-
-Q(clear)
-Q(copy)
-Q(fromkeys)
-Q(get)
-Q(items)
-Q(keys)
-Q(pop)
-Q(popitem)
-Q(setdefault)
-Q(update)
-Q(values)
-Q(append)
-Q(close)
-Q(send)
-Q(throw)
-Q(count)
-Q(extend)
-Q(index)
-Q(remove)
-Q(insert)
-Q(pop)
-Q(sort)
-Q(join)
-Q(strip)
-Q(lstrip)
-Q(rstrip)
-Q(format)
-Q(key)
-Q(reverse)
-Q(add)
-Q(clear)
-Q(copy)
-Q(pop)
-Q(remove)
-Q(find)
-Q(rfind)
-Q(rindex)
-Q(split)
-#if MICROPY_PY_BUILTINS_STR_SPLITLINES
-Q(splitlines)
-Q(keepends)
Q(\n)
-#endif
-Q(rsplit)
-Q(startswith)
-Q(endswith)
-Q(replace)
-Q(partition)
-Q(rpartition)
-Q(lower)
-Q(upper)
-Q(isspace)
-Q(isalpha)
-Q(isdigit)
-Q(isupper)
-Q(islower)
-Q(iterable)
-Q(start)
-
-Q(bound_method)
-Q(closure)
-Q(dict_view)
-Q(function)
-Q(generator)
-Q(iterator)
-Q(module)
-Q(slice)
-
-#if MICROPY_PY_BUILTINS_SET
-Q(discard)
-Q(difference)
-Q(difference_update)
-Q(intersection)
-Q(intersection_update)
-Q(isdisjoint)
-Q(issubset)
-Q(issuperset)
-Q(set)
-Q(symmetric_difference)
-Q(symmetric_difference_update)
-Q(union)
-Q(update)
-#endif
-
-#if MICROPY_PY_BUILTINS_FROZENSET
-Q(frozenset)
-#endif
-
-#if MICROPY_PY_MATH || MICROPY_PY_CMATH
-Q(math)
-Q(e)
-Q(pi)
-Q(sqrt)
-Q(pow)
-Q(exp)
-#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
-Q(expm1)
-#endif
-Q(log)
-#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
-Q(log2)
-Q(log10)
-Q(cosh)
-Q(sinh)
-Q(tanh)
-Q(acosh)
-Q(asinh)
-Q(atanh)
-#endif
-Q(cos)
-Q(sin)
-Q(tan)
-Q(acos)
-Q(asin)
-Q(atan)
-Q(atan2)
-Q(ceil)
-Q(copysign)
-Q(fabs)
-Q(fmod)
-Q(floor)
-Q(isfinite)
-Q(isinf)
-Q(isnan)
-Q(trunc)
-Q(modf)
-Q(frexp)
-Q(ldexp)
-Q(degrees)
-Q(radians)
-#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
-Q(erf)
-Q(erfc)
-Q(gamma)
-Q(lgamma)
-#endif
-#endif
-
-#if MICROPY_PY_CMATH
-Q(cmath)
-Q(phase)
-Q(polar)
-Q(rect)
-#endif
-
-#if MICROPY_PY_MICROPYTHON_MEM_INFO
-#if MICROPY_MEM_STATS
-Q(mem_total)
-Q(mem_current)
-Q(mem_peak)
-#endif
-Q(mem_info)
-Q(qstr_info)
-#if MICROPY_STACK_CHECK
-Q(stack_use)
-#endif
-#endif
-#if MICROPY_ENABLE_GC
-Q(heap_lock)
-Q(heap_unlock)
-#endif
-
-#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && (MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0)
-Q(alloc_emergency_exception_buf)
-#endif
Q(maximum recursion depth exceeded)
-
Q(<module>)
Q(<lambda>)
Q(<listcomp>)
@@ -499,265 +49,12 @@
Q(<genexpr>)
Q(<string>)
Q(<stdin>)
-
-#if MICROPY_CPYTHON_COMPAT
-Q(encode)
-Q(decode)
Q(utf-8)
-#endif
-
-#if MICROPY_PY_SYS
-Q(argv)
-Q(byteorder)
-Q(big)
-Q(exit)
-Q(little)
-#ifdef MICROPY_PY_SYS_PLATFORM
-Q(platform)
-#endif
-Q(stdin)
-Q(stdout)
-Q(stderr)
-#if MICROPY_PY_SYS_STDIO_BUFFER
-Q(buffer)
-#endif
-Q(version)
-Q(version_info)
-#if MICROPY_PY_ATTRTUPLE
-Q(name)
-#endif
-Q(implementation)
-#if MICROPY_PY_SYS_MAXSIZE
-Q(maxsize)
-#endif
-#if MICROPY_PY_SYS_MODULES
-Q(modules)
-#endif
-#if MICROPY_PY_SYS_EXC_INFO
-Q(exc_info)
-#endif
-Q(print_exception)
-#endif
-
-#if MICROPY_PY_STRUCT
-Q(struct)
-Q(ustruct)
-Q(pack)
-Q(pack_into)
-Q(unpack)
-Q(unpack_from)
-Q(calcsize)
-#endif
-
-#if MICROPY_PY_UCTYPES
-Q(uctypes)
-Q(struct)
-Q(sizeof)
-Q(addressof)
-Q(bytes_at)
-Q(bytearray_at)
-
-Q(NATIVE)
-Q(LITTLE_ENDIAN)
-Q(BIG_ENDIAN)
-
-Q(VOID)
-
-Q(UINT8)
-Q(INT8)
-Q(UINT16)
-Q(INT16)
-Q(UINT32)
-Q(INT32)
-Q(UINT64)
-Q(INT64)
-
-Q(BFUINT8)
-Q(BFINT8)
-Q(BFUINT16)
-Q(BFINT16)
-Q(BFUINT32)
-Q(BFINT32)
-
-Q(FLOAT32)
-Q(FLOAT64)
-
-Q(ARRAY)
-Q(PTR)
-//Q(BITFIELD)
-
-Q(BF_POS)
-Q(BF_LEN)
-#endif
-
-#if MICROPY_PY_IO
-Q(_io)
-Q(readall)
-Q(readinto)
-Q(readline)
-Q(readlines)
-Q(seek)
-Q(tell)
-Q(FileIO)
-Q(TextIOWrapper)
-Q(StringIO)
-Q(BytesIO)
-Q(getvalue)
-Q(file)
-Q(mode)
-Q(r)
-Q(encoding)
-#if MICROPY_PY_IO_BUFFEREDWRITER
-Q(BufferedWriter)
-#endif
-#endif
-
-#if MICROPY_PY_GC
-Q(gc)
-Q(collect)
-Q(disable)
-Q(enable)
-Q(isenabled)
-Q(mem_free)
-Q(mem_alloc)
-#endif
-
-#if MICROPY_PY_BUILTINS_PROPERTY
-Q(property)
-Q(getter)
-Q(setter)
-Q(deleter)
-Q(doc)
-#endif
-#if MICROPY_PY_UZLIB
-Q(uzlib)
-Q(decompress)
-#endif
-
-#if MICROPY_PY_UJSON
-Q(ujson)
-Q(dumps)
-Q(loads)
-#endif
-
-#if MICROPY_PY_URE
-Q(ure)
-Q(compile)
-Q(match)
-Q(search)
-Q(group)
-Q(DEBUG)
-#endif
-
-#if MICROPY_PY_UHEAPQ
-Q(uheapq)
-Q(heappush)
-Q(heappop)
-Q(heapify)
-#endif
-
-#if MICROPY_PY_UHASHLIB
-Q(uhashlib)
-Q(update)
-Q(digest)
-Q(sha256)
-Q(sha1)
-#endif
-
-#if MICROPY_PY_UBINASCII
-Q(ubinascii)
-Q(hexlify)
-Q(unhexlify)
-Q(a2b_base64)
-Q(b2a_base64)
-#endif
-
-#if MICROPY_PY_MACHINE
-Q(umachine)
-Q(mem)
-Q(mem8)
-Q(mem16)
-Q(mem32)
-#endif
-
-#if MICROPY_PY_USSL
-Q(ussl)
-Q(wrap_socket)
-#endif
-
-#if MICROPY_PY_LWIP
-// for lwip module
-Q(lwip)
-Q(reset)
-Q(callback)
-Q(socket)
-Q(AF_INET)
-Q(AF_INET6)
-Q(SOCK_STREAM)
-Q(SOCK_DGRAM)
-Q(SOCK_RAW)
-Q(SOL_SOCKET)
-Q(SO_REUSEADDR)
-// for lwip.socket
-Q(close)
-Q(bind)
-Q(listen)
-Q(accept)
-Q(connect)
-Q(send)
-Q(recv)
-Q(sendto)
-Q(recvfrom)
-Q(settimeout)
-Q(setsockopt)
-Q(makefile)
-#if MICROPY_PY_LWIP_SLIP
-// for lwip.slip
-Q(slip)
-Q(status)
-#endif
-#endif
-
-#if MICROPY_FSUSERMOUNT
-// for user-mountable block devices
-Q(mount)
-Q(umount)
-Q(readonly)
-Q(mkfs)
-Q(listdir)
-Q(mkdir)
-Q(remove)
-Q(rename)
-Q(readblocks)
-Q(writeblocks)
-Q(ioctl)
-Q(sync)
-Q(count)
-#endif
-
-#if MICROPY_PY_OS_DUPTERM
-Q(dupterm)
-#endif
-
-#if MICROPY_PY_URANDOM
-Q(urandom)
-Q(getrandbits)
-Q(seed)
-#if MICROPY_PY_URANDOM_EXTRA_FUNCS
-Q(randrange)
-Q(randint)
-Q(choice)
-Q(random)
-Q(uniform)
-#endif
-#endif
-
-#if MICROPY_VFS_FAT
-Q(VfsFat)
-Q(flush)
-#endif
-
-#if MICROPY_PY_WEBSOCKET
-Q(websocket)
-#endif
+// The following qstrings not referenced from anywhere in the sources
+Q(__locals__)
+Q(BufferError)
+Q(FileExistsError)
+Q(FileNotFoundError)
+Q(FloatingPointError)
+Q(UnboundLocalError)
--- a/py/repl.c Sat Apr 16 22:42:43 2016 +0100
+++ b/py/repl.c Sat Apr 16 22:43:41 2016 +0100
@@ -57,6 +57,9 @@
|| str_startswith_word(input, "with")
|| str_startswith_word(input, "def")
|| str_startswith_word(input, "class")
+ #if MICROPY_PY_ASYNC_AWAIT
+ || str_startswith_word(input, "async")
+ #endif
;
// check for unmatched open bracket, quote or escape quote