diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 182 |
1 files changed, 70 insertions, 112 deletions
@@ -1,141 +1,99 @@ +#include <ctype.h> #include <stddef.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <stdio.h> +#include "lex.h" -#define DECLARE_VEC(T, Name) \ - typedef struct { \ - T* items; \ - size_t count; \ - size_t cap; \ - size_t incr_step; \ - } Name; \ - static inline Name make_##Name(size_t step) { \ - return (Name) { \ - .items = malloc(step* sizeof(T)), \ - .count = 0, \ - .cap = step, \ - .incr_step = step, \ - }; \ - } \ - static inline void push_to_##Name(Name* vec, T item) { \ - if (vec->count == vec->cap) { \ - vec->cap += vec->incr_step; \ - vec->items = realloc( \ - vec->items, \ - vec->cap * sizeof(T) \ - ); \ - } \ - vec->items[vec->count++] = item; \ - } \ - - -DECLARE_VEC(char, String); - -void append_str_to_String(String* target, char* src_str) { - size_t required_size = - ((target->count + strlen(src_str)) / target->incr_step + 1) * target->incr_step; - if (required_size > target->cap) { - target->cap = required_size; - target->items = realloc(target->items, required_size * sizeof(char)); +String collect_identifier(char* input, size_t* pos) { + String id_buf = make_String(256); + while (input[*pos] == '_' || isalnum(input[*pos])) { + push_to_String(&id_buf, input[(*pos)++]); } - memcpy(target->items + target->count, src_str, strlen(src_str)); - target->count += strlen(src_str); + return id_buf; } +String collect_single_quoted_section(char* input, size_t* pos) { + (*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)++]); + } + (*pos)++; // Consume closing quote + return chunk_str; +} -#define DECLARE_MAYBE(T) \ - typedef struct { \ - bool some; \ - T value; \ - } Maybe##T; \ - - - -typedef enum { - UN_Q, - SINGLE_Q, - DOUBLE_Q, -} QuotationMode; - -typedef struct Region Region; - -typedef enum { - LITERAL, - CMD_SUB, - ARITHM, - PARAM, -} ChunkKind; +TokenVec lex_region(char* input, size_t* pos, char until); -typedef struct { - ChunkKind kind; - QuotationMode mode; +void expect_char(char* input, size_t* pos, char expected) { + if (input[*pos] != expected) exit(42); // TODO: nicer handling + (*pos)++; +} - union { - char* lit_str; - Region* sub_cmd_region; - Region* arithm_expr_region; - Region* param_region; - } as; -} Chunk; +void lex_double_quoted_section(char* input, size_t* pos, ChunkVec* coll, RegionVec* reg_arena) { + (*pos)++; + String accum = make_String(256); + while (input[*pos] != '\"') { + if (input[*pos] == '\0') exit(42); + + 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_RegionVec(reg_arena, (Region){.}) + push_to_ChunkVec(coll, (Chunk){.mode = DOUBLE_Q, .kind = ARITHM, .as.arithm_expr_region = inner_toks}); + } + } 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)}); + } + continue; + } + } else { + + } + } +} -DECLARE_VEC(Chunk, ChunkVec) -typedef enum { - TOK_WORD, - TOK_SPECIAL, -} TokenKind; -typedef enum { - PIPE, - WRITE_REDIR_TRUNC, - WRITE_REDIR_APPEND, - READ_REDIR, - EOL, -} SpecialToken; typedef struct { - TokenKind kind; - - union { - ChunkVec word; - SpecialToken spec; - } as; -} Token; - - -DECLARE_VEC(Token, TokenVec) - -DECLARE_MAYBE(SpecialToken) - -struct Region { - QuotationMode mode; - TokenVec tokens; -}; - -DECLARE_MAYBE(Chunk); - - -MaybeChunk unquoted_next_chunk(char* input, size_t* pos) { - String chunk; - char curr_c; - for (;(curr_c = input[*pos], curr_c != '$' && curr_c != '\'' && curr_c != '\"' && curr_c != '\0'); pos++) { - exit(1); - } - exit(1); -} - + 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) { - while (input[*pos] == ' ') (*pos)++; + // 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){.mode=SINGLE_Q, .kind = LITERAL, .as.lit_str = qstring.items}); + break; + + } } return tokens; |
