1"""collect function declaration information and invocation information in processes"""
5from ..utils
import dprint, is_tree_type, is_tree_types
6from ..grammar
import UnexpectedHCodeStructureError
7from .name_stub
import ProcessVarNameStub
8from warnings
import warn
9from pprint
import pprint
10from copy
import deepcopy
15 This pass tags inout IDs assigned within the function parameters and marks the position of the inout params.
16 These information is useful for the next pass which translates the functions and their invocations
32 @current_module_function_nodes.setter
40 @current_process_function_invocations.setter
61 raise ValueError(
'Current scope is not set')
63 @current_function_assignments.setter
69 tree.function_invocations = []
78 tree.function_invocations = []
93 tree.func_param_var_name = []
94 for idx, param
in enumerate(tree.children):
95 var_name = param.children[0]
96 if param.data ==
'funcparamio':
98 tree.io_params.append((idx, var_name))
99 tree.func_param_var_name.append(var_name)
103 tree.local_var_name = []
104 for var_decl
in tree.children:
105 tree.local_var_name.append(var_decl.children[0])
109 self.__push_back(tree)
113 if hasattr(tree,
'func_repl_id'):
120 delattr(tree,
'func_repl_id')
125 array_ref = tree.children[0]
127 array_ref.func_repl_id =
True
128 delattr(tree,
'push_down')
133 array_ref = tree.children[0]
135 array_ref.func_repl_id =
True
141 func_repl_id being true means that this ID should be replaced by another name,
142 because the ID crosses the boundary of parameters and need special handlings for
143 blocking/non-blocking assignments
145 lhs = tree.children[0]
147 lhs.func_repl_id =
True
158 tree.function_invocations = []
162 func_name = tree.children[0]
167 for child
in tree.children[1:]:
168 if child.data ==
'hfunctionparams':
170 elif child.data ==
'hfunctionrettype':
172 elif child.data ==
'hfunctionlocalvars':
174 elif child.data ==
'hfunctionbody':
187 """Similar to FunctionInfoPass, but this pass collects invocation information"""
197 func_name = tree.children[0]
202 for child
in tree.children[1:]:
203 if child.data ==
'hfunctionparams':
205 elif child.data ==
'hfunctionrettype':
207 elif child.data ==
'hfunctionlocalvars':
209 elif child.data ==
'hfunctionbody':
211 return func_name, ret_type, func_params, local_vars, func_body
219 if f.children[0] == func_name:
224 if f.children[0][:-1] == func_name[:-1]:
226 raise ValueError(f
'Function {func_name} not found')
235 if not allow_failure:
236 raise ValueError(f
'ID {id} not found in current scope')
245 raise ValueError(
'Redefinition of variable')
249 self.
add_id_type(tree.children[0].children[0], tree.children[1])
253 self.
add_id_type(tree.children[0].children[0], tree.children[1])
260 self.
add_id_type(tree.children[0], tree.children[1])
264 self.
add_id_type(tree.children[0], tree.children[1])
268 self.
add_id_type(tree.children[0], tree.children[1])
294 if is_tree_type(arg_node,
'hvarref'):
295 return arg_node.children[0]
296 elif is_tree_types(arg_node, [
'hliteral',
'hbinop',
'hmethodcall',
'syscread',
'hunop',
'hslice']):
297 warn(
'Complex expression or constant used for in/out argument, '
298 'this will cause phantom argument to be created and the output result will be discarded. '
299 'Consider using non-reference or const-reference instead')
301 arg_node.phantom_var = phantom_var
303 elif isinstance(arg_node, str):
305 raise ValueError(
'Unsupported form of function argument')
308 tree.name_stub = dict()
309 tree.phantom_vars = dict()
310 names_to_stub = set()
311 for invoc
in tree.function_invocations:
312 invoc_params = invoc.children[1:]
313 f_name = invoc.children[0]
315 func_name, ret_type, func_params, local_vars, func_body = self.
__extract_func_def(func_node)
316 if func_params
is not None:
317 for idx, param
in func_params.io_params:
318 arg_node = invoc_params[idx]
319 tpe = func_params.children[idx].children[1]
321 if hasattr(arg_node,
'phantom_var'):
322 tree.phantom_vars[name] = tpe
323 names_to_stub.add(name)
326 for nm
in names_to_stub:
329 tree.name_stub[nm] = stub