systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
type_node.py
Go to the documentation of this file.
2class TypeNode(object):
3 """
4 This class represents any type that is present in the _hdl.txt
5 Note: this type is used in two places:
6 1. representing the nested type itself, with typedef, in which it is a tree like structure
7 2. representing the type instantiation, which is only provided with concrete value of type params
8 """
9 def __init__(self, name, params, aliases, fields):
10 """
11 name: type name
12 params: type parameteres, a list of string, in fp_t, this would be E, F
13 aliases: type aliases, used to represent typedef's within a type, in block_header, this would be
14 hType typename FP::expo_t NOLIST
15 fields: a list of (string, TypeNode) tuple, representing the fields, a primitive type should keep this as empty. In fp_t, this would be (frac, ... ), (expo, ... ), (sign, ... )
16 """
17 self.name = name
18 self.params = params
19 self.aliases = aliases
20 self.fieldsfields = fields
21
22
23 # The two function below (bind and build_param_dict)
24 def build_param_dict(self, params):
25 # This is not very efficient - could be improved with topological sorting, but we don't need that
26 # 1. map type parameter to TypeNode
27 type_nodes = []
28 type_resolved = []
29 for k, p in zip(self.params, params):
30 type_nodes.append((k, p))
31 type_resolved.append((k, False))
32 type_nodes = dict(type_nodes)
33 type_resolved = dict(type_resolved)
34 type_resolved_count = 0
35 for k, v in type_nodes.items():
36 if type(v) is not type(self):
37 type_resolved_count += 1
38 # 2. instantiate the types
39 while type_resolved_count != len(type_nodes):
40 for k in type_nodes.keys():
41 if type_resolved[k]:
42 continue
43 else:
44 if len(type_nodes[k].params) == 0:
45 type_nodes[k] = type_nodes[k].instantiate()
46 type_resolved_count += 1
47 else:
48 raise
49 return type_nodes
50
51 def bind(self, param_list, param_dict=None):
52 """
53 if params_dict is not empty, use params_dict, otherwise, first build param dict
54 currently, things like template<E, sc_in<E> > is not supported
55 """
56 param_dict = param_dict or self.build_param_dict(param_list)
57 fields = []
58 for field_name, field_type in self.fieldsfields:
59 if len(field_type.params) > 0:
60 instantiate_list = [ param_dict[p.name] if p.name in param_dict else p.instantiate() for p in field_type.params ]
61 res = field_type.instantiate(params=instantiate_list)
62 fields.append((field_name, res))
63 else:
64 fields.append((field_name, field_type.instantiate()))
65 fields = [ (str(field[0]), field[1]) for field in fields ]
66 return aggregate(params=None, fields=fields)
67
68 def instantiate(self, params=None):
69 # create an object with to_str for the classes
70 primitive_type = Primitive.get_primitive(self.name)
71 is_int = re.match(r'^[-+]?[0-9]+$', self.name)
72 # print('Instantiating: ', self.name, ' with ', params)
73
74 if primitive_type:
75 if params is None:
76 res = primitive_type(*list(map(lambda x: x.instantiate(), self.params)))
77 else:
78 res = primitive_type(*list(params))
79 return res
80 elif is_int:
81 return int(self.name)
82 else:
83 # Non-primitive type, like fp_t
84 res = aggregate(params, self.fieldsfields)
85 assert CType.types.is_custom_type(self.name), f'{self.name} is not a custom type'
86 t = CType.types.get_custom_type(self.name)
87 return t.bind(param_list=self.params)
88
89 # Use this class as a metaclass and register other types?
90
91
bind(self, param_list, param_dict=None)
Definition type_node.py:51
__init__(self, name, params, aliases, fields)
Definition type_node.py:9