From 1d086299904873c9123ad3449b991eb301d8be05 Mon Sep 17 00:00:00 2001 From: Ákos Kőrösi Date: Tue, 12 May 2026 07:30:27 +0200 Subject: work on consolidating typing in lexer - define RawLine struct - change function signatures around --- lex.h | 3 ++ main.c | 157 ++++++++++++++++++++++++++++++++++++----------------------------- 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 = ®_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 = ®_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 = ®_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) { - 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 { -- cgit v1.2.3