stage1 禁止隐式调用 修复bug
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user