diff options
| author | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-19 21:03:12 +0200 |
|---|---|---|
| committer | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-19 21:03:12 +0200 |
| commit | 6a391a1180766ac5717c40efa70d46cacca83f91 (patch) | |
| tree | dae1c0d5987e4ef54e12e2562b842deb0792eeeb | |
| parent | 32773451f89612dcd863fbb8c9bfd552ef83a913 (diff) | |
sketch new setup
| -rw-r--r-- | lexparse.c | 92 | ||||
| -rw-r--r-- | syntax.h | 71 |
2 files changed, 158 insertions, 5 deletions
@@ -31,6 +31,21 @@ static void consolidate_buffer(LexingBuffer* buf, PseudoAst ps_ast) { } +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); @@ -40,11 +55,29 @@ static Chunk collect_single_q_section(char* line, size_t* pos) { } if (line[i] == '\0') exit(44); - *pos = i; + *pos = ++i; return (Chunk){ .qmode = SINGLE_Q, - .kind = LITERAL, - .as.literal_str = inner(&buf) + .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) }; } @@ -91,11 +124,62 @@ static void lex_level(char* line, size_t* pos, char until, PseudoAst ps_ast) { 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}; } @@ -3,11 +3,13 @@ #include "utils.h" +// Stage 1 + typedef enum { PLUS, MINUS, MULT, - DIV, +DIV, } BinOp; typedef enum { @@ -20,6 +22,7 @@ struct ArithmNode { ArithmNodeKind kind; union { int lit_val; + IntVec open_fds; struct { BinOp op; ArithmNode* left; @@ -96,3 +99,69 @@ typedef struct { TokenVec token_pool; TokenPtrVec top_tokens; } Ast; + + + +// Stage 2 + + +typedef enum { + REDIR_FILE_IN, + REDIR_FILE_OUT, + REDIR_FDS, +} RedirectKind; + +typedef struct { + RedirectKind kind; + union { + char* filename; + struct{int from; int to;} fds; + } as; +} Redirect; + +DECLARE_VEC(Redirect, RedirectVec) + +typedef struct { + char** args; + RedirectVec redirects; +} SimpleCommand; + +DECLARE_VEC(SimpleCommand, SimpleCommandVec) +DECLARE_VEC(SimpleCommand*, SimpleCommandPtrVec) + + +typedef enum { + CONN_PIPE, + CONN_EOL, +} Connector; + +typedef struct { + SimpleCommand* cmd; + SimpleCommandPtrVec deps; + Connector conn; +} PlCommand; + +DECLARE_VEC(PlCommand, PlCommandVec) + +typedef struct { + SimpleCommandVec commands; + PlCommandVec pipeline; +} ExecTree; + + + +// Stage 3 + +typedef struct { + int redirected; + int to; +} FdRedirect; + +DECLARE_VEC(FdRedirect, FdRedirectVec) + +typedef struct { + char** args; + FdRedirectVec redirects; + int stdin_fd, stdout_fd; + IntVec open_fds; +} ExecutableCommand; |
