feat: add await syntax for direct async function calls and new generator/phonebook apps
Add compiler support for calling async functions directly with `await fn(args)` syntax, automatically translating to `await fn.call(args)`. Introduce `create_merge` Makefile target for merging Wren source files. Include new `apps/generator.wren` source code generator using OpenRouter API, `apps/phonebook.wren` CLI phonebook with SQLite backend, and `apps/minitut.md` Wren tutorial reference. Update `example/await_demo.wren` with parameterized async functions, nested awaits, and expression usage. Fix JSON parsing in `example/openrouter_demo.wren` to strip markdown code fences. Document new await syntax in `manual/api/scheduler.html`.
This commit is contained in:
Vendored
+81
-9
@@ -2534,7 +2534,52 @@ static void await_(Compiler* compiler, bool canAssign)
|
||||
emitShortArg(compiler, CODE_LOAD_MODULE_VAR, schedulerSymbol);
|
||||
|
||||
ignoreNewlines(compiler);
|
||||
expression(compiler);
|
||||
|
||||
if (peek(compiler) == TOKEN_NAME)
|
||||
{
|
||||
Token nameToken = compiler->parser->current;
|
||||
Variable variable = resolveNonmodule(compiler, nameToken.start, nameToken.length);
|
||||
|
||||
if (variable.index == -1)
|
||||
{
|
||||
variable.scope = SCOPE_MODULE;
|
||||
variable.index = wrenSymbolTableFind(&compiler->parser->module->variableNames,
|
||||
nameToken.start, nameToken.length);
|
||||
}
|
||||
|
||||
if (variable.index != -1)
|
||||
{
|
||||
TokenType following = peekNext(compiler);
|
||||
|
||||
if (following == TOKEN_LEFT_PAREN)
|
||||
{
|
||||
nextToken(compiler->parser);
|
||||
loadVariable(compiler, variable);
|
||||
|
||||
Signature signature = { "call", 4, SIG_GETTER, 0 };
|
||||
methodCall(compiler, CODE_CALL_0, &signature);
|
||||
|
||||
allowLineBeforeDot(compiler);
|
||||
while (match(compiler, TOKEN_DOT))
|
||||
{
|
||||
namedCall(compiler, false, CODE_CALL_0);
|
||||
allowLineBeforeDot(compiler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
expression(compiler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
expression(compiler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
expression(compiler);
|
||||
}
|
||||
|
||||
callMethod(compiler, 1, "await_(_)", 9);
|
||||
}
|
||||
@@ -2544,18 +2589,45 @@ static void async_(Compiler* compiler, bool canAssign)
|
||||
int schedulerSymbol = resolveScheduler(compiler);
|
||||
if (schedulerSymbol == -1) return;
|
||||
|
||||
emitShortArg(compiler, CODE_LOAD_MODULE_VAR, schedulerSymbol);
|
||||
|
||||
consume(compiler, TOKEN_LEFT_BRACE, "Expect '{' after 'async'.");
|
||||
|
||||
Compiler fnCompiler;
|
||||
initCompiler(&fnCompiler, compiler->parser, compiler, false);
|
||||
fnCompiler.fn->arity = 0;
|
||||
if (match(compiler, TOKEN_PIPE))
|
||||
{
|
||||
Compiler outerCompiler;
|
||||
initCompiler(&outerCompiler, compiler->parser, compiler, false);
|
||||
|
||||
finishBody(&fnCompiler);
|
||||
endCompiler(&fnCompiler, "[async]", 7);
|
||||
Signature outerSignature = { "", 0, SIG_METHOD, 0 };
|
||||
finishParameterList(&outerCompiler, &outerSignature);
|
||||
consume(compiler, TOKEN_PIPE, "Expect '|' after parameters.");
|
||||
outerCompiler.fn->arity = outerSignature.arity;
|
||||
|
||||
callMethod(compiler, 1, "async_(_)", 9);
|
||||
emitShortArg(&outerCompiler, CODE_LOAD_MODULE_VAR, schedulerSymbol);
|
||||
|
||||
Compiler innerCompiler;
|
||||
initCompiler(&innerCompiler, outerCompiler.parser, &outerCompiler, false);
|
||||
innerCompiler.fn->arity = 0;
|
||||
|
||||
finishBody(&innerCompiler);
|
||||
endCompiler(&innerCompiler, "[async]", 7);
|
||||
|
||||
callMethod(&outerCompiler, 1, "async_(_)", 9);
|
||||
emitOp(&outerCompiler, CODE_RETURN);
|
||||
|
||||
endCompiler(&outerCompiler, "[async fn]", 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
emitShortArg(compiler, CODE_LOAD_MODULE_VAR, schedulerSymbol);
|
||||
|
||||
Compiler fnCompiler;
|
||||
initCompiler(&fnCompiler, compiler->parser, compiler, false);
|
||||
fnCompiler.fn->arity = 0;
|
||||
|
||||
finishBody(&fnCompiler);
|
||||
endCompiler(&fnCompiler, "[async]", 7);
|
||||
|
||||
callMethod(compiler, 1, "async_(_)", 9);
|
||||
}
|
||||
}
|
||||
|
||||
// Subscript or "array indexing" operator like `foo[bar]`.
|
||||
|
||||
Reference in New Issue
Block a user