From 2d33640c037c9f3bcbddc200eec39bb713ca0c9f Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Sat, 2 Sep 2023 15:21:56 +0100 Subject: INIT Simple parser, took like an hour. Not very smart but at least it's like O(n). --- .gitignore | 2 + Makefile | 20 +++++++ main.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..386f581 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.out +*.o \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cfd0ecb --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +CC=gcc +CFLAGS=-Wall -Wextra -Wpedantic -ggdb -fsanitize=address -std=c11 +LIBS= +OBJECTS=main.o +OUT=obf.out +ARGS= + +%.o: %.c + $(CC) $(CFLAGS) -c $^ -o $@ $(LIBS) + +$(OUT): $(OBJECTS) + $(CC) $(CFLAGS) $^ -o $@ $(LIBS) + +.PHONY: +clean: + rm -rfv $(OUT) $(OBJECTS) + +.PHONY: run +run: $(OUT) + ./$^ $(ARGS) diff --git a/main.c b/main.c new file mode 100644 index 0000000..5174e3d --- /dev/null +++ b/main.c @@ -0,0 +1,193 @@ +/* main.c + * Created: 2023-09-02 + * Author: Aryadev Chavali + * Description: Entrypoint of compiler + */ + +#include +#include +#include +#include +#include + +#define MEMORY_DEFAULT 30000 + +typedef struct +{ + size_t dp; + uint8_t memory[MEMORY_DEFAULT]; +} machine_t; + +bool usable_character(char c) +{ + return c == '>' || c == '<' || c == '+' || c == '-' || c == '-' || c == '.' || + c == ',' || c == '[' || c == ']'; +} + +typedef struct AST +{ + size_t col, row; + enum + { + NEXT = 0, + PREV, + INC, + DEC, + OUT, + READ, + LIN, + LOUT + } type; + int loop_ref; +} node_t; + +struct PResult +{ + node_t *nodes; + size_t size; +} parse_input(const char *input, size_t input_size) +{ + node_t *nodes = NULL; + size_t usable = 0, loops = 0; + for (size_t i = 0; i < input_size; ++i) + if (usable_character(input[i])) + { + ++usable; + if (input[i] == '[') + ++loops; + } + nodes = calloc(usable, sizeof(*nodes)); + + // First pass: Get my info + for (size_t i = 0, col = 0, row = 1, nptr = 0; i < input_size; ++i) + { + ++col; + if (input[i] == '\n') + { + ++row; + col = 0; + } + else if (usable_character(input[i])) + { + nodes[nptr].col = col; + nodes[nptr].row = row; + switch (input[i]) + { + case '>': + nodes[nptr].type = NEXT; + break; + case '<': + nodes[nptr].type = PREV; + break; + case '+': + nodes[nptr].type = INC; + break; + case '-': + nodes[nptr].type = DEC; + break; + case '.': + nodes[nptr].type = OUT; + break; + case ',': + nodes[nptr].type = READ; + break; + case '[': + nodes[nptr].type = LIN; + nodes[nptr].loop_ref = -1; + break; + case ']': + nodes[nptr].type = LOUT; + nodes[nptr].loop_ref = -1; + break; + } + ++nptr; + } + } + + // Second pass: setup any loop references + node_t *stack[loops]; + memset(stack, 0, loops); + size_t stackptr = 0; + for (size_t i = 0; i < usable; ++i) + { + node_t *node = nodes + i; + if (node->type == LIN) + stack[stackptr++] = node; + else if (node->type == LOUT) + { + if (stackptr == 0) + { + fputs("ERROR: Unbalanced square brackets!\n", stderr); + goto error; + } + // Access last IN loop + --stackptr; + node->loop_ref = stack[stackptr] - nodes; + stack[stackptr]->loop_ref = i; + } + } + + if (stackptr > 0) + { + fputs("ERROR: Unbalanced square brackets!\n", stderr); + goto error; + } + + return (struct PResult){nodes, usable}; +error: + if (nodes) + free(nodes); + return (struct PResult){0}; +} + +char *ast_to_str(node_t *ast, size_t size) +{ + char *out = calloc(size + 1, 1); + for (size_t i = 0; i < size; ++i) + { + switch (ast[i].type) + { + case NEXT: + out[i] = '>'; + break; + case PREV: + out[i] = '<'; + break; + case INC: + out[i] = '+'; + break; + case DEC: + out[i] = '-'; + break; + case OUT: + out[i] = '.'; + break; + case READ: + out[i] = ','; + break; + case LIN: + out[i] = '['; + break; + case LOUT: + out[i] = ']'; + break; + } + } + out[size] = '\0'; + return out; +} + +int main(void) +{ + const char input[] = "[[->+<]"; + struct PResult res = parse_input(input, sizeof(input) / sizeof(input[0])); + if (res.nodes == NULL) + { + fputs("Exiting early...\n", stderr); + return 1; + } + char *str = ast_to_str(res.nodes, res.size); + free(str); + free(res.nodes); + return 0; +} -- cgit v1.2.3-13-gbd6f