Main Page | Class List | Directories | File List | Class Members | File Members

slarith.c

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2004, 2005, 2006 John E. Davis
00003 
00004 This file is part of the S-Lang Library.
00005 
00006 The S-Lang Library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License as
00008 published by the Free Software Foundation; either version 2 of the
00009 License, or (at your option) any later version.
00010 
00011 The S-Lang Library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this library; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 USA.  
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  * This file defines binary and unary operations on all integer types.
00053  * Supported types include:
00054  *
00055  *    SLANG_CHAR_TYPE     (char)
00056  *    SLANG_SHORT_TYPE    (short)
00057  *    SLANG_INT_TYPE      (int)
00058  *    SLANG_LONG_TYPE     (long)
00059  *    SLANG_FLOAT_TYPE    (float)
00060  *    SLANG_DOUBLE_TYPE   (double)
00061  *
00062  * as well as unsigned types.  The result-type of an arithmentic operation
00063  * will depend upon the data types involved.  I am going to distinguish
00064  * between the boolean operations such as `and' and `or' from the arithmetic
00065  * operations such as `plus'.  Since the result of a boolean operation is
00066  * either 1 or 0, a boolean result will be represented by SLANG_CHAR_TYPE.
00067  * Ordinarily I would use an integer but for arrays it makes more sense to
00068  * use a character data type.
00069  *
00070  * So, the following will be assumed (`+' is any arithmetic operator)
00071  *
00072  *    char + char = int
00073  *    char|short + short = int
00074  *    char|short|int + int = int
00075  *    char|short|int|long + long = long
00076  *    char|short|int|long|float + float = float
00077  *    char|short|int|long|float|double + double = double
00078  *
00079  * In the actual implementation, a brute force approach is avoided.  Such
00080  * an approach would mean defining different functions for all possible
00081  * combinations of types.  Including the unsigned types, and not including
00082  * the complex number type, there are 10 arithmetic types and 10*10=100
00083  * different combinations of types.  Clearly this would be too much.
00084  *
00085  * One approach would be to define binary functions only between operands of
00086  * the same type and then convert types as appropriate.  This would require
00087  * just 6 such functions (int, uint, long, ulong, float, double).
00088  * However, many conversion functions are going to be required, particularly
00089  * since we are going to allow typecasting from one arithmetic to another.
00090  * Since the bit pattern of signed and unsigned types are the same, and only
00091  * the interpretation differs, there will be no functions to convert between
00092  * signed and unsigned forms of a given type.
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 /* This table contains the types that have been implemented here */
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 /* Here are a bunch of functions to convert from one type to another.  To
00137  * facilitate the process, a macros will be used.
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 /* Each element of the matrix determines how the row maps onto the column.
00173  * That is, let the matrix be B_ij.  Where the i,j indices refer to
00174  * precedence of the type.  Then,
00175  * B_ij->copy_function copies type i to type j.  Similarly,
00176  * B_ij->convert_function mallocs a new array of type j and copies i to it.
00177  *
00178  * Since types are always converted to higher levels of precedence for binary
00179  * operations, many of the elements are NULL.
00180  *
00181  * Is the idea clear?
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                                 /* SLANG_HAS_FLOAT */
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                                 /* LONG_IS_NOT_INT */
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                                 /* HAVE_LONG_LONG */
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                                 /* SLANG_HAS_FLOAT */
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                                 /* SHORT_IS_NOT_INT */
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         /* drop */
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         /* The bit-level operations are defined just for integer types */
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 /* This array of functions must be indexed by precedence after arithmetic
00516  * promotions.
00517  */
00518 static Bin_Fun_Type Bin_Fun_Map [MAX_ARITHMETIC_TYPES] =
00519 {
00520    NULL,                               /* char */
00521      NULL,                             /* uchar */
00522      NULL,                             /* short */
00523      NULL,                             /* ushort */
00524      int_int_bin_op,                   /* int */
00525      uint_uint_bin_op,                 /* uint */
00526      long_long_bin_op,                 /* long */
00527      ulong_ulong_bin_op,               /* ulong */
00528 #ifdef HAVE_LONG_LONG
00529      llong_llong_bin_op,               /* llong */
00530      ullong_ullong_bin_op,             /* ullong */
00531 #else
00532      NULL, NULL,
00533 #endif
00534      float_float_bin_op,                       /* float */
00535      double_double_bin_op                      /* double */
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    /* Pop it as a double and let the double function do all the typcasting */
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 /* Double */
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                                 /* SLANG_HAS_FLOAT */
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 /* Note that integer literals are all stored in the byte-code as longs.  This
00961  * is why it is necessary to use *(long*).
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    /* The assumption is that sizeof(unsigned X) == sizeof (X) */
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