/*************************************************************************** subr_math_temp.h Mathematical routines templates (c) 2000-2007 Benoit Minisini This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************************/ #if SMT_TYPE == 1 PUBLIC void SMT_NAME(void) { #ifdef SMT_FLOAT static void *jump[] = { &&__VARIANT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__ERROR }; #elif defined(SMT_INTEGER) static void *jump[] = { &&__VARIANT, &&__INTEGER, &&__INTEGER, &&__INTEGER, &&__INTEGER, &&__LONG, &&__ERROR, &&__ERROR, &&__ERROR }; #else static void *jump[] = { &&__VARIANT, &&__INTEGER, &&__INTEGER, &&__INTEGER, &&__INTEGER, &&__LONG, &&__FLOAT, &&__FLOAT, &&__ERROR }; #endif VALUE *P1; void *jump_end; TYPE type = EXEC_code & 0x0F; P1 = SP - 1; jump_end = &&__END; goto *jump[type]; __VARIANT: type = P1->type; if (TYPE_is_number_date(type)) { *PC |= type; goto *jump[type]; } if (TYPE_is_variant(type)) { type = P1->_variant.vtype; if (TYPE_is_number_date(type)) { VARIANT_undo(P1); jump_end = &&__VARIANT_END; goto *jump[type]; } } goto __ERROR; #ifndef SMT_FLOAT __INTEGER: #ifdef SMT_OP P1->_integer.value = SMT_OP ( P1->_integer.value ); #elif defined(SMT_FUNC_INTEGER) P1->_integer.value = SMT_FUNC_INTEGER ( P1->_integer.value ); #elif defined(SMT_FUNC) P1->_integer.value = SMT_FUNC ( P1->_integer.value ); #endif P1->type = type; goto *jump_end; __LONG: VALUE_conv(P1, T_LONG); #ifdef SMT_OP P1->_long.value = SMT_OP ( P1->_long.value ); #elif defined(SMT_FUNC_LONG) P1->_long.value = SMT_FUNC_LONG ( P1->_long.value ); #elif defined(SMT_FUNC) P1->_long.value = SMT_FUNC ( P1->_long.value ); #else #error "LONG function not defined" #endif P1->type = type; goto *jump_end; #endif #ifndef SMT_INTEGER __FLOAT: VALUE_conv(P1, T_FLOAT); #ifdef SMT_OP P1->_float.value = SMT_OP ( P1->_float.value ); #elif defined(SMT_FUNC_FLOAT) P1->_float.value = SMT_FUNC_FLOAT ( P1->_float.value ); #elif defined(SMT_FUNC) P1->_float.value = SMT_FUNC ( P1->_float.value ); #endif if (!finite(P1->_float.value)) THROW(E_MATH); goto *jump_end; #endif __ERROR: THROW(E_TYPE, "Number", TYPE_get_name(type)); __VARIANT_END: VALUE_conv(P1, T_VARIANT); __END: return; /* SP--;*/ /* if (PCODE_is_void(*PC)) SP--;*/ } #endif #if SMT_TYPE == 2 PUBLIC void SMT_NAME(void) { #ifdef SMT_FLOAT static void *jump[] = { &&__VARIANT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__FLOAT, &&__DATE }; #elif defined(SMT_INTEGER) static void *jump[] = { &&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__ERROR, &&__ERROR, &&__DATE }; #else static void *jump[] = { &&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__FLOAT, &&__FLOAT, &&__DATE }; #endif TYPE type; VALUE *P1, *P2; void *jump_end; P1 = SP - 2; P2 = P1 + 1; jump_end = &&__END; type = EXEC_code & 0x0F; goto *jump[type]; #ifndef SMT_FLOAT __BOOLEAN: __BYTE: __SHORT: __INTEGER: /* VALUE_conv(P1, type); VALUE_conv(P2, type); */ #ifdef SMT_TEST_ZERO if (P2->_integer.value == 0) THROW(E_ZERO); #endif P1->_integer.value SMT_OP P2->_integer.value; P1->type = type; goto *jump_end; __LONG: VALUE_conv(P1, T_LONG); VALUE_conv(P2, T_LONG); #ifdef SMT_TEST_ZERO if (P2->_long.value == 0) THROW(E_ZERO); #endif P1->_long.value SMT_OP P2->_long.value; P1->type = type; goto *jump_end; #endif __DATE: #ifndef SMT_DATE goto __ERROR; #endif #ifndef SMT_INTEGER __FLOAT: VALUE_conv(P1, T_FLOAT); VALUE_conv(P2, T_FLOAT); #ifdef SMT_OP P1->_float.value SMT_OP P2->_float.value; #elif defined(SMT_FUNC) P1->_float.value = SMT_FUNC ( P1->_float.value, P2->_float.value ); #endif #ifdef SMT_TEST_ZERO if (!finite(P1->_float.value)) { if (P2->_float.value == 0.0) THROW(E_ZERO); else THROW(E_MATH); } #elif defined(SMT_TEST_RESULT) if (!finite(P1->_float.value)) THROW(E_MATH); #endif goto *jump_end; #endif __VARIANT: type = Max(P1->type, P2->type); if (TYPE_is_number_date(type)) { *PC |= type; goto *jump[type]; } if (TYPE_is_variant(P1->type)) VARIANT_undo(P1); if (TYPE_is_variant(P2->type)) VARIANT_undo(P2); if (TYPE_is_string(P1->type)) VALUE_conv(P1, T_FLOAT); if (TYPE_is_string(P2->type)) VALUE_conv(P2, T_FLOAT); if (TYPE_is_null(P1->type) || TYPE_is_null(P2->type)) type = T_NULL; else type = Max(P1->type, P2->type); if (TYPE_is_number_date(type)) { jump_end = &&__VARIANT_END; goto *jump[type]; } goto __ERROR; __ERROR: THROW(E_TYPE, "Number", TYPE_get_name(type)); __VARIANT_END: VALUE_conv(P1, T_VARIANT); __END: SP--; /*if (!PCODE_is_void(*PC)) SP++;*/ } #endif #if SMT_TYPE == 3 PUBLIC void SMT_NAME(void) { static void *jump[] = { &&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__ERROR, &&__ERROR, &&__ERROR }; TYPE type; VALUE *P1, *P2; P1 = SP - 2; P2 = P1 + 1; type = *PC & 0x0F; goto *jump[type]; __VARIANT: type = Max(P1->type, P2->type); if (TYPE_is_integer_long(type)) { *PC |= type; goto *jump[type]; } if (TYPE_is_variant(P1->type)) VARIANT_undo(P1); if (TYPE_is_variant(P2->type)) VARIANT_undo(P2); if (TYPE_is_null(P1->type) || TYPE_is_null(P2->type)) type = T_NULL; else type = Max(P1->type, P2->type); if (TYPE_is_integer_long(type)) goto *jump[type]; goto __ERROR; __BOOLEAN: __BYTE: __SHORT: __INTEGER: /* VALUE_conv(P1, type); VALUE_conv(P2, type); */ if (P2->_integer.value == 0) THROW(E_ZERO); P1->_integer.value SMT_OP P2->_integer.value; P1->type = T_INTEGER; goto __END; __LONG: VALUE_conv(P1, T_LONG); VALUE_conv(P2, T_LONG); if (P2->_long.value == 0) THROW(E_ZERO); P1->_long.value SMT_OP P2->_long.value; P1->type = T_LONG; goto __END; __ERROR: THROW(E_TYPE, "Integer", TYPE_get_name(type)); __END: SP--; /*if (!PCODE_is_void(*PC)) SP++;*/ } #endif #undef SMT_TYPE #undef SMT_NAME #ifdef SMT_OP #undef SMT_OP #endif #ifdef SMT_FUNC #undef SMT_FUNC #endif #ifdef SMT_FUNC_INTEGER #undef SMT_FUNC_INTEGER #endif #ifdef SMT_FUNC_LONG #undef SMT_FUNC_LONG #endif #ifdef SMT_FUNC_FLOAT #undef SMT_FUNC_FLOAT #endif #ifdef SMT_FLOAT #undef SMT_FLOAT #endif #ifdef SMT_DATE #undef SMT_DATE #endif #ifdef SMT_INTEGER #undef SMT_INTEGER #endif #ifdef SMT_TEST_ZERO #undef SMT_TEST_ZERO #endif #ifdef SMT_CHECK_FLOAT #undef SMT_CHECK_FLOAT #endif #ifdef SMT_RESULT #undef SMT_RESULT #endif