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",
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;
}
}

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)
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);

View File

@@ -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 */

View File

@@ -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 };

View File

@@ -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;