aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-05-06 18:48:56 +0200
committerMel <mel@rnrd.eu>2026-05-06 18:48:56 +0200
commitac696b22b3f03ae9670a9d1d154ce7ff848b5e55 (patch)
treee1f7ac3e1cd1f545d1ab0c1dc5c19130a9b23c5f
parent3850a7b311bca7bae925aeea456a41036f116ebd (diff)
downloadcatskill-ac696b22b3f03ae9670a9d1d154ce7ff848b5e55.tar.zst
catskill-ac696b22b3f03ae9670a9d1d154ce7ff848b5e55.zip
Tests for new IR transpiler
Signed-off-by: Mel <mel@rnrd.eu>
-rw-r--r--boot/tests/transpile/basic.cskt16
-rw-r--r--boot/tests/transpile/compound_assigns.cskt27
-rw-r--r--boot/tests/transpile/conditionals.cskt37
-rw-r--r--boot/tests/transpile/expressions.cskt27
-rw-r--r--boot/tests/transpile/functions.cskt49
-rw-r--r--boot/tests/transpile/loops.cskt43
-rw-r--r--boot/tests/transpile/types_and_aliases.cskt32
7 files changed, 227 insertions, 4 deletions
diff --git a/boot/tests/transpile/basic.cskt b/boot/tests/transpile/basic.cskt
index eb22b84..5844f94 100644
--- a/boot/tests/transpile/basic.cskt
+++ b/boot/tests/transpile/basic.cskt
@@ -1,7 +1,9 @@
-the transpiler has to follow a simple pattern of
-the files it creates to make viable c source.
-here we check that the simplest possible file has
-all of the expected parts needed.
+smoke test for the ir-driven transpiler: every translation
+unit starts with the core preamble, optionally declares types
+(forward + full def in topological order), then forward-decls
+all functions, then bodies, then the runtime trailer when a
+`main` is present. `main` is renamed to `catskill_main` so the
+runtime can wrap it.
<<<
@@ -9,3 +11,9 @@ main = fun () {
}
>>>
+
+#include "core.c"
+void catskill_main(void);
+void catskill_main(void) {
+}
+#include "runtime.c"
diff --git a/boot/tests/transpile/compound_assigns.cskt b/boot/tests/transpile/compound_assigns.cskt
new file mode 100644
index 0000000..e480f31
--- /dev/null
+++ b/boot/tests/transpile/compound_assigns.cskt
@@ -0,0 +1,27 @@
+compound assigns are desugared during lowering so the c output
+only ever has plain assignments.
+
+<<<
+
+main = fun () {
+ var x int = 0
+ x += 1
+ x *= 2
+ x++
+ x -= 3
+ x--
+}
+
+>>>
+
+#include "core.c"
+void catskill_main(void);
+void catskill_main(void) {
+ integer x = 0;
+ x = x + 1;
+ x = x * 2;
+ x = x + 1;
+ x = x - 3;
+ x = x - 1;
+}
+#include "runtime.c"
diff --git a/boot/tests/transpile/conditionals.cskt b/boot/tests/transpile/conditionals.cskt
new file mode 100644
index 0000000..96c3877
--- /dev/null
+++ b/boot/tests/transpile/conditionals.cskt
@@ -0,0 +1,37 @@
+if/else-if/else chains and nested conditionals emit as a single
+chained `if () { } else if () { } else { }` c block.
+
+<<<
+
+classify = fun (n int) int {
+ if n < 0 {
+ return -1
+ } else if n == 0 {
+ return 0
+ } else {
+ return 1
+ }
+}
+
+main = fun () {
+ classify(5)
+}
+
+>>>
+
+#include "core.c"
+integer classify(integer n);
+void catskill_main(void);
+integer classify(integer n) {
+ if (n < 0) {
+ return -1;
+ } else if (n == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+void catskill_main(void) {
+ classify(5);
+}
+#include "runtime.c"
diff --git a/boot/tests/transpile/expressions.cskt b/boot/tests/transpile/expressions.cskt
new file mode 100644
index 0000000..c127b9a
--- /dev/null
+++ b/boot/tests/transpile/expressions.cskt
@@ -0,0 +1,27 @@
+precedence-aware expression emission only inserts parentheses when the
+child binds more loosely than the parent expects.
+
+<<<
+
+main = fun () {
+ var a int = 1 + 2 * 3
+ var b int = (1 + 2) * 3
+ var c int = 10 - 4 - 1
+ var d int = 10 - (4 - 1)
+ var e int = -1 + 2
+ var f bool = a == b && c != 0 || d > 0
+}
+
+>>>
+
+#include "core.c"
+void catskill_main(void);
+void catskill_main(void) {
+ integer a = 1 + 2 * 3;
+ integer b = (1 + 2) * 3;
+ integer c = 10 - 4 - 1;
+ integer d = 10 - (4 - 1);
+ integer e = -1 + 2;
+ bool f = a == b && c != 0 || d > 0;
+}
+#include "runtime.c"
diff --git a/boot/tests/transpile/functions.cskt b/boot/tests/transpile/functions.cskt
new file mode 100644
index 0000000..889ffb3
--- /dev/null
+++ b/boot/tests/transpile/functions.cskt
@@ -0,0 +1,49 @@
+all function forwards land before any function body, so
+mutual recursion compiles without ordering games.
+`main` is renamed to `catskill_main` and wrapped by the
+runtime trailer to allow catskill programs to receive
+arguments using preferred types instead of the classic
+`argc` and `argv`.
+
+<<<
+
+is_even = fun (n int) bool {
+ if n == 0 {
+ return true
+ }
+ return is_odd(n - 1)
+}
+
+is_odd = fun (n int) bool {
+ if n == 0 {
+ return false
+ }
+ return is_even(n - 1)
+}
+
+main = fun () {
+ is_even(10)
+}
+
+>>>
+
+#include "core.c"
+bool is_even(integer n);
+bool is_odd(integer n);
+void catskill_main(void);
+bool is_even(integer n) {
+ if (n == 0) {
+ return true;
+ }
+ return is_odd(n - 1);
+}
+bool is_odd(integer n) {
+ if (n == 0) {
+ return false;
+ }
+ return is_even(n - 1);
+}
+void catskill_main(void) {
+ is_even(10);
+}
+#include "runtime.c"
diff --git a/boot/tests/transpile/loops.cskt b/boot/tests/transpile/loops.cskt
new file mode 100644
index 0000000..d6493d9
--- /dev/null
+++ b/boot/tests/transpile/loops.cskt
@@ -0,0 +1,43 @@
+while loops are 1:1; c-style and range for-each both desugar to
+a `{ var; while { body; iter; } }` block.
+
+<<<
+
+main = fun () {
+ var i int = 0
+ while i < 10 {
+ i++
+ }
+ for j int = 0, j < 5, j++ {
+ var k int = j
+ }
+ for r int = 0..3 {
+ var s int = r
+ }
+}
+
+>>>
+
+#include "core.c"
+void catskill_main(void);
+void catskill_main(void) {
+ integer i = 0;
+ while (i < 10) {
+ i = i + 1;
+ }
+ {
+ integer j = 0;
+ while (j < 5) {
+ integer k = j;
+ j = j + 1;
+ }
+ }
+ {
+ integer r = 0;
+ while (r < 3) {
+ integer s = r;
+ r = r + 1;
+ }
+ }
+}
+#include "runtime.c"
diff --git a/boot/tests/transpile/types_and_aliases.cskt b/boot/tests/transpile/types_and_aliases.cskt
new file mode 100644
index 0000000..cccc4e6
--- /dev/null
+++ b/boot/tests/transpile/types_and_aliases.cskt
@@ -0,0 +1,32 @@
+structures forward-declare then emit their full definition
+in topological dependency order.
+an alias to a struct emits as a c typedef.
+primitives are resolved to c directly on use.
+
+<<<
+
+Point = type { x int, y int }
+Node = type { value int, next &Node }
+Coord = type Point
+
+main = fun () {
+}
+
+>>>
+
+#include "core.c"
+struct Point;
+struct Node;
+struct Point {
+ integer x;
+ integer y;
+};
+struct Node {
+ integer value;
+ struct Node* next;
+};
+typedef struct Point Coord;
+void catskill_main(void);
+void catskill_main(void) {
+}
+#include "runtime.c"