Define UVECTOR and ATOM
[muddle-interpreter.git] / src / object.h
index 1d9918e20a415404bfe1e0f5005643452bae256b..ec322b5d219547c405b6632735a3a0130fce5663 100644 (file)
@@ -31,14 +31,18 @@ typedef uint32_t evaltype;
 enum
 {
 // pool OK
+  TYPEPRIM_LOSE = 0x00000000,
   TYPEPRIM_FIX32 = 0x00010000,
   TYPEPRIM_FIX64 = 0x00020000,
   TYPEPRIM_LIST = 0x00030000,
   TYPEPRIM_VECTOR = 0x00040000,
-  TYPEPRIM_SUBR = 0x00050000,
+  TYPEPRIM_UVECTOR = 0x00050000,
+  TYPEPRIM_SUBR = 0x00060000,
+  TYPEPRIM_ATOM = 0x00070000,
 
 // can't be in pool
   TYPEPRIM_NOPOOL_MASK = 0x70000000,
+  TYPEPRIM_VECTOR_BODY = 0x70000000,
   TYPEPRIM_TUPLE = 0x70010000,
 
 // TYPEPRIM is half of EVALTYPE
@@ -47,6 +51,8 @@ enum
 
 enum
 {
+  EVALTYPE_LOSE = TYPEPRIM_LOSE,
+
   EVALTYPE_FIX32 = TYPEPRIM_FIX32,
 
   EVALTYPE_FIX64 = TYPEPRIM_FIX64,
@@ -57,8 +63,16 @@ enum
 
   EVALTYPE_VECTOR = TYPEPRIM_VECTOR,
 
+  EVALTYPE_UVECTOR = TYPEPRIM_UVECTOR,
+  EVALTYPE_OBLIST,
+
   EVALTYPE_SUBR = TYPEPRIM_SUBR,
 
+  EVALTYPE_ATOM = TYPEPRIM_ATOM,
+
+  EVALTYPE_VECTOR_BODY = TYPEPRIM_VECTOR_BODY,
+  EVALTYPE_ATOM_BODY,
+
   EVALTYPE_TUPLE = TYPEPRIM_TUPLE,
 };
 
@@ -106,44 +120,88 @@ about types.
 
 typedef union object object;
 
+typedef struct
+{
+  alignas (8) uint32_t _pad;
+  int32_t n;
+} fix32_val;
 typedef struct
 {
   alignas (16) evaltype type;
   pool_ptr rest;
-  uint32_t _pad;
-  int32_t val;
+  fix32_val val;
 } fix32_object;
 
+typedef struct
+{
+  alignas (8) int64_t n;
+} fix64_val;
 typedef struct
 {
   alignas (16) evaltype type;
   pool_ptr rest;
-  int64_t val;
+  fix64_val val;
 } fix64_object;
 
+typedef struct
+{
+  alignas (8) uint32_t _pad;
+  pool_ptr head;
+} list_val;
 typedef struct
 {
   alignas (16) evaltype type;
   pool_ptr rest;
-  uint32_t _pad;
-  pool_ptr head;
+  list_val val;
 } list_object;
 
+typedef struct
+{
+  alignas (8) uint32_t len;
+  heap_ptr body;
+} vector_val;
 typedef struct
 {
   alignas (16) evaltype type;
   pool_ptr rest;
-  uint32_t len;
-  heap_ptr body;
+  vector_val val;
 } vector_object;
 
+typedef struct
+{
+  alignas (8) uint32_t len;
+  heap_ptr body;
+} uvector_val;
+typedef struct
+{
+  alignas (16) evaltype type;
+  pool_ptr rest;
+  uvector_val val;
+} uvector_object;
+
+typedef struct
+{
+  alignas (8) void (*fn) ();
+} subr_val;
 typedef struct
 {
   alignas (16) evaltype type;
   pool_ptr rest;
-  void (*fn) ();
+  subr_val val;
 } subr_object;
 
+typedef struct
+{
+  alignas (8) uint32_t _pad;
+  heap_ptr body;
+} atom_val;
+typedef struct
+{
+  alignas (16) evaltype type;
+  pool_ptr rest;
+  atom_val val;
+} atom_object;
+
 typedef struct
 {
   alignas (16)
@@ -155,6 +213,14 @@ typedef struct
   // uniq_id uid ??
 } tuple_object;
 
+typedef struct
+{
+  alignas (16) evaltype type;
+  uint32_t grow;
+  uint32_t len;
+  uint32_t gc;
+} dope_object;
+
 /// 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
@@ -162,6 +228,7 @@ typedef union pool_object
   /// any pool object has a type and a rest
   struct
   {
+    // NB. never take the address of these type-punned fields!
     alignas (16) evaltype type;
     pool_ptr rest;
     opaque64 val;
@@ -171,13 +238,28 @@ typedef union pool_object
   fix64_object fix64;
   list_object list;
   vector_object vector;
+  uvector_object uvector;
+  atom_object atom;
 } 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
   struct
   {
+    // NB. never take the address of these type-punned fields!
     alignas (16) evaltype type;
     opaque32 _unknown0;
     opaque64 _unknown1;
@@ -189,6 +271,8 @@ union object
   fix64_object fix64;
   list_object list;
   vector_object vector;
+  uvector_object uvector;
+  atom_object atom;
   tuple_object tuple;
 };
 
@@ -201,7 +285,10 @@ new_fix32 (int32_t n)
 {
   return (fix32_object)
   {
-  .type = EVALTYPE_FIX32,.rest = 0,.val = n};
+    .type = EVALTYPE_FIX32,.rest = 0,.val = (fix32_val)
+    {
+    .n = n}
+  };
 }
 
 static inline fix64_object
@@ -209,7 +296,10 @@ new_fix64 (int64_t n)
 {
   return (fix64_object)
   {
-  .type = EVALTYPE_FIX64,.rest = 0,.val = n};
+    .type = EVALTYPE_FIX64,.rest = 0,.val = (fix64_val)
+    {
+    .n = n}
+  };
 }
 
 static inline list_object
@@ -217,7 +307,10 @@ new_list (pool_ptr head)
 {
   return (list_object)
   {
-  .type = EVALTYPE_LIST,.rest = 0,.head = head,};
+    .type = EVALTYPE_LIST,.rest = 0,.val = (list_val)
+    {
+    .head = head}
+  ,};
 }
 
 static inline vector_object
@@ -225,7 +318,21 @@ new_vector (heap_ptr body, uint32_t length)
 {
   return (vector_object)
   {
-  .type = EVALTYPE_VECTOR,.rest = 0,.len = length,.body = body,};
+    .type = EVALTYPE_VECTOR,.rest = 0,.val = (vector_val)
+    {
+    .len = length,.body = body}
+  ,};
+}
+
+static inline uvector_object
+new_uvector (heap_ptr body, uint32_t length)
+{
+  return (uvector_object)
+  {
+    .type = EVALTYPE_VECTOR,.rest = 0,.val = (uvector_val)
+    {
+    .len = length,.body = body}
+  };
 }
 
 static inline tuple_object
@@ -233,7 +340,7 @@ new_tuple (object * body, uint32_t length)
 {
   return (tuple_object)
   {
-  .type = EVALTYPE_TUPLE,.len = length,.body = body,};
+  .type = EVALTYPE_TUPLE,.len = length,.body = body};
 }
 
 static inline subr_object
@@ -241,7 +348,21 @@ new_subr (void (*fn) ())
 {
   return (subr_object)
   {
-  .type = EVALTYPE_SUBR,.rest = 0,.fn = fn,};
+    .type = EVALTYPE_SUBR,.rest = 0,.val = (subr_val)
+    {
+    .fn = fn}
+  };
+}
+
+static inline atom_object
+new_atom (pool_ptr body)
+{
+  return (atom_object)
+  {
+    .type = EVALTYPE_ATOM,.rest = 0,.val = (atom_val)
+    {
+    .body = body}
+  };
 }
 
 /**
@@ -268,6 +389,13 @@ as_vector (object * o)
   return &o->vector;
 }
 
+static inline uvector_object *
+as_uvector (object * o)
+{
+  assert (TYPEPRIM_EQ (o->type, EVALTYPE_UVECTOR));
+  return &o->uvector;
+}
+
 static inline pool_object *
 as_pool (object * p)
 {