aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c58
-rw-r--r--src/parse.c52
-rw-r--r--src/term.c23
-rw-r--r--src/test.c9
4 files changed, 115 insertions, 27 deletions
diff --git a/src/main.c b/src/main.c
index 8c05b85..36ca46a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}
diff --git a/src/term.c b/src/term.c
index a88a2f7..cf66f01 100644
--- a/src/term.c
+++ b/src/term.c
@@ -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) {
diff --git a/src/test.c b/src/test.c
index c9023ea..c9bb3a6 100644
--- a/src/test.c
+++ b/src/test.c
@@ -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