def convert_module_to_package( module: ast.Module, type_info: type_info_mod.TypeInfo, emit_positions: bool = True, traverse_tests: bool = False) -> ir_package.Package: """Converts the contents of a module to IR form. Args: module: Module to convert. type_info: Concrete type information used in conversion. emit_positions: Whether to emit positional metadata into the output IR. traverse_tests: Whether to convert functions called in DSLX test constructs. Note that this does NOT convert the test constructs themselves. Returns: The IR package that corresponds to this module. """ emitted = [] # type: List[Text] package = ir_package.Package(module.name) order = extract_conversion_order.get_order(module, type_info, type_info.get_imports(), traverse_tests) logging.vlog(3, 'Convert order: %s', pprint.pformat(order)) for record in order: emitted.append( _convert_one_function( package, record.m, record.f, record.type_info, symbolic_bindings=record.bindings, emit_positions=emit_positions)) verifier_mod.verify_package(package) return package
def test_builtin_is_elided(self): program = """ fn main() -> u32 { fail!(u32:0) } """ m, type_info = self._get_module(program) order = extract_conversion_order.get_order(m, type_info, imports={}) self.assertLen(order, 1) self.assertEqual(order[0].f.identifier, 'main') self.assertEqual(order[0].bindings, SymbolicBindings())
def test_simple_linear_callgraph(self): program = """ fn g() -> u32 { u32:42 } fn f() -> u32 { g() } fn main() -> u32 { f() } """ m, type_info = self._get_module(program) order = extract_conversion_order.get_order(m, type_info, imports={}) self.assertLen(order, 3) self.assertEqual(order[0].f.identifier, 'g') self.assertEqual(order[1].f.identifier, 'f') self.assertEqual(order[2].f.identifier, 'main')
def test_transitive_parametric(self): program = """ fn g<M: u32>(x: bits[M]) -> u32 { M } fn f<N: u32>(x: bits[N]) -> u32 { g(x) } fn main() -> u32 { f(u2:0) } """ m, type_info = self._get_module(program) order = extract_conversion_order.get_order(m, type_info, imports={}) self.assertLen(order, 3) self.assertEqual(order[0].f.identifier, 'g') self.assertEqual(order[0].bindings, SymbolicBindings([('M', 2)])) self.assertEqual(order[1].f.identifier, 'f') self.assertEqual(order[1].bindings, SymbolicBindings([('N', 2)])) self.assertEqual(order[2].f.identifier, 'main') self.assertEqual(order[2].bindings, SymbolicBindings())
def test_transitive_parametric(self): program = """ fn [M: u32] g(x: bits[M]) -> u32 { M } fn [N: u32] f(x: bits[N]) -> u32 { g(x) } fn main() -> u32 { f(u2:0) } """ m, node_to_type = self._get_module(program) order = extract_conversion_order.get_order(m, node_to_type, imports={}) self.assertLen(order, 3) self.assertEqual(order[0].f.identifier, 'g') self.assertEqual(order[0].bindings, (('M', 2), )) self.assertEqual(order[1].f.identifier, 'f') self.assertEqual(order[1].bindings, (('N', 2), )) self.assertEqual(order[2].f.identifier, 'main') self.assertEqual(order[2].bindings, ())
def test_parametric(self): program = """ fn f<N: u32>(x: bits[N]) -> u32 { N } fn main() -> u32 { f(u2:0) } """ m, type_info = self._get_module(program) order = extract_conversion_order.get_order(m, type_info, imports={}) self.assertLen(order, 2) self.assertEqual(order[0].f.identifier, 'f') self.assertEqual(order[0].bindings, SymbolicBindings([('N', 2)])) self.assertEqual(order[0].callees, ()) self.assertEqual(order[1].f.identifier, 'main') self.assertEqual(order[1].bindings, SymbolicBindings()) f = m.get_function('f') self.assertEqual( tuple((c.f, c.m, c.sym_bindings) for c in order[1].callees), ((f, m, SymbolicBindings([('N', 2)])), ))