216 lines
4.6 KiB
Plaintext
216 lines
4.6 KiB
Plaintext
/* ===== 模块5:复合类型 =====
|
||
* test10_struct — 结构体
|
||
* 难度:2/5
|
||
* 验证点:struct 定义、字段访问、内联 type、嵌套结构体
|
||
*/
|
||
type Pair = struct {
|
||
a: i32,
|
||
b: i32,
|
||
}
|
||
|
||
type Three = struct {
|
||
a: i64,
|
||
b: i64,
|
||
c: i64,
|
||
}
|
||
|
||
type Tag = enum {
|
||
Unknown,
|
||
BlockComment,
|
||
LineComment,
|
||
Ident,
|
||
Number,
|
||
}
|
||
|
||
type Token = struct {
|
||
loc_start: i32,
|
||
loc_end: i32,
|
||
tag: Tag,
|
||
}
|
||
|
||
fn make_three(a: i64, b: i64, c: i64) Three {
|
||
ret Three { .a = a, .b = b, .c = c };
|
||
}
|
||
|
||
fn sum_three(t: Three) i64 {
|
||
ret t.a + t.b + t.c;
|
||
}
|
||
|
||
fn make_token(s: i32, e: i32, t: Tag) Token {
|
||
ret Token { .loc_start = s, .loc_end = e, .tag = t };
|
||
}
|
||
|
||
fn test_ret_enum_struct() i32 {
|
||
var tok := make_token(10, 20, Tag.BlockComment);
|
||
if tok.loc_start != 10 { ret 1; }
|
||
if tok.loc_end != 20 { ret 2; }
|
||
if tok.tag != Tag.BlockComment { ret 3; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_nested_ret_enum() i32 {
|
||
var tok := make_token(1, 5, Tag.Ident);
|
||
if tok.tag != Tag.Ident { ret 1; }
|
||
var tok2 := make_token(6, 9, Tag.Number);
|
||
if tok2.tag != Tag.Number { ret 2; }
|
||
if tok.tag != Tag.Ident { ret 3; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_copy_token() i32 {
|
||
var tok := make_token(0, 100, Tag.LineComment);
|
||
var c := tok;
|
||
if c.loc_start != 0 { ret 1; }
|
||
if c.tag != Tag.LineComment { ret 2; }
|
||
c.tag = Tag.Ident;
|
||
if tok.tag != Tag.LineComment { ret 3; }
|
||
if c.tag != Tag.Ident { ret 4; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_pass_token(t: Token) i32 {
|
||
if t.tag != Tag.Number { ret 1; }
|
||
if t.loc_start != 42 { ret 2; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_param_pass_token() i32 {
|
||
var tok := make_token(42, 99, Tag.Number);
|
||
var r := test_pass_token(tok);
|
||
if r != 0 { ret r; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_get_tag(tok: Token) i32 {
|
||
ret tok.tag;
|
||
}
|
||
|
||
fn test_chain_func_call() i32 {
|
||
var tok := make_token(1, 2, Tag.BlockComment);
|
||
var tg := test_get_tag(tok);
|
||
if tg != Tag.BlockComment { ret 1; }
|
||
var tok2 := make_token(3, 4, Tag.LineComment);
|
||
var tg2 := test_get_tag(tok2);
|
||
if tg2 != Tag.LineComment { ret 2; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_ret_multi_slot_struct() i32 {
|
||
var t := make_three(10, 20, 30);
|
||
if t.a != 10 { ret 1; }
|
||
if t.b != 20 { ret 2; }
|
||
if t.c != 30 { ret 3; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_pass_struct_by_value() i32 {
|
||
var t := make_three(10, 20, 30);
|
||
var sum := sum_three(t);
|
||
if sum != 60 { ret 1; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_copy_struct() i32 {
|
||
var t := make_three(10, 20, 30);
|
||
var t2: Three;
|
||
t2 = t;
|
||
if t2.a != 10 { ret 1; }
|
||
t2.a = 99;
|
||
if t.a != 10 { ret 2; }
|
||
if t2.a != 99 { ret 3; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_multi_calls() i32 {
|
||
var ta := make_three(5, 10, 15);
|
||
var tb := make_three(20, 25, 30);
|
||
if ta.a + ta.b + ta.c != 30 { ret 1; }
|
||
if tb.a + tb.b + tb.c != 75 { ret 2; }
|
||
ret 0;
|
||
}
|
||
|
||
fn test_literal_arg() i32 {
|
||
var sum := sum_three(Three { .a = 7, .b = 8, .c = 9 });
|
||
if sum != 24 { ret 1; }
|
||
ret 0;
|
||
}
|
||
|
||
fn main() i32 {
|
||
/* struct 字段访问 */
|
||
var p: Pair;
|
||
p.a = 1;
|
||
p.b = 2;
|
||
if p.a != 1 { ret 1; }
|
||
if p.b != 2 { ret 2; }
|
||
|
||
/* 同一类型复用 */
|
||
var p2: Pair;
|
||
p2.a = 10;
|
||
p2.b = 20;
|
||
if p2.a + p2.b != 30 { ret 3; }
|
||
|
||
/* 不影响其他实例 */
|
||
if p.a != 1 { ret 4; }
|
||
|
||
/* 内联 type 定义(在函数内) */
|
||
type Triple = struct {
|
||
x: i32,
|
||
y: i32,
|
||
z: i32,
|
||
}
|
||
|
||
var t: Triple;
|
||
t.x = 5;
|
||
t.y = 10;
|
||
t.z = 15;
|
||
if t.x + t.y + t.z != 30 { ret 5; }
|
||
|
||
/* 结构体字段运算 */
|
||
var calc: Pair;
|
||
calc.a = 7;
|
||
calc.b = 3;
|
||
var r := calc.a * calc.b + calc.a - calc.b;
|
||
if r != 25 { ret 6; }
|
||
|
||
/* 结构体嵌套 */
|
||
type Outer = struct {
|
||
inner: Inner,
|
||
extra: i32,
|
||
type Inner = struct {
|
||
val: i32,
|
||
}
|
||
}
|
||
|
||
var o: Outer;
|
||
o.inner.val = 42;
|
||
o.extra = 58;
|
||
if o.inner.val != 42 { ret 7; }
|
||
if o.extra != 58 { ret 8; }
|
||
|
||
/* 多 slot 结构体返回值测试 */
|
||
var r9 := test_ret_multi_slot_struct();
|
||
if r9 != 0 { ret 100; }
|
||
var r10 := test_pass_struct_by_value();
|
||
if r10 != 0 { ret 101; }
|
||
var r11 := test_copy_struct();
|
||
if r11 != 0 { ret 102; }
|
||
var r12 := test_multi_calls();
|
||
if r12 != 0 { ret 103; }
|
||
var r13 := test_literal_arg();
|
||
if r13 != 0 { ret 104; }
|
||
|
||
/* 含 enum 字段的结构体返回值测试 */
|
||
var r14 := test_ret_enum_struct();
|
||
if r14 != 0 { ret 110; }
|
||
var r15 := test_nested_ret_enum();
|
||
if r15 != 0 { ret 111; }
|
||
var r16 := test_copy_token();
|
||
if r16 != 0 { ret 112; }
|
||
var r17 := test_param_pass_token();
|
||
if r17 != 0 { ret 113; }
|
||
var r18 := test_chain_func_call();
|
||
if r18 != 0 { ret 114; }
|
||
|
||
ret 0;
|
||
}
|