systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
typedef_expansion.py
Go to the documentation of this file.
1import itertools
2from .top_down import TopDown
3from ..primitives import Primitive
4from .node import TypeDefType
5from ..compound import aggregate
6from lark import Tree, Token
7import copy
8import warnings
9from ..utils import dprint, is_tree_type, get_ids_in_tree, alternate_ids, get_tree_types, set_ids_in_tree_dfs, map_hvarref_ids, ContextManager
10
11
13 """Expands block assignment of custom types into primitive types"""
14 def __init__(self, types):
15 super().__init__()
17 # expanded is the variable stack
18 self.expanded = [dict()]
20
21 def __expand_htype(self, htype):
22 """expand non-primitive htype into primitive sub-field type"""
23 # Note: expansion will stop at custom type boundary,
24 # futher nested type expansion will be handled in the TypeDefType expansion
25 assert htype.data == 'htype'
26 # depth first search, use non-recursive version to better handle copy of the node
27 stack = list()
28 stack.append(htype)
29 expandable = 0
30 while stack:
31 stack_top = stack.pop()
32 assert stack_top.data == 'htype'
33 type_name, *type_params = stack_top.children
34 if type_name in self.typestypestypestypes:
35 expandable += 1
36 fields = self.typestypestypestypes[type_name].get_fields_with_instantiation(type_params, self.typestypestypestypes)
37 else:
38 # expand other htype fields
39 for child in type_params:
40 if isinstance(child, Tree):
41 stack.append(child)
42
43 if expandable == 0:
44 return [('', htype)] # no expansion required
45 elif expandable == 1:
46 res = []
47 for k, v in fields:
48 new_type = copy.deepcopy(htype)
49 stack.append(new_type)
50 while stack:
51 stack_top = stack.pop()
52 type_name, *type_params = stack_top.children
53 if type_name in self.typestypestypestypes: # this is the only type that gets expanded
54 stack_top.children = v.children
55 else:
56 for child in type_params:
57 if isinstance(child, Tree):
58 stack.append(child)
59 res.append((k, new_type))
60 return res
61 else:
62 assert False, 'Cannot expand more than 1 custom type'
63
64 def __expand_typeinfo(self, typeinfo):
65 assert typeinfo.data == 'htypeinfo'
66 assert len(typeinfo.children) == 1
67 res = self.__expand_htype(typeinfo.children[0])
68 # reconstruct typeinfo
69 return [(x[0], Tree(typeinfo.data, [x[1]], typeinfo.meta)) for x in res]
70
71 def __expand_helper(self, portdecl, typeinfo):
72 """portdecl is the name:
73 Tree(outportdecl, [Token(ID, 'dout')])
74 typeinfo is the real type info:
75 Tree(htypeinfo, [Tree(htype, [Token(TYPESTR, 'sc_out'), Tree(htype, [Token(TYPESTR, 'fp_t'), 52, 11])])])
76 """
77 res = self.__expand_typeinfo(typeinfo)
78 res_types = []
79 for suffix, tpe in res:
80 children = []
81 for x in portdecl.children:
82 # keep to newly generated name to be a token
83 new_token = copy.deepcopy(x)
84 new_token = new_token.update(value=new_token.value + ('_' + suffix if suffix else ''))
85 children.append(new_token)
86 port = Tree(portdecl.data, children, portdecl.meta)
87 res_types.append([port, tpe])
88 return res_types
89
90 def __expand_portdecltype(self, tree):
91 """The expansion is achieved by first traverse the type subtree to detect the expandable type,
92 then, any parent path is duplicated
93 An example of tree:
94 Tree(portdecltype, [Tree(inportdecl, [Token(ID, 'clk')]), Tree(htypeinfo,
95 [Tree(htype, [Token(TYPESTR, 'sc_in'), Tree(htype, [Token(TYPESTR, '_Bool')])])])])
96 """
97 assert len(tree.children) == 2
98 expanded_ports = self.__expand_helper(tree.children[0], tree.children[1])
99 res = [Tree(tree.data, x, tree.meta) for x in expanded_ports]
100 return res
101
102 def __expand_vardecltype(self, tree):
103 assert tree.data in ['vardeclinit', 'funcparami', 'funcparamio']
104 if len(tree.children) == 2:
105 # the case without initial value
106 expanded_ports = self.__expand_helper(Tree('stub', [tree.children[0]]), tree.children[1])
107 expanded_ports = [[var.children[0], tpe] for var, tpe in expanded_ports]
108 res = [Tree(tree.data, x, tree.meta) for x in expanded_ports]
109 return res
110 elif len(tree.children) == 3:
111 # This case expands the vardecltype with initial value
112 expanded_type = self.__expanded_type(tree.children[0])
113 if expanded_type is None:
114 return [tree]
115 # the case with initial value, and it might be expanded
116 # this is similar to blkassign
117 new_node = copy.copy(tree)
118 new_node.children = tree.children[0:3:2]
119 # a hack to re-use the __expand_blkassign and __expand_helper
120 # a formal way would be to abstract this into a assign-like top class
121 new_node.children[0] = Tree('hliteral', children=[new_node.children[0]])
122 # print(new_node)
123 res = self.__expand_blkassign(new_node)
124 decls = self.__expand_helper(new_node.children[0], Tree(data='htypeinfo', children=[expanded_type]))
125 for x in zip(decls, res):
126 var_name_decl, var_type = x[0]
127 var_name, init_val = x[1].children
128 # print('Testing: ')
129 # print('var_name_decl: ', var_name_decl)
130 assert var_name_decl == var_name
131 x[1].children[0] = x[1].children[0].children[0]
132 x[1].children.insert(1, var_type)
133 # print(res)
134 return res
135 else:
136 assert False, 'vardeclinit/funcparami/funcparamio should contain 2 or 3 sub-trees'
137
138 def __expand_sigdecltype(self, tree):
139 return self.__expand_portdecltype(tree)
140
141 def hsensvars(self, tree):
142 """expand identifiers in sensitivity list with fields"""
143 self.__push_up(tree)
144 new_children = []
145 for sense_var in tree.children:
146 var_type = self.__expanded_type(sense_var)
147 # dprint(sense_var, self.__expanded_type(sense_var))
148 if var_type:
149 var_type = self.__get_expandable_type_from_htype(var_type)
150 type_name = var_type.children[0]
151 type_params = var_type.children[1:]
152 tpe = self.typestypestypestypes[type_name]
153 fields = tpe.get_fields_with_instantiation(type_params, self.typestypestypestypes)
154 for field_name, _ in fields:
155 new_children.append(sense_var + '_' + field_name)
156 else:
157 new_children.append(sense_var)
158 tree.children = new_children
159 return tree
160
161 def hnamedsensvar(self, tree):
162 """expand identifiers in sensitivity list with fields"""
163 self.__push_up(tree)
164 res = []
165 # there will only be one sense var for thjis node
166 sense_var = tree.children[1]
167 sense_var = get_ids_in_tree(sense_var)[0]
168 var_type = self.__expanded_type(sense_var)
169
170 # we will have to duplicate this node multiple times
171 if var_type:
172 var_type = self.__get_expandable_type_from_htype(var_type)
173 type_name = var_type.children[0]
174 type_params = var_type.children[1:]
175 tpe = self.typestypestypestypes[type_name]
176 fields = tpe.get_fields_with_instantiation(type_params, self.typestypestypestypes)
177
178
179 # we need to modify the id so that, so that the array reference is
180 # expanded correctly
181 for field_name, _ in fields:
182 new_child = copy.deepcopy(tree)
183 varrefs = get_tree_types(new_child, ['hvarref'])
184 for vars in varrefs:
185 if vars.children[0].value == sense_var.value:
186 vars.children[0] = Token('ID', sense_var.value + '_' + field_name)
187 res.append(new_child)
188 return res
189 return tree
190
191 def modportsiglist(self, tree):
192 self.__push_up(tree)
193 new_children = []
194 # print('Mod Port Sig List')
195 for node in tree.children:
196 if node.data == 'portdecltype':
197 var_name = node.children[0].children[0]
198 var_type = node.children[1].children[0]
199 var_type_name = var_type.children[1].children[0]
200 if var_type_name in self.typestypestypestypes:
201 self.__set_expanded(var_name, var_type)
202 new_children.extend(self.__expand_portdecltype(node))
203 elif node.data == 'sigdecltype':
204 var_name = node.children[0].children[0]
205 var_type = node.children[1].children[0]
206 # dprint(var_name)
207 # dprint(var_type)
208 var_tokens = map(lambda x:
209 filter(lambda y: isinstance(y, str), x.children),
210 var_type.iter_subtrees_topdown())
211 for var_type_name in itertools.chain.from_iterable(var_tokens):
212 if var_type_name in self.typestypestypestypes: # detect the first type that is in the typedef list
213 self.__set_expanded(var_name, var_type)
214 break
215 new_children.extend(self.__expand_sigdecltype(node))
216 else:
217 # for vardeclinit, the structure is slightly different
218 # no expansion for now
219 var_name = node.children[0]
220 var_type = node.children[1].children[0]
221 var_tokens = map(lambda x:
222 filter(lambda y: isinstance(y, str), x.children),
223 var_type.iter_subtrees_topdown())
224 type_name = var_type.children[0]
225 # dprint(node)
226 if not Primitive.get_primitive(type_name) and not type_name in self.typestypestypestypes:
227 # dprint(tree)
228 # module instantiate
229 new_children.append(Tree('moduleinst', node.children, node.meta))
230 # dprint(new_children[-1])
231 # assert False
232 continue
233 if type_name == 'array':
234 # array of module instantiations
235 sub_type_name = var_type.children[1].children[0]
236 if not Primitive.get_primitive(sub_type_name) and not sub_type_name in self.typestypestypestypes:
237 # inst_name, module_name, array_size
238 # NOTE: here we are trying to instantiate a module array
239 # But we don't want to unroll the array
240 new_node = Tree('modulearrayinst', node.children, node.meta)
241 new_children.append(new_node)
242 # inst_arr_name = node.children[0]
243 # n_inst = var_type.children[2][0]
244 # inst_type = Tree('htypeinfo', children=[var_type.children[1]])
245 # for i in range(n_inst):
246 # inst_name = inst_arr_name + '#' + str(i)
247 # new_children.append(Tree('moduleinst', [inst_name, inst_type], node.meta))
248 continue
249 array_of_typedef = False
250 for var_type_name in itertools.chain.from_iterable(var_tokens):
251 if var_type_name in self.typestypestypestypes: # detect the first type that is in the typedef list
252 self.__set_expanded(var_name, var_type)
253 break
254 elif var_type_name == "array":
255 continue
256 res = self.__expand_vardecltype(node)
257 new_children.extend(res)
258 # original type
259 # print('Var Name: ', var_name)
260 # print('Var Type: ', var_type)
261 # print()
262 tree.children = new_children
263 # print('---')
264 # for node in tree.children:
265 # print(node)
266 return tree
267
269 # returns the first expandable sub-tree
270 for subtree in htype.iter_subtrees_topdown():
271 if isinstance(subtree, Tree) and subtree.data == 'htype' and subtree.children[0] in self.typestypestypestypes:
272 return subtree
273 return None
274
276 assert isinstance(tree, Tree)
277 if tree.data in ['hliteral', 'hvarref']:
278 var_name = tree.children[0]
279 if self.__expanded_type(var_name):
280 return var_name
281 elif tree.data == 'harrayref':
282 # TODO: support for multi-dimension array
283 # Special cases for handling hSigAssignR as array reference
284 if tree.children[0].data == 'hsigassignr':
285 var_name = tree.children[1].children[0]
286 else:
287 var_name = tree.children[0].children[0]
288 if self.__expanded_type(var_name):
289 return var_name
290 elif tree.data == 'hbinop' and tree.children[0] == 'ARRAYSUBSCRIPT': # simmilar to array ref
291 var_name = tree.children[1].children[0]
292 if self.__expanded_type(var_name):
293 return var_name
294 elif tree.data == 'hvarref':
295 var_name = tree.children[0]
296 if self.__expanded_type(var_name):
297 return var_name
298 elif tree.data == 'syscread':
299 # this is only used in statement vardeclinit
300 # syscread can also be performed on hararyref
301 assert tree.children[1].data in ['hliteral', 'hvarref', 'harrayref'], f'Actual: {tree.children[1].data} ({tree})'
302 if tree.children[1].data in ['harrayref']:
303 var_name = self.__get_expandable_var_from_tree(tree.children[1])
304 else:
305 var_name = tree.children[1].children[0]
306 if self.__expanded_type(var_name):
307 return var_name
308 elif tree.data == 'hvarinitlist':
309 # RHS is a list of variable
310 new_children = []
311 for element in tree.children:
312 new_children.append(self.__get_expandable_var_from_tree(element))
313 return new_children
314 return None
315
316 def __append_to_expandable_var_to_tree(self, tree, field_name):
317 """append the field_name to the expandable variable in tree"""
318 # TODO: the self.__expanded_type is excessive
319 assert isinstance(tree, Tree)
320 if tree.data in ['hliteral', 'hvarref']:
321 var_name = tree.children[0]
322 if self.__expanded_type(var_name):
323 tree.children[0] = var_name + '_' + field_name
324 elif tree.data == 'harrayref':
325 var_name = tree.children[0].children[0]
326 if self.__expanded_type(var_name):
327 tree.children[0].children[0] = var_name + '_' + field_name
328 elif tree.data == 'hbinop' and tree.children[0] == 'ARRAYSUBSCRIPT':
329 var_name = tree.children[1].children[0]
330 if self.__expanded_type(var_name):
331 tree.children[1].children[0] = var_name + '_' + field_name
332 elif tree.data == 'syscread':
333 assert tree.children[1].data in ['hliteral', 'hvarref', 'harrayref']
334 if tree.children[1].data in ['harrayref']:
335 var_name = self.__get_expandable_var_from_tree(tree.children[1])
336 else:
337 var_name = tree.children[1].children[0]
338 if self.__expanded_type(var_name):
339 tree.children[1].children[0] = var_name + '_' + field_name
340 elif tree.data == 'hvarinitlist':
341 for t in tree.children:
342 self.__append_to_expandable_var_to_tree(t, field_name)
343
344 def __is_all_none(self, v):
345 """checks if v is None or is a (nested) list containing only none"""
346 if v is None:
347 return True
348 if type(v) == list:
349 return all(map(lambda e: self.__is_all_none(e), v))
350 return False
351
352
353 def __expand_blkassign(self, tree):
354 """detects the expandable variable on lhs and rhs and
355 expand them with the fields"""
356 # Note: we only need fields here, and we don't need the actual type
357 lhs, rhs = tree.children
358 # if lhs.children[0] == 'ts_mc_proc_local_2':
359 # assert False
360 # dprint('LHS ', lhs)
361 # dprint('RHS ', rhs, tree.data)
362 lhs_var = self.__get_expandable_var_from_tree(lhs)
363 rhs_var = self.__get_expandable_var_from_tree(rhs)
364 # dprint('LHS var ', lhs_var)
365 # dprint('isallnone ', self.__is_all_none(rhs_var))
366 if lhs_var is not None and (not self.__is_all_none(rhs_var) or rhs.data == 'hliteral') and (rhs_var is not None or rhs.data == 'hliteral'):
367 lhs_expanded_type = self.__expanded_type(lhs_var)
368 assert lhs_expanded_type is not None, '{} should have expanded type'.format(lhs_var)
369 lhs_type = self.__get_expandable_type_from_htype(lhs_expanded_type)
370 # dprint(rhs_var)
371 if isinstance(rhs_var,list):
372 rhs_type = self.__get_expandable_type_from_htype(self.__expanded_type(rhs_var[0]))
373 if lhs_type.children[0] != rhs_type.children[0]:
374 raise RuntimeError('Type does not match between LHS and RHS')
375 for remaining_rhs_var in rhs_var:
376 rhs_var_type = self.__get_expandable_type_from_htype(self.__expanded_type(remaining_rhs_var))
377 if rhs_type.children[0] != rhs_var_type.children[0]:
378 raise RuntimeError('Type does not match among RHS elements')
379 elif rhs.data != 'hliteral':
380 rhs_type = self.__get_expandable_type_from_htype(self.__expanded_type(rhs_var))
381 # dprint(rhs_type)
382 if lhs_type.children[0] != rhs_type.children[0]:
383 raise RuntimeError('Type does not match between LHS and RHS')
384 else:
385 # warnings.warn('Treating CXXDefaultArgExpr as 0')
386 assert rhs.data == 'hliteral'
387 type_name = lhs_type.children[0]
388 type_params = lhs_type.children[1:]
389 tpe = self.typestypestypestypes[type_name]
390 fields = tpe.get_fields_with_instantiation(type_params, self.typestypestypestypes)
391 res = []
392 for field_member, _ in fields:
393 new_assign = copy.deepcopy(tree)
394 if tree.data == 'blkassign':
395 new_assign.must_block = tree.must_block
396 assert type(new_assign.must_block) == type(False)
397 new_lhs, new_rhs = new_assign.children
398 self.__append_to_expandable_var_to_tree(new_lhs, field_member)
399 if rhs.data == 'hliteral':
400 new_assign.children[1] = Tree('hliteral', [0], meta=rhs.meta)
401 else:
402 self.__append_to_expandable_var_to_tree(new_rhs, field_member)
403 res.append(new_assign)
404 # dprint(res)
405 return res
406 elif lhs_var is None and self.__is_all_none(rhs_var):
407 return [tree]
408 elif lhs_var is not None and self.__is_all_none(rhs_var):
409 return [tree]
410 else:
411 raise RuntimeError('Error while expanding blkassign, LHS and RHS expandability does not match')
412
413
414
415 def __expanded_type(self, var_name):
416 for d in reversed(self.expanded):
417 if var_name in d:
418 return d[var_name]
419 return None
420
421 def __set_expanded(self, var_name, var_type):
422 if self.__expanded_type(var_name):
423 raise RuntimeError('Duplicate variable ', var_name)
424 self.expanded[-1][var_name] = var_type
425
426 def hprocess(self, tree):
427
428 """add another scope for a process"""
429 with self.ctx.add_values(current_process=tree.children[0]):
430 self.expanded.append(dict())
431 self.__push_up(tree)
432 self.expanded.pop()
433 # if self.ctx.current_module == 'encode_stream_sc_module_8':
434 # dprint(tree.pretty())
435 # assert False
436 return tree
437
438 def hfunction(self, tree):
439 self.expanded.append(dict())
440 self.__push_up(tree)
441 self.expanded.pop()
442 return tree
443
444 def hfunctionparams(self, tree):
445 # self.expanded.append(dict())
446 self.__push_up(tree)
447 tree.children = self.__expand_decl_in_tree_children(tree, ['funcparami', 'funcparamio'])
448 # self.expanded.pop()
449 return tree
450
451 def hmethodcall(self, tree):
452 self.__push_up(tree)
453 new_children = []
454 for sense_var in tree.children[1:]:
455 # add case for function call on array member
456 var_name = self.__get_expandable_var_from_tree(sense_var)
457 var_type = self.__expanded_type(var_name)
458 # dprint(var_name, self.__expanded_type(var_name))
459 if var_type:
460 var_type = self.__get_expandable_type_from_htype(var_type)
461 type_name = var_type.children[0]
462 type_params = var_type.children[1:]
463 tpe = self.typestypestypestypes[type_name]
464 fields = tpe.get_fields_with_instantiation(type_params, self.typestypestypestypes)
465 for field_name, _ in fields:
466 new_sense_var = copy.deepcopy(sense_var)
467 self.__append_to_expandable_var_to_tree(new_sense_var, field_name)
468 # dprint("Origina...", var_name + '_' + field_name)
469 # dprint(new_sense_var)
470 # new_children.append(var_name + '_' + field_name)
471 new_children.append(new_sense_var)
472 else:
473 new_children.append(sense_var)
474 tree.children[1:] = new_children
475 return tree
476
477 def vardecl(self, tree):
478 """for variable expansion in statement"""
479 self.__push_up(tree)
480 tree.children = self.__expand_decl_in_tree_children(tree)
481 return tree
482
483 def hfunctionlocalvars(self, tree):
484 self.__push_up(tree)
485 tree.children = self.__expand_decl_in_tree_children(tree)
486 return tree
487
488 def __expand_decl_in_tree_children(self, tree, expand_data=None):
489 if expand_data is None:
490 expand_data = ['vardeclinit']
491 new_children = []
492 for node in tree.children:
493 if node.data in expand_data:
494 var_name = node.children[0]
495 var_type = node.children[1].children[0]
496 var_tokens = map(lambda x:
497 filter(lambda y: isinstance(y, str), x.children),
498 var_type.iter_subtrees_topdown())
499 type_name = var_type.children[0]
500 if 'funcparamio' in expand_data:
501 # dprint(var_name, var_type, type_name)
502 pass
503 if not Primitive.get_primitive(type_name) and not type_name in self.typestypestypestypes:
504 # module instantiate
505 assert False, 'Type {} not found or module instantiation cannot reside in process: {}, {}'.format(type_name, var_name, type_name)
506 for var_type_name in itertools.chain.from_iterable(var_tokens):
507 if var_type_name in self.typestypestypestypes: # detect the first type that is in the typedef list
508 self.__set_expanded(var_name, var_type)
509 break
510 res = self.__expand_vardecltype(node)
511 new_children.extend(res)
512 else:
513 new_children.append(node)
514 return new_children
515
516 def hmodinitblock(self, tree):
517 """
518 expands the hmodinitblock
519 hmodinitblock includes a initialization block and portdecl block, both of which can include
520 aggregated types
521 """
523 self.__push_up(tree)
525 return tree
526
527 # def stmt(self, tree):
528 # # TODO: expand blkassign for aggregated types
529 # assert False
530 # if self.ctx.current_module == 'encode_stream_sc_module_8':
531 # assert False
532 # self.__push_up(tree)
533 # new_children = []
534 # # dprint(tree.pretty())
535 # for ch in tree.children:
536 # if isinstance(ch, list):
537 # new_children.append(ch)
538 # elif ch.data == 'blkassign':
539 # res = self.__expand_blkassign(ch)
540 # new_children.extend(res)
541 # else:
542 # new_children.append(ch)
543 # tree.children = new_children
544 # return tree
545
546 def stmts(self, tree):
547 # if self.ctx.current_module == 'encode_stream_sc_module_8':
548 # tree.children = self.visit_children(tree)
549 # import pdb; pdb. set_trace()
550 # dprint(tree)
551 # assert False
552 # import pdb; pdb. set_trace()
553 self.__push_up(tree)
554
555 # assert False
556
557 # assert False
558 # if not self.is_in_initblock:
559 # return tree
560
561 # we might need to flatten port binidngs
562 new_children = []
563 for child in tree.children:
564 if isinstance(child, list):
565 new_children.extend(child)
566 else:
567 new_children.append(child)
568 tree.children = new_children
569 return tree
570
571 def forbody(self, tree):
572 self.__push_up(tree)
574 return tree
575 new_children = []
576 for ch in tree.children:
577 if isinstance(ch, list):
578 new_children.extend(ch)
579 else:
580 new_children.append(ch)
581 tree.children = new_children
582 return tree
583
584
586 assert stmt.data == 'stmt'
587 # portbinding is the only child
588 if len(stmt.children) == 1 and stmt.children[0].data == 'portbinding':
589 return True
590 return False
591
592 def stmt(self, tree):
593 is_portbinding = self.__check_stmt_portbinding(tree)
594 self.__push_up(tree)
595 if not self.is_in_initblockis_in_initblock or not is_portbinding:
596 # self.__push_up(tree)
597 new_children = []
598 # dprint(tree.pretty())
599 for ch in tree.children:
600 if isinstance(ch, list):
601 # new_children.append(ch)
602 new_children.extend(ch)
603 elif ch.data == 'blkassign':
604 res = self.__expand_blkassign(ch)
605 new_children.extend(res)
606 else:
607 new_children.append(ch)
608 tree.children = new_children
609 return tree
610
611 # portbinding
612
613 assert len(tree.children) == 1
614 new_children = tree.children[0]
615 tree.children = []
616 res = [
617 copy.deepcopy(tree)
618 for child in new_children
619 ]
620 for r, ch in zip(res, new_children):
621 r.children = [ch]
622 return res
623
624
625
626 def portbinding(self, binding):
627
628 new_bindings = []
629 mod_name, sub, par = binding.children
630 sub_v = sub.children[0]
631 if is_tree_type(par, 'hbindingarrayref'):
632 par_v = get_ids_in_tree(par)[0]
633 else:
634 par_v = par.children[0]
635 par_v_query = par_v.value.replace('##', '_')
636 typeinfo = self.__expanded_type(par_v_query)
637 if typeinfo: # if the bindinding is on a customized type
638 type_name = self.__get_expandable_type_from_htype(typeinfo).children[0]
639 tpe = self.typestypestypestypes[type_name]
640 b = []
641 for field in tpe.fields:
642 new_sub = copy.deepcopy(sub)
643 new_par = copy.deepcopy(par)
644
645 # TODO: this doesn't seem good, should have a more general wrapper
646 # def __alternate(x):
647 # assert isinstance(x, Token)
648 # x.value += '_' + field.children[0]
649
650 # alternate_ids(new_sub, [__alternate])
651 # alternate_ids(new_par, [__alternate])
652
653 def __map(x):
654 assert isinstance(x, Token)
655 return Token("ID", x.value + '_' + field.children[0], x.pos_in_stream, x.line, x.column)
656
657 map_hvarref_ids(new_sub, [__map])
658 map_hvarref_ids(new_par, [__map])
659 # new_sub.children[0].value += '_' + field.children[0]
660 # new_par.children[0].value += '_' + field.children[0]
661
662 new_binding = copy.copy(binding)
663 new_binding.children = [mod_name, new_sub, new_par]
664 b.append(new_binding)
665 new_bindings.extend(b)
666 else:
667 new_bindings.append(binding)
668
669 # if self.ctx.current_module == 'rvfifo_cc_sc_module_9':
670 # dprint(new_bindings)
671 return new_bindings
672
673 def portbindinglist(self, tree):
674 if self.ctx.current_module == 'rvfifo_cc_sc_module_9':
675 assert False
676 # TODO: deadcode, we need to remove this
677 module_name, *bindings = tree.children
678 new_bindings = []
679 for binding in bindings:
680 mod_name, sub, par = binding.children
681 sub_v = sub.children[0]
682 if is_tree_type(par, 'hbindingarrayref'):
683 par_v = get_ids_in_tree(par)[0]
684 else:
685 par_v = par.children[0]
686 typeinfo = self.__expanded_type(par_v.value)
687 if typeinfo: # if the bindinding is on a customized type
688 type_name = self.__get_expandable_type_from_htype(typeinfo).children[0]
689 tpe = self.typestypestypestypes[type_name]
690 b = []
691 for field in tpe.fields:
692 new_sub = copy.deepcopy(sub)
693 new_par = copy.deepcopy(par)
694
695 # TODO: this doesn't seem good, should have a more general wrapper
696 def __alternate(x):
697 x.value += '_' + field.children[0]
698
699 alternate_ids(new_sub, [__alternate])
700 alternate_ids(new_par, [__alternate])
701 # new_sub.children[0].value += '_' + field.children[0]
702 # new_par.children[0].value += '_' + field.children[0]
703 new_binding = copy.copy(binding)
704 new_binding.children = [mod_name, new_sub, new_par]
705 b.append(new_binding)
706 new_bindings.extend(b)
707 else:
708 new_bindings.append(binding)
709 tree.children = [module_name, new_bindings]
710 return tree
711
712 def hsenslist(self, tree):
713 self.__push_up(tree)
714 new_children = []
715 # tree.children[0] is the proc_name
716 for sense_var in tree.children[1:]:
717 # var_name = sense_var.children[0].children[0] # hvarref
718 var_ids = get_ids_in_tree(sense_var.children[0])
719 if len(var_ids) != 1:
720 raise ValueError('Sensitivity variable should only have one ID')
721 var_name = var_ids[0]
722 var_type = self.__expanded_type(var_name)
723
724 if var_type:
725 var_type = self.__get_expandable_type_from_htype(var_type)
726 type_name = var_type.children[0]
727 type_params = var_type.children[1:]
728 tpe = self.typestypestypestypes[type_name]
729 fields = tpe.get_fields_with_instantiation(type_params, self.typestypestypestypes)
730
731 def __alternate(x, y):
732 return x + '_' + y
733
734 for field_name, _ in fields:
735 new_sense_var = copy.deepcopy(sense_var)
736 # alternate_ids(new_sense_var, [lambda x: __alternate(x, field_name)])
737 set_ids_in_tree_dfs(new_sense_var, [lambda x: __alternate(x, field_name)])
738 new_children.append(new_sense_var)
739
740 else:
741 new_children.append(sense_var)
742 tree.children[1:] = new_children
743 return tree
744
745 def hmodule(self, tree):
746 """add another scope for a module"""
747 with self.ctx.add_values(current_module=tree.children[0]):
748 self.expanded.append(dict())
749 self.__push_up(tree)
750 self.expanded.pop()
751 return tree
__push_up(self, current_node)
Definition top_down.py:29
# detect the first type that is in the typedef list types
# this is the only type that gets expanded types