emit int result in int-int division if possible

This commit is contained in:
Yuichi Nishiwaki 2013-11-09 16:32:13 +09:00
parent 0d2e49c17e
commit fd3300f9db
1 changed files with 7 additions and 29 deletions

View File

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <limits.h> #include <limits.h>
#include <math.h>
#include "picrin.h" #include "picrin.h"
#include "picrin/pair.h" #include "picrin/pair.h"
@ -552,14 +553,14 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
NEXT; NEXT;
} }
#define DEFINE_ARITH_OP(opcode, op) \ #define DEFINE_ARITH_OP(opcode, op, guard) \
CASE(opcode) { \ CASE(opcode) { \
pic_value a, b; \ pic_value a, b; \
b = POP(); \ b = POP(); \
a = POP(); \ a = POP(); \
if (pic_int_p(a) && pic_int_p(b)) { \ if (pic_int_p(a) && pic_int_p(b)) { \
double f = (double)pic_int(a) op (double)pic_int(b); \ double f = (double)pic_int(a) op (double)pic_int(b); \
if (INT_MIN <= f && f <= INT_MAX) { \ if (INT_MIN <= f && f <= INT_MAX && (guard)) { \
PUSH(pic_int_value((int)f)); \ PUSH(pic_int_value((int)f)); \
} \ } \
else { \ else { \
@ -582,33 +583,10 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
NEXT; \ NEXT; \
} }
DEFINE_ARITH_OP(OP_ADD, +); DEFINE_ARITH_OP(OP_ADD, +, true);
DEFINE_ARITH_OP(OP_SUB, -); DEFINE_ARITH_OP(OP_SUB, -, true);
DEFINE_ARITH_OP(OP_MUL, *); DEFINE_ARITH_OP(OP_MUL, *, true);
DEFINE_ARITH_OP(OP_DIV, /, f == round(f));
/* special care for (int / int) division */
CASE(OP_DIV) {
pic_value a, b;
b = POP();
a = POP();
if (pic_int_p(a) && pic_int_p(b)) {
PUSH(pic_float_value((double)pic_int(a) / pic_int(b)));
}
else if (pic_float_p(a) && pic_float_p(b)) {
PUSH(pic_float_value(pic_float(a) / pic_float(b)));
}
else if (pic_int_p(a) && pic_float_p(b)) {
PUSH(pic_float_value(pic_int(a) / pic_float(b)));
}
else if (pic_float_p(a) && pic_int_p(b)) {
PUSH(pic_float_value(pic_float(a) / pic_int(b)));
}
else {
pic->errmsg = "/ got non-number operands";
goto L_RAISE;
}
NEXT;
}
CASE(OP_MINUS) { CASE(OP_MINUS) {
pic_value n; pic_value n;