278 lines
8.9 KiB
C
278 lines
8.9 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);
|
|
|
|
/* 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__ */
|