~jasper/type_stack_calc

e3b237a851ac28e63896a025d37dd6cadd966ea2 — Jasper den Ouden 1 year, 6 months ago e3032f7
First definition of types, using typecalc detection and to_c not entirely aligned? Not sure why
M test/sets/range.py => test/sets/range.py +4 -4
@@ 138,14 138,14 @@ for i in range(10):  # Above again but >= can deal with 0.
    dx = random()
    while dx == 0: dx = random()   # (some will give `None` if 0)
    got = getattr(inp, f"iparam_<=")(SetRange_1(fr - dx))  # Before is always true.
    assert got.true()
    assert got[0] is True
    got = getattr(inp, f"iparam_<=")(SetRange_1(to + dx))  # After always false.
    assert got.false(), dx
    assert got[0] is False, dx

    got = getattr(inp, f"iparam_>=")(SetRange_1(fr - dx))  # Before is always false.
    assert got.false()
    assert got[0] is False
    got = getattr(inp, f"iparam_>=")(SetRange_1(to + dx))  # After always true.
    assert got.true()
    assert got[0] is True

check_range(inp.iparam_negative(), -to, -fr)
check_range_via(inp.iparam_negative(), lambda x:-x, to, fr)

M type_stack_calc/base/component.py => type_stack_calc/base/component.py +31 -24
@@ 23,8 23,9 @@ class BaseComponentSet(BaseNArgs):
    c_name, infix, fun_tp = '=', True, 'method'

    def __init__(self, component):
        self.component = component
        self.initial_set, self.definitional = False, False
        self.comp = component
        self.definitional, self.destructive = False, None
        self.first_set = False

    def deal_relevant_comp(self, rl, args):
        args[0].relevant_comp = rl


@@ 36,15 37,15 @@ class BaseComponentSet(BaseNArgs):
    def extract(self, extractor, gen, tp):
        """Only needs extraction if specifying type now. Though can be specified to always do it."""
        # TODO return for instance should _never_ need extraction?
        if self.initial_set or extractor.always_extract_set:
        if self.first_set or extractor.always_extract_set: # (needed for defining)
            # Extract a bit.
            ilist = []
            # Extractor for internals that includes the component that may replace the temporary-variable.
            ext = Extractor((ilist.append, extractor[1]))
            extractor[1](self)  # This should get the component.
            extractor[1](self)  # This should get the comp.
            ext.extract_1(gen)
            varlist = ilist.copy()  # Variables into non-extracted also.
            ext.extract_1_w_var(gen, self.component)  # And this is the value.
            ext.extract_1_w_var(gen, self.comp)  # And this is the value.
            extractor[1](ilist + [PostExtractDrop])
            extractor[0](varlist)  # ... which goes into the arguments.
        else:  # Plainly set in side.


@@ 53,41 54,43 @@ class BaseComponentSet(BaseNArgs):
    def extract_top(self, extractor, gen, tp):
        extractor[0](self)
        extractor.extract_1(gen)
        extractor.extract_1_w_var(gen, self.component)
        extractor.extract_1_w_var(gen, self.comp)

    def to_c(self, tc, gen):
        wfile, prep = tc[:2]
        var = next(gen)
        assert isinstance(var, BaseComponent), (self, self.component, var, list(gen))
        assert isinstance(var, BaseComponent), (var, self, self.comp, list(gen))
        next_tc = next(gen)
        if var.key == '~r':  # ~ indicates inbuilt "weirdo variable".
            if next_tc is StopMarker: return  # Indicates it is not needed.
            wfile("return ")
        else:
            if self.initial_set:
                #assert var.val is not None, var  # TODO
                wfile((var.val and var.val.c_name or f"Bug({var})") + " ")
            wfile(f"{var.key} = ")
        tc.new_context(prep, '(').c_1(gen, next_tc)
        if next_tc != StopMarker:
            wfile, prep = tc[:2]
            comp = self.comp
            if comp.key == '~r':  # ~ indicates inbuilt "weirdo variable".
                wfile("return")
            else:  # TODO should correspond with `.first_set`..
                if not comp.c_defined:
                    comp.c_defined = True
                    wfile((comp.val and comp.val.c_name or f"Bug({var})") + " ")

                wfile(f"{self.comp.key}")
            wfile(' ' if var.key == '~r' else ' = ')
            tc.new_context(prep, '(').c_1(gen, next_tc)

    def tp_calc(self, sc, vs, args):
        to, component = args
        to, comp = args
        if isinstance(to, BaseComponent):  # If component, get the value.
            to = to.val
            assert not isinstance(to, BaseComponent), f"More than one layer of components? ({to})"

        assert_acceptable_vals((to,), component, vs,
        assert_acceptable_vals((to,), comp, vs,
                               desc="Setting variable")

        self.initial_set = component.sc_set(sc, to)
        self.first_set = comp.sc_set(sc, to) or False
        self.definitional = getattr(to, 'definitional', None)
        assert id(component.access_obj.get_comp(component.key)) == id(component)
        #self.initial_set = c.access_obj.sc_set_param(sc, c, to)
        assert id(comp.access_obj.get_comp(comp.key)) == id(comp)
        sc.does.add('something')  # Variables/components were modified.

        if not getattr(self, 'destructive', None):
        if not self.destructive:
            self.destructive = getattr(to, 'destructive', None) and 'setcomp'
        if component.key == '~r':
        if comp.key == '~r':
            return [ReturnStop], self
        return [to], self



@@ 103,13 106,17 @@ NOTE: it doesn't access `.set`, `.glob` from the value because the methods for t
            desc="Making component object for {access_obj}, {key}")
        assert access_obj is not None, key
        self.access_obj, self.key = access_obj, key

        self.c_defined = False
        if key[0] == '~': self.destructive = 'returnlike'

    @property
    def param_set(self):
        """The 'method' that sets stuff."""
        return self._param_set_cls(self)

    param_ = param_set  # Alias to empty string.(Just a dot accesses it)

    @property
    def setter(self):
        return [self, self.param_set]

M type_stack_calc/extractor.py => type_stack_calc/extractor.py +1 -1
@@ 23,7 23,7 @@ For instance `c_function(int x=4);` isn't allowed and `int x=4; c_function(x);` 
Derives from tuple; first is a function that puts it inside the function, and the second puts it outside."""

    # NOTE: needs to be true or side-effects may be incorrectly omitted.
    always_extract_set = True
    always_extract_set = False

    def _extract_1(self, gen, obj, ename='extract'):
        # It has a function that extracts it.

M type_stack_calc/ib/scope.py => type_stack_calc/ib/scope.py +7 -0
@@ 10,6 10,8 @@ from type_stack_calc.base.named import Named
from type_stack_calc.base.component import BaseComponent, BaseComponentSet
from type_stack_calc.ib.plain_component import PlainComponent 

from type_stack_calc.pe.tmpvar import DefVar

from type_stack_calc.util.various import do_all

class ScopeVariableSet(BaseComponentSet): pass


@@ 26,6 28,11 @@ class ScopeVariable(BaseComponent):
        assert type(key) == str
        # Direct val is the stored value without logic about getting it from other scopes.
        self.key, self.direct_val = key, None
        self.c_defined = False

    @property
    def deffer(self):
        if self.key != '~r': return DefVar((self,))

    @property
    def val(self):

M type_stack_calc/pe/tmpvar.py => type_stack_calc/pe/tmpvar.py +10 -7
@@ 8,11 8,13 @@

from type_stack_calc.base.n_args import BaseNArgs

class DefTmpVar(tuple):
    """Defining a temporary variable."""
class DefVar(tuple):
    """Defining a variable. (temporary or not)"""
    def to_c(self, tc, _gen):
        s = self[0]
        tc[0](f"{s.tp.c_name}_{s.c_name};")
        if not s.c_defined:
            s.c_defined = True
            tc[0](f"{s.val.c_name} {s.c_name};")

    def __repr__(self): return 'def' + self[0].__repr__()



@@ 31,16 33,17 @@ class TmpVar:
    counters = dict()

    def __init__(self, name, tp):
        self.name, self.tp = name, tp
        self.key, self.val = name, tp
        self.i = self.counters.get(name, 0)
        self.counters[name] = self.i + 1
        self.setter, self.deffer = [SetTmpVar((self,))], [DefTmpVar((self,))]
        self.setter, self.deffer = [SetTmpVar((self,))], [DefVar((self,))]
        self.c_defined = False  # More needer for `DefVar`s of other things

    valuer = 'self'

    def __repr__(self):
        return f"tmp:{self.name}{self.i}"
        return f"tmp:{self.key}{self.i}"

    @property
    def c_name(self):
        return f"tmp_{self.name}_{self.i}"
        return f"tmp_{self.key}_{self.i}"

M type_stack_calc/tp/component_collection.py => type_stack_calc/tp/component_collection.py +2 -2
@@ 29,9 29,9 @@ class ComponentRefSelf:
class ComponentSet(BaseComponentSet):
    """Setting a component."""
    def __init__(self, component):
        self.component = component
        self.comp = component

    initial_set, destructive = None, True
    destructive = True

    def to_c(self, tc, gen):  # Doesn't listen?
        wfile = tc[0]