다이나믹 한 언어 개발 언어를위한 몇 가지 VM이 있지만 내

매우 간단한 언어를 위해 여러 가지 손으로 쓴 컴파일러를 만들었지 만 이제는 단순화 된 Python 또는 Ruby와 유사한 동적 언어를 개발하려고합니다. 그러나 컴파일러가 작동하는 방식을 머릿속으로 감싸기 쉬웠습니다. 원시 컴파일러는 번역 만합니다. 그러나 언어가 역동적이라면 이것을 할 수 없습니다. 런타임에 정보를 추적하고 더 많은 작업을 수행하는 인터프리터 또는 VM을 작성해야합니다.

간단히 말해서, 컴파일러가 작동하는 방식을 알고 있지만 인터프리터를 작성하기 위해 마이그레이션하려는 것을 고려할 때 확인해야 할 리소스가 있습니까? 동적 언어를위한 몇 가지 VM이 있지만 내 롤링에는 아무런 문제가 없습니다. 이것은 모두 내 개인적인 경험을위한 것입니다.

컴파일러에서 인터프리터로 이동하는 방법에 대한 정보를 찾고 있습니다. 이미 언어 X 용 컴파일러를 만들었지 만 이제 인터프리터를 작성해야하는 경우 수행해야 할 작업과 프로세스를 처리하는 리소스가 있습니까?

컴파일러 또는 가상 머신의 작동 방식을 다루는 광범위하거나 추상적 인 리소스를 원하지 않습니다. 나는 주제에 관한 많은 교과서를 가지고 있습니다. 내가 온라인에서 찾은 모든 자료는 경험이 없다고 가정하여 어휘 또는 구문 분석으로 시작하거나 매우 추상적입니다. 작동하는 컴파일러가 있지만 이제 이것을 인터프리터로 바꾸고 언어에 동적 기능을 추가하고 싶습니다.

이 과정에서 자원을 찾을 수 없거나, 범위가 너무 제한적이거나, 너무 이론적이지 않고 통역사의 “백엔드”에있는 자원이 여기에 게시 된 이유입니다.



답변

먼저 통역사 구현에 대해 배웁니다. PLAI (프로그래밍 언어 : 응용 및 해석)를 권장 합니다. 그것은 구문에 오래 머 무르지 않고 해석의 고기에 빨리 도달합니다.

언어의 경우 컴파일러의 프론트 엔드 (주로 파서) 및 런타임 라이브러리 (GC, 데이터 구조, 기본 연산 등)를 재사용 할 수 있습니다.

물론 인터프리터에서 사용하는 것과 동일한 데이터 구조를 조작하는 코드를 생성하는 컴파일러를 사용하여 동적 언어를 구현할 수도 있습니다. 예를 들어, 인터프리터에서 전역 변수를 문자열 색인 해시 테이블로 구현할 수 있습니다. 컴파일러에서는 전역 변수 참조를 동일한 테이블을 사용하여 조회를 수행하는 코드로 컴파일합니다. 반대로, 어휘 변수를보다 효율적인 표현 ( “네이티브”인수 및 클로저 구조 참조)으로 컴파일 할 수 있습니다.


답변

동적 언어에 대한 인터프리터 구현의 기본 사항을 배우고 싶다면 최초의 동적 해석 언어 인 Lisp의 원점보다 시작하기에 더 좋은 곳을 상상할 수 없습니다.

John McCarthy는 그의 1960 년 논문 에서 Lisp에 필요한 5 가지 기본 기능을 정의했습니다. 물론, McCarthy는 Lisp에 대한 논문을 학업 연습으로 의도했습니다. 그것은 eval집회에 임박 하여 최초의 Lisp 통역사를 만든 대학원생이었습니다 . Paul Graham 인용, 원자, eq, 단점, 자동차, cdr 및 cond의 7 가지 기본 요소를 식별 합니다.

문제는 실제로 어떤 언어로든 Lisp를 구현할 수 있다는 것입니다. 일단 구현 eval하면 REPL을 설정하기 쉽고 대화식 인터프리터가 있습니다. 사람들은 C, Java, Ruby, Python 및 기타 여러 언어로 Lisp를 구현할만큼 지루하거나 궁금합니다. 항상 의도적 인 것은 아닙니다. Greenspun의 10 번째 규칙 을 기억하는 것이 중요합니다 .

충분히 복잡한 C 또는 Fortran 프로그램에는 Common Lisp의 절반을 임시로, 비공식적으로 지정하고, 버그를 해결하며, 느리게 구현 한 임시 프로그램이 포함되어 있습니다.

나는 당신의 최종 목표가 Lisp 구현이어야한다고 말하지 않습니다. 그러나 동성애는 동적 인 언어를 구현하는 법을 배울 때 이점이 있습니다. 관용구가 렉서 / 파서를 사용하는 언어의 AST와 동일한 언어를 배울 수 있는데 왜 구문 문제를 다루는가?

어쨌든 … 그냥 제안입니다. 그러나 C 이후로 훌륭한 프로그래밍 언어의 대부분은 Lisp 특성을 조금 가지고 있기 때문에 좋은 이유가 있습니다.


답변

따옴표 / 목록 / 적용 / 평가 / 테스트 / 등을 지원하고 Lisp와 같은 구문 및 / 또는 시맨틱 내장을 쉽게 사용자 정의 할 수있는 공개 도메인에 이것을 (~ 600 줄의 C #) 넣었습니다.

https://repl.it/CdjV/3

예 :

        var factorial = (Lambda)language.
            Evaluate
            (@"
                ( => ( n ) (
                        ? ( != n 0 )
                        ( * n ( this ( - n 1 ) ) )
                        1
                    )
                )
            ");

        var sw = new System.Diagnostics.Stopwatch();
        var n = 12;
        var r = 0;
        int k;
        sw.Start();
        for (k = 0; k < 10000; k++)
        {
            r = (int)factorial.Invoke(null, n);
        }
        sw.Stop();
        Console.WriteLine("{0}! = {1}", n, r);
        Console.WriteLine();
        Console.WriteLine("in {0} ms (for {1} times)", sw.ElapsedMilliseconds, k.ToString("0,0"));

‘HTH,


답변

당신이 계획의 조금 알고 가정 (예 읽고 SICP를 )이나 리스프, 나는 Queinnec의 추천 리스프에서 작은 조각의 책을. Lisp와 같은 인터프리터 및 컴파일러 (바이트 코드 또는 C 포함)의 여러 변형을 설명합니다.

또한 최신 Dragon Book , GC 핸드북 , Pierce의 유형 및 프로그래밍 언어 인 Scott ‘s Programming Language Pragmatics를 읽으십시오 .

컴파일러에서 인터프리터로 이동하는 방법에 대한 정보를 찾고 있습니다.

그런 다음 부분 평가 (& Futamura 예상) 및 연속 전달 스타일 이 적합 할 수 있습니다.