/* * dpas-types.c - Special handling for Dynamic Pascal types. * * Copyright (C) 2004 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "dpas-internal.h" #include /* * Define some special integer types that are distinguished from normal ones. */ jit_type_t dpas_type_boolean; jit_type_t dpas_type_cboolean; jit_type_t dpas_type_char; jit_type_t dpas_type_string; jit_type_t dpas_type_address; jit_type_t dpas_type_nil; jit_type_t dpas_type_size_t; jit_type_t dpas_type_ptrdiff_t; /* * Register a predefined type within the global scope. */ static void register_type(const char *name, jit_type_t type) { dpas_scope_add(dpas_scope_global(), name, type, DPAS_ITEM_TYPE, 0, 0, "(builtin)", 1); } /* * Get an integer type of a specific size. */ static jit_type_t get_int_type(unsigned int size) { if(size == sizeof(jit_int)) { return jit_type_int; } else if(size == sizeof(jit_long)) { return jit_type_long; } else if(size == sizeof(jit_nint)) { return jit_type_nint; } else if(size == sizeof(jit_short)) { return jit_type_short; } else if(size == sizeof(jit_sbyte)) { return jit_type_sbyte; } else { return jit_type_int; } } /* * Get an unsigned integer type of a specific size. */ static jit_type_t get_uint_type(unsigned int size) { if(size == sizeof(jit_uint)) { return jit_type_uint; } else if(size == sizeof(jit_ulong)) { return jit_type_ulong; } else if(size == sizeof(jit_nuint)) { return jit_type_nuint; } else if(size == sizeof(jit_ushort)) { return jit_type_ushort; } else if(size == sizeof(jit_ubyte)) { return jit_type_ubyte; } else { return jit_type_uint; } } void dpas_init_types(void) { jit_constant_t value; /* * Create the special types. */ dpas_type_boolean = jit_type_create_tagged (jit_type_sys_int, DPAS_TAG_BOOLEAN, 0, 0, 1); dpas_type_cboolean = jit_type_create_tagged (jit_type_sys_char, DPAS_TAG_CBOOLEAN, 0, 0, 1); if(((char)0xFF) < 0) { dpas_type_char = jit_type_create_tagged (jit_type_sbyte, DPAS_TAG_CHAR, 0, 0, 1); } else { dpas_type_char = jit_type_create_tagged (jit_type_ubyte, DPAS_TAG_CHAR, 0, 0, 1); } dpas_type_string = jit_type_create_pointer(dpas_type_char, 1); dpas_type_address = jit_type_void_ptr; dpas_type_nil = jit_type_create_tagged (jit_type_void_ptr, DPAS_TAG_NIL, 0, 0, 1); dpas_type_size_t = get_uint_type(sizeof(size_t)); dpas_type_ptrdiff_t = get_uint_type(sizeof(ptrdiff_t)); /* * Register all of the builtin types. */ register_type("Boolean", dpas_type_boolean); register_type("CBoolean", dpas_type_cboolean); register_type("Char", dpas_type_char); register_type("String", dpas_type_string); register_type("Address", dpas_type_address); register_type("Integer", jit_type_int); register_type("Cardinal", jit_type_uint); register_type("Word", jit_type_uint); register_type("Byte", jit_type_ubyte); register_type("ByteInt", jit_type_sbyte); register_type("ByteWord", jit_type_ubyte); register_type("ByteCard", jit_type_ubyte); register_type("ShortInt", jit_type_short); register_type("ShortWord", jit_type_ushort); register_type("ShortCard", jit_type_ushort); register_type("MedInt", jit_type_nint); register_type("MedWord", jit_type_nuint); register_type("MedCard", jit_type_nuint); register_type("LongInt", jit_type_long); register_type("LongWord", jit_type_ulong); register_type("LongCard", jit_type_ulong); register_type("LongestInt", jit_type_long); register_type("LongestWord", jit_type_ulong); register_type("LongestCard", jit_type_ulong); register_type("PtrInt", jit_type_nint); register_type("PtrWord", jit_type_nuint); register_type("PtrCard", jit_type_nuint); register_type("SmallInt", jit_type_short); register_type("Comp", jit_type_long); register_type("ShortReal", jit_type_float32); register_type("Single", jit_type_float32); register_type("Real", jit_type_float64); register_type("Double", jit_type_float64); register_type("LongReal", jit_type_nfloat); register_type("Extended", jit_type_nfloat); register_type("PtrDiffType", dpas_type_ptrdiff_t); register_type("SizeType", dpas_type_size_t); register_type("SysInt", jit_type_sys_int); register_type("SysCard", jit_type_sys_uint); register_type("SysWord", jit_type_sys_uint); register_type("SysLongInt", jit_type_sys_long); register_type("SysLongCard", jit_type_sys_ulong); register_type("SysLongWord", jit_type_sys_ulong); register_type("SysLongestInt", jit_type_sys_longlong); register_type("SysLongestCard", jit_type_sys_ulonglong); register_type("SysLongestWord", jit_type_sys_ulonglong); /* * Register the "True" and "False" constants. */ value.type = dpas_type_boolean; value.un.int_value = 1; dpas_scope_add_const(dpas_scope_global(), "True", &value, "(builtin)", 1); value.type = dpas_type_boolean; value.un.int_value = 0; dpas_scope_add_const(dpas_scope_global(), "False", &value, "(builtin)", 1); } unsigned int dpas_type_find_name(jit_type_t type, const char *name) { unsigned int field = jit_type_num_fields(type); const char *fname; while(field > 0) { --field; fname = jit_type_get_name(type, field); if(fname && !jit_stricmp(fname, name)) { return field; } } return JIT_INVALID_NAME; } jit_type_t dpas_type_get_field(jit_type_t type, const char *name, jit_nint *offset) { unsigned int field; const char *fname; jit_type_t field_type; type = jit_type_normalize(type); field = jit_type_num_fields(type); while(field > 0) { --field; fname = jit_type_get_name(type, field); field_type = jit_type_get_field(type, field); if(fname && !jit_stricmp(fname, name)) { *offset = jit_type_get_offset(type, field); return field_type; } else if(!fname) { /* Probably a nested struct or union in a variant record */ if(dpas_type_is_record(field_type)) { field_type = dpas_type_get_field(field_type, name, offset); if(field_type != 0) { *offset += jit_type_get_offset(type, field); return field_type; } } } } return 0; } /* * Concatenate two strings. */ static char *concat_strings(char *str1, char *str2) { char *str; if(!str1 || !str2) { dpas_out_of_memory(); } str = (char *)jit_malloc(jit_strlen(str1) + jit_strlen(str2) + 1); if(!str) { dpas_out_of_memory(); } jit_strcpy(str, str1); jit_strcat(str, str2); jit_free(str1); jit_free(str2); return str; } static char *type_name(const char *embed_name, jit_type_t type) { char *temp; dpas_subrange *range; char *name; if(jit_type_is_primitive(type)) { if(type == jit_type_void) { temp = jit_strdup("void"); } else if(type == jit_type_sbyte) { temp = jit_strdup("ByteInt"); } else if(type == jit_type_ubyte) { temp = jit_strdup("Byte"); } else if(type == jit_type_short) { temp = jit_strdup("ShortInt"); } else if(type == jit_type_ushort) { temp = jit_strdup("ShortCard"); } else if(type == jit_type_int) { temp = jit_strdup("Integer"); } else if(type == jit_type_uint) { temp = jit_strdup("Cardinal"); } else if(type == jit_type_long) { temp = jit_strdup("LongInt"); } else if(type == jit_type_ulong) { temp = jit_strdup("LongCard"); } else if(type == jit_type_float32) { temp = jit_strdup("ShortReal"); } else if(type == jit_type_float64) { temp = jit_strdup("Real"); } else if(type == jit_type_nfloat) { temp = jit_strdup("LongReal"); } else { temp = jit_strdup("unknown-primitive-type"); } } else if(jit_type_is_struct(type) || jit_type_is_union(type)) { /* Shouldn't happen: record types should be tagged with a name */ temp = jit_strdup("unknown-struct-or-union"); } else if(jit_type_is_signature(type)) { char *temp; jit_type_t return_type, param_type; unsigned int param, num_params; const char *param_name; return_type = jit_type_get_return(type); if(return_type == jit_type_void) { temp = jit_strdup("procedure"); } else { temp = jit_strdup("function"); } if(embed_name) { temp = concat_strings(temp, jit_strdup(" ")); temp = concat_strings(temp, jit_strdup(embed_name)); } num_params = jit_type_num_params(type); if(num_params > 0) { temp = concat_strings(temp, jit_strdup("(")); for(param = 0; param < num_params; ++param) { if(param > 0) { temp = concat_strings(temp, jit_strdup(", ")); } param_type = jit_type_get_param(type, param); param_name = jit_type_get_name(type, param); temp = concat_strings (temp, type_name(param_name, param_type)); } temp = concat_strings(temp, jit_strdup(")")); } if(return_type != jit_type_void) { temp = concat_strings(temp, jit_strdup(" : ")); temp = concat_strings(temp, type_name(0, return_type)); } return temp; } else if(jit_type_is_pointer(type)) { if(jit_type_get_ref(type) == dpas_type_char) { temp = jit_strdup("String"); } else if(jit_type_get_ref(type) == jit_type_void) { temp = jit_strdup("Address"); } else { temp = concat_strings (jit_strdup("^"), type_name(0, jit_type_get_ref(type))); } } else if(jit_type_is_tagged(type)) { switch(jit_type_get_tagged_kind(type)) { case DPAS_TAG_BOOLEAN: temp = jit_strdup("Boolean"); break; case DPAS_TAG_CBOOLEAN: temp = jit_strdup("CBoolean"); break; case DPAS_TAG_CHAR: temp = jit_strdup("Char"); break; case DPAS_TAG_NIL: temp = jit_strdup("nil"); break; case DPAS_TAG_NAME: { name = (char *)jit_type_get_tagged_data(type); if(name) { temp = jit_strdup(name); } else { temp = jit_strdup("anonymous_record"); } } break; case DPAS_TAG_VAR: { return concat_strings (jit_strdup("var "), type_name(embed_name, jit_type_get_ref (jit_type_get_tagged_type(type)))); } /* Not reached */ case DPAS_TAG_SUBRANGE: { range = (dpas_subrange *)jit_type_get_tagged_data(type); temp = concat_strings (dpas_constant_name(&(range->first)), concat_strings (jit_strdup(".."), dpas_constant_name(&(range->last)))); } break; case DPAS_TAG_ENUM: { name = ((dpas_enum *)jit_type_get_tagged_data(type))->name; if(name) { temp = jit_strdup(name); } else { temp = jit_strdup("anonymous_enum"); } } break; case DPAS_TAG_SET: { temp = concat_strings (jit_strdup("set of "), type_name(0, (jit_type_t)jit_type_get_tagged_data(type))); } break; case DPAS_TAG_ARRAY: { int dim; jit_type_t array_type; dpas_array *array_info = (dpas_array *) jit_type_get_tagged_data(type); temp = jit_strdup("array ["); for(dim = 0; dim < array_info->num_bounds; ++dim) { if(dim != 0) { temp = concat_strings(temp, jit_strdup(", ")); } if(array_info->bounds[dim]) { temp = concat_strings (temp, type_name(0, array_info->bounds[dim])); } else { /* User-supplied type which can't be used as a bound */ temp = concat_strings(temp, jit_strdup("0 .. 0")); } } temp = concat_strings(temp, jit_strdup("] of ")); array_type = jit_type_get_tagged_type(type); temp = concat_strings (temp, type_name(0, jit_type_get_field(array_type, 0))); } break; case DPAS_TAG_CONFORMANT_ARRAY: { int dim; jit_type_t array_type; dpas_conformant_array *array_info; array_info = (dpas_conformant_array *) jit_type_get_tagged_data(type); if(array_info->is_packed) { temp = jit_strdup("packed array ["); } else { temp = jit_strdup("array ["); } for(dim = 1; dim < array_info->num_bounds; ++dim) { temp = concat_strings(temp, jit_strdup(",")); } temp = concat_strings(temp, jit_strdup("] of ")); array_type = jit_type_get_ref(jit_type_get_tagged_type(type)); temp = concat_strings(temp, type_name(0, array_type)); if(embed_name) { temp = concat_strings (concat_strings(jit_strdup("var "), jit_strdup(embed_name)), concat_strings(jit_strdup(" : "), temp)); } else { temp = concat_strings(jit_strdup("var "), temp); } return temp; } /* Not reached */ default: temp = jit_strdup("unknown-tagged-type"); break; } } else { /* We shouldn't get here */ temp = jit_strdup("unknown-jit-type"); } if(!temp) { dpas_out_of_memory(); } if(embed_name) { temp = concat_strings(concat_strings (jit_strdup(embed_name), jit_strdup(" : ")), temp); } return temp; } char *dpas_type_name(jit_type_t type) { char *temp = type_name(0, type); if(!temp) { dpas_out_of_memory(); } return temp; } char *dpas_type_name_with_var(const char *name, jit_type_t type) { char *temp = type_name(name, type); if(!temp) { dpas_out_of_memory(); } return temp; } jit_type_t dpas_promote_type(jit_type_t type) { if(jit_type_get_tagged_kind(type) == DPAS_TAG_SUBRANGE) { /* Convert subrange types into their real integer counterparts */ type = jit_type_get_tagged_type(type); } if(type == jit_type_sbyte || type == jit_type_ubyte || type == jit_type_short || type == jit_type_ushort) { return jit_type_int; } else if(type == jit_type_nint) { if(sizeof(jit_nint) == sizeof(jit_int)) { return jit_type_int; } else { return jit_type_long; } } else if(type == jit_type_nuint) { if(sizeof(jit_nuint) == sizeof(jit_uint)) { return jit_type_uint; } else { return jit_type_ulong; } } else if(type == jit_type_float32 || type == jit_type_float64) { return jit_type_nfloat; } else { return type; } } jit_type_t dpas_common_type(jit_type_t type1, jit_type_t type2, int int_only) { type1 = dpas_promote_type(type1); type2 = dpas_promote_type(type2); if(type1 == type2) { if(int_only && type1 == jit_type_nfloat) { return 0; } return type1; } if(type1 == jit_type_int) { if(type2 == jit_type_uint) { return jit_type_int; } else if(type2 == jit_type_long || type2 == jit_type_ulong) { return jit_type_long; } else if(type2 == jit_type_nfloat) { if(!int_only) { return jit_type_nfloat; } } } else if(type1 == jit_type_uint) { if(type2 == jit_type_int) { return jit_type_int; } else if(type2 == jit_type_long) { return jit_type_long; } else if(type2 == jit_type_ulong) { return jit_type_ulong; } else if(type2 == jit_type_nfloat) { if(!int_only) { return jit_type_nfloat; } } } else if(type1 == jit_type_long) { if(type2 == jit_type_int || type2 == jit_type_uint || type2 == jit_type_ulong) { return jit_type_long; } else if(type2 == jit_type_nfloat) { if(!int_only) { return jit_type_nfloat; } } } else if(type1 == jit_type_ulong) { if(type2 == jit_type_int || type2 == jit_type_long) { return jit_type_long; } else if(type2 == jit_type_uint) { return jit_type_ulong; } else if(type2 == jit_type_nfloat) { if(!int_only) { return jit_type_nfloat; } } } else if(type1 == jit_type_nfloat) { if(type2 == jit_type_int || type2 == jit_type_uint || type2 == jit_type_long || type2 == jit_type_ulong) { if(!int_only) { return jit_type_nfloat; } } } return 0; } jit_type_t dpas_create_subrange(jit_type_t underlying, dpas_subrange *values) { dpas_subrange *copy; jit_type_t type; copy = jit_new(dpas_subrange); if(!copy) { dpas_out_of_memory(); } *copy = *values; type = jit_type_create_tagged(underlying, DPAS_TAG_SUBRANGE, copy, jit_free, 1); if(!type) { dpas_out_of_memory(); } return type; } /* * Free the information block for an enumerated type. */ static void free_enum(void *info) { jit_free(((dpas_enum *)info)->name); jit_free(info); } jit_type_t dpas_create_enum(jit_type_t underlying, int num_elems) { dpas_enum *enum_info; jit_type_t type; enum_info = jit_new(dpas_enum); if(!enum_info) { dpas_out_of_memory(); } enum_info->name = 0; enum_info->num_elems = num_elems; type = jit_type_create_tagged(underlying, DPAS_TAG_ENUM, enum_info, free_enum, 1); if(!type) { dpas_out_of_memory(); } return type; } jit_nuint dpas_type_range_size(jit_type_t type) { if(jit_type_get_tagged_kind(type) == DPAS_TAG_ENUM) { return (jit_nuint)(jit_nint) (((dpas_enum *)jit_type_get_tagged_data(type))->num_elems); } else if(jit_type_get_tagged_kind(type) == DPAS_TAG_SUBRANGE && jit_type_get_tagged_type(type) == jit_type_int) { return (jit_nuint)(jit_nint) (((dpas_subrange *)jit_type_get_tagged_data(type)) ->last.un.int_value - ((dpas_subrange *)jit_type_get_tagged_data(type)) ->first.un.int_value + 1); } else { return 0; } } jit_type_t dpas_create_array(jit_type_t *bounds, int num_bounds, jit_type_t elem_type) { jit_type_t type; jit_type_t tagged; dpas_array *info; jit_nuint size; int posn; /* Create a struct type, with the element type in the first field */ type = jit_type_create_struct(&elem_type, 1, 0); if(!type) { dpas_out_of_memory(); } /* Tag the structure with the array bound information */ info = (dpas_array *)jit_malloc(sizeof(dpas_array)); if(!info) { dpas_out_of_memory(); } info->bounds = bounds; info->num_bounds = num_bounds; tagged = jit_type_create_tagged(type, DPAS_TAG_ARRAY, info, jit_free, 0); /* Infer the total size of the array */ size = jit_type_get_size(elem_type); for(posn = 0; posn < num_bounds; ++posn) { size *= dpas_type_range_size(bounds[posn]); } /* If the array is empty, then allocate space for one element so that the type's total size is non-zero */ if(!size) { size = jit_type_get_size(elem_type); } /* Set the array's final size and alignment */ jit_type_set_size_and_alignment (type, size, jit_type_get_alignment(elem_type)); /* Return the tagged version of the array to the caller */ return tagged; } jit_type_t dpas_create_conformant_array(jit_type_t elem_type, int num_bounds, int is_packed) { jit_type_t type; dpas_conformant_array *info; /* A conformant array is actually a pointer to the first element */ type = jit_type_create_pointer(elem_type, 0); if(!type) { dpas_out_of_memory(); } /* Tag the pointer so that the rest of the system knows what it is */ info = jit_new(dpas_conformant_array); if(!info) { dpas_out_of_memory(); } info->num_bounds = num_bounds; info->is_packed = is_packed; type = jit_type_create_tagged(type, DPAS_TAG_CONFORMANT_ARRAY, info, jit_free, 0); if(!type) { dpas_out_of_memory(); } return type; } void dpas_type_set_name(jit_type_t type, const char *name) { char *copy; dpas_enum *enum_info; if(jit_type_get_tagged_kind(type) == DPAS_TAG_NAME) { if(!jit_type_get_tagged_data(type)) { copy = jit_strdup(name); if(!copy) { dpas_out_of_memory(); } jit_type_set_tagged_data(type, copy, jit_free); } } else if(jit_type_get_tagged_kind(type) == DPAS_TAG_ENUM) { enum_info = (dpas_enum *)jit_type_get_tagged_data(type); if(!(enum_info->name)) { copy = jit_strdup(name); if(!copy) { dpas_out_of_memory(); } enum_info->name = copy; } } } void dpas_convert_constant(jit_constant_t *result, jit_constant_t *from, jit_type_t to_type) { jit_type_t from_type = dpas_promote_type(from->type); to_type = dpas_promote_type(to_type); result->type = to_type; result->un = from->un; if(to_type == jit_type_int) { if(from_type == jit_type_int) { result->un.int_value = jit_int_to_int(from->un.int_value); } else if(from_type == jit_type_uint) { result->un.int_value = jit_uint_to_int(from->un.uint_value); } else if(from_type == jit_type_long) { result->un.int_value = jit_long_to_int(from->un.long_value); } else if(from_type == jit_type_ulong) { result->un.int_value = jit_ulong_to_int(from->un.ulong_value); } else if(from_type == jit_type_nfloat) { result->un.int_value = jit_nfloat_to_int(from->un.nfloat_value); } } else if(to_type == jit_type_uint) { if(from_type == jit_type_int) { result->un.uint_value = jit_int_to_uint(from->un.int_value); } else if(from_type == jit_type_uint) { result->un.uint_value = jit_uint_to_uint(from->un.uint_value); } else if(from_type == jit_type_long) { result->un.uint_value = jit_long_to_uint(from->un.long_value); } else if(from_type == jit_type_ulong) { result->un.uint_value = jit_ulong_to_uint(from->un.ulong_value); } else if(from_type == jit_type_nfloat) { result->un.uint_value = jit_nfloat_to_uint(from->un.nfloat_value); } } else if(to_type == jit_type_long) { if(from_type == jit_type_int) { result->un.long_value = jit_int_to_long(from->un.int_value); } else if(from_type == jit_type_uint) { result->un.long_value = jit_uint_to_long(from->un.uint_value); } else if(from_type == jit_type_long) { result->un.long_value = jit_long_to_long(from->un.long_value); } else if(from_type == jit_type_ulong) { result->un.long_value = jit_ulong_to_long(from->un.ulong_value); } else if(from_type == jit_type_nfloat) { result->un.long_value = jit_nfloat_to_long(from->un.nfloat_value); } } else if(to_type == jit_type_ulong) { if(from_type == jit_type_int) { result->un.ulong_value = jit_int_to_ulong(from->un.int_value); } else if(from_type == jit_type_uint) { result->un.ulong_value = jit_uint_to_ulong(from->un.uint_value); } else if(from_type == jit_type_long) { result->un.ulong_value = jit_long_to_ulong(from->un.long_value); } else if(from_type == jit_type_ulong) { result->un.ulong_value = jit_ulong_to_ulong(from->un.ulong_value); } else if(from_type == jit_type_nfloat) { result->un.ulong_value = jit_nfloat_to_ulong(from->un.nfloat_value); } } else if(to_type == jit_type_nfloat) { if(from_type == jit_type_int) { result->un.nfloat_value = jit_int_to_nfloat(from->un.int_value); } else if(from_type == jit_type_uint) { result->un.nfloat_value = jit_uint_to_nfloat(from->un.uint_value); } else if(from_type == jit_type_long) { result->un.nfloat_value = jit_long_to_nfloat(from->un.long_value); } else if(from_type == jit_type_ulong) { result->un.nfloat_value = jit_ulong_to_nfloat(from->un.ulong_value); } else if(from_type == jit_type_nfloat) { result->un.nfloat_value = from->un.nfloat_value; } } } static char *format_integer(char *buf, int is_neg, jit_ulong value) { buf += 64; *(--buf) = '\0'; if(value == 0) { *(--buf) = '0'; } else { while(value != 0) { *(--buf) = '0' + (int)(value % 10); value /= 10; } } if(is_neg) { *(--buf) = '-'; } return buf; } char *dpas_constant_name(jit_constant_t *value) { jit_type_t type; char buf[64]; char *result; if(value->type == dpas_type_nil) { return jit_strdup("nil"); } else if(jit_type_is_pointer(value->type) && jit_type_get_ref(value->type) == dpas_type_char) { return concat_strings (concat_strings(jit_strdup("\""), jit_strdup((char *)(value->un.ptr_value))), jit_strdup("\"")); } type = dpas_promote_type(value->type); if(type == jit_type_int) { if(value->un.int_value < 0) { result = format_integer (buf, 1, (jit_ulong)(-((jit_long)(value->un.int_value)))); } else { result = format_integer (buf, 0, (jit_ulong)(jit_long)(value->un.int_value)); } } else if(type == jit_type_uint) { result = format_integer (buf, 0, (jit_ulong)(value->un.uint_value)); } else if(type == jit_type_long) { if(value->un.int_value < 0) { result = format_integer (buf, 1, (jit_ulong)(-(value->un.long_value))); } else { result = format_integer (buf, 0, (jit_ulong)(value->un.long_value)); } } else if(type == jit_type_ulong) { result = format_integer(buf, 0, value->un.ulong_value); } else if(type == jit_type_nfloat) { sprintf(buf, "%g", (double)(value->un.nfloat_value)); result = buf; } else { result = "unknown constant"; } return jit_strdup(result); } int dpas_is_set_compatible(jit_type_t type) { if(jit_type_get_tagged_kind(type) == DPAS_TAG_ENUM) { return (((dpas_enum *)jit_type_get_tagged_data(type))->num_elems <= 32); } else if(jit_type_get_tagged_kind(type) == DPAS_TAG_SUBRANGE) { dpas_subrange *range; if(jit_type_get_tagged_type(type) != jit_type_int) { return 0; } range = (dpas_subrange *)jit_type_get_tagged_data(type); if(range->first.un.int_value < 0 || range->first.un.int_value > 31 || range->last.un.int_value < 0 || range->last.un.int_value > 31) { return 0; } return 1; } return 0; } int dpas_type_is_numeric(jit_type_t type) { if(type == jit_type_sbyte || type == jit_type_ubyte || type == jit_type_short || type == jit_type_ushort || type == jit_type_int || type == jit_type_uint || type == jit_type_long || type == jit_type_ulong || type == jit_type_float32 || type == jit_type_float64 || type == jit_type_nfloat) { return 1; } if(jit_type_get_tagged_kind(type) == DPAS_TAG_SUBRANGE) { return 1; } return 0; } int dpas_type_is_integer(jit_type_t type) { if(type == jit_type_sbyte || type == jit_type_ubyte || type == jit_type_short || type == jit_type_ushort || type == jit_type_int || type == jit_type_uint || type == jit_type_long || type == jit_type_ulong) { return 1; } if(jit_type_get_tagged_kind(type) == DPAS_TAG_SUBRANGE) { return 1; } return 0; } int dpas_type_is_boolean(jit_type_t type) { return (type == dpas_type_boolean || type == dpas_type_cboolean); } int dpas_type_is_record(jit_type_t type) { type = jit_type_normalize(type); return (jit_type_is_struct(type) || jit_type_is_union(type)); } jit_type_t dpas_type_is_var(jit_type_t type) { if(jit_type_is_tagged(type) && jit_type_get_tagged_kind(type) == DPAS_TAG_VAR) { return jit_type_get_ref(jit_type_normalize(type)); } return 0; }