aboutsummaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2024-01-09 18:39:49 -0800
committerPreston Pan <preston@nullring.xyz>2024-01-09 18:39:49 -0800
commitac6004730fa54a756d1627a4e8450cd32df86f75 (patch)
tree8cb4d59438a1252fa069788b2ffb78b2a1bbad3e /parser.c
parent6ccf0572469dfc8cd8fa7b8537b2ac6c265d2df6 (diff)
reorganize directory structure
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c451
1 files changed, 0 insertions, 451 deletions
diff --git a/parser.c b/parser.c
deleted file mode 100644
index 2d5dd47..0000000
--- a/parser.c
+++ /dev/null
@@ -1,451 +0,0 @@
-#include "parser.h"
-#include "macros.h"
-#include <ctype.h>
-#include <math.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-array_t *STACK;
-array_t *EVAL_STACK;
-ht_t *WORD_TABLE;
-char *INBUF;
-parser_t *PARSER;
-
-ht_t *FLIT;
-ht_t *OBJ_TABLE;
-
-void func_free(void *f) {}
-
-array_t *init_array(size_t size) {
- array_t *a = calloc(1, sizeof(array_t));
- a->size = 0;
- a->capacity = size;
- a->items = calloc(a->capacity, sizeof(value_t *));
- return a;
-}
-
-void array_append(array_t *a, value_t *v) {
- if (a->size >= a->capacity - 2) {
- a->capacity = a->capacity * 2;
- a->items = realloc(a->items, a->capacity * sizeof(value_t *));
- }
- a->items[a->size] = v;
- a->size++;
-}
-
-value_t *array_pop(array_t *a) {
- if (a->size > 0) {
- value_t *v = a->items[a->size - 1];
- a->size--;
- return v;
- }
- return NULL;
-}
-
-void array_extend(array_t *a, array_t *b) {
- for (int i = 0; i < b->size; i++) {
- array_append(a, b->items[i]);
- }
-}
-
-void array_free(array_t *a) {
- for (int i = 0; i < a->size; i++) {
- value_free(a->items[i]);
- }
- free(a->items);
- free(a);
-}
-
-array_t *array_copy(array_t *a) {
- array_t *b = calloc(1, sizeof(array_t));
- b->size = a->size;
- b->capacity = a->capacity;
- b->items = calloc(b->capacity, sizeof(value_t *));
- for (int i = 0; i < a->size; i++) {
- b->items[i] = value_copy(a->items[i]);
- }
- return b;
-}
-
-value_t *init_value(int type) {
- value_t *v = calloc(1, sizeof(value_t));
- v->type = type;
- v->escaped = false;
- return v;
-}
-
-value_t *value_copy(value_t *v) {
- value_t *a = init_value(VINT);
- a->type = v->type;
- if (v->type == VINT || v->type == VFLOAT) {
- a->int_float = v->int_float;
- } else if (v->type == VSTR || v->type == VWORD) {
- a->str_word = string_copy(v->str_word);
- a->escaped = v->escaped;
- } else if (v->type == VQUOTE) {
- a->quote = array_copy(v->quote);
- } else if (v->type == VCUSTOM) {
- custom_t *c = ht_get(OBJ_TABLE, a->str_word);
- a->custom = c->copyfunc(v->custom);
- a->str_word = string_copy(v->str_word);
- }
- return a;
-}
-
-void value_free(void *vtmp) {
- value_t *v = (value_t *)vtmp;
- if (v->type == VSTR || v->type == VWORD) {
- string_free(v->str_word);
- }
- if (v->type == VQUOTE) {
- array_free(v->quote);
- }
- if (v->type == VCUSTOM) {
- void (*freefunc)(void *) = ht_get(OBJ_TABLE, v->str_word);
- freefunc(v->custom);
- }
- free(v);
-}
-
-custom_t *init_custom(void (*printfunc)(void *), void (*freefunc)(void *),
- void *(*copyfunc)(void *)) {
- custom_t *c = calloc(1, sizeof(custom_t));
- c->printfunc = printfunc;
- c->freefunc = freefunc;
- c->copyfunc = copyfunc;
- return c;
-}
-
-void custom_free(void *c) { free(c); }
-
-parser_t *init_parser(char *source) {
- parser_t *p = calloc(1, sizeof(parser_t));
- p->i = 0;
- p->source = source;
- p->c = source[0];
- return p;
-}
-
-void parser_reset(parser_t *p, char *source) {
- p->source = source;
- p->i = 0;
- p->c = source[0];
-}
-
-void parser_move(parser_t *p) {
- if (p->i < strlen(p->source) && p->c != '\0') {
- p->i++;
- p->c = p->source[p->i];
- }
-}
-
-void parser_skip_whitespace(parser_t *p) {
- while (isspace(p->c)) {
- parser_move(p);
- }
-}
-
-value_t *parse_string(parser_t *p) {
- value_t *retv = init_value(VSTR);
- parser_move(p);
- string_t *s = init_string(NULL);
- bool escaped = false;
- while (escaped || p->c != '"' && p->c != '\0') {
- if (p->c == '\\') {
- escaped = true;
- parser_move(p);
- continue;
- }
- if (escaped) {
- switch (p->c) {
- case '"':
- string_append(s, '"');
- break;
- case 'n':
- string_append(s, '\n');
- break;
- case 'r':
- string_append(s, '\r');
- break;
- case 't':
- string_append(s, '\t');
- break;
- case '\\':
- string_append(s, '\\');
- break;
- default:
- string_append(s, p->c);
- break;
- }
- parser_move(p);
- escaped = false;
- } else {
- string_append(s, p->c);
- parser_move(p);
- escaped = false;
- }
- }
- parser_move(p);
- retv->str_word = s;
- return retv;
-}
-
-value_t *parse_quote(parser_t *p) {
- value_t *retv = init_value(VQUOTE);
- retv->quote = init_array(10);
- parser_move(p);
- parser_skip_whitespace(p);
- while (p->c != ']') {
- array_append(retv->quote, parser_get_next(p));
- parser_skip_whitespace(p);
- }
- parser_move(p);
- return retv;
-}
-
-void parser_error(parser_t *p) { exit(1); }
-
-value_t *parse_word(parser_t *p) {
- value_t *retv = init_value(VWORD);
- string_t *s = init_string(NULL);
- if (p->c == '\\') {
- retv->escaped = true;
- parser_move(p);
- if (isspace(p->c) || p->c == '\0') {
- parser_error(p);
- }
- }
- while (!isspace(p->c) && p->c != '\0') {
- string_append(s, p->c);
- parser_move(p);
- }
- retv->str_word = s;
- return retv;
-}
-
-value_t *parse_num(parser_t *p) {
- value_t *retv;
- string_t *s = init_string(NULL);
- bool is_float = false;
- while (isdigit(p->c) || (p->c == '.') && !is_float) {
- if (p->c == '.')
- is_float = true;
- string_append(s, p->c);
- parser_move(p);
- }
- if (is_float)
- retv = init_value(VFLOAT);
- else
- retv = init_value(VINT);
- retv->int_float = atof(s->value);
- string_free(s);
- return retv;
-}
-
-value_t *parser_get_next(parser_t *p) {
- parser_skip_whitespace(p);
- if (isdigit(p->c)) {
- return parse_num(p);
- }
- switch (p->c) {
- case '"':
- return parse_string(p);
- case '[':
- return parse_quote(p);
- case '\0':
- return NULL;
- default:
- return parse_word(p);
- }
-}
-
-node_t *init_node(string_t *key, void *value) {
- node_t *n = calloc(1, sizeof(node_t));
- n->key = key;
- n->value = value;
- n->next = NULL;
- return n;
-}
-
-void node_free(node_t *n, void (*freefunc)(void *)) {
- string_free(n->key);
- freefunc(n->value);
- free(n);
-}
-
-sll_t *init_sll() {
- sll_t *l = calloc(1, sizeof(sll_t));
- l->size = 0;
- l->head = NULL;
- return l;
-}
-
-void sll_add(sll_t *l, string_t *s, void *v) {
- if (l->head == NULL) {
- node_t *n = init_node(s, v);
- l->head = n;
- l->size++;
- return;
- }
- node_t *cur = l->head;
- while (cur->next != NULL) {
- if (strcmp(s->value, cur->key->value) == 0) {
- value_free(cur->value);
- string_free(s);
- cur->value = v;
- return;
- }
- cur = cur->next;
- }
- if (strcmp(s->value, cur->key->value) == 0) {
- value_free(cur->value);
- string_free(s);
- cur->value = v;
- return;
- }
- node_t *n = init_node(s, v);
- cur->next = n;
-}
-
-void sll_add_func(sll_t *l, string_t *s, void *v) {
- if (l->head == NULL) {
- node_t *n = init_node(s, v);
- l->head = n;
- l->size++;
- return;
- }
- node_t *cur = l->head;
- while (cur->next != NULL) {
- if (strcmp(s->value, cur->key->value) == 0) {
- string_free(s);
- cur->value = v;
- return;
- }
- cur = cur->next;
- }
- if (strcmp(s->value, cur->key->value) == 0) {
- string_free(s);
- cur->value = v;
- return;
- }
- node_t *n = init_node(s, v);
- cur->next = n;
-}
-
-void *sll_get(sll_t *l, string_t *k) {
- if (l->head == NULL)
- return NULL;
- node_t *cur = l->head;
- while (cur != NULL) {
- if (strcmp(k->value, cur->key->value) == 0)
- return cur->value;
- cur = cur->next;
- }
- return NULL;
-}
-
-void sll_free(sll_t *l, void (*func)(void *)) {
- node_t *cur = l->head;
- node_t *tmp;
- while (cur != NULL) {
- tmp = cur;
- cur = cur->next;
- node_free(tmp, func);
- }
- free(l);
-}
-
-ht_t *init_ht(size_t size) {
- ht_t *h = calloc(1, sizeof(ht_t));
- h->size = size;
- h->buckets = calloc(h->size, sizeof(sll_t *));
- for (int i = 0; i < size; i++) {
- h->buckets[i] = init_sll();
- }
- return h;
-}
-
-void ht_add(ht_t *h, string_t *key, void *v) {
- sll_add(h->buckets[hash(h, key->value)], key, v);
-}
-
-void ht_add_func(ht_t *h, string_t *key, void *v) {
- sll_add_func(h->buckets[hash(h, key->value)], key, v);
-}
-
-void *ht_get(ht_t *h, string_t *key) {
- return sll_get(h->buckets[hash(h, key->value)], key);
-}
-
-bool ht_exists(ht_t *h, string_t *key) { return ht_get(h, key) != NULL; }
-
-void ht_free(ht_t *h, void (*func)(void *)) {
- for (int i = 0; i < h->size; i++) {
- sll_free(h->buckets[i], func);
- }
- free(h->buckets);
- free(h);
-}
-
-/* DJB2 HASH FUNCTION */
-unsigned long hash(ht_t *h, char *key) {
- unsigned long hash = 5381;
- int c;
-
- while (c = *key++)
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-
- return hash % h->size;
-}
-
-bool eval_ht(value_t *v) {
- value_t *func = ht_get(WORD_TABLE, v->str_word);
- if (func == NULL)
- return false;
- value_free(v);
- if (func->type == VQUOTE) {
- for (int i = 0; i < func->quote->size; i++) {
- eval(value_copy(func->quote->items[i]));
- }
- } else {
- eval(value_copy(func));
- }
- return true;
-}
-
-bool eval_builtins(value_t *v) {
- void (*func)(value_t *) = ht_get(FLIT, v->str_word);
- if (func == NULL)
- return false;
- array_append(EVAL_STACK, v);
- func(v);
- array_pop(EVAL_STACK);
- value_free(v);
- return true;
-}
-
-void eval(value_t *v) {
- switch (v->type) {
- case VINT:
- case VFLOAT:
- case VSTR:
- case VQUOTE:
- case VERR:
- case VCUSTOM:
- array_append(STACK, v);
- break;
- case VWORD:
- if (v->escaped) {
- v->escaped = false;
- array_append(STACK, v);
- } else {
- if (!eval_builtins(v)) {
- if (!eval_ht(v)) {
- array_append(STACK, v);
- }
- }
- }
- }
-}