summaryrefslogtreecommitdiff
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
parentb59501340a5d6b1c0ace169f140391cc0555015e (diff)
work on double-quote lexing
-rw-r--r--lex.h27
-rw-r--r--main.c77
2 files changed, 81 insertions, 23 deletions
diff --git a/lex.h b/lex.h
index db4d713..ba2a666 100644
--- a/lex.h
+++ b/lex.h
@@ -1,7 +1,7 @@
#include "typeutils.h"
-typedef struct Region Region;
+typedef struct ExpansionRegion ExpansionRegion;
typedef enum {
@@ -10,24 +10,19 @@ typedef enum {
DOUBLE_Q,
} QuotationMode;
-
typedef enum {
LITERAL,
- CMD_SUB,
- ARITHM,
+ REGION_EXP,
VAR_EXP, // TODO: Later include other exps
} ChunkKind;
-
typedef struct {
ChunkKind kind;
- QuotationMode mode;
-
+ QuotationMode qmode;
union {
- char* lit_str;
- Region* sub_cmd_region;
- Region* arithm_expr_region;
- char* param_string;
+ char* literal_str;
+ ExpansionRegion* reg_ptr;
+ char* varname;
} as;
} Chunk;
@@ -61,12 +56,16 @@ DECLARE_VEC(Token, TokenVec)
DECLARE_MAYBE(SpecialToken)
+typedef enum {
+ CMD_SUB,
+ ARITHM,
+} RegionMode;
-struct Region {
- QuotationMode mode;
+struct ExpansionRegion {
+ RegionMode mode;
TokenVec tokens;
};
DECLARE_MAYBE(Chunk);
-DECLARE_VEC(Region, RegionVec)
+DECLARE_VEC(ExpansionRegion, ExpansionRegionVec)
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;
-
+
}
}