diff --git a/stage0/spl_vm.c b/stage0/spl_vm.c index 1e6e602..c11d8de 100644 --- a/stage0/spl_vm.c +++ b/stage0/spl_vm.c @@ -152,6 +152,7 @@ static int spl_type_size(spl_type_t t) { _r = (spl_val_t)((int64_t)_a OP(int64_t) _b); \ break; \ case SPL_U64: \ + case SPL_PTR: \ case SPL_USIZE: \ case SPL_ISIZE: \ _r = _a OP _b; \ @@ -213,6 +214,7 @@ static int spl_type_size(spl_type_t t) { _r = (spl_val_t)((int64_t)_a OP(int64_t) _b); \ break; \ case SPL_U64: \ + case SPL_PTR: \ case SPL_USIZE: \ case SPL_ISIZE: \ _r = (spl_val_t)((int64_t)_a OP(int64_t) _b); \ @@ -254,6 +256,7 @@ static int spl_type_size(spl_type_t t) { _r = (spl_val_t)((uint64_t)_a OP(uint64_t) _b); \ break; \ case SPL_U64: \ + case SPL_PTR: \ case SPL_USIZE: \ case SPL_ISIZE: \ _r = _a OP _b; \ @@ -346,6 +349,7 @@ static int spl_type_size(spl_type_t t) { _r = (int64_t)_a OP(int64_t) _b; \ break; \ case SPL_U64: \ + case SPL_PTR: \ case SPL_USIZE: \ case SPL_ISIZE: \ _r = _a OP _b; \ @@ -399,6 +403,7 @@ static int spl_type_size(spl_type_t t) { _r = (uint64_t)_a OP(uint64_t) _b; \ break; \ case SPL_U64: \ + case SPL_PTR: \ case SPL_USIZE: \ case SPL_ISIZE: \ _r = _a OP _b; \ @@ -665,7 +670,8 @@ int spl_vm_run_once(spl_vm_t *vm) { if (vm->trace) { fprintf(stderr, "vm: ip=%zd op=%s type=%s imm=%zu sp=%zd fp=%zd\n", vm->ip - 1, - spl_opcode_name(ins->opcode), spl_type_tag_name(ins->type), ins->imm, vm->sp, vm->fp); + spl_opcode_name(ins->opcode), spl_type_tag_name(ins->type), ins->imm, vm->sp, + vm->fp); } switch (ins->opcode) { @@ -1084,7 +1090,7 @@ void spl_vm_dump_instr(spl_vm_t *vm, spl_val_t ip) { return; spl_ins_t *ins = &vec_at(vm->prog->insns, ip); fprintf(stderr, " instr at ip=%zd: op=%s type=%s imm=%zu\n", ip, spl_opcode_name(ins->opcode), - spl_type_tag_name(ins->type), ins->imm); + spl_type_tag_name(ins->type), ins->imm); } void spl_vm_stackdump(spl_vm_t *vm, spl_val_t sp) { diff --git a/stage1/spl_comp.c b/stage1/spl_comp.c index 6049adc..b614830 100644 --- a/stage1/spl_comp.c +++ b/stage1/spl_comp.c @@ -67,17 +67,10 @@ 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); - int n = vsnprintf(ctx->error_msg + loc_len, COMP_ERROR_MAX - loc_len - 1, fmt, args); + vsnprintf(ctx->error_msg, COMP_ERROR_MAX - 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; } @@ -216,8 +209,6 @@ int spl_add_global_data(spl_comp_t *ctx, void *data, usize size) { return spl_prog_add_data(&ctx->prog, data, size); } - - /* ---- Register runtime natives ---- */ void spl_comp_register(spl_prog_t *prog) { (void)prog; } diff --git a/stage1/spl_comp.h b/stage1/spl_comp.h index aea46cb..2e098b9 100644 --- a/stage1/spl_comp.h +++ b/stage1/spl_comp.h @@ -196,7 +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); - /* Register runtime natives (stub) */ void spl_comp_register(spl_prog_t *prog); diff --git a/stage1/spl_expr.c b/stage1/spl_expr.c index 8f8ef7d..725c5db 100644 --- a/stage1/spl_expr.c +++ b/stage1/spl_expr.c @@ -402,7 +402,10 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in } emit_dup(&ctx->emit); emit_ptr_add(&ctx->emit, i * stride); + int saved_aom = ctx->addr_of_mode; + ctx->addr_of_mode = 0; spl_parse_expr(ctx, PREC_MIN); + ctx->addr_of_mode = saved_aom; if (elem_type_idx >= 0 && !spl_type_is_scalar(&ctx->tctx, elem_type_idx)) { emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, elem_type_idx), 1); @@ -618,9 +621,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", - spl_tok_loc_str(ctx), arg_idx + 1, fname, + ctx->fname, 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)); } @@ -878,7 +881,7 @@ static spl_expr_result_t parse_primary_expr(spl_comp_t *ctx) { expect(ctx, TOK_R_PAREN); if (ti < 0) { spl_comp_error(ctx, "@sizeof: invalid type"); - spl_expr_result_t r = { -1, 0 }; + spl_expr_result_t r = {-1, 0}; return r; } usize sz = spl_type_size(&ctx->tctx, ti); @@ -1080,14 +1083,20 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l continue; } + int saved_aom = ctx->addr_of_mode; + ctx->addr_of_mode = 0; spl_parse_expr(ctx, PREC_MIN); + ctx->addr_of_mode = saved_aom; if (peek(ctx)->type == TOK_RANGE) { advance(ctx); spl_expr_result_t end_expr = {-1, 0}; int has_explicit_end = (peek(ctx)->type != TOK_R_BRACKET); if (has_explicit_end) { + int saved_aom = ctx->addr_of_mode; + ctx->addr_of_mode = 0; end_expr = spl_parse_expr(ctx, PREC_MIN); + ctx->addr_of_mode = saved_aom; } (void)end_expr; expect(ctx, TOK_R_BRACKET); @@ -1145,6 +1154,11 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_PTR || spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE)) { int idx_elem_idx = spl_type_elem_type(&ctx->tctx, left.type_idx); + /* void* -> treat as u8* */ + if (idx_elem_idx >= 0 && spl_type_kind(&ctx->tctx, idx_elem_idx) == TYPE_BASIC && + spl_type_basic_type(&ctx->tctx, idx_elem_idx) == SPL_VOID) { + idx_elem_idx = spl_type_basic(&ctx->tctx, SPL_U8); + } if (spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE) { emit_slice_index(ctx, idx_elem_idx); diff --git a/stage1/spl_lex_util.c b/stage1/spl_lex_util.c index b464dbb..6138174 100644 --- a/stage1/spl_lex_util.c +++ b/stage1/spl_lex_util.c @@ -122,11 +122,3 @@ 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_parser.c b/stage1/spl_parser.c index 9b95da3..b0b1bea 100644 --- a/stage1/spl_parser.c +++ b/stage1/spl_parser.c @@ -99,7 +99,10 @@ static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, int ret_type_idx, spl_pop_scope(ctx); emit_return(&ctx->emit, &ctx->tctx, ctx->current_ret_type_idx); - spl_prog_end_func(&ctx->prog, fi); + { + spl_func_info_t *f = &vec_at(ctx->funcs, fi); + spl_prog_end_func(&ctx->prog, f->func_idx); + } ctx->current_func_idx = -1; ctx->current_ret_type_idx = -1; return fi; @@ -293,7 +296,8 @@ static void parse_type_body(spl_comp_t *ctx, int container_type_idx, int is_enum 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_R_PAREN) + break; if (peek(ctx)->type == TOK_COMMA) { advance(ctx); /* , */ skip_nl(ctx); @@ -365,9 +369,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 if (tt == TOK_EOF) { - break; - } 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); diff --git a/stage1/spl_stmt.c b/stage1/spl_stmt.c index 629afb4..9e15295 100644 --- a/stage1/spl_stmt.c +++ b/stage1/spl_stmt.c @@ -991,7 +991,20 @@ void spl_parse_stmt(spl_comp_t *ctx) { case TOK_LINE_COMMENT: advance(ctx); break; - case TOK_AT: /* @extern(...) */ + case TOK_AT: { /* @extern(...) or @dbg/@@sizeof expression */ + usize saved = ctx->tok_idx; + advance(ctx); /* @ */ + skip_nl(ctx); + spl_tok_t *t = peek(ctx); + if (t && t->type == KW_EXTERN) { + ctx->tok_idx = saved; + parse_extern_decl(ctx); + } else { + ctx->tok_idx = saved; + parse_expr_stmt(ctx); + } + break; + } case TOK_SHARP: /* #[extern(...)] (legacy) */ parse_extern_decl(ctx); break; diff --git a/stage1/spl_type.c b/stage1/spl_type.c index 865de52..77b58e9 100644 --- a/stage1/spl_type.c +++ b/stage1/spl_type.c @@ -192,9 +192,7 @@ int spl_type_ptr(spl_type_ctx_t *tctx, int elem_type_idx) { } int spl_type_array(spl_type_ctx_t *tctx, int elem_type_idx, usize len) { - spl_type_info_t *elem = (elem_type_idx >= 0) - ? &vec_at(tctx->types, elem_type_idx) - : NULL; + spl_type_info_t *elem = (elem_type_idx >= 0) ? &vec_at(tctx->types, elem_type_idx) : NULL; spl_type_info_t t; memset(&t, 0, sizeof(t)); @@ -310,8 +308,7 @@ int spl_type_alias(spl_type_ctx_t *tctx, const char *name, int target_type_idx) * Item management * ============================================================ */ -void spl_type_add_field(spl_type_ctx_t *tctx, int type_idx, const char *name, - int field_type_idx) { +void spl_type_add_field(spl_type_ctx_t *tctx, int type_idx, const char *name, int field_type_idx) { spl_type_info_t *t = &vec_at(tctx->types, type_idx); spl_type_item_t item; memset(&item, 0, sizeof(item)); @@ -322,8 +319,7 @@ void spl_type_add_field(spl_type_ctx_t *tctx, int type_idx, const char *name, vec_push(t->items, item); } -void spl_type_add_variant(spl_type_ctx_t *tctx, int type_idx, const char *name, - int data_type_idx) { +void spl_type_add_variant(spl_type_ctx_t *tctx, int type_idx, const char *name, int data_type_idx) { spl_type_info_t *t = &vec_at(tctx->types, type_idx); spl_type_item_t item; memset(&item, 0, sizeof(item)); @@ -334,15 +330,13 @@ void spl_type_add_variant(spl_type_ctx_t *tctx, int type_idx, const char *name, vec_push(t->items, item); } -void spl_type_add_method(spl_type_ctx_t *tctx, int type_idx, const char *name, - int func_idx) { +void spl_type_add_method(spl_type_ctx_t *tctx, int type_idx, const char *name, int func_idx) { spl_type_info_t *t = &vec_at(tctx->types, type_idx); /* Deduplicate: update existing method entry */ vec_for(t->items, i) { spl_type_item_t *it = &vec_at(t->items, i); - if (it->item_kind == ITEM_METHOD && it->name && - strcmp(it->name, name) == 0) { + if (it->item_kind == ITEM_METHOD && it->name && strcmp(it->name, name) == 0) { it->method.func_idx = func_idx; return; } @@ -357,7 +351,7 @@ void spl_type_add_method(spl_type_ctx_t *tctx, int type_idx, const char *name, } void spl_type_add_nested(spl_type_ctx_t *tctx, int parent_idx, const char *name, - int child_type_idx) { + int child_type_idx) { spl_type_info_t *t = &vec_at(tctx->types, parent_idx); spl_type_item_t item; memset(&item, 0, sizeof(item)); @@ -387,8 +381,7 @@ void spl_type_compute_layout(spl_type_ctx_t *tctx, int type_idx) { spl_type_item_t *it = &vec_at(t->items, i); if (it->item_kind == ITEM_FIELD && it->aggregate_field.type_idx >= 0) { spl_type_compute_layout(tctx, it->aggregate_field.type_idx); - spl_type_info_t *ft = - &vec_at(tctx->types, it->aggregate_field.type_idx); + spl_type_info_t *ft = &vec_at(tctx->types, it->aggregate_field.type_idx); it->aggregate_field.offset = offset; offset += ft->byte_size; } @@ -407,8 +400,7 @@ void spl_type_compute_layout(spl_type_ctx_t *tctx, int type_idx) { spl_type_item_t *it = &vec_at(t->items, i); if (it->item_kind == ITEM_FIELD && it->aggregate_field.type_idx >= 0) { spl_type_compute_layout(tctx, it->aggregate_field.type_idx); - spl_type_info_t *ft = - &vec_at(tctx->types, it->aggregate_field.type_idx); + spl_type_info_t *ft = &vec_at(tctx->types, it->aggregate_field.type_idx); it->aggregate_field.offset = 0; if (ft->byte_size > max_sz) max_sz = ft->byte_size; @@ -426,11 +418,9 @@ void spl_type_compute_layout(spl_type_ctx_t *tctx, int type_idx) { usize max_dsize = 0; vec_for(t->items, i) { spl_type_item_t *it = &vec_at(t->items, i); - if (it->item_kind == ITEM_VARIANT && - it->enum_field.type_idx >= 0) { + if (it->item_kind == ITEM_VARIANT && it->enum_field.type_idx >= 0) { spl_type_compute_layout(tctx, it->enum_field.type_idx); - spl_type_info_t *dt = - &vec_at(tctx->types, it->enum_field.type_idx); + spl_type_info_t *dt = &vec_at(tctx->types, it->enum_field.type_idx); if (dt->byte_size > max_dsize) max_dsize = dt->byte_size; } @@ -543,8 +533,7 @@ int spl_type_is_scalar(spl_type_ctx_t *tctx, int type_idx) { } int spl_type_needs_multi_slot(spl_type_ctx_t *tctx, int type_idx) { - return !spl_type_is_scalar(tctx, type_idx) && - spl_type_slot_count(tctx, type_idx) > 1; + return !spl_type_is_scalar(tctx, type_idx) && spl_type_slot_count(tctx, type_idx) > 1; } int spl_type_is_aggregate(spl_type_ctx_t *tctx, int type_idx) { @@ -629,21 +618,18 @@ const char *spl_type_str(spl_type_ctx_t *tctx, int type_idx) { } case TYPE_PTR: { static char buf[64]; - snprintf(buf, sizeof(buf), "*%s", - spl_type_str(tctx, spl_type_elem_type(tctx, type_idx))); + snprintf(buf, sizeof(buf), "*%s", spl_type_str(tctx, spl_type_elem_type(tctx, type_idx))); return buf; } case TYPE_ARRAY: { static char buf[64]; - snprintf(buf, sizeof(buf), "[%zu]%s", - spl_type_array_len(tctx, type_idx), + snprintf(buf, sizeof(buf), "[%zu]%s", spl_type_array_len(tctx, type_idx), spl_type_str(tctx, spl_type_elem_type(tctx, type_idx))); return buf; } case TYPE_SLICE: { static char buf[64]; - snprintf(buf, sizeof(buf), "[]%s", - spl_type_str(tctx, spl_type_elem_type(tctx, type_idx))); + snprintf(buf, sizeof(buf), "[]%s", spl_type_str(tctx, spl_type_elem_type(tctx, type_idx))); return buf; } case TYPE_STRUCT: @@ -661,8 +647,7 @@ const char *spl_type_str(spl_type_ctx_t *tctx, int type_idx) { * Item iteration * ============================================================ */ -int spl_type_item_count(spl_type_ctx_t *tctx, int type_idx, - spl_type_item_kind_t kind) { +int spl_type_item_count(spl_type_ctx_t *tctx, int type_idx, spl_type_item_kind_t kind) { if (type_idx < 0) return 0; spl_type_info_t *t = &vec_at(tctx->types, type_idx); @@ -674,8 +659,7 @@ int spl_type_item_count(spl_type_ctx_t *tctx, int type_idx, return count; } -spl_type_item_t *spl_type_item_at(spl_type_ctx_t *tctx, int type_idx, - int item_index) { +spl_type_item_t *spl_type_item_at(spl_type_ctx_t *tctx, int type_idx, int item_index) { if (type_idx < 0) return NULL; spl_type_info_t *t = &vec_at(tctx->types, type_idx); @@ -685,8 +669,7 @@ spl_type_item_t *spl_type_item_at(spl_type_ctx_t *tctx, int type_idx, } spl_type_item_t *spl_type_first_of_kind(spl_type_ctx_t *tctx, int type_idx, - spl_type_item_kind_t kind, - int *count) { + spl_type_item_kind_t kind, int *count) { if (type_idx < 0) { if (count) *count = 0; @@ -737,15 +720,13 @@ int spl_type_resolve(spl_type_ctx_t *tctx, const char *name) { return -1; } -int spl_type_resolve_in(spl_type_ctx_t *tctx, int parent_idx, - const char *name) { +int spl_type_resolve_in(spl_type_ctx_t *tctx, int parent_idx, const char *name) { if (parent_idx < 0 || !name) return -1; spl_type_info_t *t = &vec_at(tctx->types, parent_idx); vec_for(t->items, i) { spl_type_item_t *it = &vec_at(t->items, i); - if (it->item_kind == ITEM_NESTED_TYPE && it->name && - strcmp(it->name, name) == 0) + if (it->item_kind == ITEM_NESTED_TYPE && it->name && strcmp(it->name, name) == 0) return it->nested_type.type_idx; } return -1; @@ -859,8 +840,7 @@ int spl_type_parse(spl_type_ctx_t *tctx, struct spl_comp *ctx) { } /* Identifier: basic type or named type */ - if (tok->type == TOK_IDENT || - ((int)tok->type >= (int)KW_AS && (int)tok->type <= (int)KW_ANY)) { + if (tok->type == TOK_IDENT || ((int)tok->type >= (int)KW_AS && (int)tok->type <= (int)KW_ANY)) { const char *name = tok->lexeme; usize len = tok->len; diff --git a/stage1/spl_type.h b/stage1/spl_type.h index afd1aed..6716e4a 100644 --- a/stage1/spl_type.h +++ b/stage1/spl_type.h @@ -79,9 +79,9 @@ typedef struct spl_type_info { spl_type_kind_t kind; spl_type_t basic_type; /* for TYPE_BASIC */ spl_type_item_vec_t items; - usize byte_size; /* total byte size (cached) */ - usize slot_count; /* stack slot count (cached) */ - int resolved; /* layout computed */ + usize byte_size; /* total byte size (cached) */ + usize slot_count; /* stack slot count (cached) */ + int resolved; /* layout computed */ int parent_type_idx; /* enclosing type, -1 for root */ } spl_type_info_t; @@ -127,14 +127,11 @@ int spl_type_alias(spl_type_ctx_t *tctx, const char *name, int target_type_idx); * Item management — add members to aggregate types * ============================================================ */ -void spl_type_add_field(spl_type_ctx_t *tctx, int type_idx, const char *name, - int field_type_idx); -void spl_type_add_variant(spl_type_ctx_t *tctx, int type_idx, const char *name, - int data_type_idx); -void spl_type_add_method(spl_type_ctx_t *tctx, int type_idx, const char *name, - int func_idx); +void spl_type_add_field(spl_type_ctx_t *tctx, int type_idx, const char *name, int field_type_idx); +void spl_type_add_variant(spl_type_ctx_t *tctx, int type_idx, const char *name, int data_type_idx); +void spl_type_add_method(spl_type_ctx_t *tctx, int type_idx, const char *name, int func_idx); void spl_type_add_nested(spl_type_ctx_t *tctx, int parent_idx, const char *name, - int child_type_idx); + int child_type_idx); /* ============================================================ * Layout — compute byte_size / slot_count, set resolved @@ -185,13 +182,11 @@ const char *spl_type_str(spl_type_ctx_t *tctx, int type_idx); * Item iteration — filter by item_kind * ============================================================ */ -int spl_type_item_count(spl_type_ctx_t *tctx, int type_idx, - spl_type_item_kind_t kind); -spl_type_item_t *spl_type_item_at(spl_type_ctx_t *tctx, int type_idx, - int item_index); +int spl_type_item_count(spl_type_ctx_t *tctx, int type_idx, spl_type_item_kind_t kind); +spl_type_item_t *spl_type_item_at(spl_type_ctx_t *tctx, int type_idx, int item_index); /* Returns pointer to first item of given kind, with *count set */ spl_type_item_t *spl_type_first_of_kind(spl_type_ctx_t *tctx, int type_idx, - spl_type_item_kind_t kind, int *count); + spl_type_item_kind_t kind, int *count); /* Get raw items vec for direct iteration (avoids double-lookup) */ spl_type_item_vec_t *spl_type_items(spl_type_ctx_t *tctx, int type_idx);