1*61046927SAndroid Build Coastguard Worker# coding=utf-8 2*61046927SAndroid Build Coastguard Worker# 3*61046927SAndroid Build Coastguard Worker# Copyright © 2011 Intel Corporation 4*61046927SAndroid Build Coastguard Worker# 5*61046927SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a 6*61046927SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the "Software"), 7*61046927SAndroid Build Coastguard Worker# to deal in the Software without restriction, including without limitation 8*61046927SAndroid Build Coastguard Worker# the rights to use, copy, modify, merge, publish, distribute, sublicense, 9*61046927SAndroid Build Coastguard Worker# and/or sell copies of the Software, and to permit persons to whom the 10*61046927SAndroid Build Coastguard Worker# Software is furnished to do so, subject to the following conditions: 11*61046927SAndroid Build Coastguard Worker# 12*61046927SAndroid Build Coastguard Worker# The above copyright notice and this permission notice (including the next 13*61046927SAndroid Build Coastguard Worker# paragraph) shall be included in all copies or substantial portions of the 14*61046927SAndroid Build Coastguard Worker# Software. 15*61046927SAndroid Build Coastguard Worker# 16*61046927SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*61046927SAndroid Build Coastguard Worker# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*61046927SAndroid Build Coastguard Worker# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*61046927SAndroid Build Coastguard Worker# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*61046927SAndroid Build Coastguard Worker# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21*61046927SAndroid Build Coastguard Worker# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22*61046927SAndroid Build Coastguard Worker# DEALINGS IN THE SOFTWARE. 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Worker# This file contains helper functions for manipulating sexps in Python. 25*61046927SAndroid Build Coastguard Worker# 26*61046927SAndroid Build Coastguard Worker# We represent a sexp in Python using nested lists containing strings. 27*61046927SAndroid Build Coastguard Worker# So, for example, the sexp (constant float (1.000000)) is represented 28*61046927SAndroid Build Coastguard Worker# as ['constant', 'float', ['1.000000']]. 29*61046927SAndroid Build Coastguard Worker 30*61046927SAndroid Build Coastguard Workerimport re 31*61046927SAndroid Build Coastguard Worker 32*61046927SAndroid Build Coastguard Workerdef check_sexp(sexp): 33*61046927SAndroid Build Coastguard Worker """Verify that the argument is a proper sexp. 34*61046927SAndroid Build Coastguard Worker 35*61046927SAndroid Build Coastguard Worker That is, raise an exception if the argument is not a string or a 36*61046927SAndroid Build Coastguard Worker list, or if it contains anything that is not a string or a list at 37*61046927SAndroid Build Coastguard Worker any nesting level. 38*61046927SAndroid Build Coastguard Worker """ 39*61046927SAndroid Build Coastguard Worker if isinstance(sexp, list): 40*61046927SAndroid Build Coastguard Worker for s in sexp: 41*61046927SAndroid Build Coastguard Worker check_sexp(s) 42*61046927SAndroid Build Coastguard Worker elif not isinstance(sexp, str): 43*61046927SAndroid Build Coastguard Worker raise Exception('Not a sexp: {0!r}'.format(sexp)) 44*61046927SAndroid Build Coastguard Worker 45*61046927SAndroid Build Coastguard Workerdef parse_sexp(sexp): 46*61046927SAndroid Build Coastguard Worker """Convert a string, of the form that would be output by mesa, 47*61046927SAndroid Build Coastguard Worker into a sexp represented as nested lists containing strings. 48*61046927SAndroid Build Coastguard Worker """ 49*61046927SAndroid Build Coastguard Worker sexp_token_regexp = re.compile( 50*61046927SAndroid Build Coastguard Worker '[a-zA-Z_]+(@[0-9]+)?|[0-9]+(\\.[0-9]+)?|[^ \r?\n]') 51*61046927SAndroid Build Coastguard Worker stack = [[]] 52*61046927SAndroid Build Coastguard Worker for match in sexp_token_regexp.finditer(sexp): 53*61046927SAndroid Build Coastguard Worker token = match.group(0) 54*61046927SAndroid Build Coastguard Worker if token == '(': 55*61046927SAndroid Build Coastguard Worker stack.append([]) 56*61046927SAndroid Build Coastguard Worker elif token == ')': 57*61046927SAndroid Build Coastguard Worker if len(stack) == 1: 58*61046927SAndroid Build Coastguard Worker raise Exception('Unmatched )') 59*61046927SAndroid Build Coastguard Worker sexp = stack.pop() 60*61046927SAndroid Build Coastguard Worker stack[-1].append(sexp) 61*61046927SAndroid Build Coastguard Worker else: 62*61046927SAndroid Build Coastguard Worker stack[-1].append(token) 63*61046927SAndroid Build Coastguard Worker if len(stack) != 1: 64*61046927SAndroid Build Coastguard Worker raise Exception('Unmatched (') 65*61046927SAndroid Build Coastguard Worker if len(stack[0]) != 1: 66*61046927SAndroid Build Coastguard Worker raise Exception('Multiple sexps') 67*61046927SAndroid Build Coastguard Worker return stack[0][0] 68*61046927SAndroid Build Coastguard Worker 69*61046927SAndroid Build Coastguard Workerdef sexp_to_string(sexp): 70*61046927SAndroid Build Coastguard Worker """Convert a sexp, represented as nested lists containing strings, 71*61046927SAndroid Build Coastguard Worker into a single string of the form parseable by mesa. 72*61046927SAndroid Build Coastguard Worker """ 73*61046927SAndroid Build Coastguard Worker if isinstance(sexp, str): 74*61046927SAndroid Build Coastguard Worker return sexp 75*61046927SAndroid Build Coastguard Worker assert isinstance(sexp, list) 76*61046927SAndroid Build Coastguard Worker result = '' 77*61046927SAndroid Build Coastguard Worker for s in sexp: 78*61046927SAndroid Build Coastguard Worker sub_result = sexp_to_string(s) 79*61046927SAndroid Build Coastguard Worker if result == '': 80*61046927SAndroid Build Coastguard Worker result = sub_result 81*61046927SAndroid Build Coastguard Worker elif '\n' not in result and '\n' not in sub_result and \ 82*61046927SAndroid Build Coastguard Worker len(result) + len(sub_result) + 1 <= 70: 83*61046927SAndroid Build Coastguard Worker result += ' ' + sub_result 84*61046927SAndroid Build Coastguard Worker else: 85*61046927SAndroid Build Coastguard Worker result += '\n' + sub_result 86*61046927SAndroid Build Coastguard Worker return '({0})'.format(result.replace('\n', '\n ')) 87*61046927SAndroid Build Coastguard Worker 88*61046927SAndroid Build Coastguard Workerdef sort_decls(sexp): 89*61046927SAndroid Build Coastguard Worker """Sort all toplevel variable declarations in sexp. 90*61046927SAndroid Build Coastguard Worker 91*61046927SAndroid Build Coastguard Worker This is used to work around the fact that 92*61046927SAndroid Build Coastguard Worker ir_reader::read_instructions reorders declarations. 93*61046927SAndroid Build Coastguard Worker """ 94*61046927SAndroid Build Coastguard Worker assert isinstance(sexp, list) 95*61046927SAndroid Build Coastguard Worker decls = [] 96*61046927SAndroid Build Coastguard Worker other_code = [] 97*61046927SAndroid Build Coastguard Worker for s in sexp: 98*61046927SAndroid Build Coastguard Worker if isinstance(s, list) and len(s) >= 4 and s[0] == 'declare': 99*61046927SAndroid Build Coastguard Worker decls.append(s) 100*61046927SAndroid Build Coastguard Worker else: 101*61046927SAndroid Build Coastguard Worker other_code.append(s) 102*61046927SAndroid Build Coastguard Worker return sorted(decls) + other_code 103*61046927SAndroid Build Coastguard Worker 104