00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "slinclud.h"
00024
00025 #include <math.h>
00026 #include <limits.h>
00027
00028 #ifdef HAVE_LOCALE_H
00029 # include <locale.h>
00030 #endif
00031
00032 #if SLANG_HAS_FLOAT
00033 # include <float.h>
00034 # ifdef HAVE_FLOATINGPOINT_H
00035 # include <floatingpoint.h>
00036 # endif
00037
00038 # ifdef HAVE_IEEEFP_H
00039 # include <ieeefp.h>
00040 # endif
00041
00042 # ifdef HAVE_NAN_H
00043 # include <nan.h>
00044 # endif
00045
00046 #endif
00047
00048 #include "slang.h"
00049 #include "_slang.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #ifdef HAVE_LONG_LONG
00096 # define MAX_SLARITH_INT_TYPE SLANG_ULLONG_TYPE
00097 #else
00098 # define MAX_SLARITH_INT_TYPE SLANG_ULONG_TYPE
00099 #endif
00100
00101 #define MAX_SLARITH_TYPE SLANG_LDOUBLE_TYPE
00102
00103 #define MAX_ARITHMETIC_TYPES (MAX_SLARITH_TYPE-SLANG_CHAR_TYPE+1)
00104 #define TYPE_TO_TABLE_INDEX(t) ((t)-SLANG_CHAR_TYPE)
00105 #define TABLE_INDEX_TO_TYPE(i) ((i)+SLANG_CHAR_TYPE)
00106
00107 #define IS_INTEGER_TYPE(t) \
00108 (((t) >= SLANG_CHAR_TYPE) && ((t) <= MAX_SLARITH_INT_TYPE))
00109
00110
00111 SLtype _pSLarith_Arith_Types [MAX_ARITHMETIC_TYPES+1] =
00112 {
00113 SLANG_CHAR_TYPE,
00114 SLANG_UCHAR_TYPE,
00115 SLANG_SHORT_TYPE,
00116 SLANG_USHORT_TYPE,
00117 SLANG_INT_TYPE,
00118 SLANG_UINT_TYPE,
00119 SLANG_LONG_TYPE,
00120 SLANG_ULONG_TYPE,
00121 #ifdef HAVE_LONG_LONG
00122 SLANG_LLONG_TYPE, SLANG_ULLONG_TYPE,
00123 #endif
00124 #ifdef SLANG_HAS_FLOAT
00125 SLANG_FLOAT_TYPE,
00126 SLANG_DOUBLE_TYPE,
00127 # ifdef HAVE_LONG_DOUBLE
00128 SLANG_LDOUBLE_TYPE,
00129 # endif
00130 #endif
00131 0
00132 };
00133
00134 static SLtype Alias_Map [MAX_ARITHMETIC_TYPES];
00135
00136
00137
00138
00139
00140 #define DEFUN_1(f,from_type,to_type) \
00141 static void f (to_type *y, from_type *x, unsigned int n) \
00142 { \
00143 unsigned int i; \
00144 for (i = 0; i < n; i++) y[i] = (to_type) x[i]; \
00145 }
00146
00147 #define DEFUN_2(f,from_type,to_type,copy_fun) \
00148 static VOID_STAR f (VOID_STAR xp, unsigned int n) \
00149 { \
00150 from_type *x; \
00151 to_type *y; \
00152 x = (from_type *) xp; \
00153 if (NULL == (y = (to_type *) SLmalloc (sizeof (to_type) * n))) return NULL; \
00154 copy_fun (y, x, n); \
00155 return (VOID_STAR) y; \
00156 }
00157 typedef VOID_STAR (*Convert_Fun_Type)(VOID_STAR, unsigned int);
00158
00159 #if SLANG_HAS_FLOAT
00160 #define TO_DOUBLE_FUN(name,type) \
00161 static double name (VOID_STAR x) { return (double) *(type *) x; }
00162
00163 typedef SLCONST struct
00164 {
00165 unsigned int sizeof_type;
00166 double (*to_double_fun)(VOID_STAR);
00167 }
00168 To_Double_Fun_Table_Type;
00169
00170 #endif
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 typedef struct
00184 {
00185 FVOID_STAR copy_function;
00186 Convert_Fun_Type convert_function;
00187 }
00188 Binary_Matrix_Type;
00189
00190 #include "slarith2.inc"
00191
00192 #if SLANG_HAS_FLOAT
00193 SLang_To_Double_Fun_Type
00194 SLarith_get_to_double_fun (SLtype type, unsigned int *sizeof_type)
00195 {
00196 To_Double_Fun_Table_Type *t;
00197
00198 if ((type < SLANG_CHAR_TYPE) || (type > MAX_SLARITH_TYPE))
00199 return NULL;
00200
00201 t = To_Double_Fun_Table + (type - SLANG_CHAR_TYPE);
00202 if ((sizeof_type != NULL)
00203 && (t->to_double_fun != NULL))
00204 *sizeof_type = t->sizeof_type;
00205
00206 return t->to_double_fun;
00207 }
00208 #endif
00209
00210 #define GENERIC_BINARY_FUNCTION int_int_bin_op
00211 #define GENERIC_BIT_OPERATIONS
00212 #define GENERIC_TYPE int
00213 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00214 #define POW_RESULT_TYPE double
00215 #define ABS_FUNCTION abs
00216 #define MOD_FUNCTION(a,b) ((a) % (b))
00217 #define TRAP_DIV_ZERO 1
00218 #define GENERIC_UNARY_FUNCTION int_unary_op
00219 #define GENERIC_ARITH_UNARY_FUNCTION int_arith_unary_op
00220 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00221 #if SLANG_OPTIMIZE_FOR_SPEED
00222 # define SCALAR_BINARY_FUNCTION int_int_scalar_bin_op
00223 #endif
00224 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_int_obj(SLANG_INT_TYPE,(x))
00225 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00226 #define CMP_FUNCTION int_cmp_function
00227 #include "slarith.inc"
00228
00229 #define GENERIC_BINARY_FUNCTION uint_uint_bin_op
00230 #define GENERIC_BIT_OPERATIONS
00231 #define GENERIC_TYPE unsigned int
00232 #define GENERIC_TYPE_IS_UNSIGNED
00233 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00234 #define POW_RESULT_TYPE double
00235 #define MOD_FUNCTION(a,b) ((a) % (b))
00236 #define TRAP_DIV_ZERO 1
00237 #define GENERIC_UNARY_FUNCTION uint_unary_op
00238 #define GENERIC_ARITH_UNARY_FUNCTION uint_arith_unary_op
00239 #define ABS_FUNCTION(a) (a)
00240 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
00241 #if SLANG_OPTIMIZE_FOR_SPEED
00242 # define SCALAR_BINARY_FUNCTION uint_uint_scalar_bin_op
00243 #endif
00244 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_int_obj(SLANG_UINT_TYPE,(int)(x))
00245 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00246 #define CMP_FUNCTION uint_cmp_function
00247 #include "slarith.inc"
00248
00249 #if LONG_IS_NOT_INT
00250 #define GENERIC_BINARY_FUNCTION long_long_bin_op
00251 #define GENERIC_BIT_OPERATIONS
00252 #define GENERIC_TYPE long
00253 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00254 #define POW_RESULT_TYPE double
00255 #define MOD_FUNCTION(a,b) ((a) % (b))
00256 #define TRAP_DIV_ZERO 1
00257 #define GENERIC_UNARY_FUNCTION long_unary_op
00258 #define GENERIC_ARITH_UNARY_FUNCTION long_arith_unary_op
00259 #define ABS_FUNCTION(a) (((a) >= 0) ? (a) : -(a))
00260 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00261 #if SLANG_OPTIMIZE_FOR_SPEED
00262 # define SCALAR_BINARY_FUNCTION long_long_scalar_bin_op
00263 #endif
00264 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_long_obj(SLANG_LONG_TYPE,(x))
00265 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00266 #define CMP_FUNCTION long_cmp_function
00267 #include "slarith.inc"
00268
00269 #define GENERIC_BINARY_FUNCTION ulong_ulong_bin_op
00270 #define GENERIC_BIT_OPERATIONS
00271 #define GENERIC_TYPE unsigned long
00272 #define GENERIC_TYPE_IS_UNSIGNED
00273 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00274 #define POW_RESULT_TYPE double
00275 #define MOD_FUNCTION(a,b) ((a) % (b))
00276 #define TRAP_DIV_ZERO 1
00277 #define GENERIC_UNARY_FUNCTION ulong_unary_op
00278 #define GENERIC_ARITH_UNARY_FUNCTION ulong_arith_unary_op
00279 #define ABS_FUNCTION(a) (a)
00280 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
00281 #if SLANG_OPTIMIZE_FOR_SPEED
00282 # define SCALAR_BINARY_FUNCTION ulong_ulong_scalar_bin_op
00283 #endif
00284 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_long_obj(SLANG_ULONG_TYPE,(long)(x))
00285 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00286 #define CMP_FUNCTION ulong_cmp_function
00287 #include "slarith.inc"
00288 #else
00289 #define long_long_bin_op int_int_bin_op
00290 #define ulong_ulong_bin_op uint_uint_bin_op
00291 #define long_unary_op int_unary_op
00292 #define ulong_unary_op uint_unary_op
00293 #define long_cmp_function int_cmp_function
00294 #define ulong_cmp_function uint_cmp_function
00295 #endif
00296
00297 #ifdef HAVE_LONG_LONG
00298 #define GENERIC_BINARY_FUNCTION llong_llong_bin_op
00299 #define GENERIC_BIT_OPERATIONS
00300 #define GENERIC_TYPE long long
00301 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00302 #define POW_RESULT_TYPE double
00303 #define MOD_FUNCTION(a,b) ((a) % (b))
00304 #define TRAP_DIV_ZERO 1
00305 #define GENERIC_UNARY_FUNCTION llong_unary_op
00306 #define GENERIC_ARITH_UNARY_FUNCTION llong_arith_unary_op
00307 #define ABS_FUNCTION(a) (((a) >= 0) ? (a) : -(a))
00308 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00309 #if SLANG_OPTIMIZE_FOR_SPEED
00310 # define SCALAR_BINARY_FUNCTION llong_llong_scalar_bin_op
00311 #endif
00312 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_llong_obj(SLANG_LLONG_TYPE,(x))
00313 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00314 #define CMP_FUNCTION llong_cmp_function
00315 #include "slarith.inc"
00316
00317 #define GENERIC_BINARY_FUNCTION ullong_ullong_bin_op
00318 #define GENERIC_BIT_OPERATIONS
00319 #define GENERIC_TYPE unsigned long long
00320 #define GENERIC_TYPE_IS_UNSIGNED
00321 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00322 #define POW_RESULT_TYPE double
00323 #define MOD_FUNCTION(a,b) ((a) % (b))
00324 #define TRAP_DIV_ZERO 1
00325 #define GENERIC_UNARY_FUNCTION ullong_unary_op
00326 #define GENERIC_ARITH_UNARY_FUNCTION ullong_arith_unary_op
00327 #define ABS_FUNCTION(a) (a)
00328 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
00329 #if SLANG_OPTIMIZE_FOR_SPEED
00330 # define SCALAR_BINARY_FUNCTION ullong_ullong_scalar_bin_op
00331 #endif
00332 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_llong_obj(SLANG_ULLONG_TYPE,(long long)(x))
00333 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00334 #define CMP_FUNCTION ullong_cmp_function
00335 #include "slarith.inc"
00336 #endif
00337
00338 #if SLANG_HAS_FLOAT
00339 #define GENERIC_BINARY_FUNCTION float_float_bin_op
00340 #define GENERIC_TYPE float
00341 #define POW_FUNCTION(a,b) (float)pow((double)(a),(double)(b))
00342 #define POW_RESULT_TYPE float
00343 #define MOD_FUNCTION(a,b) (float)fmod((a),(b))
00344 #define TRAP_DIV_ZERO 0
00345 #define GENERIC_UNARY_FUNCTION float_unary_op
00346 #define GENERIC_ARITH_UNARY_FUNCTION float_arith_unary_op
00347 #define ABS_FUNCTION(a) (float)fabs((double) a)
00348 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00349 #if SLANG_OPTIMIZE_FOR_SPEED
00350 # define SCALAR_BINARY_FUNCTION float_float_scalar_bin_op
00351 #endif
00352 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_float_obj(SLANG_FLOAT_TYPE,(x))
00353 #define PUSH_POW_OBJ_FUN(x) SLclass_push_float_obj(SLANG_FLOAT_TYPE, (x))
00354 #define CMP_FUNCTION float_cmp_function
00355 #include "slarith.inc"
00356
00357 #define GENERIC_BINARY_FUNCTION double_double_bin_op
00358 #define GENERIC_TYPE double
00359 #define POW_FUNCTION(a,b) pow((double)(a),(double)(b))
00360 #define POW_RESULT_TYPE double
00361 #define MOD_FUNCTION(a,b) (float)fmod((a),(b))
00362 #define TRAP_DIV_ZERO 0
00363 #define GENERIC_UNARY_FUNCTION double_unary_op
00364 #define GENERIC_ARITH_UNARY_FUNCTION double_arith_unary_op
00365 #define ABS_FUNCTION(a) fabs(a)
00366 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00367 #if SLANG_OPTIMIZE_FOR_SPEED
00368 # define SCALAR_BINARY_FUNCTION double_double_scalar_bin_op
00369 #endif
00370 #define PUSH_SCALAR_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE,(x))
00371 #define PUSH_POW_OBJ_FUN(x) SLclass_push_double_obj(SLANG_DOUBLE_TYPE, (x))
00372 #define CMP_FUNCTION double_cmp_function
00373 #include "slarith.inc"
00374 #endif
00375
00376 #define GENERIC_UNARY_FUNCTION char_unary_op
00377 #define GENERIC_ARITH_UNARY_FUNCTION char_arith_unary_op
00378 #define GENERIC_BIT_OPERATIONS
00379 #define GENERIC_TYPE signed char
00380 #define ABS_FUNCTION abs
00381 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00382 #define CMP_FUNCTION char_cmp_function
00383 #include "slarith.inc"
00384
00385 #define GENERIC_UNARY_FUNCTION uchar_unary_op
00386 #define GENERIC_ARITH_UNARY_FUNCTION uchar_arith_unary_op
00387 #define GENERIC_BIT_OPERATIONS
00388 #define GENERIC_TYPE unsigned char
00389 #define GENERIC_TYPE_IS_UNSIGNED
00390 #define ABS_FUNCTION(x) (x)
00391 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
00392 #define CMP_FUNCTION uchar_cmp_function
00393 #include "slarith.inc"
00394
00395 #if SHORT_IS_NOT_INT
00396 #define GENERIC_UNARY_FUNCTION short_unary_op
00397 #define GENERIC_ARITH_UNARY_FUNCTION short_arith_unary_op
00398 #define GENERIC_BIT_OPERATIONS
00399 #define GENERIC_TYPE short
00400 #define ABS_FUNCTION abs
00401 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
00402 #define CMP_FUNCTION short_cmp_function
00403 #include "slarith.inc"
00404
00405 #define GENERIC_UNARY_FUNCTION ushort_unary_op
00406 #define GENERIC_ARITH_UNARY_FUNCTION ushort_arith_unary_op
00407 #define GENERIC_BIT_OPERATIONS
00408 #define GENERIC_TYPE unsigned short
00409 #define GENERIC_TYPE_IS_UNSIGNED
00410 #define ABS_FUNCTION(x) (x)
00411 #define SIGN_FUNCTION(x) (((x) > 0) ? 1 : 0)
00412 #define CMP_FUNCTION ushort_cmp_function
00413 #include "slarith.inc"
00414 #endif
00415
00416
00417 int _pSLarith_get_precedence (SLtype type)
00418 {
00419 if ((type < SLANG_CHAR_TYPE) || (type > MAX_SLARITH_TYPE))
00420 return -1;
00421
00422 type = Alias_Map[TYPE_TO_TABLE_INDEX(type)];
00423 return type - SLANG_CHAR_TYPE;
00424 }
00425
00426 SLtype _pSLarith_promote_type (SLtype t)
00427 {
00428 t = Alias_Map[TYPE_TO_TABLE_INDEX(t)];
00429
00430 switch (t)
00431 {
00432 case SLANG_INT_TYPE:
00433 case SLANG_UINT_TYPE:
00434 case SLANG_LONG_TYPE:
00435 case SLANG_ULONG_TYPE:
00436 #ifdef HAVE_LONG_LONG
00437 case SLANG_LLONG_TYPE:
00438 case SLANG_ULLONG_TYPE:
00439 #endif
00440 case SLANG_FLOAT_TYPE:
00441 case SLANG_DOUBLE_TYPE:
00442 break;
00443
00444 case SLANG_USHORT_TYPE:
00445 #if SHORT_IS_INT
00446 t = SLANG_UINT_TYPE;
00447 break;
00448 #endif
00449
00450 case SLANG_CHAR_TYPE:
00451 case SLANG_UCHAR_TYPE:
00452 case SLANG_SHORT_TYPE:
00453 default:
00454 t = SLANG_INT_TYPE;
00455 }
00456
00457 return t;
00458 }
00459
00460 static SLtype promote_to_common_type (SLtype a, SLtype b)
00461 {
00462 a = _pSLarith_promote_type (a);
00463 b = _pSLarith_promote_type (b);
00464
00465 return (a > b) ? a : b;
00466 }
00467
00468 static int arith_bin_op_result (int op, SLtype a_type, SLtype b_type,
00469 SLtype *c_type)
00470 {
00471 switch (op)
00472 {
00473 case SLANG_EQ:
00474 case SLANG_NE:
00475 case SLANG_GT:
00476 case SLANG_GE:
00477 case SLANG_LT:
00478 case SLANG_LE:
00479 case SLANG_OR:
00480 case SLANG_AND:
00481 *c_type = SLANG_CHAR_TYPE;
00482 return 1;
00483 #if SLANG_HAS_FLOAT
00484 case SLANG_POW:
00485 if (SLANG_FLOAT_TYPE == promote_to_common_type (a_type, b_type))
00486 *c_type = SLANG_FLOAT_TYPE;
00487 else
00488 *c_type = SLANG_DOUBLE_TYPE;
00489 return 1;
00490 #endif
00491 case SLANG_BAND:
00492 case SLANG_BXOR:
00493 case SLANG_BOR:
00494 case SLANG_SHL:
00495 case SLANG_SHR:
00496
00497 if ((0 == IS_INTEGER_TYPE (a_type))
00498 || (0 == IS_INTEGER_TYPE(b_type)))
00499 return 0;
00500 break;
00501
00502 default:
00503 break;
00504 }
00505
00506 *c_type = promote_to_common_type (a_type, b_type);
00507 return 1;
00508 }
00509
00510 typedef int (*Bin_Fun_Type) (int,
00511 SLtype, VOID_STAR, unsigned int,
00512 SLtype, VOID_STAR, unsigned int,
00513 VOID_STAR);
00514
00515
00516
00517
00518 static Bin_Fun_Type Bin_Fun_Map [MAX_ARITHMETIC_TYPES] =
00519 {
00520 NULL,
00521 NULL,
00522 NULL,
00523 NULL,
00524 int_int_bin_op,
00525 uint_uint_bin_op,
00526 long_long_bin_op,
00527 ulong_ulong_bin_op,
00528 #ifdef HAVE_LONG_LONG
00529 llong_llong_bin_op,
00530 ullong_ullong_bin_op,
00531 #else
00532 NULL, NULL,
00533 #endif
00534 float_float_bin_op,
00535 double_double_bin_op
00536 };
00537
00538 static int arith_bin_op (int op,
00539 SLtype a_type, VOID_STAR ap, unsigned int na,
00540 SLtype b_type, VOID_STAR bp, unsigned int nb,
00541 VOID_STAR cp)
00542 {
00543 Convert_Fun_Type af, bf;
00544 Bin_Fun_Type binfun;
00545 int a_indx, b_indx, c_indx;
00546 SLtype c_type;
00547 int ret;
00548
00549 c_type = promote_to_common_type (a_type, b_type);
00550
00551 a_indx = TYPE_TO_TABLE_INDEX(a_type);
00552 b_indx = TYPE_TO_TABLE_INDEX(b_type);
00553 c_indx = TYPE_TO_TABLE_INDEX(c_type);
00554
00555 af = Binary_Matrix[a_indx][c_indx].convert_function;
00556 bf = Binary_Matrix[b_indx][c_indx].convert_function;
00557 binfun = Bin_Fun_Map[c_indx];
00558
00559 if ((af != NULL)
00560 && (NULL == (ap = (VOID_STAR) (*af) (ap, na))))
00561 return -1;
00562
00563 if ((bf != NULL)
00564 && (NULL == (bp = (VOID_STAR) (*bf) (bp, nb))))
00565 {
00566 if (af != NULL) SLfree ((char *) ap);
00567 return -1;
00568 }
00569
00570 ret = (*binfun) (op, a_type, ap, na, b_type, bp, nb, cp);
00571 if (af != NULL) SLfree ((char *) ap);
00572 if (bf != NULL) SLfree ((char *) bp);
00573
00574 return ret;
00575 }
00576
00577 static int arith_unary_op_result (int op, SLtype a, SLtype *b)
00578 {
00579 (void) a;
00580 switch (op)
00581 {
00582 default:
00583 return 0;
00584
00585 case SLANG_SQR:
00586 case SLANG_MUL2:
00587 case SLANG_PLUSPLUS:
00588 case SLANG_MINUSMINUS:
00589 case SLANG_CHS:
00590 case SLANG_ABS:
00591 *b = a;
00592 break;
00593
00594 case SLANG_BNOT:
00595 if (0 == IS_INTEGER_TYPE(a))
00596 return 0;
00597 *b = a;
00598 break;
00599
00600 case SLANG_SIGN:
00601 *b = SLANG_INT_TYPE;
00602 break;
00603
00604 case SLANG_NOT:
00605 case SLANG_ISPOS:
00606 case SLANG_ISNEG:
00607 case SLANG_ISNONNEG:
00608 *b = SLANG_CHAR_TYPE;
00609 break;
00610 }
00611 return 1;
00612 }
00613
00614
00615 static int integer_pop (SLtype type, VOID_STAR ptr)
00616 {
00617 SLang_Object_Type obj;
00618 int i, j;
00619 void (*f)(VOID_STAR, VOID_STAR, unsigned int);
00620
00621 if (-1 == SLang_pop (&obj))
00622 return -1;
00623
00624 if (0 == IS_INTEGER_TYPE(obj.data_type))
00625 {
00626 _pSLclass_type_mismatch_error (type, obj.data_type);
00627 SLang_free_object (&obj);
00628 return -1;
00629 }
00630
00631 i = TYPE_TO_TABLE_INDEX(type);
00632 j = TYPE_TO_TABLE_INDEX(obj.data_type);
00633 f = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
00634 Binary_Matrix[j][i].copy_function;
00635
00636 (*f) (ptr, (VOID_STAR)&obj.v, 1);
00637
00638 return 0;
00639 }
00640
00641 static int integer_push (SLtype type, VOID_STAR ptr)
00642 {
00643 SLang_Object_Type obj;
00644 int i;
00645 void (*f)(VOID_STAR, VOID_STAR, unsigned int);
00646
00647 i = TYPE_TO_TABLE_INDEX(type);
00648 f = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
00649 Binary_Matrix[i][i].copy_function;
00650
00651 obj.data_type = type;
00652
00653 (*f) ((VOID_STAR)&obj.v, ptr, 1);
00654
00655 return SLang_push (&obj);
00656 }
00657
00658 int SLang_pop_char (char *i)
00659 {
00660 return integer_pop (SLANG_CHAR_TYPE, (VOID_STAR) i);
00661 }
00662
00663 int SLang_pop_uchar (unsigned char *i)
00664 {
00665 return integer_pop (SLANG_UCHAR_TYPE, (VOID_STAR) i);
00666 }
00667
00668 int SLang_pop_short (short *i)
00669 {
00670 return integer_pop (_pSLANG_SHORT_TYPE, (VOID_STAR) i);
00671 }
00672
00673 int SLang_pop_ushort (unsigned short *i)
00674 {
00675 return integer_pop (_pSLANG_USHORT_TYPE, (VOID_STAR) i);
00676 }
00677
00678 int SLang_pop_long (long *i)
00679 {
00680 return integer_pop (_pSLANG_LONG_TYPE, (VOID_STAR) i);
00681 }
00682
00683 int SLang_pop_ulong (unsigned long *i)
00684 {
00685 return integer_pop (_pSLANG_ULONG_TYPE, (VOID_STAR) i);
00686 }
00687
00688 #ifdef HAVE_LONG_LONG
00689
00690 static void llong_byte_code_destroy (SLtype unused, VOID_STAR ptr)
00691 {
00692 (void) unused;
00693 SLfree (*(char **) ptr);
00694 }
00695
00696 int SLang_pop_long_long (long long *i)
00697 {
00698 return integer_pop (_pSLANG_LLONG_TYPE, (VOID_STAR) i);
00699 }
00700
00701 int SLang_pop_ulong_long (unsigned long long *i)
00702 {
00703 return integer_pop (_pSLANG_ULLONG_TYPE, (VOID_STAR) i);
00704 }
00705 #endif
00706
00707 int SLang_pop_uint (unsigned int *i)
00708 {
00709 return integer_pop (SLANG_UINT_TYPE, (VOID_STAR) i);
00710 }
00711
00712 int SLang_push_int (int i)
00713 {
00714 return SLclass_push_int_obj (SLANG_INT_TYPE, i);
00715 }
00716 int SLang_push_uint (unsigned int i)
00717 {
00718 return SLclass_push_int_obj (SLANG_UINT_TYPE, (int) i);
00719 }
00720 int SLang_push_char (char i)
00721 {
00722 return SLclass_push_char_obj (SLANG_CHAR_TYPE, i);
00723 }
00724
00725 int SLang_push_uchar (unsigned char i)
00726 {
00727 return SLclass_push_char_obj (SLANG_UCHAR_TYPE, (char) i);
00728 }
00729 int SLang_push_short (short i)
00730 {
00731 return SLclass_push_short_obj (_pSLANG_SHORT_TYPE, i);
00732 }
00733 int SLang_push_ushort (unsigned short i)
00734 {
00735 return SLclass_push_short_obj (_pSLANG_USHORT_TYPE, (unsigned short) i);
00736 }
00737 int SLang_push_long (long i)
00738 {
00739 return SLclass_push_long_obj (_pSLANG_LONG_TYPE, i);
00740 }
00741 int SLang_push_ulong (unsigned long i)
00742 {
00743 return SLclass_push_long_obj (_pSLANG_ULONG_TYPE, (long) i);
00744 }
00745
00746 #if HAVE_LONG_LONG
00747 int SLang_push_long_long (long long i)
00748 {
00749 return SLclass_push_llong_obj (_pSLANG_LLONG_TYPE, i);
00750 }
00751 int SLang_push_ulong_long (unsigned long long i)
00752 {
00753 return SLclass_push_llong_obj (_pSLANG_ULLONG_TYPE, (long long) i);
00754 }
00755 #endif
00756
00757 _INLINE_
00758 int _pSLarith_typecast (SLtype a_type, VOID_STAR ap, unsigned int na,
00759 SLtype b_type, VOID_STAR bp)
00760 {
00761 int i, j;
00762
00763 void (*copy)(VOID_STAR, VOID_STAR, unsigned int);
00764
00765 i = TYPE_TO_TABLE_INDEX (a_type);
00766 j = TYPE_TO_TABLE_INDEX (b_type);
00767
00768 copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int))
00769 Binary_Matrix[i][j].copy_function;
00770
00771 (*copy) (bp, ap, na);
00772 return 1;
00773 }
00774
00775 #if SLANG_HAS_FLOAT
00776
00777 int SLang_pop_double (double *x)
00778 {
00779 SLang_Object_Type obj;
00780
00781 if (0 != SLang_pop (&obj))
00782 return -1;
00783
00784 switch (obj.data_type)
00785 {
00786 case SLANG_FLOAT_TYPE:
00787 *x = (double) obj.v.float_val;
00788 break;
00789
00790 case SLANG_DOUBLE_TYPE:
00791 *x = obj.v.double_val;
00792 break;
00793
00794 case SLANG_INT_TYPE:
00795 *x = (double) obj.v.int_val;
00796 break;
00797
00798 case SLANG_CHAR_TYPE: *x = (double) obj.v.char_val; break;
00799 case SLANG_UCHAR_TYPE: *x = (double) obj.v.uchar_val; break;
00800 case SLANG_SHORT_TYPE: *x = (double) obj.v.short_val; break;
00801 case SLANG_USHORT_TYPE: *x = (double) obj.v.ushort_val; break;
00802 case SLANG_UINT_TYPE: *x = (double) obj.v.uint_val; break;
00803 case SLANG_LONG_TYPE: *x = (double) obj.v.long_val; break;
00804 case SLANG_ULONG_TYPE: *x = (double) obj.v.ulong_val; break;
00805 #ifdef HAVE_LONG_LONG
00806 case SLANG_LLONG_TYPE: *x = (double) obj.v.llong_val; break;
00807 case SLANG_ULLONG_TYPE: *x = (double) obj.v.ullong_val; break;
00808 #endif
00809 default:
00810 _pSLclass_type_mismatch_error (SLANG_DOUBLE_TYPE, obj.data_type);
00811 SLang_free_object (&obj);
00812 return -1;
00813 }
00814 return 0;
00815 }
00816
00817 int SLang_push_double (double x)
00818 {
00819 return SLclass_push_double_obj (SLANG_DOUBLE_TYPE, x);
00820 }
00821
00822 int SLang_pop_float (float *x)
00823 {
00824 double d;
00825
00826
00827 if (-1 == SLang_pop_double (&d))
00828 return -1;
00829
00830 *x = (float) d;
00831 return 0;
00832 }
00833
00834 int SLang_push_float (float f)
00835 {
00836 return SLclass_push_float_obj (SLANG_FLOAT_TYPE, (double) f);
00837 }
00838
00839
00840 static int double_push (SLtype type, VOID_STAR ptr)
00841 {
00842 #if SLANG_OPTIMIZE_FOR_SPEED
00843 SLang_Object_Type obj;
00844 obj.data_type = type;
00845 obj.v.double_val = *(double *)ptr;
00846 return SLang_push (&obj);
00847 #else
00848 return SLclass_push_double_obj (type, *(double *) ptr);
00849 #endif
00850 }
00851
00852 static int double_push_literal (SLtype type, VOID_STAR ptr)
00853 {
00854 return SLclass_push_double_obj (type, **(double **)ptr);
00855 }
00856
00857 static int double_pop (SLtype unused, VOID_STAR ptr)
00858 {
00859 (void) unused;
00860 return SLang_pop_double ((double *) ptr);
00861 }
00862
00863 static void double_byte_code_destroy (SLtype unused, VOID_STAR ptr)
00864 {
00865 (void) unused;
00866 SLfree (*(char **) ptr);
00867 }
00868
00869 static int float_push (SLtype unused, VOID_STAR ptr)
00870 {
00871 (void) unused;
00872 SLang_push_float (*(float *) ptr);
00873 return 0;
00874 }
00875
00876 static int float_pop (SLtype unused, VOID_STAR ptr)
00877 {
00878 (void) unused;
00879 return SLang_pop_float ((float *) ptr);
00880 }
00881
00882 #endif
00883
00884 #if SLANG_HAS_FLOAT
00885 static char Double_Format[16] = "%g";
00886
00887 void _pSLset_double_format (char *s)
00888 {
00889 strncpy (Double_Format, s, 15);
00890 Double_Format[15] = 0;
00891 }
00892 #endif
00893
00894 static char *arith_string (SLtype type, VOID_STAR v)
00895 {
00896 char buf [1024];
00897 char *s;
00898
00899 s = buf;
00900
00901 switch (type)
00902 {
00903 default:
00904 s = SLclass_get_datatype_name (type);
00905 break;
00906
00907 case SLANG_CHAR_TYPE:
00908 sprintf (s, "%d", *(char *) v);
00909 break;
00910 case SLANG_UCHAR_TYPE:
00911 sprintf (s, "%u", *(unsigned char *) v);
00912 break;
00913 case SLANG_SHORT_TYPE:
00914 sprintf (s, "%d", *(short *) v);
00915 break;
00916 case SLANG_USHORT_TYPE:
00917 sprintf (s, "%u", *(unsigned short *) v);
00918 break;
00919 case SLANG_INT_TYPE:
00920 sprintf (s, "%d", *(int *) v);
00921 break;
00922 case SLANG_UINT_TYPE:
00923 sprintf (s, "%u", *(unsigned int *) v);
00924 break;
00925 case SLANG_LONG_TYPE:
00926 sprintf (s, "%ld", *(long *) v);
00927 break;
00928 case SLANG_ULONG_TYPE:
00929 sprintf (s, "%lu", *(unsigned long *) v);
00930 break;
00931 #ifdef HAVE_LONG_LONG
00932 case SLANG_LLONG_TYPE:
00933 sprintf (s, "%lld", *(long long *) v);
00934 break;
00935 case SLANG_ULLONG_TYPE:
00936 sprintf (s, "%llu", *(unsigned long long *) v);
00937 break;
00938 #endif
00939 #if SLANG_HAS_FLOAT
00940 case SLANG_FLOAT_TYPE:
00941 if (EOF == SLsnprintf (buf, sizeof (buf), Double_Format, *(float *) v))
00942 sprintf (s, "%e", *(float *) v);
00943 break;
00944 case SLANG_DOUBLE_TYPE:
00945 if (EOF == SLsnprintf (buf, sizeof (buf), Double_Format, *(double *) v))
00946 sprintf (s, "%e", *(double *) v);
00947 break;
00948 #endif
00949 }
00950
00951 return SLmake_string (s);
00952 }
00953
00954 static int integer_to_bool (SLtype type, int *t)
00955 {
00956 (void) type;
00957 return SLang_pop_integer (t);
00958 }
00959
00960
00961
00962
00963 static int push_int_literal (SLtype type, VOID_STAR ptr)
00964 {
00965 return SLclass_push_int_obj (type, (int) *(long *) ptr);
00966 }
00967
00968 static int push_char_literal (SLtype type, VOID_STAR ptr)
00969 {
00970 return SLclass_push_char_obj (type, (char) *(long *) ptr);
00971 }
00972
00973 #if SHORT_IS_NOT_INT
00974 static int push_short_literal (SLtype type, VOID_STAR ptr)
00975 {
00976 return SLclass_push_short_obj (type, (short) *(long *) ptr);
00977 }
00978 #endif
00979
00980 #if LONG_IS_NOT_INT
00981 static int push_long_literal (SLtype type, VOID_STAR ptr)
00982 {
00983 return SLclass_push_long_obj (type, *(long *) ptr);
00984 }
00985 #endif
00986
00987 #ifdef HAVE_LONG_LONG
00988 static int push_llong_literal (SLtype type, VOID_STAR ptr)
00989 {
00990 return SLclass_push_llong_obj (type, **(long long **)ptr);
00991 }
00992 #endif
00993 typedef struct
00994 {
00995 char *name;
00996 SLtype data_type;
00997 unsigned int sizeof_type;
00998 int (*unary_fun)(int, SLtype, VOID_STAR, unsigned int, VOID_STAR);
00999 int (*push_literal) (SLtype, VOID_STAR);
01000 void (*byte_code_destroy)(SLtype, VOID_STAR);
01001 int (*cmp_fun) (SLtype, VOID_STAR, VOID_STAR, int *);
01002 }
01003 Integer_Info_Type;
01004
01005 #ifdef HAVE_LONG_LONG
01006 # define NUM_INTEGER_TYPES 10
01007 #else
01008 # define NUM_INTEGER_TYPES 8
01009 #endif
01010 static Integer_Info_Type Integer_Types [NUM_INTEGER_TYPES] =
01011 {
01012 {"Char_Type", SLANG_CHAR_TYPE, sizeof (char), char_unary_op, push_char_literal, NULL, char_cmp_function},
01013 {"UChar_Type", SLANG_UCHAR_TYPE, sizeof (unsigned char), uchar_unary_op, push_char_literal, NULL, uchar_cmp_function},
01014 #if SHORT_IS_NOT_INT
01015 {"Short_Type", SLANG_SHORT_TYPE, sizeof (short), short_unary_op, push_short_literal, NULL, short_cmp_function},
01016 {"UShort_Type", SLANG_USHORT_TYPE, sizeof (unsigned short), ushort_unary_op, push_short_literal, NULL, ushort_cmp_function},
01017 #else
01018 {NULL, SLANG_SHORT_TYPE, 0, NULL, NULL, NULL, NULL},
01019 {NULL, SLANG_USHORT_TYPE, 0, NULL, NULL, NULL, NULL},
01020 #endif
01021
01022 {"Integer_Type", SLANG_INT_TYPE, sizeof (int), int_unary_op, push_int_literal, NULL, int_cmp_function},
01023 {"UInteger_Type", SLANG_UINT_TYPE, sizeof (unsigned int), uint_unary_op, push_int_literal, NULL, uint_cmp_function},
01024
01025 #if LONG_IS_NOT_INT
01026 {"Long_Type", SLANG_LONG_TYPE, sizeof (long), long_unary_op, push_long_literal, NULL, long_cmp_function},
01027 {"ULong_Type", SLANG_ULONG_TYPE, sizeof (unsigned long), ulong_unary_op, push_long_literal, NULL, ulong_cmp_function},
01028 #else
01029 {NULL, SLANG_LONG_TYPE, 0, NULL, NULL, NULL, NULL},
01030 {NULL, SLANG_ULONG_TYPE, 0, NULL, NULL, NULL, NULL},
01031 #endif
01032 #ifdef HAVE_LONG_LONG
01033 # if LLONG_IS_NOT_LONG
01034 {"LLong_Type", SLANG_LLONG_TYPE, sizeof (long long), llong_unary_op, push_llong_literal, llong_byte_code_destroy, llong_cmp_function},
01035 {"ULLong_Type", SLANG_ULLONG_TYPE, sizeof (unsigned long long), ullong_unary_op, push_llong_literal, llong_byte_code_destroy, ullong_cmp_function},
01036 # else
01037 {NULL, SLANG_LLONG_TYPE, 0, NULL, NULL, NULL, NULL},
01038 {NULL, SLANG_ULLONG_TYPE, 0, NULL, NULL, NULL, NULL},
01039 # endif
01040 #endif
01041 };
01042
01043 static int create_synonyms (void)
01044 {
01045 static char *names[8] =
01046 {
01047 "Int16_Type", "UInt16_Type", "Int32_Type", "UInt32_Type",
01048 "Int64_Type", "UInt64_Type",
01049 "Float32_Type", "Float64_Type"
01050 };
01051 int types[8];
01052 unsigned int i;
01053
01054 memset ((char *) types, 0, sizeof (types));
01055
01056 types[0] = _pSLANG_INT16_TYPE;
01057 types[1] = _pSLANG_UINT16_TYPE;
01058 types[2] = _pSLANG_INT32_TYPE;
01059 types[3] = _pSLANG_UINT32_TYPE;
01060 types[4] = _pSLANG_INT64_TYPE;
01061 types[5] = _pSLANG_UINT64_TYPE;
01062
01063 #if SLANG_HAS_FLOAT
01064
01065 #if SIZEOF_FLOAT == 4
01066 types[6] = SLANG_FLOAT_TYPE;
01067 #else
01068 # if SIZEOF_DOUBLE == 4
01069 types[6] = SLANG_DOUBLE_TYPE;
01070 # endif
01071 #endif
01072 #if SIZEOF_FLOAT == 8
01073 types[7] = SLANG_FLOAT_TYPE;
01074 #else
01075 # if SIZEOF_DOUBLE == 8
01076 types[7] = SLANG_DOUBLE_TYPE;
01077 # endif
01078 #endif
01079
01080 #endif
01081
01082 if ((-1 == SLclass_create_synonym ("Int_Type", SLANG_INT_TYPE))
01083 || (-1 == SLclass_create_synonym ("UInt_Type", SLANG_UINT_TYPE)))
01084 return -1;
01085
01086 for (i = 0; i < 8; i++)
01087 {
01088 if (types[i] == 0) continue;
01089
01090 if (-1 == SLclass_create_synonym (names[i], types[i]))
01091 return -1;
01092 }
01093
01094 for (i = 0; i < MAX_ARITHMETIC_TYPES; i++)
01095 {
01096 Alias_Map[i] = TABLE_INDEX_TO_TYPE(i);
01097 }
01098 #if SHORT_IS_INT
01099 Alias_Map [TYPE_TO_TABLE_INDEX(SLANG_SHORT_TYPE)] = SLANG_INT_TYPE;
01100 Alias_Map [TYPE_TO_TABLE_INDEX(SLANG_USHORT_TYPE)] = SLANG_UINT_TYPE;
01101 if ((-1 == SLclass_create_synonym ("Short_Type", SLANG_INT_TYPE))
01102 || (-1 == SLclass_create_synonym ("UShort_Type", SLANG_UINT_TYPE))
01103 || (-1 == _pSLclass_copy_class (SLANG_SHORT_TYPE, SLANG_INT_TYPE))
01104 || (-1 == _pSLclass_copy_class (SLANG_USHORT_TYPE, SLANG_UINT_TYPE)))
01105 return -1;
01106 #endif
01107 #if LONG_IS_INT
01108 Alias_Map [TYPE_TO_TABLE_INDEX(SLANG_LONG_TYPE)] = SLANG_INT_TYPE;
01109 Alias_Map [TYPE_TO_TABLE_INDEX(SLANG_ULONG_TYPE)] = SLANG_UINT_TYPE;
01110 if ((-1 == SLclass_create_synonym ("Long_Type", SLANG_INT_TYPE))
01111 || (-1 == SLclass_create_synonym ("ULong_Type", SLANG_UINT_TYPE))
01112 || (-1 == _pSLclass_copy_class (SLANG_LONG_TYPE, SLANG_INT_TYPE))
01113 || (-1 == _pSLclass_copy_class (SLANG_ULONG_TYPE, SLANG_UINT_TYPE)))
01114 return -1;
01115 #endif
01116 #if LLONG_IS_LONG
01117 Alias_Map [TYPE_TO_TABLE_INDEX(SLANG_LLONG_TYPE)] = _pSLANG_LONG_TYPE;
01118 Alias_Map [TYPE_TO_TABLE_INDEX(SLANG_ULLONG_TYPE)] = _pSLANG_ULONG_TYPE;
01119 if ((-1 == SLclass_create_synonym ("LLong_Type", _pSLANG_LONG_TYPE))
01120 || (-1 == SLclass_create_synonym ("ULLong_Type", _pSLANG_ULONG_TYPE))
01121 || (-1 == _pSLclass_copy_class (SLANG_LLONG_TYPE, _pSLANG_LONG_TYPE))
01122 || (-1 == _pSLclass_copy_class (SLANG_ULLONG_TYPE, _pSLANG_ULONG_TYPE)))
01123 return -1;
01124 #endif
01125
01126 return 0;
01127 }
01128
01129 static