Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | 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(object):
  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(object):
  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(object):
  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[ -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[ -1 ]
  267.         return tn.pointer
  268.  
  269.  
  270.     def format_string(self):
  271.         tn = 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.