void ty_struct_member_index(EagleComplexType *ett, char *member, int *index, EagleComplexType **type) { EagleStructType *st = (EagleStructType *)ett; Arraylist *names = hst_get(&struct_table, st->name, NULL, NULL); Arraylist *types = hst_get(&types_table, st->name, NULL, NULL); if(!names) { *type = NULL; *index = -2; return; } int i; for(i = 0; i < names->count; i++) { char *tmp = names->items[i]; if(!strcmp(tmp, member)) { *type = types->items[i]; if(ty_is_class(st->name)) i += 1; *index = i; return; } } *type = NULL; *index = -1; }
EagleComplexType *ty_method_lookup(char *name, char *method) { Hashtable *lst = hst_get(&method_table, name, NULL, NULL); if(!lst) return NULL; return hst_get(lst, method, NULL, NULL); }
VarBundle *vs_get_from_module(VarScopeStack *vs, char *ident, char *mod_name) { Hashtable *module = hst_get(&vs->modules, mod_name, NULL, NULL); if(!module) return NULL; return hst_get(module, ident, NULL, NULL); }
void ty_struct_get_members(EagleComplexType *ett, Arraylist **names, Arraylist **types) { EagleStructType *st = (EagleStructType *)ett; if(names) *names = hst_get(&struct_table, st->name, NULL, NULL); if(types) *types = hst_get(&types_table, st->name, NULL, NULL); }
void ty_register_interface(char *name) { if(hst_get(&interface_table, name, NULL, NULL)) die(-1, "Redeclaring interface with name: %s", name); if(hst_get(&method_table, name, NULL, NULL)) die(-1, "Interface declaration %s clashes with previously named class.", name); Arraylist *list = malloc(sizeof(Arraylist)); *list = arr_create(10); hst_put(&interface_table, name, list, NULL, NULL); }
int ty_needs_destructor(EagleComplexType *ett) { EagleStructType *st = (EagleStructType *)ett; Arraylist *types = hst_get(&types_table, st->name, NULL, NULL); if(!types) return -2; int i; for(i = 0; i < types->count; i++) { EagleComplexType *ty = types->items[i]; if(ET_IS_COUNTED(ty) || ET_IS_WEAK(ty)) return 1; if(ty->type == ETStruct) { if(ty_needs_destructor(ty)) return 1; } if(ty->type == ETArray && ett_array_has_counted(ty)) return 1; } return 0; }
VarBundle *vs_get(VarScopeStack *vs, char *ident) { VarScope *s = vs->scope; for(; s; s = s->next) { if(s->scope == BARRIER) { VarScopeStack temp; temp.scope = s->next; VarBundle *o = vs_get(&temp, ident); if(o) { VarBarrier *vb = (VarBarrier *)s; vb->closedCallback(o, ident, vb->closedData); // We expect the callback to alter the scope stack so the // following code doesn't recurse forever return vs_get(vs, ident); } return NULL; } VarBundle *o = hst_get(&s->table, ident, NULL, NULL); if(o) return o; } return NULL; }
void ty_add_enum_item(char *name, char *item, long val) { Hashtable *en = hst_get(&enum_table, name, NULL, NULL); if(!en) die(__LINE__, "Internal compiler error declaring enum item %s.%s", name, item); hst_put(en, item, PTR(val), NULL, NULL); }
long ty_lookup_enum_item(EagleComplexType *ty, char *item, int *valid) { EagleEnumType *et = (EagleEnumType *)ty; Hashtable *en = hst_get(&enum_table, et->name, NULL, NULL); if(!en) die(__LINE__, "Internal compiler error could not find enum item %s.%s", et->name, item); if(!hst_contains_key(en, item, NULL, NULL)) { *valid = 0; return 0; } *valid = 1; return (long)hst_get(en, item, NULL, NULL); }
void ty_set_generic_type(char *ident, EagleComplexType *with) { EagleComplexType *ty = hst_get(&generic_ident_table, ident, NULL, NULL); if(!ty) die(-1, "Unknown generic type: %s", ident); memcpy(ty, with, ty_size_of_type(with)); }
int ty_interface_count(char *name) { Arraylist *names = hst_get(&interface_table, name, NULL, NULL); if(!names) return -1; return (int)names->count; }
void vs_add_callback(VarScopeStack *vs, char *ident, LostScopeCallback callback, void *data) { VarScope *s = vs->scope; VarBundle *vb = hst_get(&s->table, ident, NULL, NULL); if(!vb) return; vb->scopeCallback = callback; vb->scopeData = data; }
int vs_is_in_local_scope(VarScopeStack *vs, char *ident) { VarScope *s = vs->scope; if(!s) return 0; if(s->scope == BARRIER) return 0; return !!(int)(uintptr_t)hst_get(&s->table, ident, NULL, NULL); }
void ty_set_typedef(char *name, EagleComplexType *type) { void *tag = hst_get(&typedef_table, name, NULL, NULL); // If tag isn't found, we must have a redundant // typedef if(!tag) return; memcpy(tag, type, ty_size_of_type(type)); }
void ty_register_enum(char *name) { Hashtable *en = hst_get(&enum_table, name, NULL, NULL); if(en) die(-1, "Redeclaring enum with name: %s", name); en = malloc(sizeof(*en)); *en = hst_create(); en->duplicate_keys = 1; hst_put(&enum_table, name, en, NULL, NULL); }
void ty_register_class(char *name) { Hashtable *lst = hst_get(&method_table, name, NULL, NULL); if(lst) die(-1, "Redeclaring class with name: %s", name); lst = malloc(sizeof(Hashtable)); *lst = hst_create(); lst->duplicate_keys = 1; hst_put(&method_table, name, lst, NULL, NULL); }
int ty_interface_offset(char *name, char *method) { Arraylist *names = hst_get(&interface_table, name, NULL, NULL); if(!names) return -1; int i; for(i = 0; i < names->count; i++) if(strcmp(names->items[i], method) == 0) return i; return -1; }
void ty_add_method(char *name, char *method, EagleComplexType *ty) { Hashtable *lst = hst_get(&method_table, name, NULL, NULL); if(!lst) { lst = malloc(sizeof(Hashtable)); *lst = hst_create(); lst->duplicate_keys = 1; hst_put(&method_table, name, lst, NULL, NULL); } hst_put(lst, method, ty, NULL, NULL); }
int vs_is_in_global_scope(VarScopeStack *vs, char *ident) { VarScope *s = vs->scope; for(; s; s = s->next) { if(s->scope == BARRIER) continue; VarBundle *o = hst_get(&s->table, ident, NULL, NULL); if(o) return !s->next; } return 0; }
EagleComplexType *ett_generic_type(char *ident) { EagleComplexType *ty = hst_get(&generic_ident_table, ident, NULL, NULL); if(ty) return ty; ty = calloc(ty_type_max_size(), 1); ty->type = ETGeneric; ((EagleGenericType *)ty)->ident = ident; hst_put(&generic_ident_table, ident, ty, NULL, NULL); pool_add(&type_mempool, ty); return ty; }
EagleComplexType *ett_interface_type(char *name) { EagleComplexType *et = hst_get(&type_named_table, name, NULL, NULL); if(et) return et; EagleInterfaceType *ett = malloc(sizeof(EagleInterfaceType)); ett->names = arr_create(3); arr_append(&ett->names, name); ett->type = ETInterface; pool_add(&list_mempool, &ett->names); pool_add(&type_mempool, ett); return (EagleComplexType *)ett; }
EagleComplexType *ett_class_type(char *name) { EagleComplexType *et = hst_get(&type_named_table, name, NULL, NULL); if(et) return et; EagleStructType *ett = malloc(sizeof(EagleStructType)); ett->type = ETClass; ett->types = arr_create(10); ett->names = arr_create(10); ett->name = name; hst_put(&type_named_table, name, ett, NULL, NULL); pool_add(&type_mempool, ett); pool_add(&list_mempool, &ett->types); pool_add(&list_mempool, &ett->names); return (EagleComplexType *)ett; }
VarBundle *vs_put_in_module(VarScopeStack *vs, char *ident, char *module, LLVMValueRef val, EagleComplexType *type) { VarBundle *vb = vs_create(ident, module, type, val, -1); Hashtable *mod = hst_get(&vs->modules, module, NULL, NULL); if(!mod) { mod = malloc(sizeof(Hashtable)); *mod = hst_create(); mod->duplicate_keys = 1; hst_put(&vs->modules, module, mod, NULL, NULL); } hst_put(mod, ident, vb, NULL, NULL); pool_add(&vs->pool, vb); return vb; }
LLVMTypeRef ty_get_counted(LLVMTypeRef in) { char *translated = LLVMPrintTypeToString(in); LLVMTypeRef ref = hst_get(&counted_table, translated, NULL, NULL); if(!ref) { ref = LLVMStructCreateNamed(utl_get_current_context(), ""); LLVMTypeRef tys[6]; LLVMGetStructElementTypes(in, tys); LLVMStructSetBody(ref, tys, 6, 0); hst_put(&counted_table, translated, ref, NULL, NULL); } LLVMDisposeMessage(translated); return ref; }
EagleComplexType *ett_enum_type(char *name) { EagleComplexType *et = hst_get(&enum_named_table, name, NULL, NULL); if(et) return et; char *anam = hst_retrieve_duped_key(&enum_table, name); if(!anam) die(__LINE__, "Internal compiler error: no such enum %s", name); EagleEnumType *en = malloc(sizeof(*en)); en->type = ETEnum; en->name = anam; pool_add(&type_mempool, en); hst_put(&enum_named_table, name, en, NULL, NULL); return (EagleComplexType *)en; }
EagleComplexType *et_parse_string(char *text) { TTEST(text, "auto", ETAuto); TTEST(text, "any", ETAny); TTEST(text, "bool", ETInt1); TTEST(text, "byte", ETInt8); TTEST(text, "ubyte", ETUInt8); TTEST(text, "short", ETInt16); TTEST(text, "ushort", ETUInt16); TTEST(text, "int", ETInt32); TTEST(text, "uint", ETUInt32); TTEST(text, "long", ETInt64); TTEST(text, "ulong", ETUInt64); TTEST(text, "float", ETFloat); TTEST(text, "double", ETDouble); TTEST(text, "void", ETVoid); if(ty_is_name(text)) { void *type = hst_get(&typedef_table, text, NULL, NULL); if(type) return type; if(ty_is_class(text)) return ett_class_type(text); else if(ty_is_interface(text)) return ett_interface_type(text); else if(ty_is_enum(text)) return ett_enum_type(text); else return ett_struct_type(text); } if(pipe_is_type(text)) { return ett_generic_type(text); } return NULL; }
int ty_is_enum(char *name) { return (int)(uintptr_t)hst_get(&enum_table, name, NULL, NULL); }
int ty_is_interface(char *name) { return (int)(uintptr_t)hst_get(&interface_table, name, NULL, NULL); }
int ty_is_class(char *name) { return (int)(uintptr_t)hst_get(&method_table, name, NULL, NULL); }
int ty_is_name(char *name) { return (int)(uintptr_t)hst_get(&name_table, name, NULL, NULL); }