aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--main.c157
-rw-r--r--parser.c144
-rw-r--r--parser.h32
4 files changed, 178 insertions, 157 deletions
diff --git a/Makefile b/Makefile
index 9e7800c..09de95d 100644
--- a/Makefile
+++ b/Makefile
@@ -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=
diff --git a/main.c b/main.c
index dc7269a..dad7e92 100644
--- a/main.c
+++ b/main.c
@@ -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