int strm_nil_p(strm_value v) { if (strm_value_tag(v) != STRM_TAG_PTR) return FALSE; return strm_value_val(v) == 0; }
int strm_value_eq(strm_value a, strm_value b) { if (a == b) return TRUE; if (strm_value_tag(a) != strm_value_tag(b)) goto typediff; switch (strm_value_tag(a)) { case STRM_TAG_STRUCT: return strm_ary_eq(a, b); case STRM_TAG_STRING_O: case STRM_TAG_STRING_F: return strm_str_eq(a, b); case STRM_TAG_CFUNC: return (strm_cfunc)(intptr_t)strm_value_val(a) == (strm_cfunc)(intptr_t)strm_value_val(b); case STRM_TAG_PTR: return strm_value_vptr(a) == strm_value_vptr(b); typediff: default: if (strm_number_p(a) && strm_number_p(b)) { return strm_value_flt(a) == strm_value_flt(b); } return FALSE; } }
int strm_value_bool(strm_value v) { uint64_t i = strm_value_val(v); if (i == 0) { switch (strm_value_tag(v)) { case STRM_TAG_BOOL: /* false */ case STRM_TAG_PTR: /* nil */ break; default: assert(strm_value_tag(v) == STRM_TAG_BOOL); break; } return FALSE; } else { return TRUE; } }
strm_string strm_to_str(strm_value v) { char buf[32]; int n; strm_state* ns = strm_value_ns(v); if (ns) { strm_value m; n = strm_var_get(ns, strm_str_intern_lit("string"), &m); if (n == STRM_OK) { n = strm_funcall(NULL, m, 1, &v, &m); if (n == STRM_OK && strm_string_p(m)) return m; } } switch (strm_value_tag(v)) { case STRM_TAG_INT: n = sprintf(buf, "%d", strm_to_int(v)); return strm_str_new(buf, n); case STRM_TAG_BOOL: n = sprintf(buf, strm_to_int(v) ? "true" : "false"); return strm_str_new(buf, n); case STRM_TAG_CFUNC: n = sprintf(buf, "<cfunc:%p>", (void*)strm_value_cfunc(v)); return strm_str_new(buf, n); case STRM_TAG_STRING_I: case STRM_TAG_STRING_6: case STRM_TAG_STRING_O: case STRM_TAG_STRING_F: return strm_value_str(v); case STRM_TAG_ARRAY: case STRM_TAG_STRUCT: return strm_inspect(v); case STRM_TAG_PTR: if (strm_value_val(v) == 0) return strm_str_lit("nil"); else { void *p = strm_ptr(v); switch (strm_ptr_type(p)) { case STRM_PTR_STREAM: n = sprintf(buf, "<stream:%p>", p); break; case STRM_PTR_IO: { strm_io io = (strm_io)p; char *mode; switch (io->mode & 3) { case STRM_IO_READ: mode = "r"; break; case STRM_IO_WRITE: mode = "w"; break; case STRM_IO_READ|STRM_IO_WRITE: mode = "rw"; break; default: mode = "?"; break; } n = sprintf(buf, "<io: fd=%d mode=%s>", io->fd, mode); break; } case STRM_PTR_LAMBDA: n = sprintf(buf, "<lambda:%p>", p); break; case STRM_PTR_AUX: n = sprintf(buf, "<obj:%p>", p); break; } return strm_str_new(buf, n); } default: if (strm_flt_p(v)) { n = sprintf(buf, "%.14g", strm_to_flt(v)); return strm_str_new(buf, n); } n = sprintf(buf, "<%p>", strm_value_vptr(v)); return strm_str_new(buf, n); } /* not reached */ return strm_str_null; }
strm_cfunc strm_value_cfunc(strm_value v) { assert(strm_value_tag(v) == STRM_TAG_CFUNC); return (strm_cfunc)(intptr_t)strm_value_val(v); }
strm_string strm_to_str(strm_value v) { char buf[32]; int n; switch (strm_value_tag(v)) { case STRM_TAG_INT: n = sprintf(buf, "%d", strm_to_int(v)); return strm_str_new(buf, n); case STRM_TAG_BOOL: n = sprintf(buf, strm_to_int(v) ? "true" : "false"); return strm_str_new(buf, n); case STRM_TAG_CFUNC: n = sprintf(buf, "<cfunc:%p>", (void*)strm_value_cfunc(v)); return strm_str_new(buf, n); case STRM_TAG_STRING_I: case STRM_TAG_STRING_6: case STRM_TAG_STRING_O: case STRM_TAG_STRING_F: return strm_value_str(v); case STRM_TAG_ARRAY: case STRM_TAG_STRUCT: return strm_inspect(v); case STRM_TAG_PTR: if (strm_value_val(v) == 0) return strm_str_new("nil", 3); else { void *p = strm_ptr(v); switch (strm_ptr_type(p)) { case STRM_PTR_TASK: n = sprintf(buf, "<task:%p>", p); break; case STRM_PTR_IO: { strm_io io = (strm_io)p; char *mode; switch (io->mode & 3) { case STRM_IO_READ: mode = "r"; break; case STRM_IO_WRITE: mode = "w"; break; case STRM_IO_READ|STRM_IO_WRITE: mode = "rw"; break; } n = sprintf(buf, "<io: fd=%d mode=%s>", io->fd, mode); break; } case STRM_PTR_LAMBDA: n = sprintf(buf, "<lambda:%p>", p); break; case STRM_PTR_MISC: n = sprintf(buf, "<obj:%p>", p); break; } return strm_str_new(buf, n); break; } default: if (strm_flt_p(v)) { n = sprintf(buf, "%g", strm_to_flt(v)); return strm_str_new(buf, n); } n = sprintf(buf, "<%p>", strm_value_vptr(v)); return strm_str_new(buf, n); } /* not reached */ return strm_str_null; }
struct strm_array* strm_ary_struct(strm_value v) { return (struct strm_array*)strm_value_val(v); }