~jasper/type_stack_calc

ref: 6aca66fb1a7cf1e10f7dd3263f04537c8ff37590 type_stack_calc/type_stack_calc/base/variant_able_function.py -rw-r--r-- 1.8 KiB
6aca66fb — Jasper den Ouden Apparently `to_c` can already read ahead one, hopefully its this simple... 1 year, 1 month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from type_stack_calc.ib.tc_variant import TCVariant
from type_stack_calc.util.types_eq import types_key

class VariantAbleFunction:
    """Helps functions ensure variants are available.
Provides just `.ensure_variant`"""

    # TODO maybe odd to use attrs that way..
    def __init__(self, code_names, max_try_cnt=100, max_depth=100):
        for name in code_names:
            assert getattr(self, f"code_{name}", 'omitted') != 'omitted', \
                f"Declaring there is a code by the name `{name}` but it is missing.\n{self.code_type}"
            setattr(self, f"variants_{name}", dict())
            setattr(self, f"max_try_cnt_{name}", max_try_cnt)
            setattr(self, f"max_depth_{name}", max_depth)

    def ensure_variant(self, code_name, inp, real, depth):
        """Calculate or get type-compiled variant, pertaining to `code_name`"""
        assert len(inp) == self.n, \
            f"""{self}: Wrong number of arguments. {len(inp)} != {self.n}
{inp}"""
        key = types_key(inp)
        vdict = getattr(self, f"variants_{code_name}")
        variant = vdict.get(key)
        if variant is None:
            variant = TCVariant(code_name, self, inp, depth)
            vdict[key] = variant  # Remember it,
            variant.variant_tp_calc(real)  # AFTER type calculate, it may refer back to the remembered.

        return variant

    def cleanup_variants(self, code_name, n):
        """Deletes variants that are not used much."""
        del_these = []
        vdict = getattr(self, f"variants_{code_name}")
        for k, variant in vdict.items():
            if variant.tc_code is None:  # Typecalculated but the result ditched, can delete.
                del_these.append(k)
                if n < len(del_these):
                    break  # Got enough.

        for k in del_these:
            del vdict[k]