summaryrefslogtreecommitdiff
path: root/lexparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'lexparse.c')
-rw-r--r--lexparse.c101
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;
+}