forked from M-Labs/artiq
Add lit-based tests for type inferencer.
This commit is contained in:
parent
5f06c6af10
commit
7f77632f1a
|
@ -13,3 +13,4 @@ doc/manual/_build
|
|||
/*.egg-info
|
||||
/.coverage
|
||||
examples/master/results
|
||||
Output/
|
||||
|
|
|
@ -129,10 +129,10 @@ class LocalExtractor(algorithm.Visitor):
|
|||
class Inferencer(algorithm.Transformer):
|
||||
def __init__(self, engine):
|
||||
self.engine = engine
|
||||
self.env_stack = [{}]
|
||||
self.env_stack = []
|
||||
self.function = None # currently visited function
|
||||
|
||||
def _unify(self, typea, typeb, loca, locb, kind):
|
||||
def _unify(self, typea, typeb, loca, locb, kind='generic'):
|
||||
try:
|
||||
typea.unify(typeb)
|
||||
except types.UnificationError as e:
|
||||
|
@ -186,6 +186,13 @@ class Inferencer(algorithm.Transformer):
|
|||
"name '{name}' is not bound to anything", {"name":name}, loc)
|
||||
self.engine.process(diag)
|
||||
|
||||
def visit_root(self, node):
|
||||
extractor = LocalExtractor(env_stack=self.env_stack, engine=self.engine)
|
||||
extractor.visit(node)
|
||||
self.env_stack.append(extractor.typing_env)
|
||||
|
||||
return self.visit(node)
|
||||
|
||||
# Visitors that replace node with a typed node
|
||||
#
|
||||
def visit_arg(self, node):
|
||||
|
@ -349,17 +356,25 @@ class Printer(algorithm.Visitor):
|
|||
super().generic_visit(node)
|
||||
|
||||
def main():
|
||||
import sys, fileinput
|
||||
import sys, fileinput, os
|
||||
|
||||
inference_mode = True
|
||||
|
||||
engine = diagnostic.Engine(all_errors_are_fatal=True)
|
||||
try:
|
||||
buf = source.Buffer("".join(fileinput.input()), fileinput.filename())
|
||||
parsed = parse_buffer(buf, engine=engine)
|
||||
typed = Inferencer(engine=engine).visit(parsed)
|
||||
buf = source.Buffer("".join(fileinput.input()), os.path.basename(fileinput.filename()))
|
||||
parsed, comments = parse_buffer(buf, engine=engine)
|
||||
typed = Inferencer(engine=engine).visit_root(parsed)
|
||||
printer = Printer(buf)
|
||||
printer.visit(typed)
|
||||
for comment in comments:
|
||||
if comment.text.find("CHECK") >= 0:
|
||||
printer.rewriter.remove(comment.loc)
|
||||
print(printer.rewrite().source)
|
||||
except diagnostic.Error as e:
|
||||
print("\n".join(e.diagnostic.render()), file=sys.stderr)
|
||||
if inference_mode:
|
||||
print("\n".join(e.diagnostic.render()), file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
The purpose of this harness is to emulate the behavior of
|
||||
the python executable, but add the ARTIQ root to sys.path
|
||||
beforehand.
|
||||
|
||||
This is necessary because eggs override the PYTHONPATH environment
|
||||
variable, but not current directory; therefore `python -m artiq...`
|
||||
ran from the ARTIQ root would work, but there is no simple way to
|
||||
emulate the same behavior when invoked under lit.
|
||||
"""
|
||||
|
||||
import sys, os, argparse, importlib
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('-m', metavar='mod', type=str, help='run library module as a script')
|
||||
parser.add_argument('args', type=str, nargs='+', help='arguments passed to program in sys.argv[1:]')
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
artiq_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
sys.path.insert(1, artiq_path)
|
||||
|
||||
sys.argv[1:] = args.args
|
||||
importlib.import_module(args.m).main()
|
|
@ -0,0 +1,12 @@
|
|||
import lit.util
|
||||
import lit.formats
|
||||
|
||||
config.name = 'ARTIQ'
|
||||
config.test_format = lit.formats.ShTest()
|
||||
config.suffixes = ['.py']
|
||||
config.excludes = ['harness.py']
|
||||
config.test_source_root = os.path.dirname(__file__)
|
||||
|
||||
python_executable = 'python3'
|
||||
harness = '{} {}'.format(python_executable, os.path.join(config.test_source_root, 'harness.py'))
|
||||
config.substitutions.append( ('%python', harness) )
|
|
@ -0,0 +1,26 @@
|
|||
# RUN: %python -m artiq.py2llvm.typing %s >%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
a = 1
|
||||
# CHECK-L: a:int(width='a)
|
||||
|
||||
b = a
|
||||
# CHECK-L: b:int(width='a)
|
||||
|
||||
c = True
|
||||
# CHECK-L: c:bool
|
||||
|
||||
d = False
|
||||
# CHECK-L: d:bool
|
||||
|
||||
e = None
|
||||
# CHECK-L: e:NoneType
|
||||
|
||||
f = 1.0
|
||||
# CHECK-L: f:float
|
||||
|
||||
g = []
|
||||
# CHECK-L: g:list(elt='b)
|
||||
|
||||
h = [1]
|
||||
# CHECK-L: h:list(elt=int(width='c))
|
2
setup.py
2
setup.py
|
@ -6,7 +6,7 @@ from setuptools import setup, find_packages
|
|||
requirements = [
|
||||
"sphinx", "sphinx-argparse", "pyserial", "numpy", "scipy",
|
||||
"python-dateutil", "prettytable", "h5py", "pydaqmx", "pyelftools",
|
||||
"quamash", "pyqtgraph", "pythonparser"
|
||||
"quamash", "pyqtgraph", "pythonparser", "lit", "OutputCheck"
|
||||
]
|
||||
|
||||
scripts = [
|
||||
|
|
Loading…
Reference in New Issue