Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(594)

Side by Side Diff: tools/js2c.py

Issue 2800042: JS2C tweaks: (Closed)
Patch Set: Fixed bug in macro search Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2006-2008 the V8 project authors. All rights reserved. 3 # Copyright 2006-2008 the V8 project authors. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 # allowed in the natives files. 97 # allowed in the natives files.
98 eval_match = EVAL_PATTERN.search(lines) 98 eval_match = EVAL_PATTERN.search(lines)
99 if eval_match: 99 if eval_match:
100 raise ("Eval disallowed in natives: %s" % file) 100 raise ("Eval disallowed in natives: %s" % file)
101 with_match = WITH_PATTERN.search(lines) 101 with_match = WITH_PATTERN.search(lines)
102 if with_match: 102 if with_match:
103 raise ("With statements disallowed in natives: %s" % file) 103 raise ("With statements disallowed in natives: %s" % file)
104 104
105 105
106 def ExpandConstants(lines, constants): 106 def ExpandConstants(lines, constants):
107 for key, value in constants.items(): 107 for key, value in constants:
108 lines = lines.replace(key, str(value)) 108 lines = key.sub(str(value), lines)
109 return lines 109 return lines
110 110
111 111
112 def ExpandMacros(lines, macros): 112 def ExpandMacros(lines, macros):
113 for name, macro in macros.items(): 113 # We allow macros to depend on the previously declared macros, but
114 start = lines.find(name + '(', 0) 114 # we don't allow self-dependecies or recursion.
115 while start != -1: 115 for name_pattern, macro in reversed(macros):
116 pattern_match = name_pattern.search(lines, 0)
117 while pattern_match is not None:
116 # Scan over the arguments 118 # Scan over the arguments
117 assert lines[start + len(name)] == '('
118 height = 1 119 height = 1
119 end = start + len(name) + 1 120 start = pattern_match.start()
121 end = pattern_match.end()
122 assert lines[end - 1] == '('
120 last_match = end 123 last_match = end
121 arg_index = 0 124 arg_index = 0
122 mapping = { } 125 mapping = { }
123 def add_arg(str): 126 def add_arg(str):
124 # Remember to expand recursively in the arguments 127 # Remember to expand recursively in the arguments
125 replacement = ExpandMacros(str.strip(), macros) 128 replacement = ExpandMacros(str.strip(), macros)
126 mapping[macro.args[arg_index]] = replacement 129 mapping[macro.args[arg_index]] = replacement
127 while end < len(lines) and height > 0: 130 while end < len(lines) and height > 0:
128 # We don't count commas at higher nesting levels. 131 # We don't count commas at higher nesting levels.
129 if lines[end] == ',' and height == 1: 132 if lines[end] == ',' and height == 1:
130 add_arg(lines[last_match:end]) 133 add_arg(lines[last_match:end])
131 last_match = end + 1 134 last_match = end + 1
132 elif lines[end] in ['(', '{', '[']: 135 elif lines[end] in ['(', '{', '[']:
133 height = height + 1 136 height = height + 1
134 elif lines[end] in [')', '}', ']']: 137 elif lines[end] in [')', '}', ']']:
135 height = height - 1 138 height = height - 1
136 end = end + 1 139 end = end + 1
137 # Remember to add the last match. 140 # Remember to add the last match.
138 add_arg(lines[last_match:end-1]) 141 add_arg(lines[last_match:end-1])
139 result = macro.expand(mapping) 142 result = macro.expand(mapping)
140 # Replace the occurrence of the macro with the expansion 143 # Replace the occurrence of the macro with the expansion
141 lines = lines[:start] + result + lines[end:] 144 lines = lines[:start] + result + lines[end:]
142 start = lines.find(name + '(', end) 145 pattern_match = name_pattern.search(lines, start + len(result))
143 return lines 146 return lines
144 147
145 class TextMacro: 148 class TextMacro:
146 def __init__(self, args, body): 149 def __init__(self, args, body):
147 self.args = args 150 self.args = args
148 self.body = body 151 self.body = body
149 def expand(self, mapping): 152 def expand(self, mapping):
150 result = self.body 153 result = self.body
151 for key, value in mapping.items(): 154 for key, value in mapping.items():
152 result = result.replace(key, value) 155 result = result.replace(key, value)
153 return result 156 return result
154 157
155 class PythonMacro: 158 class PythonMacro:
156 def __init__(self, args, fun): 159 def __init__(self, args, fun):
157 self.args = args 160 self.args = args
158 self.fun = fun 161 self.fun = fun
159 def expand(self, mapping): 162 def expand(self, mapping):
160 args = [] 163 args = []
161 for arg in self.args: 164 for arg in self.args:
162 args.append(mapping[arg]) 165 args.append(mapping[arg])
163 return str(self.fun(*args)) 166 return str(self.fun(*args))
164 167
165 CONST_PATTERN = re.compile(r'^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') 168 CONST_PATTERN = re.compile(r'^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$')
166 MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]* );$') 169 MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]* );$')
167 PYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]* )\)\s*=\s*([^;]*);$') 170 PYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]* )\)\s*=\s*([^;]*);$')
168 171
172
169 def ReadMacros(lines): 173 def ReadMacros(lines):
170 constants = { } 174 constants = []
171 macros = { } 175 macros = []
172 for line in lines: 176 for line in lines:
173 hash = line.find('#') 177 hash = line.find('#')
174 if hash != -1: line = line[:hash] 178 if hash != -1: line = line[:hash]
175 line = line.strip() 179 line = line.strip()
176 if len(line) is 0: continue 180 if len(line) is 0: continue
177 const_match = CONST_PATTERN.match(line) 181 const_match = CONST_PATTERN.match(line)
178 if const_match: 182 if const_match:
179 name = const_match.group(1) 183 name = const_match.group(1)
180 value = const_match.group(2).strip() 184 value = const_match.group(2).strip()
181 constants[name] = value 185 constants.append((re.compile("\\b%s\\b" % name), value))
182 else: 186 else:
183 macro_match = MACRO_PATTERN.match(line) 187 macro_match = MACRO_PATTERN.match(line)
184 if macro_match: 188 if macro_match:
185 name = macro_match.group(1) 189 name = macro_match.group(1)
186 args = map(string.strip, macro_match.group(2).split(',')) 190 args = map(string.strip, macro_match.group(2).split(','))
187 body = macro_match.group(3).strip() 191 body = macro_match.group(3).strip()
188 macros[name] = TextMacro(args, body) 192 macros.append((re.compile("\\b%s\\(" % name), TextMacro(args, body)))
189 else: 193 else:
190 python_match = PYTHON_MACRO_PATTERN.match(line) 194 python_match = PYTHON_MACRO_PATTERN.match(line)
191 if python_match: 195 if python_match:
192 name = python_match.group(1) 196 name = python_match.group(1)
193 args = map(string.strip, python_match.group(2).split(',')) 197 args = map(string.strip, python_match.group(2).split(','))
194 body = python_match.group(3).strip() 198 body = python_match.group(3).strip()
195 fun = eval("lambda " + ",".join(args) + ': ' + body) 199 fun = eval("lambda " + ",".join(args) + ': ' + body)
196 macros[name] = PythonMacro(args, fun) 200 macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun)))
197 else: 201 else:
198 raise ("Illegal line: " + line) 202 raise ("Illegal line: " + line)
199 return (constants, macros) 203 return (constants, macros)
200 204
201 205
202 HEADER_TEMPLATE = """\ 206 HEADER_TEMPLATE = """\
203 // Copyright 2008 Google Inc. All Rights Reserved. 207 // Copyright 2008 Google Inc. All Rights Reserved.
204 208
205 // This file was generated from .js source files by SCons. If you 209 // This file was generated from .js source files by SCons. If you
206 // want to make changes to this file you should either change the 210 // want to make changes to this file you should either change the
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 371
368 def main(): 372 def main():
369 natives = sys.argv[1] 373 natives = sys.argv[1]
370 natives_empty = sys.argv[2] 374 natives_empty = sys.argv[2]
371 type = sys.argv[3] 375 type = sys.argv[3]
372 source_files = sys.argv[4:] 376 source_files = sys.argv[4:]
373 JS2C(source_files, [natives, natives_empty], { 'TYPE': type }) 377 JS2C(source_files, [natives, natives_empty], { 'TYPE': type })
374 378
375 if __name__ == "__main__": 379 if __name__ == "__main__":
376 main() 380 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698