1 #include <stdlib.h>
2 #include "lib/mlr_globals.h"
3 #include "lib/mlrutil.h"
4 #include "mlr_dsl_cst.h"
5 #include "context_flags.h"
6
7 // ================================================================
8 typedef struct _conditional_block_state_t {
9 rval_evaluator_t* pexpression_evaluator;
10 } conditional_block_state_t;
11
12 static mlr_dsl_cst_statement_freer_t free_conditional_block;
13 static mlr_dsl_cst_statement_handler_t handle_conditional_block;
14
15 // ----------------------------------------------------------------
alloc_conditional_block(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)16 mlr_dsl_cst_statement_t* alloc_conditional_block(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
17 int type_inferencing, int context_flags)
18 {
19 conditional_block_state_t* pstate = mlr_malloc_or_die(sizeof(conditional_block_state_t));
20
21 pstate->pexpression_evaluator = NULL;
22
23 // Right node is a list of statements to be executed if the left evaluates to true.
24 mlr_dsl_ast_node_t* pleft = pnode->pchildren->phead->pvvalue;
25 mlr_dsl_ast_node_t* pright = pnode->pchildren->phead->pnext->pvvalue;
26
27 pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast(
28 pleft, pcst->pfmgr, type_inferencing, context_flags);
29
30 MLR_INTERNAL_CODING_ERROR_IF(pright->subframe_var_count == MD_UNUSED_INDEX);
31 cst_statement_block_t* pblock = cst_statement_block_alloc(pright->subframe_var_count);
32
33 for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) {
34 mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
35 mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
36 type_inferencing, context_flags);
37 sllv_append(pblock->pstatements, pchild_statement);
38 }
39
40 mlr_dsl_cst_block_handler_t* pblock_handler = (context_flags & IN_BREAKABLE)
41 ? mlr_dsl_cst_handle_statement_block_with_break_continue
42 : mlr_dsl_cst_handle_statement_block;
43
44 return mlr_dsl_cst_statement_valloc_with_block(
45 pnode,
46 handle_conditional_block,
47 pblock,
48 pblock_handler,
49 free_conditional_block,
50 pstate);
51 }
52
53 // ----------------------------------------------------------------
free_conditional_block(mlr_dsl_cst_statement_t * pstatement,context_t * _)54 static void free_conditional_block(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
55 conditional_block_state_t* pstate = pstatement->pvstate;
56
57 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
58
59 free(pstate);
60 }
61
62 // ----------------------------------------------------------------
handle_conditional_block(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)63 static void handle_conditional_block(
64 mlr_dsl_cst_statement_t* pstatement,
65 variables_t* pvars,
66 cst_outputs_t* pcst_outputs)
67 {
68 conditional_block_state_t* pstate = pstatement->pvstate;
69
70 local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
71 local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count);
72
73 rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator;
74
75 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
76 if (mv_is_non_null(&val)) {
77 mv_set_boolean_strict(&val);
78 if (val.u.boolv) {
79 pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs);
80 }
81 }
82
83 local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count);
84 }
85
86 // ================================================================
87 typedef struct _if_head_state_t {
88 sllv_t* pif_chain_statements;
89 } if_head_state_t;
90
91 typedef struct _if_item_state_t {
92 rval_evaluator_t* pexpression_evaluator;
93 } if_item_state_t;
94
95 static mlr_dsl_cst_statement_handler_t handle_if_head;
96 static mlr_dsl_cst_statement_freer_t free_if_head;
97 static mlr_dsl_cst_statement_freer_t free_if_item;
98
99 static mlr_dsl_cst_statement_t* alloc_if_item(
100 mlr_dsl_cst_t* pcst,
101 mlr_dsl_ast_node_t* pitemnode,
102 mlr_dsl_ast_node_t* pexprnode,
103 mlr_dsl_ast_node_t* plistnode,
104 int type_inferencing,
105 int context_flags);
106
107 // ----------------------------------------------------------------
108 // Example parser-input:
109 //
110 // if (NR == 9) {
111 // $x = 10;
112 // $x = 11
113 // } elif (NR == 12) {
114 // $x = 13;
115 // $x = 14
116 // } else {
117 // $x = 15;
118 // $x = 16
119 // };
120 //
121 // Corresponding parser-output AST:
122 // if_head (if_head):
123 // if (if_item):
124 // == (operator):
125 // NR (context_variable).
126 // 9 (numeric_literal).
127 // list (statement_list):
128 // = (srec_assignment):
129 // x (field_name).
130 // 10 (numeric_literal).
131 // = (srec_assignment):
132 // x (field_name).
133 // 11 (numeric_literal).
134 // elif (if_item):
135 // == (operator):
136 // NR (context_variable).
137 // 12 (numeric_literal).
138 // list (statement_list):
139 // = (srec_assignment):
140 // x (field_name).
141 // 13 (numeric_literal).
142 // = (srec_assignment):
143 // x (field_name).
144 // 14 (numeric_literal).
145 // else (if_item):
146 // list (statement_list):
147 // = (srec_assignment):
148 // x (field_name).
149 // 15 (numeric_literal).
150 // = (srec_assignment):
151 // x (field_name).
152 // 16 (numeric_literal).
153
alloc_if_head(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)154 mlr_dsl_cst_statement_t* alloc_if_head(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
155 int type_inferencing, int context_flags)
156 {
157 if_head_state_t* pstate = mlr_malloc_or_die(sizeof(if_head_state_t));
158
159 pstate->pif_chain_statements = sllv_alloc();
160
161 for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
162 // For if and elif:
163 // * Left subnode is the AST for the boolean expression.
164 // * Right subnode is a list of statements to be executed if the left evaluates to true.
165 // For else:
166 // * Sole subnode is a list of statements to be executed.
167 mlr_dsl_ast_node_t* pitemnode = pe->pvvalue;
168 mlr_dsl_ast_node_t* pexprnode = NULL;
169 mlr_dsl_ast_node_t* plistnode = NULL;
170 if (pitemnode->pchildren->length == 2) {
171 pexprnode = pitemnode->pchildren->phead->pvvalue;
172 plistnode = pitemnode->pchildren->phead->pnext->pvvalue;
173 } else {
174 pexprnode = NULL;
175 plistnode = pitemnode->pchildren->phead->pvvalue;
176 }
177
178 sllv_append(pstate->pif_chain_statements,
179 alloc_if_item(pcst, pitemnode, pexprnode, plistnode, type_inferencing, context_flags)
180 );
181 }
182
183 mlr_dsl_cst_block_handler_t* pblock_handler = (context_flags & IN_BREAKABLE)
184 ? mlr_dsl_cst_handle_statement_block_with_break_continue
185 : mlr_dsl_cst_handle_statement_block;
186
187 return mlr_dsl_cst_statement_valloc_with_block(
188 pnode,
189 handle_if_head,
190 NULL,
191 pblock_handler,
192 free_if_head,
193 pstate);
194 }
195
alloc_if_item(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pitemnode,mlr_dsl_ast_node_t * pexprnode,mlr_dsl_ast_node_t * plistnode,int type_inferencing,int context_flags)196 static mlr_dsl_cst_statement_t* alloc_if_item(mlr_dsl_cst_t* pcst,
197 mlr_dsl_ast_node_t* pitemnode, mlr_dsl_ast_node_t* pexprnode, mlr_dsl_ast_node_t* plistnode,
198 int type_inferencing, int context_flags)
199 {
200 if_item_state_t* pstate = mlr_malloc_or_die(sizeof(if_item_state_t));
201
202 MLR_INTERNAL_CODING_ERROR_IF(plistnode->subframe_var_count == MD_UNUSED_INDEX);
203 cst_statement_block_t* pblock = cst_statement_block_alloc(plistnode->subframe_var_count);
204
205 for (sllve_t* pe = plistnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
206 mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
207 mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
208 type_inferencing, context_flags);
209 sllv_append(pblock->pstatements, pchild_statement);
210 }
211
212 pstate->pexpression_evaluator = pexprnode != NULL
213 ? rval_evaluator_alloc_from_ast(pexprnode, pcst->pfmgr,
214 type_inferencing, context_flags) // if-statement or elif-statement
215 : rval_evaluator_alloc_from_boolean(TRUE); // else-statement
216
217 return mlr_dsl_cst_statement_valloc_with_block(
218 pitemnode,
219 NULL, // handled by the containing if-head evaluator
220 pblock,
221 NULL, // handled by the containing if-head evaluator
222 free_if_item,
223 pstate);
224 }
225
226 // ----------------------------------------------------------------
free_if_head(mlr_dsl_cst_statement_t * pstatement,context_t * pctx)227 static void free_if_head(mlr_dsl_cst_statement_t* pstatement, context_t* pctx) {
228 if_head_state_t* pstate = pstatement->pvstate;
229
230 if (pstate->pif_chain_statements != NULL) {
231 for (sllve_t* pe = pstate->pif_chain_statements->phead; pe != NULL; pe = pe->pnext)
232 mlr_dsl_cst_statement_free(pe->pvvalue, pctx);
233 sllv_free(pstate->pif_chain_statements);
234 }
235
236 free(pstate);
237 }
238
free_if_item(mlr_dsl_cst_statement_t * pstatement,context_t * _)239 static void free_if_item(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
240 if_item_state_t* pstate = pstatement->pvstate;
241
242 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
243
244 free(pstate);
245 }
246
247 // ----------------------------------------------------------------
handle_if_head(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)248 static void handle_if_head(
249 mlr_dsl_cst_statement_t* pstatement,
250 variables_t* pvars,
251 cst_outputs_t* pcst_outputs)
252 {
253 if_head_state_t* pstate = pstatement->pvstate;
254
255 for (sllve_t* pe = pstate->pif_chain_statements->phead; pe != NULL; pe = pe->pnext) {
256 mlr_dsl_cst_statement_t* pitem_statement = pe->pvvalue;
257 if_item_state_t* pitem_state = pitem_statement->pvstate;
258 rval_evaluator_t* pexpression_evaluator = pitem_state->pexpression_evaluator;
259
260 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
261 if (mv_is_non_null(&val)) {
262 mv_set_boolean_strict(&val);
263 if (val.u.boolv) {
264 local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
265 local_stack_subframe_enter(pframe, pitem_statement->pblock->subframe_var_count);
266
267 pstatement->pblock_handler(pitem_statement->pblock, pvars, pcst_outputs);
268
269 local_stack_subframe_exit(pframe, pitem_statement->pblock->subframe_var_count);
270 break;
271 }
272 }
273 }
274 }
275
276 // ================================================================
277 typedef struct _while_state_t {
278 rval_evaluator_t* pexpression_evaluator;
279 } while_state_t;
280
281 static mlr_dsl_cst_statement_handler_t handle_while;
282 static mlr_dsl_cst_statement_freer_t free_while;
283
284 // ----------------------------------------------------------------
alloc_while(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)285 mlr_dsl_cst_statement_t* alloc_while(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
286 int type_inferencing, int context_flags)
287 {
288 while_state_t* pstate = mlr_malloc_or_die(sizeof(while_state_t));
289
290 pstate->pexpression_evaluator = NULL;
291
292 // Left child node is the AST for the boolean expression.
293 // Right child node is the list of statements in the body.
294 mlr_dsl_ast_node_t* pleft = pnode->pchildren->phead->pvvalue;
295 mlr_dsl_ast_node_t* pright = pnode->pchildren->phead->pnext->pvvalue;
296
297 MLR_INTERNAL_CODING_ERROR_IF(pright->subframe_var_count == MD_UNUSED_INDEX);
298 cst_statement_block_t* pblock = cst_statement_block_alloc(pright->subframe_var_count);
299
300 for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) {
301 mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
302 mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
303 type_inferencing, context_flags);
304 sllv_append(pblock->pstatements, pchild_statement);
305 }
306
307 pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast(
308 pleft, pcst->pfmgr, type_inferencing, context_flags);
309
310 return mlr_dsl_cst_statement_valloc_with_block(
311 pnode,
312 handle_while,
313 pblock,
314 mlr_dsl_cst_handle_statement_block_with_break_continue,
315 free_while,
316 pstate);
317 }
318
319 // ----------------------------------------------------------------
free_while(mlr_dsl_cst_statement_t * pstatement,context_t * _)320 static void free_while(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
321 while_state_t* pstate = pstatement->pvstate;
322
323 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
324
325 free(pstate);
326 }
327
328 // ----------------------------------------------------------------
handle_while(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)329 static void handle_while(
330 mlr_dsl_cst_statement_t* pstatement,
331 variables_t* pvars,
332 cst_outputs_t* pcst_outputs)
333 {
334 while_state_t* pstate = pstatement->pvstate;
335
336 local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
337 local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count);
338 loop_stack_push(pvars->ploop_stack);
339
340 rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator;
341
342 while (TRUE) {
343 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
344 if (mv_is_non_null(&val)) {
345 mv_set_boolean_strict(&val);
346 if (val.u.boolv) {
347 pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs);
348 if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) {
349 loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN);
350 break;
351 } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) {
352 loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED);
353 }
354 } else {
355 break;
356 }
357 } else {
358 break;
359 }
360 }
361
362 loop_stack_pop(pvars->ploop_stack);
363 local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count);
364 }
365
366
367 // ================================================================
368 typedef struct _do_while_state_t {
369 rval_evaluator_t* pexpression_evaluator;
370 } do_while_state_t;
371
372 static mlr_dsl_cst_statement_handler_t handle_do_while;
373 static mlr_dsl_cst_statement_freer_t free_do_while;
374
375 // ----------------------------------------------------------------
alloc_do_while(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)376 mlr_dsl_cst_statement_t* alloc_do_while(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
377 int type_inferencing, int context_flags)
378 {
379 do_while_state_t* pstate = mlr_malloc_or_die(sizeof(do_while_state_t));
380
381 pstate->pexpression_evaluator = NULL;
382
383 // Left child node is the list of statements in the body.
384 // Right child node is the AST for the boolean expression.
385 mlr_dsl_ast_node_t* pleft = pnode->pchildren->phead->pvvalue;
386 mlr_dsl_ast_node_t* pright = pnode->pchildren->phead->pnext->pvvalue;
387
388 MLR_INTERNAL_CODING_ERROR_IF(pleft->subframe_var_count == MD_UNUSED_INDEX);
389 cst_statement_block_t* pblock = cst_statement_block_alloc(pright->subframe_var_count);
390
391 for (sllve_t* pe = pleft->pchildren->phead; pe != NULL; pe = pe->pnext) {
392 mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
393 mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
394 type_inferencing, context_flags);
395 sllv_append(pblock->pstatements, pchild_statement);
396 }
397
398 pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast(
399 pright, pcst->pfmgr, type_inferencing, context_flags);
400
401 return mlr_dsl_cst_statement_valloc_with_block(
402 pnode,
403 handle_do_while,
404 pblock,
405 mlr_dsl_cst_handle_statement_block_with_break_continue,
406 free_do_while,
407 pstate);
408 }
409
410 // ----------------------------------------------------------------
free_do_while(mlr_dsl_cst_statement_t * pstatement,context_t * _)411 static void free_do_while(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
412 do_while_state_t* pstate = pstatement->pvstate;
413
414 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
415
416 free(pstate);
417 }
418
419 // ----------------------------------------------------------------
handle_do_while(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)420 static void handle_do_while(
421 mlr_dsl_cst_statement_t* pstatement,
422 variables_t* pvars,
423 cst_outputs_t* pcst_outputs)
424 {
425 do_while_state_t* pstate = pstatement->pvstate;
426
427 local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
428 local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count);
429 loop_stack_push(pvars->ploop_stack);
430
431 rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator;
432
433 while (TRUE) {
434 pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs);
435 if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) {
436 loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN);
437 break;
438 } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) {
439 loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED);
440 // don't skip the boolean test
441 }
442
443 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
444 if (mv_is_non_null(&val)) {
445 mv_set_boolean_strict(&val);
446 if (!val.u.boolv) {
447 break;
448 }
449 } else {
450 break;
451 }
452 }
453
454 loop_stack_pop(pvars->ploop_stack);
455 local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count);
456 }
457
458 // ================================================================
459 typedef struct _bare_boolean_state_t {
460 rval_evaluator_t* pexpression_evaluator;
461 } bare_boolean_state_t;
462
463 static mlr_dsl_cst_statement_handler_t handle_bare_boolean;
464 static mlr_dsl_cst_statement_freer_t free_bare_boolean;
465
466 // ----------------------------------------------------------------
alloc_bare_boolean(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)467 mlr_dsl_cst_statement_t* alloc_bare_boolean(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
468 int type_inferencing, int context_flags)
469 {
470 bare_boolean_state_t* pstate = mlr_malloc_or_die(sizeof(bare_boolean_state_t));
471
472 pstate->pexpression_evaluator = NULL;
473
474 pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast(
475 pnode, pcst->pfmgr, type_inferencing, context_flags);
476
477 return mlr_dsl_cst_statement_valloc(
478 pnode,
479 handle_bare_boolean,
480 free_bare_boolean,
481 pstate);
482 }
483
484 // ----------------------------------------------------------------
free_bare_boolean(mlr_dsl_cst_statement_t * pstatement,context_t * _)485 static void free_bare_boolean(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
486 bare_boolean_state_t* pstate = pstatement->pvstate;
487
488 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
489
490 free(pstate);
491 }
492
493 // ----------------------------------------------------------------
handle_bare_boolean(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)494 static void handle_bare_boolean(
495 mlr_dsl_cst_statement_t* pstatement,
496 variables_t* pvars,
497 cst_outputs_t* pcst_outputs)
498 {
499 bare_boolean_state_t* pstate = pstatement->pvstate;
500 rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator;
501
502 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
503 if (mv_is_non_null(&val))
504 mv_set_boolean_strict(&val);
505 }
506
507 // ================================================================
508 typedef struct _filter_state_t {
509 rval_evaluator_t* pexpression_evaluator;
510 } filter_state_t;
511
512 static mlr_dsl_cst_statement_handler_t handle_filter;
513 static mlr_dsl_cst_statement_freer_t free_filter;
514
515 // ----------------------------------------------------------------
alloc_filter(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int type_inferencing,int context_flags)516 mlr_dsl_cst_statement_t* alloc_filter(
517 mlr_dsl_cst_t* pcst,
518 mlr_dsl_ast_node_t* pnode,
519 int type_inferencing,
520 int context_flags)
521 {
522 filter_state_t* pstate = mlr_malloc_or_die(sizeof(filter_state_t));
523
524 mlr_dsl_ast_node_t* pchild = pnode->pchildren->phead->pvvalue;
525
526 pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast(
527 pchild, pcst->pfmgr, type_inferencing, context_flags);
528
529 return mlr_dsl_cst_statement_valloc(
530 pnode,
531 handle_filter,
532 free_filter,
533 pstate);
534 }
535
536 // ----------------------------------------------------------------
free_filter(mlr_dsl_cst_statement_t * pstatement,context_t * _)537 static void free_filter(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
538 filter_state_t* pstate = pstatement->pvstate;
539
540 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
541
542 free(pstate);
543 }
544
545 // ----------------------------------------------------------------
handle_filter(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)546 static void handle_filter(
547 mlr_dsl_cst_statement_t* pstatement,
548 variables_t* pvars,
549 cst_outputs_t* pcst_outputs)
550 {
551 filter_state_t* pstate = pstatement->pvstate;
552 rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator;
553
554 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
555
556 if (mv_is_non_null(&val)) {
557 mv_set_boolean_strict(&val);
558 *pcst_outputs->pshould_emit_rec = val.u.boolv;
559 } else {
560 *pcst_outputs->pshould_emit_rec = FALSE;
561 }
562 }
563
564 // ================================================================
565 typedef struct _final_filter_state_t {
566 rval_evaluator_t* pexpression_evaluator;
567 int negate_final_filter;
568 } final_filter_state_t;
569
570 static mlr_dsl_cst_statement_handler_t handle_final_filter;
571 static mlr_dsl_cst_statement_freer_t free_final_filter;
572
573 // ----------------------------------------------------------------
alloc_final_filter(mlr_dsl_cst_t * pcst,mlr_dsl_ast_node_t * pnode,int negate_final_filter,int type_inferencing,int context_flags)574 mlr_dsl_cst_statement_t* alloc_final_filter(
575 mlr_dsl_cst_t* pcst,
576 mlr_dsl_ast_node_t* pnode,
577 int negate_final_filter,
578 int type_inferencing,
579 int context_flags)
580 {
581 final_filter_state_t* pstate = mlr_malloc_or_die(sizeof(final_filter_state_t));
582
583 pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast(
584 pnode, pcst->pfmgr, type_inferencing, context_flags);
585
586 pstate->negate_final_filter = negate_final_filter;
587
588 return mlr_dsl_cst_statement_valloc(
589 pnode,
590 handle_final_filter,
591 free_final_filter,
592 pstate);
593 }
594
595 // ----------------------------------------------------------------
free_final_filter(mlr_dsl_cst_statement_t * pstatement,context_t * _)596 static void free_final_filter(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
597 final_filter_state_t* pstate = pstatement->pvstate;
598
599 pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator);
600
601 free(pstate);
602 }
603
604 // ----------------------------------------------------------------
handle_final_filter(mlr_dsl_cst_statement_t * pstatement,variables_t * pvars,cst_outputs_t * pcst_outputs)605 static void handle_final_filter(
606 mlr_dsl_cst_statement_t* pstatement,
607 variables_t* pvars,
608 cst_outputs_t* pcst_outputs)
609 {
610 final_filter_state_t* pstate = pstatement->pvstate;
611 rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator;
612
613 mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars);
614
615 if (mv_is_non_null(&val)) {
616 mv_set_boolean_strict(&val);
617 *pcst_outputs->pshould_emit_rec = val.u.boolv ^ pstate->negate_final_filter;
618 } else {
619 *pcst_outputs->pshould_emit_rec = FALSE;
620 }
621 }
622