Colin Hogben / micropython

Dependents:   micropython-repl

Files at this revision

API Documentation at this revision

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

lib/utils/pyexec.c Show annotated file Show diff for this revision Revisions of this file
py/builtin.h Show annotated file Show diff for this revision Revisions of this file
py/builtinimport.c Show annotated file Show diff for this revision Revisions of this file
py/compile.c Show annotated file Show diff for this revision Revisions of this file
py/emitglue.c Show annotated file Show diff for this revision Revisions of this file
py/emitglue.h Show annotated file Show diff for this revision Revisions of this file
py/frozenmod.c Show annotated file Show diff for this revision Revisions of this file
py/frozenmod.h Show annotated file Show diff for this revision Revisions of this file
py/grammar.h Show annotated file Show diff for this revision Revisions of this file
py/lexer.c Show annotated file Show diff for this revision Revisions of this file
py/lexer.h Show annotated file Show diff for this revision Revisions of this file
py/map.c Show annotated file Show diff for this revision Revisions of this file
py/modbuiltins.c Show annotated file Show diff for this revision Revisions of this file
py/mpconfig.h Show annotated file Show diff for this revision Revisions of this file
py/obj.h Show annotated file Show diff for this revision Revisions of this file
py/objexcept.c Show annotated file Show diff for this revision Revisions of this file
py/objmodule.c Show annotated file Show diff for this revision Revisions of this file
py/objstr.c Show annotated file Show diff for this revision Revisions of this file
py/parse.c Show annotated file Show diff for this revision Revisions of this file
py/qstr.c Show annotated file Show diff for this revision Revisions of this file
py/qstr.h Show annotated file Show diff for this revision Revisions of this file
py/qstrdefs.h Show annotated file Show diff for this revision Revisions of this file
py/repl.c Show annotated file Show diff for this revision Revisions of this file
--- 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