Extend syntax
Posted: Wed Dec 16, 2015 10:46 pm
Hi, I want to extend syntax with async def/await. At first, just as sugar for mark function as generator and replace yield from with await. If so I will understand how hard it should be to implement async for/async with/awaitable objects etc.
Lets say I want async def:
1. Add MP_TOKEN_KW_ASYNC, to lexer.h right after MP_TOKEN_KW_YIELD.
2. Add "async", to lexer.c right after "yield",
3. Add rule to grammar.h (almost copy of function rule)
Here I understand, that there should be some changes for decorating async def, but lets omit this right now.
4. Add functions to compile.c
I thought it is enough and it even compiles, but...
So, what I missed? And it will be great if someone will explain the logic/flow of micropython compiling process.
Lets say I want async def:
1. Add MP_TOKEN_KW_ASYNC, to lexer.h right after MP_TOKEN_KW_YIELD.
2. Add "async", to lexer.c right after "yield",
3. Add rule to grammar.h (almost copy of function rule)
Code: Select all
DEF_RULE(asyncfuncdef, c(asyncfuncdef), blank | and(9), tok(KW_ASYNC), tok(KW_DEF), tok(NAME), tok(DEL_PAREN_OPEN), opt_rule(typedargslist), tok(DEL_PAREN_CLOSE), opt_rule(funcdefrettype), tok(DEL_COLON), rule(suite))
4. Add functions to compile.c
Code: Select all
STATIC void compile_asyncfuncdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
qstr fname = compile_asyncfuncdef_helper(comp, pns, comp->scope_cur->emit_options);
// store function object into function name
compile_store_id(comp, fname);
}
...
STATIC qstr compile_asyncfuncdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this function
scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options);
// store the function scope so the compiling function can use it at each pass
pns->nodes[4] = (mp_parse_node_t)s;
}
// get the scope for this function
scope_t *fscope = (scope_t*)pns->nodes[4];
fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
// compile the function definition
compile_funcdef_lambdef(comp, fscope, pns->nodes[1], PN_typedargslist);
// return its name (the 'f' in "def f(...):")
return fscope->simple_name;
}
Code: Select all
>>> async def yoba(): pass
Traceback (most recent call last):
File "<stdin>", line 1
SyntaxError: invalid syntax
>>>