summaryrefslogtreecommitdiff
path: root/src/parser/parser_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/parser_expr.c')
-rw-r--r--src/parser/parser_expr.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c
index 8005e8e..3a205a8 100644
--- a/src/parser/parser_expr.c
+++ b/src/parser/parser_expr.c
@@ -65,6 +65,10 @@ static void validate_named_arguments(Token call_token, const char *func_name, ch
extern ASTNode *global_user_structs;
+// Forward declaration
+char *resolve_struct_name_from_type(ParserContext *ctx, Type *t, int *is_ptr_out,
+ char **allocated_out);
+
// Helper to check if a type is a struct type
int is_struct_type(ParserContext *ctx, const char *type_name)
{
@@ -3094,9 +3098,7 @@ ASTNode *parse_primary(ParserContext *ctx, Lexer *l)
int overloaded_get = 0;
if (node->type_info && node->type_info->kind != TYPE_ARRAY &&
- (node->type_info->kind == TYPE_STRUCT ||
- (node->type_info->kind == TYPE_POINTER && node->type_info->inner &&
- node->type_info->inner->kind == TYPE_STRUCT)))
+ node->type_info->kind == TYPE_STRUCT)
{
Type *st = node->type_info;
char *struct_name = (st->kind == TYPE_STRUCT) ? st->name : st->inner->name;
@@ -3200,12 +3202,11 @@ Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_na
}
}
- char *sname = struct_type->name;
- // Handle Pointers (User* -> User)
- if (struct_type->kind == TYPE_POINTER && struct_type->inner)
- {
- sname = struct_type->inner->name;
- }
+ // Use resolve_struct_name_from_type to handle Generics and Pointers correctly
+ int is_ptr = 0;
+ char *alloc_name = NULL;
+ char *sname = resolve_struct_name_from_type(ctx, struct_type, &is_ptr, &alloc_name);
+
if (!sname)
{
return NULL;
@@ -3214,6 +3215,10 @@ Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_na
ASTNode *def = find_struct_def(ctx, sname);
if (!def)
{
+ if (alloc_name)
+ {
+ free(alloc_name);
+ }
return NULL;
}
@@ -3222,10 +3227,18 @@ Type *get_field_type(ParserContext *ctx, Type *struct_type, const char *field_na
{
if (strcmp(f->field.name, field_name) == 0)
{
+ if (alloc_name)
+ {
+ free(alloc_name);
+ }
return f->type_info;
}
f = f->next;
}
+ if (alloc_name)
+ {
+ free(alloc_name);
+ }
return NULL;
}
@@ -4476,11 +4489,16 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
{
struct_name = t->name;
}
+ /*
else if (t->kind == TYPE_POINTER && t->inner && t->inner->kind == TYPE_STRUCT)
{
- struct_name = t->inner->name;
- is_ptr = 1;
+ // struct_name = t->inner->name;
+ // is_ptr = 1;
+ // DISABLE: Pointers should use array indexing by default, not operator
+ overload.
+ // If users want operator overload, they must dereference first (*ptr)[idx]
}
+ */
}
if (!struct_name && lhs->resolved_type)
{
@@ -4570,6 +4588,17 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
}
}
+ // Assign type_info for index access (Fix for nested generics)
+ if (lhs->type_info &&
+ (lhs->type_info->kind == TYPE_ARRAY || lhs->type_info->kind == TYPE_POINTER))
+ {
+ node->type_info = lhs->type_info->inner;
+ }
+ if (!node->type_info)
+ {
+ node->type_info = type_new(TYPE_INT);
+ }
+
lhs = node;
}
continue;
@@ -4589,6 +4618,9 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
node->member.field = token_strdup(field);
node->member.is_pointer_access = 0;
+ node->member.field = token_strdup(field);
+ node->member.is_pointer_access = 0;
+
if (lhs->type_info && lhs->type_info->kind == TYPE_POINTER)
{
node->member.is_pointer_access = 1;
@@ -5203,6 +5235,8 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
{
int is_rhs_ptr = 0;
char *r_alloc = NULL;
+
+ // This gives a warning as "unused" but it's needed for the rewrite.
char *r_name =
resolve_struct_name_from_type(ctx, rhs->type_info, &is_rhs_ptr, &r_alloc);
if (r_alloc)