summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
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
commit100e1ed4d97d3958f8585d7d956ea0c4c9762f22 (patch)
treee5de4cad8087bfbcafb171bff219bac7ae40272a /main.c
parentb59501340a5d6b1c0ace169f140391cc0555015e (diff)
work on double-quote lexing
Diffstat (limited to 'main.c')
-rw-r--r--main.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/main.c b/main.c
index cbbe8b3..744ccfe 100644
--- a/main.c
+++ b/main.c
@@ -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 = &reg_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 = &reg_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;
-
+
}
}