diff options
Diffstat (limited to 'src/parse.c')
-rw-r--r-- | src/parse.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..f2f89cd --- /dev/null +++ b/src/parse.c @@ -0,0 +1,66 @@ +// Copyright (c) 2024, Marvin Borner <dev@marvinborner.de> +// SPDX-License-Identifier: MIT + +#include <parse.h> +#include <log.h> +#include <term.h> + +Term *parse_blc_fp(FILE *fp) +{ + Term *res = 0; + + char a = getc(fp); + + if (a == '0') { + char b = getc(fp); + if (b == '0') { + res = term_new(ABS); + res->u.abs.body = parse_blc_fp(fp); + } + if (b == '1') { + res = term_new(APP); + res->u.app.lhs = parse_blc_fp(fp); + res->u.app.rhs = parse_blc_fp(fp); + } + } + + if (a == '1') { + res = term_new(IDX); + res->u.index = 0; + while (getc(fp) == '1') + res->u.index++; + } + + if (!res) + fatal("invalid parsing state!\n"); + + return res; +} + +Term *parse_blc(const char **term) +{ + Term *res = 0; + if (!**term) { + fatal("invalid parsing state!\n"); + } else if (**term == '0' && *(*term + 1) == '0') { + (*term) += 2; + res = term_new(ABS); + res->u.abs.body = parse_blc(term); + } else if (**term == '0' && *(*term + 1) == '1') { + (*term) += 2; + res = term_new(APP); + res->u.app.lhs = parse_blc(term); + res->u.app.rhs = parse_blc(term); + } else if (**term == '1') { + const char *cur = *term; + while (**term == '1') + (*term)++; + res = term_new(IDX); + res->u.index = *term - cur - 1; + (*term)++; + } else { + (*term)++; + res = parse_blc(term); + } + return res; +} |