diff options
author | Marvin Borner | 2023-05-26 22:03:58 +0200 |
---|---|---|
committer | Marvin Borner | 2023-05-26 22:03:58 +0200 |
commit | d977a98fec7fcea74e7ab51762a6d93084a8c70c (patch) | |
tree | c44d2e0b2875b164530f7ea78205b20a049c8b5b | |
parent | 896e0e1bd8502a6d7f901f9e13bcd95df5d98635 (diff) |
Added depth
-rw-r--r-- | inc/parse.h | 4 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/parse.c | 126 |
3 files changed, 82 insertions, 50 deletions
diff --git a/inc/parse.h b/inc/parse.h index dd25806..c1e21b2 100644 --- a/inc/parse.h +++ b/inc/parse.h @@ -12,6 +12,7 @@ struct term { term_type_t type; hash_t hash; size_t refs; + size_t depth; union { struct { hash_t term; @@ -26,6 +27,7 @@ struct term { } u; }; -hash_t parse_blc(char **term); +hash_t parse_blc(char **term, int depth); +int parse_get_max_depth(void); #endif @@ -53,7 +53,7 @@ int main(int argc, char *argv[]) map_initialize(); char *orig_term = term; - parse_blc(&term); + parse_blc(&term, 1); free(orig_term); map_destroy(); diff --git a/src/parse.c b/src/parse.c index 55bcb86..24d2339 100644 --- a/src/parse.c +++ b/src/parse.c @@ -8,78 +8,108 @@ #include <map.h> #include <log.h> -static struct term *new_term(term_type_t type) +static int max_depth = 0; + +static struct term *new_term(term_type_t type, hash_t hash, int depth) { struct term *term = malloc(sizeof(*term)); if (!term) fatal("out of memory!\n"); term->type = type; + term->refs = 1; + term->hash = hash; + term->depth = depth; return term; } +static hash_t abs_blc(char **term, int depth) +{ + term_type_t res_type = ABS; + hash_t inner_hash = parse_blc(term, depth + 1); + hash_t res = hash((uint8_t *)&res_type, sizeof(res_type), inner_hash); + + struct term *res_term; + if ((res_term = map_get(res))) { + res_term->refs++; + res_term->depth = (res_term->depth + depth) / 2; + } else { + res_term = new_term(res_type, res, depth); + res_term->u.abs.term = inner_hash; + map_set(res_term, res); + } + + return res; +} + +static hash_t app_blc(char **term, int depth) +{ + term_type_t res_type = APP; + hash_t lhs_hash = parse_blc(term, depth + 1); + hash_t rhs_hash = parse_blc(term, depth + 1); + + hash_t res = hash((uint8_t *)&res_type, sizeof(res_type), lhs_hash); + res = hash((uint8_t *)&res, sizeof(res), rhs_hash); + + struct term *res_term; + if ((res_term = map_get(res))) { + res_term->refs++; + res_term->depth = (res_term->depth + depth) / 2; + } else { + res_term = new_term(res_type, res, depth); + res_term->u.app.lhs = lhs_hash; + res_term->u.app.rhs = rhs_hash; + map_set(res_term, res); + } + + return res; +} + +static hash_t var_blc(int index, int depth) +{ + term_type_t res_type = VAR; + hash_t res = hash((uint8_t *)&res_type, sizeof(res_type), index); + + struct term *res_term; + if ((res_term = map_get(res))) { + res_term->refs++; + res_term->depth = (res_term->depth + depth) / 2; + } else { + res_term = new_term(res_type, res, depth); + res_term->u.var.index = index; + map_set(res_term, res); + } + return res; +} + +int parse_get_max_depth(void) +{ + return max_depth; +} + // TODO: bit parse_bblc -hash_t parse_blc(char **term) +// TODO: BLoC support (needs entry reference index sth two passes) +hash_t parse_blc(char **term, int depth) { - hash_t res = 0; - struct term *res_term = 0; - term_type_t res_type = 0; + if (depth > max_depth) + max_depth = depth; 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); - } + return abs_blc(term, depth); } 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); - } + return app_blc(term, depth); } 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)++; + return var_blc(index, depth); } else { (*term)++; - res = parse_blc(term); + return parse_blc(term, depth); } - return res; } |