Files
doslang-mirror/TODO.md
T
coolguy 6dc298d828 docs: 문서 하나가 질문 하나에 답하게
GOAL.md 는 계획일 때 값어치가 있었는데 완료 보고로 바꾸는 순간 git log 의
중복이 됐다. 끝난 계획은 문서가 아니라 히스토리다. 내용은 이미 TODO 와 SPEC
에 들어갔으니 지운다.

fixture-report.md 도 지운다. 기준선이 150/188 인 일회성 조사 스냅샷이고
지금은 245/245 다. 필요하면 2f140e1 에 있다.

TODO 의 '정해진 것' 이 두 종류를 섞고 있었다. 언어 규칙은 SPEC 문장을 옮겨
적은 것이라 한쪽만 고치면 갈라지고, 구현 결정은 SPEC 에 없어서 여기가 유일한
출처다. 둘로 쪼갰다 -- 앞의 표는 §번호만 담고, 뒤의 표는 내용과 그것이 사는
파일을 담는다.

SPEC 의 §7.9 를 §7.7 로 옮겼다. 7.7 과 7.8 없이 7.9 가 떠 있었다.

1847 → 1173 줄. 245/245, 38/38.
2026-08-17 16:40:50 +09:00

5.2 KiB

TODO

uv run python tests/run.py     245/245   컴파일러가 프로그램에 대해 뭐라고 하는가
uv run python tests/exec.py     38/38    컴파일된 프로그램이 실제로 무엇을 하는가
.fe → fec → i386 asm → wasm → wlink → .exe → Windows 11

셀프호스팅 전에 하기로 했던 것 — 전부 끝남

@print / @fprint 전개 SPEC §6.3.1 대로 컴파일 단계에서 편다. 진단 한 줄이 한 줄이다
파일과 명령줄 열기·읽기·쓰기·닫기, argv. 프로그램이 소스에 박힌 데이터 밖으로 나왔다
match 페이로드와 if let 태그드 유니온을 안전하게 해체한다
조용히 잘리던 상한 자란다. 넘쳐도 틀린 코드가 아니라 오류다
mem.Arena R11 이 말하는 아레나 + 핸들이 실제로 쓸 수 있다
레지스터 할당 블록 단위 선형 스캔. calc 4437 → 3796 줄 (-14%)
Ferro 렉서를 Ferro 로 강제 함수. 돌아간다
std.map 키를 맵이 소유한 버퍼에 복사하고 슬롯은 위치만 든다
Ferro 파서를 Ferro 로 노드 배열 하나 + 인덱스. 1 + 2 * 3(+ 1 (* 2 3)) 로 묶인다
필드 단위 대여 p.ap.b 는 다른 place 다. std.mapkeep 이 다시 함수 하나가 됐다
외부 스펙 감사 대응 니치 옵셔널·store 폭·배치 세 버그, 스펙 빈칸, 죽은 C 백엔드, stdlib 다섯, 측정

파서가 알려준 것: 자기 참조 자료구조는 인덱스로 짓는다. 노드는 ^Node 를 들 수 없고(자식이 여럿이며 한 번씩 소유하지 않는다) &Node 도 들 수 없다(R4). 소유자 하나와 인덱스 여럿이 남는 유일한 모양이고, 그것으로 충분했다.


셀프호스팅으로 가는 길

# 규모 비고
1 리졸버를 Ferro 로 도구는 다 있다: intern, map, Node.bind, Map.clear
2 타입 검사를 Ferro 로 리졸버 다음
3 io.read 로 줄 단위 읽기 지금은 버퍼 하나로 통째로 읽는다
4 여러 반환값 또는 out 파라미터 &mut 재대여로 되지만 장황하다
5 fec 을 Ferro 로 여기까지 오면 언어가 자기 무게를 견딘다

언어에 남은 구멍

[value; count] 배열 반복 리터럴 없다. 큰 버퍼는 undefined 로 선언한다
정수 폭 섞임 1 + 함수호출() 같은 데서 뻑뻑하다. 리터럴이 늘 맞춰주지 않는다
@sprint 전개하지 않는다. @print/@fprint
interrupt shared atomic critical 파싱만 되고 의미 없음. SPEC §11 에서 v0.2
lowering 미구현 진단 internal: cannot lower X. 사용자 오류처럼 보이지 않는다
배열·enum 페이로드의 자동 해제 release_at 은 구조체 필드까지만 내려간다. ?^T 도 아직이라 mem.replace 로 직접 꺼내야 한다
컨테이너 두 원소의 동시 &mut 인덱스는 갈라지지 않는다. swap 같은 것은 stdlib 안에서 해결한다
--strip-error-names 받아들이지만 아무것도 하지 않는다 (SPEC §4.6)
fmt.fmt_error 없다. SPEC §4.6 이 약속만 하고 있다
0b / 0o 리터럴 렉서는 받지만 값 계산이 10진과 16진만 안다

정해진 것 — 언어

SPEC.md 가 유일한 출처다. 여기는 어디를 보는지만 적는다. 문장을 옮겨 적으면 한쪽만 고쳐져서 갈라진다.

타깃, usize/isize §2
정수 리터럴의 타입과 범위 §3
호출 인자·반환 위치의 대여 약화 §4.2
해제는 소유자를 따라 내려간다 §5 R1
대여는 place 단위 §5 R6
배타 대여를 호출에 넘기는 것은 재대여 §4.2, §5 R6
자기 drop 안의 부분 이동 §5 R7
--no-checks 의 오버플로는 랩어라운드 §7.4
match·defer·순회·undefined 등 작은 규칙 일곱 §7.7
제네릭은 모노모피제이션 §9

정해진 것 — 구현

SPEC.md 에 없는 것들. 여기가 출처다.

사는 곳
덩어리 전달 전부 주소로. ISA 마다 다른 구조체 전달 ABI 를 피해감 lower.c
슬라이스 배치 포인터 다음 길이 lowerpri.h 한 군데에만
store 폭 값이 아니라 자리가 정한다 lowerstm.c store_into
트랩 fe_trap(reason, FE_FILE_n, line). 파일은 검사가 쓰인 유닛 x86.c, rt/start.asm
오류 코드 빌드 전체에서 모아 철자 순으로 1부터 lowerstm.c
레지스터 ebx·esi·edi 를 블록 안에 머무는 임시값에. eax/ecx/edx 는 스크래치 x86.c
제네릭 인스턴스 짓는 중에는 배치하지 않는다. 멤버가 안 정해진 집합 타입은 굳지 않고 물러난다 types.c layout_type
unsafe 예산 std.mem/std.sys 밖은 0. 늘어나면 빌드가 실패한다 tests/run.py

파일 크기 규칙

2,000 줄을 넘기지 않는다. 웬만하면 1,000 줄. 넘으면 나눈다 -- check.c 는 3,937 줄이었고 lower.c 는 1,913 줄이었다. 지금 가장 큰 것은 checkcal.c 1,044 줄이다.