ref: fd1e36f98d997c8183d3040b66fa6f9cd91e825b
dir: /types.c/
#include "flisp.h"
#include "cvalues.h"
#include "equalhash.h"
#include "types.h"
fltype_t *
get_type(value_t t)
{
fltype_t *ft;
if(issymbol(t)){
ft = ((symbol_t*)ptr(t))->type;
if(ft != nil)
return ft;
}
void **bp = equalhash_bp(&FL(TypeTable), (void*)t);
if(*bp != HT_NOTFOUND){
assert(*bp != nil);
return *bp;
}
bool isarray = iscons(t) && car_(t) == FL_arraysym && iscons(cdr_(t));
size_t sz;
if(isarray && !iscons(cdr_(cdr_(t)))){
// special case: incomplete array type
sz = 0;
}else{
sz = ctype_sizeof(t);
}
ft = MEM_CALLOC(1, sizeof(fltype_t));
assert(ft != nil);
ft->type = t;
ft->numtype = NONNUMERIC;
if(issymbol(t)){
ft->numtype = sym_to_numtype(t);
assert(valid_numtype(ft->numtype));
((symbol_t*)ptr(t))->type = ft;
}
ft->size = sz;
if(iscons(t)){
if(isarray){
fltype_t *eltype = get_type(car_(cdr_(t)));
assert(eltype != nil);
if(eltype->size == 0){
MEM_FREE(ft);
lerrorf(FL_ArgError, "invalid array element type");
}
ft->elsz = eltype->size;
ft->eltype = eltype;
ft->init = cvalue_array_init;
//eltype->artype = ft; -- this is a bad idea since some types carry array sizes
}
}
*bp = ft;
return ft;
}
fltype_t *
get_array_type(value_t eltype)
{
fltype_t *et = get_type(eltype);
if(et->artype == nil)
et->artype = get_type(fl_list2(FL_arraysym, eltype));
return et->artype;
}
fltype_t *
define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab, cvinitfunc_t init)
{
fltype_t *ft = MEM_CALLOC(1, sizeof(fltype_t));
assert(ft != nil);
ft->type = sym;
ft->numtype = NONNUMERIC;
ft->size = sz;
ft->vtable = vtab;
ft->init = init;
return ft;
}
void
relocate_typetable(void)
{
htable_t *h = &FL(TypeTable);
size_t i;
void *nv;
for(i = 0; i < h->size; i += 2){
if(h->table[i] != HT_NOTFOUND){
nv = (void*)relocate((value_t)h->table[i]);
h->table[i] = nv;
if(h->table[i+1] != HT_NOTFOUND)
((fltype_t*)h->table[i+1])->type = (value_t)nv;
}
}
}