From 7c5bb41e09024589e61bbe85876508881cd51ce7 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Tue, 21 Jul 2026 09:56:19 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E6=95=B4=E7=90=86=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=20=E6=8F=90=E4=BE=9B=E6=9B=B4=E5=A4=9A=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage1/spl_comp.c | 55 ++++++-------------------------------- stage1/spl_comp.h | 3 --- stage1/spl_emit.c | 46 ++++++++++++++++++++++++++++++++ stage1/spl_emit.h | 2 ++ stage1/spl_expr.c | 24 ++++++++++++----- stage1/spl_lex_util.c | 8 ++++++ stage1/spl_lex_util.h | 1 + stage1/spl_parser.c | 62 ++++++++++++++++++++++++++++++++----------- 8 files changed, 129 insertions(+), 72 deletions(-) diff --git a/stage1/spl_comp.c b/stage1/spl_comp.c index ba0a71b..6049adc 100644 --- a/stage1/spl_comp.c +++ b/stage1/spl_comp.c @@ -67,10 +67,17 @@ void spl_comp_reset(spl_comp_t *ctx) { } void spl_comp_error(spl_comp_t *ctx, const char *fmt, ...) { + const char *loc = spl_tok_loc_str(ctx); + int loc_len = (int)strlen(loc); + memcpy(ctx->error_msg, loc, loc_len); va_list args; va_start(args, fmt); - vsnprintf(ctx->error_msg, COMP_ERROR_MAX - 1, fmt, args); + int n = vsnprintf(ctx->error_msg + loc_len, COMP_ERROR_MAX - loc_len - 1, fmt, args); va_end(args); + if (n >= 0 && loc_len + n < COMP_ERROR_MAX - 2) { + ctx->error_msg[loc_len + n] = '\n'; + ctx->error_msg[loc_len + n + 1] = '\0'; + } ctx->has_error = 1; } @@ -209,53 +216,7 @@ int spl_add_global_data(spl_comp_t *ctx, void *data, usize size) { return spl_prog_add_data(&ctx->prog, data, size); } -/* ---- Defer ---- */ -void spl_emit_defer(spl_comp_t *ctx) { - if (ctx->defer_count >= DEFER_MAX) - return; - - spl_val_t jmp_skip = emit_jmp_here(&ctx->emit); - - spl_defer_entry_t *e = &ctx->defer_stack[ctx->defer_count]; - e->body_start = jmp_skip + 1; - e->jmp_exit = 0; - e->depth = ctx->scope_depth; - e->count_at_decl = ctx->defer_count; - ctx->defer_count++; -} - -void spl_emit_defer_epilogue(spl_comp_t *ctx, int depth) { - for (int i = 0; i < ctx->defer_count; i++) { - if (ctx->defer_stack[i].depth != depth) - continue; - spl_defer_entry_t *e = &ctx->defer_stack[i]; - - spl_val_t skip_addr = e->body_start - 1; - spl_val_t skip_target = e->jmp_exit + 1; - emit_patch(&ctx->emit, skip_addr, skip_target - skip_addr - 1); - } - - for (int i = ctx->defer_count - 1; i >= 0; i--) { - if (ctx->defer_stack[i].depth != depth) - continue; - spl_defer_entry_t *e = &ctx->defer_stack[i]; - - spl_val_t here = vec_size(ctx->prog.insns); - spl_val_t jmp_offset = (spl_val_t)((isize)e->body_start - (isize)here - 1); - emit_jmp(&ctx->emit, jmp_offset); - - if (e->jmp_exit > 0) - emit_patch(&ctx->emit, e->jmp_exit, here + 1 - e->jmp_exit - 1); - } - - int new_count = 0; - for (int i = 0; i < ctx->defer_count; i++) { - if (ctx->defer_stack[i].depth != depth) - ctx->defer_stack[new_count++] = ctx->defer_stack[i]; - } - ctx->defer_count = new_count; -} /* ---- Register runtime natives ---- */ diff --git a/stage1/spl_comp.h b/stage1/spl_comp.h index 5932c3c..aea46cb 100644 --- a/stage1/spl_comp.h +++ b/stage1/spl_comp.h @@ -196,9 +196,6 @@ int spl_add_global_data(spl_comp_t *ctx, void *data, usize size); void spl_push_scope(spl_comp_t *ctx); void spl_pop_scope(spl_comp_t *ctx); -/* Defer */ -void spl_emit_defer(spl_comp_t *ctx); -void spl_emit_defer_epilogue(spl_comp_t *ctx, int depth); /* Register runtime natives (stub) */ void spl_comp_register(spl_prog_t *prog); diff --git a/stage1/spl_emit.c b/stage1/spl_emit.c index 9383382..80b4f85 100644 --- a/stage1/spl_emit.c +++ b/stage1/spl_emit.c @@ -231,3 +231,49 @@ void spl_emit_store_init(spl_comp_t *ctx, int var_offset, int var_type_idx) { emit_store_to_laddr(&ctx->emit, var_offset, bt); } } + +void spl_emit_defer(spl_comp_t *ctx) { + if (ctx->defer_count >= DEFER_MAX) + return; + + spl_val_t jmp_skip = emit_jmp_here(&ctx->emit); + + spl_defer_entry_t *e = &ctx->defer_stack[ctx->defer_count]; + e->body_start = jmp_skip + 1; + e->jmp_exit = 0; + e->depth = ctx->scope_depth; + e->count_at_decl = ctx->defer_count; + ctx->defer_count++; +} + +void spl_emit_defer_epilogue(spl_comp_t *ctx, int depth) { + for (int i = 0; i < ctx->defer_count; i++) { + if (ctx->defer_stack[i].depth != depth) + continue; + spl_defer_entry_t *e = &ctx->defer_stack[i]; + + spl_val_t skip_addr = e->body_start - 1; + spl_val_t skip_target = e->jmp_exit + 1; + emit_patch(&ctx->emit, skip_addr, skip_target - skip_addr - 1); + } + + for (int i = ctx->defer_count - 1; i >= 0; i--) { + if (ctx->defer_stack[i].depth != depth) + continue; + spl_defer_entry_t *e = &ctx->defer_stack[i]; + + spl_val_t here = vec_size(ctx->prog.insns); + spl_val_t jmp_offset = (spl_val_t)((isize)e->body_start - (isize)here - 1); + emit_jmp(&ctx->emit, jmp_offset); + + if (e->jmp_exit > 0) + emit_patch(&ctx->emit, e->jmp_exit, here + 1 - e->jmp_exit - 1); + } + + int new_count = 0; + for (int i = 0; i < ctx->defer_count; i++) { + if (ctx->defer_stack[i].depth != depth) + ctx->defer_stack[new_count++] = ctx->defer_stack[i]; + } + ctx->defer_count = new_count; +} diff --git a/stage1/spl_emit.h b/stage1/spl_emit.h index 6273782..2344a83 100644 --- a/stage1/spl_emit.h +++ b/stage1/spl_emit.h @@ -149,5 +149,7 @@ void emit_patch_call_fixups(spl_emit_t *e, spl_prog_t *prog); struct spl_comp; void spl_emit_ret(struct spl_comp *ctx, int ret_type_idx); void spl_emit_store_init(struct spl_comp *ctx, int var_offset, int var_type_idx); +void spl_emit_defer(struct spl_comp *ctx); +void spl_emit_defer_epilogue(struct spl_comp *ctx, int depth); #endif /* __SPL_EMIT_H__ */ diff --git a/stage1/spl_expr.c b/stage1/spl_expr.c index b810a8e..8f8ef7d 100644 --- a/stage1/spl_expr.c +++ b/stage1/spl_expr.c @@ -618,9 +618,9 @@ static void spl_check_arg_type(spl_comp_t *ctx, const char *fname, int arg_type_ strcmp(spl_type_name(&ctx->tctx, arg_type_idx), spl_type_name(&ctx->tctx, spl_type_elem_type(&ctx->tctx, param_type_idx))) == 0) { fprintf(stderr, - "%s: warning: argument %d of '%s' expects '%s*', " + "%s warning: argument %d of '%s' expects '%s*', " "got '%s' (missing '&'?)\n", - ctx->fname, arg_idx + 1, fname, + spl_tok_loc_str(ctx), arg_idx + 1, fname, spl_type_name(&ctx->tctx, spl_type_elem_type(&ctx->tctx, param_type_idx)), spl_type_name(&ctx->tctx, arg_type_idx)); } @@ -781,6 +781,7 @@ static spl_expr_result_t parse_prefix_op(spl_comp_t *ctx) { if (!right.is_lvalue) { spl_comp_error(ctx, "cannot take address of rvalue"); } + right.type_idx = spl_type_ptr(&ctx->tctx, right.type_idx); break; case TOK_MUL: if (right.type_idx >= 0 && spl_type_kind(&ctx->tctx, right.type_idx) == TYPE_PTR && @@ -871,6 +872,18 @@ static spl_expr_result_t parse_primary_expr(spl_comp_t *ctx) { emit_dbg_void(&ctx->emit); } return (spl_expr_result_t){spl_type_basic(&ctx->tctx, SPL_VOID), 0}; + } else if (strcmp(bname, "sizeof") == 0) { + expect(ctx, TOK_L_PAREN); + int ti = spl_type_parse(&ctx->tctx, ctx); + expect(ctx, TOK_R_PAREN); + if (ti < 0) { + spl_comp_error(ctx, "@sizeof: invalid type"); + spl_expr_result_t r = { -1, 0 }; + return r; + } + usize sz = spl_type_size(&ctx->tctx, ti); + emit_push_usize(&ctx->emit, sz); + return (spl_expr_result_t){spl_type_basic(&ctx->tctx, SPL_USIZE), 0}; } else { spl_comp_error(ctx, "unknown builtin '@%s'", bname); spl_expr_result_t r = {-1, 0}; @@ -935,7 +948,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l int nargs = 0; int is_instance = 0; - if (func->nparams > 0 && func->param_type_indices[0] >= 0 && + if (func->nparams > 0 && func->param_type_indices && + func->param_type_indices[0] >= 0 && spl_type_kind(&ctx->tctx, func->param_type_indices[0]) == TYPE_PTR && spl_type_elem_type(&ctx->tctx, func->param_type_indices[0]) == methods_type_idx) { @@ -954,10 +968,6 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l { int *cp = func->param_type_indices; int cn = func->nparams; - if (is_instance && cn > 0) { - cp++; - cn--; - } nargs += parse_call_args_checked(ctx, func->name, cp, cn); } expect(ctx, TOK_R_PAREN); diff --git a/stage1/spl_lex_util.c b/stage1/spl_lex_util.c index 6138174..b464dbb 100644 --- a/stage1/spl_lex_util.c +++ b/stage1/spl_lex_util.c @@ -122,3 +122,11 @@ usize spl_tok_copy_name(spl_tok_t *tok, char *buf, usize buf_size) { buf[nlen] = '\0'; return nlen; } + +const char *spl_tok_loc_str(spl_comp_t *ctx) { + static char buf[256]; + spl_tok_t *tok = peek(ctx); + snprintf(buf, sizeof(buf), "%s:%zu:%zu: ", tok->fname ? tok->fname : "?", tok->line, + tok->col); + return buf; +} diff --git a/stage1/spl_lex_util.h b/stage1/spl_lex_util.h index 0bcb1ca..3ddb43d 100644 --- a/stage1/spl_lex_util.h +++ b/stage1/spl_lex_util.h @@ -19,6 +19,7 @@ void spl_tok_dump(spl_tok_t *tok); void spl_tok_vec_dump(spl_tok_vec_t *toks); void spl_tok_vec_drop(spl_tok_vec_t *toks); usize spl_tok_copy_name(spl_tok_t *tok, char *buf, usize buf_size); +const char *spl_tok_loc_str(spl_comp_t *ctx); /* Parse an integer literal value, handling optional '-' prefix for negatives. * Returns 1 on success (value in *val), 0 if current token isn't an integer. diff --git a/stage1/spl_parser.c b/stage1/spl_parser.c index 27805b8..9b95da3 100644 --- a/stage1/spl_parser.c +++ b/stage1/spl_parser.c @@ -46,6 +46,17 @@ static int parse_params_decl(spl_comp_t *ctx, char pnames[][256], int ptypes[]) 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); + + { + spl_func_info_t *f = &vec_at(ctx->funcs, fi); + f->param_type_indices = calloc(nparams, sizeof(int)); + f->param_names = calloc(nparams, sizeof(char *)); + for (int i = 0; i < nparams; i++) { + f->param_type_indices[i] = ptypes[i]; + f->param_names[i] = strdup(pnames[i]); + } + } + ctx->current_func_idx = fi; ctx->current_ret_type_idx = ret_type_idx; fa_init(&ctx->emit.frame); @@ -87,16 +98,6 @@ static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, int ret_type_idx, spl_emit_defer_epilogue(ctx, ctx->scope_depth); spl_pop_scope(ctx); - { - spl_func_info_t *f = &vec_at(ctx->funcs, fi); - f->param_type_indices = calloc(nparams, sizeof(int)); - f->param_names = calloc(nparams, sizeof(char *)); - for (int i = 0; i < nparams; i++) { - f->param_type_indices[i] = ptypes[i]; - f->param_names[i] = strdup(pnames[i]); - } - } - emit_return(&ctx->emit, &ctx->tctx, ctx->current_ret_type_idx); spl_prog_end_func(&ctx->prog, fi); ctx->current_func_idx = -1; @@ -207,10 +208,13 @@ static void skip_type_decl(spl_comp_t *ctx) { int bd = 1; advance(ctx); while (bd > 0 && ctx->tok_idx < vec_size(ctx->toks)) { - if (peek(ctx)->type == TOK_L_BRACE) + spl_tok_type_t tt = peek(ctx)->type; + if (tt == TOK_L_BRACE) bd++; - else if (peek(ctx)->type == TOK_R_BRACE) + else if (tt == TOK_R_BRACE) bd--; + else if (tt == TOK_EOF) + break; advance(ctx); } } else { @@ -247,6 +251,8 @@ static void parse_type_body(spl_comp_t *ctx, int container_type_idx, int is_enum advance(ctx); } else if (tt == KW_TYPE && depth == 1) { parse_type_decl(ctx); + } else if (tt == TOK_EOF) { + break; } else { advance(ctx); } @@ -276,10 +282,34 @@ static void parse_type_body(spl_comp_t *ctx, int container_type_idx, int is_enum spl_tok_t *name_tok = advance(ctx); char mname[256]; spl_tok_copy_name(name_tok, mname, sizeof(mname)); + + /* Count parameters for forward reference */ + int pcount = 0; + if (peek(ctx)->type == TOK_L_PAREN) { + advance(ctx); /* ( */ + skip_nl(ctx); + if (peek(ctx)->type != TOK_R_PAREN) { + pcount = 1; + for (;;) { + advance(ctx); /* skip param name or type token */ + skip_nl(ctx); + if (peek(ctx)->type == TOK_R_PAREN) break; + if (peek(ctx)->type == TOK_COMMA) { + advance(ctx); /* , */ + skip_nl(ctx); + pcount++; + } + } + } + advance(ctx); /* ) */ + } + char qualified[512]; snprintf(qualified, sizeof(qualified), "%s.%s", cname, mname); - int fi = spl_declare_func(ctx, qualified, -1, 0, 0, 0); + int fi = spl_declare_func(ctx, qualified, -1, pcount, 0, 0); spl_type_add_method(&ctx->tctx, container_type_idx, mname, fi); + } else if (tt == TOK_EOF) { + break; } else { advance(ctx); } @@ -335,7 +365,9 @@ static void parse_type_body(spl_comp_t *ctx, int container_type_idx, int is_enum spl_tok_copy_name(vtok, vname, sizeof(vname)); spl_type_add_variant(&ctx->tctx, container_type_idx, vname, dtype >= 0 ? dtype : -1); - } else { + } else if (tt == TOK_EOF) { + break; + } else { char vname[256]; spl_tok_copy_name(vtok, vname, sizeof(vname)); spl_type_add_variant(&ctx->tctx, container_type_idx, vname, -1); @@ -480,7 +512,7 @@ void spl_parse_prog(spl_comp_t *ctx) { break; } default: { - int prev = ctx->tok_idx; + usize prev = ctx->tok_idx; spl_parse_stmt(ctx); if (ctx->tok_idx == prev) advance(ctx);