From 3df7cada4c3d050a01980afffdbfc0fc60be0fb5 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Sat, 24 Jan 2026 01:39:38 +0000 Subject: Fix for #106 --- src/parser/parser_expr.c | 40 ++----------------------------- src/parser/parser_type.c | 3 ++- src/parser/parser_utils.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index c848072..1556ee7 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -3623,44 +3623,8 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) } else if (is_token(t, "sizeof")) { - lexer_next(l); - if (lexer_peek(l).type == TOK_LPAREN) - { - const char *start = l->src + l->pos; - int depth = 0; - while (1) - { - Token tk = lexer_peek(l); - if (tk.type == TOK_EOF) - { - zpanic_at(tk, "Unterminated sizeof"); - } - if (tk.type == TOK_LPAREN) - { - depth++; - } - if (tk.type == TOK_RPAREN) - { - depth--; - if (depth == 0) - { - lexer_next(l); - break; - } - } - lexer_next(l); - } - int len = (l->src + l->pos) - start; - char *content = xmalloc(len + 8); - sprintf(content, "sizeof%.*s", len, start); - lhs = ast_create(NODE_RAW_STMT); - lhs->raw_stmt.content = content; - lhs->type_info = type_new(TYPE_INT); - } - else - { - zpanic_at(lexer_peek(l), "sizeof must be followed by ("); - } + lexer_next(l); // consume sizeof + lhs = parse_sizeof_expr(ctx, l); } else { diff --git a/src/parser/parser_type.c b/src/parser/parser_type.c index 39a4dc7..5774571 100644 --- a/src/parser/parser_type.c +++ b/src/parser/parser_type.c @@ -483,7 +483,8 @@ Type *parse_type_base(ParserContext *ctx, Lexer *l) ty->is_explicit_struct = explicit_struct; // Handle Generics or - if (lexer_peek(l).type == TOK_LANGLE) + if (lexer_peek(l).type == TOK_LANGLE || + (lexer_peek(l).type == TOK_OP && strncmp(lexer_peek(l).start, "<", 1) == 0)) { lexer_next(l); // eat < Type *first_arg = parse_type_formal(ctx, l); diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c index 0b47d2a..05ea74a 100644 --- a/src/parser/parser_utils.c +++ b/src/parser/parser_utils.c @@ -1713,6 +1713,48 @@ ASTNode *copy_ast_replacing(ASTNode *n, const char *p, const char *c, const char replace_type_str(n->impl_trait.target_type, p, c, os, ns); new_node->impl_trait.methods = copy_ast_replacing(n->impl_trait.methods, p, c, os, ns); break; + case NODE_EXPR_SIZEOF: + if (n->size_of.target_type) + { + char *replaced = replace_type_str(n->size_of.target_type, p, c, os, ns); + if (replaced && strchr(replaced, '<')) + { + char *src = replaced; + char *mangled = xmalloc(strlen(src) * 2 + 1); + char *dst = mangled; + while (*src) + { + if (*src == '<' || *src == ',') + { + *dst++ = '_'; + while (*(src + 1) == ' ') + { + src++; // skip space + } + } + else if (*src == '>') + { + // skip + } + else if (*src == '*') + { + strcpy(dst, "Ptr"); + dst += 3; + } + else if (!isspace(*src)) + { + *dst++ = *src; + } + src++; + } + *dst = 0; + free(replaced); + replaced = mangled; + } + new_node->size_of.target_type = replaced; + } + new_node->size_of.expr = copy_ast_replacing(n->size_of.expr, p, c, os, ns); + break; default: break; } @@ -2408,8 +2450,13 @@ void instantiate_generic(ParserContext *ctx, const char *tpl, const char *arg, i->type_info->traits = t->struct_node->type_info->traits; i->type_info->is_restrict = t->struct_node->type_info->is_restrict; } - - // Use first generic param for substitution (single-param backward compat) + i->strct.is_packed = t->struct_node->strct.is_packed; + i->strct.is_union = t->struct_node->strct.is_union; + i->strct.align = t->struct_node->strct.align; + if (t->struct_node->strct.parent) + { + i->strct.parent = xstrdup(t->struct_node->strct.parent); + } const char *gp = (t->struct_node->strct.generic_param_count > 0) ? t->struct_node->strct.generic_params[0] : "T"; @@ -2535,6 +2582,15 @@ void instantiate_generic_multi(ParserContext *ctx, const char *tpl, char **args, i->strct.name = xstrdup(m); i->strct.is_template = 0; + // Copy struct attributes + i->strct.is_packed = t->struct_node->strct.is_packed; + i->strct.is_union = t->struct_node->strct.is_union; + i->strct.align = t->struct_node->strct.align; + if (t->struct_node->strct.parent) + { + i->strct.parent = xstrdup(t->struct_node->strct.parent); + } + // Copy fields with sequential substitutions for each param ASTNode *fields = t->struct_node->strct.fields; int param_count = t->struct_node->strct.generic_param_count; -- cgit v1.2.3