Reduct  v1.0.4-3-gdaf0d70
A functional and immutable language.
Loading...
Searching...
No Matches
handle_impl.h
Go to the documentation of this file.
1#ifndef REDUCT_HANDLE_IMPL_H
2#define REDUCT_HANDLE_IMPL_H 1
3
4#include "char.h"
5#include "core.h"
6#include "defs.h"
7#include "eval.h"
8#include "gc.h"
9#include "handle.h"
10#include "item.h"
11#include "stringify.h"
12
14 reduct_size_t* outLen)
15{
16 reduct_handle_ensure_item(reduct, handle);
18 if (item->type != REDUCT_ITEM_TYPE_ATOM)
19 {
20 REDUCT_ERROR_RUNTIME(reduct, "expected atom, got %s", reduct_item_type_str(item->type));
21 }
22 *outStr = item->atom.string;
23 *outLen = item->length;
24}
25
27{
28 REDUCT_ASSERT(reduct != REDUCT_NULL);
29 REDUCT_ASSERT(handle != REDUCT_NULL);
30
31 if (REDUCT_HANDLE_IS_ITEM(handle))
32 {
33 return;
34 }
35
36 if (REDUCT_HANDLE_IS_INT(handle))
37 {
39 *handle = REDUCT_HANDLE_FROM_ATOM(atom);
40 return;
41 }
42
45}
46
53
56{
57 REDUCT_ASSERT(reduct != REDUCT_NULL);
61
63 {
67 return;
68 }
69
71 {
75 return;
76 }
77
80
83
85 {
88 {
89 out->a.floatVal = itemA->atom.floatValue;
90 }
91 else
92 {
94 }
95
97 {
98 out->b.floatVal = itemB->atom.floatValue;
99 }
100 else
101 {
103 }
104 }
105 else if ((itemA->flags & REDUCT_ITEM_FLAG_INT_SHAPED) && (itemB->flags & REDUCT_ITEM_FLAG_INT_SHAPED))
106 {
108 out->a.intVal = itemA->atom.integerValue;
109 out->b.intVal = itemB->atom.integerValue;
110 }
111 else
112 {
113 REDUCT_ERROR_RUNTIME(reduct, "unsupported operand type %s and %s", reduct_item_type_str(itemA->type),
114 reduct_item_type_str(itemB->type));
115 }
116}
117
119{
120 REDUCT_ASSERT(reduct != REDUCT_NULL);
123
124 if (*a == *b)
125 {
126 return REDUCT_TRUE;
127 }
128
130 {
132 reduct_handle_promote(reduct, a, b, &prom);
134 {
135 return prom.a.intVal == prom.b.intVal;
136 }
137 return prom.a.floatVal == prom.b.floatVal;
138 }
139
140 reduct_handle_ensure_item(reduct, a);
141 reduct_handle_ensure_item(reduct, b);
142
145
146 if (itemA == itemB)
147 {
148 return REDUCT_TRUE;
149 }
150
151 if (itemA->type != itemB->type)
152 {
153 return REDUCT_FALSE;
154 }
155
156 if (itemA->flags != itemB->flags)
157 {
158 return REDUCT_FALSE;
159 }
160
161 if (itemA->type == REDUCT_ITEM_TYPE_LIST)
162 {
163 reduct_list_t* listA = &itemA->list;
164 reduct_list_t* listB = &itemB->list;
165
166 if (listA->length != listB->length)
167 {
168 return REDUCT_FALSE;
169 }
170
173 reduct_handle_t itemA, itemB;
174
175 while (reduct_list_iter_next(&iterA, &itemA) && reduct_list_iter_next(&iterB, &itemB))
176 {
177 if (!reduct_handle_is_equal(reduct, &itemA, &itemB))
178 {
179 return REDUCT_FALSE;
180 }
181 }
182
183 return REDUCT_TRUE;
184 }
185
186 return REDUCT_FALSE;
187}
188
199
201{
202 REDUCT_ASSERT(handle != REDUCT_NULL);
204
205 if (REDUCT_HANDLE_IS_INT(handle))
206 {
207 out->group = 0;
208 out->isFloat = REDUCT_FALSE;
209 out->num.i = REDUCT_HANDLE_TO_INT(handle);
210 out->item = REDUCT_NULL;
211 return;
212 }
213
214 if (REDUCT_HANDLE_IS_FLOAT(handle))
215 {
216 out->group = 0;
217 out->isFloat = REDUCT_TRUE;
218 out->num.f = REDUCT_HANDLE_TO_FLOAT(handle);
219 out->item = REDUCT_NULL;
220 return;
221 }
222
223 out->item = REDUCT_HANDLE_TO_ITEM(handle);
224 if (out->item != REDUCT_NULL && out->item->type == REDUCT_ITEM_TYPE_LIST)
225 {
226 out->group = 2;
227 return;
228 }
229
231 {
232 out->group = 0;
233 out->isFloat = REDUCT_TRUE;
234 out->num.f = out->item->atom.floatValue;
235 return;
236 }
237
239 {
240 out->group = 0;
241 out->isFloat = REDUCT_FALSE;
242 out->num.i = out->item->atom.integerValue;
243 return;
244 }
245
246 out->group = 1;
247}
248
250{
251 REDUCT_ASSERT(reduct != REDUCT_NULL);
254
255 if (a == b || *a == *b)
256 {
257 return 0;
258 }
259
260 reduct_cmp_val_t va, vb;
261 reduct_handle_unpack(a, &va);
262 reduct_handle_unpack(b, &vb);
263
264 if (va.group != vb.group)
265 {
266 return va.group - vb.group;
267 }
268
269 if (va.group == 0)
270 {
271 if (!va.isFloat && !vb.isFloat)
272 {
273 return (va.num.i < vb.num.i) ? -1 : ((va.num.i > vb.num.i) ? 1 : 0);
274 }
275 else if (va.isFloat && vb.isFloat)
276 {
277 return (va.num.f < vb.num.f) ? -1 : ((va.num.f > vb.num.f) ? 1 : 0);
278 }
279
280 reduct_float_t fa = va.isFloat ? va.num.f : (reduct_float_t)va.num.i;
281 reduct_float_t fb = vb.isFloat ? vb.num.f : (reduct_float_t)vb.num.i;
282 if (fa < fb)
283 {
284 return -1;
285 }
286 if (fa > fb)
287 {
288 return 1;
289 }
290 return va.isFloat ? 1 : -1;
291 }
292 else if (va.group == 1)
293 {
294 reduct_atom_t* atomA = va.item ? &va.item->atom : REDUCT_NULL;
295 reduct_atom_t* atomB = vb.item ? &vb.item->atom : REDUCT_NULL;
296 reduct_size_t lenA = atomA ? atomA->length : 0;
297 reduct_size_t lenB = atomB ? atomB->length : 0;
298 reduct_size_t minLen = lenA < lenB ? lenA : lenB;
299
300 if (minLen > 0)
301 {
302 int cmp = memcmp(atomA->string, atomB->string, minLen);
303 if (cmp != 0)
304 {
305 return cmp;
306 }
307 }
308
309 return (reduct_int64_t)lenA - (reduct_int64_t)lenB;
310 }
311
312 reduct_list_t* listA = va.item ? &va.item->list : REDUCT_NULL;
313 reduct_list_t* listB = vb.item ? &vb.item->list : REDUCT_NULL;
314 reduct_size_t lenA = listA ? listA->length : 0;
315 reduct_size_t lenB = listB ? listB->length : 0;
316 reduct_size_t minLen = lenA < lenB ? lenA : lenB;
317
320 reduct_handle_t itemA, itemB;
321 while (iterA.index < minLen && reduct_list_iter_next(&iterA, &itemA) && reduct_list_iter_next(&iterB, &itemB))
322 {
323 reduct_int64_t cmp = reduct_handle_compare(reduct, &itemA, &itemB);
324 if (cmp != 0)
325 {
326 return cmp;
327 }
328 }
329
330 return (reduct_int64_t)lenA - (reduct_int64_t)lenB;
331}
332
339
346
353
354#endif
Character handling.
Core definitions and structures.
size_t reduct_size_t
Definition defs.h:100
reduct_bool_t
Boolean type.
Definition defs.h:135
@ REDUCT_FALSE
Definition defs.h:137
@ REDUCT_TRUE
Definition defs.h:136
#define REDUCT_CONTAINER_OF(_ptr, _type, _member)
Container of macro.
Definition defs.h:184
int64_t reduct_int64_t
Definition defs.h:92
reduct_uint64_t reduct_handle_t
Handle type.
Definition defs.h:189
double reduct_float_t
Definition defs.h:102
#define REDUCT_ASSERT(_cond)
Definition defs.h:25
#define REDUCT_API
Definition defs.h:7
#define REDUCT_NULL
Definition defs.h:23
Virtual machine evaluation.
Garbage collection.
REDUCT_API reduct_atom_t * reduct_atom_lookup_int(struct reduct *reduct, reduct_int64_t value)
Lookup an atom by integer value.
REDUCT_API reduct_atom_t * reduct_atom_lookup_float(struct reduct *reduct, reduct_float_t value)
Lookup an atom by float value.
#define REDUCT_ERROR_RUNTIME(_reduct,...)
Throw a runtime error using the jump buffer in the error structure.
Definition error.h:175
#define REDUCT_HANDLE_IS_ITEM(_handle)
Check if a handle is an item.
Definition handle.h:171
#define REDUCT_HANDLE_IS_INT(_handle)
Check if a handle is an integer.
Definition handle.h:118
#define REDUCT_HANDLE_GET_FLAGS(_handle)
Get flags from an item handle.
Definition handle.h:265
#define REDUCT_HANDLE_IS_NUMBER_SHAPED(_handle)
Check if a handle is a number or references a number shaped item.
Definition handle.h:162
#define REDUCT_HANDLE_TO_INT(_handle)
Get the integer value of a handle.
Definition handle.h:236
#define REDUCT_HANDLE_TO_ITEM(_handle)
Get the item pointer of a handle.
Definition handle.h:257
REDUCT_API void reduct_handle_promote(struct reduct *reduct, reduct_handle_t *a, reduct_handle_t *b, reduct_promotion_t *out)
Promote two handles to a common numeric type.
Definition handle_impl.h:54
#define REDUCT_HANDLE_TO_FLOAT(_handle)
Get the float value of a handle.
Definition handle.h:244
#define REDUCT_HANDLE_FROM_ATOM(_atom)
Create a handle from an atom pointer.
Definition handle.h:85
#define REDUCT_HANDLE_FROM_ITEM(_ptr)
Create a handle from an item pointer.
Definition handle.h:76
#define REDUCT_HANDLE_IS_FLOAT(_handle)
Check if a handle is a float.
Definition handle.h:126
@ REDUCT_PROMOTION_TYPE_INT
Definition handle.h:374
@ REDUCT_PROMOTION_TYPE_FLOAT
Definition handle.h:375
#define REDUCT_ITEM_TYPE_LIST
A list.
Definition item.h:28
REDUCT_API const char * reduct_item_type_str(reduct_item_type_t type)
Get the string representation of an Reduct item type.
Definition item_impl.h:139
#define REDUCT_ITEM_TYPE_ATOM
An atom.
Definition item.h:27
#define REDUCT_ITEM_FLAG_INT_SHAPED
Item is an integer shaped atom.
Definition item.h:39
#define REDUCT_ITEM_FLAG_FLOAT_SHAPED
Item is a float shaped atom.
Definition item.h:40
Handle management.
REDUCT_API reduct_handle_t reduct_handle_pi(reduct_t *reduct)
REDUCT_API reduct_handle_t reduct_handle_e(reduct_t *reduct)
REDUCT_API void reduct_handle_get_string_params(reduct_t *reduct, reduct_handle_t *handle, char **outStr, reduct_size_t *outLen)
Definition handle_impl.h:13
static void reduct_handle_unpack(reduct_handle_t *handle, reduct_cmp_val_t *out)
REDUCT_API reduct_bool_t reduct_handle_is_equal(reduct_t *reduct, reduct_handle_t *a, reduct_handle_t *b)
REDUCT_API reduct_int64_t reduct_handle_compare(reduct_t *reduct, reduct_handle_t *a, reduct_handle_t *b)
REDUCT_API reduct_handle_t reduct_handle_nil(reduct_t *reduct)
REDUCT_API reduct_item_t * reduct_handle_item(reduct_t *reduct, reduct_handle_t *handle)
Definition handle_impl.h:47
REDUCT_API void reduct_handle_ensure_item(reduct_t *reduct, reduct_handle_t *handle)
Definition handle_impl.h:26
Item management.
#define REDUCT_LIST_ITER(_list)
Create a initializer for a list iterator.
Definition list.h:156
REDUCT_API reduct_bool_t reduct_list_iter_next(reduct_list_iter_t *iter, reduct_handle_t *out)
Get the next element from the iterator.
Definition list_impl.h:255
Stringification.
Atom structure.
Definition atom.h:48
reduct_int64_t integerValue
Pre-computed integer value, item must have REDUCT_ITEM_FLAG_INT_SHAPED.
Definition atom.h:55
reduct_uint32_t length
The length of the string (must be first, check the reduct_item_t structure).
Definition atom.h:49
char * string
Pointer to the string.
Definition atom.h:53
reduct_float_t floatValue
Pre-computed float value, item must have REDUCT_ITEM_FLAG_FLOAT_SHAPED.
Definition atom.h:56
reduct_bool_t isFloat
reduct_float_t f
reduct_int64_t i
union reduct_cmp_val_t::@6 num
reduct_item_t * item
Item structure.
Definition item.h:57
reduct_list_t list
A list.
Definition item.h:67
reduct_uint32_t length
Common length for the item. (Stored in the union to save space due to padding rules....
Definition item.h:65
reduct_item_flags_t flags
Flags for the item.
Definition item.h:60
reduct_atom_t atom
An atom.
Definition item.h:66
reduct_item_type_t type
The type of the item.
Definition item.h:61
List iterator structure.
Definition list.h:139
reduct_size_t index
Definition list.h:141
List structure.
Definition list.h:48
reduct_uint32_t length
Total number of elements.
Definition list.h:49
Promotion result for numeric operations.
Definition handle.h:383
reduct_int64_t intVal
Definition handle.h:386
reduct_float_t floatVal
Definition handle.h:387
union reduct_promotion_t::@7 a
union reduct_promotion_t::@8 b
reduct_promotion_type_t type
Definition handle.h:384
State structure.
Definition core.h:61
reduct_item_t * piItem
Definition core.h:73
reduct_item_t * nilItem
Definition core.h:72
reduct_item_t * eItem
Definition core.h:74