Skip to content

Latest commit

 

History

History
134 lines (108 loc) · 7.87 KB

ARCHITECTURE.md

File metadata and controls

134 lines (108 loc) · 7.87 KB

ARCHITECTURE

이 문서는 의도한 설계를 현재형으로 기술한다. 전부 구현된 것은 아니다. 오늘 실제로 동작하는 범위는 docs/LANGUAGE.md(언어 표면)와 docs/STATUS.md(실측 상태)가 정본이며, 아직 만들지 않은 항목에는 ⏳ 미구현을 붙였다. 설계 기록으로서의 값을 유지하려고 문장을 미래형으로 바꾸지는 않았다.

원칙

개발자가 보는 계층과 실행 계층을 분리한다.
변환은 컴파일 타임에만 일어난다. 실행 시점에는 네이티브 코드만 남긴다.

[표면 문법 소스 .mls]
        │  parse / typecheck
        ▼
[내부 IR]
        │  lower to native backend
        ▼
[네이티브 오브젝트]
        │  link + optional protect
        ▼
[배포 모듈 .dll  (⏳ .so/ELF·.mll 컨테이너는 미구현)]
        │  C ABI
        ▼
[호스트 앱: C ✅ CI 게이트 / Delphi ✅ 로컬 게이트 / C++ ✅ 헤더 컴파일만 / C# ⏳ 미검증]

파일 확장자는 가칭이다. 확정 전.

컴파일 파이프라인

  1. Lex / Parse
    표면 문법 → AST
  2. Resolve / Typecheck
    강한 정적 타입. 호스트가 제공한 인터페이스 정의도 여기서 검증(⏳ 미구현 — 호스트 인터페이스 입력이 아직 없다)
  3. IR
    언어 중립에 가깝되, 네이티브/Delphi 실행 모델(값 타입, 명시적 수명 후보)을 표현할 수 있어야 함
  4. Codegen
    내부 IR → no_std·extern "C"·repr(C) Rust → cargo cdylib (D19, 잠정). C-emit 백엔드 슬롯은 열려 있고 LLVM 직접 방출은 이연했다 — 이 줄은 "LLVM 또는 기존 네이티브 툴체인에 lowering"이라는 후보로 적혀 있었으나, D19가 2026-08-28에 정했고 그 뒤로 계속 출하돼 왔다(compiler/src/codegen.rs).
    “내부가 Delphi 방식”이 Delphi 컴파일러를 반드시 호출한다는 뜻은 아님.
    의미 모델이 Object Pascal/네이티브에 가깝다는 뜻이다.
  5. Packaging
    export 테이블, 버전 심볼, 그리고 인터페이스 지문(ml_iface_hash_<모듈>, #105) — iface.rs가 ml-iface/1 매니페스트를 만들고 생성 헤더가 ML_<모듈>_IFACE_HASH를 박으며, 참조 C 호스트 둘이 어긋난 모듈을 거부한다(실측). ⏳ 미구현으로 남은 것은 .mll 컨테이너다(D18: 커스텀 컨테이너는 P1).

    (2026-09-22 정정: 이 줄은 지문이 출하된 뒤에도 없는 것으로 적고 있었다 — 같은 파일 아래 문단이 지문의 존재를 전제하고 그 한계를 설명하는데도. 옛 표현을 인용하지 않는다: no_document_calls_interface_metadata_unimplemented가 그것을 금지하므로, 인용하면 정정문이 자기 가드를 트립시킨다 — 이 저장소에서 오늘만 네 번째다.)

  6. Protect
    strip과 심볼 제거는 구현됨(모든 빌드에 적용, 실측). 이후의 단계적 강화(P1·P2)와 "배포 빌드만" 이라는 구분(D13)은 ⏳ 미구현 — 지금은 빌드 프로파일이 하나다

런타임에 존재하는 것

  • 로더 — 오늘은 호스트 쪽이다(LoadLibrary/GetProcAddress). 얇은 C 런타임은 ⏳ 미구현
  • C ABI 호출 규약
  • 선택적 무결성 검사 — ⏳ 미구현(P1, SECURITY.md)
  • 에러 코드 규약(D17, 구현됨). 모듈용 할당자 등 그 밖의 런타임 지원은 ⏳ 미구현

런타임에 존재하지 말아야 할 것:

  • 소스 파서
  • 표면 문법 인터프리터
  • 일반 eval

모듈과 호스트

모듈은 플러그인이다.

  • 호스트가 모듈을 load
  • 모듈 export를 호스트가 호출한다. 반대 방향(호스트가 허용한 함수/객체를 모듈에 넘기는 것)은 ⏳ 미구현
  • 모듈 교체 = 파일 교체 + 재로드. 모듈의 시그니처가 그대로인 한 호스트 재빌드 없음. 이 조건은 실측으로 좁혀졌다(2026-09-01): 규칙을 i32 코드로 표현하면 그 코드의 어휘가 호스트에 살게 되어, 모듈에 케이스 하나를 더하면 재빌드하지 않은 호스트가 모르는 코드를 출력한다. 임계값 변경은 파일 교체로 나가고, 케이스 집합 확장은 호스트 재빌드를 요구한다 (docs/slices/SPEC-string-return.md §0.1). 배열도 같다 — 원소 개수를 파라미터 개수로 흉내내면 개수가 바뀔 때 옛 호스트가 조용히 틀린 값을 받거나 segfault한다(실측). 세 번째 좁힘(2026-09-07, STATUS §9-9): 규칙의 일정이 바뀌어도 재빌드가 필요하다. fold로 쪼갠 호스트는 "패스가 몇 번이고 그 사이에 무엇이 옮겨지는가"를 자기 코드에 갖는다. 순위를 한 번 매기는 전제로 얼린 호스트에 제수법 모듈을 끼우면 크래시 없이 다른 규칙의 답을 내고, 시그니처가 같으므로 인터페이스 지문도 이것을 보지 못한다(실측).

개발 vs 배포

⏳ 이 표는 D13이 의도한 구분이며, 아직 구현되지 않았다. 현재는 빌드 프로파일이 하나뿐이라 개발 빌드도 배포 빌드와 같게 strip된다.

개발 배포
소스 로컬에만 없음
심볼/디버그 가능 제거
보호 약하거나 없음 단계적 강화
피드백 빠른 컴파일, 명확한 타입 에러 실행과 무결성

웹

브라우저에서 DLL을 실행하지 않는다.
웹이 필요해지면 별도 WASM 타깃을 추가하는 것이지, 기본 모델을 WASM으로 바꾸지 않는다.

구현 시 권장 경계

  • compiler/: 프론트엔드 + IR
  • backend/: 네이티브 codegen
  • runtime/: 얇은 C ABI 런타임
  • host/delphi, host/c: 바인딩
  • packager/: 모듈 포맷

MVP는 compiler 최소 + C ABI + Delphi 또는 C 호스트 하나면 충분하다.

현재 실제 레이아웃 (2026-08-29)

위는 권장 경계이고, 아래는 그것이 실제 디렉터리로 어떻게 내려앉았는지의 대응표다. 나머지는 조기 경계이므로 필요해질 때 만든다(빈 크레이트를 미리 만들지 않는다).

여기에 "이것뿐이다"라고 쓰지 않는다. 그렇게 적혀 있었고, 그 문장이 두 번 거짓이 됐다 — hosts/delphi-host/(#111)와 hosts/c-host-link/(#126)가 생겼는데 표는 그대로였다. 디렉터리의 정본은 트리이고, 이 표는 권장 경계 ↔ 실재의 대응을 설명하는 자리다.

경로 내용 상태
compiler/ lex → parse → typecheck → IR → codegen + mlc build CLI 있음 (codegen도 여기)
runtime/ C ABI 헤더·예약 심볼 규약 있음 (헤더만, 런타임 코드 없음)
hosts/rust-oracle/ kernel32 로더 + PE export 리더 (테스트 오라클) 있음
examples/ .mls 예제 있음
backend/ · packager/ — 미생성(실측: 두 디렉터리 모두 없다)
host/delphi hosts/delphi-host/ 실재하고, 로컬 게이트가 있다. MATHLESS_GATE_DELPHI가 dcc64로 빌드해 호출한다 — 에디션이 명령줄 빌드를 거부하므로 게이트가 IDE(bds.exe -b)를 부른다(STATUS §9-20). CI 게이트는 아니다: 러너에 Delphi도 대화형 세션도 없다. Free Pascal은 CI에서 매번 돈다(MATHLESS_GATE_FPC·MATHLESS_GATE_FPC_HOST)
hosts/c-host-link/ — 있음 — 헤더를 include하고 .lib을 링크하는 두 번째 소비 경로. GetProcAddress가 한 번도 나오지 않는다(#126)
host/c hosts/c-host/ 이름만 다르다 — 실재한다. MSVC로 빌드하는 C11 호스트가 수용 D를 닫고 CI의 정본 잡이 이를 실행한다(.github/workflows/ci.yml). 이 표는 권장 경계를 기준으로 쓰였고, 실제 디렉터리는 hosts/ 아래에 있다