stage1 重构代码

This commit is contained in:
zzy
2026-07-20 12:10:55 +08:00
parent ab63c8ed90
commit 21f35b30fa
14 changed files with 1963 additions and 1539 deletions

View File

@@ -10,108 +10,22 @@
#include <stdlib.h>
#include <string.h>
/* ============================================================
* Type representation
* ============================================================ */
typedef enum {
TYPE_VOID,
TYPE_BASIC,
TYPE_PTR,
TYPE_ARRAY,
TYPE_SLICE,
TYPE_STRUCT,
TYPE_UNION,
TYPE_ENUM,
TYPE_ENUM_VARIANT, /* enum variant with data */
TYPE_NAME, /* named alias */
TYPE_INFER, /* _ (to be inferred) */
} spl_type_kind_t;
#include "spl_type.h"
#include "spl_emit.h"
/* Forward declarations */
typedef struct spl_type_info spl_type_info_t;
typedef struct spl_comp spl_comp_t;
/* Struct field */
typedef struct {
char *name;
spl_type_info_t *type;
usize offset; /* byte offset in struct layout */
} spl_field_t;
typedef VEC(spl_field_t) spl_field_vec_t;
/* Enum variant */
typedef struct {
char *name;
spl_type_info_t *data_type; /* NULL for simple enum */
int value; /* constant index */
} spl_enum_variant_t;
typedef VEC(spl_enum_variant_t) spl_enum_variant_vec_t;
/* Method info (struct/enum methods) */
typedef struct {
char *name;
int func_idx; /* index in ctx->funcs */
} spl_method_info_t;
typedef VEC(spl_method_info_t) spl_method_info_vec_t;
struct spl_type_info {
spl_type_kind_t kind;
spl_type_t basic_type; /* for TYPE_BASIC */
spl_type_info_t *elem; /* for PTR/ARRAY/SLICE element type */
usize array_len; /* for TYPE_ARRAY */
char *name; /* type name for TYPE_NAME/STRUCT/ENUM */
spl_field_vec_t fields; /* for TYPE_STRUCT */
spl_enum_variant_vec_t variants; /* for TYPE_ENUM */
spl_method_info_vec_t methods; /* methods */
MAP(const char *, spl_type_info_t *) children; /* nested type namespace */
usize byte_size; /* total byte size (cached) */
usize slot_count; /* stack slot count */
int is_pub; /* public visibility */
int resolved; /* type fully resolved */
};
/* Type constructor helpers */
spl_type_info_t *spl_type_basic(spl_type_t bt);
spl_type_info_t *spl_type_ptr(spl_type_info_t *elem);
spl_type_info_t *spl_type_array(spl_type_info_t *elem, usize len);
spl_type_info_t *spl_type_slice(spl_type_info_t *elem);
spl_type_info_t *spl_type_struct(const char *name);
spl_type_info_t *spl_type_union(const char *name);
spl_type_info_t *spl_type_enum(const char *name);
void spl_type_add_field(spl_type_info_t *st, const char *name, spl_type_info_t *ftype);
void spl_type_add_variant(spl_type_info_t *et, const char *name, spl_type_info_t *dtype);
void spl_type_add_method(spl_type_info_t *t, const char *name, int func_idx);
void spl_type_compute_layout(spl_type_info_t *t);
usize spl_type_size(spl_type_info_t *t);
usize spl_type_slot_count(spl_type_info_t *t);
/* Byte stride between consecutive elements in storage (slot-based layout) */
usize spl_type_elem_stride(spl_type_info_t *elem);
const char *spl_type_str(spl_type_info_t *t);
int spl_type_is_integer(spl_type_t bt);
spl_type_info_t *spl_type_clone(spl_type_info_t *t);
/* Determine the uniform type for LOAD/STORE codegen */
spl_type_t spl_type_emit_type(spl_type_info_t *type);
/* Returns 1 if type is scalar (fits in one slot, auto-loadable, comparable with ==/!=) */
int spl_type_is_scalar(spl_type_info_t *type);
/* Emit LOAD from [saved_ptr + byte_offset] and STORE to local var at var_offset.
* Stack: [] → []
* The saved_ptr is loaded from the 1-slot temp at ptr_slot_offset. */
void spl_emit_load_to_var(spl_comp_t *ctx, int ptr_slot_offset, usize byte_offset,
spl_type_info_t *data_type, int var_offset);
/* ============================================================
* Scope / symbol table
* ============================================================ */
typedef struct spl_var_info {
char *name;
spl_type_info_t *type;
int offset; /* byte offset from fp */
int type_idx;
int offset;
int is_const;
int depth; /* scope depth */
int depth;
} spl_var_info_t;
typedef VEC(spl_var_info_t) spl_var_vec_t;
@@ -123,12 +37,12 @@ typedef VEC(spl_scope_t) spl_scope_vec_t;
typedef struct spl_func_info {
char *name;
spl_type_info_t *ret_type;
spl_type_info_t **param_types;
int ret_type_idx;
int *param_type_indices;
char **param_names;
int nparams;
int func_idx; /* index in prog->funcs */
int is_extern; /* #[extern("vm")] */
int func_idx;
int is_extern;
int is_pub;
} spl_func_info_t;
typedef VEC(spl_func_info_t) spl_func_info_vec_t;
@@ -141,10 +55,10 @@ typedef VEC(spl_func_info_t) spl_func_info_vec_t;
#define DEFER_MAX 64
typedef struct {
usize body_start; /* IP where defer body starts (after skip-JMP) */
usize jmp_exit; /* IP of the JMP after the body (to patch at scope exit) */
int depth; /* scope depth */
int count_at_decl; /* defer_count when declared */
usize body_start;
usize jmp_exit;
int depth;
int count_at_decl;
} spl_defer_entry_t;
typedef struct spl_comp {
@@ -157,6 +71,9 @@ typedef struct spl_comp {
/* Program output */
spl_prog_t prog;
/* IR emission + frame allocator */
spl_emit_t emit;
/* Error state */
char error_msg[COMP_ERROR_MAX];
int has_error;
@@ -168,22 +85,19 @@ typedef struct spl_comp {
/* Function table */
spl_func_info_vec_t funcs;
/* Type definitions (name → spl_type_info_t*) */
MAP(const char *, spl_type_info_t *) type_defs;
/* Type context — first-class type arena + namespace */
spl_type_ctx_t tctx;
/* Current function context */
int current_func_idx;
spl_type_info_t *current_ret_type;
int current_local_bytes; /* next free local byte offset */
int peak_local_bytes; /* peak current_local_bytes for ALLOC sizing */
VEC(spl_type_info_t *) ns_chain; /* type namespace scope chain */
int current_ret_type_idx;
/* Loop context for break/continue */
int in_loop;
usize *break_patches; /* instruction addresses to patch */
usize *break_patches;
usize break_patch_count;
usize break_patch_cap;
usize continue_target; /* ip to jump to for continue */
usize continue_target;
/* Defer stack */
spl_defer_entry_t defer_stack[DEFER_MAX];
@@ -195,13 +109,7 @@ typedef struct spl_comp {
/* Const values */
MAP(const char *, spl_val_t) const_values;
int addr_of_mode; /* 1 = inside & operator, suppress loads */
/* Fixup list: PUSH instructions whose immediate (function address) must
* be patched after ALL function bodies are compiled. This handles forward
* references — method A calling method B defined later in the same type. */
VEC(spl_val_t) call_fixups; /* instruction indices of PUSH insns to patch */
VEC(int) call_fixup_funcs; /* prog->funcs index for each fixup */
int addr_of_mode;
} spl_comp_t;
/* Initialize/destroy compiler context */
@@ -228,7 +136,6 @@ void parse_type_decl(spl_comp_t *ctx);
* Expression functions (spl_expr.c)
* ============================================================ */
/* Precedence levels for Pratt parser */
enum {
PREC_MIN = 0,
PREC_ASSIGN = 1,
@@ -246,22 +153,17 @@ enum {
PREC_POSTFIX = 13
};
/* Result of expression codegen */
typedef struct {
spl_type_info_t *type;
int is_lvalue; /* 1 = address on stack, 0 = value on stack */
int type_idx;
int is_lvalue;
} spl_expr_result_t;
spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec);
spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *type);
spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx);
/* Match arm pattern comparison — emit code to compare saved match value
* against a parsed pattern. Comparison logic belongs in expr layer
* so that match arms behave as "enhanced if-conditions".
* For enum: parses .VariantName, emits tag comparison, returns variant.
* For value: parses expression, emits equality comparison. */
spl_enum_variant_t *spl_emit_match_enum_cmp(spl_comp_t *ctx, spl_type_info_t *enum_type,
int val_offset, int by_value);
/* Match arm pattern comparison */
int spl_emit_match_enum_cmp(spl_comp_t *ctx, int enum_type_idx, int val_offset,
int by_value);
void spl_emit_match_value_cmp(spl_comp_t *ctx, int val_offset);
/* ============================================================
@@ -273,35 +175,21 @@ void spl_parse_block(spl_comp_t *ctx);
spl_expr_result_t spl_parse_block_expr(spl_comp_t *ctx);
/* ============================================================
* Codegen helpers (spl_comp.c)
* Remaining helpers in spl_comp.c
* ============================================================ */
spl_val_t spl_emit(spl_comp_t *ctx, uint16_t opcode, uint16_t type, spl_val_t imm);
void spl_patch(spl_comp_t *ctx, spl_val_t addr, spl_val_t target);
spl_val_t spl_emit_jmp(spl_comp_t *ctx);
spl_val_t spl_emit_bz(spl_comp_t *ctx);
spl_val_t spl_emit_bnz(spl_comp_t *ctx);
void spl_patch_to_here(spl_comp_t *ctx, spl_val_t addr);
/* Copy multi-slot value from TOS (temp address) to frame-relative destination.
* Stack: [..., temp_addr] → [...]
* Copies nslots slots (each sizeof(spl_val_t) bytes) from temp offset to dest_offset. */
void spl_emit_copy_slots(spl_comp_t *ctx, int dest_offset, usize nslots);
void spl_emit_copy_addr_to_addr(spl_comp_t *ctx, usize nslots, int depth);
void spl_emit_ret(spl_comp_t *ctx, spl_type_info_t *ret_type);
void spl_emit_store_init(spl_comp_t *ctx, int var_offset, spl_type_info_t *var_type);
void spl_emit_ret(spl_comp_t *ctx, int ret_type_idx);
void spl_emit_store_init(spl_comp_t *ctx, int var_offset, int var_type_idx);
/* Variable management */
int spl_declare_var(spl_comp_t *ctx, const char *name, spl_type_info_t *type, int is_const);
int spl_declare_var(spl_comp_t *ctx, const char *name, int type_idx, int is_const);
spl_var_info_t *spl_lookup_var(spl_comp_t *ctx, const char *name);
int spl_get_var_offset(spl_comp_t *ctx, const char *name);
/* Function management */
int spl_declare_func(spl_comp_t *ctx, const char *name, spl_type_info_t *ret_type, int nparams,
int spl_declare_func(spl_comp_t *ctx, const char *name, int ret_type_idx, int nparams,
int is_extern, int is_pub);
int spl_lookup_func(spl_comp_t *ctx, const char *name);
/* Ensure a native function is registered for NCALL dispatch, returns index */
int spl_ensure_native(spl_comp_t *ctx, const char *name);
/* String/data management */
@@ -312,23 +200,12 @@ 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);
/* Namespace chain management */
void spl_ns_push(spl_comp_t *ctx, spl_type_info_t *type);
void spl_ns_pop(spl_comp_t *ctx);
/* Register runtime natives */
void spl_comp_register(spl_prog_t *prog);
/* Patch all CALL fixups after all function bodies are compiled */
void spl_patch_call_fixups(spl_comp_t *ctx);
/* Defer */
void spl_emit_defer(spl_comp_t *ctx);
void spl_emit_defer_epilogue(spl_comp_t *ctx, int depth);
/* Type lookup and parsing */
spl_type_info_t *spl_resolve_type(spl_comp_t *ctx, const char *name);
spl_type_info_t *spl_parse_type(spl_comp_t *ctx);
/* Register runtime natives (stub) */
void spl_comp_register(spl_prog_t *prog);
/* Shared token helpers (defined in spl_parser.c) */
spl_tok_t *peek(spl_comp_t *ctx);