diff options
Diffstat (limited to 'src/parser/parser_utils.c')
| -rw-r--r-- | src/parser/parser_utils.c | 115 |
1 files changed, 78 insertions, 37 deletions
diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c index 918e8e1..97e6e78 100644 --- a/src/parser/parser_utils.c +++ b/src/parser/parser_utils.c @@ -1991,10 +1991,9 @@ char *instantiate_function_template(ParserContext *ctx, const char *name, const char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms, int *count) { - (void)ctx; // suppress unused parameter warning - char *gen = xmalloc(4096); + char *gen = xmalloc(8192); // Increased buffer size - strcpy(gen, "({ static char _b[1024]; _b[0]=0; char _t[128]; "); + strcpy(gen, "({ static char _b[4096]; _b[0]=0; char _t[1024]; "); char *s = xstrdup(content); char *cur = s; @@ -2048,7 +2047,7 @@ char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms } *p = 0; - char *expr = brace + 1; + char *expr_str = brace + 1; char *fmt = NULL; if (colon) { @@ -2056,34 +2055,19 @@ char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms 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; - } + // Parse expression fully to handle default arguments etc. + Lexer expr_lex; + lexer_init(&expr_lex, expr_str); + ASTNode *expr_node = parse_expression(ctx, &expr_lex); - if (used_syms && count) - { - *used_syms = xrealloc(*used_syms, sizeof(char *) * (*count + 1)); - (*used_syms)[*count] = name; - (*count)++; - } - else - { - free(name); - } - } - } + // Codegen expression to temporary buffer + char *code_buffer = NULL; + size_t code_len = 0; + FILE *mem_stream = open_memstream(&code_buffer, &code_len); + if (mem_stream) + { + codegen_expression(ctx, expr_node, mem_stream); + fclose(mem_stream); } if (fmt) @@ -2091,18 +2075,44 @@ char *process_fstring(ParserContext *ctx, const char *content, char ***used_syms strcat(gen, "sprintf(_t, \"%"); strcat(gen, fmt); strcat(gen, "\", "); - strcat(gen, expr); + if (code_buffer) + { + strcat(gen, code_buffer); + } + else + { + strcat(gen, expr_str); // Fallback + } strcat(gen, "); strcat(_b, _t); "); } else { strcat(gen, "sprintf(_t, _z_str("); - strcat(gen, expr); + if (code_buffer) + { + strcat(gen, code_buffer); + } + else + { + strcat(gen, expr_str); + } strcat(gen, "), "); - strcat(gen, expr); + if (code_buffer) + { + strcat(gen, code_buffer); + } + else + { + strcat(gen, expr_str); + } strcat(gen, "); strcat(_b, _t); "); } + if (code_buffer) + { + free(code_buffer); + } + cur = p + 1; } @@ -3261,9 +3271,40 @@ char *parse_and_convert_args(ParserContext *ctx, Lexer *l, char ***defaults_out, if (lexer_peek(l).type == TOK_OP && is_token(lexer_peek(l), "=")) { - lexer_next(l); - Token val = lexer_next(l); - defaults[count - 1] = token_strdup(val); + lexer_next(l); // consume = + + const char *start_ptr = lexer_peek(l).start; + int nesting = 0; + while (1) + { + Token t = lexer_peek(l); + if (t.type == TOK_EOF) + { + zpanic_at(t, "Unexpected EOF in default arg"); + } + + if (nesting == 0 && (t.type == TOK_COMMA || t.type == TOK_RPAREN)) + { + break; + } + + if (t.type == TOK_LPAREN || t.type == TOK_LBRACE || t.type == TOK_LBRACKET) + { + nesting++; + } + if (t.type == TOK_RPAREN || t.type == TOK_RBRACE || t.type == TOK_RBRACKET) + { + nesting--; + } + + lexer_next(l); + } + const char *end_ptr = lexer_peek(l).start; + size_t len = end_ptr - start_ptr; + char *def_val = xmalloc(len + 1); + strncpy(def_val, start_ptr, len); + def_val[len] = 0; + defaults[count - 1] = def_val; } } if (lexer_peek(l).type == TOK_COMMA) |
