# Copyright (c) PARRRATE T&V 2021. All rights reserved. from typing import Any from bu4.evaluation.av.aftervalue import AfterValue from bu4.evaluation.constructs.evaluable import Evaluable from bu4.evaluation.constructs.evalue import EValue from bu4.evaluation.sync import sync from bu4.evaluation.targets.avtarget import AVTarget __all__ = ('eproxy', 'antiproxy') class AVProxyCall(AVTarget): def __init__(self, value: Any): self.value = value def given(self, value: EValue) -> Evaluable: if isinstance(value, EProxy): return eproxy(self.value(value.value)) else: return eproxy(self.value(antiproxy(value))) def __str__(self): return f'<{self.value}>' class EProxy(EValue): def __init__(self, value: Any): super().__init__() self.value = value def call(self, value: Evaluable) -> Evaluable: return AfterValue(value, AVProxyCall(self.value)) def __str__(self): return str(self.value) class AntiProxy: def __init__(self, evaluable: EValue): self.evaluable = evaluable def __call__(self, value): return antiproxy(sync(self.evaluable.call(eproxy(value)))) def __str__(self): return str(self.evaluable) def eproxy(value: Any) -> Evaluable: if isinstance(value, Evaluable): return value elif isinstance(value, AntiProxy): return value.evaluable else: return EProxy(value) def antiproxy(evaluable: EValue): if isinstance(evaluable, EProxy): return evaluable.value else: return AntiProxy(evaluable)