first VM impl

This commit is contained in:
Yuichi Nishiwaki 2013-10-12 00:16:19 +09:00
parent 03fbd0bdb6
commit 643d8be66d
4 changed files with 90 additions and 0 deletions

View File

@ -6,6 +6,13 @@ build:
lex scan.l
gcc -o bin/picrin -I./include src/main.c src/state.c src/gc.c src/pair.c src/write.c src/symbol.c src/value.c src/y.tab.c src/lex.yy.c src/eval.c src/bool.c
test-vm:
cd src; \
yacc -d parse.y; \
lex scan.l
gcc -o bin/picrin -I./include src/vm.c src/state.c src/gc.c src/pair.c src/write.c src/symbol.c src/value.c src/y.tab.c src/lex.yy.c src/eval.c src/bool.c
bin/picrin
clean:
rm -f src/y.tab.c src/y.tab.h src/lex.yy.c
rm -f bin/picrin

View File

@ -12,6 +12,7 @@ struct pic_env {
};
typedef struct {
pic_value *sp;
struct pic_env *global_env;
} pic_state;

View File

@ -20,6 +20,7 @@ pic_open()
pic_state *pic;
pic = (pic_state *)malloc(sizeof(pic_state));
pic->sp = (pic_value *)malloc(sizeof(pic_value) * 1024);
pic->global_env = pic_new_empty_env();
return pic;

81
src/vm.c Normal file
View File

@ -0,0 +1,81 @@
#include <stdlib.h>
#include "picrin.h"
enum pic_instruction {
OP_PUSHI,
OP_ADD,
OP_STOP
};
struct pic_code {
enum pic_instruction insn;
union {
int i;
} u;
};
struct pic_proc {
union {
struct pic_code *code;
} u;
};
pic_value
pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
{
struct pic_code *pc;
pic_value *sp;
pc = proc->u.code;
sp = pic->sp;
while (1) {
switch (pc->insn) {
case OP_PUSHI: {
*++sp = pic_int_value(pc->u.i);
break;
}
case OP_ADD: {
pic_value a, b;
a = *sp--;
b = *sp--;
*++sp = pic_int_value(pic_int(a) + pic_int(b));
break;
}
case OP_STOP:
goto STOP;
}
pc++;
}
STOP:
return *sp;
}
int
main()
{
pic_state *pic;
struct pic_proc proc;
struct pic_code *code;
pic_value v;
pic = pic_open();
proc.u.code = code = (struct pic_code *)malloc(sizeof(struct pic_code) * 256);
code[0].insn = OP_PUSHI;
code[0].u.i = 1;
code[1].insn = OP_PUSHI;
code[1].u.i = 2;
code[2].insn = OP_ADD;
code[3].insn = OP_STOP;
v = pic_run(pic, &proc, pic_nil_value());
pic_debug(pic, v);
pic_close(pic);
return 0;
}