ba19f3c1dd
git-svn-id: svn://localhost/gambas/trunk@893 867c0c6c-44f3-4631-809d-bfa615b0a4ec
446 lines
7.4 KiB
C
446 lines
7.4 KiB
C
/***************************************************************************
|
|
|
|
subr_math_temp.h
|
|
|
|
Mathematical routines templates
|
|
|
|
(c) 2000-2007 Benoit Minisini <gambas@users.sourceforge.net>
|
|
|
|
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
|