예전에 컴파일러 개발한다고 글을 올린 이후로 오랬만에 컴파일러 개발 근황을 올립니다.
아무래도 오유에는 컴파일러 개발에 관심있는 분들이 많지 않은 것 같아 컴파일러 관련해서는 프로그래밍 전문 커뮤니티에 글을 쓰고 있습니다.
현재 개발중인 컴파일러는 간단하게 말해서 C Preprocessor + Rust + Python 입니다.
전에는 컴파일러가 생성한 어셈블리 코드를 FASM을 이용하여 컴파일하고 실행파일을 만들어 냈는데 현재 어셈블러를 직접 만들고 있습니다.
컴파일 전과정을 직접 개발하여 성능의 극대화를 추구하려는 것도 있지만 가장 큰 이유는 기존의 컴파일러 개발 방식과는 전혀 다른 방식으로 접근하기 위해서 입니다.
일반적으로 컴파일러는 문법을 BNF으로 정의하고 직접 렉서, 파서를 만들거나 오픈 소스 렉서, 파서 등으로 토큰 테이블과 신택스 트리를 생성한 다음 중간 코드 생성하고 생성된 중간 코드를 플랫폼에 맞게 기계어로 변환하고 링커로 실행파일을 만드는 과정을 거칩니다.
저는 어셈블러에 살을 붙이는 방식으로 역으로 컴파일러를 개발하고 있습니다.
우선 순수하게 어셈블러 니모닉과 지시어로 이루어진 어셈블러를 만든 후 앞단에 C Preprocessor를 붙이고 어셈블러의 스캐너와 파서에 고급언어 문법을 추가할 생각입니다.
고급 언어의 문법추가는 실제로 컴파일시 생성되야 할 기계어 코드를 어셈블리로 직접 생성한 이후 같은 기능을 하는 문법을 추가하고 컴파일하여 동일한 결과가 나오는지 검토하는 방식을 사용할 생각입니다.
이미 FastASM을 개발할 때 계속 사용했던 방식인데 예전에는 고급언어 문법 스캐너, 파서와 어셈블러의 스캐너, 파서가 분리되어 있었다면 지금은 이걸 하나로 합치려는 것이죠.
문법은 기존의 Visual Basic .Net에 비슷한 문법에서 생산성과 접근성을 위해 파이썬으로 변경했습니다.
최대한 파이썬의 문법에 가깝게 만들어 기존의 수많은 파이썬을 어렵지 않게 포팅할 수 있게 하여 제가 만들고 있는 컴파일러가 그냥 마이너 컴파일러가 되지 않게 하기 위해서 입니다.
아예 동일하게 문법을 하지 않는 이유는 파이썬의 문법이 갖고 있는 수많은 단점들과 모든 문법을 지원할 경우 제가 원하는 어셈블리어에 버금가는 성능의 고급언어는 구현이 불가능하기 때문입니다.
C의 Preprocessor 도입은 운영체제 API들이나 DLL API를 사용하기 위해 해야하는 정의를 최대한 줄이기 위해서 입니다.
문법을 파이썬으로 해서 파이썬 라이브러리의 포팅을 쉽게할 수 있게 했듯이 C의 Preprocessor를 도입하여 API 등을 사용하기 위한 정의를 C의 해더를 이용하겠다는 겁니다.
현재 어셈블러는 절반이상 진행이 된 상태로 PE 해더부분만 더 가다듬으면 내일중에 간단한 명령들은 컴파일이 될 것 같습니다.
하지만 요즘 CPU들 명령이 너무 많아 모든 명령이 추가 되려면 상당한 시간이 걸릴 것 같습니다.
컴파일러의 구조는 대부분 만들어진 상황으로 앞으로는 부지런한 노가다가 될 것 같습니다.
파이썬 문법 추가후 셀프 호스팅으로 다시 컴파일러를 만드는 것은 내년에나 가능하지 않을까 생각중입니다.