From 8d7e628878aac07d0380463196f823502d1816ce Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Tue, 13 Jan 2026 12:58:55 +0000 Subject: Fix for #10 --- src/parser/parser.h | 1 + src/parser/parser_stmt.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/parser') diff --git a/src/parser/parser.h b/src/parser/parser.h index 4aeb2c8..e3a5e6b 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -265,6 +265,7 @@ struct ParserContext FILE *hoist_out; // For plugins to hoist code to file scope int skip_preamble; // If 1, codegen_node(NODE_ROOT) won't emit preamble int is_repl; // REPL mode flag + int has_async; // Track if async features are used }; // Token helpers diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index 8a89cc7..4478d22 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -37,6 +37,11 @@ ASTNode *parse_function(ParserContext *ctx, Lexer *l, int is_async) Token name_tok = lexer_next(l); char *name = token_strdup(name_tok); + if (is_async) + { + ctx->has_async = 1; + } + // Check for C reserved word conflict if (is_c_reserved_word(name)) { @@ -3876,7 +3881,7 @@ char *run_comptime_block(ParserContext *ctx, Lexer *l) zpanic("Could not create temp file %s", filename); } - emit_preamble(f); + emit_preamble(ctx, f); fprintf( f, "size_t _z_check_bounds(size_t index, size_t size) { if (index >= size) { fprintf(stderr, " -- cgit v1.2.3 From 6b0a0e7d7c017f78e7cca4a423fac686c0282575 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Tue, 13 Jan 2026 13:44:31 +0000 Subject: Fix for #29 --- src/ast/ast.h | 2 ++ src/parser/parser.h | 6 +++--- src/parser/parser_expr.c | 4 ++-- src/parser/parser_stmt.c | 47 +++++++++++++++++++++++++++++++++++++++-------- src/parser/parser_utils.c | 32 +++++++++++++++++++++++++++++++- 5 files changed, 77 insertions(+), 14 deletions(-) (limited to 'src/parser') diff --git a/src/ast/ast.h b/src/ast/ast.h index 8c5bff4..1e14369 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -416,6 +416,8 @@ struct ASTNode struct { char *content; + char **used_symbols; + int used_symbol_count; } raw_stmt; struct diff --git a/src/parser/parser.h b/src/parser/parser.h index e3a5e6b..9cdd0d2 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -377,7 +377,7 @@ void init_builtins(); // Expression rewriting char *rewrite_expr_methods(ParserContext *ctx, char *raw); -char *process_fstring(ParserContext *ctx, const char *content); +char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms, int *count); char *instantiate_function_template(ParserContext *ctx, const char *name, const char *concrete_type); FuncSig *find_func(ParserContext *ctx, const char *name); @@ -409,8 +409,8 @@ ASTNode *parse_guard(ParserContext *ctx, Lexer *l); ASTNode *parse_match(ParserContext *ctx, Lexer *l); ASTNode *parse_return(ParserContext *ctx, Lexer *l); -char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, - const char *target); +char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, const char *target, + char ***used_syms, int *count); ASTNode *parse_assert(ParserContext *ctx, Lexer *l); ASTNode *parse_defer(ParserContext *ctx, Lexer *l); ASTNode *parse_asm(ParserContext *ctx, Lexer *l); diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index f7af80f..9861de6 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -2240,7 +2240,7 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) } // Reuse printf sugar to generate the prompt print - char *print_code = process_printf_sugar(ctx, inner, 0, "stdout"); + char *print_code = process_printf_sugar(ctx, inner, 0, "stdout", NULL, NULL); free(inner); // Checks for (args...) suffix for SCAN mode @@ -2405,7 +2405,7 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) newline = 0; } - char *code = process_printf_sugar(ctx, inner, newline, "stderr"); + char *code = process_printf_sugar(ctx, inner, newline, "stderr", NULL, NULL); free(inner); ASTNode *n = ast_create(NODE_RAW_STMT); diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index 4478d22..484d742 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -1673,7 +1673,8 @@ ASTNode *parse_for(ParserContext *ctx, Lexer *l) return n; } -char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, const char *target) +char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, const char *target, + char ***used_syms, int *count) { char *gen = xmalloc(8192); strcpy(gen, "({ "); @@ -1765,12 +1766,34 @@ char *process_printf_sugar(ParserContext *ctx, const char *content, int newline, clean_expr++; // Skip leading spaces } - // Mark the variable as used (fixes "Unused variable" warnings for f-string - // interpolation) - Symbol *sym = find_symbol_entry(ctx, clean_expr); - if (sym) + // Analyze usage { - sym->is_used = 1; + Lexer lex; + lexer_init(&lex, clean_expr); + Token t; + while ((t = lexer_next(&lex)).type != TOK_EOF) + { + if (t.type == TOK_IDENT) + { + char *name = token_strdup(t); + Symbol *sym = find_symbol_entry(ctx, name); + if (sym) + { + sym->is_used = 1; + } + + if (used_syms && count) + { + *used_syms = xrealloc(*used_syms, sizeof(char *) * (*count + 1)); + (*used_syms)[*count] = name; + (*count)++; + } + else + { + free(name); + } + } + } } char *type = find_symbol_type(ctx, clean_expr); @@ -2097,7 +2120,9 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) // ; means println (end of line), .. means print (continuation) int is_ln = (next_type == TOK_SEMICOLON); - char *code = process_printf_sugar(ctx, inner, is_ln, "stdout"); + char **used_syms = NULL; + int used_count = 0; + char *code = process_printf_sugar(ctx, inner, is_ln, "stdout", &used_syms, &used_count); if (next_type == TOK_SEMICOLON) { @@ -2114,6 +2139,8 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) ASTNode *n = ast_create(NODE_RAW_STMT); n->raw_stmt.content = code; + n->raw_stmt.used_symbols = used_syms; + n->raw_stmt.used_symbol_count = used_count; free(inner); return n; } @@ -2506,7 +2533,9 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) inner[t.len - 2] = 0; } - char *code = process_printf_sugar(ctx, inner, is_ln, target); + char **used_syms = NULL; + int used_count = 0; + char *code = process_printf_sugar(ctx, inner, is_ln, target, &used_syms, &used_count); free(inner); if (lexer_peek(l).type == TOK_SEMICOLON) @@ -2516,6 +2545,8 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) ASTNode *n = ast_create(NODE_RAW_STMT); n->raw_stmt.content = code; + n->raw_stmt.used_symbols = used_syms; + n->raw_stmt.used_symbol_count = used_count; return n; } } diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c index 7733ef7..ba506a0 100644 --- a/src/parser/parser_utils.c +++ b/src/parser/parser_utils.c @@ -1554,7 +1554,7 @@ char *instantiate_function_template(ParserContext *ctx, const char *name, const return mangled; } -char *process_fstring(ParserContext *ctx, const char *content) +char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms, int *count) { (void)ctx; // suppress unused parameter warning char *gen = xmalloc(4096); @@ -1621,6 +1621,36 @@ char *process_fstring(ParserContext *ctx, const char *content) fmt = colon + 1; } + // Analyze usage in expression + { + Lexer lex; + lexer_init(&lex, expr); + Token t; + while ((t = lexer_next(&lex)).type != TOK_EOF) + { + if (t.type == TOK_IDENT) + { + char *name = token_strdup(t); + Symbol *sym = find_symbol_entry(ctx, name); + if (sym) + { + sym->is_used = 1; + } + + if (used_syms && count) + { + *used_syms = xrealloc(*used_syms, sizeof(char *) * (*count + 1)); + (*used_syms)[*count] = name; + (*count)++; + } + else + { + free(name); + } + } + } + } + if (fmt) { strcat(gen, "sprintf(_t, \"%"); -- cgit v1.2.3