Coverage for skema/program_analysis/CAST2FN/ann_cast/grfn_var_creation_pass.py: 80%
303 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 17:15 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 17:15 +0000
1import typing
2from functools import singledispatchmethod
4from skema.model_assembly.metadata import VariableCreationReason
5from skema.program_analysis.CAST2FN.ann_cast.ann_cast_helpers import (
6 CON_STR_SEP,
7 ELSEBODY,
8 IFBODY,
9 IFEXPR,
10 LOOP_VAR_UPDATED_VERSION,
11 LOOPPRE,
12 LOOPBODY,
13 LOOPEXPR,
14 LOOPPOST,
15 VAR_EXIT_VERSION,
16 VAR_INIT_VERSION,
17 add_metadata_from_name_node,
18 add_metadata_to_grfn_var,
19 ann_cast_name_to_fullid,
20 build_fullid,
21 call_container_name,
22 con_scope_to_str,
23 create_grfn_var,
24 create_grfn_var_from_name_node,
25 generate_from_source_metadata,
26 make_cond_var_name,
27 make_loop_exit_name,
28)
29from skema.program_analysis.CAST2FN.ann_cast.annotated_cast import *
30from skema.program_analysis.CAST2FN.model.cast import (
31 ScalarType,
32 StructureType,
33 ValueConstructor,
34)
37class GrfnVarCreationPass:
38 def __init__(self, pipeline_state: PipelineState):
39 self.pipeline_state = pipeline_state
40 self.nodes = self.pipeline_state.nodes
41 # the fullid of a AnnCastName node is a string which includes its
42 # variable name, numerical id, version, and scope
43 for node in self.pipeline_state.nodes:
44 self.visit(node)
46 # DEBUG printing
47 if self.pipeline_state.PRINT_DEBUGGING_INFO:
48 self.print_created_grfn_vars()
50 def visit(self, node: AnnCastNode):
51 """
52 External visit that callsthe internal visit
53 Useful for debugging/development. For example,
54 printing the nodes that are visited
55 """
56 # print current node being visited.
57 # this can be useful for debugging
58 # class_name = node.__class__.__name__
59 # print(f"\nProcessing node type {class_name}")
61 # call internal visit
62 return self._visit(node)
64 def visit_node_list(self, node_list: typing.List[AnnCastNode]):
65 return [self.visit(node) for node in node_list]
67 def get_grfn_var_for_name_node(self, node: AnnCastName):
68 """
69 Obtains the GrFN variable node for the fullid of
70 this AnnCastName node
71 """
72 fullid = ann_cast_name_to_fullid(node)
73 return self.pipeline_state.grfn_id_to_grfn_var[
74 self.pipeline_state.fullid_to_grfn_id[fullid]
75 ]
77 def alias_copied_func_body_init_vers(self, node: AnnCastCall):
78 """
79 Precondition: This should be called after visiting copied function body.
80 This is used for GrFN 2.2 generation.
82 Aliases `VAR_INIT_VERSION` version variables from the function body to
83 `VAR_INIT_VERSION` of calling container sccope.
84 """
85 func_def_copy = node.func_def_copy
86 call_con_scopestr = con_scope_to_str(
87 node.func.con_scope + [call_container_name(node)]
88 )
89 func_con_scopestr = con_scope_to_str(func_def_copy.con_scope)
91 # alias `VAR_INIT_VERSION` variables in call_con_scopestr
92 # to the `VAR_INIT_VERSION` version occuring the func body
93 version = VAR_INIT_VERSION
94 # we alias globals which are used for the top interface
95 for id, var_name in node.top_interface_vars.items():
96 body_fullid = build_fullid(
97 var_name, id, version, func_con_scopestr
98 )
99 call_fullid = build_fullid(
100 var_name, id, version, call_con_scopestr
101 )
102 # we create GrFN variables with call_fullid during VariableVersionPass
103 self.pipeline_state.alias_grfn_vars(body_fullid, call_fullid)
105 # we also alias function parameters
106 for i, call_fullid in node.param_index_to_fullid.items():
107 var = func_def_copy.func_args[i]
108 assert isinstance(var, AnnCastVar)
109 name = var.val
110 func_id = name.id
111 var_name = name.name
112 func_fullid = build_fullid(
113 var_name, func_id, version, func_con_scopestr
114 )
115 # we create GrFN variables with call_fullid during VariableVersionPass
116 self.pipeline_state.alias_grfn_vars(func_fullid, call_fullid)
118 def alias_copied_func_body_highest_vers(self, node: AnnCastCall):
119 """
120 Precondition: This should be called after visiting copied function body.
121 This is used for GrFN 2.2 generation.
123 Aliases highest version variables from the function body to
124 `VAR_EXIT_VERSION` of calling container sccope.
125 """
126 func_def_copy = node.func_def_copy
127 call_con_scopestr = con_scope_to_str(
128 node.func.con_scope + [call_container_name(node)]
129 )
130 func_con_scopestr = con_scope_to_str(func_def_copy.con_scope)
132 # alias `VAR_EXIT_VERSION` variables in call_con_scopestr
133 # to the highest version occuring the func body
134 exit_version = VAR_EXIT_VERSION
135 for id, var_name in node.bot_interface_vars.items():
136 body_version = func_def_copy.body_highest_var_vers[id]
137 body_fullid = build_fullid(
138 var_name, id, body_version, func_con_scopestr
139 )
140 exit_fullid = build_fullid(
141 var_name, id, exit_version, call_con_scopestr
142 )
143 self.pipeline_state.alias_grfn_vars(exit_fullid, body_fullid)
145 def alias_if_expr_highest_vers(self, node: AnnCastModelIf):
146 """
147 Precondition: This should be called after visiting if-expr.
149 Aliases highest version variables from the if expr to both
150 - `VAR_INIT_VERSION` of if-body variables
151 - `VAR_INIT_VERSION` of else-body variables
152 """
153 con_scopestr = con_scope_to_str(node.con_scope)
155 # alias all top_interface_vars in if body and else body to the
156 # highest version GrFN variable from if-expr
157 body_version = VAR_INIT_VERSION
158 for id, var_name in node.top_interface_vars.items():
159 expr_version = node.expr_highest_var_vers[id]
160 expr_scopestr = con_scopestr + CON_STR_SEP + IFEXPR
161 expr_fullid = build_fullid(
162 var_name, id, expr_version, expr_scopestr
163 )
165 for body in [IFBODY, ELSEBODY]:
166 body_scopestr = con_scopestr + CON_STR_SEP + body
167 body_fullid = build_fullid(
168 var_name, id, body_version, body_scopestr
169 )
170 self.pipeline_state.alias_grfn_vars(body_fullid, expr_fullid)
172 def create_grfn_vars_model_if(self, node: AnnCastModelIf):
173 """
174 Create GrFN `VariableNode`s for variables which are accessed
175 or modified by this ModelIf container. This does the following:
177 - creates a version `VAR_INIT_VERSION` GrFN variable of all used variables.
178 These GrFN variables will be used for the `top_interface_out`.
179 - aliases `VAR_INIT_VERSION` of if-expr variables to created `VAR_INIT_VERSION` GrFN variables
180 - for modified variables, creates version `VAR_EXIT_VERSION` GrFN variables to
181 be used for the `decision_out` and `top_interface_in`
182 """
183 con_scopestr = con_scope_to_str(node.con_scope)
185 # by convention, we introduce version `VAR_INIT_VERSION` at the top of the container
186 for id, var_name in node.top_interface_vars.items():
187 version = VAR_INIT_VERSION
188 grfn_var = create_grfn_var(var_name, id, version, con_scopestr)
189 fullid = build_fullid(var_name, id, version, con_scopestr)
190 self.pipeline_state.store_grfn_var(fullid, grfn_var)
191 # create From Source metadata for the GrFN var
192 # See comment above declaration for `FROM_SOURCE_FOR_GE` in annotated_cast.py
193 from_source = (
194 True if self.pipeline_state.FROM_SOURCE_FOR_GE else False
195 )
196 from_source_mdata = generate_from_source_metadata(
197 from_source, VariableCreationReason.TOP_IFACE_INTRO
198 )
199 add_metadata_to_grfn_var(grfn_var, from_source_mdata)
201 # alias VAR_INIT_VERSION expr variables
202 expr_scopestr = con_scopestr + CON_STR_SEP + IFEXPR
203 expr_fullid = build_fullid(var_name, id, version, expr_scopestr)
204 self.pipeline_state.alias_grfn_vars(expr_fullid, fullid)
206 # by convention, we introduce `VAR_EXIT_VERSION` for modified variables
207 # to be used as the output of the Decision node, and input to bot interface
208 for id, var_name in node.bot_interface_vars.items():
209 version = VAR_EXIT_VERSION
210 grfn_var = create_grfn_var(var_name, id, version, con_scopestr)
211 fullid = build_fullid(var_name, id, version, con_scopestr)
212 self.pipeline_state.store_grfn_var(fullid, grfn_var)
213 # create From Source metadata for the GrFN var
214 # See comment above declaration for `FROM_SOURCE_FOR_GE` in annotated_cast.py
215 from_source = (
216 True if self.pipeline_state.FROM_SOURCE_FOR_GE else False
217 )
218 from_source_mdata = generate_from_source_metadata(
219 from_source, VariableCreationReason.BOT_IFACE_INTRO
220 )
221 add_metadata_to_grfn_var(grfn_var, from_source_mdata)
223 def setup_model_if_condition(self, node: AnnCastModelIf):
224 """
225 Creates a GrFN `VariableNode` for the condtion variable of
226 this ModelIf container. Populates the `condition_in` and `condition_out`
227 attributes based on the if expr's used variables and the newly
228 created GrFN condition variable.
229 """
230 if_scopestr = con_scope_to_str(node.con_scope)
231 expr_scopestr = con_scope_to_str(node.con_scope + [IFEXPR])
233 # inputs to condition node are the highest versions of used variables of the expr
234 for id, var_name in node.expr_used_vars.items():
235 highest_ver = node.expr_highest_var_vers[id]
236 fullid = build_fullid(var_name, id, highest_ver, expr_scopestr)
237 node.condition_in[id] = fullid
239 # build condition variable
240 cond_name = make_cond_var_name(if_scopestr)
241 # use new collapsed id
242 cond_id = self.pipeline_state.next_collapsed_id()
243 cond_version = VAR_INIT_VERSION
244 cond_fullid = build_fullid(
245 cond_name, cond_id, cond_version, if_scopestr
246 )
247 cond_var = create_grfn_var(
248 cond_name, cond_id, cond_version, if_scopestr
249 )
250 self.pipeline_state.store_grfn_var(cond_fullid, cond_var)
251 # create From Source metadata for the GrFN var
252 from_source = False
253 from_source_mdata = generate_from_source_metadata(
254 from_source, VariableCreationReason.COND_VAR
255 )
256 add_metadata_to_grfn_var(cond_var, from_source_mdata)
258 # cache condtiional variable
259 node.condition_var = cond_var
261 # ouput of condition node is new condition var
262 node.condition_out[cond_id] = cond_fullid
264 def setup_model_if_decision(self, node: AnnCastModelIf):
265 """
266 Precondition: `setup_model_if_condition` has already been called on this node
268 Populates `decision_in` and `decision_out` attributes of node.
269 Inputs to the decision node are the highest versions of modified variables
270 along if branch and else branch.
271 Outputs are version `VAR_EXIT_VERSION` variables at the if container scope.
273 Note, the condition variable will also have an edge to the Decision node in GrFN,
274 but we do not add it to the `decision_in` dict to make iterating over that
275 dict simpler
276 """
277 if_scopestr = con_scope_to_str(node.con_scope)
278 ifbody_scopestr = con_scope_to_str(node.con_scope + [IFBODY])
279 elsebody_scopestr = con_scope_to_str(node.con_scope + [ELSEBODY])
280 # inputs to decision node are the highest versions in if-body and else-body
281 # of variables modified within if container
282 # NOTE: bot_interface_vars is the same as modified_vars
283 for id, var_name in node.bot_interface_vars.items():
284 if_highest = node.ifbody_highest_var_vers[id]
285 if_fullid = build_fullid(var_name, id, if_highest, ifbody_scopestr)
286 else_highest = node.elsebody_highest_var_vers[id]
287 else_fullid = build_fullid(
288 var_name, id, else_highest, elsebody_scopestr
289 )
290 node.decision_in[id] = {IFBODY: if_fullid, ELSEBODY: else_fullid}
292 # outputs to the decision node are version `VAR_EXIT_VERSION` variables in if container scope
293 out_version = VAR_EXIT_VERSION
294 for id, var_name in node.bot_interface_vars.items():
295 fullid = build_fullid(var_name, id, out_version, if_scopestr)
296 node.decision_out[id] = fullid
298 def create_grfn_vars_loop(self, node: AnnCastLoop):
299 """
300 Create GrFN `VariableNode`s for variables which are accessed
301 or modified by this Loop container. This does the following:
302 - creates a version VAR_INIT_VERSION GrFN variable for all used variables.
303 These GrFN variables will be produced by the `top_interface_out`.
304 Furthermore, they are aliased with loop expr init version variables.
305 - creates a version LOOP_VAR_UPDATED_VERSION GrFN variable for all modified variables.
306 These GrFN variables are used for `top_interface_updated`.
307 - creates a version VAR_EXIT_VERSION GrFN variable for all modified variables
308 These GrFN variables are used for `bot_interface_in`.
309 """
310 con_scopestr = con_scope_to_str(node.con_scope)
312 # create version `VAR_INIT_VERSION` for used variables
313 for id, var_name in node.top_interface_vars.items():
314 version = VAR_INIT_VERSION
315 grfn_var = create_grfn_var(var_name, id, version, con_scopestr)
316 fullid = build_fullid(var_name, id, version, con_scopestr)
317 self.pipeline_state.store_grfn_var(fullid, grfn_var)
318 # create From Source metadata for the GrFN var
319 # See comment above declaration for `FROM_SOURCE_FOR_GE` in annotated_cast.py
320 from_source = (
321 True if self.pipeline_state.FROM_SOURCE_FOR_GE else False
322 )
323 from_source_mdata = generate_from_source_metadata(
324 from_source, VariableCreationReason.TOP_IFACE_INTRO
325 )
326 add_metadata_to_grfn_var(grfn_var, from_source_mdata)
328 # alias VAR_INIT_VERSION expr variables
329 expr_version = VAR_INIT_VERSION
330 expr_scopestr = con_scopestr + CON_STR_SEP + LOOPEXPR
331 expr_fullid = build_fullid(
332 var_name, id, expr_version, expr_scopestr
333 )
334 self.pipeline_state.alias_grfn_vars(expr_fullid, fullid)
336 # create version `LOOP_VAR_UPDATED_VERSION` and `VAR_EXIT_VERSION`
337 # for modified variables (which are the same as bot interface_vars)
338 for id, var_name in node.bot_interface_vars.items():
339 for version in [LOOP_VAR_UPDATED_VERSION, VAR_EXIT_VERSION]:
340 grfn_var = create_grfn_var(var_name, id, version, con_scopestr)
341 fullid = build_fullid(var_name, id, version, con_scopestr)
342 self.pipeline_state.store_grfn_var(fullid, grfn_var)
343 # we intentionally do not add metadata to the GrFN variables here, since
344 # these variables will be aliased to other variables created from Name nodes
345 # and the metadata will be populated from those Name nodes
347 def alias_loop_expr_highest_vers(self, node: AnnCastLoop):
348 """
349 Precondition: This should be called after visiting loop-expr.
351 Aliases highest version variables from the loop expr to both
352 - `VAR_INIT_VERSION` of loop-body variables
353 - `VAR_EXIT_VERSION` of modified variables
354 """
355 con_scopestr = con_scope_to_str(node.con_scope)
357 # alias intial body version for top_interface_vars to the
358 # highest version GrFN variable from loop-expr
359 # if the variable is modified, also alias
360 # exit version to highest version from loop-expr
361 body_version = VAR_INIT_VERSION
362 exit_version = VAR_EXIT_VERSION
363 for id, var_name in node.top_interface_vars.items():
364 expr_version = node.expr_highest_var_vers[id]
365 expr_scopestr = con_scopestr + CON_STR_SEP + LOOPEXPR
366 expr_fullid = build_fullid(
367 var_name, id, expr_version, expr_scopestr
368 )
369 body_scopestr = con_scopestr + CON_STR_SEP + LOOPBODY
370 body_fullid = build_fullid(
371 var_name, id, body_version, body_scopestr
372 )
373 self.pipeline_state.alias_grfn_vars(body_fullid, expr_fullid)
375 if id in node.bot_interface_vars:
376 exit_scopestr = con_scopestr
377 exit_fullid = build_fullid(
378 var_name, id, exit_version, exit_scopestr
379 )
380 self.pipeline_state.alias_grfn_vars(exit_fullid, expr_fullid)
382 def alias_loop_init_highest_vers(self, node: AnnCastLoop):
383 """
384 Precondition: This should be called after visiting loop-init.
386 Aliases highest version variables from the loop init to
387 `LOOP_VAR_UPDATED_VERSION` variables.
388 """
389 con_scopestr = con_scope_to_str(node.con_scope)
391 # alias `LOOP_VAR_UPDATED_VERSION` modified variables
392 # to the highest version occuring the loop body
393 updated_version = LOOP_VAR_UPDATED_VERSION
394 for id, var_name in node.modified_vars.items():
395 init_version = node.init_highest_var_vers[id]
396 init_scopestr = con_scopestr + CON_STR_SEP + LOOPPRE
397 init_fullid = build_fullid(
398 var_name, id, init_version, init_scopestr
399 )
400 updated_fullid = build_fullid(
401 var_name, id, updated_version, con_scopestr
402 )
403 self.pipeline_state.alias_grfn_vars(updated_fullid, init_fullid)
405 def alias_loop_body_highest_vers(self, node: AnnCastLoop):
406 """
407 Precondition: This should be called after visiting loop-body.
409 Aliases highest version variables from the loop body to
410 `LOOP_VAR_UPDATED_VERSION` variables.
411 """
412 con_scopestr = con_scope_to_str(node.con_scope)
414 # alias `LOOP_VAR_UPDATED_VERSION` modified variables
415 # to the highest version occuring the loop body
416 updated_version = LOOP_VAR_UPDATED_VERSION
417 for id, var_name in node.modified_vars.items():
418 body_version = node.body_highest_var_vers[id]
419 body_scopestr = con_scopestr + CON_STR_SEP + LOOPBODY
420 body_fullid = build_fullid(
421 var_name, id, body_version, body_scopestr
422 )
423 updated_fullid = build_fullid(
424 var_name, id, updated_version, con_scopestr
425 )
426 self.pipeline_state.alias_grfn_vars(updated_fullid, body_fullid)
428 def setup_loop_condition(self, node: AnnCastLoop):
429 """
430 Creates a GrFN `VariableNode` for the condtion variable of
431 this Loop container. Populates the `condition_in` and `condition_out`
432 attributes based on the loop expr's used variables and the newly
433 created GrFN condition variable.
434 """
435 loop_scopestr = con_scope_to_str(node.con_scope)
436 expr_scopestr = con_scope_to_str(node.con_scope + [LOOPEXPR])
438 # inputs to condition node are the highest versions of used variables of the expr
439 for id, var_name in node.expr_used_vars.items():
440 highest_ver = node.expr_highest_var_vers[id]
441 fullid = build_fullid(var_name, id, highest_ver, expr_scopestr)
442 node.condition_in[id] = fullid
444 # build condition variable
445 cond_name = make_loop_exit_name(loop_scopestr)
446 # use new collapsed id
447 cond_id = self.pipeline_state.next_collapsed_id()
448 cond_version = VAR_INIT_VERSION
449 cond_fullid = build_fullid(
450 cond_name, cond_id, cond_version, loop_scopestr
451 )
452 cond_var = create_grfn_var(
453 cond_name, cond_id, cond_version, loop_scopestr
454 )
455 # mark the node as an exit
456 cond_var.is_exit = True
457 self.pipeline_state.store_grfn_var(cond_fullid, cond_var)
458 # create From Source metadata for the GrFN var
459 from_source = False
460 from_source_mdata = generate_from_source_metadata(
461 from_source, VariableCreationReason.COND_VAR
462 )
463 add_metadata_to_grfn_var(cond_var, from_source_mdata)
465 # cache condtiional variable
466 node.condition_var = cond_var
468 # ouput of condition node is new condition var
469 node.condition_out[cond_id] = cond_fullid
471 def print_created_grfn_vars(self):
472 print("Created the follwing GrFN variables")
473 print("-" * 50)
474 print(f"{'fullid':<70}{'grfn_id':<70}{'index':<2}")
475 print(f"{'------':<70}{'-------':<70}{'-----':<2}")
476 for fullid, grfn_id in self.pipeline_state.fullid_to_grfn_id.items():
477 grfn_var = self.pipeline_state.grfn_id_to_grfn_var[grfn_id]
478 print(f"{fullid:<70}{grfn_id:<70}{grfn_var.identifier.index:<2}")
480 @singledispatchmethod
481 def _visit(self, node: AnnCastNode):
482 """
483 Internal visit
484 """
485 raise NameError(f"Unrecognized node type: {type(node)}")
487 @_visit.register
488 def visit_assignment(self, node: AnnCastAssignment):
489 self.visit(node.right)
490 # The AnnCastTuple is added to handle scenarios where an assignment
491 # is made by assigning to a tuple of values, as opposed to one singular value
492 assert (
493 isinstance(node.left, AnnCastVar)
494 or (isinstance(node.left, AnnCastLiteralValue) and (node.left.value_type == StructureType.TUPLE))
495 or isinstance(node.left, AnnCastAttribute)
496 ), f"container_scope: visit_assigment: node.left is not AnnCastVar or AnnCastTuple it is {type(node.left)}"
497 self.visit(node.left)
499 @_visit.register
500 def visit_attribute(self, node: AnnCastAttribute):
501 pass
503 @_visit.register
504 def visit_call(self, node: AnnCastCall):
505 if node.is_grfn_2_2:
506 self.visit_call_grfn_2_2(node)
507 return
509 self.visit_node_list(node.arguments)
511 def visit_call_grfn_2_2(self, node: AnnCastCall):
512 assert isinstance(node.func, AnnCastName)
513 # alias GrFN variables before visiting children
514 self.alias_copied_func_body_init_vers(node)
515 self.alias_copied_func_body_highest_vers(node)
517 self.visit_node_list(node.arguments)
518 self.visit_function_def_copy(node.func_def_copy)
520 @_visit.register
521 def visit_record_def(self, node: AnnCastRecordDef):
522 pass
524 def visit_function_def_copy(self, node: AnnCastFunctionDef):
525 self.visit_node_list(node.func_args)
526 self.visit_node_list(node.body)
528 @_visit.register
529 def visit_function_def(self, node: AnnCastFunctionDef):
530 self.visit_node_list(node.func_args)
531 self.visit_node_list(node.body)
533 @_visit.register
534 def visit_goto(self, node: AnnCastGoto):
535 if node.expr != None:
536 self.visit(node.expr)
537 # self.visit(node.label)
539 @_visit.register
540 def visit_label(self, node: AnnCastLabel):
541 # self.visit(node.label)
542 pass
544 @_visit.register
545 def visit_literal_value(self, node: AnnCastLiteralValue):
546 if node.value_type == "List[Any]":
547 # val has
548 # operator - string
549 # size - Var node or a LiteralValue node (for number)
550 # initial_value - LiteralValue node
551 val = node.value
553 # visit size's anncast name node
554 self.visit(val.size)
556 # List literal doesn't need to add any other changes
557 # to the anncast at this pass
559 elif node.value_type == StructureType.TUPLE: # or node.value_type == StructureType.LIST:
560 self.visit_node_list(node.value)
561 elif node.value_type == ScalarType.INTEGER:
562 pass
563 elif node.value_type == ScalarType.ABSTRACTFLOAT:
564 pass
565 pass
567 @_visit.register
568 def visit_loop(self, node: AnnCastLoop):
569 self.create_grfn_vars_loop(node)
570 # if len(node.init) > 0:
571 # self.alias_loop_init_highest_vers(node)
572 self.alias_loop_expr_highest_vers(node)
573 self.alias_loop_body_highest_vers(node)
574 # visit children
575 if len(node.pre) > 0:
576 self.visit_node_list(node.pre)
578 self.visit(node.expr)
579 self.setup_loop_condition(node)
580 self.visit_node_list(node.body)
582 # NOTE: might need to alias loop post
583 if len(node.post) > 0:
584 self.visit_node_list(node.post)
586 @_visit.register
587 def visit_model_break(self, node: AnnCastModelBreak):
588 pass
590 @_visit.register
591 def visit_model_continue(self, node: AnnCastModelContinue):
592 pass
594 @_visit.register
595 def visit_model_import(self, node: AnnCastModelImport):
596 pass
598 @_visit.register
599 def visit_model_if(self, node: AnnCastModelIf):
600 self.create_grfn_vars_model_if(node)
601 # alias highest version vars inside expr to initial body versions
602 self.alias_if_expr_highest_vers(node)
604 # visit expr, then setup condition info
605 self.visit(node.expr)
606 self.setup_model_if_condition(node)
608 self.visit_node_list(node.body)
609 self.visit_node_list(node.orelse)
611 # populate node.decision_in, node.decision_out
612 self.setup_model_if_decision(node)
614 # DEBUG printing
615 if self.pipeline_state.PRINT_DEBUGGING_INFO:
616 print("ModelIf Interface vars")
617 print(f" top_interface_out: {node.top_interface_out}")
618 print(f" bot_interface_out: {node.bot_interface_out}")
620 @_visit.register
621 def visit_model_return(self, node: AnnCastModelReturn):
622 self.visit(node.value)
624 @_visit.register
625 def visit_module(self, node: AnnCastModule):
626 self.visit_node_list(node.body)
628 @_visit.register
629 def visit_name(self, node: AnnCastName):
630 fullid = ann_cast_name_to_fullid(node)
631 # if we haven't already created the GrFN `VariableNode`, create it
632 if fullid not in self.pipeline_state.fullid_to_grfn_id:
633 grfn_var = create_grfn_var_from_name_node(node)
634 self.pipeline_state.store_grfn_var(fullid, grfn_var)
636 # now, store the grfn_id in the nane node
637 node.grfn_id = self.pipeline_state.fullid_to_grfn_id[fullid]
639 # store metdata for GrFN var associated to this Name node
640 grfn_var = self.pipeline_state.get_grfn_var(fullid)
641 add_metadata_from_name_node(grfn_var, node)
643 @_visit.register
644 def visit_operator(self, node: AnnCastOperator):
645 # visit operands
646 self.visit_node_list(node.operands)
648 @_visit.register
649 def visit_set(self, node: AnnCastSet):
650 pass
652 @_visit.register
653 def visit_tuple(self, node: AnnCastTuple):
654 self.visit_node_list(node.values)
656 @_visit.register
657 def visit_var(self, node: AnnCastVar):
658 self.visit(node.val)