ReviewOS

also looking at this

home-lang/home

fix(interpreter): match range and or patterns in match statements

#930
Open mkantautas wants to merge fix/interpreter-range-or-patterns into main
2 files +90 -0
packages/interpreter/tests/program_eval_test.zigmodified+66-0
Changes to packages/interpreter/tests/program_eval_test.zig
@@ -75,6 +75,72 @@ test "eval: multiple statements and a returning function" {
7575 );
7676}
7777
78test "eval: match statement range and or patterns" {
79 try runProgram(
80 \\fn classify(x: int): int {
81 \\ match x {
82 \\ 0..=9 => return 1,
83 \\ 10..20 => return 2,
84 \\ 30 | 40 => return 3,
85 \\ 60 | 70..=75 => return 4,
86 \\ 50 => return 5,
87 \\ n if n > 100 => return n,
88 \\ _ => return 0,
89 \\ }
90 \\ return -1
91 \\}
92 \\
93 \\fn main() {
94 \\ assert(classify(0) == 1)
95 \\ assert(classify(9) == 1)
96 \\ assert(classify(10) == 2)
97 \\ assert(classify(19) == 2)
98 \\ assert(classify(20) == 0)
99 \\ assert(classify(30) == 3)
100 \\ assert(classify(40) == 3)
101 \\ assert(classify(41) == 0)
102 \\ assert(classify(60) == 4)
103 \\ assert(classify(75) == 4)
104 \\ assert(classify(76) == 0)
105 \\ assert(classify(50) == 5)
106 \\ assert(classify(101) == 101)
107 \\ assert(classify(-1) == 0)
108 \\}
109 );
110}
111
112test "eval: failed or-pattern alternatives leave no bindings" {
113 try runProgram(
114 \\struct P {
115 \\ a: int,
116 \\ b: int,
117 \\}
118 \\
119 \\fn after_failed_alternatives(p: P): int {
120 \\ let x = 99
121 \\ match p {
122 \\ P { a: x, b: 0 } | P { a: x, b: 3 } => return -1,
123 \\ _ => return x,
124 \\ }
125 \\ return -2
126 \\}
127 \\
128 \\fn from_matching_alternative(p: P): int {
129 \\ match p {
130 \\ P { a: y, b: 0 } | P { a: y, b: 2 } => return y,
131 \\ _ => return -1,
132 \\ }
133 \\ return -2
134 \\}
135 \\
136 \\fn main() {
137 \\ let p = P { a: 1, b: 2 }
138 \\ assert(after_failed_alternatives(p) == 99)
139 \\ assert(from_matching_alternative(p) == 1)
140 \\}
141 );
142}
143
78144test "eval: finite recursive calls remain valid" {
79145 try runProgram(
80146 \\fn countdown(n: i32): i32 {