stage1 禁止隐式调用 修复bug

This commit is contained in:
zzy
2026-07-12 11:43:27 +08:00
parent 118c153280
commit 9b9b25ce0f
5 changed files with 23 additions and 17 deletions

View File

@@ -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", spl_comp_error(ctx, "cannot call instance method '%s' on type",
fname); 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); 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) {
if (ret_type->kind == TYPE_BASIC) { if (ret_type->kind == TYPE_BASIC) {
rt = ret_type->basic_type; rt = ret_type->basic_type;
} else if (ret_type->kind == TYPE_PTR) { } else {
rt = SPL_PTR; /* Pointer, struct, enum, etc: return address of value */
} else if (spl_type_size(ret_type) <= sizeof(spl_val_t)) {
rt = SPL_PTR; rt = SPL_PTR;
} }
} }

View File

@@ -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) if (peek(ctx)->type == TOK_SEMICOLON || peek(ctx)->type == TOK_COMMA)
advance(ctx); advance(ctx);
} else if (tt == KW_FN && depth == 1) { } 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); parse_method_decl(ctx, container);
} else { } else {
advance(ctx); advance(ctx);

View File

@@ -448,14 +448,15 @@ static void parse_for_stmt(spl_comp_t *ctx) {
/* Load slice[idx] and store to val */ /* 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, 2); /* copy ptr: [ptr, len, idx, ptr] */
spl_emit(ctx, SPL_PICK, SPL_VOID, 1); /* copy idx: [ptr, len, idx, ptr, idx] */ 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_PUSH, SPL_U64, elem_byte_size);
spl_emit(ctx, SPL_MUL, SPL_U64, 0); spl_emit(ctx, SPL_MUL, SPL_U64, 0);
spl_emit(ctx, SPL_ADD, 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_LADDR, SPL_PTR, val_offset);
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); 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); skip_nl(ctx);
spl_parse_block(ctx); /* body */ spl_parse_block(ctx); /* body */

View File

@@ -34,7 +34,7 @@ type Expr = enum {
fn main() i32 { fn main() i32 {
/* struct 方法调用 */ /* struct 方法调用 */
var p: Point = Point.init(3, 4); var p: Point = Point.init(3, 4);
p.dump(); p.dump(&p);
/* enum 方法 + match */ /* enum 方法 + match */
var expr_l := Expr { .Int = 3 }; var expr_l := Expr { .Int = 3 };

View File

@@ -156,23 +156,23 @@ fn test_nested_struct() i32 {
fn test_struct_method() i32 { fn test_struct_method() i32 {
var c: Counter = Counter { .val = 0 }; var c: Counter = Counter { .val = 0 };
/* 实例方法调用 c.inc() */ /* 实例方法调用 c.inc(&c) */
var r1: i32 = c.inc(); var r1: i32 = c.inc(&c);
if r1 != 1 { ret 1; } if r1 != 1 { ret 1; }
if c.val != 1 { ret 2; } if c.val != 1 { ret 2; }
/* 带参数方法调用 c.add(n) */ /* 带参数方法调用 c.add(&c, n) */
var r2: i32 = c.add(5); var r2: i32 = c.add(&c, 5);
if r2 != 6 { ret 3; } if r2 != 6 { ret 3; }
if c.val != 6 { ret 4; } if c.val != 6 { ret 4; }
/* 连续调用 */ /* 连续调用 (显式 self) */
c.reset(); c.reset(&c);
if c.val != 0 { ret 5; } if c.val != 0 { ret 5; }
c.add(10); c.add(&c, 10);
c.inc(); c.inc(&c);
var r3: i32 = c.get(); var r3: i32 = c.get(&c);
if r3 != 11 { ret 6; } if r3 != 11 { ret 6; }
ret 0; ret 0;