X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fcalc.c;h=8bffc02090441fe58e03bec1cc64450401aafe11;hp=b1b3a7418d59d9b16be67af2bcc1fe98f075ae40;hb=7df12c88a4e14611a2585d6e7c994c59e8d7485a;hpb=8c3b5c915ddf11e03e595d7db8917b2b4711a35b diff --git a/src/calc.c b/src/calc.c index b1b3a74..8bffc02 100644 --- a/src/calc.c +++ b/src/calc.c @@ -24,14 +24,51 @@ *******************************************************************************/ #include "php_psi_stdinc.h" +#include #include "token.h" #include "calc.h" -#define PRIfval "f" -#define PRIdval "lf" -#define PRIldval "Lf" +#define PSI_CALC_CAST_SET(in_type, in_val, out_val, out_var) \ +switch (in_type) { \ +case PSI_T_INT8: (out_val)->out_var = (in_val)->i8; break; \ +case PSI_T_UINT8: (out_val)->out_var = (in_val)->u8; break; \ +case PSI_T_INT16: (out_val)->out_var = (in_val)->i16; break; \ +case PSI_T_UINT16: (out_val)->out_var = (in_val)->u16; break; \ +case PSI_T_INT32: (out_val)->out_var = (in_val)->i32; break; \ +case PSI_T_UINT32: (out_val)->out_var = (in_val)->u32; break; \ +case PSI_T_INT64: (out_val)->out_var = (in_val)->i64; break; \ +case PSI_T_UINT64: (out_val)->out_var = (in_val)->u64; break; \ +case PSI_T_FLOAT: (out_val)->out_var = (in_val)->fval; break; \ +case PSI_T_DOUBLE: (out_val)->out_var = (in_val)->dval; break; \ +case PSI_T_LONG_DOUBLE: (out_val)->out_var = (in_val)->ldval; break; \ +default: \ + assert(0); \ +} + +#define PSI_CALC_CAST(in_type, in_val, out_type, out_val) \ +switch (out_type) { \ +case PSI_T_INT8: PSI_CALC_CAST_SET(in_type, in_val, out_val, i8) break; \ +case PSI_T_UINT8: PSI_CALC_CAST_SET(in_type, in_val, out_val, u8) break; \ +case PSI_T_INT16: PSI_CALC_CAST_SET(in_type, in_val, out_val, i16) break; \ +case PSI_T_UINT16: PSI_CALC_CAST_SET(in_type, in_val, out_val, u16) break; \ +case PSI_T_INT32: PSI_CALC_CAST_SET(in_type, in_val, out_val, i32) break; \ +case PSI_T_UINT32: PSI_CALC_CAST_SET(in_type, in_val, out_val, u32) break; \ +case PSI_T_INT64: PSI_CALC_CAST_SET(in_type, in_val, out_val, i64) break; \ +case PSI_T_UINT64: PSI_CALC_CAST_SET(in_type, in_val, out_val, u64) break; \ +case PSI_T_FLOAT: PSI_CALC_CAST_SET(in_type, in_val, out_val, fval) break; \ +case PSI_T_DOUBLE: PSI_CALC_CAST_SET(in_type, in_val, out_val, dval) break; \ +case PSI_T_LONG_DOUBLE: PSI_CALC_CAST_SET(in_type, in_val, out_val, ldval) break; \ +default: \ + assert(0); \ +} + +void psi_calc_cast(token_t in_type, impl_val *in_val, token_t out_type, impl_val *out_val) +{ + PSI_CALC_CAST(in_type, in_val, out_type, out_val) +} +#if 0 #define PSI_CALC_OP(var) do { \ const char *fmt = "calc %" PRI##var ", %" PRI##var ": %" PRI##var "\n"; \ res->var = PSI_CALC(v1->var, v2->var); \ @@ -42,6 +79,10 @@ res->vres = PSI_CALC(v1->var1, v2->var2); \ if (!res->vres && (v1->var1 || v2->var2)) fprintf(stderr, fmt, v1->var1, v2->var2, res->vres); \ } while(0) +#else +#define PSI_CALC_OP(var) res->var = PSI_CALC(v1->var, v2->var) +#define PSI_CALC_OP2(vres, var1, var2) res->vres = PSI_CALC(v1->var1, v2->var2) +#endif #ifdef HAVE_LONG_DOUBLE # define PSI_CALC_NO_LD @@ -209,7 +250,7 @@ break; \ } \ } \ - ZEND_ASSERT(0); \ + assert(0); \ return 0; \ } @@ -225,3 +266,30 @@ PSI_CALC_FN(sub) #undef PSI_CALC #define PSI_CALC(var1, var2) (var1) / (var2) PSI_CALC_FN(div) +#undef PSI_CALC + +#define PSI_CALC_BIN_FN(op) token_t psi_calc_##op(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res) \ +{ \ + impl_val i1, i2; \ + PSI_CALC_CAST(t1, v1, PSI_T_UINT64, &i1); \ + PSI_CALC_CAST(t2, v2, PSI_T_UINT64, &i2); \ + res->u64 = PSI_CALC(i1.u64, i2.u64); \ + return PSI_T_UINT64; \ +} + +#define PSI_CALC(var1, var2) (var1) << (var2) +PSI_CALC_BIN_FN(bin_lshift) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) >> (var2) +PSI_CALC_BIN_FN(bin_rshift) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) & (var2) +PSI_CALC_BIN_FN(bin_and) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) ^ (var2) +PSI_CALC_BIN_FN(bin_xor) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) | (var2) +PSI_CALC_BIN_FN(bin_or) +#undef PSI_CALC +