/* spl_comp.h — SPL compiler: type system, parser, codegen */ #ifndef __SPL_COMP_H__ #define __SPL_COMP_H__ #include "../stage0/spl_ir.h" #include "spl_lexer.h" #include #include #include #include /* ============================================================ * Type representation * ============================================================ */ typedef enum { TYPE_VOID, TYPE_BASIC, TYPE_PTR, TYPE_ARRAY, TYPE_SLICE, TYPE_STRUCT, TYPE_ENUM, TYPE_ENUM_VARIANT, /* enum variant with data */ TYPE_NAME, /* named alias */ TYPE_INFER, /* _ (to be inferred) */ } spl_type_kind_t; /* Forward declaration */ typedef struct spl_type_info spl_type_info_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; 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 */ 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_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_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); 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); /* ============================================================ * Scope / symbol table * ============================================================ */ typedef struct spl_var_info { char *name; spl_type_info_t *type; int slot; /* stack slot offset from fp */ int is_const; int depth; /* scope depth */ } spl_var_info_t; typedef VEC(spl_var_info_t) spl_var_vec_t; typedef struct spl_scope { spl_var_vec_t vars; int depth; } spl_scope_t; 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; char **param_names; int nparams; int func_idx; /* index in prog->funcs */ int is_extern; /* #[extern("vm")] */ int is_pub; } spl_func_info_t; typedef VEC(spl_func_info_t) spl_func_info_vec_t; /* ============================================================ * Compiler context * ============================================================ */ #define COMP_ERROR_MAX 256 #define DEFER_MAX 64 typedef struct { /* Lexer output */ spl_tok_vec_t toks; usize tok_idx; const char *fname; const char *source; /* Program output */ spl_prog_t prog; /* Error state */ char error_msg[COMP_ERROR_MAX]; int has_error; /* Scopes */ spl_scope_vec_t scopes; int scope_depth; /* Function table */ spl_func_info_vec_t funcs; /* Type definitions (name → spl_type_info_t*) */ MAP(const char *, spl_type_info_t *) type_defs; /* Current function context */ int current_func_idx; spl_type_info_t *current_ret_type; int current_local_slot; /* next free local slot */ /* Loop context for break/continue */ int in_loop; usize *break_patches; /* instruction addresses to patch */ usize break_patch_count; usize break_patch_cap; usize continue_target; /* ip to jump to for continue */ /* Defer stack */ usize defer_addrs[DEFER_MAX]; int defer_count; /* Global data index for string literals */ int next_gdata_idx; /* Const values */ MAP(const char *, spl_val_t) const_values; int addr_of_mode; /* 1 = inside & operator, suppress loads */ } spl_comp_t; /* Initialize/destroy compiler context */ void spl_comp_init(spl_comp_t *ctx); void spl_comp_drop(spl_comp_t *ctx); /* Main compilation entry: source → .sir */ int spl_compile(spl_comp_t *ctx, const char *source, const char *fname); /* Reset for a new compilation */ void spl_comp_reset(spl_comp_t *ctx); /* Error reporting */ void spl_comp_error(spl_comp_t *ctx, const char *fmt, ...); /* ============================================================ * Parser functions (spl_parser.c) * ============================================================ */ void spl_parse_prog(spl_comp_t *ctx); 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, PREC_LOGOR = 2, PREC_LOGAND = 3, PREC_OR = 4, PREC_XOR = 5, PREC_AND = 6, PREC_CMPEQ = 7, PREC_CMP = 8, PREC_SHIFT = 9, PREC_ADD = 10, PREC_MUL = 11, PREC_PREFIX = 12, 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 */ } spl_expr_result_t; spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec); /* ============================================================ * Statement functions (spl_stmt.c) * ============================================================ */ void spl_parse_stmt(spl_comp_t *ctx); void spl_parse_block(spl_comp_t *ctx); /* ============================================================ * Codegen helpers (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); /* Variable management */ int spl_declare_var(spl_comp_t *ctx, const char *name, spl_type_info_t *type, int is_const); spl_var_info_t *spl_lookup_var(spl_comp_t *ctx, const char *name); int spl_get_var_slot(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 is_extern, int is_pub); int spl_lookup_func(spl_comp_t *ctx, const char *name); /* String/data management */ int spl_add_string(spl_comp_t *ctx, const char *str); int spl_add_global_data(spl_comp_t *ctx, void *data, usize size); /* Scope management */ void spl_push_scope(spl_comp_t *ctx); void spl_pop_scope(spl_comp_t *ctx); /* Register runtime natives */ void spl_comp_register(spl_prog_t *prog); /* Defer */ void spl_emit_defer(spl_comp_t *ctx); void spl_emit_defer_epilogue(spl_comp_t *ctx); /* 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); #endif /* __SPL_COMP_H__ */