systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
utils.py
Go to the documentation of this file.
1"""Utility library"""
2from inspect import currentframe, getframeinfo, stack
3import os
4from lark import Tree
5
6def tidify(verilog, current_indent = 0, indent_width = 2):
7 """makes the generated verilog looks a bit better, may be subject to changes later"""
8 add_indent_pattern = re.compile(r'(^(module|if|always|for|case)|(\: begin))')
9 sub_indent_pattern = re.compile(r'^(endmodule|end)')
10 sub_add_indent_pattern = re.compile(r'^(\‍)\;|end else begin)')
11 res = []
12 for l in verilog.splitlines():
13 if add_indent_pattern.search(l):
14 s = ' ' * (current_indent) + l
15 current_indent += indent_width
16 elif sub_add_indent_pattern.search(l):
17 s = ' ' * (current_indent - indent_width) + l
18 elif sub_indent_pattern.search(l):
19 current_indent -= indent_width
20 s = ' ' * (current_indent) + l
21 else:
22 s = ' ' * current_indent + l
23 # print(s)
24 res.append(s)
25
26 return '\n'.join(res)
27
28
29debug = True
30def p(decorated):
31 """a decorator that helps printing out the transformation results"""
32 if debug:
33 def wrapper(self, args):
34 print(f'[DBG] {decorated.__name__}: \n{args} \n\n')
35 res = decorated(self, args)
36 print(f'[DBG] returns: {res}\n')
37 return res
38 return wrapper
39 else:
40 return decorated
41
42
43def dprint(*arg, **kwargs):
44 """debug utility for printing, prints line number"""
45 frameinfo = currentframe()
46 caller = getframeinfo(stack()[1][0])
47 print(os.path.basename(caller.filename), ': L', frameinfo.f_back.f_lineno, ":", "\u001b[31m", *arg, "\u001b[0m", **kwargs)
48
49def terminate_with_no_trace():
50 assert False
51
52def is_tree_type(t, name):
53 """Check whether t is lark Tree and whether the tree type is name"""
54 return isinstance(t, Tree) and t.data == name
55
56
57def is_tree_types(t, names):
58 """Check whether t is lark Tree and whether the tree type is name"""
59 if not isinstance(names, list):
60 raise ValueError('name argument should be list')
61 return isinstance(t, Tree) and t.data in names
62
63
64def get_ids_in_tree(tree):
65 """get all ids"""
66 __id_types = ['hvarref']
67 if not isinstance(tree, Tree):
68 raise ValueError('Only Tree type is accepted')
69 res = []
70 for t in tree.iter_subtrees():
71 if is_tree_types(t, __id_types):
72 assert t.children[0], 'hvarref should only contain one children'
73 res.append(t.children[0])
74 return res
75
76def get_ids_in_tree_types(tree, types=['hvarref']):
77 """get all ids"""
78 __id_types = types
79 if not isinstance(tree, Tree):
80 raise ValueError('Only Tree type is accepted')
81 res = []
82 for t in tree.iter_subtrees():
83 if is_tree_types(t, __id_types):
84 assert t.children[0], 'hvarref should only contain one children'
85 res.append(t.children[0])
86 return res
87
88
89def get_tree_types(tree, types=['hvarref']):
90 """get all ids"""
91 __id_types = types
92 if not isinstance(tree, Tree):
93 raise ValueError('Only Tree type is accepted')
94 res = []
95 for t in tree.iter_subtrees():
96 if is_tree_types(t, __id_types):
97 res.append(t)
98 return res
99
100def get_ids_in_tree_dfs(tree):
101 """get all ids"""
102 # __id_types = ['hvarref']
103 # if not isinstance(tree, Tree):
104 # raise ValueError('Only Tree type is accepted')
105 # res = []
106 # for t in tree.iter_subtrees():
107 # if is_tree_types(t, __id_types):
108 # assert t.children[0], 'hvarref should only contain one children'
109 # res.append(t.children[0])
110 # return res
111
112 res = []
113 dfs_stack = list()
114 dfs_stack.append(tree)
115 i = 0
116 while len(dfs_stack) != 0:
117 t = dfs_stack.pop(0)
118 for idx in range(len(t.children)):
119 nxt = t.children[idx]
120 if isinstance(nxt, Tree):
121 dfs_stack.append(nxt)
122 elif is_tree_types(t, __id_types):
123 assert t.children[0], 'hvarref should only contain one children'
124 res.append(t.children[0])
125 return res
126
127
128def set_ids_in_tree_dfs(tree, ids):
129 __id_types = ['hvarref']
130 dfs_stack = list()
131 dfs_stack.append(tree)
132 i = 0
133 while len(dfs_stack) != 0:
134 t = dfs_stack.pop(0)
135 for idx in range(len(t.children)):
136 nxt = t.children[idx]
137 if isinstance(nxt, Tree):
138 dfs_stack.append(nxt)
139 elif is_tree_types(t, __id_types):
140 t.children[idx] = ids[i](t.children[idx])
141 i += 1
142
143
144def alternate_ids(tree, ops):
145 """Change the ids within a tree, given operations ops as an array of lambdas"""
146 ids = get_ids_in_tree(tree)
147 if len(ops) != len(ids):
148 raise ValueError('ops should have the same length as ids')
149 for idx, _ in enumerate(ids):
150 ops[idx](ids[idx])
151
152def map_hvarref_ids(tree, ops):
153 """get all and apply mapping function"""
154 __id_types = ['hvarref']
155 if not isinstance(tree, Tree):
156 raise ValueError('Only Tree type is accepted')
157 # res = []
158 idx = 0
159 for t in tree.iter_subtrees():
160 if is_tree_types(t, __id_types):
161 assert len(t.children) == 1, 'hvarref should only contain one children'
162 mapped_token = ops[idx](t.children[0])
163 assert mapped_token, 'mapping function should return a token'
164 t.children[0] = mapped_token
165 idx += 1
166 # res.append(t.children[0])
167
168
169class ContextManager(object):
170 def __init__(self):
171 self.stack = []
172
173 def __getattr__(self, key):
174 if key in self.__dict__:
175 return self.__dict__[key]
176 for d in reversed(self.stack):
177 if key in d:
178 return d[key]
179 return None
180
181 def search_key_in_outer_context(self, key):
182 if len(self.stack) <= 1:
183 return None
184
185 for d in reversed(self.stack[:-1]):
186 if key in d:
187 return d[key]
188 return None
189
190 def add_values(self, **kwargs):
191 self.stack.append(kwargs)
192 return self
193
194 def __enter__(self):
195 return self
196
197 def __exit__(self, type, value, traceback):
198 self.stack.pop()
tidify(verilog, current_indent=0, indent_width=2)
Definition utils.py:6