Reduct  v1.0.4-3-gdaf0d70
A functional and immutable language.
Loading...
Searching...
No Matches
compile_impl.h
Go to the documentation of this file.
1#include "inst.h"
2#ifndef REDUCT_COMPILE_IMPL_H
3#define REDUCT_COMPILE_IMPL_H 1
4
5#include "compile.h"
6#include "core.h"
7#include "gc.h"
8#include "intrinsic.h"
9#include "item.h"
10#include "item_impl.h"
11#include "list.h"
12
14{
15 REDUCT_ASSERT(reduct != REDUCT_NULL);
17
19 reduct_item_t* funcItem = REDUCT_CONTAINER_OF(func, reduct_item_t, function);
20 REDUCT_GC_RETAIN_ITEM(reduct, funcItem);
21
22 reduct_compiler_t compiler;
23 reduct_compiler_init(&compiler, reduct, func, REDUCT_NULL);
24
26 compiler.lastItem = astItem;
27 funcItem->input = astItem->input;
28
30 reduct_intrinsic_block_generic(&compiler, astItem, 0, &lastExpr);
31
32 reduct_compile_return(&compiler, &lastExpr);
33 reduct_expr_done(&compiler, &lastExpr);
34
35 reduct_compiler_deinit(&compiler);
36
37 return func;
38}
39
41 reduct_compiler_t* enclosing)
42{
43 REDUCT_ASSERT(compiler != REDUCT_NULL);
44 REDUCT_ASSERT(reduct != REDUCT_NULL);
45 REDUCT_ASSERT(function != REDUCT_NULL);
46
47 compiler->enclosing = enclosing;
48 compiler->reduct = reduct;
49 compiler->function = function;
50 compiler->localCount = 0;
51 compiler->lastItem = REDUCT_NULL;
52
53 REDUCT_MEMSET(compiler->regAlloc, 0, sizeof(compiler->regAlloc));
54 REDUCT_MEMSET(compiler->regLocal, 0, sizeof(compiler->regLocal));
55 REDUCT_MEMSET(compiler->locals, 0, sizeof(compiler->locals));
56}
57
59{
60 REDUCT_ASSERT(compiler != REDUCT_NULL);
61 (void)compiler;
62}
63
65{
66 REDUCT_ASSERT(compiler != REDUCT_NULL);
67
68 for (reduct_uint32_t w = 0; w < REDUCT_REGISTER_MAX / 64; w++)
69 {
70 if (compiler->regAlloc[w] != ~(reduct_uint64_t)0)
71 {
72 for (reduct_uint32_t b = 0; b < 64; b++)
73 {
74 if (!(compiler->regAlloc[w] & (1ULL << b)))
75 {
76 reduct_reg_t reg = (reduct_reg_t)(w * 64 + b);
77 REDUCT_REG_SET_ALLOCATED(compiler, reg);
78 return reg;
79 }
80 }
81 }
82 }
83
84 REDUCT_ERROR_COMPILE(compiler, compiler->lastItem, "too many registers in function");
85 return REDUCT_REG_INVALID;
86}
87
89{
90 REDUCT_ASSERT(compiler != REDUCT_NULL);
91
92 if (count == 0)
93 {
94 return 0;
95 }
96
97 for (reduct_uint32_t i = 0; i <= REDUCT_REGISTER_MAX - count; i++)
98 {
99 reduct_uint32_t length;
100 for (length = 0; length < count; length++)
101 {
102 reduct_uint32_t reg = i + length;
103 if (REDUCT_REG_IS_ALLOCATED(compiler, reg))
104 {
105 break;
106 }
107 }
108 if (length == count)
109 {
110 for (reduct_uint32_t j = 0; j < count; j++)
111 {
112 reduct_uint32_t reg = i + j;
113 REDUCT_REG_SET_ALLOCATED(compiler, reg);
114 }
115 return i;
116 }
117 i += length;
118 }
119
120 REDUCT_ERROR_COMPILE(compiler, compiler->lastItem, "too many registers in function");
121 return REDUCT_REG_INVALID;
122}
123
125{
126 REDUCT_ASSERT(compiler != REDUCT_NULL);
127 if (reg >= REDUCT_REGISTER_MAX)
128 {
129 return;
130 }
131
132 if (REDUCT_REG_IS_LOCAL(compiler, reg))
133 {
134 return;
135 }
136
137 REDUCT_REG_CLEAR_ALLOCATED(compiler, reg);
138}
139
141{
142 REDUCT_ASSERT(compiler != REDUCT_NULL);
143
144 for (reduct_uint32_t i = 0; i < count; i++)
145 {
146 reduct_reg_free(compiler, start + i);
147 }
148}
149
150static inline void reduct_expr_build_atom(reduct_compiler_t* compiler, reduct_item_t* atom, reduct_expr_t* out)
151{
152 REDUCT_ASSERT(compiler != REDUCT_NULL);
153 REDUCT_ASSERT(atom != REDUCT_NULL);
155
156 if (atom->flags &
159 {
160 *out = REDUCT_EXPR_CONST_ITEM(compiler, atom);
161 return;
162 }
163
164 reduct_local_t* local = reduct_local_lookup(compiler, &atom->atom);
165 if (local != REDUCT_NULL)
166 {
167 if (!REDUCT_LOCAL_IS_DEFINED(local))
168 {
169 REDUCT_ERROR_COMPILE(compiler, atom, "undefined variable '%.*s'", atom->atom.length, atom->atom.string);
170 }
171
172 *out = local->expr;
173 return;
174 }
175
176 for (reduct_uint32_t i = 0; i < compiler->reduct->constantCount; i++)
177 {
178 if (&atom->atom == compiler->reduct->constants[i].name)
179 {
180 *out = REDUCT_EXPR_CONST_ITEM(compiler, compiler->reduct->constants[i].item);
181 return;
182 }
183 }
184
185 REDUCT_ERROR_COMPILE(compiler, atom, "undefined variable '%.*s'", atom->atom.length, atom->atom.string);
186}
187
188static inline void reduct_expr_build_list(reduct_compiler_t* compiler, reduct_item_t* list, reduct_expr_t* out)
189{
190 REDUCT_ASSERT(compiler != REDUCT_NULL);
191 REDUCT_ASSERT(list != REDUCT_NULL);
193
194 if (list->flags & REDUCT_ITEM_FLAG_QUOTED)
195 {
196 *out = REDUCT_EXPR_CONST_ITEM(compiler, list);
197 return;
198 }
199
200 if (list->length == 0)
201 {
202 *out = REDUCT_EXPR_NIL(compiler);
203 return;
204 }
205
206 reduct_item_t* head = reduct_list_nth_item(compiler->reduct, &list->list, 0);
207 if ((head->flags & REDUCT_ITEM_FLAG_QUOTED) ||
208 (head->type == REDUCT_ITEM_TYPE_ATOM &&
211 {
212 reduct_reg_t target = reduct_expr_get_reg(compiler, out);
213 reduct_compile_list(compiler, target);
214
216 REDUCT_LIST_FOR_EACH(&h, &list->list)
217 {
220 reduct_expr_build(compiler, item, &argExpr);
221
223 reduct_compile_append(compiler, target, &argExpr);
224
225 reduct_expr_done(compiler, &argExpr);
226 }
227
228 *out = REDUCT_EXPR_REG(target);
229 return;
230 }
231
233 {
235 if (handler != REDUCT_NULL)
236 {
237 handler(compiler, list, out);
238 return;
239 }
240 }
241
242 reduct_uint32_t arity = (reduct_uint32_t)list->length - 1;
243 reduct_uint32_t regCount = arity == 0 ? 1 : arity;
244
245 reduct_reg_t base = reduct_reg_get_base(compiler);
246
247 if (base + regCount > REDUCT_REGISTER_MAX)
248 {
249 REDUCT_ERROR_COMPILE(compiler, list, "too many registers in function");
250 }
251
252 for (reduct_uint32_t i = 0; i < regCount; i++)
253 {
254 REDUCT_REG_SET_ALLOCATED(compiler, base + i);
255 }
256
257 reduct_expr_t callable = REDUCT_EXPR_NONE();
258 reduct_expr_build(compiler, head, &callable);
259
260 reduct_handle_t argH;
261 REDUCT_LIST_FOR_EACH_AT(&argH, &list->list, 1)
262 {
263 reduct_reg_t target = (reduct_reg_t)(base + _iter.index - 2);
264 reduct_expr_t argExpr = REDUCT_EXPR_TARGET(target);
265 reduct_expr_build(compiler, REDUCT_HANDLE_TO_ITEM(&argH), &argExpr);
266
267 if (argExpr.mode != REDUCT_MODE_REG || argExpr.reg != target)
268 {
269 reduct_compile_move(compiler, target, &argExpr);
270 reduct_expr_done(compiler, &argExpr);
271 }
272 }
273
274 reduct_compile_call(compiler, base, &callable, arity);
275
276 reduct_expr_done(compiler, &callable);
277
278 if (regCount > 1)
279 {
280 reduct_reg_free_range(compiler, base + 1, regCount - 1);
281 }
282
283 *out = REDUCT_EXPR_REG(base);
284}
285
287{
288 REDUCT_ASSERT(compiler != REDUCT_NULL);
289 REDUCT_ASSERT(item != REDUCT_NULL);
291
292 reduct_item_t* previousItem = compiler->lastItem;
293 if (item != REDUCT_NULL && item->input != REDUCT_NULL)
294 {
295 compiler->lastItem = item;
296 }
297
298 if (item->type == REDUCT_ITEM_TYPE_ATOM)
299 {
300 reduct_expr_build_atom(compiler, item, out);
301 }
302 else
303 {
304 reduct_expr_build_list(compiler, item, out);
305 }
306
307 compiler->lastItem = previousItem;
308}
309
311{
312 REDUCT_ASSERT(compiler != REDUCT_NULL);
313 REDUCT_ASSERT(name != REDUCT_NULL);
314
315 if (compiler->localCount >= REDUCT_REGISTER_MAX)
316 {
317 REDUCT_ERROR_COMPILE(compiler, compiler->lastItem, "too many local variables");
318 }
319
320 compiler->locals[compiler->localCount].name = name;
321 compiler->locals[compiler->localCount].expr = REDUCT_EXPR_NONE();
322 return &compiler->locals[compiler->localCount++];
323}
324
326{
327 REDUCT_ASSERT(compiler != REDUCT_NULL);
328 REDUCT_ASSERT(local != REDUCT_NULL);
329 REDUCT_ASSERT(expr != REDUCT_NULL);
330
331 if (local->expr.mode != REDUCT_MODE_NONE)
332 {
333 return;
334 }
335
336 if (expr->mode == REDUCT_MODE_REG)
337 {
338 REDUCT_REG_SET_LOCAL(compiler, expr->reg);
339 }
340
341 local->expr = *expr;
342}
343
345{
346 REDUCT_ASSERT(compiler != REDUCT_NULL);
347 REDUCT_ASSERT(name != REDUCT_NULL);
348
349 if (compiler->localCount >= REDUCT_REGISTER_MAX)
350 {
351 REDUCT_ERROR_COMPILE(compiler, compiler->lastItem, "too many local variables");
352 }
353
354 reduct_reg_t reg = reduct_reg_alloc(compiler);
355 compiler->locals[compiler->localCount].name = name;
356 compiler->locals[compiler->localCount].expr = REDUCT_EXPR_REG(reg);
357 REDUCT_REG_SET_LOCAL(compiler, reg);
358
359 return &compiler->locals[compiler->localCount++];
360}
361
363{
364 REDUCT_ASSERT(compiler != REDUCT_NULL);
365 reduct_reg_t resultReg =
366 (result != REDUCT_NULL && result->mode == REDUCT_MODE_REG) ? result->reg : REDUCT_REG_INVALID;
367
368 for (reduct_uint32_t i = compiler->localCount; i > (reduct_uint32_t)toCount; i--)
369 {
370 reduct_local_t* local = &compiler->locals[i - 1];
371 if (local->expr.mode == REDUCT_MODE_REG)
372 {
373 reduct_bool_t isResult = (local->expr.reg == resultReg);
374 reduct_bool_t isOuterLocal = REDUCT_FALSE;
375 for (reduct_uint32_t j = 0; j < (reduct_uint32_t)toCount; j++)
376 {
377 if (compiler->locals[j].expr.mode == REDUCT_MODE_REG && compiler->locals[j].expr.reg == local->expr.reg)
378 {
379 isOuterLocal = REDUCT_TRUE;
380 break;
381 }
382 }
383
384 if (!isOuterLocal)
385 {
386 REDUCT_REG_CLEAR_LOCAL(compiler, local->expr.reg);
387 if (!isResult)
388 {
389 REDUCT_REG_CLEAR_ALLOCATED(compiler, local->expr.reg);
390 }
391 }
392 }
393 local->name = REDUCT_NULL;
394 local->expr = REDUCT_EXPR_NONE();
395 }
396 compiler->localCount = toCount;
397}
398
400{
401 REDUCT_ASSERT(compiler != REDUCT_NULL);
402 REDUCT_ASSERT(name != REDUCT_NULL);
403
404 for (reduct_int16_t i = compiler->localCount - 1; i >= 0; i--)
405 {
406 if (compiler->locals[i].name == name)
407 {
408 return &compiler->locals[i];
409 }
410 }
411
412 reduct_compiler_t* current = compiler->enclosing;
413 while (current != REDUCT_NULL)
414 {
415 for (reduct_int16_t i = current->localCount - 1; i >= 0; i--)
416 {
417 if (current->locals[i].name != name)
418 {
419 continue;
420 }
421
422 if (current->locals[i].expr.mode == REDUCT_MODE_CONST)
423 {
424 reduct_const_t constant = reduct_function_lookup_constant(compiler->reduct, compiler->function,
425 &current->function->constants[current->locals[i].expr.constant]);
426 reduct_expr_t constExpr = REDUCT_EXPR_CONST(constant);
427
428 reduct_local_t* local = reduct_local_def(compiler, name);
429 reduct_local_def_done(compiler, local, &constExpr);
430 return local;
431 }
432
434 reduct_const_t constant = reduct_function_lookup_constant(compiler->reduct, compiler->function, &slot);
435 reduct_expr_t constExpr = REDUCT_EXPR_CONST(constant);
436
437 reduct_local_t* local = reduct_local_def(compiler, name);
438 reduct_local_def_done(compiler, local, &constExpr);
439 return local;
440 }
441 current = current->enclosing;
442 }
443
444 return REDUCT_NULL;
445}
446
447#endif
Bytecode compilation.
static void reduct_expr_build_list(reduct_compiler_t *compiler, reduct_item_t *list, reduct_expr_t *out)
static void reduct_expr_build_atom(reduct_compiler_t *compiler, reduct_item_t *atom, reduct_expr_t *out)
Core definitions and structures.
int16_t reduct_int16_t
Definition defs.h:96
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
reduct_uint64_t reduct_handle_t
Handle type.
Definition defs.h:189
uint32_t reduct_uint32_t
Definition defs.h:95
#define REDUCT_ASSERT(_cond)
Definition defs.h:25
#define REDUCT_MEMSET(_ptr, _val, _size)
Definition defs.h:32
#define REDUCT_API
Definition defs.h:7
uint16_t reduct_uint16_t
Definition defs.h:97
uint64_t reduct_uint64_t
Definition defs.h:93
#define REDUCT_NULL
Definition defs.h:23
Garbage collection.
reduct_const_t constant
Constant index.
Definition compile.h:33
#define REDUCT_EXPR_CONST_ITEM(_compiler, _item)
Create a REDUCT_MODE_CONST mode expression for a specific item.
Definition compile.h:207
REDUCT_API reduct_local_t * reduct_local_add_arg(reduct_compiler_t *compiler, reduct_atom_t *name)
Add a function argument local to the compiler context.
REDUCT_API void reduct_reg_free(reduct_compiler_t *compiler, reduct_reg_t reg)
Free a register.
reduct_mode_t mode
Expression mode.
Definition compile.h:29
#define REDUCT_EXPR_NIL(_compiler)
Create a REDUCT_MODE_CONST mode expression for the nil constant.
Definition compile.h:252
#define REDUCT_REG_SET_ALLOCATED(_compiler, _reg)
Set a register as allocated.
Definition compile.h:98
static void reduct_expr_done(reduct_compiler_t *compiler, reduct_expr_t *expr)
Free resources associated with an expression descriptor.
Definition compile.h:295
REDUCT_API void reduct_expr_build(reduct_compiler_t *compiler, reduct_item_t *item, reduct_expr_t *out)
Compiles a single Reduct item into an expression descriptor.
#define REDUCT_EXPR_CONST(_const)
Create a REDUCT_MODE_CONST mode expression.
Definition compile.h:199
reduct_uint16_t localCount
The amount of local variables.
Definition compile.h:56
REDUCT_API reduct_function_t * reduct_compile(reduct_t *reduct, reduct_handle_t *ast)
Compiles a Reduct AST into a callable bytecode function.
REDUCT_API reduct_local_t * reduct_local_def(reduct_compiler_t *compiler, reduct_atom_t *name)
Define a new local variable.
REDUCT_API void reduct_local_def_done(reduct_compiler_t *compiler, reduct_local_t *local, reduct_expr_t *expr)
Finalize a local variable definition with its value expression.
static reduct_reg_t reduct_reg_get_base(reduct_compiler_t *compiler)
Get the first unallocated register index.
Definition compile.h:328
#define REDUCT_REG_CLEAR_ALLOCATED(_compiler, _reg)
Clear a register's allocation status.
Definition compile.h:114
reduct_local_t locals[REDUCT_REGISTER_MAX]
The local variables.
Definition compile.h:59
struct reduct_compiler * enclosing
The enclosing compiler context, or REDUCT_NULL.
Definition compile.h:53
static void reduct_compile_return(reduct_compiler_t *compiler, reduct_expr_t *expr)
Emits a REDUCT_OPCODE_RET instruction.
Definition compile.h:533
reduct_uint64_t regAlloc[REDUCT_REGISTER_MAX/64]
Bitmask of allocated registers.
Definition compile.h:57
REDUCT_API void reduct_reg_free_range(reduct_compiler_t *compiler, reduct_reg_t start, reduct_uint32_t count)
Free a range of registers.
reduct_expr_t expr
The expression representing the local's value.
Definition compile.h:44
reduct_reg_t reg
Register index.
Definition compile.h:32
#define REDUCT_REG_CLEAR_LOCAL(_compiler, _reg)
Clear a register's local status.
Definition compile.h:138
reduct_atom_t * name
The name of the local variable.
Definition compile.h:43
reduct_t * reduct
The Reduct structure.
Definition compile.h:54
#define REDUCT_EXPR_TARGET(_reg)
Create a REDUCT_MODE_TARGET mode expression.
Definition compile.h:227
#define REDUCT_REG_IS_LOCAL(_compiler, _reg)
Check if a register is a local.
Definition compile.h:146
static void reduct_compile_call(reduct_compiler_t *compiler, reduct_reg_t target, reduct_expr_t *callable, reduct_uint32_t arity)
Emits a REDUCT_OPCODE_CALL instruction, that returns its result in the target register.
Definition compile.h:429
REDUCT_API void reduct_local_pop(reduct_compiler_t *compiler, reduct_uint16_t toCount, reduct_expr_t *result)
Pop local variables from the stack, releasing their registers if they are no longer used.
static void reduct_compile_list(reduct_compiler_t *compiler, reduct_reg_t target)
Emits a REDUCT_OPCODE_LIST instruction, that creates a list in the target register.
Definition compile.h:415
#define REDUCT_EXPR_NONE()
Create a REDUCT_MODE_NONE mode expression.
Definition compile.h:185
reduct_function_t * function
The function being compiled.
Definition compile.h:55
REDUCT_API void reduct_compiler_init(reduct_compiler_t *compiler, reduct_t *reduct, reduct_function_t *function, reduct_compiler_t *enclosing)
Initialize a compiler context.
REDUCT_API reduct_reg_t reduct_reg_alloc(reduct_compiler_t *compiler)
Allocate a new register.
REDUCT_API void reduct_compiler_deinit(reduct_compiler_t *compiler)
Deinitialize a compiler context.
static void reduct_compile_move(reduct_compiler_t *compiler, reduct_reg_t target, reduct_expr_t *expr)
Emits a REDUCT_OPCODE_MOVE instruction, that moves the value of the source expression to the target r...
Definition compile.h:447
#define REDUCT_LOCAL_IS_DEFINED(_local)
Check if a local variable has finished being defined.
Definition compile.h:347
reduct_item_t * lastItem
The last item processed by the compiler, used for error reporting.
Definition compile.h:60
#define REDUCT_REG_SET_LOCAL(_compiler, _reg)
Set a register as a local.
Definition compile.h:130
static void reduct_compile_append(reduct_compiler_t *compiler, reduct_reg_t target, reduct_expr_t *expr)
Emits an REDUCT_OPCODE_APPEND instruction.
Definition compile.h:623
#define REDUCT_REG_IS_ALLOCATED(_compiler, _reg)
Check if a register is allocated.
Definition compile.h:122
static reduct_reg_t reduct_expr_get_reg(reduct_compiler_t *compiler, reduct_expr_t *out)
Allocate a new register, favoring the output expression's target if provided.
Definition compile.h:312
reduct_uint64_t regLocal[REDUCT_REGISTER_MAX/64]
Bitmask of registers used by locals.
Definition compile.h:58
REDUCT_API reduct_reg_t reduct_reg_alloc_range(reduct_compiler_t *compiler, reduct_uint32_t count)
Allocate a range of registers.
#define REDUCT_EXPR_REG(_reg)
Create a REDUCT_MODE_REG mode expression.
Definition compile.h:192
REDUCT_API reduct_local_t * reduct_local_lookup(reduct_compiler_t *compiler, reduct_atom_t *name)
Look up a local by name and return its expression.
#define REDUCT_ERROR_COMPILE(_compiler, _item,...)
Throw a compile error using the jump buffer in the error structure.
Definition error.h:162
#define REDUCT_CONST_SLOT_CAPTURE(_capture)
Create a constant slot containing a variable name to be captured.
Definition function.h:64
reduct_uint16_t reduct_const_t
Constant index type.
Definition function.h:71
REDUCT_API reduct_function_t * reduct_function_new(struct reduct *reduct)
Create a new function.
REDUCT_API reduct_const_t reduct_function_lookup_constant(struct reduct *reduct, reduct_function_t *func, reduct_const_slot_t *slot)
Get the index of a constant in a function's constant template, adding it if it doesn't exist.
#define REDUCT_GC_RETAIN_ITEM(_reduct, _item)
Retain a item, preventing it from being collected by the GC.
Definition gc.h:56
#define REDUCT_HANDLE_TO_ITEM(_handle)
Get the item pointer of a handle.
Definition handle.h:257
#define REDUCT_REG_INVALID
Invalid register value.
Definition inst.h:92
reduct_uint16_t reduct_reg_t
Register type.
Definition inst.h:87
#define REDUCT_REGISTER_MAX
The max number of registers per function frame.
Definition inst.h:108
@ REDUCT_MODE_REG
Register operand mode.
Definition inst.h:40
@ REDUCT_MODE_NONE
Invalid mode.
Definition inst.h:38
@ REDUCT_MODE_CONST
Constant operand mode.
Definition inst.h:41
reduct_intrinsic_handler_t reductIntrinsicHandlers[REDUCT_INTRINSIC_MAX]
Intrinsic handler functions array.
void reduct_intrinsic_block_generic(struct reduct_compiler *compiler, struct reduct_item *list, reduct_uint32_t startIdx, struct reduct_expr *out)
Compiles a block of expressions (like a do block).
void(* reduct_intrinsic_handler_t)(struct reduct_compiler *compiler, struct reduct_item *expr, struct reduct_expr *out)
Intrinsic handler function type.
Definition intrinsic.h:70
#define REDUCT_ITEM_TYPE_LIST
A list.
Definition item.h:28
#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
#define REDUCT_ITEM_FLAG_NATIVE
Item is an atom and a native function.
Definition item.h:42
#define REDUCT_ITEM_FLAG_INTRINSIC
Item is an atom and a intrinsic.
Definition item.h:41
#define REDUCT_ITEM_FLAG_QUOTED
Item is a quoted atom.
Definition item.h:43
Bytecode instruction format.
Intrinsic management.
Item management.
List management.
#define REDUCT_LIST_FOR_EACH_AT(_handle, _list, _start)
Macro for iterating over elements in a list starting from a specific index.
Definition list.h:191
#define REDUCT_LIST_FOR_EACH(_handle, _list)
Macro for iterating over all elements in a list.
Definition list.h:181
REDUCT_API struct reduct_item * reduct_list_nth_item(struct reduct *reduct, reduct_list_t *list, reduct_size_t index)
Get the nth element of the list as an item.
Definition list_impl.h:172
Atom structure.
Definition atom.h:48
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_intrinsic_t intrinsic
Cached intrinsic, item must have REDUCT_ITEM_FLAG_INTRINSIC.
Definition atom.h:52
Compiler structure.
Definition compile.h:52
Constant slot.
Definition function.h:43
struct reduct_atom * name
Definition core.h:52
struct reduct_item * item
Definition core.h:53
Expression descriptor structure.
Definition compile.h:28
Compiled function structure.
Definition function.h:78
reduct_const_slot_t * constants
The array of constant slots forming the constant template.
Definition function.h:83
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
struct reduct_input * input
The parsed input that created this item.
Definition item.h:58
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
Local structure.
Definition compile.h:42
State structure.
Definition core.h:61
reduct_constant_t constants[REDUCT_CONSTANTS_MAX]
Definition core.h:76
reduct_uint32_t constantCount
Definition core.h:77