summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lexparse.c26
-rw-r--r--src/main.c4
-rw-r--r--src/preproc.c53
-rw-r--r--src/stages.h3
-rw-r--r--src/syntax.h2
5 files changed, 66 insertions, 22 deletions
diff --git a/src/lexparse.c b/src/lexparse.c
index 3d48cfe..4ef228c 100644
--- a/src/lexparse.c
+++ b/src/lexparse.c
@@ -1,4 +1,5 @@
#include <ctype.h>
+#include <stddef.h>
#include "syntax.h"
#include "../src/utils.h"
@@ -38,6 +39,31 @@ MaybeToken consolidate_buffer(LexingBuffer* buf) {
}
+static MaybeChunk handle_dollar_expansion(char* line, size_t* pos, QuotationMode qmode) {
+ (*pos)++;
+
+ if (line[*pos] == '(') {
+ // TODO
+ exit(66);
+ } else if (line[*pos] == '_' || isalnum(line[*pos])){
+ String buf = make_String(256);
+ while (line[*pos] == '_' || isalnum(line[*pos])) {
+ push_to_String(&buf, line[(*pos)++]);
+ }
+ return (MaybeChunk){
+ .some = true,
+ .value = (Chunk){
+ .qmode = qmode,
+ .kind = CHUNK_VAR,
+ .as.varname = inner(&buf)
+ }
+ };
+ } else {
+ return (MaybeChunk){.some = false};
+ }
+}
+
+
static Chunk collect_un_q_literal(char* line, size_t* pos) {
String buf = make_String(256);
size_t i;
diff --git a/src/main.c b/src/main.c
index dc451f9..1f9198b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,9 +6,11 @@
#include "syntax.h"
#include "stages.h"
+#include "utils.h"
int main() {
+ ShellState shstate = {.shell_vars = make_KeyValMap(256), .aliases = make_KeyValMap(256)};
char* line;
while (1) {
line = readline("$ ");
@@ -16,7 +18,7 @@ int main() {
if (strcmp(line, "exit") == 0) exit(0);
add_history(line);
Ast ast = lex(line);
- PipelineTree pltree = process_ast(ast);
+ PipelineTree pltree = process_ast(ast, &shstate);
execute_pipeline_tree(pltree);
}
free(line);
diff --git a/src/preproc.c b/src/preproc.c
index d64f4c3..6aa7748 100644
--- a/src/preproc.c
+++ b/src/preproc.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <stdio.h>
#include "syntax.h"
+#include "utils.h"
void split_str_on_space(char* str, StrVec* result) {
String buf = make_String(256);
@@ -19,23 +20,34 @@ void split_str_on_space(char* str, StrVec* result) {
}
}
-StrVec process_word(Word word) {
+
+void process_chunk(Chunk chunk, StrVec* result, ShellState* shstate) {
+ assert(!(chunk.qmode == SINGLE_Q && chunk.kind != CHUNK_LIT));
+
+ char* chunk_val;
+ switch (chunk.kind) {
+ case CHUNK_LIT:
+ chunk_val = chunk.as.lit_str;
+ break;
+ case CHUNK_VAR:
+ chunk_val = get_var(chunk.as.varname, shstate);
+ break;
+ default:
+ exit(77);
+ }
+
+ if (chunk.qmode == UN_Q) {
+ split_str_on_space(chunk_val, result);
+ } else {
+ push_to_StrVec(result, chunk_val);
+ }
+}
+
+StrVec process_word(Word word, ShellState* shstate) {
StrVec result = make_StrVec(256);
for (int i = 0; i < word.count; i++) {
Chunk chunk = *get_from_Word(&word, i);
- switch (chunk.qmode) {
- case SINGLE_Q:
- push_to_StrVec(&result, chunk.as.lit_str);
- break;
- case DOUBLE_Q:
- // TODO
- exit(67);
- break;
- case UN_Q:
- // TODO: this only does literals, implement the rest
- split_str_on_space(chunk.as.lit_str, &result);
- break;
- }
+ process_chunk(chunk, &result, shstate);
}
return result;
}
@@ -51,7 +63,8 @@ typedef struct {
DECLARE_VEC(ExpandedToken, ExpandedTokenVec)
-Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) {
+
+Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool, ShellState* shstate) {
ExpandedTokenVec exp_tokens = make_ExpandedTokenVec(256);
@@ -63,7 +76,7 @@ Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) {
push_to_ExpandedTokenVec(&exp_tokens, (ExpandedToken){.kind = TOK_SPEC, .as.spec = tok.as.spec});
break;
case TOK_WORD:
- strs = process_word(tok.as.word);
+ strs = process_word(tok.as.word, shstate);
for (int n = 0; n < strs.count; n++) {
push_to_ExpandedTokenVec(&exp_tokens, (ExpandedToken){.kind = TOK_WORD, .as.word = *get_from_StrVec(&strs, n)});
}
@@ -120,11 +133,11 @@ Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) {
}
break;
case SPEC_SUB_IN:
- sub_pl = process_token_sequence(*(TokenVec*)curr_tok.as.spec.as.proc_sub_region, pl_pool);
+ sub_pl = process_token_sequence(*(TokenVec*)curr_tok.as.spec.as.proc_sub_region, pl_pool, shstate);
push_to_ArgVec(&curr_cmd.args, (Arg){.kind = ARG_PS_IN, .as.sub_pipeline = sub_pl});
break;
case SPEC_SUB_OUT:
- sub_pl = process_token_sequence(*(TokenVec*)curr_tok.as.spec.as.proc_sub_region, pl_pool);
+ sub_pl = process_token_sequence(*(TokenVec*)curr_tok.as.spec.as.proc_sub_region, pl_pool, shstate);
push_to_ArgVec(&curr_cmd.args, (Arg){.kind = ARG_PS_OUT, .as.sub_pipeline = sub_pl});
break;
}
@@ -134,8 +147,8 @@ Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) {
}
-PipelineTree process_ast(Ast ast) {
+PipelineTree process_ast(Ast ast, ShellState* shstate) {
PipelineVec pls = make_PipelineVec(256);
- Pipeline* root_pl = process_token_sequence(*ast.root, &pls);
+ Pipeline* root_pl = process_token_sequence(*ast.root, &pls, shstate);
return (PipelineTree){.pl_pool = pls, root_pl};
}
diff --git a/src/stages.h b/src/stages.h
index 4faaf14..f009c78 100644
--- a/src/stages.h
+++ b/src/stages.h
@@ -1,7 +1,8 @@
#pragma once
#include "syntax.h"
+#include "utils.h"
Ast lex(char* input);
-PipelineTree process_ast(Ast ast);
+PipelineTree process_ast(Ast ast, ShellState* shstate);
void execute_pipeline_tree(PipelineTree pltree);
diff --git a/src/syntax.h b/src/syntax.h
index a0ccfac..12293ae 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -63,6 +63,8 @@ typedef struct {
} as;
} Chunk;
+DECLARE_MAYBE(Chunk, MaybeChunk)
+
DECLARE_VEC(Chunk, Word)