aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2023-05-26 20:34:07 +0200
committerMarvin Borner2023-05-26 20:34:22 +0200
commit896e0e1bd8502a6d7f901f9e13bcd95df5d98635 (patch)
tree4bc1916e81f75980c213802b1d4f3e81f74fb3b3
parent464cca35825a02541efd46cfd3af91146c118d01 (diff)
Abstract abstractification
-rw-r--r--inc/lib/hash.h (renamed from inc/hash.h)4
-rw-r--r--inc/lib/hashmap.h (renamed from inc/hashmap.h)4
-rw-r--r--inc/log.h4
-rw-r--r--inc/map.h14
-rw-r--r--inc/parse.h31
-rw-r--r--makefile3
-rw-r--r--src/lib/hash.c (renamed from src/hash.c)2
-rw-r--r--src/lib/hashmap.c (renamed from src/hashmap.c)4
-rw-r--r--src/main.c139
-rw-r--r--src/map.c53
-rw-r--r--src/parse.c85
11 files changed, 203 insertions, 140 deletions
diff --git a/inc/hash.h b/inc/lib/hash.h
index f0bb468..88b9215 100644
--- a/inc/hash.h
+++ b/inc/lib/hash.h
@@ -1,8 +1,8 @@
// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
// SPDX-License-Identifier: MIT
-#ifndef BLOC_HASH_H
-#define BLOC_HASH_H
+#ifndef CALM_HASH_H
+#define CALM_HASH_H
#include <stdint.h>
#include <stddef.h>
diff --git a/inc/hashmap.h b/inc/lib/hashmap.h
index b13b815..809ddca 100644
--- a/inc/hashmap.h
+++ b/inc/lib/hashmap.h
@@ -3,8 +3,8 @@
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
-#ifndef HASHMAP_H
-#define HASHMAP_H
+#ifndef CALM_HASHMAP_H
+#define CALM_HASHMAP_H
#include <stdbool.h>
#include <stddef.h>
diff --git a/inc/log.h b/inc/log.h
index 8d33658..846b4f5 100644
--- a/inc/log.h
+++ b/inc/log.h
@@ -1,8 +1,8 @@
// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
// SPDX-License-Identifier: MIT
-#ifndef BLOC_LOG_H
-#define BLOC_LOG_H
+#ifndef CALM_LOG_H
+#define CALM_LOG_H
void debug(const char *format, ...);
void debug_enable(int enable);
diff --git a/inc/map.h b/inc/map.h
new file mode 100644
index 0000000..427cee5
--- /dev/null
+++ b/inc/map.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#ifndef CALM_MAP_H
+#define CALM_MAP_H
+
+#include <lib/hash.h>
+
+struct term *map_get(hash_t hash);
+void map_set(struct term *term, hash_t hash);
+void map_initialize(void);
+void map_destroy(void);
+
+#endif
diff --git a/inc/parse.h b/inc/parse.h
new file mode 100644
index 0000000..dd25806
--- /dev/null
+++ b/inc/parse.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#ifndef CALM_PARSE_H
+#define CALM_PARSE_H
+
+#include <lib/hash.h>
+
+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;
+};
+
+hash_t parse_blc(char **term);
+
+#endif
diff --git a/makefile b/makefile
index 56e0fc8..c2acce0 100644
--- a/makefile
+++ b/makefile
@@ -7,7 +7,7 @@ TG = ctags
BUILD = ${CURDIR}/build
SRC = ${CURDIR}/src
INC = ${CURDIR}/inc
-SRCS = $(wildcard $(SRC)/*.c)
+SRCS = $(wildcard $(SRC)/*.c) $(wildcard $(SRC)/*/*.c)
OBJS = $(patsubst $(SRC)/%.c, $(BUILD)/%.o, $(SRCS))
CFLAGS_DEBUG = -Wno-error -g -O0 -Wno-unused -fsanitize=address,undefined,leak
@@ -39,6 +39,7 @@ sync: # Ugly hack
@$(TG) -R --exclude=.git --exclude=build .
$(BUILD)/%.o: $(SRC)/%.c
+ @mkdir -p $(@D)
@$(CC) -c -o $@ $(CFLAGS) $<
$(BUILD)/calm: $(OBJS)
diff --git a/src/hash.c b/src/lib/hash.c
index be8e369..392f79d 100644
--- a/src/hash.c
+++ b/src/lib/hash.c
@@ -11,7 +11,7 @@
#include <string.h>
-#include <hash.h>
+#include <lib/hash.h>
#define XXH_PRIME_1 11400714785074694791ULL
#define XXH_PRIME_2 14029467366897019727ULL
diff --git a/src/hashmap.c b/src/lib/hashmap.c
index 94b170d..7de7245 100644
--- a/src/hashmap.c
+++ b/src/lib/hashmap.c
@@ -11,8 +11,8 @@
#include <stdint.h>
#include <stddef.h>
-#include <hashmap.h>
-#include <hash.h>
+#include <lib/hashmap.h>
+#include <lib/hash.h>
#define GROW_AT 0.60
#define SHRINK_AT 0.10
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;
}
diff --git a/src/map.c b/src/map.c
new file mode 100644
index 0000000..411ba4e
--- /dev/null
+++ b/src/map.c
@@ -0,0 +1,53 @@
+// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <stdlib.h>
+
+#include <lib/hashmap.h>
+#include <map.h>
+#include <parse.h>
+
+static struct hashmap *all_terms;
+
+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);
+}
+
+struct term *map_get(hash_t hash)
+{
+ struct term **handle = hashmap_get(all_terms, hash);
+ if (!handle)
+ return 0;
+ return *handle;
+}
+
+void map_set(struct term *term, hash_t hash)
+{
+ hashmap_set(all_terms, &term, hash);
+}
+
+void map_initialize(void)
+{
+ all_terms = hashmap_new(sizeof(struct term *), 0, hashmap_free_term);
+}
+
+void map_destroy(void)
+{
+ hashmap_free(all_terms);
+}
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;
+}