101e04c3fSmrg# coding=utf-8 201e04c3fSmrg# 301e04c3fSmrg# Copyright © 2011 Intel Corporation 401e04c3fSmrg# 501e04c3fSmrg# Permission is hereby granted, free of charge, to any person obtaining a 601e04c3fSmrg# copy of this software and associated documentation files (the "Software"), 701e04c3fSmrg# to deal in the Software without restriction, including without limitation 801e04c3fSmrg# the rights to use, copy, modify, merge, publish, distribute, sublicense, 901e04c3fSmrg# and/or sell copies of the Software, and to permit persons to whom the 1001e04c3fSmrg# Software is furnished to do so, subject to the following conditions: 1101e04c3fSmrg# 1201e04c3fSmrg# The above copyright notice and this permission notice (including the next 1301e04c3fSmrg# paragraph) shall be included in all copies or substantial portions of the 1401e04c3fSmrg# Software. 1501e04c3fSmrg# 1601e04c3fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1701e04c3fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1801e04c3fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1901e04c3fSmrg# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2001e04c3fSmrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2101e04c3fSmrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2201e04c3fSmrg# DEALINGS IN THE SOFTWARE. 2301e04c3fSmrg 2401e04c3fSmrg# This file contains helper functions for manipulating sexps in Python. 2501e04c3fSmrg# 2601e04c3fSmrg# We represent a sexp in Python using nested lists containing strings. 2701e04c3fSmrg# So, for example, the sexp (constant float (1.000000)) is represented 2801e04c3fSmrg# as ['constant', 'float', ['1.000000']]. 2901e04c3fSmrg 3001e04c3fSmrgimport re 3101e04c3fSmrg 3201e04c3fSmrgdef check_sexp(sexp): 3301e04c3fSmrg """Verify that the argument is a proper sexp. 3401e04c3fSmrg 3501e04c3fSmrg That is, raise an exception if the argument is not a string or a 3601e04c3fSmrg list, or if it contains anything that is not a string or a list at 3701e04c3fSmrg any nesting level. 3801e04c3fSmrg """ 3901e04c3fSmrg if isinstance(sexp, list): 4001e04c3fSmrg for s in sexp: 4101e04c3fSmrg check_sexp(s) 427ec681f3Smrg elif not isinstance(sexp, str): 4301e04c3fSmrg raise Exception('Not a sexp: {0!r}'.format(sexp)) 4401e04c3fSmrg 4501e04c3fSmrgdef parse_sexp(sexp): 4601e04c3fSmrg """Convert a string, of the form that would be output by mesa, 4701e04c3fSmrg into a sexp represented as nested lists containing strings. 4801e04c3fSmrg """ 4901e04c3fSmrg sexp_token_regexp = re.compile( 507ec681f3Smrg '[a-zA-Z_]+(@[0-9]+)?|[0-9]+(\\.[0-9]+)?|[^ \r?\n]') 5101e04c3fSmrg stack = [[]] 5201e04c3fSmrg for match in sexp_token_regexp.finditer(sexp): 5301e04c3fSmrg token = match.group(0) 5401e04c3fSmrg if token == '(': 5501e04c3fSmrg stack.append([]) 5601e04c3fSmrg elif token == ')': 5701e04c3fSmrg if len(stack) == 1: 5801e04c3fSmrg raise Exception('Unmatched )') 5901e04c3fSmrg sexp = stack.pop() 6001e04c3fSmrg stack[-1].append(sexp) 6101e04c3fSmrg else: 6201e04c3fSmrg stack[-1].append(token) 6301e04c3fSmrg if len(stack) != 1: 6401e04c3fSmrg raise Exception('Unmatched (') 6501e04c3fSmrg if len(stack[0]) != 1: 6601e04c3fSmrg raise Exception('Multiple sexps') 6701e04c3fSmrg return stack[0][0] 6801e04c3fSmrg 6901e04c3fSmrgdef sexp_to_string(sexp): 7001e04c3fSmrg """Convert a sexp, represented as nested lists containing strings, 7101e04c3fSmrg into a single string of the form parseable by mesa. 7201e04c3fSmrg """ 737ec681f3Smrg if isinstance(sexp, str): 7401e04c3fSmrg return sexp 7501e04c3fSmrg assert isinstance(sexp, list) 7601e04c3fSmrg result = '' 7701e04c3fSmrg for s in sexp: 7801e04c3fSmrg sub_result = sexp_to_string(s) 7901e04c3fSmrg if result == '': 8001e04c3fSmrg result = sub_result 8101e04c3fSmrg elif '\n' not in result and '\n' not in sub_result and \ 8201e04c3fSmrg len(result) + len(sub_result) + 1 <= 70: 8301e04c3fSmrg result += ' ' + sub_result 8401e04c3fSmrg else: 8501e04c3fSmrg result += '\n' + sub_result 8601e04c3fSmrg return '({0})'.format(result.replace('\n', '\n ')) 8701e04c3fSmrg 8801e04c3fSmrgdef sort_decls(sexp): 8901e04c3fSmrg """Sort all toplevel variable declarations in sexp. 9001e04c3fSmrg 9101e04c3fSmrg This is used to work around the fact that 9201e04c3fSmrg ir_reader::read_instructions reorders declarations. 9301e04c3fSmrg """ 9401e04c3fSmrg assert isinstance(sexp, list) 9501e04c3fSmrg decls = [] 9601e04c3fSmrg other_code = [] 9701e04c3fSmrg for s in sexp: 9801e04c3fSmrg if isinstance(s, list) and len(s) >= 4 and s[0] == 'declare': 9901e04c3fSmrg decls.append(s) 10001e04c3fSmrg else: 10101e04c3fSmrg other_code.append(s) 10201e04c3fSmrg return sorted(decls) + other_code 10301e04c3fSmrg 104