FILE *src = fopen("examples/study.goe", "r");
if (!src) { perror("Goemon's scroll (study.goe) not found"); return 1; }
int bytecode[1024];
int count = 0;
char line[256];
while (fgets(line, sizeof(line), src)) {
if (strncmp(line, "push", 4) == 0) {
int val = atoi(line + 5);
bytecode[count++] = OP_PUSH;
bytecode[count++] = val;
} else if (strstr(line, "add")) {
bytecode[count++] = OP_ADD;
//ここのwhile文でpushやaddなどの文字列を探してOP_PUSHやOP_ADDなどのOpCodeに変換します。実行VMが実行できる形です。実行VM側でも同じ構造体を定義しています。
....省略(クソコードすぎるので)
バイナリファイルを最終的に実行エンジンが読み取り実行していくといった形になります。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef enum {
OP_PUSH,
OP_ADD,
OP_SUB,
OP_MUL,
OP_DUP,
OP_SWAP,
OP_POP,
OP_MOD,
OP_EQ,
OP_JMP,
OP_JZ,
OP_PRINT,
OP_HALT
} OpCode;
void run(int* program) {
int stack[256];
int sp = -1;
int pc = 0;
while (true) {
int instruction = program[pc++];
switch (instruction) {
case OP_PUSH:
stack[++sp] = program[pc++];
break;
case OP_ADD: {
int b = stack[sp--];
int a = stack[sp--];
stack[++sp] = a + b;
break;
}
case OP_SUB: {
int b = stack[sp--];
int a = stack[sp--];
stack[++sp] = a - b;
break;
}
//ここのwhile文でバイナリファイルを読み取って、OpCodeがないか探します。見つかった場合、それぞれの処理を実行します。
...省略(クソコードすぎるので)
で、最終的にはこんな感じで実行結果が返ってきます。
test.com@sample goemon-src % make run
./kama-c
絶景かな! Compiled study.goe to study.gb
./kama-e examples/study.gb
VM Output: 2
コメント