diff options
Diffstat (limited to 'lexparse.c')
| -rw-r--r-- | lexparse.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/lexparse.c b/lexparse.c new file mode 100644 index 0000000..19ce08b --- /dev/null +++ b/lexparse.c @@ -0,0 +1,101 @@ +#include <ctype.h> +#include "syntax.h" +#include "utils.h" + +typedef struct { + Word word_germ; + String lit_germ; +} LexingBuffer; + +typedef struct { + TokenVec* token_pool; + TokenPtrVec* top_tokens; +} PseudoAst; + +static void consolidate_buffer(LexingBuffer* buf, PseudoAst ps_ast) { + if (buf->lit_germ.count > 0) { + push_to_Word(&buf->word_germ, (Chunk){ + .qmode = UN_Q, + .kind = CHUNK_LIT, + .as.lit_str = inner(&buf->lit_germ) + }); + buf->lit_germ = make_String(256); + } + if (buf->word_germ.count > 0) { + Token* tok_ptr = push_to_TokenVec(ps_ast.token_pool, (Token){ + .kind = TOK_WORD, + .as.word = buf->word_germ + }); + push_to_TokenPtrVec(ps_ast.top_tokens, tok_ptr); + } +} + + +static Chunk collect_single_q_section(char* line, size_t* pos) { + (*pos)++; + String buf = make_String(256); + size_t i; + for (i = *pos; line[*pos] != '\'' && line[*pos] != '\0'; i++) { + push_to_String(&buf, line[*pos]); + } + if (line[i] == '\0') exit(44); + + *pos = i; + return (Chunk){ + .qmode = SINGLE_Q, + .kind = LITERAL, + .as.literal_str = inner(&buf) + }; +} + +DECLARE_MAYBE(SpecialToken, MaybeSpecialToken) + + +static MaybeSpecialToken recognize_spec_token(char* line, size_t* pos) { + // TODO: add more error guards for peekaheads + char next_ch; + + switch (line[*pos]) { + case '|': + (*pos)++; + return (MaybeSpecialToken){.some = true, .value = SPEC_PIPE}; + case '>': + next_ch = line[(*pos)+1]; + switch (next_ch) { + case '(': + return (MaybeSpecialToken){.some = false}; + case '>': + *pos += 2; + return (MaybeSpecialToken){.some = true, .value = SPEC_REDIR_W_APPEND}; + default: + (*pos)++; + return (MaybeSpecialToken){.some = true, .value = SPEC_REDIR_W_TRUNC}; + } + case '<': + next_ch = line[(*pos)+1]; + if (line[(*pos)+1] == '(') { + return (MaybeSpecialToken){.some = false}; + } else { + (*pos)++; + return (MaybeSpecialToken){.some = true, .value = SPEC_REDIR_R}; + } + default: + return (MaybeSpecialToken){.some = false}; + } +} + +static void lex_level(char* line, size_t* pos, char until, PseudoAst ps_ast) { + LexingBuffer buf = {.word_germ = make_Word(256), .lit_germ = make_String(256)}; + while (line[*pos] != until) { + if (line[*pos] == ' ') { + consolidate_buffer(&buf, ps_ast); + while (line[*pos] == ' ') (*pos)++; + continue; + } + MaybeSpecialToken m_spec = recognize_spec_token(line, pos); + } +} + +Ast lex(char* input) { + size_t line_pos = 0; +} |
