diff options
author | Preston Pan <preston@nullring.xyz> | 2024-01-09 18:39:49 -0800 |
---|---|---|
committer | Preston Pan <preston@nullring.xyz> | 2024-01-09 18:39:49 -0800 |
commit | ac6004730fa54a756d1627a4e8450cd32df86f75 (patch) | |
tree | 8cb4d59438a1252fa069788b2ffb78b2a1bbad3e /parser.c | |
parent | 6ccf0572469dfc8cd8fa7b8537b2ac6c265d2df6 (diff) |
reorganize directory structure
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 451 |
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); - } - } - } - } -} |