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

@@ -4,15 +4,6 @@
#include "spl_lex_util.h"
#include <string.h>
spl_tok_t *peek(spl_comp_t *ctx) { return &vec_at(ctx->toks, ctx->tok_idx); }
spl_tok_t *advance(spl_comp_t *ctx) {
spl_tok_t *t = &vec_at(ctx->toks, ctx->tok_idx);
if (t->type != TOK_EOF)
ctx->tok_idx++;
return t;
}
/* ============================================================
* Parse function definition
* ============================================================ */
@@ -52,8 +43,8 @@ static int parse_params_decl(spl_comp_t *ctx, char pnames[][256], int ptypes[])
return nparams;
}
static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, int ret_type_idx,
int nparams, char pnames[][256], int ptypes[], int is_pub) {
static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, int ret_type_idx, int nparams,
char pnames[][256], int ptypes[], int is_pub) {
int fi = spl_declare_func(ctx, fn_name, ret_type_idx, nparams, 0, is_pub);
ctx->current_func_idx = fi;
ctx->current_ret_type_idx = ret_type_idx;
@@ -84,8 +75,7 @@ static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, int ret_type_idx,
total_phys_slots += (int)((psz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t));
}
if (spl_type_needs_multi_slot(&ctx->tctx, ret_type_idx)) {
usize min_bytes =
spl_type_slot_count(&ctx->tctx, ret_type_idx) * sizeof(spl_val_t);
usize min_bytes = spl_type_slot_count(&ctx->tctx, ret_type_idx) * sizeof(spl_val_t);
if ((usize)ctx->emit.frame.peak_bytes < min_bytes)
ctx->emit.frame.peak_bytes = (int)min_bytes;
}
@@ -137,9 +127,13 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
skip_nl(ctx);
}
int fi;
if (is_extern) {
spl_declare_func(ctx, fn_name, ret_type_idx, nparams, 1, is_pub);
fi = spl_declare_func(ctx, fn_name, ret_type_idx, nparams, 1, is_pub);
spl_ensure_native(ctx, fn_name);
if (ctx->tctx.current_type_idx == 0)
spl_type_add_method(&ctx->tctx, 0, fn_name, fi);
if (peek(ctx)->type == TOK_SEMICOLON)
advance(ctx);
return;
@@ -152,7 +146,9 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
skip_nl(ctx);
parse_fn_body(ctx, fn_name, ret_type_idx, nparams, pnames, ptypes, is_pub);
fi = parse_fn_body(ctx, fn_name, ret_type_idx, nparams, pnames, ptypes, is_pub);
if (ctx->tctx.current_type_idx == 0)
spl_type_add_method(&ctx->tctx, 0, fn_name, fi);
}
/* ============================================================
@@ -449,19 +445,40 @@ void spl_parse_prog(spl_comp_t *ctx) {
parse_type_decl(ctx);
break;
}
case TOK_SHARP:
advance(ctx); /* # */
if (peek(ctx)->type == TOK_L_BRACKET) {
advance(ctx); /* [ */
while (peek(ctx)->type != TOK_R_BRACKET && peek(ctx)->type != TOK_EOF)
advance(ctx);
if (peek(ctx)->type == TOK_R_BRACKET)
advance(ctx);
case TOK_AT:
case TOK_SHARP: {
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 (e.g. "vm") */
skip_nl(ctx);
if (peek(ctx)->type == TOK_R_PAREN)
advance(ctx);
}
}
} else {
/* #[extern("vm")] fn ... (legacy) */
if (peek(ctx)->type == TOK_L_BRACKET) {
advance(ctx); /* [ */
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);
if (peek(ctx)->type == KW_FN)
parse_fn_decl(ctx, 1, 0);
break;
}
default: {
int prev = ctx->tok_idx;
spl_parse_stmt(ctx);