aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.c19
-rw-r--r--src/main.c130
-rw-r--r--src/parse.c32
-rw-r--r--src/term.c29
4 files changed, 136 insertions, 74 deletions
diff --git a/src/build.c b/src/build.c
index fff5651..9fdcad4 100644
--- a/src/build.c
+++ b/src/build.c
@@ -67,12 +67,9 @@ static void write_bblc(struct tree *tree, FILE *file)
fwrite(&byte, 1, 1, file);
}
-void write_bloc(struct list *table, const char *path)
+static void write_bloc_file(struct list *table, FILE *file)
{
short length = table->val;
- debug("writing bloc with %ld elements to %s\n", length, path);
-
- FILE *file = fopen(path, "wb");
fwrite(BLOC_IDENTIFIER, BLOC_IDENTIFIER_LENGTH, 1, file);
fwrite(&length, 2, 1, file);
@@ -81,8 +78,14 @@ void write_bloc(struct list *table, const char *path)
write_bblc(iterator->data, file);
iterator = iterator->next;
}
+}
- fclose(file);
+void write_bloc(struct list *table, FILE *file)
+{
+ short length = table->val;
+ debug("writing bloc with %ld elements\n", length);
+
+ write_bloc_file(table, file);
}
static void fprint_bloc_blc(struct term *term, struct bloc_parsed *bloc,
@@ -115,12 +118,8 @@ static void fprint_bloc_blc(struct term *term, struct bloc_parsed *bloc,
}
}
-void write_blc(struct bloc_parsed *bloc, const char *path)
+void write_blc(struct bloc_parsed *bloc, FILE *file)
{
- FILE *file = fopen(path, "wb");
-
fprint_bloc_blc(bloc->entries[bloc->length - 1], bloc, file);
fprintf(file, "\n");
-
- fclose(file);
}
diff --git a/src/main.c b/src/main.c
index a5faa80..4258281 100644
--- a/src/main.c
+++ b/src/main.c
@@ -44,13 +44,8 @@ static char *read_stdin(void)
return string;
}
-static char *read_file(const char *path)
+static char *read_file(FILE *f)
{
- debug("reading from %s\n", path);
- FILE *f = fopen(path, "rb");
- if (!f)
- fatal("can't open file %s: %s\n", path, strerror(errno));
-
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
@@ -59,17 +54,104 @@ static char *read_file(const char *path)
if (!string)
fatal("out of memory!\n");
int ret = fread(string, fsize, 1, f);
- fclose(f);
if (ret != 1) {
free(string);
- fatal("can't read file %s: %s\n", path, strerror(errno));
+ fatal("can't read file: %s\n", strerror(errno));
}
string[fsize] = 0;
return string;
}
+static char *read_path(const char *path)
+{
+ debug("reading from %s\n", path);
+ FILE *f = fopen(path, "rb");
+ if (!f)
+ fatal("can't open file %s: %s\n", path, strerror(errno));
+ char *string = read_file(f);
+ fclose(f);
+ return string;
+}
+
+static void test(char *input)
+{
+ debug("parsing as blc\n");
+
+ struct term *parsed_1 = parse_blc(input);
+ free(input);
+ debug("parsed original blc\n");
+
+ debug("merging duplicates\n");
+ struct list *table = tree_merge_duplicates(parsed_1);
+
+ FILE *temp_bloc = tmpfile();
+ write_bloc(table, temp_bloc);
+ tree_destroy(table);
+
+ debug("parsing as bloc\n");
+ char *temp = read_file(temp_bloc);
+ struct bloc_parsed *bloc = parse_bloc(temp);
+ fseek(temp_bloc, 0, SEEK_END);
+ fprintf(stderr, "size bloc: %lu\n", ftell(temp_bloc));
+ fclose(temp_bloc);
+
+ FILE *temp_blc = tmpfile();
+ write_blc(bloc, temp_blc);
+ char *input_2 = read_file(temp_blc);
+ struct term *parsed_2 = parse_blc(input_2);
+ fseek(temp_blc, 0, SEEK_END);
+ fprintf(stderr, "size blc: ~%lu\n", ftell(temp_blc) / 8);
+ fclose(temp_blc);
+ free(input_2);
+ debug("parsed reconstructed blc\n");
+
+ diff_term(parsed_1, parsed_2);
+ debug("diffed two terms\n");
+
+ free_term(parsed_1);
+ free_term(parsed_2);
+ debug("done!\n");
+}
+
+static void from_blc(char *input, char *output_path)
+{
+ debug("parsing as blc\n");
+
+ struct term *parsed = parse_blc(input);
+ debug("parsed blc\n");
+
+ debug("merging duplicates\n");
+ struct list *table = tree_merge_duplicates(parsed);
+
+ FILE *file = fopen(output_path, "wb");
+ write_bloc(table, file);
+ fclose(file);
+
+ tree_destroy(table);
+ free_term(parsed);
+ free(input);
+
+ debug("done!\n");
+}
+
+static void from_bloc(char *input, char *output_path, int dump)
+{
+ debug("parsing as bloc\n");
+
+ struct bloc_parsed *bloc = parse_bloc(input);
+ if (dump)
+ print_bloc(bloc);
+
+ FILE *file = fopen(output_path, "wb");
+ write_blc(bloc, file);
+ fclose(file);
+
+ free(input);
+ free_bloc(bloc);
+}
+
int main(int argc, char **argv)
{
struct gengetopt_args_info args;
@@ -82,40 +164,24 @@ int main(int argc, char **argv)
if (args.input_arg[0] == '-') {
input = read_stdin();
} else {
- input = read_file(args.input_arg);
+ input = read_path(args.input_arg);
}
if (!input)
return 1;
- if (args.from_blc_flag && !args.from_bloc_flag) {
- debug("parsing as blc\n");
-
- struct term *parsed = parse_blc(input);
- debug("parsed blc\n");
-
- debug("merging duplicates\n");
- struct list *table = tree_merge_duplicates(parsed);
-
- write_bloc(table, args.output_arg);
-
- tree_destroy(table);
- free_term(parsed);
- free(input);
+ if (args.test_flag && args.from_blc_flag && !args.from_bloc_flag) {
+ test(input);
+ return 0;
+ }
- debug("done!\n");
+ if (args.from_blc_flag && !args.from_bloc_flag) {
+ from_blc(input, args.output_arg);
return 0;
}
if (args.from_bloc_flag && !args.from_blc_flag) {
- debug("parsing as bloc\n");
-
- struct bloc_parsed *bloc = parse_bloc(input);
- if (args.dump_flag)
- print_bloc(bloc);
- write_blc(bloc, args.output_arg);
- free(input);
- free_bloc(bloc);
+ from_bloc(input, args.output_arg, args.dump_flag);
return 0;
}
diff --git a/src/parse.c b/src/parse.c
index 9a8af45..f6e047d 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -120,35 +120,3 @@ void free_bloc(struct bloc_parsed *bloc)
free(bloc->entries);
free(bloc);
}
-
-static struct term *rec_bloc(struct term *term, struct bloc_parsed *bloc)
-{
- switch (term->type) {
- case ABS:
- rec_bloc(term->u.abs.term, bloc);
- break;
- case APP:
- rec_bloc(term->u.app.lhs, bloc);
- rec_bloc(term->u.app.rhs, bloc);
- break;
- case VAR:
- break;
- case REF:
- if (term->u.ref.index >= bloc->length)
- fatal("invalid entry reference\n");
- memcpy(term,
- bloc->entries[bloc->length - term->u.ref.index - 1],
- sizeof(*term));
- break;
- default:
- fatal("invalid type %d\n", term->type);
- return 0;
- }
- return term;
-}
-
-struct term *from_bloc(struct bloc_parsed *bloc)
-{
- struct term *last = bloc->entries[bloc->length - 1];
- return rec_bloc(last, bloc);
-}
diff --git a/src/term.c b/src/term.c
index 63bbb05..2ffc1c8 100644
--- a/src/term.c
+++ b/src/term.c
@@ -6,6 +6,7 @@
#include <string.h>
#include <term.h>
+#include <print.h>
#include <log.h>
struct term *new_term(term_type type)
@@ -39,3 +40,31 @@ void free_term(struct term *term)
fatal("invalid type %d\n", term->type);
}
}
+
+void diff_term(struct term *a, struct term *b)
+{
+ if (a->type != b->type) {
+ fprintf(stderr, "Term a: ");
+ print_bruijn(a);
+ fprintf(stderr, "\nTerm b: ");
+ print_bruijn(b);
+ fatal("\ntype mismatch %d %d\n", a->type, b->type);
+ }
+
+ switch (a->type) {
+ case ABS:
+ diff_term(a->u.abs.term, b->u.abs.term);
+ break;
+ case APP:
+ diff_term(a->u.app.lhs, b->u.app.lhs);
+ diff_term(a->u.app.rhs, b->u.app.rhs);
+ break;
+ case VAR:
+ if (a->u.var.index != b->u.var.index)
+ fatal("var mismatch %d=%d\n", a->u.var.index,
+ b->u.var.index);
+ break;
+ default:
+ fatal("invalid type %d\n", a->type);
+ }
+}