1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond#!/usr/bin/env python
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# (C) Copyright IBM Corporation 2005
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# All Rights Reserved.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond#
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# Permission is hereby granted, free of charge, to any person obtaining a
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# copy of this software and associated documentation files (the "Software"),
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# to deal in the Software without restriction, including without limitation
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# on the rights to use, copy, modify, merge, publish, distribute, sub
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# license, and/or sell copies of the Software, and to permit persons to whom
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# the Software is furnished to do so, subject to the following conditions:
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond#
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# The above copyright notice and this permission notice (including the next
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# paragraph) shall be included in all copies or substantial portions of the
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# Software.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond#
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# IN THE SOFTWARE.
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond#
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond# Authors:
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond#    Ian Romanick <idr@us.ibm.com>
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport string, copy
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondclass type_node(object):
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def __init__(self):
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.pointer = 0  # bool
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.const = 0    # bool
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.signed = 1   # bool
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.integer = 1  # bool
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        # If elements is set to non-zero, then field is an array.
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.elements = 0
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.name = None
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.size = 0     # type's size in bytes
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def string(self):
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        """Return string representation of this type_node."""
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        s = ""
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if self.pointer:
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            s = "* "
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if self.const:
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            s += "const "
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if not self.pointer:
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if self.integer:
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                if self.signed:
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    s += "signed "
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                else:
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    s += "unsigned "
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if self.name:
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                s += "%s " % (self.name)
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return s
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondclass type_table(object):
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def __init__(self):
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.types_by_name = {}
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def add_type(self, type_expr):
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.types_by_name[ type_expr.get_base_name() ] = type_expr
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def find_type(self, name):
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if name in self.types_by_name:
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return self.types_by_name[ name ]
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        else:
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return None
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymonddef create_initial_types():
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    tt = type_table()
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    basic_types = [
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("char",   1, 1),
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("short",  2, 1),
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("int",    4, 1),
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("long",   4, 1),
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("float",  4, 0),
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("double", 8, 0),
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            ("enum",   4, 1)
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    ]
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for (type_name, type_size, integer) in basic_types:
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        te = type_expression(None)
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = type_node()
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn.name = type_name
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn.size = type_size
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn.integer = integer
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        te.expr.append(tn)
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tt.add_type( te )
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    type_expression.built_in_types = tt
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    return
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondclass type_expression(object):
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    built_in_types = None
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def __init__(self, type_string, extra_types = None):
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.expr = []
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if not type_string:
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.original_string = type_string
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if not type_expression.built_in_types:
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        # Replace '*' with ' * ' in type_string.  Then, split the string
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        # into tokens, separated by spaces.
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tokens = string.split( string.replace( type_string, "*", " * " ) )
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        const = 0
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        t = None
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        signed = 0
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        unsigned = 0
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for i in tokens:
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if i == "const":
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                if t and t.pointer:
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    t.const = 1
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                else:
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    const = 1
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            elif i == "signed":
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                signed = 1
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            elif i == "unsigned":
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                unsigned = 1
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            elif i == "*":
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                # This is a quirky special-case because of the
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                # way the C works for types.  If 'unsigned' is
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                # specified all by itself, it is treated the
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                # same as "unsigned int".
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                if unsigned:
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    self.set_base_type( "int", signed, unsigned, const, extra_types )
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    const = 0
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    signed = 0
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    unsigned = 0
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                if not self.expr:
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    raise RuntimeError("Invalid type expression (dangling pointer)")
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                if signed:
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                t = type_node()
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                t.pointer = 1
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                self.expr.append( t )
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            else:
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                if self.expr:
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string))
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                self.set_base_type( i, signed, unsigned, const, extra_types )
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                const = 0
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                signed = 0
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                unsigned = 0
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            if signed and unsigned:
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if const:
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            raise RuntimeError("Invalid type expression (dangling const)")
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if unsigned:
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            raise RuntimeError("Invalid type expression (dangling signed)")
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if signed:
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            raise RuntimeError("Invalid type expression (dangling unsigned)")
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def set_base_type(self, type_name, signed, unsigned, const, extra_types):
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        te = type_expression.built_in_types.find_type( type_name )
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if not te:
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            te = extra_types.find_type( type_name )
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if not te:
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            raise RuntimeError('Unknown base type "%s".' % (type_name))
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.expr = copy.deepcopy(te.expr)
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        t = self.expr[ len(self.expr) - 1 ]
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        t.const = const
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if signed:
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            t.signed = 1
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        elif unsigned:
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            t.signed = 0
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def set_base_type_node(self, tn):
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        self.expr = [tn]
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def set_elements(self, count):
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = self.expr[0]
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn.elements = count
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def string(self):
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        s = ""
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for t in self.expr:
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            s += t.string()
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return s
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def get_base_type_node(self):
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return self.expr[0]
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def get_base_name(self):
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if len(self.expr):
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return self.expr[0].name
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        else:
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return None
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def get_element_size(self):
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = self.expr[0]
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if tn.elements:
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return tn.elements * tn.size
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        else:
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return tn.size
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def get_element_count(self):
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = self.expr[0]
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return tn.elements
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def get_stack_size(self):
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = self.expr[ -1 ]
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if tn.elements or tn.pointer:
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 4
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        elif not tn.integer:
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return tn.size
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        else:
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return 4
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def is_pointer(self):
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = self.expr[ -1 ]
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return tn.pointer
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    def format_string(self):
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        tn = self.expr[ -1 ]
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if tn.pointer:
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return "%p"
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        elif not tn.integer:
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return "%f"
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        else:
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return "%d"
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondif __name__ == '__main__':
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                     "unsigned * const *", \
285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                     "float", "const double", "double * const"]
286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    create_initial_types()
288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    for t in types_to_try:
290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        print 'Trying "%s"...' % (t)
291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        te = type_expression( t )
292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        print 'Got "%s" (%u, %u).' % (te.string(), te.get_stack_size(), te.get_element_size())
293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond