summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..0052ad9
--- /dev/null
+++ b/main.c
@@ -0,0 +1,147 @@
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+
+#define DECLARE_VEC(T, Name) \
+ typedef struct { \
+ T* items; \
+ size_t count; \
+ size_t cap; \
+ size_t incr_step; \
+ } Name; \
+ static inline Name make_##Name(size_t step) { \
+ return (Name) { \
+ .items = malloc(step* sizeof(T)), \
+ .count = 0, \
+ .cap = step, \
+ .incr_step = step, \
+ }; \
+ } \
+ static inline void push_to_##Name(Name* vec, T item) { \
+ if (vec->count == vec->cap) { \
+ vec->cap += vec->incr_step; \
+ vec->items = realloc( \
+ vec->items, \
+ vec->cap * sizeof(T) \
+ ); \
+ } \
+ vec->items[vec->count++] = item; \
+ } \
+
+
+DECLARE_VEC(char, String);
+
+void append_str_to_String(String* target, char* src_str) {
+ size_t required_size =
+ ((target->count + strlen(src_str)) / target->incr_step + 1) * target->incr_step;
+ if (required_size > target->cap) {
+ target->cap = required_size;
+ target->items = realloc(target->items, required_size * sizeof(char));
+ }
+ memcpy(target->items + target->count, src_str, strlen(src_str));
+ target->count += strlen(src_str);
+}
+
+
+#define DECLARE_MAYBE(T) \
+ typedef struct { \
+ bool some; \
+ T value; \
+ } Maybe##T; \
+
+
+
+typedef enum {
+ UN_Q,
+ SINGLE_Q,
+ DOUBLE_Q,
+} QuotationMode;
+
+typedef struct Region Region;
+
+typedef enum {
+ LITERAL,
+ CMD_SUB,
+ ARITHM,
+ PARAM,
+} ChunkKind;
+
+
+typedef struct {
+ ChunkKind kind;
+ QuotationMode mode;
+
+ union {
+ char* lit_str;
+ Region* sub_cmd_region;
+ Region* arithm_expr_region;
+ Region* param_region;
+ } as;
+} Chunk;
+
+
+DECLARE_VEC(Chunk, ChunkVec)
+
+typedef enum {
+ TOK_WORD,
+ TOK_SPECIAL,
+} TokenKind;
+
+typedef enum {
+ PIPE,
+ WRITE_REDIR_TRUNC,
+ WRITE_REDIR_APPEND,
+ READ_REDIR,
+ EOL,
+} SpecialToken;
+
+typedef struct {
+ TokenKind kind;
+
+ union {
+ ChunkVec word;
+ SpecialToken spec;
+ } as;
+} Token;
+
+
+DECLARE_VEC(Token, TokenVec)
+
+DECLARE_MAYBE(SpecialToken)
+
+struct Region {
+ QuotationMode mode;
+ TokenVec tokens;
+};
+
+DECLARE_MAYBE(Chunk);
+
+
+MaybeChunk unquoted_next_chunk(char* input, size_t* pos) {
+ String chunk;
+ char curr_c;
+ for (;(curr_c = input[*pos], curr_c != '$' && curr_c != '\'' && curr_c != '\"' && curr_c != '\0'); pos++) {
+ exit(1);
+ }
+ exit(1);
+}
+
+
+TokenVec lex_region(char* input, size_t* pos, char until) {
+ TokenVec tokens = make_TokenVec(256);
+
+ while (input[*pos] != until) {
+ while (input[*pos] == ' ') (*pos)++;
+
+
+ }
+ return tokens;
+}
+
+TokenVec lex(char* input) {
+ size_t pos = 0;
+ return lex_region(input, &pos, '\0');
+}