refactor preproc arrays

This commit is contained in:
sfja 2026-09-22 02:42:14 +02:00
parent da32555e6e
commit ceed68ed47
4 changed files with 52 additions and 33 deletions

View File

@ -1,8 +1,10 @@
int puts(const char* __s);
#define PUTS(A, B) puts(A, B)
#define A puts
#define B(V, W) A(V)
#define C B("hello world", 123)
int main()
{
PUTS("hello", "world");
C;
}

21
main.c
View File

@ -57,7 +57,7 @@ int main(int argc, char* argv[])
return EXIT_FAILURE;
}
printf("text:\n%s\n", text);
printf("--- text ---\n%s\n", text);
SourceIter source_chars;
source_iter_init(&source_chars, text);
@ -74,12 +74,25 @@ int main(int argc, char* argv[])
Preproc preproc;
preproc_init(&preproc, &lexer);
printf("tokens:\n");
printf("--- tokens ---\n");
int line = 1;
int col = 1;
Tok tok;
while ((tok = preproc_next_with_newline(&preproc)).ty != Tok_Eof) {
while ((tok = preproc_next(&preproc)).ty != Tok_Eof) {
// printf("%s\t%s\n", tokty_str(tok.ty), tok.text);
printf("%s ", tok.text);
while (line < tok.line) {
printf("\n");
line += 1;
col = 1;
}
while (col < tok.col) {
printf(" ");
col += 1;
}
printf("%s", tok.text);
line = tok.line;
col = tok.col + strlen(tok.text);
}
fputs("\n", stdout);

20
parse.h
View File

@ -81,19 +81,27 @@ Tok lexer_next(Lexer* l);
typedef struct MacroDef MacroDef;
typedef struct MacroInv MacroInv;
typedef struct {
MacroDef* data;
size_t cap;
size_t size;
} MacroDefs;
typedef struct {
MacroInv* data;
size_t cap;
size_t size;
} MacroInvs;
typedef struct {
Lexer* lexer;
Tok curr;
MacroDef* defs;
size_t defs_cap;
size_t defs_size;
MacroDefs defs;
Hashmap def_map;
Arena arg_arena;
MacroInv* macro_invs;
size_t macro_invs_cap;
size_t macro_invs_size;
MacroInvs macro_invs;
} Preproc;
void preproc_init(Preproc* p, Lexer* lexer);

View File

@ -34,15 +34,11 @@ void preproc_init(Preproc* p, Lexer* lexer)
.lexer = lexer,
.curr = curr,
.defs = nullptr,
.defs_cap = 0,
.defs_size = 0,
.defs = { },
.def_map = { },
.arg_arena = { },
.macro_invs = nullptr,
.macro_invs_cap = 0,
.macro_invs_size = 0,
.macro_invs = { },
};
hashmap_init(&p->def_map);
@ -51,14 +47,14 @@ void preproc_init(Preproc* p, Lexer* lexer)
void preproc_deinit(Preproc* p)
{
if (p->defs) {
for (size_t i = 0; i < p->defs_size; ++i) {
free(p->defs[i].toks);
if (p->defs[i].params) {
free(p->defs[i].params);
if (p->defs.data) {
for (size_t i = 0; i < p->defs.size; ++i) {
free(p->defs.data[i].toks);
if (p->defs.data[i].params) {
free(p->defs.data[i].params);
}
}
free(p->defs);
free(p->defs.data);
}
hashmap_deinit(&p->def_map);
arena_deinit(&p->arg_arena);
@ -142,9 +138,9 @@ static Tok p_define(Preproc* p)
}
array_push(
(void**)&p->defs, &p->defs_cap, &p->defs_size, &def, sizeof(def));
(void**)&p->defs, &p->defs.cap, &p->defs.size, &def, sizeof(def));
MacroDef* deftoks = &p->defs[p->defs_size - 1];
MacroDef* deftoks = &p->defs.data[p->defs.size - 1];
hashmap_set(&p->def_map, ident_tok.text, deftoks);
return p->curr;
@ -189,10 +185,10 @@ static Tok p_include(Preproc* p)
static Tok p_paste_macro_body(Preproc* p)
{
MacroInv* inv = &p->macro_invs[p->macro_invs_size - 1];
MacroInv* inv = &p->macro_invs.data[p->macro_invs.size - 1];
if (inv->tok_idx >= inv->def->toks_size) {
p->macro_invs_size -= 1;
p->macro_invs.size -= 1;
return preproc_next_with_newline(p);
}
@ -225,7 +221,7 @@ static Tok p_detect_macro(Preproc* p, Tok head)
hashmap_init(&inv.arg_map);
array_push(
(void**)&p->macro_invs, &p->defs_cap, &p->defs_size, &inv, sizeof(inv));
(void**)&p->macro_invs, &p->defs.cap, &p->defs.size, &inv, sizeof(inv));
if (!def->params)
return preproc_next_with_newline(p);
@ -322,7 +318,7 @@ static Tok replace_candidate_tok(Preproc* p, Tok tok, size_t inv_idx)
{
if (inv_idx == 0)
return tok;
MacroInv* inv = &p->macro_invs[inv_idx];
MacroInv* inv = &p->macro_invs.data[inv_idx];
if (tok.ty != Tok_Ident)
return tok;
MacroArg* arg = hashmap_get(&inv->arg_map, tok.text);
@ -332,13 +328,13 @@ static Tok replace_candidate_tok(Preproc* p, Tok tok, size_t inv_idx)
static Tok expand_tok(Preproc* p, Tok tok)
{
if (p->macro_invs_size == 0)
if (p->macro_invs.size == 0)
return tok;
MacroInv* inv = &p->macro_invs[p->macro_invs_size - 1];
MacroInv* inv = &p->macro_invs.data[p->macro_invs.size - 1];
if (inv->tok_idx >= inv->def->toks_size) {
p->macro_invs_size -= 1;
p->macro_invs.size -= 1;
return expand_tok(p, tok);
}
}