📄 si_libs.c
字号:
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Lang_characterSet( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
/*
Function created 990322 by KHN
*/
{
pstructVar result = Var_New();
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (result == NULL) {
return ERR_WAE_WMLS_LIB;
}
/* The WMLS interpreter handles all strings internally in
the unicode (UCS2) format */
Var_AssignInt( result, (INT32)(IANA_CHARSET_UCS2) );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
/* Float library *************************************************************/
enumErrorCode Call_Float_int( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
#ifdef HAS_FLOAT
if (Var_ConvertMethod( CONVERT_INT_FLOAT, op1, NULL )) {
if (op1->type == typeFloat) {
if ((op1->val.theFloat >= FLOAT32_INTMAX_AS_FLOAT) || (op1->val.theFloat < INT32_MIN) ) {
Var_AssignInvalid( op1 ); /*the float is bigger/smaller than an int can be*/
}
else {
Var_AssignInt( op1, (INT32) op1->val.theFloat );
}
}
/* else int => op1 doesn't need converting */
}
else {
Var_AssignInvalid( op1 );
}
#else
Var_AssignInvalid( op1 );
#endif
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_floor( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
#ifdef HAS_FLOAT
if (Var_ConvertMethod( CONVERT_INT_FLOAT, op1, NULL )) {
if (op1->type == typeFloat) {
if ((op1->val.theFloat >= FLOAT32_INTMAX_AS_FLOAT) || (op1->val.theFloat < INT32_MIN) ) {
Var_AssignInvalid( op1 ); /*the float is bigger/smaller than an int can be*/
}
else {
Var_AssignInt( op1, (INT32)floor( op1->val.theFloat ) );
}
}
/* else int => op1 doesn't need converting */
}
else {
Var_AssignInvalid( op1 );
}
#else
Var_AssignInvalid( op1 );
#endif
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_ceil( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
#ifdef HAS_FLOAT
if (Var_ConvertMethod( CONVERT_INT_FLOAT, op1, NULL )) {
if (op1->type == typeFloat) {
if ((op1->val.theFloat >= FLOAT32_INTMAX_AS_FLOAT) || (op1->val.theFloat < INT32_MIN) ) {
Var_AssignInvalid( op1 ); /*the float is bigger/smaller than an int can be*/
}
else {
Var_AssignInt( op1, (INT32) ceil( op1->val.theFloat ) );
}
}
/* else int => op1 doesn't need converting */
}
else {
Var_AssignInvalid( op1 );
}
#else
Var_AssignInvalid( op1 );
#endif
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_pow( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op2 = RE_Pop( si->RE );
pstructVar op1 = RE_Pop( si->RE );
pstructVar result = Var_New();
BOOL op1Z,
op1LTZ,
op2LTZ,
op2Int;
#ifdef HAS_FLOAT
FLOAT32 mathresult = (FLOAT32)0;
#endif
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (result == NULL) {
Var_Delete( &op1 );
Var_Delete( &op2 );
return ERR_WAE_WMLS_LIB;
}
#ifdef HAS_FLOAT
/* clear errno so we can be sure of error/no error when checking later */
errno = 0;
if (Var_ConvertMethod( CONVERT_INTS_FLOATS, op1, op2 )) {
if (op2->type == typeInteger) { /* then both are int */
op1Z = (op1->val.theInt == 0);
op1LTZ = (op1->val.theInt < 0);
op2LTZ = (op2->val.theInt < 0);
op2Int = TRUE;
}
else { /* ops are float */
op1Z = (op1->val.theFloat == 0);
op1LTZ = (op1->val.theFloat < 0);
op2LTZ = (op2->val.theFloat < 0);
op2Int = (op2->val.theFloat == (INT32)(op2->val.theFloat));
}
if ((op1Z && op2LTZ) || (op1LTZ && (!op2Int))) {
Var_AssignInvalid( result );
}
else {
if (op2->type == typeInteger) { /* then both are int */
if (op1Z)
{ /* 0 to the power of x = 1 */
mathresult = (FLOAT32)1.0;
}
else
{
mathresult = (FLOAT32) pow((FLOAT32)op1->val.theInt, (FLOAT32)op2->val.theInt);
}
}
else {
if (op1Z)
{ /* 0 to the power of x = 1 */
mathresult = (FLOAT32)1.0;
}
else
{
mathresult = (FLOAT32) pow(op1->val.theFloat, op2->val.theFloat);
}
}
}
}
else {
Var_AssignInvalid( result );
}
if ( ((mathresult != 0) && (errno == ERANGE)) || (errno == EDOM) )
{ /* math error! */
Var_AssignInvalid( result );
}
else if ( result->type != typeInvalid )
{
Var_AssignFloat( result, mathresult );
}
/* restore errno */
errno = 0;
#else
Var_AssignInvalid( result );
#endif
Var_Delete( &op1 );
Var_Delete( &op2 );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_round( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
#ifdef HAS_FLOAT
if (Var_ConvertMethod( CONVERT_INT_FLOAT, op1, NULL )) {
if (op1->type == typeFloat) {
if ((op1->val.theFloat >= FLOAT32_INTMAX_AS_FLOAT) || (op1->val.theFloat < INT32_MIN) ) {
Var_AssignInvalid( op1 ); /*the float is bigger/smaller than an int can be*/
}
else
{
if (op1->val.theFloat >= 0)
{
Var_AssignInt( op1, (INT32)(op1->val.theFloat + 0.5) );
/* the typecast does trunc and not round, therefore the added 0.5 */
}
else if (( op1->val.theFloat - (INT32)op1->val.theFloat ) < -0.5)
{ /* -x.5 .. -x.99..., x.5 excluded */
Var_AssignInt( op1, (INT32)(op1->val.theFloat) -1 );
}
else
{ /* -x.0 .. -x.5, x.5 included */
Var_AssignInt( op1, (INT32)(op1->val.theFloat) );
}
}
}
/* else int => op1 doesn't need converting */
}
else {
Var_AssignInvalid( op1 );
}
#else
Var_AssignInvalid( op1 );
#endif
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_sqrt( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
#ifdef HAS_FLOAT
FLOAT32 mathresult;
#endif
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
#ifdef HAS_FLOAT
/* clear errno so we can be sure of error/no error when checking later */
errno = 0;
if (Var_ConvertMethod( CONVERT_FLOATS, op1, NULL ))
{
if (op1->val.theFloat < 0 )
{
Var_AssignInvalid( op1 ); /* Can't be a negative number */
}
else
{
mathresult = (FLOAT32) sqrt( op1->val.theFloat );
}
}
else {
Var_AssignInvalid( op1 );
}
if ( ((mathresult != 0) && (errno == ERANGE)) || (errno == EDOM) )
{ /* math error! */
Var_AssignInvalid( op1 );
}
else if ( op1->type != typeInvalid )
{
Var_AssignFloat( op1, mathresult );
}
/* restore errno */
errno = 0;
#else
Var_AssignInvalid( op1 );
#endif
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_maxFloat( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar result = Var_New();
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (result == NULL) {
return ERR_WAE_WMLS_LIB;
}
#ifdef HAS_FLOAT
Var_AssignFloat( result, FLOAT32_MAX );
#else
Var_AssignInvalid( result );
#endif
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_Float_minFloat( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar result = Var_New();
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (result == NULL) {
return ERR_WAE_WMLS_LIB;
}
#ifdef HAS_FLOAT
Var_AssignFloat( result, FLOAT32_MIN );
#else
Var_AssignInvalid( result );
#endif
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
/* String library *************************************************************/
enumErrorCode Call_String_length( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (Var_ConvertMethod( CONVERT_STRINGS, op1, NULL )) {
Var_AssignInt( op1, (INT32)(op1->theStringLen) );
}
else {
Var_AssignInvalid( op1 );
}
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_isEmpty( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op1 = RE_Pop( si->RE );
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (Var_ConvertMethod( CONVERT_STRINGS, op1, NULL )) {
Var_AssignBool( op1, (BOOL)(op1->theStringLen == 0) ); /* empty string */
}
else {
Var_AssignInvalid( op1 );
}
OpS_Push( si->RE->OpS, &op1 );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_charAt( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op2 = RE_Pop( si->RE ); /* string index */
pstructVar op1 = RE_Pop( si->RE ); /* the string */
pstructVar result = Var_New(); /* the result is initialized to an empty string */
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (Var_ConvertMethod( CONVERT_INT_FLOAT, op2, NULL )) {
if (op2->type == typeFloat) {
OpS_Push( si->RE->OpS, &op2 );
CallLibraryFunction( si, 1, 0 ); /* Float.int */
op2 = RE_Pop( si->RE );
}
if ( (op2->type == typeInteger) &&
Var_ConvertMethod( CONVERT_STRINGS, op1, NULL ))
{
/* now the op2 (string index) is of the type int */
if (op2->val.theInt < (INT32)op1->theStringLen)
{
/* the index is within the string */
Var_AssignString( result, 1, &(op1->val.theString[op2->val.theInt]) );
}
/* else do nothing since an empty string is the correct result (see var decl.) */
}
else Var_AssignInvalid( result );
}
else Var_AssignInvalid( result );
Var_Delete( &op2 );
Var_Delete( &op1 );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_subString( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op3 = RE_Pop( si->RE ); /* substring length */
pstructVar op2 = RE_Pop( si->RE ); /* start index */
pstructVar op1 = RE_Pop( si->RE ); /* src string */
pstructVar result = Var_New(); /* the result is initialized to an empty string */
INT32 startIndex;
INT32 stopIndex;
INT32 subStrLen;
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if (Var_ConvertMethod( CONVERT_INTS_FLOATS, op2, op3 )) {
if (op2->type == typeFloat) { /* then both are float */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -