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
def __init__(self, typ): self.typ = deepcopy(typ) self.isFinal = self.isFinalType(typ) self.hasFunBeenUsed = False # Only applies to function types. self.children = None if ErlType.isNonemptyList(typ): inner_type = cc.get_inner_type_from_nonempty_list(self.typ) h = Type(deepcopy(inner_type)) t = Type(ErlType.getListTypeFromNonemptyList(self.typ)) ErlType.setConsType(self.typ) self.isFinal = True self.children = [h, t]
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