Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1900 → Rev 1901

/programs/develop/libraries/Mesa/src/mapi/glapi/gen/typeexpr.py
0,0 → 1,292
#!/usr/bin/env python
 
# (C) Copyright IBM Corporation 2005
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Ian Romanick <idr@us.ibm.com>
 
import string, copy
 
class type_node:
def __init__(self):
self.pointer = 0 # bool
self.const = 0 # bool
self.signed = 1 # bool
self.integer = 1 # bool
 
# If elements is set to non-zero, then field is an array.
self.elements = 0
 
self.name = None
self.size = 0 # type's size in bytes
return
 
 
def string(self):
"""Return string representation of this type_node."""
s = ""
if self.pointer:
s = "* "
 
if self.const:
s += "const "
 
if not self.pointer:
if self.integer:
if self.signed:
s += "signed "
else:
s += "unsigned "
 
if self.name:
s += "%s " % (self.name)
 
return s
 
 
class type_table:
def __init__(self):
self.types_by_name = {}
return
 
 
def add_type(self, type_expr):
self.types_by_name[ type_expr.get_base_name() ] = type_expr
return
 
 
def find_type(self, name):
if name in self.types_by_name:
return self.types_by_name[ name ]
else:
return None
 
 
def create_initial_types():
tt = type_table()
 
basic_types = [
("char", 1, 1),
("short", 2, 1),
("int", 4, 1),
("long", 4, 1),
("float", 4, 0),
("double", 8, 0),
("enum", 4, 1)
]
 
for (type_name, type_size, integer) in basic_types:
te = type_expression(None)
tn = type_node()
tn.name = type_name
tn.size = type_size
tn.integer = integer
te.expr.append(tn)
tt.add_type( te )
 
type_expression.built_in_types = tt
return
 
 
class type_expression:
built_in_types = None
 
def __init__(self, type_string, extra_types = None):
self.expr = []
 
if not type_string:
return
 
self.original_string = type_string
 
if not type_expression.built_in_types:
raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
 
# Replace '*' with ' * ' in type_string. Then, split the string
# into tokens, separated by spaces.
tokens = string.split( string.replace( type_string, "*", " * " ) )
 
const = 0
t = None
signed = 0
unsigned = 0
 
for i in tokens:
if i == "const":
if t and t.pointer:
t.const = 1
else:
const = 1
elif i == "signed":
signed = 1
elif i == "unsigned":
unsigned = 1
elif i == "*":
# This is a quirky special-case because of the
# way the C works for types. If 'unsigned' is
# specified all by itself, it is treated the
# same as "unsigned int".
 
if unsigned:
self.set_base_type( "int", signed, unsigned, const, extra_types )
const = 0
signed = 0
unsigned = 0
 
if not self.expr:
raise RuntimeError("Invalid type expression (dangling pointer)")
 
if signed:
raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
 
t = type_node()
t.pointer = 1
self.expr.append( t )
else:
if self.expr:
raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string))
 
self.set_base_type( i, signed, unsigned, const, extra_types )
const = 0
signed = 0
unsigned = 0
 
if signed and unsigned:
raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
 
if const:
raise RuntimeError("Invalid type expression (dangling const)")
 
if unsigned:
raise RuntimeError("Invalid type expression (dangling signed)")
 
if signed:
raise RuntimeError("Invalid type expression (dangling unsigned)")
 
return
 
 
def set_base_type(self, type_name, signed, unsigned, const, extra_types):
te = type_expression.built_in_types.find_type( type_name )
if not te:
te = extra_types.find_type( type_name )
 
if not te:
raise RuntimeError('Unknown base type "%s".' % (type_name))
 
self.expr = copy.deepcopy(te.expr)
 
t = self.expr[ len(self.expr) - 1 ]
t.const = const
if signed:
t.signed = 1
elif unsigned:
t.signed = 0
 
 
def set_base_type_node(self, tn):
self.expr = [tn]
return
 
 
def set_elements(self, count):
tn = self.expr[0]
 
tn.elements = count
return
 
 
def string(self):
s = ""
for t in self.expr:
s += t.string()
 
return s
 
 
def get_base_type_node(self):
return self.expr[0]
 
 
def get_base_name(self):
if len(self.expr):
return self.expr[0].name
else:
return None
 
 
def get_element_size(self):
tn = self.expr[0]
 
if tn.elements:
return tn.elements * tn.size
else:
return tn.size
 
 
def get_element_count(self):
tn = self.expr[0]
return tn.elements
 
 
def get_stack_size(self):
tn = self.expr[ len(self.expr) - 1 ]
 
if tn.elements or tn.pointer:
return 4
elif not tn.integer:
return tn.size
else:
return 4
 
 
def is_pointer(self):
tn = self.expr[ len(self.expr) - 1 ]
return tn.pointer
 
 
def format_string(self):
tn = self.expr[ len(self.expr) - 1 ]
if tn.pointer:
return "%p"
elif not tn.integer:
return "%f"
else:
return "%d"
 
 
 
if __name__ == '__main__':
types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \
"unsigned * const *", \
"float", "const double", "double * const"]
 
create_initial_types()
 
for t in types_to_try:
print 'Trying "%s"...' % (t)
te = type_expression( t )
print 'Got "%s" (%u, %u).' % (te.string(), te.get_stack_size(), te.get_element_size())