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