2 Copyright (C) 2017 Keziah Wesley
4 You can redistribute and/or modify this file under the terms of the
5 GNU Affero General Public License as published by the Free Software
6 Foundation, either version 3 of the License, or (at your option) any
9 This file is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Affero General Public License for more details.
14 You should have received a copy of the GNU Affero General Public
15 License along with this file. If not, see
16 <http://www.gnu.org/licenses/>.
29 typedef uint32_t evaltype;
34 TYPEPRIM_FIX32 = 0x00010000,
35 TYPEPRIM_FIX64 = 0x00020000,
36 TYPEPRIM_LIST = 0x00030000,
37 TYPEPRIM_VECTOR = 0x00040000,
38 TYPEPRIM_SUBR = 0x00050000,
41 TYPEPRIM_NOPOOL_MASK = 0x70000000,
42 TYPEPRIM_TUPLE = 0x70010000,
44 // TYPEPRIM is half of EVALTYPE
45 TYPEPRIM_MASK = 0x7fff0000
50 EVALTYPE_FIX32 = TYPEPRIM_FIX32,
52 EVALTYPE_FIX64 = TYPEPRIM_FIX64,
54 EVALTYPE_LIST = TYPEPRIM_LIST,
58 EVALTYPE_VECTOR = TYPEPRIM_VECTOR,
60 EVALTYPE_SUBR = TYPEPRIM_SUBR,
62 EVALTYPE_TUPLE = TYPEPRIM_TUPLE,
65 static inline uint32_t
68 return x & TYPEPRIM_MASK;
72 TYPEPRIM_EQ (evaltype a, evaltype b)
74 return !((a ^ b) & TYPEPRIM_MASK);
89 An Object's value is accessed through a concrete `foo_object`
92 `object` can be used to refer to Objects of unspecified type, which
93 are opaque except for their `type` field. Checked downcasts can be
94 performed via the `as_foo` functions; unchecked downcasts via
95 `object.foo` (use only when type information is locally
96 obvious). Some objects can be upcast to more specific supertypes,
97 such as `pool_object` for objects that are known to be storeable in
100 The generic `object` type should not be used to accept parameters
101 that have constraints on their type, and should not be used to
102 return objects that are of a statically-known type. Encoding type
103 information in function signatures allows strictly local reasoning
107 typedef union object object;
111 alignas (16) evaltype type;
119 alignas (16) evaltype type;
126 alignas (16) evaltype type;
134 alignas (16) evaltype type;
142 alignas (16) evaltype type;
150 /// no rest; is a NOPOOL type
153 /// allocation can be anywhere
158 /// Object of a type that can be stored in the pool.
159 /// NB. a pool_object* can point outside the pool; contrast with pool_ptr.
160 typedef union pool_object
162 /// any pool object has a type and a rest
165 alignas (16) evaltype type;
169 /// objects of statically known type
173 vector_object vector;
178 /// any object has a type
181 alignas (16) evaltype type;
185 /// objects of statically known type
186 /// use as_X() for checked downcast
191 vector_object vector;
196 Initialization helpers.
199 static inline fix32_object
200 new_fix32 (int32_t n)
202 return (fix32_object)
204 .type = EVALTYPE_FIX32,.rest = 0,.val = n};
207 static inline fix64_object
208 new_fix64 (int64_t n)
210 return (fix64_object)
212 .type = EVALTYPE_FIX64,.rest = 0,.val = n};
215 static inline list_object
216 new_list (pool_ptr head)
220 .type = EVALTYPE_LIST,.rest = 0,.head = head,};
223 static inline vector_object
224 new_vector (heap_ptr body, uint32_t length)
226 return (vector_object)
228 .type = EVALTYPE_VECTOR,.rest = 0,.len = length,.body = body,};
231 static inline tuple_object
232 new_tuple (object * body, uint32_t length)
234 return (tuple_object)
236 .type = EVALTYPE_TUPLE,.len = length,.body = body,};
239 static inline subr_object
240 new_subr (void (*fn) ())
244 .type = EVALTYPE_SUBR,.rest = 0,.fn = fn,};
248 Common object operations.
251 uint32_t list_length (const list_object * o);
257 static inline list_object *
260 assert (TYPEPRIM_EQ (o->type, EVALTYPE_LIST));
264 static inline vector_object *
265 as_vector (object * o)
267 assert (TYPEPRIM_EQ (o->type, EVALTYPE_VECTOR));
271 static inline pool_object *
274 assert (!(TYPEPRIM (p->type) & TYPEPRIM_NOPOOL_MASK));
275 return (pool_object *) p;