python: Use the print function
[mesa.git] / src / mapi / glapi / gen / typeexpr.py
1
2 # (C) Copyright IBM Corporation 2005
3 # All Rights Reserved.
4 #
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:
11 #
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
14 # Software.
15 #
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
22 # IN THE SOFTWARE.
23 #
24 # Authors:
25 # Ian Romanick <idr@us.ibm.com>
26
27 from __future__ import print_function
28
29 import string, copy
30
31 class type_node(object):
32 def __init__(self):
33 self.pointer = 0 # bool
34 self.const = 0 # bool
35 self.signed = 1 # bool
36 self.integer = 1 # bool
37
38 # If elements is set to non-zero, then field is an array.
39 self.elements = 0
40
41 self.name = None
42 self.size = 0 # type's size in bytes
43 return
44
45
46 def string(self):
47 """Return string representation of this type_node."""
48 s = ""
49
50 if self.pointer:
51 s = "* "
52
53 if self.const:
54 s += "const "
55
56 if not self.pointer:
57 if self.integer:
58 if self.signed:
59 s += "signed "
60 else:
61 s += "unsigned "
62
63 if self.name:
64 s += "%s " % (self.name)
65
66 return s
67
68
69 class type_table(object):
70 def __init__(self):
71 self.types_by_name = {}
72 return
73
74
75 def add_type(self, type_expr):
76 self.types_by_name[ type_expr.get_base_name() ] = type_expr
77 return
78
79
80 def find_type(self, name):
81 if name in self.types_by_name:
82 return self.types_by_name[ name ]
83 else:
84 return None
85
86
87 def create_initial_types():
88 tt = type_table()
89
90 basic_types = [
91 ("char", 1, 1),
92 ("short", 2, 1),
93 ("int", 4, 1),
94 ("long", 4, 1),
95 ("float", 4, 0),
96 ("double", 8, 0),
97 ("enum", 4, 1)
98 ]
99
100 for (type_name, type_size, integer) in basic_types:
101 te = type_expression(None)
102 tn = type_node()
103 tn.name = type_name
104 tn.size = type_size
105 tn.integer = integer
106 te.expr.append(tn)
107 tt.add_type( te )
108
109 type_expression.built_in_types = tt
110 return
111
112
113 class type_expression(object):
114 built_in_types = None
115
116 def __init__(self, type_string, extra_types = None):
117 self.expr = []
118
119 if not type_string:
120 return
121
122 self.original_string = type_string
123
124 if not type_expression.built_in_types:
125 raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
126
127 # Replace '*' with ' * ' in type_string. Then, split the string
128 # into tokens, separated by spaces.
129 tokens = string.split( string.replace( type_string, "*", " * " ) )
130
131 const = 0
132 t = None
133 signed = 0
134 unsigned = 0
135
136 for i in tokens:
137 if i == "const":
138 if t and t.pointer:
139 t.const = 1
140 else:
141 const = 1
142 elif i == "signed":
143 signed = 1
144 elif i == "unsigned":
145 unsigned = 1
146 elif i == "*":
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".
151
152 if unsigned:
153 self.set_base_type( "int", signed, unsigned, const, extra_types )
154 const = 0
155 signed = 0
156 unsigned = 0
157
158 if not self.expr:
159 raise RuntimeError("Invalid type expression (dangling pointer)")
160
161 if signed:
162 raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
163
164 t = type_node()
165 t.pointer = 1
166 self.expr.append( t )
167 else:
168 if self.expr:
169 raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string))
170
171 self.set_base_type( i, signed, unsigned, const, extra_types )
172 const = 0
173 signed = 0
174 unsigned = 0
175
176 if signed and unsigned:
177 raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
178
179
180 if const:
181 raise RuntimeError("Invalid type expression (dangling const)")
182
183 if unsigned:
184 raise RuntimeError("Invalid type expression (dangling signed)")
185
186 if signed:
187 raise RuntimeError("Invalid type expression (dangling unsigned)")
188
189 return
190
191
192 def set_base_type(self, type_name, signed, unsigned, const, extra_types):
193 te = type_expression.built_in_types.find_type( type_name )
194 if not te:
195 te = extra_types.find_type( type_name )
196
197 if not te:
198 raise RuntimeError('Unknown base type "%s".' % (type_name))
199
200 self.expr = copy.deepcopy(te.expr)
201
202 t = self.expr[ len(self.expr) - 1 ]
203 t.const = const
204 if signed:
205 t.signed = 1
206 elif unsigned:
207 t.signed = 0
208
209
210 def set_base_type_node(self, tn):
211 self.expr = [tn]
212 return
213
214
215 def set_elements(self, count):
216 tn = self.expr[0]
217
218 tn.elements = count
219 return
220
221
222 def string(self):
223 s = ""
224 for t in self.expr:
225 s += t.string()
226
227 return s
228
229
230 def get_base_type_node(self):
231 return self.expr[0]
232
233
234 def get_base_name(self):
235 if len(self.expr):
236 return self.expr[0].name
237 else:
238 return None
239
240
241 def get_element_size(self):
242 tn = self.expr[0]
243
244 if tn.elements:
245 return tn.elements * tn.size
246 else:
247 return tn.size
248
249
250 def get_element_count(self):
251 tn = self.expr[0]
252 return tn.elements
253
254
255 def get_stack_size(self):
256 tn = self.expr[ -1 ]
257
258 if tn.elements or tn.pointer:
259 return 4
260 elif not tn.integer:
261 return tn.size
262 else:
263 return 4
264
265
266 def is_pointer(self):
267 tn = self.expr[ -1 ]
268 return tn.pointer
269
270
271 def format_string(self):
272 tn = self.expr[ -1 ]
273 if tn.pointer:
274 return "%p"
275 elif not tn.integer:
276 return "%f"
277 else:
278 return "%d"
279
280
281
282 if __name__ == '__main__':
283
284 types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \
285 "unsigned * const *", \
286 "float", "const double", "double * const"]
287
288 create_initial_types()
289
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()))