#include #include #include "syntax.h" void split_str_on_space(char* str, StrVec* result) { String buf = make_String(256); for (int pos = 0; str[pos] != '\0'; pos++) { if (str[pos] == ' ') { push_to_StrVec(result, inner(&buf)); buf = make_String(256); } else { push_to_String(&buf, str[pos]); } } if (buf.count > 0) { char* buf_str = inner(&buf); push_to_StrVec(result, buf_str); } } StrVec process_word(Word word) { 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; } } return result; } Pipeline* process_token_sequence(TokenVec tokens, PipelineVec* pl_pool) { Pipeline pl = make_Pipeline(256); size_t tok_pos = 0; while (tok_pos < tokens.count) { PlCommand pl_cmd = { .args = make_ArgVec(256), .redirects = make_RedirectVec(256), .conn = CONN_EOL, }; Token curr_tok; for (; ( curr_tok = *get_from_TokenVec(&tokens, tok_pos), !(curr_tok.kind == TOK_SPEC && (curr_tok.as.spec == SPEC_PIPE || curr_tok.as.spec == SPEC_EOL)) ); tok_pos++ ) { StrVec exp_word = make_StrVec(256); switch (curr_tok.kind) { case TOK_WORD: exp_word = process_word(curr_tok.as.word); for (int j = 0; j < exp_word.count; j++) { char* arg_str = *get_from_StrVec(&exp_word, j); push_to_ArgVec(&pl_cmd.args, (Arg){.kind = ARG_LIT, .as.lit_str = arg_str}); } break; case TOK_SPEC: switch (curr_tok.as.spec) { } break; default: exit(68); // TODO: the other kinds } } Token delim_tok = *get_from_TokenVec(&tokens, tok_pos++); assert(delim_tok.kind == TOK_SPEC); switch (delim_tok.as.spec) { case SPEC_PIPE: pl_cmd.conn = CONN_PIPE; break; case SPEC_EOL: pl_cmd.conn = CONN_EOL; break; default: exit(69); } for (int k = 0; k < pl_cmd.args.count; k++) { Arg arg = *get_from_ArgVec(&pl_cmd.args, k); } push_to_Pipeline(&pl, pl_cmd); } return push_to_PipelineVec(pl_pool, pl); } PipelineTree process_ast(Ast ast) { PipelineVec pls = make_PipelineVec(256); TokenVec root_toks = *ast.root; Pipeline* root_pl = process_token_sequence(root_toks, &pls); return (PipelineTree){.pl_pool = pls, root_pl}; }