컴파일러를 작성하는 것보다 간단하고 VM은 통역사를 등록하고 트램 폴린하는 것입니다. 컴파일러가 아닌 인터프리터가 있기 때문에 꼬리 호출에 대한 적절한 지원을 얻으려면 몇 가지 간단한 변환 만하면됩니다.
C/C++에서 생각하고하는 것은 이상 할 수있는 연속 전달 스타일로 모든 것을 먼저 작성해야합니다. 댄 프리드먼의 ParentheC 튜토리얼은 결국 C.
으로 기계 번역하는 형태로 높은 수준을 변화, 재귀 프로그램을 단계별로, 당신은 기본적으로 간단한 VM을 구현하는 곳이 아닌 일반 함수를 사용합니다
return applyProc(rator, rand)
는
된다 ... 평가, applyProc는 등, 당신이 전역 변수를 설정하여 인수를 전달하고 다음 인수에
goto
을 (또는 최상위 루프와 프로그램 카운터를 사용) 할 호출
reg_rator = rator
reg_rand = rand
reg_pc = applyProc
return
즉, 일반적으로 서로를 재귀 적으로 호출하는 모든 함수는 반복되지 않는 코드 블록 인 의사 어셈블리로 축소됩니다. 최상위 루프는 프로그램을 제어합니다
for(;;) {
switch(reg_pc) {
case EVAL:
eval();
break;
case APPLY_PROC:
applyProc();
break;
...
}
}
편집 : 내가 자바 스크립트로 작성 취미 계획 인터프리터에 대해 같은 과정을 통해 갔다. 익명의 절차를 많이 사용했지만 구체적인 참조로 도움이 될 수 있습니다. 2011-03-15 통해 2011-03-13부터 FoxScheme's commit history (30707a0432563ce1632a) (5dd3b521dac582507086) 봐.
편집^2 : 비 꼬리 재귀는 스택에 없더라도 여전히 메모리를 소비합니다.
나는 비슷한 질문을 한 것을 본다 : http://stackoverflow.com/questions/5986058/how-does-one-implement-a-stackless-interpreted-language – csl
Peter Norvig의 원래 JScheme은 이것을 구현했다. 멋지게 간단한 트램펄린으로. http://norvig.com/jscheme/Scheme.java에서 eval()로 스크롤하십시오. – csl