summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen/codegen.c2
-rw-r--r--src/parser/parser_core.c13
-rw-r--r--src/parser/parser_expr.c29
3 files changed, 36 insertions, 8 deletions
diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c
index 01c8204..b25c79c 100644
--- a/src/codegen/codegen.c
+++ b/src/codegen/codegen.c
@@ -461,7 +461,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
}
fprintf(out, "%s__eq(&", base);
codegen_expression(ctx, node->binary.left, out);
- fprintf(out, ", ");
+ fprintf(out, ", &");
codegen_expression(ctx, node->binary.right, out);
fprintf(out, ")");
if (strcmp(node->binary.op, "!=") == 0)
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);