summaryrefslogtreecommitdiff
path: root/tests/functions
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-14 23:59:54 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-14 23:59:54 +0000
commitdcfdc053cb5f9fb4d5eac0a2233c75126b7a8188 (patch)
treef34f30b382fa22d6fd0af46875a5b4b26d00feff /tests/functions
parenta918df69269a39ef7350a645b5db025d66ecb18a (diff)
Added some of the tests.
Diffstat (limited to 'tests/functions')
-rw-r--r--tests/functions/test_attributes.zc122
-rw-r--r--tests/functions/test_implicit_return.zc18
-rw-r--r--tests/functions/test_lambda_arrow.zc20
-rw-r--r--tests/functions/test_lambdas.zc78
-rw-r--r--tests/functions/test_must_use.zc47
-rw-r--r--tests/functions/test_varargs.zc10
6 files changed, 295 insertions, 0 deletions
diff --git a/tests/functions/test_attributes.zc b/tests/functions/test_attributes.zc
new file mode 100644
index 0000000..db77d89
--- /dev/null
+++ b/tests/functions/test_attributes.zc
@@ -0,0 +1,122 @@
+
+@must_use
+fn compute() -> int {
+ return 42;
+}
+
+@deprecated("Use new_version instead")
+fn old_function() {
+ "deprecated!";
+}
+
+@inline
+fn fast_add(a: int, b: int) -> int {
+ return a + b;
+}
+
+@must_use @inline
+fn combined() -> int {
+ return 100;
+}
+
+fn optional_result() -> int {
+ return 1;
+}
+
+@packed
+struct PackedHeader {
+ magic: U8;
+ version: U8;
+ size: U32;
+}
+
+@align(16)
+struct AlignedVec4 {
+ x: float;
+ y: float;
+ z: float;
+ w: float;
+}
+
+@packed @align(4)
+struct CombinedStruct {
+ flags: U8;
+ value: U16;
+}
+
+// Normal struct for comparison
+struct NormalStruct {
+ a: U8;
+ b: U32;
+}
+
+var init_called = 0;
+var cleanup_called = 0;
+
+@constructor
+fn my_init() {
+ init_called = 1;
+}
+
+@destructor
+fn my_cleanup() {
+ // We can't easily assert this ran in a test runner, but we can verify it compiles
+ cleanup_called = 1;
+}
+
+@noinline
+fn complex_calc(x: int) -> int {
+ return x * 2;
+}
+
+@section(".custom_section")
+fn section_func() {}
+
+@weak
+fn weak_func() {}
+
+@unused
+fn unused_func() {}
+
+test "function attributes" {
+ // @must_use: result used - no warning
+ var x = compute();
+ assert(x == 42, "compute() failed");
+
+ // No must_use - can discard
+ optional_result();
+
+ // @inline works
+ var sum = fast_add(1, 2);
+ assert(sum == 3, "inline add failed");
+
+ // Combined attributes
+ var c = combined();
+ assert(c == 100, "combined failed");
+
+ // @must_use: discarding should warn
+ compute();
+
+ // Check constructor ran
+ assert(init_called == 1, "Constructor attribute failed");
+
+ // Check noinline compiles and runs
+ assert(complex_calc(10) == 20, "Noinline function failed");
+
+ "Function attributes OK";
+}
+
+test "struct attributes" {
+ // @packed: no padding, should be 6 bytes
+ // (1 + 1 + 4 = 6)
+ // Without packing: 1 + 1 + 2(pad) + 4 = 8
+ assert(sizeof(PackedHeader) == 6, "PackedHeader should be 6 bytes");
+
+ // @align(16): aligned to 16 bytes
+ assert(sizeof(AlignedVec4) >= 16, "AlignedVec4 should be >= 16 bytes");
+
+ // Normal struct has padding
+ assert(sizeof(NormalStruct) == 8, "NormalStruct has padding");
+
+ "Struct attributes OK";
+}
diff --git a/tests/functions/test_implicit_return.zc b/tests/functions/test_implicit_return.zc
new file mode 100644
index 0000000..bb35134
--- /dev/null
+++ b/tests/functions/test_implicit_return.zc
@@ -0,0 +1,18 @@
+test "test_implicit_return" {
+ // Adds newline
+ "Hello Implicit";
+
+ // Adds newline
+ println "Hello Explicit";
+
+ // No newline
+ print "Loading";
+ print ".";
+ print ".";
+ println " Done!";
+
+ // With variables
+ var x = 42;
+ print "Value is: ";
+ println "{x}";
+}
diff --git a/tests/functions/test_lambda_arrow.zc b/tests/functions/test_lambda_arrow.zc
new file mode 100644
index 0000000..c976ecf
--- /dev/null
+++ b/tests/functions/test_lambda_arrow.zc
@@ -0,0 +1,20 @@
+
+fn compute(op: fn(I32, I32) -> I32, a: I32, b: I32) -> I32 {
+ return op(a, b);
+}
+
+test "test_lambda_arrow" {
+ var doubler = x -> x * 2;
+ var res1 = doubler(5);
+ "doubler(5) = {res1}";
+ if res1 != 10 { exit(1); }
+
+ var add = (x, y) -> x + y;
+ var res2 = add(10, 20);
+ "add(10, 20) = {res2}";
+ if res2 != 30 { exit(1); }
+
+ var res3 = compute((a, b) -> a * b, 3, 4);
+ "compute((a, b) -> a * b, 3, 4) = {res3}";
+ if res3 != 12 { exit(1); }
+}
diff --git a/tests/functions/test_lambdas.zc b/tests/functions/test_lambdas.zc
new file mode 100644
index 0000000..5f2c086
--- /dev/null
+++ b/tests/functions/test_lambdas.zc
@@ -0,0 +1,78 @@
+
+fn apply_twice(f: fn(I32) -> I32, x: I32) -> I32 {
+ return f(f(x));
+}
+
+fn make_adder(n: I32) -> fn(I32) -> I32 {
+ // Returns a lambda that captures 'n'
+ return x -> x + n;
+}
+
+test "test_complex_lambdas" {
+ println "Testing complex lambda scenarios...";
+
+ // Lambda with multiple parameters
+ var add_three = (a, b, c) -> a + b + c;
+ var res1 = add_three(1, 2, 3);
+ if (res1 == 6) {
+ println " -> Multi-param lambda: Passed";
+ } else {
+ println " -> Multi-param lambda: Failed";
+ exit(1);
+ }
+
+ // Higher-order function
+ var res2 = apply_twice(x -> x * 2, 5);
+ if (res2 == 20) {
+ println " -> Higher-order function: Passed";
+ } else {
+ println " -> Higher-order function: Failed";
+ exit(1);
+ }
+
+ // Returning a lambda (closure)
+ var add10 = make_adder(10);
+ var res3 = add10(5);
+ if (res3 == 15) {
+ println " -> Returned lambda: Passed";
+ } else {
+ println " -> Returned lambda: Failed";
+ exit(1);
+ }
+
+ // Lambda composition
+ var doubler = x -> x * 2;
+ var add5 = x -> x + 5;
+ var res4 = add5(doubler(10));
+ if (res4 == 25) {
+ println " -> Lambda composition: Passed";
+ } else {
+ println " -> Lambda composition: Failed";
+ exit(1);
+ }
+
+ // Nested application
+ var res5 = apply_twice(x -> x + 1, apply_twice(x -> x * 2, 3));
+ // (3 * 2) * 2 = 12, then (12 + 1) + 1 = 14
+ if (res5 == 14) {
+ println " -> Nested application: Passed";
+ } else {
+ println " -> Nested application: Failed";
+ exit(1);
+ }
+
+ println "All complex lambda tests passed!";
+
+
+}
+
+test "test_basic_closure" {
+ var whatever = 10;
+ var closure: fn(I32) -> I32 = x -> x + whatever;
+ var res = closure(5);
+ // "Result: {res}";
+ if (res != 15) {
+ println "Closure failed: expected 15, got {res}";
+ exit(1);
+ }
+}
diff --git a/tests/functions/test_must_use.zc b/tests/functions/test_must_use.zc
new file mode 100644
index 0000000..a42b341
--- /dev/null
+++ b/tests/functions/test_must_use.zc
@@ -0,0 +1,47 @@
+include <stdio.h>
+
+@must_use
+fn compute() -> int {
+ return 42;
+}
+
+@deprecated("Use new_version instead")
+fn old_function() {
+ "deprecated!";
+}
+
+@inline
+fn fast_add(a: int, b: int) -> int {
+ return a + b;
+}
+
+@must_use @inline
+fn combined() -> int {
+ return 100;
+}
+
+fn optional_result() -> int {
+ return 1;
+}
+
+test "attributes" {
+ // This should NOT warn (result used)
+ var x = compute();
+ assert(x == 42, "compute() should return 42");
+
+ // This should NOT warn (no must_use attribute)
+ optional_result();
+
+ // This SHOULD warn (result discarded on must_use function)
+ compute();
+
+ // Test inline works
+ var sum = fast_add(1, 2);
+ assert(sum == 3, "inline add failed");
+
+ // Combined attributes
+ var c = combined();
+ assert(c == 100, "combined failed");
+
+ "Attributes test completed";
+}
diff --git a/tests/functions/test_varargs.zc b/tests/functions/test_varargs.zc
new file mode 100644
index 0000000..b05e168
--- /dev/null
+++ b/tests/functions/test_varargs.zc
@@ -0,0 +1,10 @@
+//> link: -lm
+
+test "test_varargs" {
+ println "Testing Varargs...";
+ printf(" Direct Printf: %d, %f, %s\n", 42, 3.14, "Hello");
+
+ var buf = malloc(100);
+ sprintf(buf, "Formatted: %d", 123);
+ println " {buf}";
+}