Exemplo n.º 1
0
    def __missing__(self, key) -> TypeScheme:
        from xotl.fl.utils import tvarsupply
        from xotl.fl.match import MatchLiteral, Extract
        from xotl.fl.ast.types import TypeVariable

        # Constructors of tuples are not fixed, since now you can have (1, 2,
        # 3..., 10000); that's a long tuple with a single constructor
        # (,,...,,); i.e 9999 commas.
        if isinstance(key, str) and TUPLE_CONS.match(key):
            items = len(key) + 1
            names = list(tvarsupply(limit=items))
            type: Type = TypeCons(key, names)
            for name in reversed(names):
                type = name >> type
            return TypeScheme.from_typeexpr(type)
        elif isinstance(key, Extract) and TUPLE_CONS.match(key.name):
            # The type of 'extract' for tuple varies with the number of
            # components of the tuple.  Example, for a triple, Extract(',,',
            # 2) -- i.e. extracting the second element; has the type scheme
            # 'forall a b c r. (a, b, c) -> (b -> r) -> r'.
            type_ = self[key.name].type_
            assert isinstance(type_, TypeCons)
            res = TypeVariable(".r", check=False)
            return TypeScheme.from_typeexpr(type_ >> (
                (type_.subtypes[key.arg - 1] >> res) >> res))
        elif isinstance(key, MatchLiteral):
            # The match has type 'a -> (a -> r) -> r'; where a is the type of
            # the literal.  We must ensure to generate a new variable not free
            # in type a.  Everywhere else we generate types '.a0', '.a1'.
            # Let's use '.r' as the result type.
            a = key.value.type_
            res = TypeVariable(".r", check=False)
            return TypeScheme.from_typeexpr(a >> ((a >> res) >> res))
        else:
            raise KeyError(key)  # pragma: no cover
Exemplo n.º 2
0
 def result(name: str) -> Type:
     missing = object()
     restype: Type = missing  # type: ignore
     pos = 0
     while restype is missing and pos < len(lst):
         generic, newvar = lst[pos]
         pos += 1
         if generic == name:
             restype = newvar
     if restype is missing:
         return TypeVariable(name, check=False)
     else:
         return restype
Exemplo n.º 3
0
 def type_variable(self, tree):
     token: Token = tree.children[0]
     return TypeVariable(token.value)
Exemplo n.º 4
0
 def __missing__(self, key) -> TypeSchema:
     try:
         return super().__missing__(key)
     except KeyError:
         var = TypeVariable(key, check=False)
         return TypeSchema.from_typeexpr(var)
Exemplo n.º 5
0
 def __next__(self) -> TypeVariable:
     name = next(self.ns)
     return TypeVariable(name, check=False)
Exemplo n.º 6
0
 def __call__(self, s: str) -> Type:
     return self.type_ if s == self.vname else TypeVariable(s, check=False)
Exemplo n.º 7
0
 def __call__(self, s: str) -> Type:
     return TypeVariable(s, check=False)
Exemplo n.º 8
0
 def __call__(self, s: str) -> Type:
     if s not in self.ts.generics:
         return self.phi(s)
     else:
         return TypeVariable(s, check=False)