2018-04-16 09:24:22 +00:00
|
|
|
|
#!/usr/bin/env python
|
2019-05-16 08:00:13 +00:00
|
|
|
|
# -*- coding: utf-8 -*-
|
2018-04-16 09:24:22 +00:00
|
|
|
|
# Copyright 2014 the V8 project authors. All rights reserved.
|
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
"""This program either generates the parser files for Torque, generating
|
|
|
|
|
the source and header files directly in V8's src directory."""
|
|
|
|
|
|
2019-02-19 08:28:26 +00:00
|
|
|
|
# for py2/py3 compatibility
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
2018-04-16 09:24:22 +00:00
|
|
|
|
import subprocess
|
|
|
|
|
import sys
|
|
|
|
|
import re
|
|
|
|
|
from subprocess import Popen, PIPE
|
|
|
|
|
|
2019-05-16 08:00:13 +00:00
|
|
|
|
kPercentEscape = r'α'; # Unicode alpha
|
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
|
def preprocess(input):
|
|
|
|
|
input = re.sub(r'(if\s+)constexpr(\s*\()', r'\1/*COxp*/\2', input)
|
|
|
|
|
input = re.sub(r'(\s+)operator\s*(\'[^\']+\')', r'\1/*_OPE \2*/', input)
|
2018-10-11 08:52:36 +00:00
|
|
|
|
|
|
|
|
|
# Mangle typeswitches to look like switch statements with the extra type
|
|
|
|
|
# information and syntax encoded in comments.
|
2018-09-24 09:28:48 +00:00
|
|
|
|
input = re.sub(r'(\s+)typeswitch\s*\(', r'\1/*_TYPE*/switch (', input)
|
2018-10-11 08:52:36 +00:00
|
|
|
|
input = re.sub(r'(\s+)case\s*\(\s*([^\:]+)\s*\)(\s*)\:\s*deferred',
|
|
|
|
|
r'\1case \2: /*_TSXDEFERRED_*/', input)
|
|
|
|
|
input = re.sub(r'(\s+)case\s*\(\s*([^\:]+)\s*\)(\s*)\:',
|
2018-09-24 09:28:48 +00:00
|
|
|
|
r'\1case \2: /*_TSX*/', input)
|
2018-10-11 08:52:36 +00:00
|
|
|
|
input = re.sub(r'(\s+)case\s*\(\s*([^\s]+)\s*\:\s*([^\:]+)\s*\)(\s*)\:\s*deferred',
|
|
|
|
|
r'\1case \3: /*_TSVDEFERRED_\2:*/', input)
|
|
|
|
|
input = re.sub(r'(\s+)case\s*\(\s*([^\s]+)\s*\:\s*([^\:]+)\s*\)(\s*)\:',
|
|
|
|
|
r'\1case \3: /*_TSV\2:*/', input)
|
|
|
|
|
|
2018-10-24 11:28:28 +00:00
|
|
|
|
# Add extra space around | operators to fix union types later.
|
|
|
|
|
while True:
|
|
|
|
|
old = input
|
|
|
|
|
input = re.sub(r'(\w+\s*)\|(\s*\w+)',
|
|
|
|
|
r'\1|/**/\2', input)
|
|
|
|
|
if old == input:
|
|
|
|
|
break;
|
|
|
|
|
|
[torque] enable multiple inheritance from Torque-generated assemblers
This enables more seamless interop between Torque and CSA:
Since CodeStubAssembler can now inherit from the Torque base namespace,
macros defined in the base namespace can be used in CodeStubAssembler
macros, even without qualification.
At the same time, macros in the base namespace can refer to
CodeStubAssembler macros. The only new limitation is that types defined
in code-stub-assembler.h cannot be referenced in the signature of macros
defined in the base namespace, since this would produce a cyclic header
dependency. A work-around for this woud be to put such types (like int31
in this CL) into a separate header included by both. I (mis-)used
code-assembler.h for that.
Another side-effec is that types and enums defined in CodeStubAssembler
have to be accessed in a qualified way from Torque.
Other assemblers can now inherit from their Torque equivalent, so
porting macros into the corresponding Torque namespace doesn't require
any change to the existing use-sites.
To avoid C++ ambiguities, the Torque-generated assemblers must not define
anything also defined in Code(Stub)Assembler. This includes the type
aliases for TNode, PLabel, ...
My workaround is to qualify everything in the generated C++.
As a drive-by fix, I had to change the formatter to avoid a situation
where it doesn't compute a fixed point: putting a keyword at the
beginning of a line removes the '\s' in front of it, so I replaced that
with '\b'.
Bug: v8:7793
Change-Id: If3b9e9ad967a181b380a10d5673615606abd1041
Reviewed-on: https://chromium-review.googlesource.com/c/1341955
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57645}
2018-11-20 10:17:24 +00:00
|
|
|
|
input = re.sub(r'\bgenerates\s+\'([^\']+)\'\s*',
|
2018-09-25 10:59:03 +00:00
|
|
|
|
r' _GeNeRaTeS00_/*\1@*/', input)
|
[torque] enable multiple inheritance from Torque-generated assemblers
This enables more seamless interop between Torque and CSA:
Since CodeStubAssembler can now inherit from the Torque base namespace,
macros defined in the base namespace can be used in CodeStubAssembler
macros, even without qualification.
At the same time, macros in the base namespace can refer to
CodeStubAssembler macros. The only new limitation is that types defined
in code-stub-assembler.h cannot be referenced in the signature of macros
defined in the base namespace, since this would produce a cyclic header
dependency. A work-around for this woud be to put such types (like int31
in this CL) into a separate header included by both. I (mis-)used
code-assembler.h for that.
Another side-effec is that types and enums defined in CodeStubAssembler
have to be accessed in a qualified way from Torque.
Other assemblers can now inherit from their Torque equivalent, so
porting macros into the corresponding Torque namespace doesn't require
any change to the existing use-sites.
To avoid C++ ambiguities, the Torque-generated assemblers must not define
anything also defined in Code(Stub)Assembler. This includes the type
aliases for TNode, PLabel, ...
My workaround is to qualify everything in the generated C++.
As a drive-by fix, I had to change the formatter to avoid a situation
where it doesn't compute a fixed point: putting a keyword at the
beginning of a line removes the '\s' in front of it, so I replaced that
with '\b'.
Bug: v8:7793
Change-Id: If3b9e9ad967a181b380a10d5673615606abd1041
Reviewed-on: https://chromium-review.googlesource.com/c/1341955
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57645}
2018-11-20 10:17:24 +00:00
|
|
|
|
input = re.sub(r'\bconstexpr\s+\'([^\']+)\'\s*',
|
2018-09-24 09:28:48 +00:00
|
|
|
|
r' _CoNsExP_/*\1@*/', input)
|
2018-09-25 15:02:46 +00:00
|
|
|
|
input = re.sub(r'\notherwise',
|
|
|
|
|
r'\n otherwise', input)
|
|
|
|
|
input = re.sub(r'(\n\s*\S[^\n]*\s)otherwise',
|
|
|
|
|
r'\1_OtheSaLi', input)
|
2019-05-16 18:56:56 +00:00
|
|
|
|
input = re.sub(r'@if\(', r'@iF(', input)
|
2019-05-20 22:14:46 +00:00
|
|
|
|
input = re.sub(r'@export', r'@eXpOrT', input)
|
2019-05-16 08:00:13 +00:00
|
|
|
|
|
|
|
|
|
# Special handing of '%' for intrinsics, turn the percent
|
|
|
|
|
# into a unicode character so that it gets treated as part of the
|
|
|
|
|
# intrinsic's name if it's already adjacent to it.
|
|
|
|
|
input = re.sub(r'%([A-Za-z])', kPercentEscape + r'\1', input)
|
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
|
return input
|
|
|
|
|
|
|
|
|
|
def postprocess(output):
|
|
|
|
|
output = re.sub(r'\/\*COxp\*\/', r'constexpr', output)
|
|
|
|
|
output = re.sub(r'(\S+)\s*: type([,>])', r'\1: type\2', output)
|
2018-11-13 13:00:34 +00:00
|
|
|
|
output = re.sub(r'(\n\s*)labels( [A-Z])', r'\1 labels\2', output)
|
2018-09-24 09:28:48 +00:00
|
|
|
|
output = re.sub(r'\/\*_OPE \'([^\']+)\'\*\/', r"operator '\1'", output)
|
|
|
|
|
output = re.sub(r'\/\*_TYPE\*\/(\s*)switch', r'typeswitch', output)
|
2018-10-19 16:00:14 +00:00
|
|
|
|
output = re.sub(r'case (\w+)\:\s*\/\*_TSXDEFERRED_\*\/',
|
2018-10-11 08:52:36 +00:00
|
|
|
|
r'case (\1): deferred', output)
|
2018-10-19 16:00:14 +00:00
|
|
|
|
output = re.sub(r'case (\w+)\:\s*\/\*_TSX\*\/',
|
2018-09-24 09:28:48 +00:00
|
|
|
|
r'case (\1):', output)
|
2018-10-19 16:00:14 +00:00
|
|
|
|
output = re.sub(r'case (\w+)\:\s*\/\*_TSVDEFERRED_([^\:]+)\:\*\/',
|
2018-10-11 08:52:36 +00:00
|
|
|
|
r'case (\2: \1): deferred', output)
|
2018-10-19 16:00:14 +00:00
|
|
|
|
output = re.sub(r'case (\w+)\:\s*\/\*_TSV([^\:]+)\:\*\/',
|
2018-09-24 09:28:48 +00:00
|
|
|
|
r'case (\2: \1):', output)
|
2018-09-25 10:59:03 +00:00
|
|
|
|
output = re.sub(r'\n_GeNeRaTeS00_\s*\/\*([^@]+)@\*\/',
|
|
|
|
|
r"\n generates '\1'", output)
|
|
|
|
|
output = re.sub(r'_GeNeRaTeS00_\s*\/\*([^@]+)@\*\/',
|
2018-09-24 09:28:48 +00:00
|
|
|
|
r"generates '\1'", output)
|
|
|
|
|
output = re.sub(r'_CoNsExP_\s*\/\*([^@]+)@\*\/',
|
|
|
|
|
r"constexpr '\1'", output)
|
2018-09-25 15:02:46 +00:00
|
|
|
|
output = re.sub(r'\n(\s+)otherwise',
|
|
|
|
|
r"\n\1 otherwise", output)
|
|
|
|
|
output = re.sub(r'\n(\s+)_OtheSaLi',
|
|
|
|
|
r"\n\1otherwise", output)
|
|
|
|
|
output = re.sub(r'_OtheSaLi',
|
|
|
|
|
r"otherwise", output)
|
2019-05-16 18:56:56 +00:00
|
|
|
|
output = re.sub(r'@iF\(', r'@if(', output)
|
2019-05-20 22:14:46 +00:00
|
|
|
|
output = re.sub(r'@eXpOrT',
|
|
|
|
|
r"@export", output)
|
2018-10-24 11:28:28 +00:00
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
old = output
|
2019-05-18 20:47:25 +00:00
|
|
|
|
output = re.sub(r'(\w+)\s{0,1}\|\s{0,1}/\*\*/(\s*\w+)',
|
|
|
|
|
r'\1 |\2', output)
|
2018-10-24 11:28:28 +00:00
|
|
|
|
if old == output:
|
|
|
|
|
break;
|
|
|
|
|
|
2019-05-16 08:00:13 +00:00
|
|
|
|
output = re.sub(kPercentEscape, r'%', output)
|
|
|
|
|
|
2018-09-24 09:28:48 +00:00
|
|
|
|
return output
|
|
|
|
|
|
2019-02-07 14:48:53 +00:00
|
|
|
|
def process(filename, lint, should_format):
|
2018-11-21 18:06:17 +00:00
|
|
|
|
with open(filename, 'r') as content_file:
|
2018-11-13 16:18:03 +00:00
|
|
|
|
content = content_file.read()
|
|
|
|
|
|
|
|
|
|
original_input = content
|
|
|
|
|
|
2019-02-20 06:53:38 +00:00
|
|
|
|
if sys.platform.startswith('win'):
|
|
|
|
|
p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
|
|
|
|
|
else:
|
|
|
|
|
p = Popen(['clang-format', '-assume-filename=.ts'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
2018-11-21 18:06:17 +00:00
|
|
|
|
output, err = p.communicate(preprocess(content))
|
2018-11-13 16:18:03 +00:00
|
|
|
|
output = postprocess(output)
|
|
|
|
|
rc = p.returncode
|
2019-02-19 08:28:26 +00:00
|
|
|
|
if (rc != 0):
|
|
|
|
|
print("error code " + str(rc) + " running clang-format. Exiting...")
|
2018-11-13 16:18:03 +00:00
|
|
|
|
sys.exit(rc);
|
|
|
|
|
|
2019-02-07 14:48:53 +00:00
|
|
|
|
if lint:
|
2018-11-13 16:18:03 +00:00
|
|
|
|
if (output != original_input):
|
2019-02-19 08:28:26 +00:00
|
|
|
|
print(filename + ' requires formatting', file=sys.stderr)
|
2019-02-07 14:48:53 +00:00
|
|
|
|
|
|
|
|
|
if should_format:
|
2018-11-21 18:06:17 +00:00
|
|
|
|
output_file = open(filename, 'w')
|
|
|
|
|
output_file.write(output);
|
2018-11-13 16:18:03 +00:00
|
|
|
|
output_file.close()
|
|
|
|
|
|
|
|
|
|
def print_usage():
|
2019-02-19 08:28:26 +00:00
|
|
|
|
print('format-torque -i file1[, file2[, ...]]')
|
|
|
|
|
print(' format and overwrite input files')
|
|
|
|
|
print('format-torque -l file1[, file2[, ...]]')
|
|
|
|
|
print(' merely indicate which files need formatting')
|
2018-11-13 16:18:03 +00:00
|
|
|
|
|
|
|
|
|
def Main():
|
|
|
|
|
if len(sys.argv) < 3:
|
2019-02-19 08:28:26 +00:00
|
|
|
|
print("error: at least 2 arguments required")
|
2018-11-13 16:18:03 +00:00
|
|
|
|
print_usage();
|
|
|
|
|
sys.exit(-1)
|
|
|
|
|
|
2019-02-07 14:48:53 +00:00
|
|
|
|
def is_option(arg):
|
|
|
|
|
return arg in ['-i', '-l', '-il']
|
|
|
|
|
|
|
|
|
|
should_format = lint = False
|
2018-11-13 16:18:03 +00:00
|
|
|
|
use_stdout = True
|
2018-04-16 09:24:22 +00:00
|
|
|
|
|
2019-02-07 14:48:53 +00:00
|
|
|
|
flag, files = sys.argv[1], sys.argv[2:]
|
|
|
|
|
if is_option(flag):
|
|
|
|
|
if '-i' == flag:
|
|
|
|
|
should_format = True
|
|
|
|
|
elif '-l' == flag:
|
|
|
|
|
lint = True
|
|
|
|
|
else:
|
|
|
|
|
lint = True
|
|
|
|
|
should_format = True
|
2018-11-13 16:18:03 +00:00
|
|
|
|
else:
|
2019-02-19 08:28:26 +00:00
|
|
|
|
print("error: -i and/or -l flags must be specified")
|
2018-11-13 16:18:03 +00:00
|
|
|
|
print_usage();
|
|
|
|
|
sys.exit(-1);
|
|
|
|
|
|
2019-02-07 14:48:53 +00:00
|
|
|
|
for filename in files:
|
|
|
|
|
process(filename, lint, should_format)
|
2018-11-13 16:18:03 +00:00
|
|
|
|
|
|
|
|
|
return 0
|
2018-04-16 09:24:22 +00:00
|
|
|
|
|
2018-11-13 16:18:03 +00:00
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
sys.exit(Main());
|