summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit6a391a1180766ac5717c40efa70d46cacca83f91 (patch)
treedae1c0d5987e4ef54e12e2562b842deb0792eeeb
parent32773451f89612dcd863fbb8c9bfd552ef83a913 (diff)
sketch new setup
-rw-r--r--lexparse.c92
-rw-r--r--syntax.h71
2 files changed, 158 insertions, 5 deletions
diff --git a/lexparse.c b/lexparse.c
index 19ce08b..0ea86df 100644
--- a/lexparse.c
+++ b/lexparse.c
@@ -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};
}
diff --git a/syntax.h b/syntax.h
index b395705..8404d15 100644
--- a/syntax.h
+++ b/syntax.h
@@ -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;