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

1import typing 

2from functools import singledispatchmethod 

3 

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) 

35 

36 

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) 

45 

46 # DEBUG printing 

47 if self.pipeline_state.PRINT_DEBUGGING_INFO: 

48 self.print_created_grfn_vars() 

49 

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}") 

60 

61 # call internal visit 

62 return self._visit(node) 

63 

64 def visit_node_list(self, node_list: typing.List[AnnCastNode]): 

65 return [self.visit(node) for node in node_list] 

66 

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 ] 

76 

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. 

81 

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) 

90 

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) 

104 

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) 

117 

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. 

122 

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) 

131 

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) 

144 

145 def alias_if_expr_highest_vers(self, node: AnnCastModelIf): 

146 """ 

147 Precondition: This should be called after visiting if-expr. 

148 

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) 

154 

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 ) 

164 

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) 

171 

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: 

176 

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) 

184 

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) 

200 

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) 

205 

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) 

222 

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]) 

232 

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 

238 

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) 

257 

258 # cache condtiional variable 

259 node.condition_var = cond_var 

260 

261 # ouput of condition node is new condition var 

262 node.condition_out[cond_id] = cond_fullid 

263 

264 def setup_model_if_decision(self, node: AnnCastModelIf): 

265 """ 

266 Precondition: `setup_model_if_condition` has already been called on this node 

267 

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. 

272 

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} 

291 

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 

297 

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) 

311 

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) 

327 

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) 

335 

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 

346 

347 def alias_loop_expr_highest_vers(self, node: AnnCastLoop): 

348 """ 

349 Precondition: This should be called after visiting loop-expr. 

350 

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) 

356 

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) 

374 

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) 

381 

382 def alias_loop_init_highest_vers(self, node: AnnCastLoop): 

383 """ 

384 Precondition: This should be called after visiting loop-init. 

385 

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) 

390 

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) 

404 

405 def alias_loop_body_highest_vers(self, node: AnnCastLoop): 

406 """ 

407 Precondition: This should be called after visiting loop-body. 

408 

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) 

413 

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) 

427 

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]) 

437 

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 

443 

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) 

464 

465 # cache condtiional variable 

466 node.condition_var = cond_var 

467 

468 # ouput of condition node is new condition var 

469 node.condition_out[cond_id] = cond_fullid 

470 

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}") 

479 

480 @singledispatchmethod 

481 def _visit(self, node: AnnCastNode): 

482 """ 

483 Internal visit 

484 """ 

485 raise NameError(f"Unrecognized node type: {type(node)}") 

486 

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) 

498 

499 @_visit.register 

500 def visit_attribute(self, node: AnnCastAttribute): 

501 pass 

502 

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 

508 

509 self.visit_node_list(node.arguments) 

510 

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) 

516 

517 self.visit_node_list(node.arguments) 

518 self.visit_function_def_copy(node.func_def_copy) 

519 

520 @_visit.register 

521 def visit_record_def(self, node: AnnCastRecordDef): 

522 pass 

523 

524 def visit_function_def_copy(self, node: AnnCastFunctionDef): 

525 self.visit_node_list(node.func_args) 

526 self.visit_node_list(node.body) 

527 

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) 

532 

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) 

538 

539 @_visit.register 

540 def visit_label(self, node: AnnCastLabel): 

541 # self.visit(node.label) 

542 pass 

543 

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 

552 

553 # visit size's anncast name node 

554 self.visit(val.size) 

555 

556 # List literal doesn't need to add any other changes 

557 # to the anncast at this pass 

558 

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 

566 

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) 

577 

578 self.visit(node.expr) 

579 self.setup_loop_condition(node) 

580 self.visit_node_list(node.body) 

581 

582 # NOTE: might need to alias loop post 

583 if len(node.post) > 0: 

584 self.visit_node_list(node.post) 

585 

586 @_visit.register 

587 def visit_model_break(self, node: AnnCastModelBreak): 

588 pass 

589 

590 @_visit.register 

591 def visit_model_continue(self, node: AnnCastModelContinue): 

592 pass 

593 

594 @_visit.register 

595 def visit_model_import(self, node: AnnCastModelImport): 

596 pass 

597 

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) 

603 

604 # visit expr, then setup condition info 

605 self.visit(node.expr) 

606 self.setup_model_if_condition(node) 

607 

608 self.visit_node_list(node.body) 

609 self.visit_node_list(node.orelse) 

610 

611 # populate node.decision_in, node.decision_out 

612 self.setup_model_if_decision(node) 

613 

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}") 

619 

620 @_visit.register 

621 def visit_model_return(self, node: AnnCastModelReturn): 

622 self.visit(node.value) 

623 

624 @_visit.register 

625 def visit_module(self, node: AnnCastModule): 

626 self.visit_node_list(node.body) 

627 

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) 

635 

636 # now, store the grfn_id in the nane node 

637 node.grfn_id = self.pipeline_state.fullid_to_grfn_id[fullid] 

638 

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) 

642 

643 @_visit.register 

644 def visit_operator(self, node: AnnCastOperator): 

645 # visit operands 

646 self.visit_node_list(node.operands) 

647 

648 @_visit.register 

649 def visit_set(self, node: AnnCastSet): 

650 pass 

651 

652 @_visit.register 

653 def visit_tuple(self, node: AnnCastTuple): 

654 self.visit_node_list(node.values) 

655 

656 @_visit.register 

657 def visit_var(self, node: AnnCastVar): 

658 self.visit(node.val)