2 # (C) Copyright IBM Corporation 2005
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # on the rights to use, copy, modify, merge, publish, distribute, sub
9 # license, and/or sell copies of the Software, and to permit persons to whom
10 # the Software is furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice (including the next
13 # paragraph) shall be included in all copies or substantial portions of the
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 # Ian Romanick <idr@us.ibm.com>
27 from __future__
import print_function
31 class type_node(object):
33 self
.pointer
= 0 # bool
35 self
.signed
= 1 # bool
36 self
.integer
= 1 # bool
38 # If elements is set to non-zero, then field is an array.
42 self
.size
= 0 # type's size in bytes
47 """Return string representation of this type_node."""
64 s
+= "%s " % (self
.name
)
69 class type_table(object):
71 self
.types_by_name
= {}
75 def add_type(self
, type_expr
):
76 self
.types_by_name
[ type_expr
.get_base_name() ] = type_expr
80 def find_type(self
, name
):
81 if name
in self
.types_by_name
:
82 return self
.types_by_name
[ name
]
87 def create_initial_types():
100 for (type_name
, type_size
, integer
) in basic_types
:
101 te
= type_expression(None)
109 type_expression
.built_in_types
= tt
113 class type_expression(object):
114 built_in_types
= None
116 def __init__(self
, type_string
, extra_types
= None):
122 self
.original_string
= type_string
124 if not type_expression
.built_in_types
:
125 raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
127 # Replace '*' with ' * ' in type_string. Then, split the string
128 # into tokens, separated by spaces.
129 tokens
= type_string
.replace("*", " * ").split()
144 elif i
== "unsigned":
147 # This is a quirky special-case because of the
148 # way the C works for types. If 'unsigned' is
149 # specified all by itself, it is treated the
150 # same as "unsigned int".
153 self
.set_base_type( "int", signed
, unsigned
, const
, extra_types
)
159 raise RuntimeError("Invalid type expression (dangling pointer)")
162 raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
166 self
.expr
.append( t
)
169 raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self
.original_string
))
171 self
.set_base_type( i
, signed
, unsigned
, const
, extra_types
)
176 if signed
and unsigned
:
177 raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
181 raise RuntimeError("Invalid type expression (dangling const)")
184 raise RuntimeError("Invalid type expression (dangling signed)")
187 raise RuntimeError("Invalid type expression (dangling unsigned)")
192 def set_base_type(self
, type_name
, signed
, unsigned
, const
, extra_types
):
193 te
= type_expression
.built_in_types
.find_type( type_name
)
195 te
= extra_types
.find_type( type_name
)
198 raise RuntimeError('Unknown base type "%s".' % (type_name
))
200 self
.expr
= copy
.deepcopy(te
.expr
)
202 t
= self
.expr
[ len(self
.expr
) - 1 ]
210 def set_base_type_node(self
, tn
):
215 def set_elements(self
, count
):
230 def get_base_type_node(self
):
234 def get_base_name(self
):
236 return self
.expr
[0].name
241 def get_element_size(self
):
245 return tn
.elements
* tn
.size
250 def get_element_count(self
):
255 def get_stack_size(self
):
258 if tn
.elements
or tn
.pointer
:
266 def is_pointer(self
):
271 def format_string(self
):
282 if __name__
== '__main__':
284 types_to_try
= [ "int", "int *", "const int *", "int * const", "const int * const", \
285 "unsigned * const *", \
286 "float", "const double", "double * const"]
288 create_initial_types()
290 for t
in types_to_try
:
291 print('Trying "%s"...' % (t
))
292 te
= type_expression( t
)
293 print('Got "%s" (%u, %u).' % (te
.string(), te
.get_stack_size(), te
.get_element_size()))