builtup4/bu4/linking/constructs/llambda.py
2021-09-12 12:39:24 +03:00

71 lines
2.4 KiB
Python

# Copyright (c) PARRRATE T&V 2021. All rights reserved.
from bu4.evaluation.av.envtype import envtype
from bu4.evaluation.constructs.eattachable import EAttachable
from bu4.evaluation.constructs.edelayed import EDelayed
from bu4.evaluation.constructs.elambda import ELambda
from bu4.evaluation.constructs.evaluable import Evaluable
from bu4.indexing.constructs.idelayed import IDelayed
from bu4.indexing.constructs.ilambda import ILambda
from bu4.indexing.constructs.indexed import Indexed
from bu4.linking.constructs.linked import Linked
from bu4.transform.states.aftertransform import AfterTransform
from bu4.transform.states.transformfinished import TransformFinished
from bu4.transform.states.transformstart import TransformStart
from bu4.transform.states.transformstate import TransformState
from bu4.transform.targets.atlambda import ATLambda
__all__ = ('LLambda',)
class LLambda(Linked):
value: Linked
def __init__(self, name: bytes, value: Linked):
self.name = name
self.value = value
self.future = self.value.future - {name}
self.multifuture = self.future
self.used = name in value.future
self.memoize = name in value.multifuture
def attach(self, env: envtype) -> Evaluable:
return (
ELambda(
{name: env[name] for name in self.future} if self.used else env,
self.name,
self.value
)
if
self.used
else
EDelayed(EAttachable(
env,
self.value
))
)
def index(self, promise: list[bytes]) -> TransformState[Indexed]:
if not self.used:
return AfterTransform(
TransformStart(lambda: self.value.index(promise)),
ATLambda(
lambda value: TransformFinished(IDelayed(value))
)
)
else:
table = [i for i in range(len(promise)) if promise[i] in self.future]
return AfterTransform(
TransformStart(lambda: self.value.index([self.name] + [promise[i] for i in table])),
ATLambda(
lambda value: TransformFinished(ILambda(
value,
table,
memoize=self.memoize
))
)
)
def __str__(self):
return f'({self.name.decode()}){self.value}'