From dcfdc053cb5f9fb4d5eac0a2233c75126b7a8188 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Wed, 14 Jan 2026 23:59:54 +0000 Subject: Added some of the tests. --- tests/functions/test_attributes.zc | 122 ++++++++++++++++++++++++++++++++ tests/functions/test_implicit_return.zc | 18 +++++ tests/functions/test_lambda_arrow.zc | 20 ++++++ tests/functions/test_lambdas.zc | 78 ++++++++++++++++++++ tests/functions/test_must_use.zc | 47 ++++++++++++ tests/functions/test_varargs.zc | 10 +++ 6 files changed, 295 insertions(+) create mode 100644 tests/functions/test_attributes.zc create mode 100644 tests/functions/test_implicit_return.zc create mode 100644 tests/functions/test_lambda_arrow.zc create mode 100644 tests/functions/test_lambdas.zc create mode 100644 tests/functions/test_must_use.zc create mode 100644 tests/functions/test_varargs.zc (limited to 'tests/functions') 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 + +@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}"; +} -- cgit v1.2.3