varg * and / operators

This commit is contained in:
Yuichi Nishiwaki 2013-11-07 12:52:59 +09:00
parent 9d304be02e
commit 62f19e85c5
1 changed files with 46 additions and 10 deletions

View File

@ -464,20 +464,56 @@ codegen(codegen_state *state, pic_value obj, bool tailpos)
break; break;
} }
else if (sym == pic->sMUL) { else if (sym == pic->sMUL) {
ARGC_ASSERT(2); pic_value args;
codegen(state, pic_car(pic, pic_cdr(pic, obj)), false);
codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), false); 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->code[irep->clen].insn = OP_MUL;
irep->clen++; irep->clen++;
args = pic_cdr(pic, args);
}
break;
}
break; break;
} }
else if (sym == pic->sDIV) { else if (sym == pic->sDIV) {
ARGC_ASSERT(2); 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); 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->code[irep->clen].insn = OP_DIV;
irep->clen++; irep->clen++;
break; 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) { else if (sym == pic->sEQ) {
ARGC_ASSERT(2); ARGC_ASSERT(2);