📄 slarith.c
字号:
sprintf (s, "%u", *(unsigned char *) v); break; case SLANG_SHORT_TYPE: sprintf (s, "%d", *(short *) v); break; case SLANG_USHORT_TYPE: sprintf (s, "%u", *(unsigned short *) v); break; case SLANG_INT_TYPE: sprintf (s, "%d", *(int *) v); break; case SLANG_UINT_TYPE: sprintf (s, "%u", *(unsigned int *) v); break; case SLANG_LONG_TYPE: sprintf (s, "%ld", *(long *) v); break; case SLANG_ULONG_TYPE: sprintf (s, "%lu", *(unsigned long *) v); break;#if SLANG_HAS_FLOAT case SLANG_FLOAT_TYPE: if (EOF == _SLsnprintf (buf, sizeof (buf), Double_Format, *(float *) v)) sprintf (s, "%e", *(float *) v); break; case SLANG_DOUBLE_TYPE: if (EOF == _SLsnprintf (buf, sizeof (buf), Double_Format, *(double *) v)) sprintf (s, "%e", *(double *) v); break;#endif } return SLmake_string (s);}static int integer_to_bool (unsigned char type, int *t){ (void) type; return SLang_pop_integer (t);}/* Note that integer literals are all stored in the byte-code as longs. This * is why it is necessary to use *(long*). */static int push_int_literal (unsigned char type, VOID_STAR ptr){ return SLclass_push_int_obj (type, (int) *(long *) ptr);}static int push_char_literal (unsigned char type, VOID_STAR ptr){ return SLclass_push_char_obj (type, (char) *(long *) ptr);}#if SIZEOF_SHORT != SIZEOF_INTstatic int push_short_literal (unsigned char type, VOID_STAR ptr){ return SLclass_push_short_obj (type, (short) *(long *) ptr);}#endif#if SIZEOF_INT != SIZEOF_LONGstatic int push_long_literal (unsigned char type, VOID_STAR ptr){ return SLclass_push_long_obj (type, *(long *) ptr);}#endiftypedef struct{ char *name; unsigned char data_type; unsigned int sizeof_type; int (*unary_fun)(int, unsigned char, VOID_STAR, unsigned int, VOID_STAR); int (*push_literal) (unsigned char, VOID_STAR); int (*cmp_fun) (unsigned char, VOID_STAR, VOID_STAR, int *);}Integer_Info_Type;static Integer_Info_Type Integer_Types [8] ={ {"Char_Type", SLANG_CHAR_TYPE, sizeof (char), char_unary_op, push_char_literal, char_cmp_function}, {"UChar_Type", SLANG_UCHAR_TYPE, sizeof (unsigned char), uchar_unary_op, push_char_literal, uchar_cmp_function},#if SIZEOF_INT != SIZEOF_SHORT {"Short_Type", SLANG_SHORT_TYPE, sizeof (short), short_unary_op, push_short_literal, short_cmp_function}, {"UShort_Type", SLANG_USHORT_TYPE, sizeof (unsigned short), ushort_unary_op, push_short_literal, ushort_cmp_function},#else {NULL, SLANG_SHORT_TYPE}, {NULL, SLANG_USHORT_TYPE},#endif {"Integer_Type", SLANG_INT_TYPE, sizeof (int), int_unary_op, push_int_literal, int_cmp_function}, {"UInteger_Type", SLANG_UINT_TYPE, sizeof (unsigned int), uint_unary_op, push_int_literal, uint_cmp_function},#if SIZEOF_INT != SIZEOF_LONG {"Long_Type", SLANG_LONG_TYPE, sizeof (long), long_unary_op, push_long_literal, long_cmp_function}, {"ULong_Type", SLANG_ULONG_TYPE, sizeof (unsigned long), ulong_unary_op, push_long_literal, ulong_cmp_function}#else {NULL, SLANG_LONG_TYPE, 0, NULL, NULL, NULL}, {NULL, SLANG_ULONG_TYPE, 0, NULL, NULL, NULL}#endif};static int create_synonyms (void){ static char *names[8] = { "Int16_Type", "UInt16_Type", "Int32_Type", "UInt32_Type", "Int64_Type", "UInt64_Type", "Float32_Type", "Float64_Type" }; int types[8]; unsigned int i; memset ((char *) types, 0, sizeof (types)); /* The assumption is that sizeof(unsigned X) == sizeof (X) */#if SIZEOF_INT == 2 types[0] = SLANG_INT_TYPE; types[1] = SLANG_UINT_TYPE;#else# if SIZEOF_SHORT == 2 types[0] = SLANG_SHORT_TYPE; types[1] = SLANG_USHORT_TYPE;# else# if SIZEOF_LONG == 2 types[0] = SLANG_LONG_TYPE; types[1] = SLANG_ULONG_TYPE;# endif# endif#endif#if SIZEOF_INT == 4 types[2] = SLANG_INT_TYPE; types[3] = SLANG_UINT_TYPE;#else# if SIZEOF_SHORT == 4 types[2] = SLANG_SHORT_TYPE; types[3] = SLANG_USHORT_TYPE;# else# if SIZEOF_LONG == 4 types[2] = SLANG_LONG_TYPE; types[3] = SLANG_ULONG_TYPE;# endif# endif#endif#if SIZEOF_INT == 8 types[4] = SLANG_INT_TYPE; types[5] = SLANG_UINT_TYPE;#else# if SIZEOF_SHORT == 8 types[4] = SLANG_SHORT_TYPE; types[5] = SLANG_USHORT_TYPE;# else# if SIZEOF_LONG == 8 types[4] = SLANG_LONG_TYPE; types[5] = SLANG_ULONG_TYPE;# endif# endif#endif#if SLANG_HAS_FLOAT#if SIZEOF_FLOAT == 4 types[6] = SLANG_FLOAT_TYPE;#else# if SIZEOF_DOUBLE == 4 types[6] = SLANG_DOUBLE_TYPE;# endif#endif#if SIZEOF_FLOAT == 8 types[7] = SLANG_FLOAT_TYPE;#else# if SIZEOF_DOUBLE == 8 types[7] = SLANG_DOUBLE_TYPE;# endif#endif#endif if ((-1 == SLclass_create_synonym ("Int_Type", SLANG_INT_TYPE)) || (-1 == SLclass_create_synonym ("UInt_Type", SLANG_UINT_TYPE))) return -1; for (i = 0; i < 8; i++) { if (types[i] == 0) continue; if (-1 == SLclass_create_synonym (names[i], types[i])) return -1; }#if SIZEOF_INT == SIZEOF_SHORT if ((-1 == SLclass_create_synonym ("Short_Type", SLANG_INT_TYPE)) || (-1 == SLclass_create_synonym ("UShort_Type", SLANG_UINT_TYPE)) || (-1 == _SLclass_copy_class (SLANG_SHORT_TYPE, SLANG_INT_TYPE)) || (-1 == _SLclass_copy_class (SLANG_USHORT_TYPE, SLANG_UINT_TYPE))) return -1;#endif#if SIZEOF_INT == SIZEOF_LONG if ((-1 == SLclass_create_synonym ("Long_Type", SLANG_INT_TYPE)) || (-1 == SLclass_create_synonym ("ULong_Type", SLANG_UINT_TYPE)) || (-1 == _SLclass_copy_class (SLANG_LONG_TYPE, SLANG_INT_TYPE)) || (-1 == _SLclass_copy_class (SLANG_ULONG_TYPE, SLANG_UINT_TYPE))) return -1;#endif return 0;}int _SLarith_register_types (void){ SLang_Class_Type *cl; int a_type, b_type; int i, j;#if defined(HAVE_SETLOCALE) && defined(LC_NUMERIC) /* make sure decimal point it used --- the parser requires it */ (void) setlocale (LC_NUMERIC, "C"); #endif for (i = 0; i < 8; i++) { Integer_Info_Type *info; info = Integer_Types + i; if (info->name == NULL) { /* This happens when the object is the same size as an integer * For this case, we really want to copy the integer class. * We will handle that when the synonym is created. */ continue; } if (NULL == (cl = SLclass_allocate_class (info->name))) return -1; (void) SLclass_set_string_function (cl, arith_string); (void) SLclass_set_push_function (cl, integer_push); (void) SLclass_set_pop_function (cl, integer_pop); cl->cl_push_literal = info->push_literal; cl->cl_to_bool = integer_to_bool; cl->cl_cmp = info->cmp_fun; if (-1 == SLclass_register_class (cl, info->data_type, info->sizeof_type, SLANG_CLASS_TYPE_SCALAR)) return -1; if (-1 == SLclass_add_unary_op (info->data_type, info->unary_fun, arith_unary_op_result)) return -1; _SLang_set_arith_type (info->data_type, 1); }#if SLANG_HAS_FLOAT if (NULL == (cl = SLclass_allocate_class ("Double_Type"))) return -1; (void) SLclass_set_push_function (cl, double_push); (void) SLclass_set_pop_function (cl, double_pop); (void) SLclass_set_string_function (cl, arith_string); cl->cl_byte_code_destroy = double_byte_code_destroy; cl->cl_push_literal = double_push_literal; cl->cl_cmp = double_cmp_function; if (-1 == SLclass_register_class (cl, SLANG_DOUBLE_TYPE, sizeof (double), SLANG_CLASS_TYPE_SCALAR)) return -1; if (-1 == SLclass_add_unary_op (SLANG_DOUBLE_TYPE, double_unary_op, arith_unary_op_result)) return -1; _SLang_set_arith_type (SLANG_DOUBLE_TYPE, 2); if (NULL == (cl = SLclass_allocate_class ("Float_Type"))) return -1; (void) SLclass_set_string_function (cl, arith_string); (void) SLclass_set_push_function (cl, float_push); (void) SLclass_set_pop_function (cl, float_pop); cl->cl_cmp = float_cmp_function; if (-1 == SLclass_register_class (cl, SLANG_FLOAT_TYPE, sizeof (float), SLANG_CLASS_TYPE_SCALAR)) return -1; if (-1 == SLclass_add_unary_op (SLANG_FLOAT_TYPE, float_unary_op, arith_unary_op_result)) return -1; _SLang_set_arith_type (SLANG_FLOAT_TYPE, 2);#endif if (-1 == create_synonyms ()) return -1; for (a_type = 0; a_type <= MAXIMUM_ARITH_TYPE_VALUE; a_type++) { if (-1 == (i = Type_Precedence_Table [a_type])) continue; for (b_type = 0; b_type <= MAXIMUM_ARITH_TYPE_VALUE; b_type++) { int implicit_ok; if (-1 == (j = Type_Precedence_Table [b_type])) continue; /* Allow implicit typecast, except from into to float */ implicit_ok = ((j >= FLOAT_PRECEDENCE_VALUE) || (i < FLOAT_PRECEDENCE_VALUE)); if (-1 == SLclass_add_binary_op (a_type, b_type, arith_bin_op, arith_bin_op_result)) return -1; if (i != j) if (-1 == SLclass_add_typecast (a_type, b_type, _SLarith_typecast, implicit_ok)) return -1; } } return 0;}#if _SLANG_OPTIMIZE_FOR_SPEEDstatic void promote_objs (SLang_Object_Type *a, SLang_Object_Type *b, SLang_Object_Type *c, SLang_Object_Type *d){ unsigned char ia, ib, ic, id; int i, j; void (*copy)(VOID_STAR, VOID_STAR, unsigned int); ia = a->data_type; ib = b->data_type; ic = _SLarith_promote_type (ia); if (ic == ib) id = ic; /* already promoted */ else id = _SLarith_promote_type (ib); i = Type_Precedence_Table[ic]; j = Type_Precedence_Table[id]; if (i > j) { id = ic; j = i; } c->data_type = d->data_type = id; i = Type_Precedence_Table[ia]; copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int)) Binary_Matrix[i][j].copy_function; (*copy) ((VOID_STAR) &c->v, (VOID_STAR)&a->v, 1); i = Type_Precedence_Table[ib]; copy = (void (*)(VOID_STAR, VOID_STAR, unsigned int)) Binary_Matrix[i][j].copy_function; (*copy) ((VOID_STAR) &d->v, (VOID_STAR)&b->v, 1);}int _SLarith_bin_op (SLang_Object_Type *oa, SLang_Object_Type *ob, int op){ unsigned char a_type, b_type; a_type = oa->data_type; b_type = ob->data_type; if (a_type != b_type) { SLang_Object_Type obj_a, obj_b; /* Handle common cases */#if SLANG_HAS_FLOAT if ((a_type == SLANG_INT_TYPE) && (b_type == SLANG_DOUBLE_TYPE)) return double_double_scalar_bin_op (oa->v.int_val, ob->v.double_val, op); if ((a_type == SLANG_DOUBLE_TYPE) && (b_type == SLANG_INT_TYPE)) return double_double_scalar_bin_op (oa->v.double_val, ob->v.int_val, op);#endif /* Otherwise do it the hard way */ promote_objs (oa, ob, &obj_a, &obj_b); oa = &obj_a; ob = &obj_b; a_type = oa->data_type; /* b_type = ob->data_type; */ } switch (a_type) { case SLANG_CHAR_TYPE: return int_int_scalar_bin_op (oa->v.char_val, ob->v.char_val, op); case SLANG_UCHAR_TYPE: return int_int_scalar_bin_op (oa->v.uchar_val, ob->v.uchar_val, op); case SLANG_SHORT_TYPE: return int_int_scalar_bin_op (oa->v.short_val, ob->v.short_val, op); case SLANG_USHORT_TYPE:# if SIZEOF_INT == SIZEOF_SHORT return uint_uint_scalar_bin_op (oa->v.ushort_val, ob->v.ushort_val, op);# else return int_int_scalar_bin_op ((int)oa->v.ushort_val, (int)ob->v.ushort_val, op);# endif#if SIZEOF_LONG == SIZEOF_INT case SLANG_LONG_TYPE:#endif case SLANG_INT_TYPE: return int_int_scalar_bin_op (oa->v.int_val, ob->v.int_val, op);#if SIZEOF_LONG == SIZEOF_INT case SLANG_ULONG_TYPE:#endif case SLANG_UINT_TYPE: return uint_uint_scalar_bin_op (oa->v.uint_val, ob->v.uint_val, op); #if SIZEOF_LONG != SIZEOF_INT case SLANG_LONG_TYPE: return long_long_scalar_bin_op (oa->v.long_val, ob->v.long_val, op); case SLANG_ULONG_TYPE: return ulong_ulong_scalar_bin_op (oa->v.ulong_val, ob->v.ulong_val, op);#endif#if SLANG_HAS_FLOAT case SLANG_FLOAT_TYPE: return float_float_scalar_bin_op (oa->v.float_val, ob->v.float_val, op); case SLANG_DOUBLE_TYPE: return double_double_scalar_bin_op (oa->v.double_val, ob->v.double_val, op);#endif } return 1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -