VM 구현을 위한 자습서/리소스
저는 C에서보다는 동적 언어를 위한 간단한 가상 머신을 자체 교육 목적으로 구현하기를 원합니다.Lua VM, Parot, Python VM과 같은 것이지만 더 단순합니다.기존 VM의 코드 및 설계 설명서를 보는 것 외에 이를 달성하는 데 유용한 리소스/자습서가 있습니까?
편집: 왜 근소한 차이로 투표합니까?저는 이해가 안 됩니다 - 이것은 프로그래밍이 아닙니다.제 질문에 구체적인 문제가 있다면 코멘트 부탁드립니다.
단순한 통역보다는 가상 머신을 원하는 것 같습니다.저는 그것들이 연속체의 두 점이라고 생각합니다.통역사는 프로그램의 원래 표현에 가까운 것을 작업합니다.VM은 보다 기본적인(및 자체 포함) 지침에서 작동합니다.이것은 하나를 다른 하나로 번역하기 위한 컴파일 단계가 필요하다는 것을 의미합니다.저는 당신이 그것을 먼저 작업하고 싶은지 아니면 아직 입력 구문을 염두에 두고 있는지 모르겠습니다.
동적 언어의 경우 데이터(키/값 쌍)를 저장하고 해당 언어에 작용하는 일부 작업을 저장할 수 있는 위치가 필요합니다.VM이 저장소를 유지 관리합니다.이 프로그램에서 실행되는 프로그램은 일련의 명령(제어 흐름 포함)입니다.명령 집합을 정의해야 합니다.간단한 세트로 시작하는 것이 좋습니다. 예를 들면 다음과 같습니다.
- 산술 비교를 포함한 기본 산술 연산, 저장소 액세스
- 기본 제어 흐름
- 붙박이 인쇄물
많은 VM이 그렇듯이 스택 기반 계산 방식을 사용하여 산술을 계산할 수도 있습니다.위의 것들은 아직 많은 역동성이 없습니다.이를 위해서는 런타임에 변수 이름을 계산하는 기능(이것은 단지 문자열 연산을 의미함)과 코드를 데이터로 처리하는 기능 두 가지가 필요합니다.이것은 함수 참조를 허용하는 것만큼 간단할 수 있습니다.
VM에 대한 입력은 바이트 코드로 하는 것이 이상적입니다.컴파일러가 아직 없는 경우 기본 어셈블리어에서 생성할 수 있습니다(VM의 일부일 수 있음).
VM 자체는 루프로 구성됩니다.
1. Look at the bytecode instruction pointed to by the instruction pointer.
2. Execute the instruction:
* If it's an arithmetic instruction, update the store accordingly.
* If it's control flow, perform the test (if there is one) and set the instruction pointer.
* If it's print, print a value from the store.
3. Advance the instruction pointer to the next instruction.
4. Repeat from 1.
계산된 변수 이름을 다루는 것은 어려울 수 있습니다. 명령어는 계산된 이름이 어떤 변수에 있는지 지정해야 합니다.명령어가 입력에 제공된 문자열 상수 풀을 참조하도록 허용하면 이 작업을 수행할 수 있습니다.
예제 프로그램(어셈블리 및 바이트 코드):
offset bytecode (hex) source
0 01 05 0E // LOAD 5, .x
3 01 03 10 // .l1: LOAD 3, .y
6 02 0E 10 0E // ADD .x, .y, .x
10 03 0E // PRINT .x
12 04 03 // GOTO .l1
14 78 00 // .x: "x"
16 79 00 // .y: "y"
포함된 지침 코드는 다음과 같습니다.
"LOAD x, k" (01 x k) Load single byte x as an integer into variable named by string constant at offset k.
"ADD k1, k2, k3" (02 v1 v2 v3) Add two variables named by string constants k1 and k2 and put the sum in variable named by string constant k3.
"PRINT k" (03 k) Print variable named by string constant k.
"GOTO a" (04 a) Go to offset given by byte a.
변수의 이름이 다른 변수 등에 의해 지정되는 경우(방향 수준이 추론하기 어려워지는 경우)에 대한 변수가 필요합니다.어셈블리어는 "ADD.x, .y, .x"와 같은 인수를 검토하고 (계산된 변수가 아닌) 문자열 상수에서 추가하기 위한 올바른 바이트 코드를 생성합니다.
글쎄요, C에서 VM을 구현하는 것에 관한 것은 아니지만, 이 질문을 보기 전에 연 마지막 탭이었기 때문에, 저는 QBASIC 바이트코드 컴파일러와 가상 머신을 자바스크립트로 구현하는 것에 대한 기사를 지적해야 할 것 같습니다.<canvas>
태그를 표시합니다.이것은 "니블" 게임을 실행하기에 충분한 QBASIC 구현을 위한 모든 소스 코드를 포함하고 있으며 컴파일러 및 바이트 코드 인터프리터의 일련의 기사 중 첫 번째 기사입니다. 이 기사는 VM을 설명하고, 그는 컴파일러를 설명하는 향후 기사도 약속합니다.
참고로, 저는 당신의 질문을 끝내기 위해 투표한 것은 아니지만, 당신이 얻은 아슬아슬한 투표는 가상 머신 구현에 대해 배우는 방법에 대한 작년의 질문과 중복된 것이었습니다.(튜토리얼이나 비교적 간단한 것에 대한) 이 질문은 열려 있어야 한다는 것과 충분히 다르다고 생각하지만, 더 많은 조언을 위해 이 질문을 참조하는 것이 좋을 것입니다.
또 다른 자료는 루아어의 구현입니다.성능에 대한 평판이 좋은 레지스터 기반 VM입니다.소스 코드는 ANSI C89에 있으며 일반적으로 매우 읽기 쉽습니다.
대부분의 고성능 스크립팅 언어와 마찬가지로 최종 사용자는 읽기 쉽고 높은 수준의 동적 언어(폐쇄, 테일 콜, 불변 문자열, 숫자 및 해시 테이블을 기본 데이터 유형으로, 1차 클래스 값으로 기능함)를 볼 수 있습니다.소스 텍스트는 Edmund의 답변에서 설명한 것과 거의 유사한 개요를 가진 VM 구현에 의해 실행하기 위해 VM의 바이트 코드로 컴파일됩니다.
VM 자체의 구현을 이동 가능하고 효율적으로 유지하기 위해 많은 노력을 기울였습니다.더 많은 성능이 필요한 경우 VM 바이트 코드에서 네이티브 명령어에 이르는 적시 컴파일러가 32비트 x86용으로 존재하며 64비트용으로 베타 릴리스에 있습니다.
시작할 때(C가 아니라 C++이라도) muParser를 볼 수 있습니다.
이것은 간단한 가상 머신을 사용하여 연산을 실행하는 수학식 파서입니다.여러분도 모든 것을 이해할 시간이 필요하다고 생각합니다. 어쨌든 이 코드는 완전한 VM이 실제 전체 프로그램을 실행할 수 있는 것보다 더 단순합니다.(참고로, 저는 C#에서 비슷한 lib를 설계하고 있습니다. 초기 단계이지만 다음 버전에서는 .NET/VMIL 또는 muParser와 같은 새로운 단순 VM으로 컴파일할 수 있습니다.)
또 다른 흥미로운 점은 NekoVM(.n 바이트코드 파일을 실행함)입니다.이것은 C로 작성된 오픈 소스 프로젝트이며, 그것의 주요 언어(.neko)는 소스 대 소스 컴파일러 기술에 의해 생성된 것으로 생각됩니다.마지막 주제의 정신으로 같은 저자의 Haxe를 봅니다(오픈 소스도 마찬가지).
당신처럼 저도 가상 머신과 컴파일러에 대해 공부해 왔습니다. 제가 추천할 만한 좋은 책은 컴파일러 디자인입니다. 가상 시스템.각 VM에 대한 명령 집합과 해당 VM에 대한 상위 수준의 언어를 컴파일하는 방법에 대한 튜토리얼을 제공하여 명령형, 기능형, 논리형 및 개체 지향 언어를 위한 가상 시스템을 설명합니다.VM은 필수 언어에만 구현되었으며 이미 매우 유용한 연습이 되었습니다.
이제 막 시작하신다면 PL101을 추천해 드릴 수 있습니다.다양한 언어를 위한 파서와 인터프리터를 구현하는 과정을 안내하는 자바스크립트의 대화형 레슨 세트입니다.
파티에 늦었지만, 작업 스크립트 언어와 VM을 0부터 작성할 수 있는 게임 스크립팅 마스터를 추천합니다.그리고 거의 전제조건 없이 말입니다.
언급URL : https://stackoverflow.com/questions/2034422/tutorial-resource-for-implementing-vm
'programing' 카테고리의 다른 글
대응-유형 스크립트: 모듈 'react-router-dom'에 내보낸 멤버 'RouteComponentProp'이 없습니다. (0) | 2023.07.09 |
---|---|
문자열에서 VBA 범위 (0) | 2023.07.09 |
Node.js 및 mongoose를 사용하여 '명령 찾기 인증 필요'를 해결하는 방법은 무엇입니까? (0) | 2023.07.09 |
테이블 또는 인덱싱된 뷰가 전체 텍스트 인덱싱되지 않았기 때문에 테이블 또는 인덱싱된 뷰에서 CONTINES 또는 FREETEXT 서술어를 사용할 수 없습니다. (0) | 2023.07.09 |
Excel 셀 내부의 숫자를 0으로 채우는 방법 (0) | 2023.07.09 |