builtup4/bu4/parsing/constructs/llambda.py
2021-07-27 22:10:59 +03:00

54 lines
1.7 KiB
Python

# 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)