Compare commits
2 Commits
78d767bf21
...
4d9509c167
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d9509c167 | |||
| d3c63dab5c |
@@ -77,6 +77,8 @@ static inline usize map_hash_str(const char *s) {
|
||||
for (usize(idx) = 0; (idx) < (map).cap; ++(idx)) \
|
||||
if ((map).data[(idx)].state == __MAP_SLOT_OCCUPIED)
|
||||
|
||||
#define unsafe_map_at(map, idx) ((map).data[(idx)])
|
||||
|
||||
/**
|
||||
* 插入(若键已存在则更新值)
|
||||
* 注意:扩容使用 realloc,失败会 abort(可自行修改错误处理)
|
||||
|
||||
@@ -54,7 +54,7 @@ int main(int argc, const char **argv) {
|
||||
spl_vm_ins_t *ins = &vec_at(prog.insns, i);
|
||||
printf("%4zd: %s", i, spl_vm_opcode_name((spl_vm_opcode_t)ins->opcode));
|
||||
if (ins->type != SPL_VOID)
|
||||
printf(" %s", spl_vm_type_kind_name((spl_type_t)ins->type));
|
||||
printf(" %s", spl_vm_type_kind_name((spl_vm_kind_t)ins->type));
|
||||
printf(" %zd", ins->imm);
|
||||
|
||||
/* annotate jumps / calls */
|
||||
|
||||
@@ -427,7 +427,7 @@ const char *opcode_name[] = {
|
||||
#undef X
|
||||
};
|
||||
const char *spl_vm_opcode_name(spl_vm_opcode_t opcode) { return opcode_name[opcode]; }
|
||||
const char *spl_vm_type_kind_name(spl_type_t type) {
|
||||
const char *spl_vm_type_kind_name(spl_vm_kind_t type) {
|
||||
switch (type) {
|
||||
case SPL_VOID:
|
||||
return "void";
|
||||
@@ -467,7 +467,7 @@ const char *spl_vm_type_kind_name(spl_type_t type) {
|
||||
void spl_vm_ins_dump(spl_vm_ins_t *ins, spl_vm_val_t addr) {
|
||||
printf("%4zu: %s", addr, spl_vm_opcode_name((spl_vm_opcode_t)ins->opcode));
|
||||
if (ins->type != SPL_VOID)
|
||||
printf(" %s", spl_vm_type_kind_name((spl_type_t)ins->type));
|
||||
printf(" %s", spl_vm_type_kind_name((spl_vm_kind_t)ins->type));
|
||||
printf(" %zd:%zx", ins->imm, ins->imm);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef enum {
|
||||
SPL_F64,
|
||||
SPL_PTR,
|
||||
SPL_TYPE_COUNT,
|
||||
} spl_type_t;
|
||||
} spl_vm_kind_t;
|
||||
|
||||
/* clang-format off */
|
||||
#define SPL_OPCODES(X) \
|
||||
@@ -213,7 +213,7 @@ spl_vm_native_t *spl_prog_get_native(spl_prog_t *prog, const char *name);
|
||||
|
||||
/* Opcode name lookup for debugging/dumping */
|
||||
const char *spl_vm_opcode_name(spl_vm_opcode_t opcode);
|
||||
const char *spl_vm_type_kind_name(spl_type_t type);
|
||||
const char *spl_vm_type_kind_name(spl_vm_kind_t type);
|
||||
|
||||
void spl_vm_ins_dump(spl_vm_ins_t *ins, spl_vm_val_t addr);
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
* Type helpers
|
||||
* ================================================================ */
|
||||
|
||||
static int spl_is_float(spl_type_t t) { return t == SPL_F32 || t == SPL_F64; }
|
||||
static int spl_is_signed(spl_type_t t) {
|
||||
static int spl_is_float(spl_vm_kind_t t) { return t == SPL_F32 || t == SPL_F64; }
|
||||
static int spl_is_signed(spl_vm_kind_t t) {
|
||||
switch (t) {
|
||||
case SPL_I8:
|
||||
case SPL_I16:
|
||||
@@ -41,7 +41,7 @@ static int spl_is_signed(spl_type_t t) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static int spl_type_size(spl_type_t t) {
|
||||
static int spl_type_size(spl_vm_kind_t t) {
|
||||
switch (t) {
|
||||
case SPL_VOID:
|
||||
return 0;
|
||||
@@ -123,7 +123,7 @@ static int spl_type_size(spl_type_t t) {
|
||||
do { \
|
||||
spl_vm_val_t _b = POP(), _a = POP(); \
|
||||
spl_vm_val_t _r = 0; \
|
||||
if (spl_is_float((spl_type_t)ins->type)) { \
|
||||
if (spl_is_float((spl_vm_kind_t)ins->type)) { \
|
||||
double _da, _db, _dr; \
|
||||
if (ins->type == SPL_F32) { \
|
||||
float _fa, _fb; \
|
||||
@@ -185,7 +185,7 @@ static int spl_type_size(spl_type_t t) {
|
||||
if (_b == 0) \
|
||||
VM_ERROR("division by zero"); \
|
||||
spl_vm_val_t _r = 0; \
|
||||
if (spl_is_float((spl_type_t)ins->type)) { \
|
||||
if (spl_is_float((spl_vm_kind_t)ins->type)) { \
|
||||
double _da, _db, _dr; \
|
||||
if (ins->type == SPL_F32) { \
|
||||
float _fa, _fb; \
|
||||
@@ -545,6 +545,7 @@ LONG WINAPI UnhandledExceptionFilterImpl(EXCEPTION_POINTERS *pExceptionInfo) {
|
||||
* ================================================================ */
|
||||
void spl_vm_init_ex(spl_vm_t *vm, int stack_size, int call_depth) {
|
||||
#ifdef _WIN32
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
SetUnhandledExceptionFilter(UnhandledExceptionFilterImpl);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
SetConsoleCP(CP_UTF8);
|
||||
@@ -843,7 +844,7 @@ int spl_vm_run_once(spl_vm_t *vm) {
|
||||
|
||||
case SPL_NEG: {
|
||||
spl_vm_val_t _a = POP();
|
||||
if (spl_is_float((spl_type_t)ins->type)) {
|
||||
if (spl_is_float((spl_vm_kind_t)ins->type)) {
|
||||
double _d;
|
||||
if (ins->type == SPL_F32) {
|
||||
float _f;
|
||||
|
||||
@@ -58,6 +58,7 @@ static inline spl_ast_node_t *node_at(spl_ast_t *ast, spl_ast_node_ref_t ref) {
|
||||
static spl_ast_node_ref_t new_node(parser_t *p, spl_ast_node_kind_t kind, const spl_tok_t *tok) {
|
||||
spl_ast_node_t n = {0};
|
||||
n.kind = kind;
|
||||
n.resolved_def_id = 0;
|
||||
if (tok) {
|
||||
n.dbg.dbg_name = spl_ast_kind_name(kind);
|
||||
n.dbg.fname = tok->fname;
|
||||
@@ -1792,8 +1793,8 @@ void spl_ast_prase(spl_ast_t *ast) {
|
||||
if (d)
|
||||
vec_push(members, d);
|
||||
}
|
||||
spl_ast_node_ref_t root = new_node(&p, SPL_AST_CONTAINER_ITEM, begin);
|
||||
node_at(ast, root)->container_item.members = members;
|
||||
spl_ast_node_ref_t root = new_node(&p, SPL_AST_CONTAINER_MEMBERS, begin);
|
||||
node_at(ast, root)->container_members = members;
|
||||
ast->root = root;
|
||||
ast->parsed = p.failed ? -1 : 1;
|
||||
}
|
||||
@@ -1809,6 +1810,12 @@ void spl_ast_drop(spl_ast_t *ast) {
|
||||
ast->root = 0;
|
||||
}
|
||||
|
||||
spl_ast_node_t *spl_ast_node(spl_ast_t *ast, spl_ast_node_ref_t node) {
|
||||
if (!ast || node == 0)
|
||||
return NULL;
|
||||
return &vec_at(ast->node_buckets, node);
|
||||
}
|
||||
|
||||
void spl_ast_valid(spl_ast_t *ast) {
|
||||
if (!ast)
|
||||
return;
|
||||
@@ -1827,6 +1834,7 @@ void spl_ast_dump(spl_ast_t *ast, spl_ast_node_ref_t node) {
|
||||
return;
|
||||
dump_stack_t stack;
|
||||
vec_init(stack);
|
||||
printf("AST:\n");
|
||||
dump_node(ast, node, &stack, 1);
|
||||
}
|
||||
|
||||
@@ -1851,9 +1859,8 @@ static void dump_node(spl_ast_t *ast, spl_ast_node_ref_t node_ref, dump_stack_t
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
case SPL_AST_CONTAINER_ITEM:
|
||||
dump_vec(ast, node->container_item.attr_list, stack);
|
||||
dump_vec(ast, node->container_item.members, stack);
|
||||
case SPL_AST_CONTAINER_MEMBERS:
|
||||
dump_vec(ast, node->container_members, stack);
|
||||
break;
|
||||
|
||||
case SPL_AST_FN_DECL:
|
||||
@@ -2104,6 +2111,7 @@ static void dump_node(spl_ast_t *ast, spl_ast_node_ref_t node_ref, dump_stack_t
|
||||
case SPL_AST_TYPE_STRUCT:
|
||||
case SPL_AST_TYPE_UNION:
|
||||
case SPL_AST_TYPE_ENUM:
|
||||
case SPL_AST_TYPE_SHAPE:
|
||||
dump_vec(ast, node->type_expr.attr_list, stack);
|
||||
dump_vec(ast, node->type_expr.aggregate_list, stack);
|
||||
break;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/* clang-format off */
|
||||
#define SPL_AST_KIND_TABLE \
|
||||
X(SPL_AST_NONE, V0, none) \
|
||||
X(SPL_AST_CONTAINER_ITEM, V0, container_item) \
|
||||
X(SPL_AST_CONTAINER_MEMBERS, V0, container_members) \
|
||||
X(SPL_AST_FN_DECL, V0, fn_decl) \
|
||||
X(SPL_AST_FN_DEFINE, V0, fn_define) \
|
||||
X(SPL_AST_TYPE_DECL, V0, type_decl) \
|
||||
@@ -97,6 +97,7 @@
|
||||
X(SPL_AST_TYPE_SLICE, V0, type_slice) \
|
||||
X(SPL_AST_TYPE_STRUCT, V0, type_struct) \
|
||||
X(SPL_AST_TYPE_UNION, V0, type_union) \
|
||||
X(SPL_AST_TYPE_SHAPE, V0, type_shape) \
|
||||
X(SPL_AST_TYPE_ENUM, V0, type_enum) \
|
||||
X(SPL_AST_TYPE_VOID, V0, type_void) \
|
||||
X(SPL_AST_TYPE_BOOL, V0, type_bool) \
|
||||
@@ -140,10 +141,7 @@ struct spl_ast_node {
|
||||
|
||||
usize resolved_def_id;
|
||||
union {
|
||||
struct {
|
||||
spl_ast_node_ref_vec_t attr_list; /* attr_item */
|
||||
spl_ast_node_ref_vec_t members; /* container_decl 列表 */
|
||||
} container_item;
|
||||
spl_ast_node_ref_vec_t container_members; /* container_decl */
|
||||
|
||||
struct {
|
||||
const char *ident;
|
||||
@@ -314,6 +312,8 @@ typedef struct {
|
||||
void spl_ast_init(spl_ast_t *ast, const spl_tok_vec_t *tok_vec /*move*/);
|
||||
void spl_ast_drop(spl_ast_t *ast);
|
||||
|
||||
spl_ast_node_t* spl_ast_node(spl_ast_t *ast, spl_ast_node_ref_t node);
|
||||
|
||||
void spl_ast_prase(spl_ast_t *ast);
|
||||
void spl_ast_valid(spl_ast_t *ast);
|
||||
void spl_ast_dump(spl_ast_t *ast, spl_ast_node_ref_t node);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef __SPL_DBG_H__
|
||||
#define __SPL_DBG_H__
|
||||
|
||||
#include "spl_tok.h"
|
||||
|
||||
typedef struct {
|
||||
const char *fname;
|
||||
int line;
|
||||
|
||||
2223
stage1/spl_sema.c
2223
stage1/spl_sema.c
File diff suppressed because it is too large
Load Diff
@@ -4,32 +4,51 @@
|
||||
#include "spl_ast.h"
|
||||
#include "spl_type.h"
|
||||
|
||||
typedef enum {
|
||||
SPL_SYMBOL_KIND_ERROR,
|
||||
SPL_SYMBOL_KIND_VAR,
|
||||
SPL_SYMBOL_KIND_MEMBER,
|
||||
SPL_SYMBOL_KIND_FN,
|
||||
SPL_SYMBOL_KIND_TYPE,
|
||||
} spl_symbol_kind_t;
|
||||
typedef struct {
|
||||
const char *name;
|
||||
spl_symbol_kind_t kind;
|
||||
spl_def_id_t node;
|
||||
} spl_symbol_t;
|
||||
|
||||
typedef usize spl_scope_id_t; /* 0 is error */
|
||||
typedef struct {
|
||||
spl_scope_id_t parent;
|
||||
MAP(const char *, spl_def_id_t) symbols;
|
||||
MAP(const char *, spl_symbol_t) symbols;
|
||||
} spl_scope_node_t;
|
||||
typedef VEC(spl_scope_node_t) spl_scope_node_vec_t;
|
||||
|
||||
typedef struct {
|
||||
spl_ast_t *ast;
|
||||
spl_type_t type;
|
||||
spl_scope_node_vec_t scopes;
|
||||
spl_scope_id_t root_scope;
|
||||
spl_scope_id_t current_scope;
|
||||
spl_def_id_t root_def;
|
||||
} spl_scope_t;
|
||||
|
||||
void spl_scope_init(spl_scope_t *scope);
|
||||
void spl_scope_drop(spl_scope_t *scope);
|
||||
|
||||
spl_scope_id_t spl_scope_alloc(spl_scope_t *scope);
|
||||
bool spl_scope_insert(spl_scope_t *scope, spl_scope_id_t id, spl_symbol_t symbol);
|
||||
typedef VEC(const char *) spl_symbol_path_t;
|
||||
bool spl_scope_find(spl_scope_t *scop, const char *symbol_name, spl_symbol_t *out);
|
||||
|
||||
typedef struct {
|
||||
spl_ast_t *ast;
|
||||
spl_type_t *type;
|
||||
spl_scope_t *scope;
|
||||
spl_symbol_t root;
|
||||
int error_count;
|
||||
} spl_sema_t;
|
||||
|
||||
void spl_sema_init(spl_sema_t *sema);
|
||||
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope_t *scope);
|
||||
void spl_sema_drop(spl_sema_t *sema);
|
||||
void spl_sema_run(spl_sema_t *sema);
|
||||
void spl_sema_check(spl_sema_t *sema);
|
||||
|
||||
spl_scope_id_t spl_sema_scope_alloc(spl_sema_t *sema);
|
||||
bool spl_sema_scope_insert(spl_sema_t *sema, spl_scope_id_t id, const char *symbol_name,
|
||||
spl_def_id_t symbol_val);
|
||||
typedef VEC(const char *) spl_symbol_path_t;
|
||||
spl_def_id_t spl_sema_scope_find(spl_sema_t *sema, spl_symbol_path_t path);
|
||||
void spl_sema_run(spl_sema_t *sema);
|
||||
void spl_sema_dump(spl_sema_t *sema);
|
||||
|
||||
#endif /* __SPL_SEMA_H__ */
|
||||
|
||||
@@ -1,7 +1,48 @@
|
||||
#include "spl_type.h"
|
||||
|
||||
static usize spl_type_hash(spl_type_node_t n) { return 0; }
|
||||
static int spl_type_eq(spl_type_node_t n1, spl_type_node_t n2) { return 1; }
|
||||
static usize spl_type_hash(spl_type_node_t n) { return n.kind; }
|
||||
static int spl_type_eq(spl_type_node_t n1, spl_type_node_t n2) {
|
||||
if (n1.kind != n2.kind)
|
||||
return 1;
|
||||
switch (n1.kind) {
|
||||
case SPL_TYPE_ERROR:
|
||||
case SPL_TYPE_VOID:
|
||||
case SPL_TYPE_BOOL:
|
||||
break;
|
||||
case SPL_TYPE_INT:
|
||||
if (n1.int_type.bits != n2.int_type.bits)
|
||||
return 1;
|
||||
if (n1.int_type.is_signed != n2.int_type.is_signed)
|
||||
return 1;
|
||||
break;
|
||||
case SPL_TYPE_FLOAT:
|
||||
if (n1.float_type.bits != n2.float_type.bits)
|
||||
return 1;
|
||||
break;
|
||||
case SPL_TYPE_PTR:
|
||||
if (n1.ptr_pointee != n2.ptr_pointee)
|
||||
return 1;
|
||||
break;
|
||||
case SPL_TYPE_SLICE:
|
||||
if (n1.slice_element != n2.slice_element)
|
||||
return 1;
|
||||
break;
|
||||
case SPL_TYPE_RANGE:
|
||||
if (n1.range_element != n2.range_element)
|
||||
return 1;
|
||||
break;
|
||||
case SPL_TYPE_ARRAY:
|
||||
if (n1.array_type.element != n2.array_type.element)
|
||||
return 1;
|
||||
if (n1.array_type.len != n2.array_type.len)
|
||||
return 1;
|
||||
break;
|
||||
// TODO
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
spl_type_id_t spl_type_node_push(spl_type_t *type, spl_type_node_t type_node) {
|
||||
spl_type_id_t ret = 0;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __SPL_TYPE_H__
|
||||
|
||||
#include "../stage0/include/utils.h"
|
||||
#include "spl_dbg.h"
|
||||
|
||||
typedef usize spl_type_id_t; /* 0 is error */
|
||||
typedef VEC(spl_type_id_t) spl_type_id_vec_t;
|
||||
@@ -77,6 +78,7 @@ typedef struct {
|
||||
SPL_DEF_DISTINCT, // newtype
|
||||
SPL_DEF_ALIAS, // sametypes
|
||||
} kind;
|
||||
spl_dbg_node_t dbg_node;
|
||||
spl_type_id_t type_id;
|
||||
union {
|
||||
spl_var_def_t var_def;
|
||||
|
||||
229
stage1/splc0.c
229
stage1/splc0.c
@@ -11,15 +11,24 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "spl_ast.h"
|
||||
#include "spl_ast2ir.h"
|
||||
#include "spl_ir2vm.h"
|
||||
// #include "spl_ast2ir.h"
|
||||
// #include "spl_ir2vm.h"
|
||||
#include "spl_lexer.h"
|
||||
#include "spl_sema.h"
|
||||
#include "spl_tok.h"
|
||||
|
||||
typedef enum {
|
||||
DUMP_NONE,
|
||||
DUMP_TOKEN,
|
||||
DUMP_AST,
|
||||
DUMP_SEMA,
|
||||
DUMP_IR,
|
||||
} dump_t;
|
||||
|
||||
static char *read_file(const char *path, long *out_len) {
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "path `%s` ", path);
|
||||
perror("fopen");
|
||||
return NULL;
|
||||
}
|
||||
@@ -47,8 +56,7 @@ static const char *const tok_type_names[] = {
|
||||
#undef X
|
||||
};
|
||||
|
||||
static void dump_tokens(const char *src, const char *fname) {
|
||||
spl_tok_vec_t toks = spl_lex(src, fname);
|
||||
static void dump_tokens(spl_tok_vec_t toks) {
|
||||
printf("tokens got (%zu)\n", toks.size);
|
||||
for (usize i = 0; i < toks.size; i++) {
|
||||
const spl_tok_t *t = &toks.data[i];
|
||||
@@ -58,170 +66,47 @@ static void dump_tokens(const char *src, const char *fname) {
|
||||
vec_free(toks);
|
||||
}
|
||||
|
||||
static void dump_ast(const char *src, const char *fname) {
|
||||
static int compile_spl(const char *src, const char *fname, const char *outpath, int gen_debug,
|
||||
dump_t dump) {
|
||||
spl_tok_vec_t toks = spl_lex(src, fname);
|
||||
if (dump == DUMP_TOKEN) {
|
||||
dump_tokens(toks);
|
||||
// memory leak
|
||||
return 0;
|
||||
}
|
||||
spl_ast_t ast;
|
||||
spl_ast_init(&ast, &toks);
|
||||
spl_ast_prase(&ast);
|
||||
if (ast.parsed < 0) {
|
||||
printf("parse failed, skip AST dump\n");
|
||||
spl_ast_drop(&ast);
|
||||
return;
|
||||
}
|
||||
spl_ast_valid(&ast);
|
||||
spl_ast_dump(&ast, ast.root);
|
||||
spl_ast_drop(&ast);
|
||||
}
|
||||
|
||||
// static void dump_sema(const char *src, const char *fname) {
|
||||
// spl_tok_vec_t toks = spl_lex(src, fname);
|
||||
// spl_ast_t ast;
|
||||
// spl_ast_init(&ast, &toks);
|
||||
// spl_ast_prase(&ast);
|
||||
// if (ast.parsed < 0) {
|
||||
// printf("parse failed, skip sema dump\n");
|
||||
// spl_ast_drop(&ast);
|
||||
// return;
|
||||
// }
|
||||
// spl_ast_valid(&ast);
|
||||
// spl_sema_t sema;
|
||||
// spl_sema_init(&sema);
|
||||
// sema.ast = *
|
||||
// spl_sema_run(&sema);
|
||||
// spl_sema_check(&sema);
|
||||
// printf("Sema root_scope=%zu scopes=%zu errors=%d\n", sema.root_scope, sema.scopes.size,
|
||||
// sema.error_count);
|
||||
// for (usize i = 0; i < sema.scopes.size; i++) {
|
||||
// printf("scope[%zu] parent=%zu\n", i, sema.scopes.data[i].parent);
|
||||
// map_for(sema.scopes.data[i].symbols, mi) {
|
||||
// printf(" %s -> def#%zu\n", sema.scopes.data[i].symbols.data[mi].key,
|
||||
// sema.scopes.data[i].symbols.data[mi].val);
|
||||
// }
|
||||
// }
|
||||
// printf("TypeTable:\n");
|
||||
// for (usize i = 0; i < sema.type.type_table.size; i++) {
|
||||
// printf(" id#%zu type=", i);
|
||||
// spl_type_pure_dump(&sema.type, i);
|
||||
// printf("\n");
|
||||
// }
|
||||
// printf("DefTable:\n");
|
||||
// for (usize i = 0; i < sema.type.def_table.size; i++) {
|
||||
// printf(" def#%zu ", i);
|
||||
// spl_type_def_dump(&sema.type, i);
|
||||
// printf("\n");
|
||||
// }
|
||||
// spl_sema_drop(&sema);
|
||||
// spl_ast_drop(&ast);
|
||||
// }
|
||||
|
||||
// static void dump_ir(const char *src, const char *fname) {
|
||||
// spl_tok_vec_t toks = spl_lex(src, fname);
|
||||
// spl_ast_t ast;
|
||||
// spl_ast_init(&ast, &toks);
|
||||
// spl_ast_prase(&ast);
|
||||
// if (ast.parsed < 0) {
|
||||
// printf("parse failed, skip IR\n");
|
||||
// spl_ast_drop(&ast);
|
||||
// return;
|
||||
// }
|
||||
// spl_ast_valid(&ast);
|
||||
// spl_sema_t sema;
|
||||
// spl_sema_init(&sema);
|
||||
// sema.ast = *
|
||||
// spl_sema_run(&sema);
|
||||
// spl_sema_check(&sema);
|
||||
// if (sema.error_count) {
|
||||
// printf("sema errors=%d, skip IR\n", sema.error_count);
|
||||
// spl_sema_drop(&sema);
|
||||
// spl_ast_drop(&ast);
|
||||
// return;
|
||||
// }
|
||||
// spl_ast2ir_t a2ir;
|
||||
// spl_ast2ir_init(&a2ir, &sema);
|
||||
// spl_ast2ir_run(&a2ir);
|
||||
// if (a2ir.err_count)
|
||||
// printf("ast2ir errors=%d\n", a2ir.err_count);
|
||||
// spl_ir_dump(&a2ir.ir, &sema.type);
|
||||
// spl_ast2ir_drop(&a2ir);
|
||||
// spl_sema_drop(&sema);
|
||||
// spl_ast_drop(&ast);
|
||||
// }
|
||||
|
||||
static int cmd_dump(const char *flags, const char *path) {
|
||||
long len;
|
||||
char *src = read_file(path, &len);
|
||||
if (!src)
|
||||
printf("parse failed, no output\n");
|
||||
// memory leak
|
||||
return 1;
|
||||
int do_tokens = strstr(flags, "tokens") != NULL || strcmp(flags, "all") == 0;
|
||||
int do_ast = strstr(flags, "ast") != NULL || strcmp(flags, "all") == 0;
|
||||
int do_sema = strstr(flags, "sema") != NULL || strcmp(flags, "all") == 0;
|
||||
int do_ir = strstr(flags, "ir") != NULL || strcmp(flags, "all") == 0;
|
||||
if (do_tokens)
|
||||
dump_tokens(src, path);
|
||||
if (do_ast)
|
||||
dump_ast(src, path);
|
||||
// if (do_sema)
|
||||
// dump_sema(src, path);
|
||||
// if (do_ir)
|
||||
// dump_ir(src, path);
|
||||
free(src);
|
||||
}
|
||||
// spl_ast_valid(&ast); TODO
|
||||
if (dump == DUMP_AST) {
|
||||
spl_ast_dump(&ast, ast.root);
|
||||
// memory leak
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -g:在 .sir 尾部追加 debug 段(文本:IR 行 + VAR 行),spl_cli -g 读取 */
|
||||
static void gen_debug_map(const char *outpath, spl_ast_t *ast, const spl_ir_t *ir,
|
||||
const spl_ir2vm_t *ir2vm) {
|
||||
FILE *f = fopen(outpath, "ab");
|
||||
if (!f)
|
||||
return;
|
||||
fprintf(f, "SPLDBG\n");
|
||||
// for (usize i = 0; i < ir2vm->fdbg.size; i++) {
|
||||
// const spl_ir2vm_fdbg_t *fd = &ir2vm->fdbg.data[i];
|
||||
// if (fd->fid >= ir->funcs.size)
|
||||
// continue;
|
||||
// const spl_ir_func_t *fn = &ir->funcs.data[fd->fid];
|
||||
// const char *fname = fn->name ? fn->name : "?";
|
||||
// for (usize ref = 1; ref < fd->node_first_ip.size; ref++) {
|
||||
// usize ip = fd->node_first_ip.data[ref];
|
||||
// if (ip == (usize)-1)
|
||||
// continue;
|
||||
// const spl_ir_node_t *n = &fn->nodes.data[ref];
|
||||
// fprintf(f, "IR %zu %zu %d %s\n", ip, ref, ast_line(ast, n->src_ref),
|
||||
// spl_ir_kind_name(n->kind));
|
||||
// }
|
||||
// for (usize j = 0; j < fn->dbg_vars.size; j++) {
|
||||
// const spl_ir_dbg_var_t *dv = &fn->dbg_vars.data[j];
|
||||
// if (!dv->name)
|
||||
// continue;
|
||||
// fprintf(f, "VAR %s %s %zu %zu %d\n", fname, dv->name, dv->offset, dv->tid,
|
||||
// dv->is_param);
|
||||
// }
|
||||
// }
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static int compile_spl(const char *src, const char *fname, const char *outpath, int gen_debug) {
|
||||
// spl_tok_vec_t toks = spl_lex(src, fname);
|
||||
// spl_ast_t ast;
|
||||
// spl_ast_init(&ast, &toks);
|
||||
// spl_ast_prase(&ast);
|
||||
// if (ast.parsed < 0) {
|
||||
// printf("parse failed, no output\n");
|
||||
// spl_ast_drop(&ast);
|
||||
// return 1;
|
||||
// }
|
||||
// spl_ast_valid(&ast);
|
||||
// spl_sema_t sema;
|
||||
// spl_sema_init(&sema);
|
||||
// sema.ast = *
|
||||
// spl_sema_run(&sema);
|
||||
// spl_sema_check(&sema);
|
||||
// if (sema.error_count) {
|
||||
// printf("sema errors=%d, no output\n", sema.error_count);
|
||||
// spl_sema_drop(&sema);
|
||||
// spl_ast_drop(&ast);
|
||||
// return 1;
|
||||
// }
|
||||
}
|
||||
spl_sema_t sema;
|
||||
spl_type_t type;
|
||||
spl_scope_t scope;
|
||||
spl_type_init(&type);
|
||||
spl_scope_init(&scope);
|
||||
spl_sema_init(&sema, &ast, &type, &scope);
|
||||
sema.ast = *
|
||||
spl_sema_run(&sema);
|
||||
if (sema.error_count) {
|
||||
printf("sema errors=%d, no output\n", sema.error_count);
|
||||
// memory leak
|
||||
return 1;
|
||||
}
|
||||
if (dump == DUMP_SEMA) {
|
||||
spl_sema_dump(&sema);
|
||||
spl_ast_dump(&ast, ast.root);
|
||||
// memory leak
|
||||
return 0;
|
||||
}
|
||||
// spl_ast2ir_t a2ir;
|
||||
// spl_ast2ir_init(&a2ir, &sema);
|
||||
// spl_ast2ir_run(&a2ir);
|
||||
@@ -252,7 +137,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) {
|
||||
LOG_INFO("splc0 <in> <out> compile (.spl -> .sir, stage B)");
|
||||
LOG_INFO("splc0 --dump <flags> <file> dump: tokens,ast,sema,ir,all");
|
||||
LOG_INFO("splc0 --dump <flags> <file> dump: lex,ast,sema,ir");
|
||||
return 0;
|
||||
}
|
||||
int argi = 1;
|
||||
@@ -260,12 +145,28 @@ int main(int argc, char **argv) {
|
||||
LOG_FATAL("Usage: splc0 [--dump <flags>] <in> [out]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dump_t dump = DUMP_NONE;
|
||||
if (strcmp(argv[argi], "--dump") == 0) {
|
||||
if (argc < argi + 3) {
|
||||
LOG_INFO("splc0: --dump need <flags> <file>");
|
||||
return 1;
|
||||
}
|
||||
return cmd_dump(argv[argi + 1], argv[argi + 2]);
|
||||
|
||||
const char *flags = argv[argi + 1];
|
||||
if (strstr(flags, "lex") != NULL) {
|
||||
dump = DUMP_TOKEN;
|
||||
}
|
||||
if (strstr(flags, "ast") != NULL) {
|
||||
dump = DUMP_AST;
|
||||
}
|
||||
if (strstr(flags, "sema") != NULL) {
|
||||
dump = DUMP_SEMA;
|
||||
}
|
||||
if (strstr(flags, "ir") != NULL) {
|
||||
dump = DUMP_IR;
|
||||
}
|
||||
argi += 2;
|
||||
}
|
||||
/* splc0 [-g] <in> <out> */
|
||||
if (argc < argi + 2) {
|
||||
@@ -285,7 +186,7 @@ int main(int argc, char **argv) {
|
||||
char *src = read_file(argv[argi], &len);
|
||||
if (!src)
|
||||
return 1;
|
||||
int rc = compile_spl(src, argv[argi], argv[argi + 1], gen_debug);
|
||||
int rc = compile_spl(src, argv[argi], argv[argi + 1], gen_debug, dump);
|
||||
free(src);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user