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 | |
parent | 464cca35825a02541efd46cfd3af91146c118d01 (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.h | 4 | ||||
-rw-r--r-- | inc/map.h | 14 | ||||
-rw-r--r-- | inc/parse.h | 31 | ||||
-rw-r--r-- | makefile | 3 | ||||
-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.c | 139 | ||||
-rw-r--r-- | src/map.c | 53 | ||||
-rw-r--r-- | src/parse.c | 85 |
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> @@ -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 @@ -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 @@ -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; +} |