From 9b9b25ce0fea0801e281fe79786bf2c2a0ae8520 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Sun, 12 Jul 2026 11:43:27 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E7=A6=81=E6=AD=A2=E9=9A=90=E5=BC=8F?= =?UTF-8?q?=E8=B0=83=E7=94=A8=20=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage1/spl_expr.c | 10 ++++++---- stage1/spl_parser.c | 3 +++ stage1/spl_stmt.c | 7 ++++--- stage1/test16_methods.spl | 2 +- stage1/test20_complex.spl | 18 +++++++++--------- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/stage1/spl_expr.c b/stage1/spl_expr.c index e4c9a0d..eba9f0f 100644 --- a/stage1/spl_expr.c +++ b/stage1/spl_expr.c @@ -922,7 +922,10 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l spl_comp_error(ctx, "cannot call instance method '%s' on type", fname); } - nargs = 1; + /* Drop implicit self from left operand — user passes + * self explicitly as first argument */ + spl_emit(ctx, SPL_DROP, SPL_VOID, 0); + nargs = 0; } nargs += parse_call_args(ctx); @@ -1246,9 +1249,8 @@ void spl_emit_ret(spl_comp_t *ctx, spl_type_info_t *ret_type) { if (ret_type) { if (ret_type->kind == TYPE_BASIC) { rt = ret_type->basic_type; - } else if (ret_type->kind == TYPE_PTR) { - rt = SPL_PTR; - } else if (spl_type_size(ret_type) <= sizeof(spl_val_t)) { + } else { + /* Pointer, struct, enum, etc: return address of value */ rt = SPL_PTR; } } diff --git a/stage1/spl_parser.c b/stage1/spl_parser.c index 269d425..c0c2700 100644 --- a/stage1/spl_parser.c +++ b/stage1/spl_parser.c @@ -318,6 +318,9 @@ static void parse_type_body(spl_comp_t *ctx, spl_type_info_t *container, int is_ if (peek(ctx)->type == TOK_SEMICOLON || peek(ctx)->type == TOK_COMMA) advance(ctx); } else if (tt == KW_FN && depth == 1) { + /* Compute layout before compiling methods so + * field offsets are correct during codegen */ + spl_type_compute_layout(container); parse_method_decl(ctx, container); } else { advance(ctx); diff --git a/stage1/spl_stmt.c b/stage1/spl_stmt.c index 0608a19..1d44f94 100644 --- a/stage1/spl_stmt.c +++ b/stage1/spl_stmt.c @@ -448,14 +448,15 @@ static void parse_for_stmt(spl_comp_t *ctx) { /* Load slice[idx] and store to val */ spl_emit(ctx, SPL_PICK, SPL_VOID, 2); /* copy ptr: [ptr, len, idx, ptr] */ spl_emit(ctx, SPL_PICK, SPL_VOID, 1); /* copy idx: [ptr, len, idx, ptr, idx] */ - usize elem_byte_size = (elem_type && elem_type->byte_size) ? elem_type->byte_size : 4; + usize elem_byte_size = elem_type ? spl_type_size(elem_type) : 4; spl_emit(ctx, SPL_PUSH, SPL_U64, elem_byte_size); spl_emit(ctx, SPL_MUL, SPL_U64, 0); spl_emit(ctx, SPL_ADD, SPL_U64, 0); - spl_emit(ctx, SPL_LOAD, SPL_I32, 0); + spl_type_t elem_bt = elem_type ? spl_type_emit_type(elem_type) : SPL_I32; + spl_emit(ctx, SPL_LOAD, elem_bt, 0); spl_emit(ctx, SPL_LADDR, SPL_PTR, val_offset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); - spl_emit(ctx, SPL_STORE, SPL_I32, 0); + spl_emit(ctx, SPL_STORE, elem_bt, 0); skip_nl(ctx); spl_parse_block(ctx); /* body */ diff --git a/stage1/test16_methods.spl b/stage1/test16_methods.spl index 165dd0c..e168163 100644 --- a/stage1/test16_methods.spl +++ b/stage1/test16_methods.spl @@ -34,7 +34,7 @@ type Expr = enum { fn main() i32 { /* struct 方法调用 */ var p: Point = Point.init(3, 4); - p.dump(); + p.dump(&p); /* enum 方法 + match */ var expr_l := Expr { .Int = 3 }; diff --git a/stage1/test20_complex.spl b/stage1/test20_complex.spl index 17f60e8..43301e6 100644 --- a/stage1/test20_complex.spl +++ b/stage1/test20_complex.spl @@ -156,23 +156,23 @@ fn test_nested_struct() i32 { fn test_struct_method() i32 { var c: Counter = Counter { .val = 0 }; - /* 实例方法调用 c.inc() */ - var r1: i32 = c.inc(); + /* 实例方法调用 c.inc(&c) */ + var r1: i32 = c.inc(&c); if r1 != 1 { ret 1; } if c.val != 1 { ret 2; } - /* 带参数方法调用 c.add(n) */ - var r2: i32 = c.add(5); + /* 带参数方法调用 c.add(&c, n) */ + var r2: i32 = c.add(&c, 5); if r2 != 6 { ret 3; } if c.val != 6 { ret 4; } - /* 连续调用 */ - c.reset(); + /* 连续调用 (显式 self) */ + c.reset(&c); if c.val != 0 { ret 5; } - c.add(10); - c.inc(); - var r3: i32 = c.get(); + c.add(&c, 10); + c.inc(&c); + var r3: i32 = c.get(&c); if r3 != 11 { ret 6; } ret 0;