summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÁkos Kőrösi <korakos99@gmail.com>2026-05-12 07:30:27 +0200
committerÁkos Kőrösi <korakos99@gmail.com>2026-05-12 07:30:27 +0200
commit1d086299904873c9123ad3449b991eb301d8be05 (patch)
treed81018f9660e32739beed892b3ea1933a7a78ff3
parent100e1ed4d97d3958f8585d7d956ea0c4c9762f22 (diff)
work on consolidating typing in lexer
- define RawLine struct - change function signatures around
-rw-r--r--lex.h3
-rw-r--r--main.c157
2 files changed, 90 insertions, 70 deletions
diff --git a/lex.h b/lex.h
index ba2a666..b777d95 100644
--- a/lex.h
+++ b/lex.h
@@ -39,6 +39,9 @@ typedef enum {
WRITE_REDIR_TRUNC,
WRITE_REDIR_APPEND,
READ_REDIR,
+ L_PROC_SUB_IN,
+ L_PROC_SUB_OUT,
+ PAREN,
EOL,
} SpecialToken;
diff --git a/main.c b/main.c
index 744ccfe..5fdb659 100644
--- a/main.c
+++ b/main.c
@@ -8,98 +8,111 @@
#include "lex.h"
#include "typeutils.h"
-String collect_identifier(char* input, size_t* pos) {
+typedef struct {
+ char* str;
+ size_t pos;
+} RawLine;
+
+
+String collect_identifier(RawLine* line) {
String id_buf = make_String(256);
- while (input[*pos] == '_' || isalnum(input[*pos])) {
- push_to_String(&id_buf, input[(*pos)++]);
+ while (line->str[line->pos] == '_' || isalnum(line->str[line->pos])) {
+ push_to_String(&id_buf, line->str[line->pos++]);
}
return id_buf;
}
-String collect_single_quoted_section(char* input, size_t* pos) {
- (*pos)++; // Consume quote mark
+String collect_single_quoted_section(RawLine* line) {
+ line->pos++; // Consume quote mark
String chunk_str = make_String(256);
- while (input[*pos] != '\'') {
- if (input[*pos] == '\0') exit(42);
- push_to_String(&chunk_str, input[(*pos)++]);
+ while (line->str[line->pos] != '\'') {
+ if (line->str[line->pos] == '\0') exit(42);
+ push_to_String(&chunk_str, line->str[line->pos++]);
}
- (*pos)++; // Consume closing quote
+ line->pos++; // Consume closing quote
return chunk_str;
}
-TokenVec lex_region(char* input, size_t* pos, char until);
+TokenVec lex_region(RawLine* line, char until);
-void expect_char(char* input, size_t* pos, char expected) {
- if (input[*pos] != expected) exit(42); // TODO: nicer handling
- (*pos)++;
+void expect_char(RawLine* line, char expected) {
+ if (line->str[line->pos] != expected) exit(42); // TODO: nicer handling
+ line->pos++;
}
-void lex_double_quoted_section(char* input, size_t* pos, ChunkVec* coll, ExpansionRegionVec* reg_arena) {
- (*pos)++;
+MaybeChunk lex_expansion_chunk(RawLine* line, ExpansionRegionVec* reg_arena) {
+ line->pos++; // Consume $
+ if (line->str[line->pos] == '(') {
+ if (line->str[line->pos] == '(') {
+ TokenVec inner_toks = lex_region(line, ')');
+ expect_char(line, ')');
+ expect_char(line, ')');
+ 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]
+ return (MaybeChunk){
+ .some = true,
+ .value = (Chunk){
+ .qmode = DOUBLE_Q,
+ .kind = REGION_EXP,
+ .as.reg_ptr = reg_ptr
+ },
+ };
+ } else {
+ TokenVec inner_toks = lex_region(line, ')');
+ expect_char(line, ')');
+ push_to_ExpansionRegionVec(
+ reg_arena,
+ (ExpansionRegion){.mode = CMD_SUB, .tokens = inner_toks}
+ );
+ ExpansionRegion* reg_ptr = &reg_arena->items[reg_arena->count];
+ return (MaybeChunk) {
+ .some = true,
+ .value = (Chunk){
+ .qmode = DOUBLE_Q,
+ .kind = REGION_EXP,
+ .as.reg_ptr = reg_ptr,
+ }
+ };
+ }
+ } else {
+ String id_name = collect_identifier(line);
+ if (id_name.count > 0) {
+ return (MaybeChunk){
+ .some = true,
+ .value = (Chunk){
+ .qmode = DOUBLE_Q,
+ .kind = VAR_EXP,
+ .as.varname = inner(id_name),
+ }
+ };
+ }
+ }
+ return (MaybeChunk){.some = false};
+}
+
+
+void lex_double_quoted_section(RawLine* line, ChunkVec* coll, ExpansionRegionVec* reg_arena) {
+ line->pos++;
String accum = make_String(256);
- while (input[*pos] != '\"') {
- if (input[*pos] == '\0') exit(42);
+ while (line->str[line->pos] != '\"') {
+ if (line->str[line->pos] == '\0') exit(42);
MaybeChunk exp_chunk = {.some = false};
- if (input[*pos] == '$') {
- (*pos)++;
- if (input[*pos] == '(') {
- if (input[*pos] == '(') {
- TokenVec inner_toks = lex_region(input, pos, ')');
- expect_char(input, pos, ')');
- expect_char(input, pos, ')');
- 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) {
- exp_chunk = (MaybeChunk){
- .some = true,
- .value = (Chunk){
- .qmode = DOUBLE_Q,
- .kind = VAR_EXP,
- .as.varname = inner(id_name),
- }
- };
- } else {
+ if (line->str[line->pos] == '$') {
+ exp_chunk = lex_expansion_chunk(line, reg_arena);
+ if (!exp_chunk.some) {
push_to_String(&accum, '$');
- }
- }
+ }
} else {
- push_to_String(&accum, input[(*pos)++]);
+ push_to_String(&accum, line->str[line->pos++]);
}
- // TODO: other special cases
+ // TODO: other special cases beyond $
if (exp_chunk.some) {
if (accum.count > 0) {
@@ -124,6 +137,10 @@ void lex_double_quoted_section(char* input, size_t* pos, ChunkVec* coll, Expansi
}
+Chunk next_chunk_unquoted(RawLine* line, ExpansionRegionVec* reg_arena) {
+ for (char c; (c=line->str[line->pos], c != '$' && c != '\0' && c != ' '), )
+}
+
typedef struct {