From 6c903db758ad5440d6352e7f9253c933ebaa7aeb Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Wed, 16 Oct 2013 17:42:47 +0900 Subject: [PATCH] if syntax --- include/picrin.h | 2 +- include/picrin/irep.h | 2 ++ src/state.c | 1 + src/vm.c | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/picrin.h b/include/picrin.h index de4fb8f9..6ae5eef3 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -23,7 +23,7 @@ typedef struct { pic_callinfo *ci; pic_callinfo *cibase, *ciend; - pic_value sDEFINE, sLAMBDA, sCONS; + pic_value sDEFINE, sLAMBDA, sIF, sCONS; pic_value sADD, sSUB, sMUL, sDIV; struct pic_env *global_env; diff --git a/include/picrin/irep.h b/include/picrin/irep.h index 47e311c9..d01315ff 100644 --- a/include/picrin/irep.h +++ b/include/picrin/irep.h @@ -9,6 +9,8 @@ enum pic_instruction { OP_GREF, OP_GSET, OP_LREF, + OP_JMP, + OP_JMPIF, OP_CALL, OP_RET, OP_LAMBDA, diff --git a/src/state.c b/src/state.c index fe21d27b..48740e64 100644 --- a/src/state.c +++ b/src/state.c @@ -47,6 +47,7 @@ pic_open() pic->sDEFINE = pic_intern_cstr(pic, "define"); pic->sLAMBDA = pic_intern_cstr(pic, "lambda"); + pic->sIF = pic_intern_cstr(pic, "if"); pic->sCONS = pic_intern_cstr(pic, "cons"); pic->sADD = pic_intern_cstr(pic, "+"); pic->sSUB = pic_intern_cstr(pic, "-"); diff --git a/src/vm.c b/src/vm.c index be0beece..4f258cb4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -210,10 +210,11 @@ static struct pic_irep *pic_gen_lambda(pic_state *, pic_value, struct pic_env *) static void pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *env) { - pic_value sDEFINE, sLAMBDA, sCONS, sADD, sSUB, sMUL, sDIV; + pic_value sDEFINE, sLAMBDA, sIF, sCONS, sADD, sSUB, sMUL, sDIV; sDEFINE = pic->sDEFINE; sLAMBDA = pic->sLAMBDA; + sIF = pic->sIF; sCONS = pic->sCONS; sADD = pic->sADD; sSUB = pic->sSUB; @@ -268,6 +269,26 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en pic->irep[pic->ilen++] = pic_gen_lambda(pic, obj, env); break; } + else if (pic_eq_p(pic, proc, sIF)) { + int s,t; + + pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env); + + irep->code[irep->clen].insn = OP_JMPIF; + s = irep->clen++; + + /* if false branch */ + pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, pic_cdr(pic, obj)))), env); + irep->code[irep->clen].insn = OP_JMP; + t = irep->clen++; + + irep->code[s].u.i = irep->clen - s; + + /* if true branch */ + pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env); + irep->code[t].u.i = irep->clen - t; + break; + } else if (pic_eq_p(pic, proc, sCONS)) { pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env); pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env); @@ -465,6 +486,20 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) PUSH(pic->ci[-1].sp[pc->u.i]); NEXT; } + CASE(OP_JMP) { + pc += pc->u.i; + JUMP; + } + CASE(OP_JMPIF) { + pic_value v; + + v = POP(); + if (! pic_false_p(v)) { + pc += pc->u.i; + JUMP; + } + NEXT; + } CASE(OP_CALL) { pic_value c, v; struct pic_proc *proc;