summaryrefslogtreecommitdiff
path: root/src/parser/parser_utils.c
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-23 14:54:12 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-23 14:54:12 +0000
commit8d0ea93a7220730ccce754429549fd63e4eeaa7c (patch)
tree8af868229559a54829991a20b7641d6c608a108d /src/parser/parser_utils.c
parentf73df8d5de30a7f3f320fccf5f57c13094940a6a (diff)
Default arguments
Diffstat (limited to 'src/parser/parser_utils.c')
-rw-r--r--src/parser/parser_utils.c115
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)