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",
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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 };
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user