Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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