void val_print(cst_file fd,const cst_val *v) { const cst_val *p; if (v == NULL) cst_fprintf(fd,"[null]"); else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_INT) cst_fprintf(fd,"%d",val_int(v)); else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_FLOAT) cst_fprintf(fd,"%f",val_float(v)); else if (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING) cst_fprintf(fd,"%s",val_string(v)); else if (cst_val_consp(v)) { cst_fprintf(fd,"("); for (p=v; p; ) { val_print(fd,val_car(p)); p=val_cdr(p); if (p) cst_fprintf(fd," "); } cst_fprintf(fd,")"); } else cst_fprintf(fd,"[Val %s 0x%p]", cst_val_defs[CST_VAL_TYPE(v)/2].name,CST_VAL_VOID(v)); }
cst_val *val_new_typed(int type,void *vv) { cst_val *v = new_val(); CST_VAL_TYPE(v) = type; CST_VAL_VOID(v) = vv; return v; }
void delete_val(cst_val *v) { if (v) { if (cst_val_consp(v)) { delete_val(CST_VAL_CAR(v)); delete_val(CST_VAL_CDR(v)); cst_free(v); } else if (val_dec_refcount(v) == 0) { if (CST_VAL_TYPE(v) == CST_VAL_TYPE_STRING) cst_free(CST_VAL_VOID(v)); else if (CST_VAL_TYPE(v) >= CST_VAL_TYPE_FIRST_FREE) (cst_val_defs[CST_VAL_TYPE(v)/2].delete_function)(CST_VAL_VOID(v)); cst_free(v); } } }
void *val_generic(const cst_val *v, int type, const char *stype) { /* a generic access function that checks the expected type */ if (v && CST_VAL_TYPE(v) == type) return CST_VAL_VOID(v); else { cst_errmsg("VAL: tried to access %s in %d type val\n", stype, (v ? CST_VAL_TYPE(v) : -1)); cst_error(); } return NULL; }
int val_equal(const cst_val *v1, const cst_val *v2) { if (v1 == v2) return TRUE; /* its eq so its equal */ else if (v1 == 0) return FALSE; else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE(v2)) { if (cst_val_consp(v1)) return ((val_equal(val_car(v1),val_car(v2))) && (val_equal(val_cdr(v1),val_cdr(v2)))); else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_INT) return (val_int(v1) == val_int(v2)); else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_FLOAT) return (val_float(v1) == val_float(v2)); else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_STRING) return (cst_streq(CST_VAL_STRING(v1),CST_VAL_STRING(v2))); else return CST_VAL_VOID(v1) == CST_VAL_VOID(v2); } else return FALSE; }
void *val_void(const cst_val *v) { /* The scary, do anything function, this shouldn't be called by mortals */ if ((v == NULL) || (CST_VAL_TYPE(v) == CST_VAL_TYPE_CONS) || (CST_VAL_TYPE(v) == CST_VAL_TYPE_INT) || (CST_VAL_TYPE(v) == CST_VAL_TYPE_FLOAT)) { cst_errmsg("VAL: tried to access void in %d typed val\n", (v ? CST_VAL_TYPE(v) : -1)); cst_error(); return NULL; } else return CST_VAL_VOID(v); }