From 62f19e85c5b96bde4a0187e4c15621a9303e9c1e Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Thu, 7 Nov 2013 12:52:59 +0900 Subject: [PATCH] varg * and / operators --- src/codegen.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 0e65d84d..cd687889 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -464,19 +464,55 @@ codegen(codegen_state *state, pic_value obj, bool tailpos) break; } else if (sym == pic->sMUL) { - ARGC_ASSERT(2); - codegen(state, pic_car(pic, pic_cdr(pic, obj)), false); - codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), false); - irep->code[irep->clen].insn = OP_MUL; - irep->clen++; + pic_value args; + + ARGC_ASSERT_GE(0); + switch (pic_length(pic, obj)) { + case 1: + irep->code[irep->clen].insn = OP_PUSHINT; + irep->code[irep->clen].u.i = 1; + irep->clen++; + break; + case 2: + codegen(state, pic_car(pic, pic_cdr(pic, obj)), tailpos); + break; + default: + args = pic_cdr(pic, obj); + codegen(state, pic_car(pic, args), false); + while (pic_length(pic, args) >= 2) { + codegen(state, pic_car(pic, pic_cdr(pic, args)), false); + irep->code[irep->clen].insn = OP_MUL; + irep->clen++; + args = pic_cdr(pic, args); + } + break; + } break; } else if (sym == pic->sDIV) { - ARGC_ASSERT(2); - codegen(state, pic_car(pic, pic_cdr(pic, obj)), false); - codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), false); - irep->code[irep->clen].insn = OP_DIV; - irep->clen++; + pic_value args; + + ARGC_ASSERT_GE(1); + switch (pic_length(pic, obj)) { + case 2: + irep->code[irep->clen].insn = OP_PUSHINT; + irep->code[irep->clen].u.i = 1; + irep->clen++; + codegen(state, pic_car(pic, pic_cdr(pic, obj)), false); + irep->code[irep->clen].insn = OP_DIV; + irep->clen++; + break; + default: + args = pic_cdr(pic, obj); + codegen(state, pic_car(pic, args), false); + while (pic_length(pic, args) >= 2) { + codegen(state, pic_car(pic, pic_cdr(pic, args)), false); + irep->code[irep->clen].insn = OP_DIV; + irep->clen++; + args = pic_cdr(pic, args); + } + break; + } break; } else if (sym == pic->sEQ) {