x-engine-c v0.2.31
The C engine for x-lang
Loading...
Searching...
No Matches
x-prim.h
Go to the documentation of this file.
1#ifndef X_PRIM_H
2#define X_PRIM_H
3
18/*
19 * ., .,
20 * {O,O}
21 * ( )
22 * " "
23 */
24
25#include "x-obj.h"
26#include "x-heap.h"
27#include "x-eval.h" /* the x_eargs helper below evaluates args through the eval slot */
28#include <stdarg.h>
29
30
56static void __attribute__((unused)) x_args(x_obj_t *p_base, x_obj_t *p_args,
57 int count, ...)
58{
59 va_list ap;
60 int i;
61
63 for (i = 0; i < count; i++) {
64 x_obj_t **slot = va_arg(ap, x_obj_t **);
65 if (p_args == NULL) { if (slot) *slot = NULL; continue; }
67 if (slot != NULL)
68 *slot = x_firstobj(p_args);
70 }
71 va_end(ap);
72}
73
87static void __attribute__((unused)) x_eargs(x_obj_t *p_base, x_obj_t *p_args, int count, ...)
88{
89 va_list ap;
90 int i;
91 int held = 0;
92 x_obj_t **p_cell = x_heap_root_slot(p_base);
93 /* Earlier results may be fresh objects whose only other homes are the
94 * caller's out-slots -- bare C stack the collector does not scan under
95 * precise rooting -- so each result is parked in a registered slot
96 * while the later arguments evaluate. Two pair cells give four slots:
97 * enough for the deepest x_eargs caller (count 5 = four results, of
98 * which the last needs no protection here). */
101 { NULL }, { NULL }),
103 { NULL }, { NULL })
104 };
105
108
109 va_start(ap, count);
110 for (i = 0; i < count; i++) {
111 x_obj_t **slot = va_arg(ap, x_obj_t **);
112 if (p_args == NULL) { if (slot) *slot = NULL; continue; }
113 /* A proper list ends at nil, handled above; an IMPROPER one ends
114 * at an ATOM, which the walk below would have read as a pair
115 * (#487). Raising here is safe with the roots pushed: the
116 * handler restores the root chain to its snapshot on the error
117 * path, exactly as it does for the C frames a longjmp cuts. */
118 x_eval_spine_guard(p_base, p_args);
119 if (slot != NULL) {
120 *slot = x_eval_call(p_base, X_SLOT_EVAL, x_argrun({ .p = x_firstobj(p_args) }));
121 if (held < 4) {
122 x_obj_data_i((x_obj_t *)roots[held >> 1], held & 1).p = *slot;
123 held++;
124 }
125 }
127 }
128 va_end(ap);
129
132}
133
147static x_obj_t __attribute__((unused)) *x_args_tail(x_obj_t *p_base,
148 x_obj_t *p_args, int count)
149{
150 while (count-- > 0 && p_args != NULL) {
151 x_eval_spine_guard(p_base, p_args); /* dotted tail (#487) */
153 }
154 return p_args;
155}
156
/* end arg_helpers */
158
159
171
173void x_value_bind(x_obj_t *p_base, x_char_t *name, x_obj_t *p_val);
174
176void x_callable_bind(x_obj_t *p_base, x_char_t *name, x_fn_t fn);
177
179void x_callable_bind_table(x_obj_t *p_base, const x_callable_entry_t *table, int count);
180
198x_obj_t *x_prims(x_obj_t *p_base);
199
210
214void x_prims_bind_table(x_obj_t *p_base, const x_prim_entry_t *table, int count);
215
223
226
230
234
239
242
249
252
255
260
263x_obj_t *x_prim_type_build_struct(x_obj_t *p_base, x_obj_t *p_name_atom,
264 x_obj_t *p_handlers);
265
268
272 x_obj_t *(*op)(x_obj_t *, x_obj_t *));
273
276
279
283
286
287#ifdef X_SIGNAL
291#endif
292
294void x_callcc_init(void);
299
300#endif /* X_PRIM_H */
static void x_obj_t int int i
Definition x-prim.h:60
x_spair_t roots[2]
Definition x-prim.h:99
va_start(ap, count)
static void x_obj_t * p_args
Definition x-prim.h:56
x_obj_t ** p_cell
Definition x-prim.h:92
static void x_obj_t int count
Definition x-prim.h:57
int held
Definition x-prim.h:91
va_end(ap)
static void __attribute__((unused)) x_args(x_obj_t *p_base
x_heap_root_push(p_cell, roots[0])
x_heap_root_pop(p_cell)
void x_value_bind(x_obj_t *p_base, x_char_t *name, x_obj_t *p_val)
Definition x-prim.c:67
void x_callable_bind(x_obj_t *p_base, x_char_t *name, x_fn_t fn)
Definition x-prim.c:50
void x_callable_bind_table(x_obj_t *p_base, const x_callable_entry_t *table, int count)
Definition x-prim.c:96
void x_prims_bind_table(x_obj_t *p_base, const x_prim_entry_t *table, int count)
Definition x-prim.c:255
x_obj_t * x_prims(x_obj_t *p_base)
Definition x-prim.c:117
x_obj_t * x_prim_signal_register(x_obj_t *p_base, x_obj_t *p_args)
Definition signal.c:160
Definition x-prim.h:167
x_fn_t fn
Definition x-prim.h:169
x_char_t * name
Definition x-prim.h:168
Definition x-prim.h:204
x_char_t * method
Definition x-prim.h:208
x_fn_t fn
Definition x-prim.h:206
x_char_t * ns
Definition x-prim.h:207
x_char_t * name
Definition x-prim.h:205
Definition x-obj.h:214
#define x_argrun(...)
Definition x-eval-slots.h:169
#define x_eval_call(B, I, A)
Definition x-eval-slots.h:190
@ X_SLOT_EVAL
Definition x-eval-slots.h:83
void x_eval_spine_guard(x_obj_t *p_base, x_obj_t *p_obj)
Definition x-eval.c:375
Evaluator object and interface – x-expr's base object plus the environment, control-flow,...
Heap management and mark-sweep garbage collection.
The x-expr object system – atoms, pairs, flags, and type dispatch.
@ X_OBJ_FLAG_NONE
Definition x-obj.h:131
#define x_obj_data_i(X, I)
Definition x-obj.h:332
#define x_obj_set(T, F,...)
Definition x-obj.h:344
x_obj_t *(* x_fn_t)(x_obj_t *p_base, x_obj_t *p_args)
Definition x-obj.h:199
#define x_firstobj(X)
Definition x-obj.h:418
x_satom_t x_type_pair_obj
Definition x-obj.c:32
x_obj_t x_spair_t[X_OBJ_META_LEN+X_OBJ_UNITS_PAIR]
Definition x-obj.h:288
#define x_restobj(X)
Definition x-obj.h:439
x_obj_t * x_heap_mark_phase(x_obj_t *p_base, x_obj_t *p_args)
Definition heap.c:82
x_obj_t * x_prim_arith_register(x_obj_t *p_base, x_obj_t *p_args)
Definition arith.c:245
x_obj_t * x_heap_sweep_phase(x_obj_t *p_base, x_obj_t *p_args)
Definition heap.c:115
x_obj_t * x_prim_base_register(x_obj_t *p_base, x_obj_t *p_args)
Definition base.c:316
x_obj_t * x_prim_pred_register(x_obj_t *p_base, x_obj_t *p_args)
Definition pred.c:140
x_obj_t * x_prim_ffi_register(x_obj_t *p_base, x_obj_t *p_args)
Register all FFI primitives and platform constants.
Definition ffi.c:775
x_obj_t * x_prim_type_build_struct(x_obj_t *p_base, x_obj_t *p_name_atom, x_obj_t *p_handlers)
Build a type struct from a handlers alist.
Definition type.c:63
x_obj_t * x_prim_heap_register(x_obj_t *p_base, x_obj_t *p_args)
Definition heap.c:404
x_obj_t * x_prim_io_register(x_obj_t *p_base, x_obj_t *p_args)
Definition io.c:224
x_obj_t * x_prim_op1(x_obj_t *p_base, x_obj_t *p_args, x_obj_t *(*op)(x_obj_t *, x_obj_t *))
Definition type.c:320
x_obj_t * x_prim_callcc_register(x_obj_t *p_base, x_obj_t *p_args)
Definition callcc.c:370
x_obj_t * x_heap_run_hooks(x_obj_t *p_base, x_obj_t *p_args)
Definition heap.c:29
x_obj_t * x_prim_image_register(x_obj_t *p_base, x_obj_t *p_args)
Definition image.c:913
x_obj_t * x_prim_register(x_obj_t *p_base, x_obj_t *p_args)
Definition x-prim.c:288
void x_callcc_init(void)
Definition callcc.c:106
x_obj_t * x_prim_core_register(x_obj_t *p_base, x_obj_t *p_args)
Definition core.c:332
x_obj_t * x_prim_repl(x_obj_t *p_base, x_obj_t *p_args)
Definition io.c:149
x_obj_t * x_prim_type_register(x_obj_t *p_base, x_obj_t *p_args)
Register all type-system and sandboxing primitives.
Definition type.c:353
x_obj_t * x_prim_string_register(x_obj_t *p_base, x_obj_t *p_args)
Definition string.c:215
x_obj_t * x_prim_iter_register(x_obj_t *p_base, x_obj_t *p_args)
Definition iter.c:68
x_obj_t * x_prim_buffer_register(x_obj_t *p_base, x_obj_t *p_args)
Definition buffer.c:283
char x_char_t
Definition x.h:138