emit int result in int-int division if possible
This commit is contained in:
parent
0d2e49c17e
commit
fd3300f9db
36
src/vm.c
36
src/vm.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue