"I'm not familiar with Makefile" says nothing about my programming skills/level. It mean right what it mean.
, your code help me a lot! Thanks! I've made async def as I want (just mark functions as generators
) and made available them to be decorated. Here is diff:
Code: Select all
diff --git a/py/compile.c b/py/compile.c
index f349dca..bab638f 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -717,6 +717,14 @@ STATIC qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns
return fscope->simple_name;
}
+STATIC qstr compile_async_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
+ assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[0]));
+ mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
+ qstr afname = compile_funcdef_helper(comp, pns0, emit_options);
+ scope_t *fscope = (scope_t*)pns0->nodes[4];
+ fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
+ return afname;
+}
// leaves class object on stack
// returns class name
STATIC qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
@@ -829,6 +837,8 @@ STATIC void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
qstr body_name = 0;
if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
body_name = compile_funcdef_helper(comp, pns_body, emit_options);
+ } else if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_async_funcdef) {
+ body_name = compile_async_funcdef_helper(comp, pns_body, emit_options);
} else {
assert(MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef); // should be
body_name = compile_classdef_helper(comp, pns_body, emit_options);
@@ -849,6 +859,12 @@ STATIC void compile_funcdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_store_id(comp, fname);
}
+STATIC void compile_async_funcdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
+ qstr fname = compile_async_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
+ // store function object into function name
+ compile_store_id(comp, fname);
+}
+
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));
@@ -1405,7 +1421,7 @@ STATIC void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// 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)) {
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])) {
diff --git a/py/grammar.h b/py/grammar.h
index b7036c8..741c034 100644
--- a/py/grammar.h
+++ b/py/grammar.h
@@ -46,8 +46,9 @@ 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]
@@ -57,8 +58,9 @@ DEF_RULE(eval_input_2, nc, and(1), tok(NEWLINE))
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_body, nc, or(2), rule(classdef), rule(funcdef))
+DEF_RULE(decorated_body, nc, or(3), rule(classdef), rule(funcdef), rule(async_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(async_funcdef, c(async_funcdef), and(2), tok(KW_ASYNC), rule(funcdef))
DEF_RULE(funcdefrettype, nc, ident | and(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))
@@ -157,7 +159,7 @@ 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))
-// 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_funcdef
// 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]
@@ -168,7 +170,7 @@ DEF_RULE(assert_stmt_extra, nc, ident | and(2), tok(DEL_COMMA), rule(test))
// with_item: test ['as' expr]
// suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
-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))
+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_funcdef))
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))
diff --git a/py/lexer.c b/py/lexer.c
index 89ecc38..e67840a 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -261,6 +261,7 @@ STATIC const char *tok_kw[] = {
"while",
"with",
"yield",
+ "async",
"__debug__",
};
diff --git a/py/lexer.h b/py/lexer.h
index 36d1e99..e3017bf 100644
--- a/py/lexer.h
+++ b/py/lexer.h
@@ -90,6 +90,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_WHILE,
MP_TOKEN_KW_WITH,
MP_TOKEN_KW_YIELD,
+ MP_TOKEN_KW_ASYNC,
MP_TOKEN_OP_PLUS, // 47
MP_TOKEN_OP_MINUS,
diff --git a/py/repl.c b/py/repl.c
index 182961b..4b3dcf9 100644
--- a/py/repl.c
+++ b/py/repl.c
@@ -57,6 +57,7 @@ bool mp_repl_continue_with_input(const char *input) {
|| str_startswith_word(input, "with")
|| str_startswith_word(input, "def")
|| str_startswith_word(input, "class")
+ || str_startswith_word(input, "async")
;
// check for unmatched open bracket, quote or escape quote