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())