Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. # coding=utf-8
  2. #
  3. # Copyright © 2011 Intel Corporation
  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. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # 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 NONINFRINGEMENT.  IN NO EVENT SHALL
  19. # THE AUTHORS OR COPYRIGHT HOLDERS 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
  22. # DEALINGS IN THE SOFTWARE.
  23.  
  24. # This file contains helper functions for manipulating sexps in Python.
  25. #
  26. # We represent a sexp in Python using nested lists containing strings.
  27. # So, for example, the sexp (constant float (1.000000)) is represented
  28. # as ['constant', 'float', ['1.000000']].
  29.  
  30. import re
  31.  
  32. def check_sexp(sexp):
  33.     """Verify that the argument is a proper sexp.
  34.  
  35.    That is, raise an exception if the argument is not a string or a
  36.    list, or if it contains anything that is not a string or a list at
  37.    any nesting level.
  38.    """
  39.     if isinstance(sexp, list):
  40.         for s in sexp:
  41.             check_sexp(s)
  42.     elif not isinstance(sexp, basestring):
  43.         raise Exception('Not a sexp: {0!r}'.format(sexp))
  44.  
  45. def parse_sexp(sexp):
  46.     """Convert a string, of the form that would be output by mesa,
  47.    into a sexp represented as nested lists containing strings.
  48.    """
  49.     sexp_token_regexp = re.compile(
  50.         '[a-zA-Z_]+(@[0-9]+)?|[0-9]+(\\.[0-9]+)?|[^ \n]')
  51.     stack = [[]]
  52.     for match in sexp_token_regexp.finditer(sexp):
  53.         token = match.group(0)
  54.         if token == '(':
  55.             stack.append([])
  56.         elif token == ')':
  57.             if len(stack) == 1:
  58.                 raise Exception('Unmatched )')
  59.             sexp = stack.pop()
  60.             stack[-1].append(sexp)
  61.         else:
  62.             stack[-1].append(token)
  63.     if len(stack) != 1:
  64.         raise Exception('Unmatched (')
  65.     if len(stack[0]) != 1:
  66.         raise Exception('Multiple sexps')
  67.     return stack[0][0]
  68.  
  69. def sexp_to_string(sexp):
  70.     """Convert a sexp, represented as nested lists containing strings,
  71.    into a single string of the form parseable by mesa.
  72.    """
  73.     if isinstance(sexp, basestring):
  74.         return sexp
  75.     assert isinstance(sexp, list)
  76.     result = ''
  77.     for s in sexp:
  78.         sub_result = sexp_to_string(s)
  79.         if result == '':
  80.             result = sub_result
  81.         elif '\n' not in result and '\n' not in sub_result and \
  82.                 len(result) + len(sub_result) + 1 <= 70:
  83.             result += ' ' + sub_result
  84.         else:
  85.             result += '\n' + sub_result
  86.     return '({0})'.format(result.replace('\n', '\n '))
  87.  
  88. def sort_decls(sexp):
  89.     """Sort all toplevel variable declarations in sexp.
  90.  
  91.    This is used to work around the fact that
  92.    ir_reader::read_instructions reorders declarations.
  93.    """
  94.     assert isinstance(sexp, list)
  95.     decls = []
  96.     other_code = []
  97.     for s in sexp:
  98.         if isinstance(s, list) and len(s) >= 4 and s[0] == 'declare':
  99.             decls.append(s)
  100.         else:
  101.             other_code.append(s)
  102.     return sorted(decls) + other_code
  103.  
  104.