Clone of mesa.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

typeexpr.py 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #!/usr/bin/env python
  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. import string, copy
  27. class type_node:
  28. def __init__(self):
  29. self.pointer = 0 # bool
  30. self.const = 0 # bool
  31. self.signed = 1 # bool
  32. self.integer = 1 # bool
  33. # If elements is set to non-zero, then field is an array.
  34. self.elements = 0
  35. self.name = None
  36. self.size = 0 # type's size in bytes
  37. return
  38. def string(self):
  39. """Return string representation of this type_node."""
  40. s = ""
  41. if self.pointer:
  42. s = "* "
  43. if self.const:
  44. s += "const "
  45. if not self.pointer:
  46. if self.integer:
  47. if self.signed:
  48. s += "signed "
  49. else:
  50. s += "unsigned "
  51. if self.name:
  52. s += "%s " % (self.name)
  53. return s
  54. class type_table:
  55. def __init__(self):
  56. self.types_by_name = {}
  57. return
  58. def add_type(self, type_expr):
  59. self.types_by_name[ type_expr.get_base_name() ] = type_expr
  60. return
  61. def find_type(self, name):
  62. if name in self.types_by_name:
  63. return self.types_by_name[ name ]
  64. else:
  65. return None
  66. def create_initial_types():
  67. tt = type_table()
  68. basic_types = [
  69. ("char", 1, 1),
  70. ("short", 2, 1),
  71. ("int", 4, 1),
  72. ("long", 4, 1),
  73. ("float", 4, 0),
  74. ("double", 8, 0),
  75. ("enum", 4, 1)
  76. ]
  77. for (type_name, type_size, integer) in basic_types:
  78. te = type_expression(None)
  79. tn = type_node()
  80. tn.name = type_name
  81. tn.size = type_size
  82. tn.integer = integer
  83. te.expr.append(tn)
  84. tt.add_type( te )
  85. type_expression.built_in_types = tt
  86. return
  87. class type_expression:
  88. built_in_types = None
  89. def __init__(self, type_string, extra_types = None):
  90. self.expr = []
  91. if not type_string:
  92. return
  93. self.original_string = type_string
  94. if not type_expression.built_in_types:
  95. raise RuntimeError("create_initial_types must be called before creating type_expression objects.")
  96. # Replace '*' with ' * ' in type_string. Then, split the string
  97. # into tokens, separated by spaces.
  98. tokens = string.split( string.replace( type_string, "*", " * " ) )
  99. const = 0
  100. t = None
  101. signed = 0
  102. unsigned = 0
  103. for i in tokens:
  104. if i == "const":
  105. if t and t.pointer:
  106. t.const = 1
  107. else:
  108. const = 1
  109. elif i == "signed":
  110. signed = 1
  111. elif i == "unsigned":
  112. unsigned = 1
  113. elif i == "*":
  114. # This is a quirky special-case because of the
  115. # way the C works for types. If 'unsigned' is
  116. # specified all by itself, it is treated the
  117. # same as "unsigned int".
  118. if unsigned:
  119. self.set_base_type( "int", signed, unsigned, const, extra_types )
  120. const = 0
  121. signed = 0
  122. unsigned = 0
  123. if not self.expr:
  124. raise RuntimeError("Invalid type expression (dangling pointer)")
  125. if signed:
  126. raise RuntimeError("Invalid type expression (signed / unsigned applied to pointer)")
  127. t = type_node()
  128. t.pointer = 1
  129. self.expr.append( t )
  130. else:
  131. if self.expr:
  132. raise RuntimeError('Invalid type expression (garbage after pointer qualifier -> "%s")' % (self.original_string))
  133. self.set_base_type( i, signed, unsigned, const, extra_types )
  134. const = 0
  135. signed = 0
  136. unsigned = 0
  137. if signed and unsigned:
  138. raise RuntimeError("Invalid type expression (both signed and unsigned specified)")
  139. if const:
  140. raise RuntimeError("Invalid type expression (dangling const)")
  141. if unsigned:
  142. raise RuntimeError("Invalid type expression (dangling signed)")
  143. if signed:
  144. raise RuntimeError("Invalid type expression (dangling unsigned)")
  145. return
  146. def set_base_type(self, type_name, signed, unsigned, const, extra_types):
  147. te = type_expression.built_in_types.find_type( type_name )
  148. if not te:
  149. te = extra_types.find_type( type_name )
  150. if not te:
  151. raise RuntimeError('Unknown base type "%s".' % (type_name))
  152. self.expr = copy.deepcopy(te.expr)
  153. t = self.expr[ len(self.expr) - 1 ]
  154. t.const = const
  155. if signed:
  156. t.signed = 1
  157. elif unsigned:
  158. t.signed = 0
  159. def set_base_type_node(self, tn):
  160. self.expr = [tn]
  161. return
  162. def set_elements(self, count):
  163. tn = self.expr[0]
  164. tn.elements = count
  165. return
  166. def string(self):
  167. s = ""
  168. for t in self.expr:
  169. s += t.string()
  170. return s
  171. def get_base_type_node(self):
  172. return self.expr[0]
  173. def get_base_name(self):
  174. if len(self.expr):
  175. return self.expr[0].name
  176. else:
  177. return None
  178. def get_element_size(self):
  179. tn = self.expr[0]
  180. if tn.elements:
  181. return tn.elements * tn.size
  182. else:
  183. return tn.size
  184. def get_element_count(self):
  185. tn = self.expr[0]
  186. return tn.elements
  187. def get_stack_size(self):
  188. tn = self.expr[ len(self.expr) - 1 ]
  189. if tn.elements or tn.pointer:
  190. return 4
  191. elif not tn.integer:
  192. return tn.size
  193. else:
  194. return 4
  195. def is_pointer(self):
  196. tn = self.expr[ len(self.expr) - 1 ]
  197. return tn.pointer
  198. def format_string(self):
  199. tn = self.expr[ len(self.expr) - 1 ]
  200. if tn.pointer:
  201. return "%p"
  202. elif not tn.integer:
  203. return "%f"
  204. else:
  205. return "%d"
  206. if __name__ == '__main__':
  207. types_to_try = [ "int", "int *", "const int *", "int * const", "const int * const", \
  208. "unsigned * const *", \
  209. "float", "const double", "double * const"]
  210. create_initial_types()
  211. for t in types_to_try:
  212. print 'Trying "%s"...' % (t)
  213. te = type_expression( t )
  214. print 'Got "%s" (%u, %u).' % (te.string(), te.get_stack_size(), te.get_element_size())