# Copyright (c) PARRRATE T&V 2021. All rights reserved. from bu4.evaluation.av.envtype import envtype from bu4.evaluation.constructs.elambda import ELambda from bu4.evaluation.constructs.evaluable import Evaluable from bu4.linking.states.afterlinking import AfterLinking from bu4.linking.states.linkingfinished import LinkingFinished from bu4.linking.states.linkingparsed import LinkingParsed from bu4.linking.states.linkingstate import LinkingState from bu4.linking.targets.allambda import ALLambda from bu4.parsing.constructs.linked import Linked, Parsed __all__ = ('PLambda',) class LLambda(Linked): value: Linked def __init__(self, promise: set[bytes], name: bytes, value: Parsed): assert name not in promise, f'overloaded: {name}' self.promise = promise self.name = name self._value = value def link(self) -> LinkingState: return AfterLinking(LinkingParsed(self.promise | {self.name}, self._value), ALLambda(self._given_value)) def _given_value(self, value: Linked) -> LinkingState: self.value = value self.future = self.value.future - {self.name} return LinkingFinished(self) def evaluable(self, env: envtype) -> Evaluable: return ELambda( {name: container for name, container in env.items() if name in self.future}, self.name, self.value ) def __str__(self): return f'({self.name.decode()}){self.value}' def unlink(self) -> Parsed: return PLambda(self.name, self._value) class PLambda(Parsed): def __init__(self, name: bytes, value: Parsed): self.name = name self.value = value def link(self, promise: set[bytes]) -> Linked: return LLambda(promise, self.name, self.value)