diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 183 |
1 files changed, 12 insertions, 171 deletions
@@ -1,181 +1,22 @@ -#include <ctype.h> -#include <stddef.h> #include <stdlib.h> -#include <string.h> -#include <stdbool.h> #include <stdio.h> +#include <readline/readline.h> +#include <string.h> #include "lex.h" -#include "typeutils.h" - -typedef struct { - char* str; - size_t pos; -} RawLine; -String collect_identifier(RawLine* line) { - String id_buf = make_String(256); - while (line->str[line->pos] == '_' || isalnum(line->str[line->pos])) { - push_to_String(&id_buf, line->str[line->pos++]); +int main() { + char* line; + while (1) { + line = readline("$"); + if (line[0] == '\0') continue; + if (strcmp(line, "exit") == 0) exit(0); + printf("%s \n", line); } - return id_buf; -} - -String collect_single_quoted_section(RawLine* line) { - line->pos++; // Consume quote mark - String chunk_str = make_String(256); - while (line->str[line->pos] != '\'') { - if (line->str[line->pos] == '\0') exit(42); - push_to_String(&chunk_str, line->str[line->pos++]); - } - line->pos++; // Consume closing quote - return chunk_str; -} - -TokenVec lex_region(RawLine* line, char until); - - -void expect_char(RawLine* line, char expected) { - if (line->str[line->pos] != expected) exit(42); // TODO: nicer handling - line->pos++; + + free(line); + } -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 (line->str[line->pos] != '\"') { - if (line->str[line->pos] == '\0') exit(42); - - MaybeChunk exp_chunk = {.some = false}; - - 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, line->str[line->pos++]); - } - // TODO: other special cases beyond $ - - 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) - }); - } -} - - -Chunk next_chunk_unquoted(RawLine* line, ExpansionRegionVec* reg_arena) { - for (char c; (c=line->str[line->pos], c != '$' && c != '\0' && c != ' '), ) -} - - - -typedef struct { - Region root_reg; - RegionVec reg_arena; -} LexResult; -// TODO: maybe make an input+pos struct - -TokenVec lex_region(char* input, size_t* pos, char until) { - TokenVec tokens = make_TokenVec(256); - RegionVec reg_arena; - - while (input[*pos] != until) { - // Getting a token - - if (input[*pos] == ' ') { - (*pos)++; - continue; - } - - ChunkVec chunks = make_ChunkVec(256); - - switch (input[*pos]) { - case '\'': - String qstring = get_single_quoted_chunk(input, pos); - push_to_ChunkVec(&chunks, (Chunk){.qmode=SINGLE_Q, .kind = LITERAL, .as.literal_str = qstring.items}); - break; - - } - - } - return tokens; -} - -TokenVec lex(char* input) { - size_t pos = 0; - return lex_region(input, &pos, '\0'); -} |
