stage1 重制18测试用例替换成match 完成现有全部测试

This commit is contained in:
zzy
2026-07-11 21:24:52 +08:00
parent 147f26e063
commit 53ae30f1ca
9 changed files with 729 additions and 143 deletions

488
stage1/test18_match.spl Normal file
View File

@@ -0,0 +1,488 @@
/* ===== 模块4match 语句 =====
* test18_match — match 枚举匹配 + 整数匹配(类似 switch
* 难度3/5
* 验证点:枚举匹配、带数据绑定、结构体字段绑定、枚举指针、
* 整数自变量匹配、默认分支 _
*/
/* ---- 简单枚举(无数据) ---- */
type Color = enum {
Red;
Green;
Blue;
}
/* ---- 带 i32 数据的枚举 ---- */
type Optional = enum {
Some: i32;
None;
}
/* ---- 带结构体数据的枚举 ---- */
type Point = struct {
var x: i32;
var y: i32;
}
type Shape = enum {
Circle: i32;
Rect: Point;
}
/* ---- 多变体枚举 ---- */
type ActionResult = enum {
Success: i32;
NotFound;
Timeout: i32;
Error: *u8;
}
/* ============================================================
* 测试 1: 无数据枚举匹配
* ============================================================ */
fn test_color_match() i32 {
var c: Color = Color { .Red };
var val: i32 = 0;
match c {
.Red => { val = 1; },
.Green => { val = 2; },
.Blue => { val = 3; }
}
if val != 1 { ret 1; }
c = Color { .Green };
match c {
.Red => { val = 0; },
.Green => { val = 2; },
.Blue => { val = 0; }
}
if val != 2 { ret 2; }
c = Color { .Blue };
match c {
.Red => { val = 0; },
.Green => { val = 0; },
.Blue => { val = 3; }
}
if val != 3 { ret 3; }
ret 0;
}
/* ============================================================
* 测试 2: 带 i32 数据枚举匹配
* ============================================================ */
fn test_optional_match() i32 {
var o: Optional = Optional { .Some = 42 };
match o {
.Some(val) => {
if val != 42 { ret 1; }
},
.None => {
ret 2;
}
}
o = Optional { .None };
var is_none: i32 = 0;
match o {
.Some(val) => {},
.None => { is_none = 1; }
}
if is_none != 1 { ret 3; }
/* 多次提取不同值 */
o = Optional { .Some = 99 };
match o {
.Some(val) => {
if val != 99 { ret 4; }
},
.None => { ret 5; }
}
ret 0;
}
/* ============================================================
* 测试 3: 带结构体数据枚举匹配(多字段绑定)
* ============================================================ */
fn test_shape_match() i32 {
/* Circle: 单数据 */
var s: Shape = Shape { .Circle = 10 };
match s {
.Circle(r) => {
if r != 10 { ret 1; }
},
.Rect(w, h) => {
ret 2;
}
}
/* Rect: 结构体数据,绑定为 (x, y) 对应 Point 的字段 */
s = Shape { .Rect = Point { .x = 3, .y = 4 } };
match s {
.Circle(r) => { ret 3; },
.Rect(w, h) => {
if w != 3 { ret 4; }
if h != 4 { ret 5; }
}
}
ret 0;
}
/* ============================================================
* 测试 4: 多数据变体枚举匹配
* ============================================================ */
fn test_action_result_match() i32 {
var r: ActionResult = ActionResult { .Success = 200 };
match r {
.Success(code) => {
if code != 200 { ret 1; }
},
.NotFound => {
ret 2;
},
.Timeout(ms) => {
ret 3;
},
.Error(msg) => {
ret 4;
}
}
r = ActionResult { .NotFound };
var found: i32 = 1;
match r {
.Success(code) => { found = 0; },
.NotFound => { },
.Timeout(ms) => { found = 0; },
.Error(msg) => { found = 0; }
}
if found != 1 { ret 5; }
r = ActionResult { .Timeout = 5000 };
match r {
.Success(code) => { ret 6; },
.NotFound => { ret 7; },
.Timeout(ms) => {
if ms != 5000 { ret 8; }
},
.Error(msg) => { ret 9; }
}
ret 0;
}
/* ============================================================
* 测试 5: 枚举指针匹配
* ============================================================ */
fn test_ptr_match() i32 {
var c: Color = Color { .Green };
var p: *Color = &c;
match p {
.Red => { ret 1; },
.Green => { },
.Blue => { ret 2; }
}
/* 修改后通过指针匹配 */
c = Color { .Blue };
match p {
.Red => { ret 3; },
.Green => { ret 4; },
.Blue => { }
}
ret 0;
}
/* ============================================================
* 测试 6: match 作为函数返回值
* ============================================================ */
fn classify_color(c: Color) i32 {
match c {
.Red => { ret 1; },
.Green => { ret 2; },
.Blue => { ret 3; }
}
ret 0;
}
fn test_match_in_func() i32 {
var r: i32;
r = classify_color(Color { .Red });
if r != 1 { ret 1; }
r = classify_color(Color { .Green });
if r != 2 { ret 2; }
r = classify_color(Color { .Blue });
if r != 3 { ret 3; }
ret 0;
}
/* ============================================================
* 测试 7: match 嵌套在循环中
* ============================================================ */
fn test_match_in_loop() i32 {
var i: i32 = 0;
var sum: i32 = 0;
while i < 3 {
var o: Optional;
if i == 0 {
o = Optional { .Some = 10 };
} else if i == 1 {
o = Optional { .Some = 20 };
} else {
o = Optional { .Some = 30 };
}
match o {
.Some(val) => {
sum = sum + val;
},
.None => { }
}
i = i + 1;
}
if sum != 60 { ret 1; }
ret 0;
}
/* ============================================================
* 测试 8: 整数 match类似 switch
* ============================================================ */
fn test_int_match() i32 {
var x: i32 = 2;
var result: i32 = 0;
match x {
1 => { result = 10; },
2 => { result = 20; },
3 => { result = 30; }
}
if result != 20 { ret 1; }
/* 匹配第一个值 */
x = 1;
match x {
1 => { result = 100; },
2 => { result = 200; },
3 => { result = 300; }
}
if result != 100 { ret 2; }
/* 匹配最后一个值 */
x = 3;
match x {
1 => { result = 1000; },
2 => { result = 2000; },
3 => { result = 3000; }
}
if result != 3000 { ret 3; }
ret 0;
}
/* ============================================================
* 测试 9: 整数 match 带默认分支 _
* ============================================================ */
fn test_int_match_default() i32 {
var x: i32 = 99;
var result: i32 = 0;
match x {
1 => { result = 1; },
2 => { result = 2; },
_ => { result = 99; }
}
if result != 99 { ret 1; }
/* 默认分支未触发 */
x = 1;
match x {
1 => { result = 1; },
2 => { result = 2; },
_ => { result = 99; }
}
if result != 1 { ret 2; }
ret 0;
}
/* ============================================================
* 测试 10: 整数 match 多个值跳转到相同逻辑
* ============================================================ */
fn test_int_match_multi() i32 {
var x: i32 = 2;
var result: i32 = 0;
/* 每个分支独立 */
match x {
0 => { result = 0; },
1 => { result = 1; },
2 => { result = 2; },
3 => { result = 3; }
}
if result != 2 { ret 1; }
/* 负数和零 */
x = -1;
match x {
-1 => { result = -1; },
0 => { result = 0; },
1 => { result = 1; }
}
if result != -1 { ret 2; }
x = 0;
match x {
-1 => { result = -1; },
0 => { result = 0; },
1 => { result = 1; }
}
if result != 0 { ret 3; }
ret 0;
}
/* ============================================================
* 测试 11a: match 多值 fallthrough: 1, 2, 3 => body
* ============================================================ */
fn test_int_match_fallthrough() i32 {
var x: i32;
var r: i32;
/* 三个值映射到同一个 body */
x = 1; r = 0;
match x {
1, 2, 3 => { r = 10; },
4, 5 => { r = 20; }
}
if r != 10 { ret 1; }
x = 3;
match x {
1, 2, 3 => { r = 10; },
4, 5 => { r = 20; }
}
if r != 10 { ret 2; }
x = 5;
match x {
1, 2, 3 => { r = 10; },
4, 5 => { r = 20; }
}
if r != 20 { ret 3; }
/* 单一值(非fallthrough)仍然正常 */
x = 7; r = 0;
match x {
1 => { r = 1; },
7 => { r = 7; }
}
if r != 7 { ret 4; }
/* 多个负数值 */
x = -2; r = 0;
match x {
-3, -2, -1 => { r = 100; },
0, 1 => { r = 200; }
}
if r != 100 { ret 5; }
ret 0;
}
/* ============================================================
* 测试 11b: match with body 中修改变量
* ============================================================ */
fn test_match_with_side_effects() i32 {
var x: i32 = 3;
var acc: i32 = 0;
match x {
1 => { acc = acc + 1; },
2 => { acc = acc + 2; },
3 => { acc = acc + 3; },
4 => { acc = acc + 4; }
}
if acc != 3 { ret 1; }
/* 再次 match 同一个变量 */
match x {
1 => { acc = acc + 1; },
2 => { acc = acc + 2; },
3 => { acc = acc + 3; },
4 => { acc = acc + 4; }
}
if acc != 6 { ret 2; }
ret 0;
}
/* ============================================================
* 主函数
* ============================================================ */
fn main() i32 {
var r: i32;
r = test_color_match();
if r != 0 { ret r; }
r = test_optional_match();
if r != 0 { ret r + 10; }
r = test_shape_match();
if r != 0 { ret r + 20; }
r = test_action_result_match();
if r != 0 { ret r + 30; }
r = test_ptr_match();
if r != 0 { ret r + 40; }
r = test_match_in_func();
if r != 0 { ret r + 50; }
r = test_match_in_loop();
if r != 0 { ret r + 60; }
r = test_int_match();
if r != 0 { ret r + 70; }
r = test_int_match_default();
if r != 0 { ret r + 80; }
r = test_int_match_multi();
if r != 0 { ret r + 90; }
r = test_match_with_side_effects();
if r != 0 { ret r + 100; }
r = test_int_match_fallthrough();
if r != 0 { ret r + 110; }
ret 0;
}