lower: 옵셔널, 에러 유니온, try/catch/orelse, defer, for

옵셔널은 태그와 페이로드, 에러 유니온은 오류 코드와 페이로드다. 코드 0 이
'오류 없음'이다. 페이로드 위치 규칙을 types.c 로 옮겨서 레이아웃 패스와 코드
생성기가 같은 것을 본다.

try 는 분기다. 실패면 지금 함수의 에러 유니온을 그 코드로 만들어 나간다 --
그 전에 defer 를 돌린다. catch 와 orelse 는 오른쪽을 필요할 때만 평가하므로
역시 분기다.

for 는 세 형태를 공유한다: 세는 것, 원소를 도는 것, 위치까지 받는 것. 개수는
본문 전에 한 번 읽는다. 원소 바인딩은 참조다 -- 그래서 루프가 원본에 쓸 수
있다.

error.Name 은 빌드 전체에서 이름을 모아 철자 순으로 1부터 번호를 준다
(SPEC 4.6). 빌드 순서가 결과를 바꾸지 않는다.

run.py 197/197, exec.py 9/9.
This commit is contained in:
2026-08-17 06:06:35 +09:00
parent 43555b261c
commit 096a5db411
6 changed files with 485 additions and 2 deletions
+18
View File
@@ -0,0 +1,18 @@
// EXIT:9
unit errunion;
fn half(v: i32) -> !i32 {
if v == 0 { return error.Empty; }
return v / 2;
}
fn chain(v: i32) -> !i32 {
let h: i32 = try half(v);
return h + 1;
}
fn main() -> i32 {
let good: i32 = chain(16) catch 100;
let bad: i32 = chain(0) catch 0;
return good + bad;
}
+11
View File
@@ -0,0 +1,11 @@
// EXIT:60
unit forloop;
fn main() -> i32 {
let a: [5]i32 = [4, 8, 12, 16, 20];
var sum: i32 = 0;
for v in a {
sum = sum + v.^;
}
return sum;
}
+15
View File
@@ -0,0 +1,15 @@
// EXIT:42
unit optional;
fn pick(flag: bool) -> ?i32 {
if flag { return 42; }
return null;
}
fn main() -> i32 {
let a: ?i32 = pick(true);
let b: ?i32 = pick(false);
let x: i32 = a orelse 0;
let y: i32 = b orelse 0;
return x + y;
}