コード例 #1
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def tupleToList(cls, tp):
     if tp.isFinal:
         return Type(ErlType.generateListAnyType())
     else:
         # preprocess unions
         if ErlType.isUnion(tp.typ):
             inner_types = cc.get_inner_types_from_union(tp.typ)
             isCnd = lambda x: ErlType.isTuple(x) or ErlType.isTupleDet(x)
             candidates = [t for t in inner_types if isCnd(t)]
             if len(candidates) > 0:
                 tp.typ = candidates[0]
                 if ErlType.isTupleDet(tp.typ):
                     ts = cc.get_inner_types_from_tupledet(tp.typ)
                     sz = len(ts)
                     tp.matchNTuple(sz)
             else:
                 # TODO Log inconsistency
                 pass
         # actual type elaborations
         if ErlType.isTuple(tp.typ):
             return Type(ErlType.generateListAnyType())
         elif ErlType.isTupleDet(tp.typ):
             children = tp.getChildren()
             t = Type(ErlType.generateListAnyType())
             for child in reversed(children):
                 t = cls.makeCons(child, t)
             return t
         else:
             # TODO Log inconsistency (if is not any())
             return Type(ErlType.generateListAnyType())
コード例 #2
0
ファイル: cuter_print.py プロジェクト: uldza/cuter
def pretty_type(d):
    if cc.is_type_any(d):
        return "any"
    if cc.is_type_atom(d):
        return "atom"
    if cc.is_type_atomlit(d):
        return pretty(cc.get_literal_from_atomlit(d))
    if cc.is_type_float(d):
        return "float"
    if cc.is_type_integer(d):
        return "integer"
    if cc.is_type_integerlit(d):
        return pretty(cc.get_literal_from_integerlit(d))
    if cc.is_type_list(d):
        return "[%s]" % pretty_type(cc.get_inner_type_from_list(d))
    if cc.is_type_nil(d):
        return "[]"
    if cc.is_type_tuple(d):
        return "tuple"
    if cc.is_type_tupledet(d):
        return "{%s}" % ", ".join(
            map(pretty_type, cc.get_inner_types_from_tupledet(d)))
    if cc.is_type_union(d):
        return "|".join(map(pretty_type, cc.get_inner_types_from_union(d)))
    if cc.is_type_range(d):
        bs = cc.get_range_bounds_from_range(d)
        return "%s..%s" % (cc.get_lower_bound(bs), cc.get_upper_bound(bs))
    if cc.is_type_generic_fun(d):
        return "fun()"
    if cc.is_type_complete_fun(d):
        args, ret = d["a"][:-1], d["a"][-1]
        args = cc.get_parameters_from_complete_fun(d)
        ret = cc.get_rettype_from_fun(d)
        return "fun(({}) -> {})".format(", ".join(map(pretty_type, args)),
                                        pretty_type(ret))
コード例 #3
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def revMatchCons(self):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             inner_types = cc.get_inner_types_from_union(self.typ)
             candidates = [tp for tp in inner_types if not ErlType.isNonemptyList(tp)]
             if len(candidates) > 0:
                 cc.set_inner_types_to_union(self.typ, candidates)
                 new_inner_types = cc.get_inner_types_from_union(self.typ)
                 for tp in new_inner_types:
                     if ErlType.isList(tp):
                         ErlType.setNilType(tp)
         # actual type elaborations
         if ErlType.isList(self.typ):
             ErlType.setNilType(self.typ)
             self.isFinal = True
コード例 #4
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def matchCons(self):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             isL = lambda x: ErlType.isList(x) or ErlType.isNonemptyList(x)
             inner_types = cc.get_inner_types_from_union(self.typ)
             candidates = [tp for tp in inner_types if isL(tp)]
             if len(candidates) > 0:
                 self.typ = candidates[0]
             else:
                 # TODO Log inconsistency
                 pass
         # actual type elaborations
         if ErlType.isList(self.typ):
             it = cc.get_inner_type_from_list(self.typ)
             h = Type(deepcopy(it))
             t = Type(deepcopy(self.typ))
             ErlType.setConsType(self.typ)
             self.isFinal = True
             self.children = [h, t]
         elif ErlType.isNonemptyList(self.typ):
             it = cc.get_inner_type_from_nonempty_list(self.typ)
             h = Type(deepcopy(it))
             t = Type(ErlType.getListTypeFromNonemptyList(self.typ))
             ErlType.setConsType(self.typ)
             self.isFinal = True
             self.children = [h, t]
         elif ErlType.isAny(self.typ):
             pass
         else:
             # TODO Log inconsistency
             pass
コード例 #5
0
ファイル: cuter_print.py プロジェクト: aggelgian/cuter
def pretty_type(d):
    if cc.is_type_any(d):
        return "any"
    if cc.is_type_atom(d):
        return "atom"
    if cc.is_type_atomlit(d):
        return pretty(cc.get_literal_from_atomlit(d))
    if cc.is_type_float(d):
        return "float"
    if cc.is_type_integer(d):
        return "integer"
    if cc.is_type_integerlit(d):
        return pretty(cc.get_literal_from_integerlit(d))
    if cc.is_type_list(d):
        return "[%s]" % pretty_type(cc.get_inner_type_from_list(d))
    if cc.is_type_nil(d):
        return "[]"
    if cc.is_type_tuple(d):
        return "tuple"
    if cc.is_type_tupledet(d):
        return "{%s}" % ", ".join(map(pretty_type, cc.get_inner_types_from_tupledet(d)))
    if cc.is_type_union(d):
        return "|".join(map(pretty_type, cc.get_inner_types_from_union(d)))
    if cc.is_type_range(d):
        bs = cc.get_range_bounds_from_range(d)
        return "%s..%s" % (cc.get_lower_bound(bs), cc.get_upper_bound(bs))
    if cc.is_type_generic_fun(d):
        return "fun()"
    if cc.is_type_complete_fun(d):
        args, ret = d["a"][:-1], d["a"][-1]
        args = cc.get_parameters_from_complete_fun(d)
        ret = cc.get_rettype_from_fun(d)
        return "fun(({}) -> {})".format(", ".join(map(pretty_type, args)), pretty_type(ret))
コード例 #6
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def unifyWithFloat(self, tp):
     if tp.isFloat():
         return True
     if tp.isUnion():
         isCnd = lambda x: ErlType.isFloat(x)
         inner_types = cc.get_inner_types_from_union(tp.typ)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
     return False
コード例 #7
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def unifyWithBitstring(self, tp):
     if tp.isBitstring():
         # FIXME Have to check if m * n is compatible
         return True
     if tp.isUnion():
         isCnd = lambda x: ErlType.isBitstring(x)
         inner_types = cc.get_inner_types_from_union(tp.typ)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
     return False
コード例 #8
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def matchNotList(self):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             inner_types = cc.get_inner_types_from_union(self.typ)
             isCnd = lambda x: not ErlType.isList(x) and not ErlType.isNil(x) and not ErlType.isNonemptyList(x)
             candidates = [tp for tp in inner_types if isCnd(tp)]
             if len(candidates) > 0:
                 cc.set_inner_types_to_union(self.typ, candidates)
             else:
                 # TODO Log inconsistency
                 pass
         if ErlType.isList(self.typ) or ErlType.isNil(self.typ) or ErlType.isNonemptyList(self.typ):
             # TODO Log inconsistency
             pass
コード例 #9
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def unifyWithAtomLit(self, tp):
     if tp.isAtom():
         return True
     if tp.isAtomLit():
         return cc.get_literal_from_atomlit(self.typ) == cc.get_literal_from_atomlit(tp.typ)
     if tp.isUnion():
         isCnd = lambda x: ErlType.isAtom(x)
         inner_types = cc.get_inner_types_from_union(tp.typ)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
         isCnd = lambda x: ErlType.isAtomLit(x) and cc.get_literal_from_atomlit(self.typ) == cc.get_literal_from_atomlit(x)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
     return False
コード例 #10
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def notMatchTuple(self):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             inner_types = cc.get_inner_types_from_union(self.typ)
             isCnd = lambda x: not ErlType.isTupleDet(x) and not ErlType.isTuple(x)
             candidates = [tp for tp in inner_types if isCnd(tp)]
             if len(candidates) > 0:
                 cc.set_inner_types_to_union(self.typ, candidates)
             else:
                 # TODO Log inconsistency
                 pass
         # actual type elaborations
         if ErlType.isTupleDet(self.typ) or ErlType.isTuple(self.typ):
             # TODO Log inconsistency
             pass
コード例 #11
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def matchNotNil(self):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             inner_types = cc.get_inner_types_from_union(self.typ)
             candidates = [tp for tp in inner_types if not ErlType.isNil(tp)]
             for cnd in candidates:
                 if ErlType.isList(cnd):
                     ErlType.setNonEmptyListType(cnd)
             if len(candidates) > 0:
                 cc.set_inner_types_to_union(self.typ, candidates)
             else:
                 # TODO Log inconsistency
                 pass
         elif ErlType.isList(self.typ):
             self.matchCons()
コード例 #12
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def unifyWithAtom(self, tp):
     if tp.isAtom():
         return True
     if tp.isAtomLit():
         self.takenOverByType(tp)
         return True
     if tp.isUnion():
         isCnd = lambda x: ErlType.isAtom(x)
         inner_types = cc.get_inner_types_from_union(tp.typ)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
         isCnd = lambda x: ErlType.isAtomLit(x)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             cc.set_inner_types_to_union(tp, candidates)
             self.takenOverByType(tp)
             return True
     return False
コード例 #13
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def unifyWithIntegerLit(self, tp):
     if tp.isInteger():
         return True
     if tp.isIntegerLit():
         return cc.get_literal_from_integerlit(self.typ) == cc.get_literal_from_integerlit(tp.typ)
     if tp.isUnion():
         isCnd = lambda x: ErlType.isInteger(x)
         inner_types = cc.get_inner_types_from_union(tp.typ)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
         isCnd = lambda x: ErlType.isIntegerLit(x) and cc.get_literal_from_integerlit(self.typ) == cc.get_literal_from_integerlit(x)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
         # FIXME Check for range properly
         isCnd = lambda x: ErlType.isRange(x)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
     return False
コード例 #14
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def matchNil(self):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             inner_types = cc.get_inner_types_from_union(self.typ)
             isCnd = lambda x: ErlType.isList(x) or ErlType.isNil(x)
             candidates = [tp for tp in inner_types if isCnd(tp)]
             if len(candidates) > 0:
                 self.typ = candidates[0]
             else:
                 # TODO Log inconsistency
                 pass
         # actual type elaborations
         if ErlType.isList(self.typ):
             ErlType.setNilType(self.typ)
             self.isFinal = True
         elif ErlType.isNil(self.typ):
             self.isFinal = True
         elif ErlType.isAny(self.typ):
             pass
         else:
             # TODO Log inconsistency
             pass
コード例 #15
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def unifyWithTuple(self, tp):
     if tp.isTuple():
         return True
     if tp.isTupleDet():
         self.takenOverByType(tp)
         return True
     if tp.isUnion():
         isCnd = lambda x: ErlType.isTuple(x)
         inner_types = cc.get_inner_types_from_union(tp.typ)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             return True
         isCnd = lambda x: ErlType.isTupleDet(x)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             # FIXME Have to check specify the type with tupledet
             return True
         isCnd = lambda x: ErlType.isNTuple(x)
         candidates = [t for t in inner_types if isCnd(t)]
         if len(candidates) > 0:
             # FIXME Have to check specify the type with ntuple
             return True
     return False
コード例 #16
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def isFinalType(self, typ):
     if ErlType.isAny(typ):
         return True
     elif ErlType.isAtom(typ):
         return True
     elif ErlType.isAtomLit(typ):
         return True
     elif ErlType.isFloat(typ):
         return True
     elif ErlType.isInteger(typ):
         return True
     elif ErlType.isIntegerLit(typ):
         return True
     elif ErlType.isList(typ):
         return False
     elif ErlType.isNil(typ):
         return True
     elif ErlType.isTuple(typ):
         return True
     elif ErlType.isTupleDet(typ):
         return all(self.isFinalType(t) for t in cc.get_inner_types_from_tupledet(typ))
     elif ErlType.isUnion(typ):
         return all(self.isFinalType(t) for t in cc.get_inner_types_from_union(typ))
     elif ErlType.isRange(typ):
         return True
     elif ErlType.isNonemptyList(typ):
         return False
     elif ErlType.isBitstring(typ):
         return True
     elif ErlType.isCons(typ):
         return True
     elif ErlType.isNTuple(typ):
         return True
     elif ErlType.isGenericFun(typ):
         return True
     elif ErlType.isFun(typ):
         return True
コード例 #17
0
ファイル: cuter_types.py プロジェクト: aggelgian/cuter
 def matchNTuple(self, sz):
     if not self.isFinal:
         # preprocess unions
         if ErlType.isUnion(self.typ):
             inner_types = cc.get_inner_types_from_union(self.typ)
             isCnd = lambda x: ErlType.isTuple(x) or (ErlType.isTupleDet(x) and len(cc.get_inner_types_from_tupledet(x)) == sz)
             candidates = [tp for tp in inner_types if isCnd(tp)]
             if len(candidates) > 0:
                 self.typ = candidates[0]
             else:
                 # TODO Log inconsistency
                 pass
         # actual type elaborations
         if ErlType.isTuple(self.typ):
             pass
         elif ErlType.isTupleDet(self.typ) and len(cc.get_inner_types_from_tupledet(self.typ)) == sz:
             self.isFinal = True
             self.children = [Type(deepcopy(tp)) for tp in cc.get_inner_types_from_tupledet(self.typ)]
             ErlType.setNTupleType(self.typ, sz)
         elif ErlType.isAny(self.typ):
             pass
         else:
             # TODO Log inconsistency
             pass
コード例 #18
0
 def build_spec(self, spec, var):
     if cc.is_type_any(spec):
         return "true"
     elif cc.is_type_float(spec):
         return ["is-real", var]
     elif cc.is_type_integer(spec):
         return ["is-int", var]
     elif cc.is_type_list(spec):
         inner_spec = cc.get_inner_type_from_list(spec)
         name = self.fun_rec_tlist(inner_spec)
         return [
             "and",
             ["is-list", var],
             [name, ["lv", var]],
         ]
     elif cc.is_type_nonempty_list(spec):
         inner_spec = cc.get_inner_type_from_nonempty_list(spec)
         name = self.fun_rec_tlist(inner_spec)
         return [
             "and",
             ["is-list", var],
             ["is-tc", ["lv", var]],
             [name, ["lv", var]],
         ]
     elif cc.is_type_tupledet(spec):
         body = ["and", ["is-tuple", var]]
         tlist = ["tv", var]
         for inner_type in cc.get_inner_types_from_tupledet(spec):
             body.append(["is-tc", tlist])
             body.append(self.build_spec(inner_type, ["th", tlist]))
             tlist = ["tt", tlist]
         body.append(["is-tn", tlist])
         return body
     elif cc.is_type_tuple(spec):
         return ["is-tuple", var]
     elif cc.is_type_union(spec):
         ret = ["or"]
         for inner_type in cc.get_inner_types_from_union(spec):
             ret.append(self.build_spec(inner_type, var))
         return ret
     elif cc.is_type_range(spec):
         ret = ["and", ["is-int", var]]
         limits = cc.get_range_bounds_from_range(spec)
         if cc.has_lower_bound(limits):
             ret.append(
                 [">=", ["iv", var],
                  build_int(cc.get_lower_bound(limits))])
         if cc.has_upper_bound(limits):
             ret.append(
                 ["<=", ["iv", var],
                  build_int(cc.get_upper_bound(limits))])
         return ret
     elif cc.is_type_atom(spec):
         return ["is-atom", var]
     elif cc.is_type_bitstring(spec):
         segment_size = cc.get_segment_size_from_bitstring(spec)
         m = int(segment_size.m)
         n = int(segment_size.n)
         slist = ["sv", var]
         axioms = ["and"]
         axioms.append(["is-str", var])
         while m > 0:
             axioms.append(["is-sc", slist])
             slist = ["st", slist]
             m -= 1
         if n == 0:
             axioms.append(["is-sn", slist])
         elif n > 1:
             axioms.append(SListSpec(slist, build_int(n), self))
         return axioms
     elif cc.is_type_complete_fun(spec):
         # TODO if a function is to be called with wrong arguments, program must crash
         par_spec = cc.get_parameters_from_complete_fun(spec)
         ret_spec = cc.get_rettype_from_fun(spec)
         name = self.fun_rec_flist(par_spec, ret_spec)
         return [
             "and", ["is-fun", var],
             ["=", ["fa", ["fv", var]],
              build_int(len(par_spec))], [name, ["fm", ["fv", var]]],
             ["not", ["=", ["fm", ["fv", var]], "fn"]]
         ]
     elif cc.is_type_generic_fun(spec):
         par_spec = None
         ret_spec = cc.get_rettype_from_fun(spec)
         name = self.fun_rec_flist(par_spec, ret_spec)
         return [
             "and", ["is-fun", var], [name, ["fm", ["fv", var]]],
             ["not", ["=", ["fm", ["fv", var]], "fn"]]
         ]
     elif cc.is_type_atomlit(spec):
         return ["=", var, self.decode(cc.get_literal_from_atomlit(spec))]
     elif cc.is_type_integerlit(spec):
         return [
             "=", var,
             self.decode(cc.get_literal_from_integerlit(spec))
         ]
     elif cc.is_type_userdef(spec):
         type_name = cc.get_type_name_of_userdef(spec)
         return ["|{}|".format(type_name), var]
     clg.debug_info("unknown spec: " + str(spec))
     assert False