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