def type_to_rtype(self, typ: Type) -> RType: if isinstance(typ, Instance): if typ.type.fullname() == 'builtins.int': return IntRType() elif typ.type.fullname() == 'builtins.bool': return BoolRType() elif typ.type.fullname() == 'builtins.list': return ListRType() elif typ.type.fullname() == 'builtins.dict': return DictRType() elif typ.type.fullname() == 'builtins.tuple': return SequenceTupleRType() elif typ.type in self.type_to_ir: return UserRType(self.type_to_ir[typ.type]) elif isinstance(typ, TupleType): return TupleRType([self.type_to_rtype(t) for t in typ.items]) elif isinstance(typ, CallableType): return ObjectRType() elif isinstance(typ, NoneTyp): return NoneRType() elif isinstance(typ, UnionType): assert len(typ.items) == 2 and any( isinstance(it, NoneTyp) for it in typ.items) if isinstance(typ.items[0], NoneTyp): value_type = typ.items[1] else: value_type = typ.items[0] return OptionalRType(self.type_to_rtype(value_type)) assert False, '%s unsupported' % type(typ)
def binary_op(self, ltype: RType, lreg: Register, rtype: RType, rreg: Register, expr_op: str, target: Optional[Register] = None) -> Register: if ltype.name == 'int' and rtype.name == 'int': # Primitive int operation if target is None: target = self.alloc_target(IntRType()) op = self.int_binary_ops[expr_op] elif (ltype.name == 'list' or rtype.name == 'list') and expr_op == '*': if rtype.name == 'list': ltype, rtype = rtype, ltype lreg, rreg = rreg, lreg if rtype.name != 'int': assert False, 'Unsupported binary operation' # TODO: Operator overloading if target is None: target = self.alloc_target(ListRType()) op = PrimitiveOp.LIST_REPEAT elif isinstance(rtype, DictRType): if expr_op == 'in': if target is None: target = self.alloc_target(BoolRType()) lreg = self.box(lreg, ltype) op = PrimitiveOp.DICT_CONTAINS else: assert False, 'Unsupported binary operation' else: assert False, 'Unsupported binary operation' self.add(PrimitiveOp(target, op, lreg, rreg)) return target
def visit_name_expr(self, expr: NameExpr) -> Register: if expr.node.fullname() == 'builtins.None': target = self.alloc_target(NoneRType()) self.add(PrimitiveOp(target, PrimitiveOp.NONE)) return target elif expr.node.fullname() == 'builtins.True': target = self.alloc_target(BoolRType()) self.add(PrimitiveOp(target, PrimitiveOp.TRUE)) return target elif expr.node.fullname() == 'builtins.False': target = self.alloc_target(BoolRType()) self.add(PrimitiveOp(target, PrimitiveOp.FALSE)) return target if not self.is_native_name_expr(expr): return self.load_static_module_attr(expr) # TODO: We assume that this is a Var node, which is very limited assert isinstance(expr.node, Var) reg = self.environment.lookup(expr.node) return self.get_using_binder(reg, expr.node, expr)
def setUp(self) -> None: self.env = Environment() self.n = self.env.add_local(Var('n'), IntRType()) self.m = self.env.add_local(Var('m'), IntRType()) self.k = self.env.add_local(Var('k'), IntRType()) self.l = self.env.add_local(Var('l'), ListRType()) self.ll = self.env.add_local(Var('ll'), ListRType()) self.o = self.env.add_local(Var('o'), ObjectRType()) self.o2 = self.env.add_local(Var('o2'), ObjectRType()) self.d = self.env.add_local(Var('d'), DictRType()) self.b = self.env.add_local(Var('b'), BoolRType()) self.context = EmitterContext() self.emitter = Emitter(self.context, self.env) self.declarations = Emitter(self.context, self.env) self.visitor = FunctionEmitterVisitor(self.emitter, self.declarations)
def test_tuple_get(self) -> None: self.assert_emit(TupleGet(self.m, self.n, 1, BoolRType()), 'cpy_r_m = cpy_r_n.f1;')
def test_set_attr(self) -> None: ir = ClassIR('A', [('x', BoolRType()), ('y', IntRType())]) rtype = UserRType(ir) self.assert_emit( SetAttr(self.n, 'y', self.m, rtype), """CPY_SET_ATTR(cpy_r_n, 3, cpy_r_m, AObject, CPyTagged);""")
def test_get_attr(self) -> None: ir = ClassIR('A', [('x', BoolRType()), ('y', IntRType())]) rtype = UserRType(ir) self.assert_emit( GetAttr(self.n, self.m, 'y', rtype), """cpy_r_n = CPY_GET_ATTR(cpy_r_m, 2, AObject, CPyTagged);""")
def test_dec_ref_tuple_nested(self) -> None: tuple_type = TupleRType( [TupleRType([IntRType(), BoolRType()]), BoolRType()]) self.assert_emit(DecRef(self.m, tuple_type), 'CPyTagged_DecRef(cpy_r_m.f0.f0);')