From 78f301794a2aa0b0ffb7daf59c79e94b723b3621 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sun, 20 Oct 2013 03:48:06 +0900 Subject: [PATCH] add OP_CAR/OP_CDR --- include/picrin.h | 4 ++-- include/picrin/irep.h | 2 ++ src/state.c | 2 ++ src/vm.c | 38 +++++++++++++++++++++++++++++++++++--- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/picrin.h b/include/picrin.h index 9e777da8..465faa9e 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -22,8 +22,8 @@ typedef struct { pic_callinfo *ci; pic_callinfo *cibase, *ciend; - pic_value sDEFINE, sLAMBDA, sIF, sBEGIN; - pic_value sCONS; + pic_value sDEFINE, sLAMBDA, sIF, sBEGIN, sQUOTE; + pic_value sCONS, sCAR, sCDR; pic_value sADD, sSUB, sMUL, sDIV; struct pic_env *global_env; diff --git a/include/picrin/irep.h b/include/picrin/irep.h index b72c3f69..867b5acb 100644 --- a/include/picrin/irep.h +++ b/include/picrin/irep.h @@ -16,6 +16,8 @@ enum pic_opcode { OP_RET, OP_LAMBDA, OP_CONS, + OP_CAR, + OP_CDR, OP_ADD, OP_SUB, OP_MUL, diff --git a/src/state.c b/src/state.c index 71d1f9ac..9846c411 100644 --- a/src/state.c +++ b/src/state.c @@ -55,6 +55,8 @@ pic_open() pic->sIF = pic_intern_cstr(pic, "if"); pic->sBEGIN = pic_intern_cstr(pic, "begin"); pic->sCONS = pic_intern_cstr(pic, "cons"); + pic->sCAR = pic_intern_cstr(pic, "car"); + pic->sCDR = pic_intern_cstr(pic, "cdr"); pic->sADD = pic_intern_cstr(pic, "+"); pic->sSUB = pic_intern_cstr(pic, "-"); pic->sMUL = pic_intern_cstr(pic, "*"); diff --git a/src/vm.c b/src/vm.c index a54c0c5d..24aff138 100644 --- a/src/vm.c +++ b/src/vm.c @@ -185,6 +185,12 @@ print_irep(pic_state *pic, struct pic_irep *irep) case OP_CONS: puts("OP_CONS"); break; + case OP_CAR: + puts("OP_CAR"); + break; + case OP_CDR: + puts("OP_CDR"); + break; case OP_ADD: puts("OP_ADD"); break; @@ -222,13 +228,15 @@ 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, sIF, sBEGIN, sCONS, sADD, sSUB, sMUL, sDIV; + pic_value sDEFINE, sLAMBDA, sIF, sBEGIN, sCONS, sCAR, sCDR, sADD, sSUB, sMUL, sDIV; sDEFINE = pic->sDEFINE; sLAMBDA = pic->sLAMBDA; sIF = pic->sIF; sBEGIN = pic->sBEGIN; sCONS = pic->sCONS; + sCAR = pic->sCAR; + sCDR = pic->sCDR; sADD = pic->sADD; sSUB = pic->sSUB; sMUL = pic->sMUL; @@ -324,6 +332,18 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en irep->clen++; break; } + else if (pic_eq_p(pic, proc, sCAR)) { + pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env); + irep->code[irep->clen].insn = OP_CAR; + irep->clen++; + break; + } + else if (pic_eq_p(pic, proc, sCDR)) { + pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env); + irep->code[irep->clen].insn = OP_CDR; + irep->clen++; + break; + } else if (pic_eq_p(pic, proc, sADD)) { 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); @@ -500,8 +520,8 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) static void *oplabels[] = { &&L_OP_POP, &&L_OP_PUSHNIL, &&L_OP_PUSHTRUE, &&L_OP_PUSHFALSE, &&L_OP_PUSHNUM, &&L_OP_GREF, &&L_OP_GSET, &&L_OP_LREF, &&L_OP_JMP, &&L_OP_JMPIF, - &&L_OP_CALL, &&L_OP_RET, &&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_ADD, - &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV, &&L_OP_STOP + &&L_OP_CALL, &&L_OP_RET, &&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_CAR, &&L_OP_CDR, + &&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV, &&L_OP_STOP }; #endif @@ -614,6 +634,18 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) pic_gc_arena_restore(pic, ai); NEXT; } + CASE(OP_CAR) { + pic_value p; + p = POP(); + PUSH(pic_car(pic, p)); + NEXT; + } + CASE(OP_CDR) { + pic_value p; + p = POP(); + PUSH(pic_cdr(pic, p)); + NEXT; + } CASE(OP_ADD) { pic_value a, b; a = POP();