📄 slarith.c
字号:
} return t;}static unsigned char promote_to_common_type (unsigned char a, unsigned char b){ a = _SLarith_promote_type (a); b = _SLarith_promote_type (b); return (Type_Precedence_Table[a] > Type_Precedence_Table[b]) ? a : b;}static int arith_bin_op_result (int op, unsigned char a_type, unsigned char b_type, unsigned char *c_type){ switch (op) { case SLANG_EQ: case SLANG_NE: case SLANG_GT: case SLANG_GE: case SLANG_LT: case SLANG_LE: case SLANG_OR: case SLANG_AND: *c_type = SLANG_CHAR_TYPE; return 1;#if SLANG_HAS_FLOAT case SLANG_POW: if (SLANG_FLOAT_TYPE == promote_to_common_type (a_type, b_type)) *c_type = SLANG_FLOAT_TYPE; else *c_type = SLANG_DOUBLE_TYPE; return 1;#endif case SLANG_BAND: case SLANG_BXOR: case SLANG_BOR: case SLANG_SHL: case SLANG_SHR: /* The bit-level operations are defined just for integer types */ if ((0 == IS_INTEGER_TYPE (a_type)) || (0 == IS_INTEGER_TYPE(b_type))) return 0; break; default: break; } *c_type = promote_to_common_type (a_type, b_type); return 1;}typedef int (*Bin_Fun_Type) (int, unsigned char, VOID_STAR, unsigned int, unsigned char, VOID_STAR, unsigned int, VOID_STAR);/* This array of functions must be indexed by precedence after arithmetic * promotions. */static Bin_Fun_Type Bin_Fun_Map [MAX_ARITHMETIC_TYPES] ={ NULL, NULL, NULL, NULL, int_int_bin_op, uint_uint_bin_op, long_long_bin_op, ulong_ulong_bin_op,#if SLANG_HAS_FLOAT float_float_bin_op, double_double_bin_op#else NULL, NULL#endif};static int arith_bin_op (int op, unsigned char a_type, VOID_STAR ap, unsigned int na, unsigned char b_type, VOID_STAR bp, unsigned int nb, VOID_STAR cp){ Convert_Fun_Type af, bf; Bin_Fun_Type binfun; int a_indx, b_indx, c_indx; unsigned char c_type; int ret; c_type = promote_to_common_type (a_type, b_type); a_indx = Type_Precedence_Table [a_type]; b_indx = Type_Precedence_Table [b_type]; c_indx = Type_Precedence_Table [c_type]; af = Binary_Matrix[a_indx][c_indx].convert_function; bf = Binary_Matrix[b_indx][c_indx].convert_function; binfun = Bin_Fun_Map[c_indx]; if ((af != NULL) && (NULL == (ap = (VOID_STAR) (*af) (ap, na)))) return -1; if ((bf != NULL) && (NULL == (bp = (VOID_STAR) (*bf) (bp, nb)))) { if (af != NULL) SLfree ((char *) ap); return -1; } ret = (*binfun) (op, a_type, ap, na, b_type, bp, nb, cp); if (af != NULL) SLfree ((char *) ap); if (bf != NULL) SLfree ((char *) bp); return ret;}static int arith_unary_op_result (int op, unsigned char a, unsigned char *b){ (void) a; switch (op) { default: return 0; case SLANG_SQR: case SLANG_MUL2: case SLANG_PLUSPLUS: case SLANG_MINUSMINUS: case SLANG_CHS: case SLANG_ABS: *b = a; break; case SLANG_NOT: case SLANG_BNOT: if (0 == IS_INTEGER_TYPE(a)) return 0; *b = a; break; case SLANG_SIGN: *b = SLANG_INT_TYPE; break; } return 1;}static int integer_pop (unsigned char type, VOID_STAR ptr){ SLang_Object_Type obj; int i, j; void (*f)(VOID_STAR, VOID_STAR, unsigned int); if (-1 == SLang_pop (&obj)) return -1; if ((obj.data_type > MAXIMUM_ARITH_TYPE_VALUE) || ((j = Type_Precedence_Table[obj.data_type]) == -1) || (j >= FLOAT_PRECEDENCE_VALUE)) { _SLclass_type_mismatch_error (type, obj.data_type); SLang_free_object (&obj); return -1; } i = Type_Precedence_Table[type]; f = (void (*)(VOID_STAR, VOID_STAR, unsigned int)) Binary_Matrix[j][i].copy_function; (*f) (ptr, (VOID_STAR)&obj.v, 1); return 0;}static int integer_push (unsigned char type, VOID_STAR ptr){ SLang_Object_Type obj; int i; void (*f)(VOID_STAR, VOID_STAR, unsigned int); i = Type_Precedence_Table[type]; f = (void (*)(VOID_STAR, VOID_STAR, unsigned int)) Binary_Matrix[i][i].copy_function; obj.data_type = type; (*f) ((VOID_STAR)&obj.v, ptr, 1); return SLang_push (&obj);}int SLang_pop_char (char *i){ return integer_pop (SLANG_CHAR_TYPE, (VOID_STAR) i);}int SLang_pop_uchar (unsigned char *i){ return integer_pop (SLANG_UCHAR_TYPE, (VOID_STAR) i);}int SLang_pop_short (short *i){ return integer_pop (SLANG_SHORT_TYPE, (VOID_STAR) i);}int SLang_pop_ushort (unsigned short *i){ return integer_pop (SLANG_USHORT_TYPE, (VOID_STAR) i);}int SLang_pop_long (long *i){ return integer_pop (SLANG_LONG_TYPE, (VOID_STAR) i);}int SLang_pop_ulong (unsigned long *i){ return integer_pop (SLANG_ULONG_TYPE, (VOID_STAR) i);}int SLang_pop_integer (int *i){#if _SLANG_OPTIMIZE_FOR_SPEED SLang_Object_Type obj; if (-1 == _SLang_pop_object_of_type (SLANG_INT_TYPE, &obj, 0)) return -1; *i = obj.v.int_val; return 0;#else return integer_pop (SLANG_INT_TYPE, (VOID_STAR) i);#endif}int SLang_pop_uinteger (unsigned int *i){ return integer_pop (SLANG_UINT_TYPE, (VOID_STAR) i);}int SLang_push_integer (int i){ return SLclass_push_int_obj (SLANG_INT_TYPE, i);}int SLang_push_uinteger (unsigned int i){ return SLclass_push_int_obj (SLANG_UINT_TYPE, (int) i);}int SLang_push_char (char i){ return SLclass_push_char_obj (SLANG_CHAR_TYPE, i);}int SLang_push_uchar (unsigned char i){ return SLclass_push_char_obj (SLANG_UCHAR_TYPE, (char) i);}int SLang_push_short (short i){ return SLclass_push_short_obj (SLANG_SHORT_TYPE, i);}int SLang_push_ushort (unsigned short i){ return SLclass_push_short_obj (SLANG_USHORT_TYPE, (unsigned short) i);}int SLang_push_long (long i){ return SLclass_push_long_obj (SLANG_LONG_TYPE, i);}int SLang_push_ulong (unsigned long i){ return SLclass_push_long_obj (SLANG_ULONG_TYPE, (long) i);}_INLINE_int _SLarith_typecast (unsigned char a_type, VOID_STAR ap, unsigned int na, unsigned char b_type, VOID_STAR bp){ int i, j; void (*copy)(VOID_STAR, VOID_STAR, unsigned int); i = Type_Precedence_Table[a_type]; j = Type_Precedence_Table[b_type]; copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int)) Binary_Matrix[i][j].copy_function; (*copy) (bp, ap, na); return 1;}#if SLANG_HAS_FLOATint SLang_pop_double(double *x, int *convertp, int *ip){ SLang_Object_Type obj; int i, convert; if (0 != SLang_pop (&obj)) return -1; i = 0; convert = 0; switch (obj.data_type) { case SLANG_FLOAT_TYPE: *x = (double) obj.v.float_val; break; case SLANG_DOUBLE_TYPE: *x = obj.v.double_val; break; case SLANG_INT_TYPE: i = obj.v.int_val; *x = (double) i; convert = 1; break; case SLANG_CHAR_TYPE: *x = (double) obj.v.char_val; break; case SLANG_UCHAR_TYPE: *x = (double) obj.v.uchar_val; break; case SLANG_SHORT_TYPE: *x = (double) obj.v.short_val; break; case SLANG_USHORT_TYPE: *x = (double) obj.v.ushort_val; break; case SLANG_UINT_TYPE: *x = (double) obj.v.uint_val; break; case SLANG_LONG_TYPE: *x = (double) obj.v.long_val; break; case SLANG_ULONG_TYPE: *x = (double) obj.v.ulong_val; break; default: _SLclass_type_mismatch_error (SLANG_DOUBLE_TYPE, obj.data_type); SLang_free_object (&obj); return -1; } if (convertp != NULL) *convertp = convert; if (ip != NULL) *ip = i; return 0;}int SLang_push_double (double x){ return SLclass_push_double_obj (SLANG_DOUBLE_TYPE, x);}int SLang_pop_float (float *x){ double d; /* Pop it as a double and let the double function do all the typcasting */ if (-1 == SLang_pop_double (&d, NULL, NULL)) return -1; *x = (float) d; return 0;}int SLang_push_float (float f){ return SLclass_push_float_obj (SLANG_FLOAT_TYPE, (double) f);}/* Double */static int double_push (SLtype type, VOID_STAR ptr){#if _SLANG_OPTIMIZE_FOR_SPEED SLang_Object_Type obj; obj.data_type = type; obj.v.double_val = *(double *)ptr; return SLang_push (&obj);#else return SLclass_push_double_obj (type, *(double *) ptr);#endif}static int double_push_literal (unsigned char type, VOID_STAR ptr){ (void) type; return SLang_push_double (**(double **)ptr);}static int double_pop (unsigned char unused, VOID_STAR ptr){ (void) unused; return SLang_pop_double ((double *) ptr, NULL, NULL);}static void double_byte_code_destroy (unsigned char unused, VOID_STAR ptr){ (void) unused; SLfree (*(char **) ptr);}static int float_push (unsigned char unused, VOID_STAR ptr){ (void) unused; SLang_push_float (*(float *) ptr); return 0;}static int float_pop (unsigned char unused, VOID_STAR ptr){ (void) unused; return SLang_pop_float ((float *) ptr);}#endif /* SLANG_HAS_FLOAT */#if SLANG_HAS_FLOATstatic char Double_Format[16] = "%g";void _SLset_double_format (char *s){ strncpy (Double_Format, s, 15); Double_Format[15] = 0;}#endifstatic char *arith_string (unsigned char type, VOID_STAR v){ char buf [256]; char *s; s = buf; switch (type) { default: s = SLclass_get_datatype_name (type); break; case SLANG_CHAR_TYPE: sprintf (s, "%d", *(char *) v); break; case SLANG_UCHAR_TYPE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -