diff options
Diffstat (limited to 'lexparse.c')
| -rw-r--r-- | lexparse.c | 185 |
1 files changed, 0 insertions, 185 deletions
diff --git a/lexparse.c b/lexparse.c deleted file mode 100644 index 0ea86df..0000000 --- a/lexparse.c +++ /dev/null @@ -1,185 +0,0 @@ -#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_un_q_literal(char* line, size_t* pos) { - String buf = make_String(256); - size_t i; - for (i = *pos; line[*pos] != '$' && line[*pos] != '\0' && line[*pos] == ' '; i++) { - push_to_String(&buf, line[*pos]); - } - *pos = i; - return (Chunk){ - .qmode = UN_Q, - .kind = CHUNK_LIT, - .as.lit_str = inner(&buf), - }; -} - - -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 = CHUNK_LIT, - .as.lit_str = inner(&buf) - }; -} - -static Chunk collect_double_q_section(char* line, size_t* pos) { - // TODO: add the extra double-q expansions - (*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 = DOUBLE_Q, - .kind = CHUNK_LIT, - .as.lit_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); - if (m_spec.some) { - Token* tok_ptr = push_to_TokenVec(ps_ast.token_pool, (Token){ - .kind = TOK_SPEC, - .as.spec = m_spec.value - }); - push_to_TokenPtrVec(ps_ast.top_tokens, tok_ptr); - continue; - } - - if (line[*pos] == '\'') { - Chunk chunk = collect_single_q_section(line, pos); - push_to_Word(&buf.word_germ, chunk); - } else if (line[*pos] == '\"') { - Chunk chunk = collect_double_q_section(line, pos); - push_to_Word(&buf.word_germ, chunk); - } else if (line[*pos] == '<' && line[(*pos)+1] == '(') { - *pos += 2; - consolidate_buffer(&buf, ps_ast); - TokenPtrVec procsub_toks = make_TokenPtrVec(256); - lex_level(line, pos, ')', (PseudoAst){ - .token_pool = ps_ast.token_pool, - .top_tokens = &procsub_toks - }); - (*pos)++; // consume ')' - Token* tok_ptr = push_to_TokenVec(ps_ast.token_pool, (Token){ - .kind = TOK_SUB_IN, - .as.procsub_toks = procsub_toks, - }); - push_to_TokenPtrVec(ps_ast.top_tokens, tok_ptr); - } else if (line[*pos] == '>' && line[(*pos)+1] == '(') { - *pos += 2; - consolidate_buffer(&buf, ps_ast); - TokenPtrVec procsub_toks = make_TokenPtrVec(256); - lex_level(line, pos, ')', (PseudoAst){ - .token_pool = ps_ast.token_pool, - .top_tokens = &procsub_toks - }); - (*pos)++; // consume ')' - Token* tok_ptr = push_to_TokenVec(ps_ast.token_pool, (Token){ - .kind = TOK_SUB_OUT, - .as.procsub_toks = procsub_toks, - }); - push_to_TokenPtrVec(ps_ast.top_tokens, tok_ptr); - } - } -} - -Ast lex(char* input) { - size_t line_pos = 0; - TokenVec token_pool = make_TokenVec(256); - TokenPtrVec top_tokens = make_TokenPtrVec(256); - lex_level(input, &line_pos, '\0', (PseudoAst){ - .token_pool = &token_pool, - .top_tokens = &top_tokens - }); - return (Ast){.token_pool = token_pool, .top_tokens = top_tokens}; -} |
