Files
spl/stage1/spl_comp.h

295 lines
9.3 KiB
C

/* 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 <stdint.h>
#include <stdio.h>
#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;
/* 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;
/* 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 */
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);
/* ============================================================
* Scope / symbol table
* ============================================================ */
typedef struct spl_var_info {
char *name;
spl_type_info_t *type;
int offset; /* byte 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 {
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 */
} spl_defer_entry_t;
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_bytes; /* next free local byte offset */
const char *current_type_name; /* name of type whose body we're parsing (for method short-name
lookup) */
/* 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 */
spl_defer_entry_t defer_stack[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);
/* 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);
/* 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_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 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, 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);
/* Shared token helpers (defined in spl_parser.c) */
spl_tok_t *peek(spl_comp_t *ctx);
spl_tok_t *advance(spl_comp_t *ctx);
#endif /* __SPL_COMP_H__ */