Compute the version number dynamically
[muddle-interpreter.git] / src / object.h
index ec322b5d219547c405b6632735a3a0130fce5663..1435f5d353098a0105296df4b9fe01ac116a996d 100644 (file)
@@ -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