Nibble: C로 작성된 미니멀리스트 LLVM 프론트엔드

현대 컴파일러 구축의 지형은 종종 거대하고 복잡한 프레임워크와 멀티 패스 아키텍처로 특징지어집니다. 하지만 glouwbug의 프로젝트인 Nibble은 약 3,000줄의 C 코드로 단일 패스 LLVM 프론트엔드를 구현함으로써 이러한 미니멀리즘에 도전합니다. 추상 구문 트리(AST) 및 동적 메모리 할당(malloc)과 같은 전통적인 컴파일러 구성 요소를 제거함으로써, Nibble은 언어 설계 및 아키텍처에서의 극단적인 미니멀리즘에 대한 설득력 있는 사례를 보여줍니다.

미니멀리즘의 아키텍처

Nibble의 주요 목표는 소스 코드에서 LLVM IR로의 효율적인 단일 패스 번역입니다. 대부분의 전통적인 컴파일러는 어휘 분석, 구문 분석, AST로의 재귀적 하강, 그리고 그 후 코드를 생성하기 위해 해당 AST를 순회하는 파이프라인을 따릅니다. Nibble은 이 전체 과정을 우회합니다.

AST를 제거함으로써, 컴파일러는 구문 분석 중인 동일한 언어의 중간 표현을 구축할 필요가 없습니다. 대신, 구문 분석을 처리하는 동일한 패스에서 직접 LLVM IR을 생성합니다. 이 접근 방식은 오버헤드의 복잡성과 컴파일러 자체의 메모리 관리 메모리 사용량을 크게 줄여줍니다.

주요 기술적 제약 사항

미니멀리즘의 경계를 더욱 넓히기 위해, 저자는 다음과 같은 제약 사항을 구현했습니다:

  • No malloc: 컴파일러는 프로세스 중에 동적 메모리 할당을 피하며, 이는 결정론적인 메모리 사용량을 보장하고 동적 할당과 관련된 단편화를 방지합니다.
  • No External Dependencies: 이 프로젝트는 순수 C로 작성되었으며, 언어의 핵심 코어 라이브러리에만 의존하여 높은 이식성과 가벼운 사용량을 보장합니다.
  • Single Pass: 번역은 동일한 소스 코드의 단일 순회에서 발생하며, 이는 번역 프로세스를 처리하는 매우 효율적인 방식입니다.

커뮤니티 피드백 및 관찰

이 프로젝트는 커뮤니티로부터 좋은 반응을 얻었지만, Hacker News 커뮤니티에서는 몇 가지 기술적 문의와 더 많은 문서에 대한 요청이 제기되었습니다.

언어 사양

주요 비판 중 하나는 포괄적인 언어 사양의 부재였습니다. 사용자들은 프로젝트가 작동하는 구현체이지만, defer 키워드 및 메모리 관리와 같은 언어의 나머지 기능들이 소스 코드를 읽는 사람들에게 미스터리로 남아 있다고 언급했습니다. 한 사용자 @childintime이 다음과 같이 언급했습니다:

"이것이 마음에 듭니다. 하지만 언어에 대한 설명이 없습니다. 예를 들어 defer는 제가 확인한 2개의 main.n 파일에서 볼 수 없었고, 메모리 관리는 여전히 미스터리입니다."

성능 및 확장성

커뮤니티는 IR 생성의 확장성에 대해 궁금해 합니다. 컴파일러가 단일 패스이고 AST가 없기 때문에, 동일한 코드에 대해 여러 번의 패스를 요구할 수 있는 특정 고수준 최적화 및 복잡한 언어 기능은 본질적으로 제한됩니다. 이는 언어가 복잡해짐에 따라 IR이 얼마나 확장될 수 있는지에 대해 의문을 갖게 만듭니다.

결론

Nibble은 컴파일러 프론트엔드 제약의 한계를 밀어붙이는 프로젝트의 능력을 증명하는 증거입니다. AST 없이, 즉 AST가 없는 단일 패스 아키텍처를 통해 기능적인 LLVM 프론트엔드를 구현할 수 있음을 증명함으로써, 단순함에 대한 귀중한 교훈을 제공합니다. 컴파일러 구축에 관심이 있는 사람들에게, Nibble은 많은 사이드 프로젝트들이 'readme-only' 단계에 머무는 것과 달리 실제로 출시된 프로젝트의 훌륭한 예시입니다.

Sources