diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 58 | ||||
-rw-r--r-- | src/parse.c | 52 | ||||
-rw-r--r-- | src/term.c | 23 | ||||
-rw-r--r-- | src/test.c | 9 |
4 files changed, 115 insertions, 27 deletions
@@ -2,12 +2,13 @@ #ifndef TEST #include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> -#define GC_PRINT_STATS 1 - -#include <parse.h> #include <reducer.h> #include <gc.h> +#include <parse.h> static void callback(int i, char ch, void *data) { @@ -17,24 +18,55 @@ static void callback(int i, char ch, void *data) /* printf("%d: %c\n", i, ch); */ } -int main(void) +static char *read_file(const char *path) +{ + FILE *f = fopen(path, "rb"); + if (!f) { + fprintf(stderr, "Can't open file %s: %s\n", path, + strerror(errno)); + return 0; + } + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *string = malloc(fsize + 1); + int ret = fread(string, fsize, 1, f); + fclose(f); + + if (ret != 1) { + fprintf(stderr, "Can't read file %s: %s\n", path, + strerror(errno)); + return 0; + } + + string[fsize] = 0; + return string; +} + +int main(int argc, char **argv) { GC_INIT(); GC_enable_incremental(); - // Benchmarking test for memory leaks and stack overflows, will probably not return: "([(((0 [[((0 1) 0)]]) [(0 0)]) 0)] [[(1 (1 0))]])" - struct term *term = - parse("([(((0 [[((0 1) 0)]]) [(0 0)]) 0)] [[(1 (1 0))]])"); + if (argc < 2) { + fprintf(stderr, "Invalid arguments\n"); + return 1; + } + + char *input = read_file(argv[1]); + if (!input) + return 1; - printf("\nReduced:\n"); - struct term *reduced = reduce(term, callback, 0); + struct term *parsed = parse_blc(input); + struct term *reduced = reduce(parsed, callback, 0); to_bruijn(reduced); - print_term(reduced); - printf("\n"); - free_term(term); + print_blc(reduced); free_term(reduced); + free_term(parsed); + free(input); return 0; } #else -static int testing; +__attribute__((unused)) static int testing; #endif diff --git a/src/parse.c b/src/parse.c index 33ca556..0b9fd82 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1,13 +1,11 @@ // Copyright (c) 2023, Marvin Borner <dev@marvinborner.de> -// Just for testing purposes -// -> parses custom bruijn syntax #include <stdio.h> #include <parse.h> #include <term.h> -static struct term *rec(const char **term) +static struct term *rec_bruijn(const char **term) { struct term *res = 0; if (!**term) { @@ -15,12 +13,12 @@ static struct term *rec(const char **term) } else if (**term == '[') { (*term)++; res = new_term(ABS); - res->u.abs.term = rec(term); + res->u.abs.term = rec_bruijn(term); } else if (**term == '(') { (*term)++; res = new_term(APP); - res->u.app.lhs = rec(term); - res->u.app.rhs = rec(term); + res->u.app.lhs = rec_bruijn(term); + res->u.app.rhs = rec_bruijn(term); } else if (**term >= '0' && **term <= '9') { res = new_term(VAR); res->u.var.name = **term - '0'; @@ -28,14 +26,50 @@ static struct term *rec(const char **term) (*term)++; } else { (*term)++; - res = rec(term); // this is quite tolerant.. + res = rec_bruijn(term); // this is quite tolerant.. } return res; } -struct term *parse(const char *term) +static struct term *rec_blc(const char **term) { - struct term *parsed = rec(&term); + struct term *res = 0; + if (!**term) { + fprintf(stderr, "invalid parsing state!\n"); + } else if (**term == '0' && *(*term + 1) == '0') { + (*term) += 2; + res = new_term(ABS); + res->u.abs.term = rec_blc(term); + } else if (**term == '0' && *(*term + 1) == '1') { + (*term) += 2; + res = new_term(APP); + res->u.app.lhs = rec_blc(term); + res->u.app.rhs = rec_blc(term); + } else if (**term == '1') { + const char *cur = *term; + while (**term == '1') + (*term)++; + res = new_term(VAR); + res->u.var.name = *term - cur - 1; + res->u.var.type = BRUIJN_INDEX; + (*term)++; + } else { + (*term)++; + res = rec_blc(term); // this is quite tolerant.. + } + return res; +} + +struct term *parse_bruijn(const char *term) +{ + struct term *parsed = rec_bruijn(&term); + to_barendregt(parsed); + return parsed; +} + +struct term *parse_blc(const char *term) +{ + struct term *parsed = rec_blc(&term); to_barendregt(parsed); return parsed; } @@ -196,6 +196,29 @@ void print_term(struct term *term) } } +void print_blc(struct term *term) +{ + switch (term->type) { + case ABS: + printf("00"); + print_blc(term->u.abs.term); + break; + case APP: + printf("01"); + print_blc(term->u.app.lhs); + print_blc(term->u.app.rhs); + break; + case VAR: + assert(term->u.var.type == BRUIJN_INDEX); + for (int i = 0; i <= term->u.var.name; i++) + printf("1"); + printf("0"); + break; + default: + fprintf(stderr, "Invalid type %d\n", term->type); + } +} + void print_scheme(struct term *term) { switch (term->type) { @@ -168,7 +168,7 @@ static void test_explode(void) deviations++; } - printf("Test explode ((n ω) x) with n<=%d: %.5fs, %d transition deviations\n", + printf("Test explode (λx.((n ω) x)) with n<=%d: %.5fs, %d transition deviations\n", limit, time, deviations); } @@ -205,7 +205,6 @@ static void callback(int i, char ch, void *data) fprintf(stderr, "Transition deviation at index %d!\n", i); test->equivalency.trans = 0; } - /* fprintf(stderr, "\n%d: %c\n", i, ch); */ } int main(void) @@ -227,11 +226,11 @@ int main(void) tests[i].trans = read_file(trans_template); char *in = read_file(in_template); - tests[i].in = parse(in); + tests[i].in = parse_bruijn(in); free(in); char *red = read_file(red_template); - tests[i].red = parse(red); + tests[i].red = parse_bruijn(red); to_bruijn(tests[i].red); free(red); @@ -270,5 +269,5 @@ int main(void) test_explode(); } #else -static int no_testing; +__attribute__((unused)) static int no_testing; #endif |