// Copyright (c) 2023, Marvin Borner // SPDX-License-Identifier: MIT #include #include #include #include #include static size_t max_depth = 0; static struct term_handle abs_blc(char **term, size_t depth) { term_type_t res_type = ABS; struct term_handle inner = 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(map_all_terms(), res))) { term_refer_head(res_term, depth); } else { res_term = term_new(res_type, res, depth); res_term->u.abs.term = inner.term; // TODO: remove hash from map_set (already in term anyway) map_set(map_all_terms(), res_term); } map_set(res_term->u.abs.term->parents, res_term); return (struct term_handle){ .term = res_term, .hash = res }; } static struct term_handle app_blc(char **term, size_t depth) { term_type_t res_type = APP; struct term_handle lhs = parse_blc(term, depth + 1); struct term_handle rhs = 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(map_all_terms(), res))) { term_refer_head(res_term, depth); } else { res_term = term_new(res_type, res, depth); res_term->u.app.lhs = lhs.term; res_term->u.app.rhs = rhs.term; map_set(map_all_terms(), res_term); } map_set(res_term->u.app.lhs->parents, res_term); map_set(res_term->u.app.rhs->parents, res_term); return (struct term_handle){ .term = res_term, .hash = res }; } static struct term_handle var_blc(int index, size_t 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(map_all_terms(), res))) { term_refer_head(res_term, depth); } else { res_term = term_new(res_type, res, depth); res_term->u.var.index = index; map_set(map_all_terms(), res_term); } return (struct term_handle){ .term = res_term, .hash = res }; } int parse_get_max_depth(void) { return max_depth; } // TODO: bit parse_bblc // TODO: BLoC support (needs entry reference index sth two passes) struct term_handle parse_blc(char **term, size_t depth) { if (depth > max_depth) max_depth = depth; if (!**term) { fatal("invalid parsing state!\n"); } else if (**term == '0' && *(*term + 1) == '0') { (*term) += 2; return abs_blc(term, depth); } else if (**term == '0' && *(*term + 1) == '1') { (*term) += 2; return app_blc(term, depth); } else if (**term == '1') { const char *cur = *term; while (**term == '1') (*term)++; int index = *term - cur - 1; (*term)++; return var_blc(index, depth); } else { (*term)++; return parse_blc(term, depth); } }