X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fcalc.c;h=2dc85f4da3dcdede96105e8909852fd7b245cc1f;hp=8bffc02090441fe58e03bec1cc64450401aafe11;hb=acb84297d3ceeb57c97e0ac4da1881eba6aee18e;hpb=7df12c88a4e14611a2585d6e7c994c59e8d7485a diff --git a/src/calc.c b/src/calc.c index 8bffc02..2dc85f4 100644 --- a/src/calc.c +++ b/src/calc.c @@ -29,43 +29,70 @@ #include "token.h" #include "calc.h" -#define PSI_CALC_CAST_SET(in_type, in_val, out_val, out_var) \ +#define PSI_CALC_CAST_SET(in_type, in_val, op, 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; \ +case PSI_T_INT8: (out_val)->out_var op (in_val)->i8; break; \ +case PSI_T_UINT8: (out_val)->out_var op (in_val)->u8; break; \ +case PSI_T_INT16: (out_val)->out_var op (in_val)->i16; break; \ +case PSI_T_UINT16: (out_val)->out_var op (in_val)->u16; break; \ +case PSI_T_INT32: (out_val)->out_var op (in_val)->i32; break; \ +case PSI_T_UINT32: (out_val)->out_var op (in_val)->u32; break; \ +case PSI_T_INT64: (out_val)->out_var op (in_val)->i64; break; \ +case PSI_T_UINT64: (out_val)->out_var op (in_val)->u64; break; \ +case PSI_T_FLOAT: (out_val)->out_var op (in_val)->fval; break; \ +case PSI_T_DOUBLE: (out_val)->out_var op (in_val)->dval; break; \ +case PSI_T_LONG_DOUBLE: (out_val)->out_var op (in_val)->ldval; break; \ default: \ assert(0); \ } -#define PSI_CALC_CAST(in_type, in_val, out_type, out_val) \ +#define PSI_CALC_CAST(in_type, in_val, op, 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; \ +case PSI_T_INT8: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, i8) break; \ +case PSI_T_UINT8: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, u8) break; \ +case PSI_T_INT16: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, i16) break; \ +case PSI_T_UINT16: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, u16) break; \ +case PSI_T_INT32: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, i32) break; \ +case PSI_T_UINT32: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, u32) break; \ +case PSI_T_INT64: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, i64) break; \ +case PSI_T_UINT64: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, u64) break; \ +case PSI_T_FLOAT: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, fval) break; \ +case PSI_T_DOUBLE: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, dval) break; \ +case PSI_T_LONG_DOUBLE: PSI_CALC_CAST_SET(in_type, in_val, op, out_val, ldval) break; \ +default: \ + assert(0); \ +} + +#define PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, out_var) \ +switch (in_type) { \ +case PSI_T_INT8: (out_val)->out_var op (in_val)->i8; break; \ +case PSI_T_UINT8: (out_val)->out_var op (in_val)->u8; break; \ +case PSI_T_INT16: (out_val)->out_var op (in_val)->i16; break; \ +case PSI_T_UINT16: (out_val)->out_var op (in_val)->u16; break; \ +case PSI_T_INT32: (out_val)->out_var op (in_val)->i32; break; \ +case PSI_T_UINT32: (out_val)->out_var op (in_val)->u32; break; \ +case PSI_T_INT64: (out_val)->out_var op (in_val)->i64; break; \ +case PSI_T_UINT64: (out_val)->out_var op (in_val)->u64; break; \ +default: \ + assert(0); \ +} +#define PSI_CALC_CAST_INT(in_type, in_val, op, out_type, out_val) \ +switch (out_type) { \ +case PSI_T_INT8: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, i8) break; \ +case PSI_T_UINT8: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, u8) break; \ +case PSI_T_INT16: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, i16) break; \ +case PSI_T_UINT16: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, u16) break; \ +case PSI_T_INT32: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, i32) break; \ +case PSI_T_UINT32: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, u32) break; \ +case PSI_T_INT64: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, i64) break; \ +case PSI_T_UINT64: PSI_CALC_CAST_SET_INT(in_type, in_val, op, out_val, u64) 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) + PSI_CALC_CAST(in_type, in_val, =, out_type, out_val) } #if 0 @@ -207,47 +234,112 @@ void psi_calc_cast(token_t in_type, impl_val *in_val, token_t out_type, impl_val } \ return t2; \ } else { \ - int64_t sval1 = v1->i64, sval2 = v2->i64; \ - uint64_t uval1 = v1->u64, uval2 = v2->u64; \ switch (t1) { \ - case PSI_T_INT8: sval1 >>= 8; \ - case PSI_T_INT16: sval1 >>= 8; \ - case PSI_T_INT32: sval1 >>= 8; \ + case PSI_T_INT8: \ + switch (t2) { \ + case PSI_T_INT8: PSI_CALC_OP2(i16, i8, i8); return PSI_T_INT16; \ + case PSI_T_UINT8: PSI_CALC_OP2(i16, i8, u8); return PSI_T_INT16; \ + case PSI_T_INT16: PSI_CALC_OP2(i32, i8, i16); return PSI_T_INT32; \ + case PSI_T_UINT16: PSI_CALC_OP2(i32, i8, u16); return PSI_T_INT32; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, i8, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(i64, i8, u32); return PSI_T_INT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, i8, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(i64, i8, u64); return PSI_T_INT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT8: \ + switch (t2) { \ + case PSI_T_INT8: PSI_CALC_OP2(i16, u8, i8); return PSI_T_INT16; \ + case PSI_T_UINT8: PSI_CALC_OP2(u16, u8, u8); return PSI_T_UINT16; \ + case PSI_T_INT16: PSI_CALC_OP2(i32, u8, i16); return PSI_T_INT32; \ + case PSI_T_UINT16: PSI_CALC_OP2(u32, u8, u16); return PSI_T_UINT32; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, u8, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(u64, u8, u32); return PSI_T_UINT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, u8, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(u64, u8, u64); return PSI_T_UINT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_INT16: \ + switch (t2) { \ + case PSI_T_INT8: PSI_CALC_OP2(i32, i16, i8); return PSI_T_INT32; \ + case PSI_T_UINT8: PSI_CALC_OP2(i32, i16, u8); return PSI_T_INT32; \ + case PSI_T_INT16: PSI_CALC_OP2(i32, i16, i16); return PSI_T_INT32; \ + case PSI_T_UINT16: PSI_CALC_OP2(i32, i16, u16); return PSI_T_INT32; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, i16, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(i64, i16, u32); return PSI_T_INT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, i16, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(i64, i16, u64); return PSI_T_INT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT16: \ + switch (t2) { \ + case PSI_T_INT8: PSI_CALC_OP2(i32, u16, i8); return PSI_T_INT32; \ + case PSI_T_UINT8: PSI_CALC_OP2(u32, u16, u8); return PSI_T_UINT32; \ + case PSI_T_INT16: PSI_CALC_OP2(i32, u16, i16); return PSI_T_INT32; \ + case PSI_T_UINT16: PSI_CALC_OP2(u32, u16, u16); return PSI_T_UINT32; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, u16, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(u64, u16, u32); return PSI_T_UINT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, u16, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(u64, u16, u64); return PSI_T_UINT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_INT32: \ + switch (t2) { \ + case PSI_T_INT8: PSI_CALC_OP2(i64, i32, i8); return PSI_T_INT64; \ + case PSI_T_UINT8: PSI_CALC_OP2(i64, i32, u8); return PSI_T_INT64; \ + case PSI_T_INT16: PSI_CALC_OP2(i64, i32, i16); return PSI_T_INT64; \ + case PSI_T_UINT16: PSI_CALC_OP2(i64, i32, u16); return PSI_T_INT64; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, i32, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(i64, i32, u32); return PSI_T_INT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, i32, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(i64, i32, u64); return PSI_T_INT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT32: \ + switch (t2) { \ + case PSI_T_INT8: PSI_CALC_OP2(i64, u32, i8); return PSI_T_INT64; \ + case PSI_T_UINT8: PSI_CALC_OP2(u64, u32, u8); return PSI_T_UINT64; \ + case PSI_T_INT16: PSI_CALC_OP2(i64, u32, i16); return PSI_T_INT64; \ + case PSI_T_UINT16: PSI_CALC_OP2(u64, u32, u16); return PSI_T_UINT64; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, u32, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(u64, u32, u32); return PSI_T_UINT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, u32, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(u64, u32, u64); return PSI_T_UINT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ case PSI_T_INT64: \ switch (t2) { \ - case PSI_T_INT8: sval2 >>= 8; \ - case PSI_T_INT16: sval2 >>= 8; \ - case PSI_T_INT32: sval2 >>= 8; \ - case PSI_T_INT64: \ - res->i64 = PSI_CALC(sval1 , sval2); \ - return PSI_T_INT64; \ - case PSI_T_UINT8: uval2 >>= 8; \ - case PSI_T_UINT16: uval2 >>= 8; \ - case PSI_T_UINT32: uval2 >>= 8; \ - case PSI_T_UINT64: \ - res->i64 = PSI_CALC(sval1, uval2); \ - return PSI_T_INT64; \ + case PSI_T_INT8: PSI_CALC_OP2(i64, i64, i8); return PSI_T_INT64; \ + case PSI_T_UINT8: PSI_CALC_OP2(i64, i64, u8); return PSI_T_INT64; \ + case PSI_T_INT16: PSI_CALC_OP2(i64, i64, i16); return PSI_T_INT64; \ + case PSI_T_UINT16: PSI_CALC_OP2(i64, i64, u16); return PSI_T_INT64; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, i64, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(i64, i64, u32); return PSI_T_INT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, i64, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(i64, i64, u64); return PSI_T_INT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ } \ break; \ - case PSI_T_UINT8: uval1 >>= 8; \ - case PSI_T_UINT16: uval1 >>= 8; \ - case PSI_T_UINT32: uval1 >>= 8; \ case PSI_T_UINT64: \ switch (t2) { \ - case PSI_T_INT8: sval2 >>= 8; \ - case PSI_T_INT16: sval2 >>= 8; \ - case PSI_T_INT32: sval2 >>= 8; \ - case PSI_T_INT64: \ - res->i64 = PSI_CALC(uval1, sval2); \ - return PSI_T_INT64; \ - case PSI_T_UINT8: uval2 >>= 8; \ - case PSI_T_UINT16: uval2 >>= 8; \ - case PSI_T_UINT32: uval2 >>= 8; \ - case PSI_T_UINT64: \ - res->u64 = PSI_CALC(uval1, uval2); \ - return PSI_T_UINT64; \ + case PSI_T_INT8: PSI_CALC_OP2(i64, u64, i8); return PSI_T_INT64; \ + case PSI_T_UINT8: PSI_CALC_OP2(u64, u64, u8); return PSI_T_UINT64; \ + case PSI_T_INT16: PSI_CALC_OP2(i64, u64, i16); return PSI_T_INT64; \ + case PSI_T_UINT16: PSI_CALC_OP2(u64, u64, u16); return PSI_T_UINT64; \ + case PSI_T_INT32: PSI_CALC_OP2(i64, u64, i32); return PSI_T_INT64; \ + case PSI_T_UINT32: PSI_CALC_OP2(u64, u64, u32); return PSI_T_UINT64; \ + case PSI_T_INT64: PSI_CALC_OP2(i64, u64, i64); return PSI_T_INT64; \ + case PSI_T_UINT64: PSI_CALC_OP2(u64, u64, u64); return PSI_T_UINT64; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ } \ break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ } \ } \ assert(0); \ @@ -268,28 +360,279 @@ PSI_CALC_FN(sub) 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) \ +token_t psi_calc_mod(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_INT64, &i1); + PSI_CALC_CAST(t2, v2, =, PSI_T_INT64, &i2); + + res->i64 = i1.i64 % i2.i64; + + return PSI_T_INT64; +} + +#define PSI_CALC_BIT_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); \ + 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) +PSI_CALC_BIT_FN(bin_lshift) #undef PSI_CALC #define PSI_CALC(var1, var2) (var1) >> (var2) -PSI_CALC_BIN_FN(bin_rshift) +PSI_CALC_BIT_FN(bin_rshift) #undef PSI_CALC #define PSI_CALC(var1, var2) (var1) & (var2) -PSI_CALC_BIN_FN(bin_and) +PSI_CALC_BIT_FN(bin_and) #undef PSI_CALC #define PSI_CALC(var1, var2) (var1) ^ (var2) -PSI_CALC_BIN_FN(bin_xor) +PSI_CALC_BIT_FN(bin_xor) #undef PSI_CALC #define PSI_CALC(var1, var2) (var1) | (var2) -PSI_CALC_BIN_FN(bin_or) +PSI_CALC_BIT_FN(bin_or) #undef PSI_CALC +#define PSI_CALC_CMP_FN(op) token_t psi_calc_##op(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res) \ +{ \ + switch (t1) { \ + case PSI_T_FLOAT: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, fval, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, fval, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, fval, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, fval, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, fval, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, fval, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, fval, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, fval, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, fval, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, fval, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, fval, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_DOUBLE: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, dval, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, dval, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, dval, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, dval, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, dval, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, dval, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, dval, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, dval, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, dval, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, dval, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, dval, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_LONG_DOUBLE: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, ldval, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, ldval, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, ldval, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, ldval, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, ldval, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, ldval, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, ldval, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, ldval, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, ldval, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, ldval, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, ldval, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_INT8: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, i8, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, i8, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, i8, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, i8, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, i8, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, i8, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, i8, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, i8, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, i8, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, i8, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, i8, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT8: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, u8, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, u8, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, u8, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, u8, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, u8, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, u8, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, u8, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, u8, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, u8, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, u8, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, u8, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_INT16: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, i16, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, i16, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, i16, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, i16, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, i16, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, i16, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, i16, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, i16, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, i16, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, i16, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, i16, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT16: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, u16, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, u16, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, u16, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, u16, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, u16, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, u16, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, u16, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, u16, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, u16, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, u16, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, u16, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_INT32: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, i32, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, i32, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, i32, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, i32, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, i32, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, i32, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, i32, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, i32, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, i32, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, i32, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, i32, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT32: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, u32, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, u32, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, u32, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, u32, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, u32, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, u32, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, u32, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, u32, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, u32, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, u32, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, u32, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_INT64: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, i64, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, i64, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, i64, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, i64, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, i64, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, i64, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, i64, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, i64, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, i64, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, i64, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, i64, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + case PSI_T_UINT64: \ + switch (t2) { \ + case PSI_T_FLOAT: PSI_CALC_OP2(u8, u64, fval); break; \ + case PSI_T_DOUBLE: PSI_CALC_OP2(u8, u64, dval); break; \ + case PSI_T_LONG_DOUBLE: PSI_CALC_OP2(u8, u64, ldval); break; \ + case PSI_T_INT8: PSI_CALC_OP2(u8, u64, i8); break; \ + case PSI_T_UINT8: PSI_CALC_OP2(u8, u64, u8); break; \ + case PSI_T_INT16: PSI_CALC_OP2(u8, u64, i16); break; \ + case PSI_T_UINT16: PSI_CALC_OP2(u8, u64, u16); break; \ + case PSI_T_INT32: PSI_CALC_OP2(u8, u64, i32); break; \ + case PSI_T_UINT32: PSI_CALC_OP2(u8, u64, u32); break; \ + case PSI_T_INT64: PSI_CALC_OP2(u8, u64, i64); break; \ + case PSI_T_UINT64: PSI_CALC_OP2(u8, u64, u64); break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + break; \ + EMPTY_SWITCH_DEFAULT_CASE(); \ + } \ + return PSI_T_UINT8; \ +} + +#define PSI_CALC(var1, var2) (var1) == (var2) +PSI_CALC_CMP_FN(cmp_eq) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) != (var2) +PSI_CALC_CMP_FN(cmp_ne) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) <= (var2) +PSI_CALC_CMP_FN(cmp_le) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) >= (var2) +PSI_CALC_CMP_FN(cmp_ge) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) < (var2) +PSI_CALC_CMP_FN(cmp_lt) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) > (var2) +PSI_CALC_CMP_FN(cmp_gt) +#undef PSI_CALC + +#define PSI_CALC_BOOL_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_UINT8, &i1); \ + PSI_CALC_CAST(t2, v2, =!!, PSI_T_UINT8, &i2); \ + res->u8 = PSI_CALC(i1.u8, i2.u8); \ + return PSI_T_UINT8; \ +} + +#define PSI_CALC(var1, var2) (var1) && (var2) +PSI_CALC_BOOL_FN(and) +#undef PSI_CALC +#define PSI_CALC(var1, var2) (var1) || (var2) +PSI_CALC_BOOL_FN(or) +#undef PSI_CALC + +token_t psi_calc_not(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res) +{ + (void) t2; + (void) v2; + + PSI_CALC_CAST(t1, v1, =!, t1, res); + return t1; +} + +token_t psi_calc_bin_not(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res) +{ + impl_val i1; + + (void) t2; + (void) v2; + + PSI_CALC_CAST(t1, v1, =, PSI_T_UINT64, &i1); + PSI_CALC_CAST_INT(t1, &i1, =~, t1, res); + return t1; +}