diff --git a/astgen.c b/astgen.c index 77eec9926e..3c56339bcb 100644 --- a/astgen.c +++ b/astgen.c @@ -9547,11 +9547,33 @@ static bool nodesNeedRlContains(const AstGenCtx* ag, uint32_t node) { } // Compare two identifier tokens by their source text. +// Handles both regular identifiers and @"..."-quoted identifiers. static bool rlTokenIdentEqual( const Ast* tree, uint32_t tok_a, uint32_t tok_b) { const char* src = tree->source; uint32_t a_start = tree->tokens.starts[tok_a]; uint32_t b_start = tree->tokens.starts[tok_b]; + bool a_quoted = (src[a_start] == '@'); + bool b_quoted = (src[b_start] == '@'); + if (a_quoted != b_quoted) + return false; + if (a_quoted) { + // Both are @"..."-quoted: skip '@"' prefix, compare up to '"'. + uint32_t ai = a_start + 2; + uint32_t bi = b_start + 2; + for (;;) { + char ca = src[ai]; + char cb = src[bi]; + if (ca == '"' && cb == '"') + return true; + if (ca == '"' || cb == '"') + return false; + if (ca != cb) + return false; + ai++; + bi++; + } + } for (uint32_t i = 0;; i++) { char ca = src[a_start + i]; char cb = src[b_start + i]; @@ -9998,10 +10020,13 @@ static bool rlExpr( else_node = tree->extra_data.arr[nd.rhs + 2]; } uint32_t main_tok = tree->nodes.main_tokens[node]; + uint32_t tok_i = main_tok; + if (tok_i >= 1 && tree->tokens.tags[tok_i - 1] == TOKEN_KEYWORD_INLINE) + tok_i = tok_i - 1; bool is_labeled - = (main_tok >= 2 && tree->tokens.tags[main_tok - 1] == TOKEN_COLON - && tree->tokens.tags[main_tok - 2] == TOKEN_IDENTIFIER); - uint32_t label_token = is_labeled ? main_tok - 2 : UINT32_MAX; + = (tok_i >= 2 && tree->tokens.tags[tok_i - 1] == TOKEN_COLON + && tree->tokens.tags[tok_i - 2] == TOKEN_IDENTIFIER); + uint32_t label_token = is_labeled ? tok_i - 2 : UINT32_MAX; // Detect payload/error. uint32_t last_cond_tok = lastToken(tree, cond_node); @@ -10069,10 +10094,14 @@ static bool rlExpr( } uint32_t main_tok = tree->nodes.main_tokens[node]; - bool is_labeled - = (main_tok >= 2 && tree->tokens.tags[main_tok - 1] == TOKEN_COLON - && tree->tokens.tags[main_tok - 2] == TOKEN_IDENTIFIER); - uint32_t label_token = is_labeled ? main_tok - 2 : UINT32_MAX; + uint32_t for_tok_i = main_tok; + if (for_tok_i >= 1 + && tree->tokens.tags[for_tok_i - 1] == TOKEN_KEYWORD_INLINE) + for_tok_i = for_tok_i - 1; + bool is_labeled = (for_tok_i >= 2 + && tree->tokens.tags[for_tok_i - 1] == TOKEN_COLON + && tree->tokens.tags[for_tok_i - 2] == TOKEN_IDENTIFIER); + uint32_t label_token = is_labeled ? for_tok_i - 2 : UINT32_MAX; for (uint32_t i = 0; i < num_inputs; i++) { uint32_t input = inputs[i]; @@ -10646,8 +10675,15 @@ static bool rlExpr( case AST_NODE_AWAIT: (void)rlExpr(ag, nd.lhs, block, RL_RI_NONE); return false; - case AST_NODE_ASSIGN_DESTRUCTURE: - return false; // TODO if needed + case AST_NODE_ASSIGN_DESTRUCTURE: { + uint32_t extra_start = nd.lhs; + uint32_t variable_count = tree->extra_data.arr[extra_start]; + for (uint32_t i = 0; i < variable_count; i++) + (void)rlExpr(ag, tree->extra_data.arr[extra_start + 1 + i], block, + RL_RI_NONE); + (void)rlExpr(ag, nd.rhs, block, RL_RI_NONE); + return false; + } case AST_NODE_ASYNC_CALL_ONE: case AST_NODE_ASYNC_CALL_ONE_COMMA: case AST_NODE_ASYNC_CALL: