lower: 검사된 AST 를 IR 로 내린다 (1차)

함수, 파라미터, 지역, 리터럴, 이름, 산술과 비교, 대입, if, while,
break/continue, 호출, 참조, 필드 접근, 포인터 역참조까지.

Slot 이 표현식의 결과다 -- 임시값에 든 값이거나 메모리 안의 자리다. 덩어리는
언제나 자리다. 임시값은 레지스터이고 덩어리는 거기 안 들어가기 때문이다.

and/or 는 연산이 아니라 제어 흐름으로 내린다. 오른쪽을 평가하지 않아야 하는
경우가 있어서다.

블록에 terminated 플래그를 뒀다. 없으면 분기 안의 return 이 join 으로 가는
점프에 덮인다.

--dump-ir 로 볼 수 있다. try/catch/defer/drop/for/배열/옵셔널/에러유니온과
제네릭 인스턴스는 아직이다.
This commit is contained in:
2026-08-17 05:51:01 +09:00
parent ddea962d14
commit 6ee3764667
6 changed files with 631 additions and 4 deletions
+8
View File
@@ -215,12 +215,16 @@ void fe_ir_copy(FeIrModule *m, FeIrBlock *b, FeIrPlace dst, FeIrPlace src,
void fe_ir_jmp(FeIrBlock *b, unsigned target)
{
if (b->terminated) return;
b->terminated = 1;
b->term = FE_IR_JMP;
b->target = target;
}
void fe_ir_br(FeIrBlock *b, unsigned cond, unsigned t, unsigned f)
{
if (b->terminated) return;
b->terminated = 1;
b->term = FE_IR_BR;
b->cond = cond;
b->target = t;
@@ -229,6 +233,8 @@ void fe_ir_br(FeIrBlock *b, unsigned cond, unsigned t, unsigned f)
void fe_ir_ret(FeIrBlock *b, unsigned value, int has_value)
{
if (b->terminated) return;
b->terminated = 1;
b->term = FE_IR_RET;
b->ret_value = value;
b->has_ret_value = has_value;
@@ -236,6 +242,8 @@ void fe_ir_ret(FeIrBlock *b, unsigned value, int has_value)
void fe_ir_trap(FeIrBlock *b, FeIrTrap reason, unsigned long line)
{
if (b->terminated) return;
b->terminated = 1;
b->term = FE_IR_TRAP;
b->trap = reason;
b->trap_line = line;