diff options
Diffstat (limited to 'src/parser')
| -rw-r--r-- | src/parser/parser_core.c | 13 | ||||
| -rw-r--r-- | src/parser/parser_expr.c | 29 |
2 files changed, 35 insertions, 7 deletions
diff --git a/src/parser/parser_core.c b/src/parser/parser_core.c index c3c91fe..acab268 100644 --- a/src/parser/parser_core.c +++ b/src/parser/parser_core.c @@ -585,17 +585,19 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char * ASTNode *fdef = find_struct_def(ctx, ft); if (fdef && fdef->type == NODE_ENUM) { - // Enum field: compare tags + // Enum field: compare tags (pointer access via auto-deref) sprintf(cmp, "self.%s.tag == other.%s.tag", fn, fn); } else if (fdef && fdef->type == NODE_STRUCT) { - // Struct field: use _eq function - sprintf(cmp, "%s__eq(&self.%s, other.%s)", ft, fn, fn); + // Struct field: use _eq function, pass addresses + // self.field is L-value, other.field is L-value (auto-deref from pointer) + // We need addresses of them: &self.field, &other.field + sprintf(cmp, "%s__eq(&self.%s, &other.%s)", ft, fn, fn); } else { - // Primitive or unknown: use == + // Primitive or unknown: use == (auto-deref) sprintf(cmp, "self.%s == other.%s", fn, fn); } strcat(body, cmp); @@ -610,7 +612,8 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char * strcat(body, ";"); } code = xmalloc(4096 + 1024); - sprintf(code, "impl %s { fn eq(self, other: %s) -> bool { %s } }", name, name, body); + // Updated signature: other is a pointer T* + sprintf(code, "impl %s { fn eq(self, other: %s*) -> bool { %s } }", name, name, body); } else if (0 == strcmp(trait, "Debug")) { diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index 97d6218..a79bb21 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -4115,9 +4115,34 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec) } } + // Handle RHS (Argument 2) Auto-Ref if needed + ASTNode *arg2 = rhs; + if (sig->total_args > 1 && sig->arg_types[1] && + sig->arg_types[1]->kind == TYPE_POINTER) + { + Type *rt = rhs->type_info; + int is_rhs_ptr = (rt && rt->kind == TYPE_POINTER); + if (!is_rhs_ptr) // Need pointer, have value + { + int is_rvalue = + (rhs->type == NODE_EXPR_CALL || rhs->type == NODE_EXPR_BINARY || + rhs->type == NODE_EXPR_STRUCT_INIT || + rhs->type == NODE_EXPR_CAST || rhs->type == NODE_MATCH); + + ASTNode *addr = ast_create(NODE_EXPR_UNARY); + addr->unary.op = is_rvalue ? xstrdup("&_rval") : xstrdup("&"); + addr->unary.operand = rhs; + if (rt) + { + addr->type_info = type_new_ptr(rt); + } + arg2 = addr; + } + } + call->call.args = arg1; - arg1->next = rhs; - rhs->next = NULL; + arg1->next = arg2; + arg2->next = NULL; call->type_info = sig->ret_type; call->resolved_type = type_to_string(sig->ret_type); |
