reinit repo after broken git
This commit is contained in:
5187
src/meta/build_tool.c
Normal file
5187
src/meta/build_tool.c
Normal file
File diff suppressed because it is too large
Load Diff
307
src/meta/parser.c
Normal file
307
src/meta/parser.c
Normal file
@@ -0,0 +1,307 @@
|
||||
typedef enum {
|
||||
|
||||
#define AST_FLAG_XLIST\
|
||||
X(null)\
|
||||
X(string)\
|
||||
X(integer)\
|
||||
X(real)\
|
||||
X(binary)\
|
||||
X(enum)\
|
||||
X(enum_member)\
|
||||
X(struct)\
|
||||
X(struct_member)\
|
||||
X(var)\
|
||||
X(type_name)\
|
||||
X(type_pointer)\
|
||||
X(type_array)\
|
||||
|
||||
#define X(NAME) ast_flag_##NAME,
|
||||
AST_FLAG_XLIST
|
||||
#undef X
|
||||
} ast_flag_t;
|
||||
|
||||
typedef struct ast_t ast_t;
|
||||
struct ast_t {
|
||||
ast_flag_t flags;
|
||||
|
||||
lex_t *pos;
|
||||
ast_t *next;
|
||||
ast_t *first;
|
||||
ast_t *last;
|
||||
i32 len;
|
||||
|
||||
s8_t string;
|
||||
f64 real;
|
||||
i64 integer;
|
||||
};
|
||||
|
||||
s8_t s8_serial_ast_flag_t(ma_arena_t *arena, ast_flag_t flag) {
|
||||
sb8_t *sb = sb8_serial_begin(arena);
|
||||
#define X(NAME) if (flag & set_bit(ast_flag_##NAME)) sb8_printf(sb, #NAME);
|
||||
AST_FLAG_XLIST
|
||||
#undef X
|
||||
s8_t result = sb8_serial_end(sb);
|
||||
return result;
|
||||
}
|
||||
|
||||
ast_t *create_ast(parser_t *par, lex_t *pos, ast_flag_t flags) {
|
||||
ast_t *result = ma_push_type(par->arena, ast_t);
|
||||
memset(result, 0, sizeof(ast_t));
|
||||
result->flags = flags;
|
||||
result->pos = pos;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ast_append(ast_t *parent, ast_t *node) {
|
||||
SLLQ_APPEND(parent->first, parent->last, node);
|
||||
parent->len += 1;
|
||||
}
|
||||
|
||||
ast_t *create_ast_binary(parser_t *par, lex_t *pos, ast_t *left, lex_kind_t op, ast_t *right) {
|
||||
ast_t *result = create_ast(par, pos, set_bit(ast_flag_string) | set_bit(ast_flag_binary) | set_bit(ast_flag_integer));
|
||||
ast_append(result, left);
|
||||
ast_append(result, right);
|
||||
result->integer = op;
|
||||
result->string = s8_serial_simple_lex_kind_t(op);
|
||||
return result;
|
||||
}
|
||||
|
||||
ast_t *parse_expr(parser_t *par);
|
||||
ast_t *parse_lit_expr(parser_t *par) {
|
||||
lex_t *token = parser_next(par);
|
||||
if (token->kind == lex_kind_int) {
|
||||
ast_t *result = create_ast(par, token, set_bit(ast_flag_integer) | set_bit(ast_flag_string));
|
||||
result->integer = token->integer;
|
||||
result->string = token->s8;
|
||||
return result;
|
||||
} else if (token->kind == lex_kind_real) {
|
||||
ast_t *result = create_ast(par, token, set_bit(ast_flag_real) | set_bit(ast_flag_string));
|
||||
result->real = (double)token->real;
|
||||
result->string = token->s8;
|
||||
return result;
|
||||
} else if (token->kind == lex_kind_open_paren) {
|
||||
ast_t *result = parse_expr(par);
|
||||
parser_expect(par, lex_kind_close_paren);
|
||||
return result;
|
||||
} else {
|
||||
lex_panicf(token, "got invalid token of kind: %S while parsing expression", s8_serial_lex_kind_t(token->kind));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ast_t *parse_mul_expr(parser_t *par) {
|
||||
ast_t *left = parse_lit_expr(par);
|
||||
while (par->at->kind == lex_kind_multiply || par->at->kind == lex_kind_divide || par->at->kind == lex_kind_modulo) {
|
||||
lex_t *op = parser_next(par);
|
||||
left = create_ast_binary(par, op, left, op->kind, parse_lit_expr(par));
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
ast_t *parse_add_expr(parser_t *par) {
|
||||
ast_t *left = parse_mul_expr(par);
|
||||
while (par->at->kind == lex_kind_plus || par->at->kind == lex_kind_minus) {
|
||||
lex_t *op = parser_next(par);
|
||||
left = create_ast_binary(par, op, left, op->kind, parse_lit_expr(par));
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
ast_t *parse_logical_and_expr(parser_t *par) {
|
||||
ast_t *left = parse_add_expr(par);
|
||||
while (par->at->kind == lex_kind_or) {
|
||||
lex_t *op = parser_next(par);
|
||||
left = create_ast_binary(par, op, left, op->kind, parse_lit_expr(par));
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
ast_t *parse_logical_or_expr(parser_t *par) {
|
||||
ast_t *left = parse_logical_and_expr(par);
|
||||
while (par->at->kind == lex_kind_or) {
|
||||
lex_t *op = parser_next(par);
|
||||
left = create_ast_binary(par, op, left, op->kind, parse_lit_expr(par));
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
ast_t *parse_expr(parser_t *par) {
|
||||
ast_t *expr = parse_logical_or_expr(par);
|
||||
return expr;
|
||||
}
|
||||
|
||||
ast_t *parse_expr_str(ma_arena_t *arena, char *file_name, char *stream) {
|
||||
lex_array_t tokens = lex_tokens(arena, file_name, stream);
|
||||
parser_t *par = parser_make(arena, tokens.data);
|
||||
ast_t *result = parse_expr(par);
|
||||
return result;
|
||||
}
|
||||
|
||||
i64 eval_const_expr(ast_t *expr) {
|
||||
if (expr->flags & set_bit(ast_flag_integer)) {
|
||||
return expr->integer;
|
||||
} else if (expr->flags & set_bit(ast_flag_binary)) {
|
||||
assert(expr->first != expr->last);
|
||||
i64 left = eval_const_expr(expr->first);
|
||||
i64 right = eval_const_expr(expr->last);
|
||||
|
||||
switch(expr->integer) {
|
||||
case lex_kind_plus: return left + right;
|
||||
case lex_kind_minus: return left - right;
|
||||
case lex_kind_multiply: return left * right;
|
||||
case lex_kind_divide: return left / right;
|
||||
case lex_kind_modulo: return left % right;
|
||||
case lex_kind_and: return left && right;
|
||||
case lex_kind_or: return left || right;
|
||||
default: lex_panicf(expr->pos, "unhandled binary operator: %S", s8_serial_lex_kind_t(expr->integer));
|
||||
}
|
||||
} else {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
lex_panicf(expr->pos, "unhandled ast in const expression evaluation: %S", s8_serial_ast_flag_t(scratch.arena, expr->flags));
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define test_expr(x) do {\
|
||||
lex_array_t tokens = lex_tokens(scratch.arena, "parser_test", #x);\
|
||||
parser_t *par = parser_make(scratch.arena, tokens.data);\
|
||||
ast_t *expr = parse_expr(par);\
|
||||
assert(expr != NULL);\
|
||||
i64 value = eval_const_expr(expr);\
|
||||
assert(value == x);\
|
||||
} while (0)
|
||||
|
||||
void run_parser_test() {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
test_expr(32 + 2 + 5 + 5);
|
||||
test_expr(32 - 2 + 5 - 5);
|
||||
test_expr(2 * 2 / 4 * 5 + 2 + 3);
|
||||
test_expr(2 * 5 * 5 / 2 + 2 - 1 - 1);
|
||||
test_expr(2 * (5 * 5) / 2 + (2 - 1 - 1));
|
||||
test_expr((2 * (5 * 5) / (2)) + (2 - 1 - 1));
|
||||
test_expr(10 % 3);
|
||||
test_expr(10 % 3 + 4 || 2);
|
||||
test_expr(10 % 3 + 4 || 2 && (4 && 2) || 3 && 1 || 0);
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
|
||||
ast_t *parse_struct_mem(parser_t *par, s8_t *name) {
|
||||
lex_t *type_name = parser_expect(par, lex_kind_ident);
|
||||
ast_t *type = create_ast(par, type_name, set_bit(ast_flag_type_name) | set_bit(ast_flag_string));
|
||||
type->string = type_name->s8;
|
||||
|
||||
while (parser_match(par, lex_kind_multiply)) {
|
||||
ast_t *pointer = create_ast(par, par->at, set_bit(ast_flag_type_pointer) | set_bit(ast_flag_string));
|
||||
ast_append(pointer, type);
|
||||
pointer->string = s8_fmt(par->arena, "%S*", type->string);
|
||||
type = pointer;
|
||||
}
|
||||
|
||||
*name = parser_expect(par, lex_kind_ident)->s8;
|
||||
|
||||
while (parser_match(par, lex_kind_open_bracket)) {
|
||||
ast_t *array = create_ast(par, par->at, set_bit(ast_flag_type_array) | set_bit(ast_flag_string));
|
||||
ast_append(array, type);
|
||||
lex_t *num = parser_match(par, lex_kind_int);
|
||||
if (num) {
|
||||
array->flags |= set_bit(ast_flag_integer);
|
||||
array->integer = (int)num->integer;
|
||||
array->string = s8_fmt(par->arena, "%S[%d]", type->string, (int)array->integer);
|
||||
} else {
|
||||
array->string = s8_fmt(par->arena, "%S[]", type->string);
|
||||
}
|
||||
parser_expect(par, lex_kind_close_bracket);
|
||||
type = array;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
ast_t *parse_decls(ma_arena_t *arena, char *file, char *code) {
|
||||
lex_array_t tokens = lex_tokens(arena, file, code);
|
||||
parser_t *par = parser_make(arena, tokens.data);
|
||||
ast_t *result = create_ast(par, par->at, set_bit(ast_flag_string));
|
||||
result->string = s8_copy_char(arena, file);
|
||||
for (;par->at->kind != lex_kind_eof;) {
|
||||
lex_t *pos = par->at;
|
||||
if (parser_matchi(par, s8_lit("enum"))) {
|
||||
ast_t *n = create_ast(par, pos, set_bit(ast_flag_string) | set_bit(ast_flag_enum));
|
||||
ast_append(result, n);
|
||||
|
||||
parser_expect(par, lex_kind_open_brace);
|
||||
while (par->at->kind == lex_kind_ident) {
|
||||
lex_t *val = parser_expect(par, lex_kind_ident);
|
||||
ast_t *mem = create_ast(par, val, set_bit(ast_flag_enum_member) | set_bit(ast_flag_string));
|
||||
mem->string = val->s8;
|
||||
ast_append(n, mem);
|
||||
|
||||
// if (parser_match(par, lex_kind_assign)) {
|
||||
// parse_expr();
|
||||
// }
|
||||
|
||||
if (!parser_match(par, lex_kind_comma)) break;
|
||||
}
|
||||
parser_expect(par, lex_kind_close_brace);
|
||||
n->string = parser_expect(par, lex_kind_ident)->s8;
|
||||
parser_expect(par, lex_kind_semicolon);
|
||||
} else if (parser_matchi(par, s8_lit("struct"))) {
|
||||
ast_t *n = create_ast(par, pos, set_bit(ast_flag_string) | set_bit(ast_flag_struct));
|
||||
ast_append(result, n);
|
||||
n->string = parser_expect(par, lex_kind_ident)->s8;
|
||||
|
||||
parser_expect(par, lex_kind_open_brace);
|
||||
while (par->at->kind != lex_kind_close_brace) {
|
||||
ast_t *mem = create_ast(par, par->at, set_bit(ast_flag_struct_member) | set_bit(ast_flag_var) | set_bit(ast_flag_string));
|
||||
ast_append(n, mem);
|
||||
|
||||
ast_t *type = parse_struct_mem(par, &mem->string);
|
||||
ast_append(mem, type);
|
||||
|
||||
parser_expect(par, lex_kind_semicolon);
|
||||
}
|
||||
parser_expect(par, lex_kind_close_brace);
|
||||
parser_expect(par, lex_kind_semicolon);
|
||||
|
||||
} else {
|
||||
parser_next(par);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ast_t *parse_table(ma_arena_t *arena, char *file, char *code) {
|
||||
lex_array_t tokens = lex_tokens(arena, file, code);
|
||||
parser_t *par = parser_make(arena, tokens.data);
|
||||
ast_t *table = create_ast(par, par->at, 0);
|
||||
while (par->at->kind != lex_kind_eof) {
|
||||
ast_t *row = create_ast(par, par->at, 0);
|
||||
ast_append(table, row);
|
||||
while (par->at->kind != lex_kind_eof) {
|
||||
parser_match(par, lex_kind_bit_or);
|
||||
|
||||
lex_t *token = par->at;
|
||||
if (parser_match(par, lex_kind_ident) || parser_match(par, lex_kind_string)) {
|
||||
ast_t *col = create_ast(par, par->at, set_bit(ast_flag_string));
|
||||
ast_append(row, col);
|
||||
col->string = token->s8;
|
||||
} else if (parser_match(par, lex_kind_int)) {
|
||||
ast_t *col = create_ast(par, par->at, set_bit(ast_flag_string) | set_bit(ast_flag_integer));
|
||||
ast_append(row, col);
|
||||
col->string = token->s8;
|
||||
col->integer = token->integer;
|
||||
} else if (parser_match(par, lex_kind_real)) {
|
||||
ast_t *col = create_ast(par, par->at, set_bit(ast_flag_string) | set_bit(ast_flag_real));
|
||||
ast_append(row, col);
|
||||
col->string = token->s8;
|
||||
col->real = token->real;
|
||||
} else if (parser_match(par, lex_kind_bit_or) || parser_match(par, lex_kind_eof)) {
|
||||
break;
|
||||
} else {
|
||||
lex_panicf(par->at, "invalid token: %S", s8_serial_lex_kind_t(par->at->kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
224
src/meta/serialize.c
Normal file
224
src/meta/serialize.c
Normal file
@@ -0,0 +1,224 @@
|
||||
s8_t s8_ast_to_cvar(ma_arena_t *arena, ast_t *ast, s8_t *name) {
|
||||
if (ast->flags & set_bit(ast_flag_type_name)) {
|
||||
return ast->string;
|
||||
} else if (ast->flags & set_bit(ast_flag_type_pointer)) {
|
||||
s8_t base = s8_ast_to_cvar(arena, ast->first, name);
|
||||
return s8_fmt(arena, "%S*", base);
|
||||
} else if (ast->flags & set_bit(ast_flag_type_array)) {
|
||||
if (ast->flags & set_bit(ast_flag_integer)) {
|
||||
*name = s8_fmt(arena, "%S[%d]", *name, ast->integer);
|
||||
} else {
|
||||
*name = s8_fmt(arena, "%S[%d]", *name, ast->integer);
|
||||
}
|
||||
|
||||
s8_t base = s8_ast_to_cvar(arena, ast->first, name);
|
||||
return base;
|
||||
} else {
|
||||
assert(!"invalid ast_str case");
|
||||
return (s8_t){0};
|
||||
}
|
||||
}
|
||||
|
||||
void sb8_serial_ast(sb8_t *sb, ast_t *n) {
|
||||
if (n->flags & set_bit(ast_flag_string)) {
|
||||
sb8_stmtf(sb, "%S", n->string);
|
||||
}
|
||||
|
||||
if (n->first) {
|
||||
sb8_printf(sb, "{");
|
||||
sb->indent += 1;
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
sb8_serial_ast(sb, it);
|
||||
}
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "}");
|
||||
}
|
||||
}
|
||||
|
||||
s8_t s8_serial_ast(ma_arena_t *arena, ast_t *n) {
|
||||
sb8_t *sb = sb8_serial_begin(arena);
|
||||
sb8_serial_ast(sb, n);
|
||||
return sb8_serial_end(sb);
|
||||
}
|
||||
|
||||
s8_t s8_serial_ast_to_code(ma_arena_t *arena, ast_t *n);
|
||||
void sb8_serial_ast_to_code(sb8_t *sb, ast_t *n) {
|
||||
if (n->flags & set_bit(ast_flag_enum)) {
|
||||
sb8_printf(sb, "typedef enum {");
|
||||
sb->indent += 1;
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
sb8_stmtf(sb, "%S,", it->string);
|
||||
}
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "} %S;", n->string);
|
||||
} else if (n->flags & set_bit(ast_flag_struct)) {
|
||||
sb8_stmtf(sb, "typedef struct %S %S;", n->string, n->string);
|
||||
sb8_stmtf(sb, "struct %S {", n->string);
|
||||
sb->indent += 1;
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
s8_t name = it->string;
|
||||
s8_t type = s8_ast_to_cvar(sb->arena, it->first, &name);
|
||||
sb8_stmtf(sb, "%S %S;", type, name);
|
||||
}
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "};");
|
||||
|
||||
} else {
|
||||
if (n->flags & set_bit(ast_flag_string)) {
|
||||
sb8_printf(sb, "/*%S*/", n->string);
|
||||
} else {
|
||||
sb8_printf(sb, "/*null*/");
|
||||
}
|
||||
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
sb8_indent(sb);
|
||||
sb8_serial_ast_to_code(sb, it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s8_t s8_serial_ast_to_code(ma_arena_t *arena, ast_t *n) {
|
||||
sb8_t *sb = sb8_serial_begin(arena);
|
||||
sb8_serial_ast_to_code(sb, n);
|
||||
s8_t result = sb8_serial_end(sb);
|
||||
return result;
|
||||
}
|
||||
|
||||
s8_t s8_serial_ast_type_to_type_info(ma_arena_t *arena, ast_t *n) {
|
||||
if (n->flags & set_bit(ast_flag_type_name)) {
|
||||
return s8_fmt(arena, "type__%S", n->string);
|
||||
} else if (n->flags & set_bit(ast_flag_type_pointer)) {
|
||||
s8_t base = s8_serial_ast_type_to_type_info(arena, n->first);
|
||||
return s8_fmt(arena, "(type_t){type_kind_pointer, s8_const_lit(\"%S\"), sizeof(void *), .base = &%S}", n->string, base);
|
||||
} else if (n->flags & set_bit(ast_flag_type_array)) {
|
||||
s8_t base = s8_serial_ast_type_to_type_info(arena, n->first);
|
||||
return s8_fmt(arena, "(type_t){type_kind_array, s8_const_lit(\"%S\"), sizeof(%S), %d, .base = &%S}", n->string, n->string, (int)n->integer, base);
|
||||
} else {
|
||||
lex_panicf(n->pos, "expected type");
|
||||
}
|
||||
return (s8_t){0};
|
||||
}
|
||||
|
||||
void sb8_serial_ast_to_type_info(sb8_t *sb, ast_t *n) {
|
||||
if (n->flags & set_bit(ast_flag_enum)) {
|
||||
sb8_printf(sb, "type_t type__%S = { type_kind_enum, s8_const_lit(\"%S\"), sizeof(%S),", n->string, n->string, n->string);
|
||||
sb->indent += 1;
|
||||
|
||||
sb8_stmtf(sb, ".members = (type_member_t[]){");
|
||||
sb->indent += 1;
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
sb8_stmtf(sb, "{.name = s8_const_lit(\"%S\"), .value = %S},", it->string, it->string);
|
||||
}
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "},");
|
||||
|
||||
sb8_stmtf(sb, ".count = %d,", n->len);
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "};");
|
||||
} else if (n->flags & set_bit(ast_flag_struct)) {
|
||||
sb8_printf(sb, "type_t type__%S = { type_kind_struct, s8_const_lit(\"%S\"), sizeof(%S),", n->string, n->string, n->string);
|
||||
sb->indent += 1;
|
||||
|
||||
sb8_stmtf(sb, ".members = (type_member_t[]){");
|
||||
sb->indent += 1;
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
s8_t name = it->string;
|
||||
s8_t type_info = s8_serial_ast_type_to_type_info(sb->arena, it->first);
|
||||
sb8_stmtf(sb, "{.name = s8_const_lit(\"%S\"), .type = &%S, .offset = offsetof(%S, %S)},", name, type_info, n->string, name);
|
||||
}
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "},");
|
||||
|
||||
sb8_stmtf(sb, ".count = %d,", n->len);
|
||||
sb->indent -= 1;
|
||||
sb8_stmtf(sb, "};");
|
||||
} else {
|
||||
if (n->flags & set_bit(ast_flag_string)) {
|
||||
sb8_printf(sb, "/*%S*/", n->string);
|
||||
} else {
|
||||
sb8_printf(sb, "/*null*/");
|
||||
}
|
||||
|
||||
for (ast_t *it = n->first; it; it = it->next) {
|
||||
sb8_indent(sb);
|
||||
sb8_serial_ast_to_type_info(sb, it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s8_t s8_serial_ast_to_type_info(ma_arena_t *arena, ast_t *n) {
|
||||
sb8_t *sb = sb8_serial_begin(arena);
|
||||
sb8_serial_ast_to_type_info(sb, n);
|
||||
s8_t result = sb8_serial_end(sb);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
int row_findi(ast_t *row, char *name) {
|
||||
s8_t s = s8_from_char(name);
|
||||
int i = 0;
|
||||
for (ast_t *col = row->first; col; col = col->next) {
|
||||
if (s8_equal(col->string, s)) {
|
||||
return i;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ast_t *row_geti(ast_t *row, int idx) {
|
||||
if (idx == -1) return NULL;
|
||||
|
||||
int i = 0;
|
||||
for (ast_t *col = row->first; col; col = col->next, i+=1) {
|
||||
if (i == idx) return col;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sb8_serial_table_enum(sb8_t *c, sb8_t *h, ast_t *table, s8_t decl) {
|
||||
int name_idx = row_findi(table->first, "name");
|
||||
int value_idx = row_findi(table->first, "value");
|
||||
|
||||
s8_t name_t = s8_fmt(c->arena, "%S_t", decl);
|
||||
|
||||
sb8_printf(h, "typedef enum {\n");
|
||||
for (ast_t *row = table->first->next; row; row = row->next) {
|
||||
s8_t name = row_geti(row, name_idx)->string;
|
||||
ast_t *value = row_geti(row, value_idx);
|
||||
sb8_printf(h, "%S_%S", decl, name);
|
||||
if (value) sb8_printf(h, " = %S", value->string);
|
||||
sb8_printf(h, ",\n");
|
||||
}
|
||||
sb8_printf(h, "%S_count,\n", decl);
|
||||
sb8_printf(h, "} %S;\n", name_t);
|
||||
|
||||
sb8_stmtf(c, "type_t type__%S = { type_kind_enum, s8_const_lit(\"%S\"), sizeof(%S),", name_t, name_t, name_t);
|
||||
c->indent += 1;
|
||||
|
||||
sb8_stmtf(c, ".members = (type_member_t[]){");
|
||||
c->indent += 1;
|
||||
int item_count = 0;
|
||||
for (ast_t *row = table->first->next; row; row = row->next) {
|
||||
s8_t name = row_geti(row, name_idx)->string;
|
||||
ast_t *value = row_geti(row, value_idx);
|
||||
sb8_stmtf(c, "{.name = s8_const_lit(\"%S_%S\"), .value = %S_%S},", decl, name, decl, name);
|
||||
item_count += 1;
|
||||
}
|
||||
c->indent -= 1;
|
||||
sb8_stmtf(c, "},");
|
||||
|
||||
sb8_stmtf(c, ".count = %d,", item_count);
|
||||
c->indent -= 1;
|
||||
sb8_stmtf(c, "};");
|
||||
}
|
||||
|
||||
#define gen_c(arena) _gen_filename(arena, s8_lit(__FILE__), s8_lit("c"))
|
||||
#define gen_h(arena) _gen_filename(arena, s8_lit(__FILE__), s8_lit("h"))
|
||||
s8_t _gen_filename(ma_arena_t *arena, s8_t lit_file, s8_t ext) {
|
||||
s8_t file_noext = s8_chop_last_period(s8_chop_last_period(lit_file));
|
||||
s8_t file = s8_fmt(arena, "%S.gen.%S", file_noext, ext);
|
||||
return file;
|
||||
}
|
||||
Reference in New Issue
Block a user