1024바이트로 Python 인터프리터 만들기

3 hours ago 2

매크로나 라이브러리 편법 없이 C 소스 1024바이트에 Python 문법 일부를 실행하는 인터프리터를 담음 토큰화·AST·바이트코드 생성 대신 소스를 파싱하면서 즉시 실행하며, 반복문과 함수 호출은 소스 위치를 이동해 다시 파싱하는 방식으로 처리함 정수 연산, 비교, 들여쓰기 블록, 조건문, 반복문, 재귀 함수 호출 등을 지원하지만, 변수 이름은 소문자 한 글자로 제한되고 오류 처리는 전혀 없음 읽기 쉬운 버전의 4800바이트 이상 코드를 GNU C89 특성과 코드 골프 기법으로 압축했으며, 두 버전 모두 GitHub에 공개함 중간 표현 없이 적은 상태만으로 Python다운 프로그램을 실행할 수 있지만, 크기를 맞추려면 기능을 줄여야 했고 압축 과정에서 변경 내용을 추적하는 작업도 상당히 번거로웠음 512바이트 계산기에서 1024바이트 Python으로 주말에 직접 코드를 작성하며 매크로나 라이브러리 편법 없이 C로 작은 Python 인터프리터를 만드는 도전에서 출발함 Python 전체 대신 Python처럼 보이는 문법을 구현 대상으로 삼음 예제 FizzBuzz는 def buzz(), for n in range(101), 중첩 if·else, print와 함수 호출로 구성됨 def, 콜론, 들여쓰기, 괄호 없는 if 조건식이 Python다운 형태를 만듦 문법의 일부만 구현하는 것 외에도 추가 제약이 필요했음 첫 시도에는 Teeny Tiny 컴파일러 등을 만들 때 사용한 재귀 하강 파서 방식을 적용함 1 + 2에서 x = 1 + 2 * 3, if x > y: z = 3 순으로 확장했지만, 결과는 목표와 달리 계산기에 가까웠고 이미 512바이트를 넘었음 Python다운 요소를 다시 추린 뒤 목표를 1024바이트로 늘리고, 먼저 동작하게 만든 다음 크기를 줄이기로 함 소스를 직접 실행하는 파서 CPython은 토큰화, 추상 구문 트리(AST) 생성, 분석·최적화, 바이트코드 생성과 실행을 거치지만, 이 구현은 그런 처리 단계를 거의 사용하지 않음 실행 상태는 소수의 전역 변수와 고정 길이 배열에 저장함 char src[999]에 대부분의 공백을 제거한 소스를 보관함 int vars[256] 하나에 변수와 함수 이름에 대응하는 값을 저장함 pos, ch, line_start로 다음 문자 위치, 현재 문자, 현재 줄 시작 위치를 추적함 표현식은 재귀 하강 방식으로 파싱하면서 계산함 덧셈·뺄셈 파서는 하위 항을 계산한...

Read Entire Article