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>
29 class type_node(object):
31 self
.pointer
= 0 # bool
33 self
.signed
= 1 # bool
34 self
.integer
= 1 # bool
36 # If elements is set to non-zero, then field is an array.
40 self
.size
= 0 # type's size in bytes
45 """Return string representation of this type_node."""
62 s
+= "%s " % (self
.name
)
67 class type_table(object):
69 self
.types_by_name
= {}
73 def add_type(self
, type_expr
):
74 self
.types_by_name
[ type_expr
.get_base_name() ] = type_expr
78 def find_type(self
, name
):
79 if name
in self
.types_by_name
:
80 return self
.types_by_name
[ name
]
85 def create_initial_types():
98 for (type_name
, type_size
, integer
) in basic_types
:
99 te
= type_expression(None)
107 type_expression
.built_in_types
= tt
111 class type_expression(object):
112 built_in_types
= None
114 def __init__(self
, type_string
, extra_types
= None):
120 self
.original_string
= type_string
122 if not type_expression
.built_in_types
:
123 raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
125 # Replace '*' with ' * ' in type_string. Then, split the string
126 # into tokens, separated by spaces.
127 tokens
= string
.split( string
.replace( type_string
, "*", " * " ) )
142 elif i
== "unsigned":
145 # This is a quirky special-case because of the
146 # way the C works for types. If 'unsigned' is
147 # specified all by itself, it is treated the
148 # same as "unsigned int".
151 self
.set_base_type( "int", signed
, unsigned
, const
, extra_types
)
157 raise RuntimeError("Invalid type expression (dangling pointer)")
160 raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
164 self
.expr
.append( t
)
167 raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self
.original_string
))
169 self
.set_base_type( i
, signed
, unsigned
, const
, extra_types
)
174 if signed
and unsigned
:
175 raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
179 raise RuntimeError("Invalid type expression (dangling const)")
182 raise RuntimeError("Invalid type expression (dangling signed)")
185 raise RuntimeError("Invalid type expression (dangling unsigned)")
190 def set_base_type(self
, type_name
, signed
, unsigned
, const
, extra_types
):
191 te
= type_expression
.built_in_types
.find_type( type_name
)
193 te
= extra_types
.find_type( type_name
)
196 raise RuntimeError('Unknown base type "%s".' % (type_name
))
198 self
.expr
= copy
.deepcopy(te
.expr
)
200 t
= self
.expr
[ len(self
.expr
) - 1 ]
208 def set_base_type_node(self
, tn
):
213 def set_elements(self
, count
):
228 def get_base_type_node(self
):
232 def get_base_name(self
):
234 return self
.expr
[0].name
239 def get_element_size(self
):
243 return tn
.elements
* tn
.size
248 def get_element_count(self
):
253 def get_stack_size(self
):
256 if tn
.elements
or tn
.pointer
:
264 def is_pointer(self
):
269 def format_string(self
):
280 if __name__
== '__main__':
282 types_to_try
= [ "int", "int *", "const int *", "int * const", "const int * const", \
283 "unsigned * const *", \
284 "float", "const double", "double * const"]
286 create_initial_types()
288 for t
in types_to_try
:
289 print 'Trying "%s"...' % (t
)
290 te
= type_expression( t
)
291 print 'Got "%s" (%u, %u).' % (te
.string(), te
.get_stack_size(), te
.get_element_size())