# Copyright (C) 2021 Jasper den Ouden. # # This is free software: you can redistribute it and/or modify # it under the terms of the Affero GNU General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. from type_stack_calc.extractor import Extractor def list_flatten(gen): for el in gen: if type(el) == list: for r_el in list_flatten(el): yield r_el else: yield el def filter_none(lst): return [el for el in lst if el is not None] class NEVER: """TODO... dunno if i can figure out how to remove this stuff..""" c_name="NEVER" class IfBlock: """`if_block.py`: `{..if..} {..else..} (..cond..).if` provider.""" def __init__(self, cond, yes, no, ret_stack): self.cond, self.yes, self.no = map(filter_none, [cond, yes, no]) self.stack = ret_stack def extract_cond(self, extractor, gen): lst = [] e_c = Extractor((lst.append, extractor[1])) gen = reversed(self.cond) for el in gen: if el is not None: e_c._extract_1(gen, el) self.cond = list_flatten(lst) # Remainder can stay. def extract(self, extractor, gen, _obj): self.extract_cond(extractor, gen) if len(self.stack) > 0: # TODO permit multi-output stuff or not? assert len(self.stack) == 1 tmp = extractor.tmp_var('if', self.stack[0]) if deffer := getattr(tmp, 'deffer', None): extractor[1](deffer) if getattr(tmp, 'key', "")[:1] == '~': extractor[0](NEVER) else: extractor[0](tmp) self.yes = [*self.yes, *tmp.setter] # internals extracted later) self.no = [*self.no, *tmp.setter] extractor[1](self) # Thing itself extracts outside. def extract_top(self, extractor, gen, _obj): self.extract_cond(extractor, gen) extractor[0](self) # Already on top, just place. # .yes and .no is done by `extracted_to_c`. def to_c(self, tc, _gen): wfile, prep = tc[:2] wfile(prep + "if(") tc.new_context(prep + " ", '(').c(self.cond) wfile(") {") body_tc = tc.new_context(prep + " ", ';') body_tc.extract_n_c(self.yes) if any(self.no): # Only do non-empty elses. wfile(prep + "} else {") body_tc.extract_n_c(self.no) wfile(prep + "}") else: wfile(prep + "}")