def test_ints(self): a = TypeDB.get_type_by_value(1) b = TypeDB.get_type_by_value(int) c = TypeDB.get_type_by_name("int") self.assertEqual(a, b) self.assertEqual(a, c) self.assertEqual(b, c) self.assertEqual(a, a) self.assertEqual(a, int)
def process_list(self, subscript: ast.AST): if isinstance(subscript, ast.Index): return TypeDB.get_list([self.visit(subscript.value)]) elif isinstance(subscript, ast.Slice): if isinstance(subscript.upper, ast.Num) and isinstance( subscript.upper.n, int): return TypeDB.get_list([self.visit(subscript.lower)], maxlen=subscript.upper.n) else: raise StaticTypeError("List length must be integer")
def visit_Try(self, node: ast.Try): if node.orelse: raise UnimplementedFeature("Can't have an else section to try") if node.finalbody: raise UnimplementedFeature("Can't have an finally section to try") self.start_line("Try {\n") self.indent += 4 self.in_try_block = True for n in node.body: self.visit(n) # noinspection PyAttributeOutsideInit self.in_try_block = False self.indent -= 4 exception_name = self.context.get_temp_var( TypeDB.get_type_by_name("int")) self.start_line(f"}} Catch({exception_name.code}) {{\n") self.indent += 4 self.start_line(f"switch ({exception_name.code}) {{\n") for handler in node.handlers: if handler.type is None: self.start_line("case default:\n") else: self.start_line(f"case {handler.type.id}:\n") self.indent += 4 for n in handler.body: self.visit(n) self.start_line("break;\n") self.indent -= 4 self.start_line("}") self.indent -= 4 self.start_line("}")
def visit_For(self, node: ast.For) -> None: # create list to iterate over lst_name = self.context.get_temp_name() assign_node = ast.Assign( targets=[ast.Name(id=lst_name, ctx=ast.Store())], value=node.iter) self.visit(assign_node) lst = self.context[lst_name] index = self.context.get_temp_var(TypeDB.get_type_by_name("int")) length = lst.tp.get_method("len") length_code = length.get_code(self.context, lst).code # construct for statement self.start_line( f"for({index.code}=0; {index.code} < {length_code}; {index.code}++) {{\n" ) self.indent += 4 assign_node = ast.Assign( targets=[node.target], value=ast.Subscript( value=ast.Name(id=lst_name, ctx=ast.Load()), slice=ast.Index(value=ast.Name(id=index.code, ctx=ast.Load())), ctx=ast.Load())) self.visit(assign_node) for statement in node.body: self.visit(statement) self.indent -= 4 self.start_line("}\n") self.all_paths_return = False
def test_something(self): tree = ast.parse(TEST_CODE) m = ModuleParser() m.visit(tree) TypeDB.get_type_by_name("int") TypeDB.get_type_by_name("float") TypeDB.get_string()
def generate_code(self): self.body = "" self.in_try_block = False self.indent = 4 self.retval = Code(tp=None, code="_retval", is_pointer=True) self.all_paths_return = False self.context.clear_temp_vars() # clear struct if class init if self.is_init(): self.start_line(f"*self = ({self.args[0].tp.c_type}){{0}};\n") for n in self.primary_node.body: self.visit(n) if not self.all_paths_return: self.retval.assign_type(TypeDB.get_type_by_value(None), " as return value")
def get_code(self, context: Context, *args: Code) -> Code: prepends = [] format_strs = [] codes = [] for arg in args: if arg.tp == "int": format_strs.append("%d") codes.append(arg.code) elif arg.tp == "float": format_strs.append("%f") codes.append(arg.code) elif arg.tp.name.strip("str__"): format_strs.append("%s") codes.append(f"{arg.as_accessor()}text") codes = [f'"{" ".join(format_strs)}\\n"'] + codes return_code = Code(tp=TypeDB.get_type_by_value(None), code=f"printf({', '.join(codes)})", libraries=["stdio"], prepends=prepends) return return_code
def test_int_equality_fails_with_bad_comparator(self): a = TypeDB.get_type_by_value(1) self.assertFalse((a == self))
def __init__(self): super().__init__("print", args=[], returns=TypeDB.get_type_by_value(None))
def visit_Name(self, node: ast.Name): return TypeDB.get_type_by_name(node.id)
def test_create_weird_type_fails(self): with self.assertRaises(AttributeError): TypeDB.get_type_by_name("fred")