1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include "lib/mlr_globals.h"
5 #include "lib/mlrutil.h"
6 #include "lib/mlrregex.h"
7 #include "lib/mtrand.h"
8 #include "mapping/mapper.h"
9 #include "dsl/context_flags.h"
10 #include "dsl/rxval_evaluators.h"
11
12 // ----------------------------------------------------------------
13 typedef struct _rxval_evaluator_variadic_state_t {
14 xv_variadic_func_t* pfunc;
15 rxval_evaluator_t** pargs;
16 boxed_xval_t* pbxvals;
17 int nargs;
18 } rxval_evaluator_variadic_state_t;
19
rxval_evaluator_variadic_func(void * pvstate,variables_t * pvars)20 static boxed_xval_t rxval_evaluator_variadic_func(void* pvstate, variables_t* pvars) {
21 rxval_evaluator_variadic_state_t* pstate = pvstate;
22 int nargs = pstate->nargs;
23
24 for (int i = 0; i < nargs; i++) {
25 rxval_evaluator_t* parg = pstate->pargs[i];
26 boxed_xval_t* pbxval = &pstate->pbxvals[i];
27 *pbxval = parg->pprocess_func(parg->pvstate, pvars);
28 }
29
30 boxed_xval_t bxrv = pstate->pfunc(pstate->pbxvals, nargs);
31
32 for (int i = 0; i < nargs; i++) {
33 boxed_xval_t* pbxval = &pstate->pbxvals[i];
34 if (pbxval->is_ephemeral) {
35 mlhmmv_xvalue_free(&pbxval->xval);
36 }
37 }
38 return bxrv;
39 }
40
rxval_evaluator_variadic_free(rxval_evaluator_t * pxevaluator)41 static void rxval_evaluator_variadic_free(rxval_evaluator_t* pxevaluator) {
42 rxval_evaluator_variadic_state_t* pstate = pxevaluator->pvstate;
43
44 for (int i = 0; i < pstate->nargs; i++)
45 pstate->pargs[i]->pfree_func(pstate->pargs[i]);
46 free(pstate->pargs);
47
48 for (int i = 0; i < pstate->nargs; i++) {
49 if (pstate->pbxvals[i].is_ephemeral) {
50 mlhmmv_xvalue_free(&pstate->pbxvals[i].xval);
51 }
52 }
53 free(pstate->pbxvals);
54
55 free(pstate);
56
57 free(pxevaluator);
58 }
59
rxval_evaluator_alloc_from_variadic_func(xv_variadic_func_t * pfunc,sllv_t * parg_nodes,fmgr_t * pfmgr,int type_inferencing,int context_flags)60 rxval_evaluator_t* rxval_evaluator_alloc_from_variadic_func(
61 xv_variadic_func_t* pfunc,
62 sllv_t* parg_nodes,
63 fmgr_t* pfmgr,
64 int type_inferencing,
65 int context_flags)
66 {
67 rxval_evaluator_variadic_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_variadic_state_t));
68 pstate->pfunc = pfunc;
69
70 int nargs = parg_nodes->length;
71 rxval_evaluator_t** pargs = mlr_malloc_or_die(nargs * sizeof(rxval_evaluator_t*));
72 int i = 0;
73 for (sllve_t* pe = parg_nodes->phead; pe != NULL; pe = pe->pnext, i++) {
74 mlr_dsl_ast_node_t* pnode = pe->pvvalue;
75 pargs[i] = rxval_evaluator_alloc_from_ast(pnode, pfmgr, type_inferencing, context_flags);
76 }
77
78 pstate->pargs = pargs;
79 pstate->nargs = nargs;
80 pstate->pbxvals = mlr_malloc_or_die(nargs * sizeof(boxed_xval_t));
81
82 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
83 pxevaluator->pvstate = pstate;
84 pxevaluator->pprocess_func = rxval_evaluator_variadic_func;
85 pxevaluator->pfree_func = rxval_evaluator_variadic_free;
86
87 return pxevaluator;
88 }
89
90 // ----------------------------------------------------------------
91 typedef struct _rxval_evaluator_x_x_state_t {
92 xv_unary_func_t* pfunc;
93 rxval_evaluator_t* parg1;
94 } rxval_evaluator_x_x_state_t;
95
rxval_evaluator_x_x_func(void * pvstate,variables_t * pvars)96 static boxed_xval_t rxval_evaluator_x_x_func(void* pvstate, variables_t* pvars) {
97 rxval_evaluator_x_x_state_t* pstate = pvstate;
98 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
99
100 boxed_xval_t bxrv = pstate->pfunc(&bxval1);
101
102 if (bxval1.is_ephemeral) {
103 mlhmmv_xvalue_free(&bxval1.xval);
104 }
105
106 return bxrv;
107 }
108
rxval_evaluator_x_x_free(rxval_evaluator_t * pxevaluator)109 static void rxval_evaluator_x_x_free(rxval_evaluator_t* pxevaluator) {
110 rxval_evaluator_x_x_state_t* pstate = pxevaluator->pvstate;
111 pstate->parg1->pfree_func(pstate->parg1);
112 free(pstate);
113 free(pxevaluator);
114 }
115
rxval_evaluator_alloc_from_x_x_func(xv_unary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)116 rxval_evaluator_t* rxval_evaluator_alloc_from_x_x_func(
117 xv_unary_func_t* pfunc,
118 mlr_dsl_ast_node_t* parg1_node,
119 fmgr_t* pfmgr,
120 int type_inferencing,
121 int context_flags)
122 {
123 rxval_evaluator_x_x_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_x_state_t));
124 pstate->pfunc = pfunc;
125 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
126
127 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
128 pxevaluator->pvstate = pstate;
129 pxevaluator->pprocess_func = rxval_evaluator_x_x_func;
130 pxevaluator->pfree_func = rxval_evaluator_x_x_free;
131
132 return pxevaluator;
133 }
134
135 // ----------------------------------------------------------------
136 typedef struct _rxval_evaluator_x_m_state_t {
137 xv_unary_func_t* pfunc;
138 rxval_evaluator_t* parg1;
139 } rxval_evaluator_x_m_state_t;
140
rxval_evaluator_x_m_func(void * pvstate,variables_t * pvars)141 static boxed_xval_t rxval_evaluator_x_m_func(void* pvstate, variables_t* pvars) {
142 rxval_evaluator_x_m_state_t* pstate = pvstate;
143 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
144
145 if (bxval1.xval.is_terminal) {
146 return box_ephemeral_val(mv_error());
147 }
148
149 boxed_xval_t bxrv = pstate->pfunc(&bxval1);
150
151 if (bxval1.is_ephemeral) {
152 mlhmmv_xvalue_free(&bxval1.xval);
153 }
154 return bxrv;
155 }
156
rxval_evaluator_x_m_free(rxval_evaluator_t * pxevaluator)157 static void rxval_evaluator_x_m_free(rxval_evaluator_t* pxevaluator) {
158 rxval_evaluator_x_m_state_t* pstate = pxevaluator->pvstate;
159 pstate->parg1->pfree_func(pstate->parg1);
160 free(pstate);
161 free(pxevaluator);
162 }
163
rxval_evaluator_alloc_from_x_m_func(xv_unary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)164 rxval_evaluator_t* rxval_evaluator_alloc_from_x_m_func(
165 xv_unary_func_t* pfunc,
166 mlr_dsl_ast_node_t* parg1_node,
167 fmgr_t* pfmgr,
168 int type_inferencing,
169 int context_flags)
170 {
171 rxval_evaluator_x_m_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_m_state_t));
172 pstate->pfunc = pfunc;
173 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
174
175 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
176 pxevaluator->pvstate = pstate;
177 pxevaluator->pprocess_func = rxval_evaluator_x_m_func;
178 pxevaluator->pfree_func = rxval_evaluator_x_m_free;
179
180 return pxevaluator;
181 }
182
183 // ----------------------------------------------------------------
184 typedef struct _rxval_evaluator_x_mx_state_t {
185 xv_binary_func_t* pfunc;
186 rxval_evaluator_t* parg1;
187 rxval_evaluator_t* parg2;
188 } rxval_evaluator_x_mx_state_t;
189
rxval_evaluator_x_mx_func(void * pvstate,variables_t * pvars)190 static boxed_xval_t rxval_evaluator_x_mx_func(void* pvstate, variables_t* pvars) {
191 rxval_evaluator_x_mx_state_t* pstate = pvstate;
192 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
193 boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
194
195 if (bxval1.xval.is_terminal) {
196 return box_ephemeral_val(mv_error());
197 }
198
199 if (!bxval2.xval.is_terminal) {
200 return box_ephemeral_val(mv_error());
201 }
202
203 boxed_xval_t bxrv = pstate->pfunc(&bxval1, &bxval2);
204
205 if (bxval1.is_ephemeral) {
206 mlhmmv_xvalue_free(&bxval1.xval);
207 }
208 if (bxval2.is_ephemeral) {
209 mlhmmv_xvalue_free(&bxval2.xval);
210 }
211 return bxrv;
212 }
213
rxval_evaluator_x_mx_free(rxval_evaluator_t * pxevaluator)214 static void rxval_evaluator_x_mx_free(rxval_evaluator_t* pxevaluator) {
215 rxval_evaluator_x_mx_state_t* pstate = pxevaluator->pvstate;
216 pstate->parg1->pfree_func(pstate->parg1);
217 pstate->parg2->pfree_func(pstate->parg2);
218 free(pstate);
219 free(pxevaluator);
220 }
221
rxval_evaluator_alloc_from_x_mx_func(xv_binary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,mlr_dsl_ast_node_t * parg2_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)222 rxval_evaluator_t* rxval_evaluator_alloc_from_x_mx_func(
223 xv_binary_func_t* pfunc,
224 mlr_dsl_ast_node_t* parg1_node,
225 mlr_dsl_ast_node_t* parg2_node,
226 fmgr_t* pfmgr,
227 int type_inferencing,
228 int context_flags)
229 {
230 rxval_evaluator_x_mx_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_mx_state_t));
231 pstate->pfunc = pfunc;
232 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
233 pstate->parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
234
235 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
236 pxevaluator->pvstate = pstate;
237 pxevaluator->pprocess_func = rxval_evaluator_x_mx_func;
238 pxevaluator->pfree_func = rxval_evaluator_x_mx_free;
239
240 return pxevaluator;
241 }
242
243 // ----------------------------------------------------------------
244 typedef struct _rxval_evaluator_x_ms_state_t {
245 xv_binary_func_t* pfunc;
246 rxval_evaluator_t* parg1;
247 rxval_evaluator_t* parg2;
248 } rxval_evaluator_x_ms_state_t;
249
rxval_evaluator_x_ms_func(void * pvstate,variables_t * pvars)250 static boxed_xval_t rxval_evaluator_x_ms_func(void* pvstate, variables_t* pvars) {
251 rxval_evaluator_x_ms_state_t* pstate = pvstate;
252 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
253 boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
254
255 if (bxval1.xval.is_terminal) {
256 return box_ephemeral_val(mv_error());
257 }
258
259 if (!bxval2.xval.is_terminal) {
260 return box_ephemeral_val(mv_error());
261 }
262 if (!mv_is_string_or_empty(&bxval2.xval.terminal_mlrval)) {
263 mv_free(&bxval2.xval.terminal_mlrval);
264 return box_ephemeral_val(mv_error());
265 }
266
267 boxed_xval_t bxrv = pstate->pfunc(&bxval1, &bxval2);
268
269 if (bxval1.is_ephemeral) {
270 mlhmmv_xvalue_free(&bxval1.xval);
271 }
272 if (bxval2.is_ephemeral) {
273 mlhmmv_xvalue_free(&bxval2.xval);
274 }
275 return bxrv;
276 }
277
rxval_evaluator_x_ms_free(rxval_evaluator_t * pxevaluator)278 static void rxval_evaluator_x_ms_free(rxval_evaluator_t* pxevaluator) {
279 rxval_evaluator_x_ms_state_t* pstate = pxevaluator->pvstate;
280 pstate->parg1->pfree_func(pstate->parg1);
281 pstate->parg2->pfree_func(pstate->parg2);
282 free(pstate);
283 free(pxevaluator);
284 }
285
rxval_evaluator_alloc_from_x_ms_func(xv_binary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,mlr_dsl_ast_node_t * parg2_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)286 rxval_evaluator_t* rxval_evaluator_alloc_from_x_ms_func(
287 xv_binary_func_t* pfunc,
288 mlr_dsl_ast_node_t* parg1_node,
289 mlr_dsl_ast_node_t* parg2_node,
290 fmgr_t* pfmgr,
291 int type_inferencing,
292 int context_flags)
293 {
294 rxval_evaluator_x_ms_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_ms_state_t));
295 pstate->pfunc = pfunc;
296 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
297 pstate->parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
298
299 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
300 pxevaluator->pvstate = pstate;
301 pxevaluator->pprocess_func = rxval_evaluator_x_ms_func;
302 pxevaluator->pfree_func = rxval_evaluator_x_ms_free;
303
304 return pxevaluator;
305 }
306
307 // ----------------------------------------------------------------
308 typedef struct _rxval_evaluator_x_ss_state_t {
309 xv_binary_func_t* pfunc;
310 rxval_evaluator_t* parg1;
311 rxval_evaluator_t* parg2;
312 } rxval_evaluator_x_ss_state_t;
313
rxval_evaluator_x_ss_func(void * pvstate,variables_t * pvars)314 static boxed_xval_t rxval_evaluator_x_ss_func(void* pvstate, variables_t* pvars) {
315 rxval_evaluator_x_ss_state_t* pstate = pvstate;
316 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
317 boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
318
319 if (!bxval1.xval.is_terminal) {
320 mv_free(&bxval1.xval.terminal_mlrval);
321 return box_ephemeral_val(mv_error());
322 }
323 if (!mv_is_string_or_empty(&bxval1.xval.terminal_mlrval)) {
324 mv_free(&bxval1.xval.terminal_mlrval);
325 return box_ephemeral_val(mv_error());
326 }
327
328 if (!bxval2.xval.is_terminal) {
329 mv_free(&bxval2.xval.terminal_mlrval);
330 return box_ephemeral_val(mv_error());
331 }
332 if (!mv_is_string_or_empty(&bxval2.xval.terminal_mlrval)) {
333 mv_free(&bxval2.xval.terminal_mlrval);
334 return box_ephemeral_val(mv_error());
335 }
336
337 boxed_xval_t bxrv = pstate->pfunc(&bxval1, &bxval2);
338
339 if (bxval1.is_ephemeral) {
340 mlhmmv_xvalue_free(&bxval1.xval);
341 }
342 if (bxval2.is_ephemeral) {
343 mlhmmv_xvalue_free(&bxval2.xval);
344 }
345 return bxrv;
346 }
347
rxval_evaluator_x_ss_free(rxval_evaluator_t * pxevaluator)348 static void rxval_evaluator_x_ss_free(rxval_evaluator_t* pxevaluator) {
349 rxval_evaluator_x_ss_state_t* pstate = pxevaluator->pvstate;
350 pstate->parg1->pfree_func(pstate->parg1);
351 pstate->parg2->pfree_func(pstate->parg2);
352 free(pstate);
353 free(pxevaluator);
354 }
355
rxval_evaluator_alloc_from_x_ss_func(xv_binary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,mlr_dsl_ast_node_t * parg2_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)356 rxval_evaluator_t* rxval_evaluator_alloc_from_x_ss_func(
357 xv_binary_func_t* pfunc,
358 mlr_dsl_ast_node_t* parg1_node,
359 mlr_dsl_ast_node_t* parg2_node,
360 fmgr_t* pfmgr,
361 int type_inferencing,
362 int context_flags)
363 {
364 rxval_evaluator_x_ss_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_ss_state_t));
365 pstate->pfunc = pfunc;
366 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
367 pstate->parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
368
369 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
370 pxevaluator->pvstate = pstate;
371 pxevaluator->pprocess_func = rxval_evaluator_x_ss_func;
372 pxevaluator->pfree_func = rxval_evaluator_x_ss_free;
373
374 return pxevaluator;
375 }
376
377 // ----------------------------------------------------------------
378 typedef struct _rxval_evaluator_x_mss_state_t {
379 xv_ternary_func_t* pfunc;
380 rxval_evaluator_t* parg1;
381 rxval_evaluator_t* parg2;
382 rxval_evaluator_t* parg3;
383 } rxval_evaluator_x_mss_state_t;
384
rxval_evaluator_x_mss_func(void * pvstate,variables_t * pvars)385 static boxed_xval_t rxval_evaluator_x_mss_func(void* pvstate, variables_t* pvars) {
386 rxval_evaluator_x_mss_state_t* pstate = pvstate;
387 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
388 boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
389 boxed_xval_t bxval3 = pstate->parg3->pprocess_func(pstate->parg3->pvstate, pvars);
390
391 if (bxval1.xval.is_terminal) {
392 return box_ephemeral_val(mv_error());
393 }
394
395 if (!bxval2.xval.is_terminal) {
396 return box_ephemeral_val(mv_error());
397 }
398 if (!mv_is_string_or_empty(&bxval2.xval.terminal_mlrval)) {
399 mv_free(&bxval2.xval.terminal_mlrval);
400 return box_ephemeral_val(mv_error());
401 }
402
403 if (!bxval3.xval.is_terminal) {
404 return box_ephemeral_val(mv_error());
405 }
406 if (!mv_is_string_or_empty(&bxval3.xval.terminal_mlrval)) {
407 mv_free(&bxval3.xval.terminal_mlrval);
408 return box_ephemeral_val(mv_error());
409 }
410
411 boxed_xval_t bxrv = pstate->pfunc(&bxval1, &bxval2, &bxval3);
412
413 if (bxval1.is_ephemeral) {
414 mlhmmv_xvalue_free(&bxval1.xval);
415 }
416 if (bxval2.is_ephemeral) {
417 mlhmmv_xvalue_free(&bxval2.xval);
418 }
419 return bxrv;
420 }
421
rxval_evaluator_x_mss_free(rxval_evaluator_t * pxevaluator)422 static void rxval_evaluator_x_mss_free(rxval_evaluator_t* pxevaluator) {
423 rxval_evaluator_x_mss_state_t* pstate = pxevaluator->pvstate;
424 pstate->parg1->pfree_func(pstate->parg1);
425 pstate->parg2->pfree_func(pstate->parg2);
426 pstate->parg3->pfree_func(pstate->parg3);
427 free(pstate);
428 free(pxevaluator);
429 }
430
rxval_evaluator_alloc_from_x_mss_func(xv_ternary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,mlr_dsl_ast_node_t * parg2_node,mlr_dsl_ast_node_t * parg3_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)431 rxval_evaluator_t* rxval_evaluator_alloc_from_x_mss_func(
432 xv_ternary_func_t* pfunc,
433 mlr_dsl_ast_node_t* parg1_node,
434 mlr_dsl_ast_node_t* parg2_node,
435 mlr_dsl_ast_node_t* parg3_node,
436 fmgr_t* pfmgr,
437 int type_inferencing,
438 int context_flags)
439 {
440 rxval_evaluator_x_mss_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_mss_state_t));
441 pstate->pfunc = pfunc;
442 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
443 pstate->parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
444 pstate->parg3 = rxval_evaluator_alloc_from_ast(parg3_node, pfmgr, type_inferencing, context_flags);
445
446 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
447 pxevaluator->pvstate = pstate;
448 pxevaluator->pprocess_func = rxval_evaluator_x_mss_func;
449 pxevaluator->pfree_func = rxval_evaluator_x_mss_free;
450
451 return pxevaluator;
452 }
453
454 // ----------------------------------------------------------------
455 typedef struct _rxval_evaluator_x_sss_state_t {
456 xv_ternary_func_t* pfunc;
457 rxval_evaluator_t* parg1;
458 rxval_evaluator_t* parg2;
459 rxval_evaluator_t* parg3;
460 } rxval_evaluator_x_sss_state_t;
461
rxval_evaluator_x_sss_func(void * pvstate,variables_t * pvars)462 static boxed_xval_t rxval_evaluator_x_sss_func(void* pvstate, variables_t* pvars) {
463 rxval_evaluator_x_sss_state_t* pstate = pvstate;
464 boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
465 boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
466 boxed_xval_t bxval3 = pstate->parg3->pprocess_func(pstate->parg3->pvstate, pvars);
467
468 if (!bxval1.xval.is_terminal) {
469 return box_ephemeral_val(mv_error());
470 }
471 if (!mv_is_string_or_empty(&bxval1.xval.terminal_mlrval)) {
472 mv_free(&bxval1.xval.terminal_mlrval);
473 return box_ephemeral_val(mv_error());
474 }
475
476 if (!bxval2.xval.is_terminal) {
477 return box_ephemeral_val(mv_error());
478 }
479 if (!mv_is_string_or_empty(&bxval2.xval.terminal_mlrval)) {
480 mv_free(&bxval2.xval.terminal_mlrval);
481 return box_ephemeral_val(mv_error());
482 }
483
484 if (!bxval3.xval.is_terminal) {
485 return box_ephemeral_val(mv_error());
486 }
487 if (!mv_is_string_or_empty(&bxval3.xval.terminal_mlrval)) {
488 mv_free(&bxval3.xval.terminal_mlrval);
489 return box_ephemeral_val(mv_error());
490 }
491
492 boxed_xval_t bxrv = pstate->pfunc(&bxval1, &bxval2, &bxval3);
493
494 if (bxval1.is_ephemeral) {
495 mlhmmv_xvalue_free(&bxval1.xval);
496 }
497 if (bxval2.is_ephemeral) {
498 mlhmmv_xvalue_free(&bxval2.xval);
499 }
500 if (bxval3.is_ephemeral) {
501 mlhmmv_xvalue_free(&bxval3.xval);
502 }
503 return bxrv;
504 }
505
rxval_evaluator_x_sss_free(rxval_evaluator_t * pxevaluator)506 static void rxval_evaluator_x_sss_free(rxval_evaluator_t* pxevaluator) {
507 rxval_evaluator_x_sss_state_t* pstate = pxevaluator->pvstate;
508 pstate->parg1->pfree_func(pstate->parg1);
509 pstate->parg2->pfree_func(pstate->parg2);
510 pstate->parg3->pfree_func(pstate->parg3);
511 free(pstate);
512 free(pxevaluator);
513 }
514
rxval_evaluator_alloc_from_x_sss_func(xv_ternary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,mlr_dsl_ast_node_t * parg2_node,mlr_dsl_ast_node_t * parg3_node,fmgr_t * pfmgr,int type_inferencing,int context_flags)515 rxval_evaluator_t* rxval_evaluator_alloc_from_x_sss_func(
516 xv_ternary_func_t* pfunc,
517 mlr_dsl_ast_node_t* parg1_node,
518 mlr_dsl_ast_node_t* parg2_node,
519 mlr_dsl_ast_node_t* parg3_node,
520 fmgr_t* pfmgr,
521 int type_inferencing,
522 int context_flags)
523 {
524 rxval_evaluator_x_sss_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_sss_state_t));
525 pstate->pfunc = pfunc;
526 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
527 pstate->parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
528 pstate->parg3 = rxval_evaluator_alloc_from_ast(parg3_node, pfmgr, type_inferencing, context_flags);
529
530 rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
531 pxevaluator->pvstate = pstate;
532 pxevaluator->pprocess_func = rxval_evaluator_x_sss_func;
533 pxevaluator->pfree_func = rxval_evaluator_x_sss_free;
534
535 return pxevaluator;
536 }
537
538 // ----------------------------------------------------------------
539 // Does type-check assertion on the argument and returns it unmodified if the
540 // test passes. Else throws an error.
541 typedef struct _rxval_evaluator_A_x_state_t {
542 xv_unary_func_t* pfunc;
543 rxval_evaluator_t* parg1;
544 char* desc;
545 } rxval_evaluator_A_x_state_t;
546
rxval_evaluator_A_x_func(void * pvstate,variables_t * pvars)547 static boxed_xval_t rxval_evaluator_A_x_func(void* pvstate, variables_t* pvars) {
548 rxval_evaluator_A_x_state_t* pstate = pvstate;
549 boxed_xval_t val1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
550
551 boxed_xval_t ok = pstate->pfunc(&val1);
552
553 if (!ok.xval.terminal_mlrval.u.boolv) {
554 fprintf(stderr, "%s: %s type-assertion failed at NR=%lld FNR=%lld FILENAME=%s\n",
555 MLR_GLOBALS.bargv0, pstate->desc, pvars->pctx->nr, pvars->pctx->fnr, pvars->pctx->filename);
556 exit(1);
557 }
558
559 return val1;
560 }
rxval_evaluator_A_x_free(rxval_evaluator_t * pevaluator)561 static void rxval_evaluator_A_x_free(rxval_evaluator_t* pevaluator) {
562 rxval_evaluator_A_x_state_t* pstate = pevaluator->pvstate;
563 pstate->parg1->pfree_func(pstate->parg1);
564 free(pstate->desc);
565 free(pstate);
566 free(pevaluator);
567 }
568
rxval_evaluator_alloc_from_A_x_func(xv_unary_func_t * pfunc,mlr_dsl_ast_node_t * parg1_node,fmgr_t * pfmgr,int type_inferencing,int context_flags,char * desc)569 rxval_evaluator_t* rxval_evaluator_alloc_from_A_x_func(
570 xv_unary_func_t* pfunc,
571 mlr_dsl_ast_node_t* parg1_node,
572 fmgr_t* pfmgr,
573 int type_inferencing,
574 int context_flags,
575 char* desc)
576 {
577
578 rxval_evaluator_A_x_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_A_x_state_t));
579 pstate->pfunc = pfunc;
580 pstate->parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
581 pstate->desc = mlr_strdup_or_die(desc);
582
583 rxval_evaluator_t* pevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
584 pevaluator->pvstate = pstate;
585 pevaluator->pprocess_func = rxval_evaluator_A_x_func;
586 pevaluator->pfree_func = rxval_evaluator_A_x_free;
587
588 return pevaluator;
589 }
590