aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 3a3e13f1d8..7ff24db184 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1237,6 +1237,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
// / IfExpr
// / KEYWORD_break BreakLabel? Expr?
// / KEYWORD_comptime Expr
+// / KEYWORD_noasync Expr
// / KEYWORD_continue BreakLabel?
// / KEYWORD_resume Expr
// / KEYWORD_return Expr?
@@ -1271,6 +1272,14 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
return res;
}
+ Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
+ if (noasync != nullptr) {
+ AstNode *expr = ast_expect(pc, ast_parse_expr);
+ AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
+ res->data.noasync_expr.expr = expr;
+ return res;
+ }
+
Token *continue_token = eat_token_if(pc, TokenIdKeywordContinue);
if (continue_token != nullptr) {
Token *label = ast_parse_break_label(pc);
@@ -1459,13 +1468,11 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
// SuffixExpr
// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
-// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments
// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
- Token *async_token = eat_token(pc);
- bool is_async = async_token->id == TokenIdKeywordAsync;
- if (is_async || async_token->id == TokenIdKeywordNoAsync) {
- if (is_async && eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
+ Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
+ if (async_token) {
+ if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
// HACK: If we see the keyword `fn`, then we assume that
// we are parsing an async fn proto, and not a call.
// We therefore put back all tokens consumed by the async
@@ -1515,13 +1522,12 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
assert(args->type == NodeTypeFnCallExpr);
AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async_token);
- res->data.fn_call_expr.modifier = is_async ? CallModifierAsync : CallModifierNoAsync;
+ res->data.fn_call_expr.modifier = CallModifierAsync;
res->data.fn_call_expr.seen = false;
res->data.fn_call_expr.fn_ref_expr = child;
res->data.fn_call_expr.params = args->data.fn_call_expr.params;
return res;
}
- put_back_token(pc);
AstNode *res = ast_parse_primary_type_expr(pc);
if (res == nullptr)
@@ -1582,6 +1588,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
// / IfTypeExpr
// / INTEGER
// / KEYWORD_comptime TypeExpr
+// / KEYWORD_noasync TypeExpr
// / KEYWORD_error DOT IDENTIFIER
// / KEYWORD_false
// / KEYWORD_null
@@ -1683,6 +1690,14 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
return res;
}
+ Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
+ if (noasync != nullptr) {
+ AstNode *expr = ast_expect(pc, ast_parse_type_expr);
+ AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
+ res->data.noasync_expr.expr = expr;
+ return res;
+ }
+
Token *error = eat_token_if(pc, TokenIdKeywordError);
if (error != nullptr) {
Token *dot = expect_token(pc, TokenIdDot);
@@ -2599,14 +2614,10 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
return res;
}
- Token *noasync_token = eat_token_if(pc, TokenIdKeywordNoAsync);
Token *await = eat_token_if(pc, TokenIdKeywordAwait);
if (await != nullptr) {
AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);
- res->data.await_expr.noasync_token = noasync_token;
return res;
- } else if (noasync_token != nullptr) {
- put_back_token(pc);
}
return nullptr;
@@ -3125,6 +3136,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeCompTime:
visit_field(&node->data.comptime_expr.expr, visit, context);
break;
+ case NodeTypeNoAsync:
+ visit_field(&node->data.comptime_expr.expr, visit, context);
+ break;
case NodeTypeBreak:
// none
break;