def handle_line(line: str, stmt_index: int): """Runs a single user-provided line as a REPL input.""" fn_name = f'repl_{stmt_index}' module_text = f""" import std fn {fn_name}() -> () {{ {line} }} """ # For error reporting we use a helper that puts this into a fake filesystem # location. def make_fakefs_open(): fs = fake_filesystem.FakeFilesystem() fs.CreateFile(FILENAME, module_text) return fake_filesystem.FakeFileOpen(fs) importer = import_helpers.Importer() while True: try: fake_module = parser.Parser( scanner.Scanner(FILENAME, module_text), fn_name).parse_module() except span.PositionalError as e: parser_helpers.pprint_positional_error(e, fs_open=make_fakefs_open()) return # First attempt at type checking, we expect this may fail the first time # around and we'll substitute the real return type we observe. try: type_info = typecheck.check_module(fake_module, f_import=importer) except XlsTypeError as e: # We use nil as a placeholder, and swap it with the type that was expected # and retry once we determine what that should be. if e.rhs_type == concrete_type_mod.ConcreteType.NIL: module_text = module_text.replace(' -> ()', ' -> ' + str(e.lhs_type)) continue # Any other errors are likely real type errors in the code and we should # report them. parser_helpers.pprint_positional_error(e, fs_open=make_fakefs_open()) return # It type checked ok, and we can proceed. break # Interpret the line and print the result. # TODO(leary): 2020-06-20 No let bindings for the moment, just useful for # evaluating expressions -- could put them into the module scope as consts. interpreter = interpreter_mod.Interpreter( fake_module, type_info, importer.typecheck, importer.cache, trace_all=False) result = interpreter.run_function(fn_name, args=()) print(result) type_info.clear_type_info_refs_for_gc() return result
def main(argv): if len(argv) != 2: raise app.UsageError('Too many command-line arguments.') f_import = import_helpers.Importer() text = argv[1] p = convert_helpers.convert_dslx_to_package(text, name='cli', f_import=f_import) entry = p.get_function_names()[0] opt_ir = convert_helpers.optimize_and_dump(p) benchmark_main_path = runfiles.get_path(BENCHMARK_MAIN_PATH) with tempfile.NamedTemporaryFile() as f: f.write(opt_ir.encode('utf-8')) f.flush() subprocess.check_call( [benchmark_main_path, f.name, '--entry={}'.format(entry)])
def main(argv): binary = os.path.basename(argv[0]) if len(argv) < 2: raise app.UsageError('Wrong number of command-line arguments; ' 'expect %s <input-file>' % binary) init_xls.init_xls(sys.argv) path = argv[1] with open(path, 'r') as f: text = f.read() name = os.path.basename(path) name, _ = os.path.splitext(name) module = parser_helpers.parse_text(text, name, print_on_error=True, filename=path) importer = import_helpers.Importer(tuple(FLAGS.dslx_path)) type_info = None try: type_info = cpp_typecheck.check_module( module, importer.cache, importer.additional_search_paths) if FLAGS.entry: print( ir_converter.convert_one_function(module, FLAGS.entry, type_info)) else: print(ir_converter.convert_module(module, type_info)) except (PositionalError, cpp_parser.CppParseError) as e: parser_helpers.pprint_positional_error(e) if FLAGS.raise_exception: raise else: sys.exit(1) finally: if type_info is not None: type_info.clear_type_info_refs_for_gc()
def main(argv): init_xls.init_xls(argv) if len(argv) > 2: raise app.UsageError('Too many command-line arguments.') path = argv[1] with open(path) as f: text = f.read() name = os.path.basename(path) name, _ = os.path.splitext(name) importer = import_helpers.Importer() module = parse_and_typecheck.parse_text( text, name, filename=path, print_on_error=True, import_cache=importer.cache, additional_search_paths=importer.additional_search_paths) pprint.pprint(module)
def parse_and_test(program: Text, name: Text, *, filename: Text, additional_search_paths: Tuple[str, ...] = (), raise_on_error: bool = True, test_filter: Optional[Text] = None, trace_all: bool = False, compare_jit: bool = True, seed: Optional[int] = None) -> bool: """Parses program and run all tests contained inside. Args: program: The program text to parse. name: Name for the module. filename: The filename from which "program" text originates. additional_search_paths: Additional paths at which we search for imported module files. raise_on_error: When true, raises exceptions that happen in tests; otherwise, simply returns a boolean to the caller when all test have run. test_filter: Test filter specification (e.g. as passed from bazel test environment). trace_all: Whether or not to trace all expressions. compare_jit: Whether or not to assert equality between interpreted and JIT'd function return values. seed: Seed for QuickCheck random input stimulus. Returns: Whether or not an error occurred during parsing/testing. Raises: ScanError, ParseError: In case of front-end errors. TypeInferenceError, TypeError: In case of type errors. EvaluateError: In case of a runtime failure. """ did_fail = False test_name = None type_info = None importer = import_helpers.Importer(additional_search_paths) ran = 0 try: module = Parser(Scanner(filename, program), name).parse_module() type_info = cpp_typecheck.check_module( module, importer.cache, importer.additional_search_paths) ir_package = (ir_converter.convert_module_to_package( module, type_info, traverse_tests=True) if compare_jit else None) interpreter = Interpreter(module, type_info, importer.typecheck, importer.additional_search_paths, importer.cache, trace_all=trace_all, ir_package=ir_package) for test_name in module.get_test_names(): if not _matches(test_name, test_filter): continue ran += 1 print('[ RUN UNITTEST ]', test_name, file=sys.stderr) interpreter.run_test(test_name) print('[ OK ]', test_name, file=sys.stderr) if ir_package and module.get_quickchecks(): if seed is None: # We want to guarantee non-determinism by default. See # https://abseil.io/docs/cpp/guides/random#stability-of-generated-sequences # for rationale. seed = int(os.getpid() * time.time()) print(f'[ SEED: {seed} ]') for quickcheck in module.get_quickchecks(): test_name = quickcheck.f.name.identifier print('[ RUN QUICKCHECK ]', test_name, file=sys.stderr) quickcheck_helpers.run_quickcheck(interpreter, ir_package, quickcheck, seed=seed) print('[ OK ]', test_name, file=sys.stderr) except (PositionalError, FailureError, CppParseError, ScanError, TypeInferenceError, XlsTypeError) as e: did_fail = True parser_helpers.pprint_positional_error(e, output=cast( io.IOBase, sys.stderr)) if test_name: print('[ FAILED ]', test_name, e.__class__.__name__, file=sys.stderr) if raise_on_error: raise finally: if type_info is not None: type_info.clear_type_info_refs_for_gc() print('[==================]', ran, 'test(s) ran.', file=sys.stderr) return did_fail