nir: Implement mul_high lowering for bit sizes other than 32
[mesa.git] / src / compiler / glsl / tests / sexps.py
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 import sys
32 if sys.version_info >= (3, 0, 0):
33 STRING_TYPE = str
34 else:
35 STRING_TYPE = unicode
36
37 def check_sexp(sexp):
38 """Verify that the argument is a proper sexp.
39
40 That is, raise an exception if the argument is not a string or a
41 list, or if it contains anything that is not a string or a list at
42 any nesting level.
43 """
44 if isinstance(sexp, list):
45 for s in sexp:
46 check_sexp(s)
47 elif not isinstance(sexp, (STRING_TYPE, bytes)):
48 raise Exception('Not a sexp: {0!r}'.format(sexp))
49
50 def parse_sexp(sexp):
51 """Convert a string, of the form that would be output by mesa,
52 into a sexp represented as nested lists containing strings.
53 """
54 sexp_token_regexp = re.compile(
55 '[a-zA-Z_]+(@[0-9]+)?|[0-9]+(\\.[0-9]+)?|[^ \r?\n]')
56 stack = [[]]
57 for match in sexp_token_regexp.finditer(sexp):
58 token = match.group(0)
59 if token == '(':
60 stack.append([])
61 elif token == ')':
62 if len(stack) == 1:
63 raise Exception('Unmatched )')
64 sexp = stack.pop()
65 stack[-1].append(sexp)
66 else:
67 stack[-1].append(token)
68 if len(stack) != 1:
69 raise Exception('Unmatched (')
70 if len(stack[0]) != 1:
71 raise Exception('Multiple sexps')
72 return stack[0][0]
73
74 def sexp_to_string(sexp):
75 """Convert a sexp, represented as nested lists containing strings,
76 into a single string of the form parseable by mesa.
77 """
78 if isinstance(sexp, STRING_TYPE):
79 return sexp
80 if isinstance(sexp, bytes):
81 return sexp.encode('utf-8')
82 assert isinstance(sexp, list)
83 result = ''
84 for s in sexp:
85 sub_result = sexp_to_string(s)
86 if result == '':
87 result = sub_result
88 elif '\n' not in result and '\n' not in sub_result and \
89 len(result) + len(sub_result) + 1 <= 70:
90 result += ' ' + sub_result
91 else:
92 result += '\n' + sub_result
93 return '({0})'.format(result.replace('\n', '\n '))
94
95 def sort_decls(sexp):
96 """Sort all toplevel variable declarations in sexp.
97
98 This is used to work around the fact that
99 ir_reader::read_instructions reorders declarations.
100 """
101 assert isinstance(sexp, list)
102 decls = []
103 other_code = []
104 for s in sexp:
105 if isinstance(s, list) and len(s) >= 4 and s[0] == 'declare':
106 decls.append(s)
107 else:
108 other_code.append(s)
109 return sorted(decls) + other_code
110