X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fobject.h;h=1435f5d353098a0105296df4b9fe01ac116a996d;hb=refs%2Fheads%2Fmaster;hp=ec322b5d219547c405b6632735a3a0130fce5663;hpb=58a5ffdfec139a0c9d399f603b77a764ae8607f7;p=muddle-interpreter.git diff --git a/src/object.h b/src/object.h index ec322b5..1435f5d 100644 --- a/src/object.h +++ b/src/object.h @@ -122,8 +122,17 @@ typedef union object object; typedef struct { - alignas (8) uint32_t _pad; + alignas (8) + // layout so that value can be upcast by reinterpreting as a fix64 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + int32_t n; + uint32_t _pad; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + uint32_t _pad; int32_t n; +#else +#error Unusual endianness? +#endif } fix32_val; typedef struct { @@ -192,7 +201,7 @@ typedef struct typedef struct { - alignas (8) uint32_t _pad; + alignas (8) uint32_t namelen; heap_ptr body; } atom_val; typedef struct @@ -221,6 +230,18 @@ typedef struct uint32_t gc; } dope_object; +/// Value half of a poolable object, for storage in a uvector. +typedef union uv_val +{ + fix32_val fix32; + fix64_val fix64; + list_val list; + vector_val vector; + uvector_val uvector; + subr_val subr; + atom_val atom; +} uv_val; + /// Object of a type that can be stored in the pool. /// NB. a pool_object* can point outside the pool; contrast with pool_ptr. typedef union pool_object @@ -231,7 +252,7 @@ typedef union pool_object // NB. never take the address of these type-punned fields! alignas (16) evaltype type; pool_ptr rest; - opaque64 val; + uv_val val; }; /// objects of statically known type fix32_object fix32; @@ -240,20 +261,9 @@ typedef union pool_object vector_object vector; uvector_object uvector; atom_object atom; + subr_object subr; } pool_object; -/// Value half of a poolable object, for storage in a uvector. -typedef union -{ - fix32_val fix32; - fix64_val fix64; - list_val list; - vector_val vector; - uvector_val uvector; - subr_val subr; - atom_val atom; -} uv_val; - union object { /// any object has a type @@ -262,7 +272,11 @@ union object // NB. never take the address of these type-punned fields! alignas (16) evaltype type; opaque32 _unknown0; - opaque64 _unknown1; + union + { + opaque64 _unknown1; + uv_val uv_val; + }; }; /// objects of statically known type /// use as_X() for checked downcast @@ -274,6 +288,7 @@ union object uvector_object uvector; atom_object atom; tuple_object tuple; + subr_object subr; }; /** @@ -329,7 +344,7 @@ new_uvector (heap_ptr body, uint32_t length) { return (uvector_object) { - .type = EVALTYPE_VECTOR,.rest = 0,.val = (uvector_val) + .type = EVALTYPE_UVECTOR,.rest = 0,.val = (uvector_val) { .len = length,.body = body} }; @@ -355,26 +370,69 @@ new_subr (void (*fn) ()) } static inline atom_object -new_atom (pool_ptr body) +new_atom (pool_ptr body, uint32_t namelen) { return (atom_object) { .type = EVALTYPE_ATOM,.rest = 0,.val = (atom_val) { - .body = body} + .body = body,.namelen = namelen} }; } +static inline dope_object +new_dope (uint32_t len, evaltype type) +{ + return (dope_object) + { + .type = type,.grow = 0,.len = len,.gc = 0}; +} + /** Common object operations. */ uint32_t list_length (const list_object * o); +dope_object *vec_dope (const vector_object * o); + +dope_object *uv_dope (const uvector_object * o); + +static inline evaltype +utype (const uvector_object * o) +{ + return uv_dope (o)->type; +} + +object +uv_get (const uvector_object * o, uint32_t i); + + +// Change the EVALTYPE of an object. New type must have same PRIMTYPE. +static inline void +chtype (object * o, evaltype type) +{ + assert (TYPEPRIM_EQ (o->type, type)); + o->type = type; +} + +// Allocate an vector of LOSEs and return a handle with length=0. +vector_object vector_create (uint32_t capacity); + +// Stack-like interface to a VECTOR (with automatic GROW!) +object *stack_push (vector_object * v); + /** Checked downcasts. */ +static inline fix32_object * +as_fix32 (object * o) +{ + assert (TYPEPRIM_EQ (o->type, TYPEPRIM_FIX32)); + return &o->fix32; +} + static inline list_object * as_list (object * o) { @@ -403,4 +461,11 @@ as_pool (object * p) return (pool_object *) p; } +static inline atom_object * +as_atom (object * o) +{ + assert (TYPEPRIM_EQ (o->type, EVALTYPE_ATOM)); + return &o->atom; +} + #endif // OBJECT_H