~jasper/type_stack_calc

ref: 6aca66fb1a7cf1e10f7dd3263f04537c8ff37590 type_stack_calc/type_stack_calc/to_c.py -rw-r--r-- 1.1 KiB
6aca66fb — Jasper den Ouden Apparently `to_c` can already read ahead one, hopefully its this simple... 11 months 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
from type_stack_calc.extractor import extract

class ToC(tuple):
    """Helper to turn code into C code.
Consists of callback that writes, what to prepend."""

    def new_context(self, *context):
        return ToC((self[0], *context))

    def _c_1(self, gen, cc):
        """Generates C code into `self[1]`. One statement, which can be multiple `next` in input `gen`."""
        wfile, prep = self[:2]
        if fun := getattr(cc, 'to_c', None):  # It has it's own function.
            fun(self, gen)
        else:  # `c_name` attribute must provide it. Otherwise, it's not supposed to be here.
            wfile(prep + cc.c_name if prep == ';' else cc.c_name)

    def c_1(self, gen, cc=None):
        return self._c_1(gen, cc or next(gen))

    def c(self, gen):
        """Generate C, runs through the whole input `gen` generator."""
        gen = iter(gen)  # ENsure it is actually a generator.
        for cc in gen:
            self._c_1(gen, cc)

    def extract_n_c(self, body):
        wfile, prep = self[:2]
        for e_code in extract(reversed(body)):
            wfile(prep)
            self.c(e_code)
            if self[2] == ';': wfile(';')