diff options
| author | Mel <mel@rnrd.eu> | 2026-05-06 18:48:56 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2026-05-06 18:48:56 +0200 |
| commit | ac696b22b3f03ae9670a9d1d154ce7ff848b5e55 (patch) | |
| tree | e1f7ac3e1cd1f545d1ab0c1dc5c19130a9b23c5f /boot/tests/transpile | |
| parent | 3850a7b311bca7bae925aeea456a41036f116ebd (diff) | |
| download | catskill-ac696b22b3f03ae9670a9d1d154ce7ff848b5e55.tar.zst catskill-ac696b22b3f03ae9670a9d1d154ce7ff848b5e55.zip | |
Tests for new IR transpiler
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/tests/transpile')
| -rw-r--r-- | boot/tests/transpile/basic.cskt | 16 | ||||
| -rw-r--r-- | boot/tests/transpile/compound_assigns.cskt | 27 | ||||
| -rw-r--r-- | boot/tests/transpile/conditionals.cskt | 37 | ||||
| -rw-r--r-- | boot/tests/transpile/expressions.cskt | 27 | ||||
| -rw-r--r-- | boot/tests/transpile/functions.cskt | 49 | ||||
| -rw-r--r-- | boot/tests/transpile/loops.cskt | 43 | ||||
| -rw-r--r-- | boot/tests/transpile/types_and_aliases.cskt | 32 |
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" |
