diff options
| author | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-12 03:26:10 +0200 |
|---|---|---|
| committer | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-12 03:26:10 +0200 |
| commit | 100e1ed4d97d3958f8585d7d956ea0c4c9762f22 (patch) | |
| tree | e5de4cad8087bfbcafb171bff219bac7ae40272a /main.c | |
| parent | b59501340a5d6b1c0ace169f140391cc0555015e (diff) | |
work on double-quote lexing
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 77 |
1 files changed, 68 insertions, 9 deletions
@@ -6,6 +6,7 @@ #include <stdio.h> #include "lex.h" +#include "typeutils.h" String collect_identifier(char* input, size_t* pos) { String id_buf = make_String(256); @@ -35,12 +36,14 @@ void expect_char(char* input, size_t* pos, char expected) { } -void lex_double_quoted_section(char* input, size_t* pos, ChunkVec* coll, RegionVec* reg_arena) { +void lex_double_quoted_section(char* input, size_t* pos, ChunkVec* coll, ExpansionRegionVec* reg_arena) { (*pos)++; String accum = make_String(256); while (input[*pos] != '\"') { if (input[*pos] == '\0') exit(42); + MaybeChunk exp_chunk = {.some = false}; + if (input[*pos] == '$') { (*pos)++; if (input[*pos] == '(') { @@ -48,19 +51,75 @@ void lex_double_quoted_section(char* input, size_t* pos, ChunkVec* coll, RegionV TokenVec inner_toks = lex_region(input, pos, ')'); expect_char(input, pos, ')'); expect_char(input, pos, ')'); - push_to_RegionVec(reg_arena, (Region){.}) - push_to_ChunkVec(coll, (Chunk){.mode = DOUBLE_Q, .kind = ARITHM, .as.arithm_expr_region = inner_toks}); + push_to_ExpansionRegionVec( + reg_arena, + (ExpansionRegion){.mode = ARITHM, .tokens = inner_toks} + ); + ExpansionRegion* reg_ptr = ®_arena->items[reg_arena->count]; // TODO: maybe have push() return a pointer [in the macro] + exp_chunk = (MaybeChunk){ + .some = true, + .value = (Chunk){ + .qmode = DOUBLE_Q, + .kind = REGION_EXP, + .as.reg_ptr = reg_ptr + }, + }; + } else { + TokenVec inner_toks = lex_region(input, pos, ')'); + expect_char(input, pos, ')'); + push_to_ExpansionRegionVec( + reg_arena, + (ExpansionRegion){.mode = CMD_SUB, .tokens = inner_toks} + ); + ExpansionRegion* reg_ptr = ®_arena->items[reg_arena->count]; + exp_chunk = (MaybeChunk){ + .some = true, + .value = (Chunk){ + .qmode = DOUBLE_Q, + .kind = REGION_EXP, + .as.reg_ptr = reg_ptr, + } + }; } } else { String id_name = collect_identifier(input, pos); if (id_name.count > 0) { - push_to_ChunkVec(coll, (Chunk){.mode = DOUBLE_Q, .kind = VAR_EXP, .as.param_string = inner(id_name)}); + exp_chunk = (MaybeChunk){ + .some = true, + .value = (Chunk){ + .qmode = DOUBLE_Q, + .kind = VAR_EXP, + .as.varname = inner(id_name), + } + }; + } else { + push_to_String(&accum, '$'); } - continue; } } else { - + push_to_String(&accum, input[(*pos)++]); } + // TODO: other special cases + + if (exp_chunk.some) { + if (accum.count > 0) { + push_to_ChunkVec(coll, (Chunk){ + .qmode = DOUBLE_Q, + .kind = LITERAL, + .as.literal_str = inner(accum) + }); + accum = make_String(256); + } + push_to_ChunkVec(coll, exp_chunk.value); + exp_chunk.some = false; + } + } + if (accum.count > 0) { + push_to_ChunkVec(coll, (Chunk){ + .qmode = DOUBLE_Q, + .kind = LITERAL, + .as.literal_str = inner(accum) + }); } } @@ -86,13 +145,13 @@ TokenVec lex_region(char* input, size_t* pos, char until) { } ChunkVec chunks = make_ChunkVec(256); - + switch (input[*pos]) { case '\'': String qstring = get_single_quoted_chunk(input, pos); - push_to_ChunkVec(&chunks, (Chunk){.mode=SINGLE_Q, .kind = LITERAL, .as.lit_str = qstring.items}); + push_to_ChunkVec(&chunks, (Chunk){.qmode=SINGLE_Q, .kind = LITERAL, .as.literal_str = qstring.items}); break; - + } } |
