TL;DR
- DummyScheme은 Lua에서 영감을 받은 레지스터 기반 바이트코드 가상 머신(VM)을 사용하는 이식형·임베디드 Scheme 구현으로, C/C++ 호스트 프로그램에 통합할 수 있음.
- 꼬리 호출 최적화,
call/cc기반 다중 샷 무제한 연속(continuation),dynamic-wind, 값 다중 반환을 지원함. syntax-rules위생적 매크로, 사용자 정의 생략 부호, 큰 정수(bignum)를 포함한 숫자 타워, 소스 위치 추적을 지원함.r4rstest와r5rs-tests테스트를 통과하며, 기본 설정에서 R5RS를 준수하고SCHEME_STD_R4RS=1설정으로 R4RS를 지원함.- 일부 구현만 완료되고 현재 사용되지 않는 세대별 증분 가비지 컬렉터(GC)를 포함하며, Lua식 해시 테이블과 C/C++ 연동 인터페이스를 제공함.
DummyScheme
- 레지스터 기반 바이트코드 VM을 사용하는 이식형 임베디드 Scheme 구현임.
개발 배경
- 게임 프로그래밍, 특히 백엔드 분야에서 다년간 경험을 쌓았으며, 게임 업계와 다른 여러 분야에서 Lua가 널리 사용되는 점에 주목함.
- SICP를 매우 좋아하고, 「The Roots Of Lisp」 글과 『Hackers and Painters』를 읽었으며, Lisp를 높이 평가함.
- Lua처럼 레지스터와 바이트코드 기반 VM을 사용하고 줄 단위 디버그 정보를 제공하는 Scheme 구현을 원함.
.h와.cpp파일을 복사해 호스트 프로그램과 함께 컴파일하고 스텁을 작성하는 방식으로 쉽게 임베드할 수 있음.
기능
- 레지스터 기반 명령어 집합을 사용하는 바이트코드 컴파일러
- 꼬리 호출 최적화
- 일급 연속(first-class continuation):
call/cc기반 다중 샷, 무제한 연속이며 호출 프레임에 쓰기 시 복사(copy-on-write) 방식을 사용함. 구분 연속(delimited continuation)은 가까운 시일 내 지원 예정임. - Lua에서 영감을 받은 평탄화 박스 값(flatten box value): 체인을 만들지 않고, 내부 람다에 의해 캡처되는 스택 값은 박싱함.
- Chez Scheme에서 영감을 받은 연속 캡처 및 체인 순회용 스택 세그먼트 기법
- 두 구간(two-halves) 증분 세대별 가비지 컬렉터: 일부 구현됐으나 현재 사용되지 않음.
- 사용자 정의 생략 부호도 지원하는
syntax-rules위생적 매크로 - 큰 정수(bignum)를 지원하는 숫자 타워
- 소스 위치 추적을 포함한 줄 단위 디버그 정보
- Lua식 임베딩 및 이식성: 플랫폼에 독립적이며 C/C++ 호스트 애플리케이션에 쉽게 통합 가능함. Windows, Linux, macOS, iOS, Android를 비롯해 C99/C++98 호환 컴파일러가 있는 모든 플랫폼을 대상으로 함.
SCHEME_STD_R4RS=1설정을 적용한r4rstest와r5rs-tests전체 테스트 통과call/cc와 중첩된dynamic-wind지원.dynamic-wind의 썽크나 본문에서 바깥으로 이동해before와after를 건너뛸 수 있으며, 안으로 이동하는 것은 금지되지 않음.values와call-with-values
추가 항목
transcript-on및transcript-off없음eval은 없지만vm->evalstr제공- Lua에서 영감을 받은 해시 테이블:
make-hash-table,hash-table-ref table key,hash-table-set! table key val,hash-table-for-each제공
사용 방법
- Scheme 코드를 테스트할 때 프로젝트의
r4rstest.scm,r5rs-tests.scm,aftertest.scm참조 main.cpp를 제외한*.cpp및*.h파일을 프로젝트에 복사- 헤더
vm.h를 포함하고Scheme네임스페이스 사용 - 기본
malloc과free를 사용하려면VM vm으로 VM 초기화 - 사용자 지정 메모리 할당·재할당·해제를 사용하려면 사용자 지정 할당 함수를 전달해
VM vm(myalloc)으로 초기화 vm.loadfile("filename.scm")로 파일 로드RegCProc항목 배열에 스텁 함수를 등록해 Scheme에서 호출할 C 함수를 연결함. 고정 인자 함수와 나머지 인자 함수 모두 등록 가능하며,regcfunc(vm, myext)로 등록함.- Scheme에서
(my-add 2 3),(my-sum 1 2 3 4)처럼 등록된 스텁 호출 - C/C++에서
vm->evalstr("(+ 1 2)")로 Scheme 코드를 평가하고,scm_get_int로 결과 정수 추출 - C/C++에서
vm->call("f", argv, n)으로 람다 호출
호환성
- 별도 설정이 없으면 R5RS 준수
SCHEME_STD_R4RS매크로 설정 시 R4RS 준수. 주된 차이는 심벌의 대문자 변환임.
향후 계획
- 최적화와 기능 추가는 계속될 수 있음.
라이선스
- MIT
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요