3
# (C) Copyright IBM Corporation 2005
6
# Permission is hereby granted, free of charge, to any person obtaining a
7
# copy of this software and associated documentation files (the "Software"),
8
# to deal in the Software without restriction, including without limitation
9
# on the rights to use, copy, modify, merge, publish, distribute, sub
10
# license, and/or sell copies of the Software, and to permit persons to whom
11
# the Software is furnished to do so, subject to the following conditions:
13
# The above copyright notice and this permission notice (including the next
14
# paragraph) shall be included in all copies or substantial portions of the
17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26
# Ian Romanick <idr@us.ibm.com>
32
self.pointer = 0 # bool
34
self.signed = 1 # bool
35
self.integer = 1 # bool
37
# If elements is set to non-zero, then field is an array.
41
self.size = 0 # type's size in bytes
46
"""Return string representation of this type_node."""
63
s += "%s " % (self.name)
70
self.types_by_name = {}
74
def add_type(self, type_expr):
75
self.types_by_name[ type_expr.get_base_name() ] = type_expr
79
def find_type(self, name):
80
if name in self.types_by_name:
81
return self.types_by_name[ name ]
86
def create_initial_types():
99
for (type_name, type_size, integer) in basic_types:
100
te = type_expression(None)
108
type_expression.built_in_types = tt
112
class type_expression:
113
built_in_types = None
115
def __init__(self, type_string, extra_types = None):
121
self.original_string = type_string
123
if not type_expression.built_in_types:
124
raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
126
# Replace '*' with ' * ' in type_string. Then, split the string
127
# into tokens, separated by spaces.
128
tokens = string.split( string.replace( type_string, "*", " * " ) )
143
elif i == "unsigned":
146
# This is a quirky special-case because of the
147
# way the C works for types. If 'unsigned' is
148
# specified all by itself, it is treated the
149
# same as "unsigned int".
152
self.set_base_type( "int", signed, unsigned, const, extra_types )
158
raise RuntimeError("Invalid type expression (dangling pointer)")
161
raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
165
self.expr.append( t )
168
raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string))
170
self.set_base_type( i, signed, unsigned, const, extra_types )
175
if signed and unsigned:
176
raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
180
raise RuntimeError("Invalid type expression (dangling const)")
183
raise RuntimeError("Invalid type expression (dangling signed)")
186
raise RuntimeError("Invalid type expression (dangling unsigned)")
191
def set_base_type(self, type_name, signed, unsigned, const, extra_types):
192
te = type_expression.built_in_types.find_type( type_name )
194
te = extra_types.find_type( type_name )
197
raise RuntimeError('Unknown base type "%s".' % (type_name))
199
self.expr = copy.deepcopy(te.expr)
201
t = self.expr[ len(self.expr) - 1 ]
209
def set_base_type_node(self, tn):
214
def set_elements(self, count):
229
def get_base_type_node(self):
233
def get_base_name(self):
235
return self.expr[0].name
240
def get_element_size(self):
244
return tn.elements * tn.size
249
def get_element_count(self):
254
def get_stack_size(self):
255
tn = self.expr[ len(self.expr) - 1 ]
257
if tn.elements or tn.pointer:
265
def is_pointer(self):
266
tn = self.expr[ len(self.expr) - 1 ]
270
def format_string(self):
271
tn = self.expr[ len(self.expr) - 1 ]
281
if __name__ == '__main__':
283
types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \
284
"unsigned * const *", \
285
"float", "const double", "double * const"]
287
create_initial_types()
289
for t in types_to_try:
290
print 'Trying "%s"...' % (t)
291
te = type_expression( t )
292
print 'Got "%s" (%u, %u).' % (te.string(), te.get_stack_size(), te.get_element_size())