aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c139
1 files changed, 9 insertions, 130 deletions
diff --git a/src/main.c b/src/main.c
index eb651bd..8b7683d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,133 +6,11 @@
#include <errno.h>
#include <string.h>
+#include <map.h>
+#include <parse.h>
#include <log.h>
-#include <hash.h>
-#include <hashmap.h>
-
-struct hashmap *all_terms;
-
-typedef enum { INV, ABS, APP, VAR } term_type_t;
-
-struct term {
- term_type_t type;
- hash_t hash;
- size_t refs;
- union {
- struct {
- hash_t term;
- } abs;
- struct {
- hash_t lhs;
- hash_t rhs;
- } app;
- struct {
- int index;
- } var;
- } u;
-};
-
-static void deref_term(struct term *term)
-{
- if (term->type == ABS) {
- deref_term(hashmap_get(all_terms, term->u.abs.term));
- } else if (term->type == APP) {
- deref_term(hashmap_get(all_terms, term->u.app.lhs));
- deref_term(hashmap_get(all_terms, term->u.app.rhs));
- }
-
- // TODO: remove from hashmap?
- if (--term->refs == 0)
- free(term);
-}
-
-static void hashmap_free_term(void *item)
-{
- struct term *term = *(struct term **)item;
- free(term);
-}
-
-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 rec_bblc
-static hash_t rec_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 = rec_blc(term);
- res = hash((uint8_t *)&res_type, sizeof(res_type), inner_hash);
-
- struct term **handle = hashmap_get(all_terms, res);
- if (handle) {
- res_term = *handle;
- res_term->refs++;
- } else {
- res_term = new_term(ABS);
- res_term->refs = 1;
- res_term->hash = res;
- res_term->u.abs.term = inner_hash;
- hashmap_set(all_terms, &res_term, res);
- }
- } else if (**term == '0' && *(*term + 1) == '1') {
- (*term) += 2;
- res_type = APP;
- hash_t lhs_hash = rec_blc(term);
- hash_t rhs_hash = rec_blc(term);
- res = hash((uint8_t *)&res_type, sizeof(res_type), lhs_hash);
- res = hash((uint8_t *)&res, sizeof(res), rhs_hash);
-
- struct term **handle = hashmap_get(all_terms, res);
- if (handle) {
- res_term = *handle;
- 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;
- hashmap_set(all_terms, &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);
-
- struct term **handle = hashmap_get(all_terms, res);
- if (handle) {
- res_term = *handle;
- res_term->refs++;
- } else {
- res_term = new_term(res_type);
- res_term->refs = 1;
- res_term->hash = res;
- res_term->u.var.index = index;
- hashmap_set(all_terms, &res_term, res);
- }
- (*term)++;
- } else {
- (*term)++;
- res = rec_blc(term);
- }
- return res;
-}
+#include <lib/hash.h>
+#include <lib/hashmap.h>
static char *read_file(FILE *f)
{
@@ -169,14 +47,15 @@ int main(int argc, char *argv[])
{
debug_enable(1);
if (argc != 2)
- fatal("usage: %s <file>\n", argv[0]);
+ fatal("usage: %s <file>\n", argc ? argv[0] : "calm");
char *term = read_path(argv[1]);
+ map_initialize();
+
char *orig_term = term;
- all_terms = hashmap_new(sizeof(struct term *), 0, hashmap_free_term);
- rec_blc(&term);
+ parse_blc(&term);
free(orig_term);
- hashmap_free(all_terms);
+ map_destroy();
return 0;
}