diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | main.c | 157 | ||||
-rw-r--r-- | parser.c | 144 | ||||
-rw-r--r-- | parser.h | 32 |
4 files changed, 178 insertions, 157 deletions
@@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -Wextra -Wpedantic -ggdb -fsanitize=address -std=c11 LIBS= -OBJECTS=lib.o main.o +OBJECTS=lib.o parser.o main.o OUT=obf.out ARGS= @@ -11,6 +11,7 @@ #include <string.h> #include "./lib.h" +#include "./parser.h" #define MEMORY_DEFAULT 30000 @@ -20,162 +21,6 @@ typedef struct uint8_t memory[MEMORY_DEFAULT]; } machine_t; -typedef struct AST -{ - size_t col, row; - enum - { - NEXT = 0, - PREV, - INC, - DEC, - OUT, - READ, - LIN, - LOUT - } type; - int loop_ref; -} node_t; - -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; -} - -struct PResult -{ - node_t *nodes; - size_t size; -} parse_buffer(buffer_t *buffer) -{ - node_t *nodes = NULL; - size_t usable = 0, loops = 0; - for (size_t i = 0; i < buffer->size; ++i) - if (usable_character(buffer->data[i])) - { - ++usable; - if (buffer->data[i] == '[') - ++loops; - } - nodes = calloc(usable, sizeof(*nodes)); - - // First pass: Get my info - for (size_t i = 0, col = 0, row = 1, nptr = 0; i < buffer->size; ++i) - { - ++col; - if (buffer->data[i] == '\n') - { - ++row; - col = 0; - } - else if (usable_character(buffer->data[i])) - { - nodes[nptr].col = col; - nodes[nptr].row = row; - switch (buffer->data[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) - { - print_error(buffer->name, node->row, node->col, - "ERROR: Unbalanced square brackets!"); - goto error; - } - // Access last IN loop - --stackptr; - node->loop_ref = stack[stackptr] - nodes; - stack[stackptr]->loop_ref = i; - } - } - - if (stackptr > 0) - { - node_t *node = nodes + usable - 1; - print_error(buffer->name, node->row, node->col, - "ERROR: Unbalanced square brackets!"); - goto error; - } - - return (struct PResult){nodes, usable}; -error: - if (nodes) - free(nodes); - return (struct PResult){0}; -} - int main(int argc, char *argv[]) { if (argc == 1) diff --git a/parser.c b/parser.c new file mode 100644 index 0000000..d1bc9c9 --- /dev/null +++ b/parser.c @@ -0,0 +1,144 @@ +/* parser.c + * Created: 2023-09-02 + * Author: Aryadev Chavali + * Description: Functions for (de)serialising + */ + +#include <string.h> + +#include "./parser.h" + +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; +} + +struct PResult parse_buffer(buffer_t *buffer) +{ + node_t *nodes = NULL; + size_t usable = 0, loops = 0; + for (size_t i = 0; i < buffer->size; ++i) + if (usable_character(buffer->data[i])) + { + ++usable; + if (buffer->data[i] == '[') + ++loops; + } + nodes = calloc(usable, sizeof(*nodes)); + + // First pass: Get my info + for (size_t i = 0, col = 0, row = 1, nptr = 0; i < buffer->size; ++i) + { + ++col; + if (buffer->data[i] == '\n') + { + ++row; + col = 0; + } + else if (usable_character(buffer->data[i])) + { + nodes[nptr].col = col; + nodes[nptr].row = row; + switch (buffer->data[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) + { + print_error(buffer->name, node->row, node->col, + "ERROR: Unbalanced square brackets!"); + goto error; + } + // Access last IN loop + --stackptr; + node->loop_ref = stack[stackptr] - nodes; + stack[stackptr]->loop_ref = i; + } + } + + if (stackptr > 0) + { + node_t *node = nodes + usable - 1; + print_error(buffer->name, node->row, node->col, + "ERROR: Unbalanced square brackets!"); + goto error; + } + + return (struct PResult){nodes, usable}; +error: + if (nodes) + free(nodes); + return (struct PResult){0}; +} diff --git a/parser.h b/parser.h new file mode 100644 index 0000000..70ed4ff --- /dev/null +++ b/parser.h @@ -0,0 +1,32 @@ +#ifndef PARSER_H +#define PARSER_H + +#include "./lib.h" + +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; +}; + +char *ast_to_str(node_t *ast, size_t size); +struct PResult parse_buffer(buffer_t *buffer); + +#endif |