summaryrefslogtreecommitdiff
path: root/tests/control_flow
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/control_flow
parenta918df69269a39ef7350a645b5db025d66ecb18a (diff)
Added some of the tests.
Diffstat (limited to 'tests/control_flow')
-rw-r--r--tests/control_flow/test_computed_goto.zc23
-rw-r--r--tests/control_flow/test_goto.zc22
-rw-r--r--tests/control_flow/test_guard_unless.zc59
-rw-r--r--tests/control_flow/test_if.zc20
-rw-r--r--tests/control_flow/test_labeled_break.zc27
-rw-r--r--tests/control_flow/test_loop_edge_cases.zc99
-rw-r--r--tests/control_flow/test_loops.zc133
-rw-r--r--tests/control_flow/test_match.zc91
-rw-r--r--tests/control_flow/test_ternary.zc30
9 files changed, 504 insertions, 0 deletions
diff --git a/tests/control_flow/test_computed_goto.zc b/tests/control_flow/test_computed_goto.zc
new file mode 100644
index 0000000..12b484c
--- /dev/null
+++ b/tests/control_flow/test_computed_goto.zc
@@ -0,0 +1,23 @@
+
+test "test_computed_goto" -> int {
+ var x = 0;
+
+ // Get address of label using && unary operator
+ var target = &&label_B;
+
+ // Jump to label A first
+ goto label_A;
+
+ label_A:
+ x = x + 1;
+ // Computed goto: goto *ptr
+ goto *target;
+
+ label_B:
+ x = x + 10;
+ goto label_C;
+
+ label_C:
+ if (x != 11) exit(1);
+
+}
diff --git a/tests/control_flow/test_goto.zc b/tests/control_flow/test_goto.zc
new file mode 100644
index 0000000..9a90139
--- /dev/null
+++ b/tests/control_flow/test_goto.zc
@@ -0,0 +1,22 @@
+
+test "test_goto" -> int {
+ var x = 0;
+
+ goto skip;
+ x = 100;
+
+skip:
+ assert x == 0;
+
+ var resource = 1;
+
+ if resource == 1 {
+ goto cleanup;
+ }
+
+ assert false;
+
+cleanup:
+ assert true;
+
+}
diff --git a/tests/control_flow/test_guard_unless.zc b/tests/control_flow/test_guard_unless.zc
new file mode 100644
index 0000000..d759551
--- /dev/null
+++ b/tests/control_flow/test_guard_unless.zc
@@ -0,0 +1,59 @@
+
+fn check_positive(x: int) -> int {
+ unless x > 0 {
+ return -1;
+ }
+ return x * 2;
+}
+
+fn safe_access(ptr: int*) -> int {
+ guard ptr != NULL else {
+ return -999;
+ }
+ return *ptr;
+}
+
+test "test_guard_unless" {
+ println "Testing guard and unless...";
+
+ // Unless with true condition (should NOT enter block)
+ var res1 = check_positive(10);
+ if (res1 == 20) {
+ println " -> unless (pass condition): Passed";
+ } else {
+ println " -> unless (pass condition): Failed";
+ exit(1);
+ }
+
+ // Unless with false condition (should enter block)
+ var res2 = check_positive(-5);
+ if (res2 == -1) {
+ println " -> unless (fail condition): Passed";
+ } else {
+ println " -> unless (fail condition): Failed";
+ exit(1);
+ }
+
+ // Guard with valid pointer
+ var val = 42;
+ var p = &val;
+ var res3 = safe_access(p);
+ if (res3 == 42) {
+ println " -> guard (valid ptr): Passed";
+ } else {
+ println " -> guard (valid ptr): Failed";
+ exit(1);
+ }
+
+ // Guard with null pointer
+ var res4 = safe_access(NULL);
+ if (res4 == -999) {
+ println " -> guard (null ptr): Passed";
+ } else {
+ println " -> guard (null ptr): Failed";
+ exit(1);
+ }
+
+ println "All guard/unless tests passed!";
+
+}
diff --git a/tests/control_flow/test_if.zc b/tests/control_flow/test_if.zc
new file mode 100644
index 0000000..463405a
--- /dev/null
+++ b/tests/control_flow/test_if.zc
@@ -0,0 +1,20 @@
+
+test "test_if" {
+ var x = 10;
+
+ if (x > 5) {
+ printf("X is big\n");
+ var y = x * 2;
+ if (y > 15) {
+ printf("Y is very big\n");
+ }
+ } else {
+ printf("X is small\n");
+ }
+
+ var i = 0;
+ while (i < 3) {
+ println "Loop {i}";
+ i++;
+ }
+}
diff --git a/tests/control_flow/test_labeled_break.zc b/tests/control_flow/test_labeled_break.zc
new file mode 100644
index 0000000..1900a99
--- /dev/null
+++ b/tests/control_flow/test_labeled_break.zc
@@ -0,0 +1,27 @@
+
+test "test_labeled_break" -> int {
+ // Test basic goto-based loop exit
+ var result = 0;
+
+ for i in 0..10 {
+ for j in 0..10 {
+ if i == 3 {
+ goto done_search;
+ }
+ }
+ result++;
+ }
+done_search:
+
+ assert result == 3;
+
+ // Test do-while
+ var x = 0;
+ do {
+ x++;
+ } while x < 3;
+
+ assert x == 3;
+
+
+}
diff --git a/tests/control_flow/test_loop_edge_cases.zc b/tests/control_flow/test_loop_edge_cases.zc
new file mode 100644
index 0000000..b5ab0ce
--- /dev/null
+++ b/tests/control_flow/test_loop_edge_cases.zc
@@ -0,0 +1,99 @@
+
+test "test_loop_edge_cases" {
+ println "Testing loop edge cases...";
+
+ // Empty range (0..0 should not iterate)
+ var count1 = 0;
+ for i in 0..0 {
+ count1++;
+ }
+ if (count1 == 0) {
+ println " -> Empty range (0..0): Passed";
+ } else {
+ println " -> Empty range (0..0): Failed";
+ exit(1);
+ }
+
+ // Single iteration range (0..1)
+ var count2 = 0;
+ for i in 0..1 {
+ count2++;
+ }
+ if (count2 == 1) {
+ println " -> Single iteration (0..1): Passed";
+ } else {
+ println " -> Single iteration (0..1): Failed";
+ exit(1);
+ }
+
+ // Repeat 0 times (should not execute)
+ var count3 = 0;
+ repeat 0 {
+ count3++;
+ }
+ if (count3 == 0) {
+ println " -> Repeat 0 times: Passed";
+ } else {
+ println " -> Repeat 0 times: Failed";
+ exit(1);
+ }
+
+ // Repeat 1 time
+ var count4 = 0;
+ repeat 1 {
+ count4++;
+ }
+ if (count4 == 1) {
+ println " -> Repeat 1 time: Passed";
+ } else {
+ println " -> Repeat 1 time: Failed";
+ exit(1);
+ }
+
+ // Nested loops
+ var total = 0;
+ for i in 0..3 {
+ for j in 0..2 {
+ total = total + 1;
+ }
+ }
+ if (total == 6) {
+ println " -> Nested for-in loops: Passed";
+ } else {
+ println " -> Nested for-in loops: Failed";
+ exit(1);
+ }
+
+ // Break in nested loop
+ var outer_count = 0;
+ for i in 0..3 {
+ outer_count = outer_count + 1;
+ var inner_done = 0;
+ loop {
+ inner_done = inner_done + 1;
+ if (inner_done >= 2) {
+ break;
+ }
+ }
+ }
+ if (outer_count == 3) {
+ println " -> Nested loop with break: Passed";
+ } else {
+ println " -> Nested loop with break: Failed";
+ exit(1);
+ }
+
+ // Large step value
+ var count7 = 0;
+ for i in 0..100 step 25 {
+ count7++;
+ }
+ if (count7 == 4) {
+ println " -> Large step value (step 25): Passed";
+ } else {
+ println " -> Large step value: Failed";
+ exit(1);
+ }
+
+ println "All loop edge cases passed!";
+}
diff --git a/tests/control_flow/test_loops.zc b/tests/control_flow/test_loops.zc
new file mode 100644
index 0000000..9968cf5
--- /dev/null
+++ b/tests/control_flow/test_loops.zc
@@ -0,0 +1,133 @@
+
+test "test_loops" {
+ println "Testing loop constructs...";
+
+ // for-in range
+ var sum1 = 0;
+ for i in 0..5 {
+ sum1 += i;
+ }
+ assert(sum1 == 10, "for-in range (0..5) failed");
+ println " -> for-in range (0..5): Passed";
+
+ // for-in with step
+ var sum2 = 0;
+ for i in 0..10 step 2 {
+ sum2 += i;
+ }
+ assert(sum2 == 20, "for-in with step failed");
+ println " -> for-in with step: Passed";
+
+ // Repeat n times
+ var count = 0;
+ repeat 7 {
+ count++;
+ }
+ assert(count == 7, "repeat 7 failed");
+ println " -> repeat 7: Passed";
+
+ // loop with break
+ var i = 0;
+ loop {
+ i++;
+ if (i >= 5) {
+ break;
+ }
+ }
+ assert(i == 5, "loop with break failed");
+ println " -> loop with break: Passed";
+
+ // While loop
+ var j = 0;
+ while j < 3 {
+ j++;
+ }
+ assert(j == 3, "while loop failed");
+ println " -> while loop: Passed";
+
+ // C-style for loop
+ var sum3 = 0;
+ for (var k = 0; k < 4; k = k + 1) {
+ sum3 += k;
+ }
+ assert(sum3 == 6, "C-style for loop failed");
+ println " -> C-style for loop: Passed";
+
+ // loop with continue
+ var sum4 = 0;
+ var m = 0;
+ loop {
+ m++;
+ if (m == 3) {
+ continue;
+ }
+ if (m > 5) {
+ break;
+ }
+ sum4 += m;
+ }
+ assert(sum4 == 12, "loop with continue failed");
+ println " -> loop with continue: Passed";
+
+ println "All loop tests passed!";
+
+}
+
+}
+
+fn print_nums(list: [int]) {
+ var i = 0;
+ while (i < list.len) {
+ println "Num: {list.data[i]}";
+ i++;
+ }
+}
+
+test "test_arrays_loop" {
+ // Array literal transformation
+ var nums: [int] = [10, 20, 30];
+ print_nums(nums);
+}
+
+test "test_do_while" {
+ var x = 0;
+
+ // Basic do-while (runs at least once)
+ do {
+ x++;
+ } while x < 5;
+
+ assert(x == 5, "do-while x expected 5");
+
+ // Do-while with false condition (still runs once)
+ var y = 0;
+ do {
+ y = 100;
+ } while false;
+
+ assert(y == 100, "do-while false expected 100");
+}
+
+test "test_range_loops_generic" {
+ println "Testing range loops with different types...";
+
+ // Test with isize variables
+ var sum_isize: isize = 0;
+ var start: isize = 0;
+ var end: isize = 5;
+ for var i: isize = start; i < end; i++ {
+ sum_isize += i;
+ }
+ println "isize range (0..5): sum = {sum_isize}";
+ assert(sum_isize == 10, "isize range failed");
+
+ // Test with regular int
+ var sum_int = 0;
+ for i in 0..5 {
+ sum_int += i;
+ }
+ println "int range (0..5): sum = {sum_int}";
+ assert(sum_int == 10, "int range failed");
+
+ "-> Range loops work with any integer type!";
+}
diff --git a/tests/control_flow/test_match.zc b/tests/control_flow/test_match.zc
new file mode 100644
index 0000000..7646256
--- /dev/null
+++ b/tests/control_flow/test_match.zc
@@ -0,0 +1,91 @@
+
+fn classify_number(n: int) -> int {
+ match n {
+ 0 => { return 100; },
+ 1 => { return 200; },
+ 2 => { return 300; },
+ _ => { return -1; }
+ }
+}
+
+fn get_sign(n: int) -> string {
+ match n {
+ 0 => { return "zero"; },
+ _ => {
+ if (n > 0) {
+ return "positive";
+ }
+ return "negative";
+ }
+ }
+}
+
+test "test_match" {
+ println "Testing match expressions...";
+
+ // Match with exact value (0)
+ var res1 = classify_number(0);
+ if (res1 == 100) {
+ println " -> match 0: Passed";
+ } else {
+ println " -> match 0: Failed";
+ exit(1);
+ }
+
+ // Match with exact value (1)
+ var res2 = classify_number(1);
+ if (res2 == 200) {
+ println " -> match 1: Passed";
+ } else {
+ println " -> match 1: Failed";
+ exit(1);
+ }
+
+ // Match with exact value (2)
+ var res3 = classify_number(2);
+ if (res3 == 300) {
+ println " -> match 2: Passed";
+ } else {
+ println " -> match 2: Failed";
+ exit(1);
+ }
+
+ // Match with default case
+ var res4 = classify_number(99);
+ if (res4 == -1) {
+ println " -> match default: Passed";
+ } else {
+ println " -> match default: Failed";
+ exit(1);
+ }
+
+ // Match with complex body (zero)
+ var sign1 = get_sign(0);
+ if (strcmp(sign1, "zero") == 0) {
+ println " -> match complex (zero): Passed";
+ } else {
+ println " -> match complex (zero): Failed";
+ exit(1);
+ }
+
+ // Match with complex body (positive)
+ var sign2 = get_sign(42);
+ if (strcmp(sign2, "positive") == 0) {
+ println " -> match complex (positive): Passed";
+ } else {
+ println " -> match complex (positive): Failed";
+ exit(1);
+ }
+
+ // Match with complex body (negative)
+ var sign3 = get_sign(-10);
+ if (strcmp(sign3, "negative") == 0) {
+ println " -> match complex (negative): Passed";
+ } else {
+ println " -> match complex (negative): Failed";
+ exit(1);
+ }
+
+ println "All match tests passed!";
+
+}
diff --git a/tests/control_flow/test_ternary.zc b/tests/control_flow/test_ternary.zc
new file mode 100644
index 0000000..cfac28b
--- /dev/null
+++ b/tests/control_flow/test_ternary.zc
@@ -0,0 +1,30 @@
+
+enum Result {
+ Ok(int),
+ Err(int)
+}
+
+fn test_unwrap() -> Result {
+ var res = Result_Ok(42);
+ var val = res?;
+ if (val == 42) println " Unwrap: Success";
+ else println " Unwrap: Failed";
+ return res;
+}
+
+test "test_ternary" {
+ println "Testing Ternary...";
+
+ // Simple Ternary
+ var x = 1 ? 10 : 20;
+ if (x == 10) println " Simple Ternary: Success";
+ else println " Simple Ternary: Failed";
+
+ // Simple Unwrap
+ test_unwrap();
+
+ // Ambiguity / Precredence
+ // 1 ? 2 : 3
+ var y = 0 ? 100 : 200;
+ if (y == 200) println " False Branch: Success";
+}