Beispiel #1
0
 def make_class_constructor(self, tdef: ClassDef) -> None:
     # Do we have a non-empty __init__?
     init = cast(FuncDef, tdef.info.get_method('__init__'))
     init_argc = len(init.args) - 1
     if init.info.fullname() == 'builtins.object':
         init = None
     
     self.enter()
     if init:
         args = [] # type: List[int]
         for arg in init.args[1:]:
             args.append(self.add_local(arg))
     target = self.alloc_register()
     self.add(Construct(target, tdef.info))
     # Inititalize data attributes to default values.
     for name, node in sorted(tdef.info.names.items()):
         if isinstance(node.node, Var):
             var = cast(Var, node.node)
             temp = self.alloc_register()
             vtype = var.type
             if is_named_instance(vtype, 'builtins.int'):
                 self.add(SetRI(temp, 0))
             else:
                 self.add(SetRNone(temp))
             self.add(SetAttr(target, name, temp, tdef.info))
     if init:
         self.add(CallMethod(self.alloc_register(), target, '__init__',
                             init.info, args, static=True))
     self.add(Return(target))
     self.generated[tdef.name] = FuncIcode(init_argc, self.blocks,
                                           self.register_types)
     self.leave()
Beispiel #2
0
 def visit_mypy_file(self, mfile: MypyFile) -> int:
     if mfile.fullname() in ('typing', 'abc'):
         # These module are special; their contents are currently all
         # built-in primitives.
         return -1
     
     self.enter()
     
     # Initialize non-int global variables.
     for name in sorted(mfile.names):
         node = mfile.names[name].node
         if (isinstance(node, Var) and
                 name not in nodes.implicit_module_attrs):
             v = cast(Var, node)
             if (not is_named_instance(v.type, 'builtins.int')
                     and v.fullname() != 'typing.Undefined'):
                 tmp = self.alloc_register()
                 self.add(SetRNone(tmp))
                 self.add(SetGR(v.fullname(), tmp))
     
     for d in mfile.defs:
         d.accept(self)
     self.add_implicit_return()
     self.generated['__init'] = FuncIcode(0, self.blocks,
                                          self.register_types)
     # TODO leave?
     return -1
Beispiel #3
0
    def visit_mypy_file(self, mfile: MypyFile) -> int:
        if mfile.fullname() in ('typing', 'abc'):
            # These module are special; their contents are currently all
            # built-in primitives.
            return -1

        self.enter()

        # Initialize non-int global variables.
        for name in sorted(mfile.names):
            node = mfile.names[name].node
            if (isinstance(node, Var)
                    and name not in nodes.implicit_module_attrs):
                v = cast(Var, node)
                if (not is_named_instance(v.type, 'builtins.int')
                        and v.fullname() != 'typing.Undefined'):
                    tmp = self.alloc_register()
                    self.add(SetRNone(tmp))
                    self.add(SetGR(v.fullname(), tmp))

        for d in mfile.defs:
            d.accept(self)
        self.add_implicit_return()
        self.generated['__init'] = FuncIcode(0, self.blocks,
                                             self.register_types)
        # TODO leave?
        return -1
Beispiel #4
0
 def add_local(self, node: Var) -> int:
     type = REF
     if is_named_instance(node.type, 'builtins.int'):
         type = INT
     reg = self.alloc_register(type)
     self.lvar_regs[node] = reg
     return reg
Beispiel #5
0
 def make_class_constructor(self, tdef):
     # Do we have a non-empty __init__?
     init = tdef.info.get_method('__init__')
     init_argc = len(init.args) - 1
     if init.info.full_name() == 'builtins.object':
         init = None
     
     self.enter()
     if init:
         args = []
         for arg in init.args[1:]:
             args.append(self.add_local(arg))
     target = self.alloc_register()
     self.add(Construct(target, tdef.info))
     # Inititalize data attributes to default values.
     for var in sorted(tdef.info.vars.keys()):
         temp = self.alloc_register()
         vtype = tdef.info.vars[var].type
         if is_named_instance(vtype, 'builtins.int'):
             self.add(SetRI(temp, 0))
         else:
             self.add(SetRNone(temp))
         self.add(SetAttr(target, var, temp, tdef.info))
     if init:
         self.add(CallMethod(self.alloc_register(), target, '__init__',
                             init.info, args, static=True))
     self.add(Return(target))
     self.generated[tdef.name] = FuncIcode(init_argc, self.blocks,
                                           self.register_types)
     self.leave()
Beispiel #6
0
 def visit_coerce_expr(self, e: CoerceExpr) -> int:
     if is_named_instance(e.source_type, "builtins.int") and isinstance(e.target_type, AnyType):
         # This is a no-op currently.
         # TODO perhaps should do boxing in some cases...
         return e.expr.accept(self)
     else:
         # Non-trivial coercions not supported yet.
         raise NotImplementedError()
Beispiel #7
0
 def add_implicit_return(self, sig: FunctionLike = None) -> None:
     if not self.current.ops or not isinstance(self.current.ops[-1], Return):
         r = self.alloc_register()
         if sig and is_named_instance((cast(Callable, sig)).ret_type, "builtins.int"):
             self.add(SetRI(r, 0))
         else:
             self.add(SetRNone(r))
         self.add(Return(r))
Beispiel #8
0
 def visit_coerce_expr(self, e: CoerceExpr) -> int:
     if (is_named_instance(e.source_type, 'builtins.int')
             and isinstance(e.target_type, AnyType)):
         # This is a no-op currently.
         # TODO perhaps should do boxing in some cases...
         return e.expr.accept(self)
     else:
         # Non-trivial coercions not supported yet.
         raise NotImplementedError()
Beispiel #9
0
 def visit_instance(self, template: Instance) -> List[Constraint]:
     actual = self.actual
     res = []  # type: List[Constraint]
     if isinstance(actual, Instance):
         instance = cast(Instance, actual)
         if (self.direction == SUBTYPE_OF
                 and template.type.has_base(instance.type.fullname())):
             mapped = map_instance_to_supertype(template, instance.type)
             for i in range(len(instance.args)):
                 # The constraints for generic type parameters are
                 # invariant. Include the default constraint and its
                 # negation to achieve the effect.
                 cb = infer_constraints(mapped.args[i], instance.args[i],
                                        self.direction)
                 res.extend(cb)
                 res.extend(negate_constraints(cb))
             return res
         elif (self.direction == SUPERTYPE_OF
               and instance.type.has_base(template.type.fullname())):
             mapped = map_instance_to_supertype(instance, template.type)
             for j in range(len(template.args)):
                 # The constraints for generic type parameters are
                 # invariant.
                 cb = infer_constraints(template.args[j], mapped.args[j],
                                        self.direction)
                 res.extend(cb)
                 res.extend(negate_constraints(cb))
             return res
     if isinstance(actual, AnyType):
         # IDEA: Include both ways, i.e. add negation as well?
         return self.infer_against_any(template.args)
     if (isinstance(actual, TupleType)
             and (is_named_instance(template, 'typing.Iterable')
                  or is_named_instance(template, 'typing.Sequence')
                  or is_named_instance(template, 'typing.Reversible'))
             and self.direction == SUPERTYPE_OF):
         actual = cast(TupleType, actual)
         for item in actual.items:
             cb = infer_constraints(template.args[0], item, SUPERTYPE_OF)
             res.extend(cb)
         return res
     else:
         return []
Beispiel #10
0
 def add_implicit_return(self, sig=None):
     if not self.current.ops or not isinstance(self.current.ops[-1],
                                               Return):
         r = self.alloc_register()
         if sig and is_named_instance((sig).ret_type,
                                      'builtins.int'):
             self.add(SetRI(r, 0))
         else:
             self.add(SetRNone(r))
         self.add(Return(r))
Beispiel #11
0
 def visit_instance(self, template: Instance) -> List[Constraint]:
     actual = self.actual
     res = []  # type: List[Constraint]
     if isinstance(actual, Instance):
         instance = cast(Instance, actual)
         if (self.direction == SUBTYPE_OF and
                 template.type.has_base(instance.type.fullname())):
             mapped = map_instance_to_supertype(template, instance.type)
             for i in range(len(instance.args)):
                 # The constraints for generic type parameters are
                 # invariant. Include the default constraint and its
                 # negation to achieve the effect.
                 cb = infer_constraints(mapped.args[i], instance.args[i],
                                        self.direction)
                 res.extend(cb)
                 res.extend(negate_constraints(cb))
             return res
         elif (self.direction == SUPERTYPE_OF and
                 instance.type.has_base(template.type.fullname())):
             mapped = map_instance_to_supertype(instance, template.type)
             for j in range(len(template.args)):
                 # The constraints for generic type parameters are
                 # invariant.
                 cb = infer_constraints(template.args[j], mapped.args[j],
                                        self.direction)
                 res.extend(cb)
                 res.extend(negate_constraints(cb))
             return res
     if isinstance(actual, AnyType):
         # IDEA: Include both ways, i.e. add negation as well?
         return self.infer_against_any(template.args)
     if (isinstance(actual, TupleType) and
         (is_named_instance(template, 'typing.Iterable') or
          is_named_instance(template, 'typing.Sequence') or
          is_named_instance(template, 'typing.Reversible'))
             and self.direction == SUPERTYPE_OF):
         actual = cast(TupleType, actual)
         for item in actual.items:
             cb = infer_constraints(template.args[0], item, SUPERTYPE_OF)
             res.extend(cb)
         return res
     else:
         return []
Beispiel #12
0
 def add_implicit_return(self, sig: FunctionLike = None) -> None:
     if not self.current.ops or not isinstance(self.current.ops[-1],
                                               Return):
         r = self.alloc_register()
         if sig and is_named_instance(
             (cast(Callable, sig)).ret_type, 'builtins.int'):
             self.add(SetRI(r, 0))
         else:
             self.add(SetRNone(r))
         self.add(Return(r))
Beispiel #13
0
 def visit_op_expr(self, e: OpExpr) -> int:
     # TODO arbitrary operand types
     left_type = self.types[e.left]
     right_type = self.types[e.right]
     if is_named_instance(left_type, "builtins.int") and is_named_instance(right_type, "builtins.int"):
         # Primitive operation
         left, left_kind = self.get_operand(e.left)
         right, right_kind = self.get_operand(e.right)
         target = self.target_register()
         self.add(BinOp(target, left, left_kind, right, right_kind, e.op))
     else:
         # Generate method call
         inst = cast(Instance, left_type)
         left = self.accept(e.left)
         right = self.accept(e.right)
         target = self.target_register()
         method = nodes.op_methods[e.op]
         if e.op == "in":
             left, right = right, left
             inst = cast(Instance, right_type)
         self.add(CallMethod(target, left, method, inst.type, [right]))
     return target
Beispiel #14
0
 def visit_op_expr(self, e: OpExpr) -> int:
     # TODO arbitrary operand types
     left_type = self.types[e.left]
     right_type = self.types[e.right]
     if (is_named_instance(left_type, 'builtins.int')
             and is_named_instance(right_type, 'builtins.int')):
         # Primitive operation
         left, left_kind = self.get_operand(e.left)
         right, right_kind = self.get_operand(e.right)
         target = self.target_register()
         self.add(BinOp(target, left, left_kind, right, right_kind, e.op))
     else:
         # Generate method call
         inst = cast(Instance, left_type)
         left = self.accept(e.left)
         right = self.accept(e.right)
         target = self.target_register()
         method = nodes.op_methods[e.op]
         if e.op == 'in':
             left, right = right, left
             inst = cast(Instance, right_type)
         self.add(CallMethod(target, left, method, inst.type, [right]))
     return target
Beispiel #15
0
 def visit_unary_expr(self, e: UnaryExpr) -> int:
     operand_type = self.types[e.expr]
     operand = self.accept(e.expr)
     target = self.target_register()
     if is_named_instance(operand_type, 'builtins.int'):
         self.add(UnaryOp(target, operand, e.op))
     else:
         if e.op == '-':
             method = '__neg__'
         elif e.op == '~':
             method = '__invert__'
         else:
             raise NotImplementedError()
         inst = cast(Instance, operand_type) # TODO more flexible
         self.add(CallMethod(target, operand, method, inst.type, []))
     return target
Beispiel #16
0
 def visit_unary_expr(self, e: UnaryExpr) -> int:
     operand_type = self.types[e.expr]
     operand = self.accept(e.expr)
     target = self.target_register()
     if is_named_instance(operand_type, 'builtins.int'):
         self.add(UnaryOp(target, operand, e.op))
     else:
         if e.op == '-':
             method = '__neg__'
         elif e.op == '~':
             method = '__invert__'
         else:
             raise NotImplementedError()
         inst = cast(Instance, operand_type)  # TODO more flexible
         self.add(CallMethod(target, operand, method, inst.type, []))
     return target
Beispiel #17
0
 def visit_mypy_file(self, mfile):
     self.enter()
     
     # Initialize non-int global variables.
     for name in sorted(mfile.names):
         node = mfile.names[name].node
         if isinstance(node, Var) and name != '__name__':
             v = node
             if not is_named_instance(v.type, 'builtins.int'):
                 tmp = self.alloc_register()
                 self.add(SetRNone(tmp))
                 self.add(SetGR(v.full_name(), tmp))
     
     for d in mfile.defs:
         d.accept(self)
     self.add_implicit_return()
     self.generated['__init'] = FuncIcode(0, self.blocks,
                                          self.register_types)
     # TODO leave?
     return -1
Beispiel #18
0
    def make_class_constructor(self, tdef: ClassDef) -> None:
        # Do we have a non-empty __init__?
        init = cast(FuncDef, tdef.info.get_method('__init__'))
        init_argc = len(init.args) - 1
        if init.info.fullname() == 'builtins.object':
            init = None

        self.enter()
        if init:
            args = []  # type: List[int]
            for arg in init.args[1:]:
                args.append(self.add_local(arg))
        target = self.alloc_register()
        self.add(Construct(target, tdef.info))
        # Inititalize data attributes to default values.
        for name, node in sorted(tdef.info.names.items()):
            if isinstance(node.node, Var):
                var = cast(Var, node.node)
                temp = self.alloc_register()
                vtype = var.type
                if is_named_instance(vtype, 'builtins.int'):
                    self.add(SetRI(temp, 0))
                else:
                    self.add(SetRNone(temp))
                self.add(SetAttr(target, name, temp, tdef.info))
        if init:
            self.add(
                CallMethod(self.alloc_register(),
                           target,
                           '__init__',
                           init.info,
                           args,
                           static=True))
        self.add(Return(target))
        self.generated[tdef.name] = FuncIcode(init_argc, self.blocks,
                                              self.register_types)
        self.leave()