213 lines
8.4 KiB
Markdown
213 lines
8.4 KiB
Markdown
# doslang 작업 인수인계
|
|
|
|
작성 시각: 2026-08-16 (Asia/Seoul)
|
|
|
|
## 최종 목표와 사용자 지시
|
|
|
|
- `SPEC.md`의 최신 명세대로 M14까지 전부 구현한다.
|
|
- DOSBox는 사용하지 않는다. 실행과 권위 있는 검증은 **QEMU FreeDOS 내부**에서만 한다.
|
|
- 컴파일러 A와 생성 C 모두 VM 내부 Open Watcom으로 컴파일한다.
|
|
- 컴파일러 A / bits16: `WCL`
|
|
- bits32 생성 C: `WCL386`
|
|
- 호스트 Windows는 소스 편집, diff, Git, 직렬 전송에만 사용한다.
|
|
- WSL이나 호스트 C 컴파일러 결과를 정식 검증으로 인정하지 않는다.
|
|
- 코딩은 가능한 한 `gpt-5.6-luna` 서브에이전트에 맡기고, 루트 에이전트는 명세 감사와 QEMU 검증을 담당한다.
|
|
- VGA 데모처럼 복잡한 멀티모달 수동 검증은 완료 게이트에서 제외한다.
|
|
- 검증된 마일스톤마다 커밋하고 항상 `origin`에 푸시한다.
|
|
- 구현 중 명세 판단이 바뀌면 `SPEC.md`를 즉시 최신화하고 `SPEC.AUDIT.md`에 변경 이유를 누적한다.
|
|
|
|
## 현재 완료 상태
|
|
|
|
현재 기준 커밋과 원격 `master`는 둘 다 다음 SHA다.
|
|
|
|
```text
|
|
53bca214b82c3abf7882ad41fb177cc488e999af
|
|
```
|
|
|
|
완료 및 QEMU/Open Watcom 검증된 범위:
|
|
|
|
- M1: lexer, parser, AST dump
|
|
- M2: 기본 타입 검사와 C 방출, bits16/bits32 경로
|
|
- M3: struct, enum, match, 배열, 슬라이스, str, 경계 검사, 반복 참조
|
|
- M4: `@print`, `@fprint`, `@sprint`, 최소 `io.Writer`
|
|
|
|
마지막 완료 커밋:
|
|
|
|
```text
|
|
53bca21 feat: implement M4 formatting builtins
|
|
8e6a409 feat: implement M3 aggregate types and iteration
|
|
57b47a5 docs: disambiguate control-flow headers
|
|
95de333 docs: disambiguate match scrutinees
|
|
3aa7618 docs: clarify char and byte conversions
|
|
```
|
|
|
|
M4 최종 검증 증거:
|
|
|
|
- VM의 `C:\FEC\BUILD.OK`: `OK`
|
|
- VM의 `C:\FEC\TEST.OK`: `OK`
|
|
- `C:\FEC\TEST-DOS.BAT`: exit 0
|
|
- 오류 코드 7을 반환하는 C89 Writer harness가 `@fprint`의 정확한 오류 보존과 첫 오류 이후 단축 중단을 실행 검증한다.
|
|
- 로컬/원격 SHA 일치까지 확인하고 푸시했다.
|
|
|
|
## 최신 명세
|
|
|
|
- `SPEC.md`: v0.1.5
|
|
- `SPEC.AUDIT.md`: 최초 감사 이후 설계 변경 로그
|
|
- 주요 후속 결정:
|
|
- `char`와 `u8`은 별개 타입이며 명시적 `as`만 허용한다.
|
|
- 제어 흐름 헤더 직후 `{`는 본문 시작이다. 헤더 최상위 구조체 초기화식은 괄호로 구분한다.
|
|
|
|
## 현재 워크트리: 미완성 M5
|
|
|
|
M5 작업 도중 인수인계를 위해 Luna를 중단했다. **아래 변경은 미검증·미커밋 상태이므로 버리지 말고 먼저 감사할 것.**
|
|
|
|
수정 파일:
|
|
|
|
```text
|
|
fec/src/check.c
|
|
fec/src/emit_c.c
|
|
fec/src/emit_c.h
|
|
fec/src/types.c
|
|
fec/src/types.h
|
|
fec/test-dos.bat
|
|
fec/tests/run-tests.sh
|
|
fec/vm-m1.bat
|
|
```
|
|
|
|
새 파일:
|
|
|
|
```text
|
|
fec/tests/m5/defer.fe
|
|
fec/tests/m5/owned.fe
|
|
fec/tests/m5/bad-move.fe
|
|
fec/tests/m5/bad-destroy.fe
|
|
```
|
|
|
|
현재 diff 규모는 약 251 insertions / 6 deletions이며 `git diff --check`는 통과했다. 아직 DOS로 전송하거나 빌드하지 않았다.
|
|
|
|
현재 부분 구현에 들어간 것으로 확인된 것:
|
|
|
|
- `FE_TYPE_OWNED`
|
|
- struct의 `has_drop` 메타데이터 일부
|
|
- 단순 `moved` 비트 기반 이동 후 사용 진단
|
|
- `mem.create` / `mem.destroy` 일부 checker/emitter 분기
|
|
- owned drop 및 block cleanup helper
|
|
- return/break/continue 정리 경로를 위한 emitter 코드 일부
|
|
- 정상 종료 defer 역순 방출 일부
|
|
|
|
그러나 M5 완료로 간주하면 안 된다. 첫 Luna 결과는 골격뿐이었고 다음 누락 때문에 반려했다.
|
|
|
|
- 자동 drop/free가 모든 경로에서 정확히 한 번 실행되는지
|
|
- `mem.create(T) -> !^T`의 실제 C ABI와 초기화
|
|
- 재대입 전에 기존 owned 값 정리
|
|
- defer와 drop의 선언 위치 기준 역순 병합
|
|
- return / break / continue / try 전파에서 cleanup
|
|
- 조건부 이동의 `MaybeMoved` 상태와 런타임 live flag
|
|
- struct drop 메서드 및 필드 역순 drop
|
|
- 분기/루프 상태 합류
|
|
- 누수와 이중 해제를 세는 런타임 harness
|
|
- R1/R3 실패 테스트 최소 수량
|
|
|
|
중단 직전 두 번째 Luna 패스가 cleanup 코드를 더 추가했으므로 위 항목 일부가 코드에 들어갔을 수 있다. 다음 세션은 반드시 `git diff`로 실제 구현을 재감사하고, 테스트가 증명하지 않는 기능은 완료 처리하지 말아야 한다.
|
|
|
|
현재는 `own.c/h`가 없고 소유권 로직이 주로 `check.c`/`emit_c.c`에 들어가 있다. 복잡도가 계속 커지면 명세 §11.5대로 `own.c/h`와 cleanup/lower 계층을 분리하는 편이 안전하다.
|
|
|
|
## 다음 세션 권장 순서
|
|
|
|
1. `git status --short`, `git diff --check`, M5 diff 전체를 읽는다.
|
|
2. Luna 읽기 전용 감사 에이전트로 M5와 R1~R5/§11.5를 대조한다.
|
|
3. 기존 Luna 구현 에이전트 또는 새 `gpt-5.6-luna`에게 발견된 누락을 수정시킨다.
|
|
4. 최소 다음 테스트를 갖춘다.
|
|
- owned 정상 scope 종료 cleanup
|
|
- 조기 return cleanup
|
|
- return 시 defer 실행
|
|
- 중첩 defer/drop 역순
|
|
- owned 재대입 시 기존 값 cleanup
|
|
- 함수 인자 이동 후 사용 실패
|
|
- 조건부 이동 후 사용 실패 및 정확한 drop
|
|
- 직접 `.drop()` 호출 실패
|
|
- `mem.destroy` 후 재사용/이중 destroy 실패
|
|
- 할당/해제 카운터로 누수 0, double free 0
|
|
5. 변경 파일과 M5 fixture를 직렬 프로토콜로 VM의 `C:\FEC`에 직접 전송한다.
|
|
6. `C:\FEC\TEST-DOS.BAT`를 실행한다. 실패하면 출력/생성 C/정확한 fixture를 좁혀 반복 수정한다.
|
|
7. `BUILD.OK`, `TEST.OK`, exit 0을 모두 확인한 뒤에만 M5 커밋 및 `git push origin master`.
|
|
8. 이후 M6~M14도 같은 방식으로 진행한다.
|
|
|
|
## QEMU와 직렬 에이전트 상태
|
|
|
|
인수인계 작성 시 QEMU는 재시작 없이 살아 있다.
|
|
|
|
```text
|
|
QEMU PID: 11700
|
|
monitor: 127.0.0.1:4444
|
|
DOS tool/controller: 127.0.0.1:5555
|
|
QEMU serial relay: 127.0.0.1:5556
|
|
observer: 127.0.0.1:5557
|
|
```
|
|
|
|
5555에 ASCII 한 줄 명령을 보내는 프로토콜:
|
|
|
|
```text
|
|
PING
|
|
READ <DOS_PATH_HEX> <OFFSET>
|
|
WRITE <DOS_PATH_HEX> T|A <CONTENT_HEX>
|
|
EXEC <COMMAND_HEX>
|
|
```
|
|
|
|
- `PING` 정상 응답: `OK 504F4E47`
|
|
- `WRITE`는 안전하게 1024바이트 조각으로 보내면 된다. 첫 조각 `T`, 이후 `A`.
|
|
- authoritative workspace는 VM의 `C:\FEC`이다.
|
|
- QEMU의 vvfat `D:`는 교환용으로만 취급하고 빌드하지 않는다. 과거 D:에서 빌드하다 QEMU가 rename 처리 오류로 종료된 적이 있다.
|
|
- DOS의 8.3 파일명 때문에 긴 fixture는 `BAD-ARI.FE`, `TRY-FPR.FE`처럼 명시적으로 짧은 이름으로 전송해야 한다.
|
|
|
|
QEMU monitor helper:
|
|
|
|
```powershell
|
|
.\.qemu\monitor.ps1 'sendkey ctrl-c'
|
|
.\.qemu\screenshot.ps1
|
|
```
|
|
|
|
긴 DOS 배치가 멈추면 QEMU를 재시작하지 말고 먼저 `sendkey ctrl-c`를 사용한다. FreeDOS가 다음 프롬프트를 보이면 monitor로 `y`, `ret`을 보낸다.
|
|
|
|
```text
|
|
Terminate batch file ... (Yes/No/All)?
|
|
```
|
|
|
|
그 뒤 `PING` 복구를 확인한다.
|
|
|
|
## 빌드 관련 함정
|
|
|
|
- 컴파일러 A는 16비트 large model로 빌드한다. small model은 메모리 부족이 났다.
|
|
- DOS 명령줄 길이 제한 때문에 compiler object link는 `*.obj`를 사용한다.
|
|
- 따라서 `fec/build-dos.bat`가 먼저 `C:\FEC\*.obj`를 지워 stale 32-bit test object가 섞이지 않게 한다.
|
|
- 생성 C의 보수적 미사용 helper 때문에 M4 Watcom 테스트는 `-wx -wcd=202`를 사용한다. W202만 끄고 다른 경고는 오류로 유지한다.
|
|
- 호스트에서 컴파일하지 말 것. 정적 text/diff 검사만 허용한다.
|
|
- `.qemu/qemu-screen.png`는 진단용이며 커밋하지 않는다.
|
|
|
|
## Git과 저장소
|
|
|
|
```text
|
|
origin: https://github.com/sebastianrcnt/doslang.git
|
|
branch: master
|
|
repository visibility: public
|
|
```
|
|
|
|
사용자는 모든 검증 커밋을 항상 원격에 푸시하길 원한다.
|
|
|
|
이 인수인계 문서는 별도 문서 커밋으로 푸시하되, 현재 미완성 M5 변경은 그 커밋에 포함하지 않는다.
|
|
|
|
## 전체 남은 목표
|
|
|
|
- M5: owned/drop/defer/move — 현재 미완성
|
|
- M6: `&`/`&mut`, R1~R8 전체 borrow checker
|
|
- M7: `?T`, `E!T`, try/catch
|
|
- M8: unit/import/.fei/분리 컴파일/std 초안
|
|
- M9: 제네릭 및 Ferro `List`/`Map`
|
|
- M10: bits16 far/asm/interrupt/shared/atomic/critical (VGA 수동 데모 제외)
|
|
- M11: Compiler B를 Ferro로 작성하고 A로 빌드
|
|
- M12: self-host fixpoint `B(B(B)) == B(B)` 후 A 폐기
|
|
- M13: 386 네이티브 백엔드
|
|
- M14: 8086 네이티브 백엔드, Watcom 없이 bits16 빌드
|
|
|
|
M14 전체 요구를 증명하기 전에는 goal을 complete로 표시하지 않는다.
|