stage1 - 全面重构 stage1 编译器架构:类型系统(arena + items)、IR 发射层(spl_emit.h/c)、统一所有 emit 调用点。

- 实现 as 类型转换运算符、修复 &&/|| 短路求值 bug。
- 在 splc1.spl 中实现 Vec/Map/Emit 基础库(~50 个方法)。
- 修复实例方法调用中 self 参数被错误丢弃的 bug。
This commit is contained in:
zzy
2026-07-20 20:53:41 +08:00
parent 21f35b30fa
commit 459b6188a9
17 changed files with 307 additions and 217 deletions

View File

@@ -163,10 +163,11 @@ spl_expr_result_t spl_parse_block_expr(spl_comp_t *ctx) {
}
spl_tok_type_t t = peek(ctx)->type;
int is_keyword = (t == KW_RET || t == KW_VAR || t == KW_CONST || t == KW_IF ||
t == KW_WHILE || t == KW_LOOP || t == KW_FOR || t == KW_BREAK ||
t == KW_CONTINUE || t == KW_DEFER || t == KW_MATCH || t == KW_TYPE ||
t == TOK_L_BRACE || t == TOK_SHARP || t == TOK_LINE_COMMENT);
int is_keyword =
(t == KW_RET || t == KW_VAR || t == KW_CONST || t == KW_IF || t == KW_WHILE ||
t == KW_LOOP || t == KW_FOR || t == KW_BREAK || t == KW_CONTINUE || t == KW_DEFER ||
t == KW_MATCH || t == KW_TYPE || t == TOK_L_BRACE || t == TOK_AT || t == TOK_SHARP ||
t == TOK_LINE_COMMENT);
if (is_keyword) {
/* Keyword statement — produces void */
@@ -433,7 +434,7 @@ static void parse_for_stmt(spl_comp_t *ctx) {
/* Condition: idx < len */
emit_pick(&ctx->emit, 1); /* copy len */
emit_pick(&ctx->emit, 1); /* copy idx */
emit_swap(&ctx->emit); /* [idx, len] → [len, idx] → SWAP → [idx, len] */
emit_swap(&ctx->emit); /* [idx, len] → [len, idx] → SWAP → [idx, len] */
emit_ult_usize(&ctx->emit);
spl_val_t bz_addr = emit_bz_here(&ctx->emit);
@@ -454,7 +455,8 @@ static void parse_for_stmt(spl_comp_t *ctx) {
spl_type_size(&ctx->tctx, elem_type_idx) > sizeof(spl_val_t)) {
emit_frame_copy(&ctx->emit, val_offset, spl_type_slot_count(&ctx->tctx, elem_type_idx));
} else {
spl_type_t elem_bt = elem_type_idx >= 0 ? spl_type_emit_type(&ctx->tctx, elem_type_idx) : SPL_I32;
spl_type_t elem_bt =
elem_type_idx >= 0 ? spl_type_emit_type(&ctx->tctx, elem_type_idx) : SPL_I32;
emit_load_type(&ctx->emit, elem_bt);
emit_store_to_laddr(&ctx->emit, val_offset, elem_bt);
}
@@ -545,8 +547,8 @@ static void parse_defer_stmt(spl_comp_t *ctx) {
/* Parse an enum variant pattern in a match arm: .VariantName
* Delegates comparison to expr layer (spl_emit_match_enum_cmp).
* Returns the variant item index, or -1 on error. */
static int parse_match_enum_variant(spl_comp_t *ctx, int enum_type_idx,
int val_offset, int by_value) {
static int parse_match_enum_variant(spl_comp_t *ctx, int enum_type_idx, int val_offset,
int by_value) {
return spl_emit_match_enum_cmp(ctx, enum_type_idx, val_offset, by_value);
}
@@ -561,9 +563,8 @@ static void parse_match_value_pattern(spl_comp_t *ctx, int val_offset) {
* Declares local variables and loads corresponding field data
* from the matched value's data area (offset 4+).
* Sets *scope_pushed = 1 if bindings declared. */
static void parse_match_enum_bindings(spl_comp_t *ctx, int enum_type_idx,
int variant_item_idx, int val_offset,
int *scope_pushed) {
static void parse_match_enum_bindings(spl_comp_t *ctx, int enum_type_idx, int variant_item_idx,
int val_offset, int *scope_pushed) {
advance(ctx); /* ( */
skip_nl(ctx);
if (peek(ctx)->type == TOK_R_PAREN) {
@@ -603,7 +604,8 @@ static void parse_match_enum_bindings(spl_comp_t *ctx, int enum_type_idx,
}
}
int boffset = spl_declare_var(ctx, bname, btype_idx, 0);
emit_load_to_var(&ctx->emit, &ctx->tctx, val_offset, field_byte_off, btype_idx, boffset);
emit_load_to_var(&ctx->emit, &ctx->tctx, val_offset, field_byte_off, btype_idx,
boffset);
bi++;
skip_nl(ctx);
@@ -721,7 +723,8 @@ static void parse_match_stmt(spl_comp_t *ctx) {
skip_nl(ctx);
if (peek(ctx)->type != TOK_ASSIGN) {
if (n_bnz < 128)
bnz_addrs[n_bnz++] = emit_bnz_here(&ctx->emit); /* fallthrough to body */
bnz_addrs[n_bnz++] =
emit_bnz_here(&ctx->emit); /* fallthrough to body */
continue;
}
break;
@@ -738,8 +741,8 @@ static void parse_match_stmt(spl_comp_t *ctx) {
/* --- Parse enum bindings (only for last variant) --- */
if (is_enum_match && has_parens && arm_variant_item >= 0) {
parse_match_enum_bindings(ctx, enum_type_idx, arm_variant_item,
val_offset, &scope_pushed);
parse_match_enum_bindings(ctx, enum_type_idx, arm_variant_item, val_offset,
&scope_pushed);
}
skip_nl(ctx);
@@ -793,13 +796,31 @@ static void parse_match_stmt(spl_comp_t *ctx) {
* ============================================================ */
static void parse_extern_decl(spl_comp_t *ctx) {
advance(ctx); /* # */
expect(ctx, TOK_L_BRACKET);
/* Skip extern("vm") or just look for fn */
while (peek(ctx)->type != TOK_R_BRACKET && peek(ctx)->type != TOK_EOF)
advance(ctx);
if (peek(ctx)->type == TOK_R_BRACKET)
advance(ctx);
int tt = peek(ctx)->type;
advance(ctx); /* @ or # */
skip_nl(ctx);
if (tt == TOK_AT) {
/* @extern(vm) fn ... */
if (peek(ctx)->type == KW_EXTERN) {
advance(ctx); /* extern */
skip_nl(ctx);
if (peek(ctx)->type == TOK_L_PAREN) {
advance(ctx); /* ( */
skip_nl(ctx);
advance(ctx); /* target name */
skip_nl(ctx);
if (peek(ctx)->type == TOK_R_PAREN)
advance(ctx);
}
}
} else {
/* #[extern("vm")] fn ... (legacy) */
expect(ctx, TOK_L_BRACKET);
while (peek(ctx)->type != TOK_R_BRACKET && peek(ctx)->type != TOK_EOF)
advance(ctx);
if (peek(ctx)->type == TOK_R_BRACKET)
advance(ctx);
}
skip_nl(ctx);
@@ -970,7 +991,8 @@ void spl_parse_stmt(spl_comp_t *ctx) {
case TOK_LINE_COMMENT:
advance(ctx);
break;
case TOK_SHARP: /* #[extern(...)] */
case TOK_AT: /* @extern(...) */
case TOK_SHARP: /* #[extern(...)] (legacy) */
parse_extern_decl(ctx);
break;
default: