Home | History | Annotate | Download | only in tests
      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