add pic_add, pic_sub, ..., pic_eq, pic_lt, ...
This commit is contained in:
parent
b01042505f
commit
10522b54e9
|
@ -582,6 +582,45 @@ pic_eqv_p(pic_value x, pic_value y)
|
|||
|
||||
#endif
|
||||
|
||||
#if PIC_ENABLE_FLOAT
|
||||
# define pic_aop(pic, a, b, op, name, guard) \
|
||||
((pic_int_p(a) && pic_int_p(b)) ? \
|
||||
((INT_MIN <= (double)pic_int(a) op (double)pic_int(b) && (double)pic_int(a) op (double)pic_int(b) <= INT_MAX && guard) \
|
||||
? pic_int_value((int)((double)pic_int(a) op (double)pic_int(b))) \
|
||||
: pic_float_value((double)pic_int(a) op (double)pic_int(b))) \
|
||||
: (pic_float_p(a) && pic_float_p(b)) ? pic_float_value(pic_float(a) op pic_float(b)) \
|
||||
: (pic_int_p(a) && pic_float_p(b)) ? pic_float_value(pic_int(a) op pic_float(b)) \
|
||||
: (pic_float_p(a) && pic_int_p(b)) ? pic_float_value(pic_float(a) op pic_int(b)) \
|
||||
: (pic_errorf(pic, name ": non-number operand given"), 0))
|
||||
#else
|
||||
# define pic_aop(pic, a, b, op, name) \
|
||||
((pic_int_p(a) && pic_int_p(b)) \
|
||||
? pic_int_value(pic_int(a) op pic_int(b)) \
|
||||
: (pic_errorf(pic, name ": non-number operand given"), 0))
|
||||
#endif
|
||||
|
||||
#define pic_add(pic, a, b) pic_aop(pic, a, b, +, "+", true)
|
||||
#define pic_sub(pic, a, b) pic_aop(pic, a, b, -, "-", true)
|
||||
#define pic_mul(pic, a, b) pic_aop(pic, a, b, *, "*", true)
|
||||
#define pic_div(pic, a, b) pic_aop(pic, a, b, /, "/", (double)pic_int(a) / (double)pic_int(b) == round((double)pic_int(a) / (double)pic_int(b)))
|
||||
|
||||
#if PIC_ENABLE_FLOAT
|
||||
# define pic_cmp(pic, a, b, op, name) \
|
||||
((pic_int_p(a) && pic_int_p(b)) ? pic_int(a) op pic_int(b) \
|
||||
: (pic_float_p(a) && pic_float_p(b)) ? pic_float(a) op pic_float(b) \
|
||||
: (pic_int_p(a) && pic_float_p(b)) ? pic_int(a) op pic_float(b) \
|
||||
: (pic_float_p(a) && pic_int_p(b)) ? pic_float(a) op pic_int(b) \
|
||||
: (pic_errorf(pic, name ": non-number operand given"), 0))
|
||||
#else
|
||||
# define pic_cmp(pic, a, b, op, name) \
|
||||
((pic_int_p(a) && pic_int_p(b)) ? pic_int(a) op pic_int(b) \
|
||||
: (pic_errorf(pic, name ": non-number operand given"), 0))
|
||||
#endif
|
||||
|
||||
#define pic_eq(pic, a, b) pic_cmp(pic, a, b, ==, "=")
|
||||
#define pic_le(pic, a, b) pic_cmp(pic, a, b, <=, "<=")
|
||||
#define pic_lt(pic, a, b) pic_cmp(pic, a, b, <, "<")
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
153
extlib/benz/vm.c
153
extlib/benz/vm.c
|
@ -921,111 +921,62 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
NEXT;
|
||||
}
|
||||
|
||||
#define DEFINE_ARITH_OP(opcode, op, guard) \
|
||||
CASE(opcode) { \
|
||||
pic_value a, b; \
|
||||
b = POP(); \
|
||||
a = POP(); \
|
||||
(void)POP(); \
|
||||
if (pic_int_p(a) && pic_int_p(b)) { \
|
||||
double f = (double)pic_int(a) op (double)pic_int(b); \
|
||||
if (INT_MIN <= f && f <= INT_MAX && (guard)) { \
|
||||
PUSH(pic_int_value((int)f)); \
|
||||
} \
|
||||
else { \
|
||||
PUSH(pic_float_value(f)); \
|
||||
} \
|
||||
} \
|
||||
else if (pic_float_p(a) && pic_float_p(b)) { \
|
||||
PUSH(pic_float_value(pic_float(a) op pic_float(b))); \
|
||||
} \
|
||||
else if (pic_int_p(a) && pic_float_p(b)) { \
|
||||
PUSH(pic_float_value(pic_int(a) op pic_float(b))); \
|
||||
} \
|
||||
else if (pic_float_p(a) && pic_int_p(b)) { \
|
||||
PUSH(pic_float_value(pic_float(a) op pic_int(b))); \
|
||||
} \
|
||||
else { \
|
||||
pic_errorf(pic, #op " got non-number operands"); \
|
||||
} \
|
||||
NEXT; \
|
||||
CASE(OP_ADD) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_add(pic, a, b));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
#define DEFINE_ARITH_OP2(opcode, op) \
|
||||
CASE(opcode) { \
|
||||
pic_value a, b; \
|
||||
b = POP(); \
|
||||
a = POP(); \
|
||||
(void)POP(); \
|
||||
if (pic_int_p(a) && pic_int_p(b)) { \
|
||||
PUSH(pic_int_value(pic_int(a) op pic_int(b))); \
|
||||
} \
|
||||
else { \
|
||||
pic_errorf(pic, #op " got non-number operands"); \
|
||||
} \
|
||||
NEXT; \
|
||||
CASE(OP_SUB) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_sub(pic, a, b));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
#if PIC_ENABLE_FLOAT
|
||||
DEFINE_ARITH_OP(OP_ADD, +, true);
|
||||
DEFINE_ARITH_OP(OP_SUB, -, true);
|
||||
DEFINE_ARITH_OP(OP_MUL, *, true);
|
||||
DEFINE_ARITH_OP(OP_DIV, /, f == round(f));
|
||||
#else
|
||||
DEFINE_ARITH_OP2(OP_ADD, +);
|
||||
DEFINE_ARITH_OP2(OP_SUB, -);
|
||||
DEFINE_ARITH_OP2(OP_MUL, *);
|
||||
DEFINE_ARITH_OP2(OP_DIV, /);
|
||||
#endif
|
||||
|
||||
#define DEFINE_COMP_OP(opcode, op) \
|
||||
CASE(opcode) { \
|
||||
pic_value a, b; \
|
||||
b = POP(); \
|
||||
a = POP(); \
|
||||
(void)POP(); \
|
||||
if (pic_int_p(a) && pic_int_p(b)) { \
|
||||
PUSH(pic_bool_value(pic_int(a) op pic_int(b))); \
|
||||
} \
|
||||
else if (pic_float_p(a) && pic_float_p(b)) { \
|
||||
PUSH(pic_bool_value(pic_float(a) op pic_float(b))); \
|
||||
} \
|
||||
else if (pic_int_p(a) && pic_float_p(b)) { \
|
||||
PUSH(pic_bool_value(pic_int(a) op pic_float(b))); \
|
||||
} \
|
||||
else if (pic_float_p(a) && pic_int_p(b)) { \
|
||||
PUSH(pic_bool_value(pic_float(a) op pic_int(b))); \
|
||||
} \
|
||||
else { \
|
||||
pic_errorf(pic, #op " got non-number operands"); \
|
||||
} \
|
||||
NEXT; \
|
||||
CASE(OP_MUL) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_mul(pic, a, b));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
#define DEFINE_COMP_OP2(opcode, op) \
|
||||
CASE(opcode) { \
|
||||
pic_value a, b; \
|
||||
b = POP(); \
|
||||
a = POP(); \
|
||||
(void)POP(); \
|
||||
if (pic_int_p(a) && pic_int_p(b)) { \
|
||||
PUSH(pic_bool_value(pic_int(a) op pic_int(b))); \
|
||||
} \
|
||||
else { \
|
||||
pic_errorf(pic, #op " got non-number operands"); \
|
||||
} \
|
||||
NEXT; \
|
||||
CASE(OP_DIV) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_div(pic, a, b));
|
||||
NEXT;
|
||||
}
|
||||
CASE(OP_EQ) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_bool_value(pic_eq(pic, a, b)));
|
||||
NEXT;
|
||||
}
|
||||
CASE(OP_LE) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_bool_value(pic_le(pic, a, b)));
|
||||
NEXT;
|
||||
}
|
||||
CASE(OP_LT) {
|
||||
pic_value a, b;
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_bool_value(pic_lt(pic, a, b)));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
#if PIC_ENABLE_FLOAT
|
||||
DEFINE_COMP_OP(OP_EQ, ==);
|
||||
DEFINE_COMP_OP(OP_LT, <);
|
||||
DEFINE_COMP_OP(OP_LE, <=);
|
||||
#else
|
||||
DEFINE_COMP_OP2(OP_EQ, ==);
|
||||
DEFINE_COMP_OP2(OP_LT, <);
|
||||
DEFINE_COMP_OP2(OP_LE, <=);
|
||||
#endif
|
||||
|
||||
CASE(OP_STOP) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue