diff options
author | Marvin Borner | 2023-05-26 20:34:07 +0200 |
---|---|---|
committer | Marvin Borner | 2023-05-26 20:34:22 +0200 |
commit | 896e0e1bd8502a6d7f901f9e13bcd95df5d98635 (patch) | |
tree | 4bc1916e81f75980c213802b1d4f3e81f74fb3b3 /src/parse.c | |
parent | 464cca35825a02541efd46cfd3af91146c118d01 (diff) |
Abstract abstractification
Diffstat (limited to 'src/parse.c')
-rw-r--r-- | src/parse.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..55bcb86 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,85 @@ +// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de> +// SPDX-License-Identifier: MIT + +#include <stdlib.h> + +#include <parse.h> +#include <lib/hashmap.h> +#include <map.h> +#include <log.h> + +static struct term *new_term(term_type_t type) +{ + struct term *term = malloc(sizeof(*term)); + if (!term) + fatal("out of memory!\n"); + term->type = type; + return term; +} + +// TODO: bit parse_bblc +hash_t parse_blc(char **term) +{ + hash_t res = 0; + struct term *res_term = 0; + term_type_t res_type = 0; + + if (!**term) { + fatal("invalid parsing state!\n"); + } else if (**term == '0' && *(*term + 1) == '0') { + (*term) += 2; + res_type = ABS; + hash_t inner_hash = parse_blc(term); + res = hash((uint8_t *)&res_type, sizeof(res_type), inner_hash); + + if ((res_term = map_get(res))) { + res_term->refs++; + } else { + res_term = new_term(ABS); + res_term->refs = 1; + res_term->hash = res; + res_term->u.abs.term = inner_hash; + map_set(res_term, res); + } + } else if (**term == '0' && *(*term + 1) == '1') { + (*term) += 2; + res_type = APP; + hash_t lhs_hash = parse_blc(term); + hash_t rhs_hash = parse_blc(term); + res = hash((uint8_t *)&res_type, sizeof(res_type), lhs_hash); + res = hash((uint8_t *)&res, sizeof(res), rhs_hash); + + if ((res_term = map_get(res))) { + res_term->refs++; + } else { + res_term = new_term(res_type); + res_term->refs = 1; + res_term->hash = res; + res_term->u.app.lhs = lhs_hash; + res_term->u.app.rhs = rhs_hash; + map_set(res_term, res); + } + } else if (**term == '1') { + res_type = VAR; + const char *cur = *term; + while (**term == '1') + (*term)++; + int index = *term - cur - 1; + res = hash((uint8_t *)&res_type, sizeof(res_type), index); + + if ((res_term = map_get(res))) { + res_term->refs++; + } else { + res_term = new_term(res_type); + res_term->refs = 1; + res_term->hash = res; + res_term->u.var.index = index; + map_set(res_term, res); + } + (*term)++; + } else { + (*term)++; + res = parse_blc(term); + } + return res; +} |