diff --git a/Makefile b/Makefile index c7c62840..50040c41 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/include/picrin.h b/include/picrin.h index 474f2096..03209454 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -12,6 +12,7 @@ struct pic_env { }; typedef struct { + pic_value *sp; struct pic_env *global_env; } pic_state; diff --git a/src/state.c b/src/state.c index 6fcb5ec5..c1e08699 100644 --- a/src/state.c +++ b/src/state.c @@ -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; diff --git a/src/vm.c b/src/vm.c new file mode 100644 index 00000000..2617e686 --- /dev/null +++ b/src/vm.c @@ -0,0 +1,81 @@ +#include + +#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; +}