aboutsummaryrefslogtreecommitdiff
path: root/src/impl
diff options
context:
space:
mode:
authorMarvin Borner2024-09-08 18:29:26 +0200
committerMarvin Borner2024-09-08 18:29:26 +0200
commit70179233d87c34b0f94521ba2752cda6ec77271d (patch)
treebc321d0d1ee095794f89a573b28f85722fd9a820 /src/impl
parentb517b450316ffd1b6ee9cb0c25085ff3b1d4b75b (diff)
Add translation mode and statisticsHEADmain
Diffstat (limited to 'src/impl')
-rw-r--r--src/impl/abs.c81
-rw-r--r--src/impl/abs_app_right.c104
-rw-r--r--src/impl/app_both.c112
-rw-r--r--src/impl/app_left.c89
-rw-r--r--src/impl/app_right.c89
-rw-r--r--src/impl/merged_abs.c0
-rw-r--r--src/impl/merged_app.c0
-rw-r--r--src/impl/merged_both.c0
8 files changed, 475 insertions, 0 deletions
diff --git a/src/impl/abs.c b/src/impl/abs.c
new file mode 100644
index 0000000..a6aa76d
--- /dev/null
+++ b/src/impl/abs.c
@@ -0,0 +1,81 @@
+// Copyright (c) 2024, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <log.h>
+#include <impl.h>
+
+static void encode(Term *term, FILE *fp)
+{
+ switch (term->type) {
+ case ABS:
+ while (1) {
+ fprintf(fp, "0");
+ if (term->u.abs.body->type != ABS)
+ break;
+ term = term->u.abs.body;
+ }
+ fprintf(fp, "01");
+ encode(term->u.abs.body, fp);
+ break;
+ case APP:
+ fprintf(fp, "01");
+ encode(term->u.app.lhs, fp);
+ encode(term->u.app.rhs, fp);
+ break;
+ case IDX:
+ for (size_t i = 0; i <= term->u.index; i++)
+ fprintf(fp, "1");
+ fprintf(fp, "0");
+ break;
+ default:
+ fatal("invalid type %d\n", term->type);
+ }
+}
+
+static Term *decode(FILE *fp)
+{
+ Term *res = 0;
+
+ char a = getc(fp);
+
+ if (a == '0') {
+ size_t count = 0;
+ while (getc(fp) == '0')
+ count++;
+
+ if (count == 0) {
+ res = term_new(APP);
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = decode(fp);
+ } else {
+ Term *head = term_new(ABS);
+
+ res = head;
+ for (size_t i = 0; i < count - 1; i++) {
+ res->u.abs.body = term_new(ABS);
+ res = res->u.abs.body;
+ }
+ res->u.abs.body = decode(fp);
+ res = head;
+ }
+ } else 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;
+}
+
+Impl impl_abs(void)
+{
+ return (Impl){
+ .name = "abs",
+ .encode = encode,
+ .decode = decode,
+ };
+}
diff --git a/src/impl/abs_app_right.c b/src/impl/abs_app_right.c
new file mode 100644
index 0000000..a346013
--- /dev/null
+++ b/src/impl/abs_app_right.c
@@ -0,0 +1,104 @@
+// Copyright (c) 2024, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <log.h>
+#include <impl.h>
+
+// my blc 3 for now!
+
+static void encode(Term *term, FILE *fp)
+{
+ switch (term->type) {
+ case ABS:
+ while (1) {
+ fprintf(fp, "0");
+ if (term->u.abs.body->type != ABS)
+ break;
+ term = term->u.abs.body;
+ }
+ fprintf(fp, "10");
+ encode(term->u.abs.body, fp);
+ break;
+ case APP:;
+ Term *stack[128] = { 0 }; // TODO: HEAP!
+ int stacked = 0;
+
+ while (1) {
+ fprintf(fp, "0");
+ stack[stacked++] = term->u.app.rhs;
+ term = term->u.app.lhs;
+ if (term->type != APP)
+ break;
+ }
+
+ fprintf(fp, "11");
+ encode(term, fp);
+ for (int i = stacked - 1; i >= 0; i--)
+ encode(stack[i], fp);
+ break;
+ case IDX:
+ for (size_t i = 0; i <= term->u.index; i++)
+ fprintf(fp, "1");
+ fprintf(fp, "0");
+ break;
+ default:
+ fatal("invalid type %d\n", term->type);
+ }
+}
+
+static Term *decode(FILE *fp)
+{
+ Term *res = 0;
+
+ char a = getc(fp);
+
+ if (a == '0') {
+ size_t count = 0;
+ while (getc(fp) == '0')
+ count++;
+
+ char b = getc(fp);
+
+ if (b == '0') {
+ Term *head = term_new(ABS);
+
+ res = head;
+ for (size_t i = 0; i < count; i++) {
+ res->u.abs.body = term_new(ABS);
+ res = res->u.abs.body;
+ }
+ res->u.abs.body = decode(fp);
+ res = head;
+ } else if (b == '1') {
+ res = term_new(APP);
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = decode(fp);
+
+ for (size_t i = 0; i < count; i++) {
+ Term *prev = res;
+ res = term_new(APP);
+ res->u.app.lhs = prev;
+ res->u.app.rhs = decode(fp);
+ }
+ }
+ } else 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;
+}
+
+Impl impl_abs_app_left(void)
+{
+ return (Impl){
+ .name = "abs_app_left",
+ .encode = encode,
+ .decode = decode,
+ };
+}
diff --git a/src/impl/app_both.c b/src/impl/app_both.c
new file mode 100644
index 0000000..47f78aa
--- /dev/null
+++ b/src/impl/app_both.c
@@ -0,0 +1,112 @@
+// Copyright (c) 2024, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <log.h>
+#include <impl.h>
+
+static void encode(Term *term, FILE *fp)
+{
+ switch (term->type) {
+ case ABS:
+ fprintf(fp, "01");
+ encode(term->u.abs.body, fp);
+ break;
+ case APP:
+ fprintf(fp, "0");
+
+ Term *stack[128] = { 0 }; // TODO: HEAP!
+ int stacked = 0;
+
+ // TODO: there's probably something here about finding optimal
+ // left/right folds but this is ok for now
+
+ int fold_right = term->u.app.rhs->type == APP;
+
+ while (1) {
+ fprintf(fp, "0");
+ stack[stacked++] =
+ fold_right ? term->u.app.lhs : term->u.app.rhs;
+ term = fold_right ? term->u.app.rhs : term->u.app.lhs;
+ if (term->type != APP)
+ break;
+ }
+
+ fprintf(fp, "1%d", fold_right);
+ if (fold_right) {
+ for (int i = 0; i < stacked; i++)
+ encode(stack[i], fp);
+ encode(term, fp);
+ } else {
+ encode(term, fp);
+ for (int i = stacked - 1; i >= 0; i--)
+ encode(stack[i], fp);
+ }
+ break;
+ case IDX:
+ for (size_t i = 0; i <= term->u.index; i++)
+ fprintf(fp, "1");
+ fprintf(fp, "0");
+ break;
+ default:
+ fatal("invalid type %d\n", term->type);
+ }
+}
+
+static Term *decode(FILE *fp)
+{
+ Term *res = 0;
+
+ char a = getc(fp);
+
+ if (a == '0') {
+ size_t count = 0;
+ while (getc(fp) == '0')
+ count++;
+
+ if (count == 0) {
+ res = term_new(ABS);
+ res->u.abs.body = decode(fp);
+ } else if (getc(fp) == '1') { // fold right
+ Term *head = term_new(APP);
+ res = head;
+ for (size_t i = 0; i < count - 1; i++) {
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = term_new(APP);
+ res = res->u.app.rhs;
+ }
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = decode(fp);
+ res = head;
+ } else { // fold left
+ res = term_new(APP);
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = decode(fp);
+
+ for (size_t i = 0; i < count - 1; i++) {
+ Term *prev = res;
+ res = term_new(APP);
+ res->u.app.lhs = prev;
+ res->u.app.rhs = decode(fp);
+ }
+ }
+ } else 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;
+}
+
+Impl impl_app_both(void)
+{
+ return (Impl){
+ .name = "app_both",
+ .encode = encode,
+ .decode = decode,
+ };
+}
diff --git a/src/impl/app_left.c b/src/impl/app_left.c
new file mode 100644
index 0000000..dcc62cd
--- /dev/null
+++ b/src/impl/app_left.c
@@ -0,0 +1,89 @@
+// Copyright (c) 2024, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <log.h>
+#include <impl.h>
+
+static void encode(Term *term, FILE *fp)
+{
+ switch (term->type) {
+ case ABS:
+ fprintf(fp, "01");
+ encode(term->u.abs.body, fp);
+ break;
+ case APP:
+ fprintf(fp, "0");
+
+ Term *stack[128] = { 0 }; // TODO: HEAP!
+ int stacked = 0;
+
+ while (1) {
+ fprintf(fp, "0");
+ stack[stacked++] = term->u.app.rhs;
+ term = term->u.app.lhs;
+ if (term->type != APP)
+ break;
+ }
+
+ fprintf(fp, "1");
+ encode(term, fp);
+ for (int i = stacked - 1; i >= 0; i--)
+ encode(stack[i], fp);
+ break;
+ case IDX:
+ for (size_t i = 0; i <= term->u.index; i++)
+ fprintf(fp, "1");
+ fprintf(fp, "0");
+ break;
+ default:
+ fatal("invalid type %d\n", term->type);
+ }
+}
+
+static Term *decode(FILE *fp)
+{
+ Term *res = 0;
+
+ char a = getc(fp);
+
+ if (a == '0') {
+ size_t count = 0;
+ while (getc(fp) == '0')
+ count++;
+
+ if (count == 0) {
+ res = term_new(ABS);
+ res->u.abs.body = decode(fp);
+ } else { // foldl1
+ res = term_new(APP);
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = decode(fp);
+
+ for (size_t i = 0; i < count - 1; i++) {
+ Term *prev = res;
+ res = term_new(APP);
+ res->u.app.lhs = prev;
+ res->u.app.rhs = decode(fp);
+ }
+ }
+ } else 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;
+}
+
+Impl impl_app_left(void)
+{
+ return (Impl){
+ .name = "app_left",
+ .encode = encode,
+ .decode = decode,
+ };
+}
diff --git a/src/impl/app_right.c b/src/impl/app_right.c
new file mode 100644
index 0000000..2583741
--- /dev/null
+++ b/src/impl/app_right.c
@@ -0,0 +1,89 @@
+// Copyright (c) 2024, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <log.h>
+#include <impl.h>
+
+static void encode(Term *term, FILE *fp)
+{
+ switch (term->type) {
+ case ABS:
+ fprintf(fp, "01");
+ encode(term->u.abs.body, fp);
+ break;
+ case APP:
+ fprintf(fp, "0");
+
+ Term *stack[128] = { 0 }; // TODO: HEAP!
+ int stacked = 0;
+
+ while (1) {
+ fprintf(fp, "0");
+ stack[stacked++] = term->u.app.lhs;
+ term = term->u.app.rhs;
+ if (term->type != APP)
+ break;
+ }
+
+ fprintf(fp, "1");
+ for (int i = 0; i < stacked; i++)
+ encode(stack[i], fp);
+ encode(term, fp);
+ break;
+ case IDX:
+ for (size_t i = 0; i <= term->u.index; i++)
+ fprintf(fp, "1");
+ fprintf(fp, "0");
+ break;
+ default:
+ fatal("invalid type %d\n", term->type);
+ }
+}
+
+static Term *decode(FILE *fp)
+{
+ Term *res = 0;
+
+ char a = getc(fp);
+
+ if (a == '0') {
+ size_t count = 0;
+ while (getc(fp) == '0')
+ count++;
+
+ if (count == 0) {
+ res = term_new(ABS);
+ res->u.abs.body = decode(fp);
+ } else {
+ Term *head = term_new(APP);
+ res = head;
+ for (size_t i = 0; i < count - 1; i++) {
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = term_new(APP);
+ res = res->u.app.rhs;
+ }
+ res->u.app.lhs = decode(fp);
+ res->u.app.rhs = decode(fp);
+ res = head;
+ }
+ } else 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;
+}
+
+Impl impl_app_right(void)
+{
+ return (Impl){
+ .name = "app_right",
+ .encode = encode,
+ .decode = decode,
+ };
+}
diff --git a/src/impl/merged_abs.c b/src/impl/merged_abs.c
deleted file mode 100644
index e69de29..0000000
--- a/src/impl/merged_abs.c
+++ /dev/null
diff --git a/src/impl/merged_app.c b/src/impl/merged_app.c
deleted file mode 100644
index e69de29..0000000
--- a/src/impl/merged_app.c
+++ /dev/null
diff --git a/src/impl/merged_both.c b/src/impl/merged_both.c
deleted file mode 100644
index e69de29..0000000
--- a/src/impl/merged_both.c
+++ /dev/null