add OP_EQ/OP_LT/OP_LE

This commit is contained in:
Yuichi Nishiwaki 2013-10-24 21:10:13 +09:00
parent 2732a5a4ec
commit 9cb28f3156
7 changed files with 81 additions and 17 deletions

View File

@ -30,6 +30,7 @@ typedef struct {
pic_value sQUASIQUOTE, sUNQUOTE, sUNQUOTE_SPLICING;
pic_value sCONS, sCAR, sCDR, sNILP;
pic_value sADD, sSUB, sMUL, sDIV;
pic_value sEQ, sLT, sLE, sGT, sGE;
struct sym_tbl *sym_tbl;

View File

@ -27,6 +27,9 @@ enum pic_opcode {
OP_SUB,
OP_MUL,
OP_DIV,
OP_EQ,
OP_LT,
OP_LE,
OP_STOP
};

View File

@ -348,6 +348,41 @@ codegen(codegen_state *state, pic_value obj)
irep->clen++;
break;
}
else if (pic_eq_p(pic, proc, pic->sEQ)) {
codegen(state, pic_car(pic, pic_cdr(pic, obj)));
codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))));
irep->code[irep->clen].insn = OP_EQ;
irep->clen++;
break;
}
else if (pic_eq_p(pic, proc, pic->sLT)) {
codegen(state, pic_car(pic, pic_cdr(pic, obj)));
codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))));
irep->code[irep->clen].insn = OP_LT;
irep->clen++;
break;
}
else if (pic_eq_p(pic, proc, pic->sLE)) {
codegen(state, pic_car(pic, pic_cdr(pic, obj)));
codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))));
irep->code[irep->clen].insn = OP_LE;
irep->clen++;
break;
}
else if (pic_eq_p(pic, proc, pic->sGT)) {
codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))));
codegen(state, pic_car(pic, pic_cdr(pic, obj)));
irep->code[irep->clen].insn = OP_LT;
irep->clen++;
break;
}
else if (pic_eq_p(pic, proc, pic->sGE)) {
codegen(state, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))));
codegen(state, pic_car(pic, pic_cdr(pic, obj)));
irep->code[irep->clen].insn = OP_LE;
irep->clen++;
break;
}
else {
codegen_call(state, obj);
break;
@ -599,6 +634,15 @@ print_irep(pic_state *pic, struct pic_irep *irep)
case OP_DIV:
puts("OP_DIV");
break;
case OP_EQ:
puts("OP_EQ");
break;
case OP_LT:
puts("OP_LT");
break;
case OP_LE:
puts("OP_LE");
break;
case OP_STOP:
puts("OP_STOP");
break;

View File

@ -251,6 +251,11 @@ gc_mark_phase(pic_state *pic)
gc_mark(pic, pic->sADD);
gc_mark(pic, pic->sSUB);
gc_mark(pic, pic->sMUL);
gc_mark(pic, pic->sEQ);
gc_mark(pic, pic->sLT);
gc_mark(pic, pic->sLE);
gc_mark(pic, pic->sGT);
gc_mark(pic, pic->sGE);
gc_mark(pic, pic->sDIV);
}

View File

@ -55,20 +55,6 @@ pic_number_nan_p(pic_state *pic)
return pic_false_value();
}
static pic_value
pic_number_lt(pic_state *pic)
{
double f,g;
pic_get_args(pic, "ff", &f, &g);
if (f < g) {
return pic_true_value();
}
else {
return pic_false_value();
}
}
static pic_value
pic_number_abs(pic_state *pic)
{
@ -293,8 +279,6 @@ pic_init_number(pic_state *pic)
pic_defun(pic, "nan?", pic_number_nan_p);
pic_gc_arena_restore(pic, ai);
pic_defun(pic, "<", pic_number_lt);
pic_defun(pic, "abs", pic_number_abs);
pic_defun(pic, "floor-quotient", pic_number_floor_quotient);

View File

@ -92,6 +92,11 @@ pic_open(int argc, char *argv[], char **envp)
pic->sSUB = pic_intern_cstr(pic, "-");
pic->sMUL = pic_intern_cstr(pic, "*");
pic->sDIV = pic_intern_cstr(pic, "/");
pic->sEQ = pic_intern_cstr(pic, "=");
pic->sLT = pic_intern_cstr(pic, "<");
pic->sLE = pic_intern_cstr(pic, "<=");
pic->sGT = pic_intern_cstr(pic, ">");
pic->sGE = pic_intern_cstr(pic, ">=");
pic_gc_arena_restore(pic, ai);
pic_init_core(pic);

View File

@ -121,7 +121,8 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
&&L_OP_PUSHCONST, &&L_OP_GREF, &&L_OP_GSET, &&L_OP_LREF, &&L_OP_LSET,
&&L_OP_CREF, &&L_OP_CSET, &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_CALL, &&L_OP_RET,
&&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_CAR, &&L_OP_CDR, &&L_OP_NILP,
&&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV, &&L_OP_STOP
&&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV,
&&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_STOP
};
#endif
@ -347,6 +348,27 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
PUSH(pic_float_value(pic_float(a) / pic_float(b)));
NEXT;
}
CASE(OP_EQ) {
pic_value a, b;
b = POP();
a = POP();
PUSH(pic_bool_value(pic_float(a) == pic_float(b)));
NEXT;
}
CASE(OP_LT) {
pic_value a, b;
b = POP();
a = POP();
PUSH(pic_bool_value(pic_float(a) < pic_float(b)));
NEXT;
}
CASE(OP_LE) {
pic_value a, b;
b = POP();
a = POP();
PUSH(pic_bool_value(pic_float(a) <= pic_float(b)));
NEXT;
}
CASE(OP_STOP) {
pic_value val;