commit ecdda4f0593bc1a7d4fc383bf15b46f887b018a7 Author: timotheyca Date: Sat Jul 24 02:34:37 2021 +0300 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5043bd --- /dev/null +++ b/.gitignore @@ -0,0 +1,221 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + + + + + + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + + + diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/builtup4.iml b/.idea/builtup4.iml new file mode 100644 index 0000000..74d515a --- /dev/null +++ b/.idea/builtup4.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..69f4ba6 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,51 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..189eafd --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..cb57d51 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bu4/codes.py b/bu4/codes.py new file mode 100644 index 0000000..ae56bdb --- /dev/null +++ b/bu4/codes.py @@ -0,0 +1,8 @@ +CODE_NULL = 0 +CODE_CALL = 1 +CODE_MAKE = 2 +CODE_NAME = 3 +CODE_SKIP = 4 +CODE_QUOT = 5 +CODE_QOPN = 6 +CODE_QCLS = 7 diff --git a/bu4/evaluation/aftervalue.py b/bu4/evaluation/aftervalue.py new file mode 100644 index 0000000..b9e729e --- /dev/null +++ b/bu4/evaluation/aftervalue.py @@ -0,0 +1,50 @@ +import abc +from typing import Mapping + +from bu4.evaluation.evaluable import Evaluable + +try: + from typing import TypeAlias +except ImportError: + TypeAlias = type + +envtype: TypeAlias = Mapping[bytes, 'AfterValue'] + + +class AVTarget: + def given(self, value: 'EValue') -> Evaluable: + raise NotImplementedError + + +class AfterValue(Evaluable): + def __init__(self, evaluable: Evaluable, target: AVTarget): + self.evaluable = evaluable + self.target = target + + def next(self) -> 'Evaluable': + if isinstance(self.evaluable, EValue): + if isinstance(self.target, AVAV): + self.evaluable, self.target = self.target.target.given(self.evaluable), self.target.aftertarget + return self + return self.target.given(self.evaluable) + if isinstance(self.evaluable, AfterValue): + self.evaluable, self.target = self.evaluable.evaluable, AVAV(self.evaluable.target, self.target) + self.evaluable = self.evaluable.next() + return self + + +class AVAV(AVTarget): + def __init__(self, target: AVTarget, aftertarget: AVTarget): + self.target = target + self.aftertarget = aftertarget + + def given(self, value: 'EValue') -> Evaluable: + return AfterValue(self.target.given(value), self.aftertarget) + + +class EValue(Evaluable, abc.ABC): + def next(self) -> 'EValue': + return self + + def call(self, argument: Evaluable) -> Evaluable: + raise NotImplementedError diff --git a/bu4/evaluation/avcall.py b/bu4/evaluation/avcall.py new file mode 100644 index 0000000..e493a30 --- /dev/null +++ b/bu4/evaluation/avcall.py @@ -0,0 +1,14 @@ +from bu4.evaluation.elinked import ELinked +from bu4.parsing.linked import Linked +from bu4.evaluation.aftervalue import Evaluable, EValue, AVTarget, envtype + +__all__ = ('AVCall',) + + +class AVCall(AVTarget): + def __init__(self, env: envtype, argument: Linked): + self.env = env + self.argument = argument + + def given(self, value: EValue) -> Evaluable: + return value.call(ELinked(self.env, self.argument)) diff --git a/bu4/evaluation/avcontainer.py b/bu4/evaluation/avcontainer.py new file mode 100644 index 0000000..0a5f25d --- /dev/null +++ b/bu4/evaluation/avcontainer.py @@ -0,0 +1,10 @@ +from bu4.evaluation.aftervalue import EValue, AfterValue, Evaluable, AVTarget + + +class AVContainer(AVTarget): + def __init__(self, evaluable: Evaluable): + self.after_value = AfterValue(evaluable, self) + + def given(self, value: EValue) -> Evaluable: + self.after_value.evaluable = value + return value diff --git a/bu4/evaluation/elambda.py b/bu4/evaluation/elambda.py new file mode 100644 index 0000000..a09f669 --- /dev/null +++ b/bu4/evaluation/elambda.py @@ -0,0 +1,22 @@ +from bu4.evaluation.elinked import ELinked +from bu4.evaluation.lambdaenv import LambdaEnv +from bu4.parsing.linked import Linked +from bu4.evaluation.aftervalue import EValue, envtype, Evaluable + +__all__ = ('ELambda',) + + +class ELambda(EValue): + def __init__(self, env: envtype, name: bytes, value: Linked): + self.env = env + self.name = name + self.value = value + + def call(self, argument: Evaluable) -> Evaluable: + return ELinked( + LambdaEnv(self.env, self.name, argument), + self.value + ) + + def __str__(self): + return f'({self.name.decode()}){self.value}' diff --git a/bu4/evaluation/elinked.py b/bu4/evaluation/elinked.py new file mode 100644 index 0000000..50cb55d --- /dev/null +++ b/bu4/evaluation/elinked.py @@ -0,0 +1,14 @@ +from bu4.parsing.linked import Linked +from bu4.evaluation.aftervalue import Evaluable, envtype + + +class ELinked(Evaluable): + def __init__(self, env: envtype, linked: Linked): + self.env = env + self.linked = linked + + def next(self) -> Evaluable: + return self.linked.evaluable(self.env) + + def __str__(self): + return f'{self.linked}' diff --git a/bu4/evaluation/enull.py b/bu4/evaluation/enull.py new file mode 100644 index 0000000..1545e6d --- /dev/null +++ b/bu4/evaluation/enull.py @@ -0,0 +1,11 @@ +from bu4.evaluation.aftervalue import EValue, Evaluable + +__all__ = ('ENull',) + + +class ENull(EValue): + def call(self, argument: Evaluable) -> Evaluable: + return self + + def __str__(self): + return f'?' diff --git a/bu4/evaluation/evaluable.py b/bu4/evaluation/evaluable.py new file mode 100644 index 0000000..960616a --- /dev/null +++ b/bu4/evaluation/evaluable.py @@ -0,0 +1,3 @@ +class Evaluable: + def next(self) -> 'Evaluable': + raise NotImplementedError diff --git a/bu4/evaluation/lambdaenv.py b/bu4/evaluation/lambdaenv.py new file mode 100644 index 0000000..58612ad --- /dev/null +++ b/bu4/evaluation/lambdaenv.py @@ -0,0 +1,24 @@ +from typing import Mapping, Iterator + +from bu4.evaluation.avcontainer import AVContainer +from bu4.evaluation.aftervalue import AfterValue, envtype, Evaluable + + +class LambdaEnv(Mapping): + def __getitem__(self, k: bytes) -> AfterValue: + if k == self.name: + return self.container + else: + return self.env[k] + + def __len__(self) -> int: + return len(self.env) + 1 + + def __iter__(self) -> Iterator[AfterValue]: + yield self.name + yield from self.env + + def __init__(self, env: envtype, name: bytes, evaluable: Evaluable): + self.env = env + self.name = name + self.container = AVContainer(evaluable).after_value diff --git a/bu4/evaluation/proxy.py b/bu4/evaluation/proxy.py new file mode 100644 index 0000000..6b82643 --- /dev/null +++ b/bu4/evaluation/proxy.py @@ -0,0 +1,51 @@ +from typing import Any + +from bu4.evaluation.aftervalue import AVTarget, EValue, Evaluable, AfterValue +from bu4.toolchain.sync import sync + + +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))) + + +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 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) diff --git a/bu4/linking/afterlinking.py b/bu4/linking/afterlinking.py new file mode 100644 index 0000000..796228d --- /dev/null +++ b/bu4/linking/afterlinking.py @@ -0,0 +1,8 @@ +from bu4.linking.altarget import ALTarget +from bu4.parsing.linked import LinkingState + + +class AfterLinking(LinkingState): + def __init__(self, state: LinkingState, target: ALTarget): + self.state = state + self.target = target diff --git a/bu4/linking/alal.py b/bu4/linking/alal.py new file mode 100644 index 0000000..5aa845d --- /dev/null +++ b/bu4/linking/alal.py @@ -0,0 +1,12 @@ +from bu4.linking.afterlinking import AfterLinking +from bu4.linking.altarget import ALTarget +from bu4.parsing.linked import Linked, LinkingState + + +class ALAL(ALTarget): + def __init__(self, target: ALTarget, aftertarget: ALTarget): + self.target = target + self.aftertarget = aftertarget + + def given(self, linked: Linked) -> LinkingState: + return AfterLinking(self.target.given(linked), self.aftertarget) diff --git a/bu4/linking/allambda.py b/bu4/linking/allambda.py new file mode 100644 index 0000000..a88f2fd --- /dev/null +++ b/bu4/linking/allambda.py @@ -0,0 +1,12 @@ +from typing import Callable + +from bu4.linking.altarget import ALTarget +from bu4.parsing.linked import Linked, LinkingState + + +class ALLambda(ALTarget): + def __init__(self, lambda_: Callable[[Linked], LinkingState]): + self.lambda_ = lambda_ + + def given(self, linked: Linked) -> LinkingState: + return self.lambda_(linked) diff --git a/bu4/linking/altarget.py b/bu4/linking/altarget.py new file mode 100644 index 0000000..e63e8be --- /dev/null +++ b/bu4/linking/altarget.py @@ -0,0 +1,6 @@ +from bu4.parsing.linked import Linked, LinkingState + + +class ALTarget: + def given(self, linked: Linked) -> LinkingState: + raise NotImplementedError diff --git a/bu4/linking/linkingfinished.py b/bu4/linking/linkingfinished.py new file mode 100644 index 0000000..3168f6e --- /dev/null +++ b/bu4/linking/linkingfinished.py @@ -0,0 +1,6 @@ +from bu4.parsing.linked import LinkingState, Linked + + +class LinkingFinished(LinkingState): + def __init__(self, linked: Linked): + self.linked = linked diff --git a/bu4/linking/linkingparsed.py b/bu4/linking/linkingparsed.py new file mode 100644 index 0000000..a3b2948 --- /dev/null +++ b/bu4/linking/linkingparsed.py @@ -0,0 +1,7 @@ +from bu4.parsing.linked import LinkingState, Parsed + + +class LinkingParsed(LinkingState): + def __init__(self, promise: set[bytes], parsed: Parsed): + self.promise = promise + self.parsed = parsed diff --git a/bu4/parsing/lcall.py b/bu4/parsing/lcall.py new file mode 100644 index 0000000..9a8ce4a --- /dev/null +++ b/bu4/parsing/lcall.py @@ -0,0 +1,60 @@ +from bu4.codes import CODE_CALL +from bu4.evaluation.avcall import AVCall +from bu4.evaluation.elinked import ELinked +from bu4.linking.afterlinking import AfterLinking +from bu4.linking.allambda import ALLambda +from bu4.parsing.linked import Linked, Parsed, LinkingState +from bu4.linking.linkingfinished import LinkingFinished +from bu4.linking.linkingparsed import LinkingParsed +from bu4.evaluation.aftervalue import envtype, Evaluable, AfterValue + +__all__ = ('LCall', 'PCall',) + + +class LCall(Linked): + argument: Linked + lambda_: Linked + + def __init__(self, promise: set[bytes], argument: Parsed, lambda_: Parsed): + self.promise = promise + self._argument = argument + self._lambda = lambda_ + + def link(self) -> LinkingState: + return AfterLinking( + LinkingParsed(self.promise, self._argument), + ALLambda(self._given_argument) + ) + + def _given_argument(self, argument: Linked) -> LinkingState: + self.argument = argument + return AfterLinking( + LinkingParsed(self.promise, self._lambda), + ALLambda(self._given_lambda) + ) + + def _given_lambda(self, lambda_) -> LinkingState: + self.lambda_ = lambda_ + self.future = self.argument.future | self.lambda_.future + return LinkingFinished(self) + + def evaluable(self, env: envtype) -> Evaluable: + return AfterValue(ELinked(env, self.lambda_), AVCall(env, self.argument)) + + def __str__(self): + return f'/{self.argument}{self.lambda_}' + + def unlink(self) -> Parsed: + return PCall(self._argument, self._lambda) + + +class PCall(Parsed): + def __init__(self, value: Parsed, lambda_: Parsed): + self.value = value + self.lambda_ = lambda_ + + def link(self, promise: set[bytes]) -> Linked: + return LCall(promise, self.value, self.lambda_) + + def __bytes__(self): + return bytes([CODE_CALL, *bytes(self.value), *bytes(self.lambda_)]) diff --git a/bu4/parsing/linked.py b/bu4/parsing/linked.py new file mode 100644 index 0000000..6c669cb --- /dev/null +++ b/bu4/parsing/linked.py @@ -0,0 +1,29 @@ +from bu4.evaluation.aftervalue import envtype, Evaluable + + +class LinkingState: + pass + + +class Linked: + future: set[bytes] + + def link(self) -> LinkingState: + raise NotImplementedError + + def evaluable(self, env: envtype) -> Evaluable: + raise NotImplementedError + + def unlink(self) -> 'Parsed': + raise NotImplementedError + + def __bytes__(self): + return bytes(self.unlink()) + + +class Parsed: + def link(self, promise: set[bytes]) -> Linked: + raise NotImplementedError + + def __bytes__(self): + raise NotImplementedError diff --git a/bu4/parsing/llambda.py b/bu4/parsing/llambda.py new file mode 100644 index 0000000..187741e --- /dev/null +++ b/bu4/parsing/llambda.py @@ -0,0 +1,53 @@ +from bu4.codes import CODE_MAKE, CODE_NULL +from bu4.evaluation.elambda import ELambda +from bu4.linking.afterlinking import AfterLinking +from bu4.linking.allambda import ALLambda +from bu4.parsing.linked import Linked, Parsed, LinkingState +from bu4.linking.linkingfinished import LinkingFinished +from bu4.linking.linkingparsed import LinkingParsed +from bu4.evaluation.aftervalue import envtype, Evaluable + +__all__ = ('LLambda', '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) + + def __bytes__(self): + return bytes([CODE_MAKE, *self.name, CODE_NULL, *bytes(self.value)]) diff --git a/bu4/parsing/lname.py b/bu4/parsing/lname.py new file mode 100644 index 0000000..8a34f82 --- /dev/null +++ b/bu4/parsing/lname.py @@ -0,0 +1,37 @@ +from bu4.codes import CODE_NAME, CODE_NULL +from bu4.parsing.linked import Linked, LinkingState, Parsed +from bu4.linking.linkingfinished import LinkingFinished +from bu4.evaluation.aftervalue import envtype, Evaluable + + +__all__ = ('LName', 'PName',) + + +class LName(Linked): + def __init__(self, promise: set[bytes], name: bytes): + assert name in promise, f'undefined: {name}' + self.name = name + self.future = {name} + + def link(self) -> LinkingState: + return LinkingFinished(self) + + def evaluable(self, env: envtype) -> Evaluable: + return env[self.name] + + def __str__(self): + return f'[{self.name.decode()}]' + + def unlink(self) -> Parsed: + return PName(self.name) + + +class PName(Parsed): + def __init__(self, name: bytes): + self.name = name + + def link(self, promise: set[bytes]) -> Linked: + return LName(promise, self.name) + + def __bytes__(self): + return bytes([CODE_NAME, *self.name, CODE_NULL]) diff --git a/bu4/parsing/lnull.py b/bu4/parsing/lnull.py new file mode 100644 index 0000000..d4a8592 --- /dev/null +++ b/bu4/parsing/lnull.py @@ -0,0 +1,33 @@ +from bu4.evaluation.enull import ENull +from bu4.codes import CODE_NULL +from bu4.parsing.linked import Linked, LinkingState, Parsed +from bu4.linking.linkingfinished import LinkingFinished +from bu4.evaluation.aftervalue import envtype, Evaluable + + +__all__ = ('LNull', 'PNull',) + + +class LNull(Linked): + def __init__(self): + self.future = set() + + def link(self) -> LinkingState: + return LinkingFinished(self) + + def evaluable(self, env: envtype) -> Evaluable: + return ENull() + + def __str__(self): + return '?' + + def unlink(self) -> Parsed: + return PNull() + + +class PNull(Parsed): + def link(self, promise: set[bytes]) -> 'Linked': + return LNull() + + def __bytes__(self): + return bytes([CODE_NULL]) diff --git a/bu4/parsing/parser.py b/bu4/parsing/parser.py new file mode 100644 index 0000000..7eb9e17 --- /dev/null +++ b/bu4/parsing/parser.py @@ -0,0 +1,141 @@ +from io import BytesIO +from typing import Callable + +from bu4.parsing.linked import Parsed +from bu4.parsing.lname import PName +from bu4.codes import CODE_NULL, CODE_CALL, CODE_MAKE, CODE_NAME, CODE_SKIP, CODE_QUOT, CODE_QOPN, CODE_QCLS +from bu4.parsing.lcall import PCall +from bu4.parsing.lnull import PNull + +from bu4.parsing.llambda import PLambda + + +class ParseState: + pass + + +class PSRead(ParseState): + pass + + +class PSFinal(ParseState): + def __init__(self, parsed: Parsed): + self.parsed = parsed + + +class PSATarget: + def given(self, parsed: Parsed) -> ParseState: + raise NotImplementedError + + +class PSAfter(ParseState): + def __init__(self, state, target: PSATarget): + self.state = state + self.target = target + + +class PSAA(PSATarget): + def __init__(self, target: PSATarget, aftertarget: PSATarget): + self.target = target + self.aftertarget = aftertarget + + def given(self, parsed: Parsed) -> ParseState: + return PSAfter(self.target.given(parsed), self.aftertarget) + + +class PSALambda(PSATarget): + def __init__(self, lambda_: Callable[[Parsed], ParseState]): + self.lambda_ = lambda_ + + def given(self, parsed: Parsed) -> ParseState: + return self.lambda_(parsed) + + +class PSAEndsWith(PSATarget): + def __init__(self, parser: 'Parser', c: int, msg: str): + self.parser = parser + self.c = c + self.msg = msg + + def given(self, parsed: Parsed) -> ParseState: + assert self.parser.read() == self.c, self.msg + return PSFinal(parsed) + + +_apacall = PSAfter( + PSRead(), + PSALambda( + lambda argument: PSAfter( + PSRead(), + PSALambda( + lambda lambda_: PSFinal( + PCall( + argument, + lambda_ + ) + ) + ) + ) + ) +) + + +class Parser: + def __init__(self, s: bytes): + self.__s = BytesIO(s) + + def read(self) -> int: + bytes_ = self.__s.read(1) + return bytes_[0] if bytes_ else 0 + + def parse_name(self) -> bytes: + s = BytesIO() + while True: + c = self.read() + if not c: + return s.getvalue() + s.write(bytes([c])) + + def _state_read(self, state: PSAfter): + c = self.read() + if c == CODE_NULL: + state.state = PSFinal(PNull()) + elif c == CODE_CALL: + state.state = _apacall + elif c == CODE_MAKE: + state.state = (lambda name: PSAfter( + PSRead(), + PSALambda( + lambda value: PSFinal(PLambda(name, value)) + ) + ))(self.parse_name()) + elif c == CODE_NAME: + state.state = PSFinal(PName(self.parse_name())) + elif c == CODE_SKIP: + pass + elif c == CODE_QUOT: + state.target = PSAA(PSAEndsWith(self, CODE_QUOT, "quot expected"), state.target) + elif c == CODE_QOPN: + state.target = PSAA(PSAEndsWith(self, CODE_QCLS, "qcls expected"), state.target) + else: + raise ValueError(f"unknown control: {hex(c)}") + return state + + def _state_next(self, state: PSAfter): + if isinstance(state.state, PSAfter): + state.state, state.target = state.state.state, PSAA(state.state.target, state.target) + elif isinstance(state.state, PSFinal): + state = state.target.given(state.state.parsed) + elif isinstance(state.state, PSRead): + state = self._state_read(state) + return state + + def parse(self) -> Parsed: + state = PSAfter(PSRead(), PSALambda(lambda parsed: PSFinal(parsed))) + while True: + if isinstance(state, PSFinal): + return state.parsed + elif isinstance(state, PSAfter): + state = self._state_next(state) + else: + raise TypeError diff --git a/bu4/toolchain/elinked.py b/bu4/toolchain/elinked.py new file mode 100644 index 0000000..dcb070d --- /dev/null +++ b/bu4/toolchain/elinked.py @@ -0,0 +1,10 @@ +from bu4.evaluation.elinked import ELinked +from bu4.parsing.linked import Parsed +from bu4.evaluation.aftervalue import envtype +from bu4.toolchain.prepare import prepare + + +def elinked(env: envtype, parsed: Parsed): + linked = parsed.link(set(env)) + prepare(linked) + return ELinked(env, linked) diff --git a/bu4/toolchain/parse.py b/bu4/toolchain/parse.py new file mode 100644 index 0000000..dfc0a29 --- /dev/null +++ b/bu4/toolchain/parse.py @@ -0,0 +1,6 @@ +from bu4.parsing.linked import Parsed +from bu4.parsing.parser import Parser + + +def parse(source: bytes) -> Parsed: + return Parser(source).parse() diff --git a/bu4/toolchain/prepare.py b/bu4/toolchain/prepare.py new file mode 100644 index 0000000..f1cab13 --- /dev/null +++ b/bu4/toolchain/prepare.py @@ -0,0 +1,28 @@ +from bu4.linking.afterlinking import AfterLinking +from bu4.linking.alal import ALAL +from bu4.parsing.linked import LinkingState, Linked +from bu4.linking.linkingfinished import LinkingFinished +from bu4.linking.linkingparsed import LinkingParsed + + +def _afterlinking_iteration(state: AfterLinking) -> LinkingState: + if isinstance(state.state, LinkingFinished): + state = state.target.given(state.state.linked) + elif isinstance(state.state, AfterLinking): + state.state, state.target = state.state.state, ALAL(state.state.target, state.target) + elif isinstance(state.state, LinkingParsed): + state.state = state.state.parsed.link(state.state.promise).link() + else: + raise TypeError + return state + + +def prepare(linked: Linked) -> Linked: + state = linked.link() + while True: + if isinstance(state, LinkingFinished): + return state.linked + elif isinstance(state, AfterLinking): + state = _afterlinking_iteration(state) + else: + raise TypeError diff --git a/bu4/toolchain/readfile.py b/bu4/toolchain/readfile.py new file mode 100644 index 0000000..716bc1f --- /dev/null +++ b/bu4/toolchain/readfile.py @@ -0,0 +1,13 @@ +import os +from io import StringIO + + +def readfile(path: str) -> str: + srcio = StringIO() + with open(path + '.bu4') as file: + for line in file: + if line.startswith('@'): + srcio.write(readfile(os.path.join(path, '..', line.removeprefix('@').strip()))) + else: + srcio.write(line) + return srcio.getvalue() diff --git a/bu4/toolchain/sync.py b/bu4/toolchain/sync.py new file mode 100644 index 0000000..c58141b --- /dev/null +++ b/bu4/toolchain/sync.py @@ -0,0 +1,8 @@ +from bu4.evaluation.aftervalue import Evaluable, EValue + + +def sync(evaluable: Evaluable) -> EValue: + while True: + if isinstance(evaluable, EValue): + return evaluable + evaluable = evaluable.next() diff --git a/bu4/toolchain/synced.py b/bu4/toolchain/synced.py new file mode 100644 index 0000000..c7b36d0 --- /dev/null +++ b/bu4/toolchain/synced.py @@ -0,0 +1,12 @@ +from bu4.evaluation.aftervalue import EValue +from bu4.toolchain.elinked import elinked +from bu4.toolchain.parse import parse +from bu4.toolchain.sync import sync +from bu4.toolchain.transply import transply + + +def synced(source: str) -> EValue: + bsource = transply(source) + parsed = parse(bsource) + evaluable = elinked({}, parsed) + return sync(evaluable) diff --git a/bu4/toolchain/transply.py b/bu4/toolchain/transply.py new file mode 100644 index 0000000..025a1c5 --- /dev/null +++ b/bu4/toolchain/transply.py @@ -0,0 +1,38 @@ +from io import BytesIO + +from bu4.codes import CODE_CALL, CODE_QOPN, CODE_MAKE, CODE_QCLS, CODE_NULL, CODE_SKIP, CODE_NAME, CODE_QUOT + + +def transply(source: str) -> bytes: + b = BytesIO() + for c in source: + if c.isspace(): + pass + elif c in '/': + b.write(bytes([CODE_CALL])) + elif c in '{': + b.write(bytes([CODE_CALL, CODE_QOPN])) + elif c in '(': + b.write(bytes([CODE_MAKE])) + elif c in '|': + b.write(bytes([CODE_QCLS, CODE_MAKE])) + elif c in '})': + b.write(bytes([CODE_NULL])) + elif c in '#': + b.write(bytes([CODE_SKIP])) + elif c in '?': + b.write(bytes([CODE_QOPN, CODE_NULL, CODE_QCLS])) + elif c in ']': + b.write(bytes([CODE_NULL, CODE_QCLS])) + elif c in '[': + b.write(bytes([CODE_QOPN, CODE_NAME])) + elif c in '"': + b.write(bytes([CODE_QUOT])) + elif c in '<': + b.write(bytes([CODE_QOPN])) + elif c in '>': + b.write(bytes([CODE_QCLS])) + else: + value = c.encode() + b.write(value if len(value) == 1 else value.hex().encode()) + return b.getvalue() diff --git a/bu4/utils.py b/bu4/utils.py new file mode 100644 index 0000000..729eeac --- /dev/null +++ b/bu4/utils.py @@ -0,0 +1,17 @@ +from bu4.evaluation.proxy import eproxy +from bu4.evaluation.aftervalue import EValue +from bu4.toolchain.sync import sync + + +def to_bool(_01): + return _01(True)(False) + + +def with_common_interface(value: EValue): + value = sync(value.call(eproxy(0))) + value = sync(value.call(eproxy(1))) + value = sync(value.call(eproxy(lambda a: lambda b: a + b))) + value = sync(value.call(eproxy(lambda n: lambda x: lambda y: x if n == 0 else y))) + value = sync(value.call(eproxy(lambda n: lambda x: lambda y: x if n & 1 else y))) + value = sync(value.call(eproxy(lambda n: n >> 1))) + return value diff --git a/main.py b/main.py new file mode 100644 index 0000000..f9ddc7f --- /dev/null +++ b/main.py @@ -0,0 +1,51 @@ +from bu4.evaluation.proxy import antiproxy, eproxy +from bu4.toolchain.readfile import readfile +from bu4.toolchain.sync import sync +from bu4.toolchain.synced import synced +from bu4.utils import with_common_interface +from timesample import TimeSample + +with TimeSample(' compilation'): + sys0 = synced(readfile('src/sys0')) +with TimeSample(' first, AP'): + print( + antiproxy(sys0)(0)(1)( + lambda a: lambda b: a + b + )( + lambda n: lambda x: lambda y: x if n == 0 else y + )( + lambda n: lambda x: lambda y: x if n & 1 else y + )( + lambda n: n >> 1 + ) + ) +with TimeSample(' second, AP'): + print( + antiproxy(sys0)(0)(1)( + lambda a: lambda b: a + b + )( + lambda n: lambda x: lambda y: x if n == 0 else y + )( + lambda n: lambda x: lambda y: x if n & 1 else y + )( + lambda n: n >> 1 + ) + ) +with TimeSample(' third, EP'): + sys0 = with_common_interface(sys0) + print(sys0) +with TimeSample(' sys2'): + with TimeSample(' compilation'): + sys2c = synced(readfile('src/sys2')) + with TimeSample(' runtime'): + sys2 = sys2c + sys2 = with_common_interface(sys2) + print(sys2) + with TimeSample(' runtime'): + sys2 = sys2c + sys2 = with_common_interface(sys2) + print(sys2) +with TimeSample(' full'): + sys3 = with_common_interface(synced(readfile('src/sys3'))) + sys3 = sync(sys3.call(eproxy(5))) + print(sys3) diff --git a/src/@.bu4 b/src/@.bu4 new file mode 100644 index 0000000..2f6cf0d --- /dev/null +++ b/src/@.bu4 @@ -0,0 +1,6 @@ +@core/@ +@church_numerals/@ +@binary/@ +@convert/@ +@io/@ +@numbers diff --git a/src/binary/01.bu4 b/src/binary/01.bu4 new file mode 100644 index 0000000..6f1a42f --- /dev/null +++ b/src/binary/01.bu4 @@ -0,0 +1,2 @@ +{ /<(b0) <(g) /[b0]/[0]/[1][g]> >[YC] | b0 } +{ <(g) /[b0]/[1]/[0][g]> | b1 } diff --git a/src/binary/@.bu4 b/src/binary/@.bu4 new file mode 100644 index 0000000..403f23c --- /dev/null +++ b/src/binary/@.bu4 @@ -0,0 +1,5 @@ +@b! +@01 +@add +@mul +@sub diff --git a/src/binary/add.bu4 b/src/binary/add.bu4 new file mode 100644 index 0000000..c33bf8b --- /dev/null +++ b/src/binary/add.bu4 @@ -0,0 +1,34 @@ +{ (b) | b_double } + +{ + /(b_add) + (bA)(bB) + /(zqA)(lbA)(hb!A) + / + /(zqB)(lbB)(hb!B) + / + / + / + / + [hb!A] + / + [hb!B] + [b_add] + / + /[b0]/[b1] + [b_add] + / + /[lbB]/[lbA][xor] + [b!] + / + [bA] + [zqB] + [bB] + / + [bB] + [zqA] + [bA] + [YC] +| + b_add +} diff --git a/src/binary/b!.bu4 b/src/binary/b!.bu4 new file mode 100644 index 0000000..0734881 --- /dev/null +++ b/src/binary/b!.bu4 @@ -0,0 +1,19 @@ +{ + (lb)(hb!) + (g) + / + [hb!] + / + [lb] + / + / + /(hzq)(hlb)(hhb!) + [hzq] + [hb!] + / + [0] + [lb] + [g] +| + b! +} diff --git a/src/binary/mul.bu4 b/src/binary/mul.bu4 new file mode 100644 index 0000000..51c743a --- /dev/null +++ b/src/binary/mul.bu4 @@ -0,0 +1,40 @@ +{ + /(b_mul) + (bA)(bB) + /(zqA)(lbA)(hb!A) + / + /(zqB)(lbB)(hb!B) + / + / + / + / + /[b0]/[hb!A] <[lbB]> + / + /[b0]/[hb!B] <[lbA]> + [b_add] + / + / + / + [hb!A] + / + [hb!B] + [b_mul] + [b_double] + [b_add] + / + + [b!] + / + [b0] + [zqB] + [bB] + / + [b0] + [zqA] + [bA] + [YC] +| + b_mul +} + +{ (b) /[b]/[b][b_mul] | b_square } diff --git a/src/binary/sub.bu4 b/src/binary/sub.bu4 new file mode 100644 index 0000000..662ea20 --- /dev/null +++ b/src/binary/sub.bu4 @@ -0,0 +1,98 @@ +{ + /(b_sub) + (bA)(bB) + /(zqA)(lbA)(hb!A) + / + /(zqB)(lbB)(hb!B) + / + /(hsAB)(hsBA) + / + / + / + /[hsBA][b_double] + / + /[hsAB][b_double] + [pair] + / + /(zqhsAB)(lbAB-unused)(hb!AB-unused) + / + / + [b0] + / + / + / + / + [b1] + / + [hsAB] + [b_sub] + [first] + / + [1] + [b!] + [pair] + / + / + /[hsBA]/[1][b!] + / + [b0] + [pair] + [zqhsAB] + [hsAB] + [lbB] + / + / + /(zqhsBA)(lbBA-unused)(hb!BA-unused) + / + / + / + / + / + [hsBA] + / + [b1] + [b_sub] + [second] + / + [1] + [b!] + / + [b0] + [pair] + / + / + [b0] + / + /[hsAB]/[1][b!] + [pair] + [zqhsBA] + [hsBA] + / + / + /[hsBA][b_double] + / + /[hsAB][b_double] + [pair] + [lbB] + [lbA] + /[hb!B]/[hb!A][b_sub] + / + / + [b0] + / + [bA] + [pair] + [zqB] + [bB] + / + / + [bB] + / + [b0] + [pair] + [zqA] + [bA] + [YC] +| + b_sub +} diff --git a/src/church_numerals/01.bu4 b/src/church_numerals/01.bu4 new file mode 100644 index 0000000..5715b6f --- /dev/null +++ b/src/church_numerals/01.bu4 @@ -0,0 +1,2 @@ +{ (f)(x) [x] | c0 } +{ (f)(x) /[x][f] | c1 } diff --git a/src/church_numerals/@.bu4 b/src/church_numerals/@.bu4 new file mode 100644 index 0000000..f7b0d1a --- /dev/null +++ b/src/church_numerals/@.bu4 @@ -0,0 +1,2 @@ +@01 +@add diff --git a/src/church_numerals/add.bu4 b/src/church_numerals/add.bu4 new file mode 100644 index 0000000..dfadfe8 --- /dev/null +++ b/src/church_numerals/add.bu4 @@ -0,0 +1,2 @@ +{ (cA)(cB)(f)(x) //[x] | c_add } +{ (c) /[c]/[c][c_add] | c_double } diff --git a/src/ci.bu4 b/src/ci.bu4 new file mode 100644 index 0000000..ea4bc71 --- /dev/null +++ b/src/ci.bu4 @@ -0,0 +1,3 @@ +(n0)(n1)(n_add)(n_zq)(n_lb)(n_h) +{ /[n_add]/[n1]/[n0] [b_to_n] | b_to_nx } +{ /[n_h]/[n_lb]/[n_zq][n_to_b] | n_to_bx } diff --git a/src/convert/@.bu4 b/src/convert/@.bu4 new file mode 100644 index 0000000..5127947 --- /dev/null +++ b/src/convert/@.bu4 @@ -0,0 +1,3 @@ +@b_to_c +@b_to_n +@n_to_b diff --git a/src/convert/b_to_c.bu4 b/src/convert/b_to_c.bu4 new file mode 100644 index 0000000..531661c --- /dev/null +++ b/src/convert/b_to_c.bu4 @@ -0,0 +1,18 @@ +{ + /(b_to_c) + (b) + /(zq)(lb)(hb!) + / + / + /[c0]/[c1][lb] + / + /[c_double] + [c_add] + / + [c0] + [zq] + [b] + [YC] +| + b_to_c +} diff --git a/src/convert/b_to_n.bu4 b/src/convert/b_to_n.bu4 new file mode 100644 index 0000000..c5a2df1 --- /dev/null +++ b/src/convert/b_to_n.bu4 @@ -0,0 +1,28 @@ +{ + (n0)(n1)(n_add) + /(b_to_nx) + (b) + /(zq)(lb)(hb!) + / + / + { /[hb!][b_to_nx] | hn } + / + [hn] + / + [hn] + [n_add] + / + / + [n0] + / + [n1] + [lb] + [n_add] + / + [n0] + [zq] + [b] + [YC] +| + b_to_n +} diff --git a/src/convert/n_to_b.bu4 b/src/convert/n_to_b.bu4 new file mode 100644 index 0000000..03b4f0a --- /dev/null +++ b/src/convert/n_to_b.bu4 @@ -0,0 +1,17 @@ +{ + (n_zq)(n_lb)(n_h) + /(n_to_bx) + (n) + / + / + //[n][n_h][n_to_bx] + / + //[n][n_lb][bool] + [b!] + / + [b0] + /[n][n_zq] + [YC] +| + n_to_b +} diff --git a/src/core/@.bu4 b/src/core/@.bu4 new file mode 100644 index 0000000..8836f14 --- /dev/null +++ b/src/core/@.bu4 @@ -0,0 +1,6 @@ +@bool +@pair +@yc +@id +@collector +@compose diff --git a/src/core/bool.bu4 b/src/core/bool.bu4 new file mode 100644 index 0000000..e6439af --- /dev/null +++ b/src/core/bool.bu4 @@ -0,0 +1,7 @@ +{ (x)(y) [x] | 1 } +{ (x)(y) [y] | 0 } +{ (x) /[0]/[1][x] | bool } +{ (x) /[1]/[0][x] | not } +{ (x)(y) /[0]/[y][x] | and } +{ (x)(y) /[y]/[1][x] | or } +{ (x)(y) /[y]/[x] | xor } diff --git a/src/core/collector.bu4 b/src/core/collector.bu4 new file mode 100644 index 0000000..31873c0 --- /dev/null +++ b/src/core/collector.bu4 @@ -0,0 +1,19 @@ +{ + /(collector) + (x) + (mode) + / + [x] + / + (g) + / + /[x][g] + [collector] + [mode] + [YC] +| + collector +} + +{ [1] | collecting } +{ [0] | collect } diff --git a/src/core/compose.bu4 b/src/core/compose.bu4 new file mode 100644 index 0000000..c8e7e72 --- /dev/null +++ b/src/core/compose.bu4 @@ -0,0 +1 @@ +{ (_first)(_second)(x) //[x][_first][_second] | compose } diff --git a/src/core/id.bu4 b/src/core/id.bu4 new file mode 100644 index 0000000..37961c9 --- /dev/null +++ b/src/core/id.bu4 @@ -0,0 +1 @@ +{ (x)[x] | ID } diff --git a/src/core/pair.bu4 b/src/core/pair.bu4 new file mode 100644 index 0000000..f12b23d --- /dev/null +++ b/src/core/pair.bu4 @@ -0,0 +1,6 @@ +{ (x)(y)(g) /[y]/[x][g] | pair } +{ (_pair) /[1][_pair] | first } +{ (_pair) /[0][_pair] | second } +{ (x) /[x]/[x][pair] | double } +{ (x)(y) /[x]/[y][pair] | iswap } +{ (_pair) /[iswap][_pair] | swap } diff --git a/src/core/yc.bu4 b/src/core/yc.bu4 new file mode 100644 index 0000000..dc3445f --- /dev/null +++ b/src/core/yc.bu4 @@ -0,0 +1,2 @@ +{ (x) /[x][x] | SC } +{ (g) /<(x)//[x][SC][g]>[SC] | YC } diff --git a/src/io/@.bu4 b/src/io/@.bu4 new file mode 100644 index 0000000..bab05e5 --- /dev/null +++ b/src/io/@.bu4 @@ -0,0 +1,5 @@ +@system +@pipe +@transform +@sysbinary +@decorator diff --git a/src/io/decorator.bu4 b/src/io/decorator.bu4 new file mode 100644 index 0000000..ec99810 --- /dev/null +++ b/src/io/decorator.bu4 @@ -0,0 +1,14 @@ +{ + (input)(output)(decorated) + / + / + [output] + / + [decorated] + [pipeline] + / + [input] + [pipeline] +| + sysDecorator +} diff --git a/src/io/pipe.bu4 b/src/io/pipe.bu4 new file mode 100644 index 0000000..b4500fa --- /dev/null +++ b/src/io/pipe.bu4 @@ -0,0 +1,37 @@ +{ + /(pipeline) + (input)(output) + /(isInputI)(outI)(outputI)(inputI) + /(isInputO)(outO)(outputO)(inputO) + / + / + (in) + / + [output] + / + /[in][inputI] + [pipeline] + / + / + [outputO] + / + [input] + [pipeline] + / + [outO] + / + [isInputO] + [system] + / + / + /[outI][inputO] + / + [outputI] + [pipeline] + //[isInputO][and] + [output] + [input] + [YC] +| + pipeline +} diff --git a/src/io/sysbinary.bu4 b/src/io/sysbinary.bu4 new file mode 100644 index 0000000..b5c4a6d --- /dev/null +++ b/src/io/sysbinary.bu4 @@ -0,0 +1,66 @@ +{ + /(sysB2Bits) + / + /(b2sys) + (b) + /(zq)(lb)(hb!) + / + / + / + / + [hb!] + [b2sys] + / + [lb] + [outSystem] + / + [0] + [outSystem] + / + / + [sysB2Bits] + / + [1] + [outSystem] + [zq] + [b] + [YC] + [inSimple] + [YC] +| + sysB2Bits +} + +{ + / + [ID] + /(sysBits2B) + (callback) + / + (in-zq) + / + / + (in-lb) + / + (b) + / + / + [b] + / + [in-lb] + [b!] + [callback] + [sysBits2B] + [inSimple] + / + / + /[ID][sysBits2B] + / + /[b0][callback] + [outSystem] + [in-zq] + [inSimple] + [YC] +| + sysBits2B +} diff --git a/src/io/system.bu4 b/src/io/system.bu4 new file mode 100644 index 0000000..1d940e1 --- /dev/null +++ b/src/io/system.bu4 @@ -0,0 +1,92 @@ +{ + (isInput)(out)(output)(input) + (g) + /[input]/[output]/[out]/[isInput] + [g] +| + system +} + +{ + (isInput)(out)(output)(input) + [isInput] +| + isSysInput +} + +{ + (isInput)(out)(output)(input) + [out] +| + outOf +} + +{ + (isInput)(out)(output)(input) + [output] +| + outputOf +} + +{ + (isInput)(out)(output)(input) + [input] +| + inputOf +} + +{ + (value)(sys) + /[value]/[inputOf][sys] +| + writeValue +} + +{ + (out)(output) + / + /[inputOf][output] + / + [output] + / + [out] + / + [0] + [system] +| + outSystem +} + + +{ + (input) + /(this) + / + [input] + / + ? + / + ? + / + [1] + [system] + [YC] +| + inSimple +} + + +{ + (out)(output)(input) + / + [input] + / + [output] + / + [out] + / + [1] + [system] +| + inSystem +} diff --git a/src/io/transform.bu4 b/src/io/transform.bu4 new file mode 100644 index 0000000..7cf282b --- /dev/null +++ b/src/io/transform.bu4 @@ -0,0 +1,15 @@ +{ + (g) + /(this) + / + (in) + / + [this] + / + /[in][g] + [outSystem] + [inSimple] + [YC] +| + sysTransform +} diff --git a/src/numbers.bu4 b/src/numbers.bu4 new file mode 100644 index 0000000..314a807 --- /dev/null +++ b/src/numbers.bu4 @@ -0,0 +1,23 @@ +{ /[b1][b_double] | b2 } +{ /[b1]/[1][b!] | b3 } +{ /[b2][b_double] | b4 } +{ /[b2]/[1][b!] | b5 } +{ /[b3][b_double] | b6 } +{ /[b3]/[1][b!] | b7 } +{ /[b4][b_double] | b8 } +{ /[b4]/[1][b!] | b9 } +{ /[b5][b_double] | bxA } +{ /[b5]/[1][b!] | bxB } + +{ /[b3][b_square] | ^1 } +{ /[^1][b_square] | ^2 } +{ /[^2][b_square] | ^3 } +{ /[^3][b_square] | ^4 } +{ /[^4][b_square] | ^5 } +{ /[^5][b_square] | ^6 } +{ /[^6][b_square] | ^7 } +{ /[^7][b_square] | ^8 } +{ /[^8][b_square] | ^9 } +{ /[^9][b_square] | ^A } +{ /[^A][b_square] | ^B } +{ /[^B][b_square] | ^C } diff --git a/src/sys0.bu4 b/src/sys0.bu4 new file mode 100644 index 0000000..18ff896 --- /dev/null +++ b/src/sys0.bu4 @@ -0,0 +1,7 @@ +@@ + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +@ci + + /[^4][b_to_nx] +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/sys2.bu4 b/src/sys2.bu4 new file mode 100644 index 0000000..40fc792 --- /dev/null +++ b/src/sys2.bu4 @@ -0,0 +1,12 @@ +@@ + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +@ci + + // + / + [^5] + / + [^4] + [b_sub][second][b_to_nx] +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/sys3.bu4 b/src/sys3.bu4 new file mode 100644 index 0000000..e6ea73c --- /dev/null +++ b/src/sys3.bu4 @@ -0,0 +1,37 @@ +@@ + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +@ci + +(n) + +/ + [outOf] +/ + [n] +/ + [inputOf] +/ + < + / + / + /[ID][sysTransform] + / + [sysBits2B] + / + [sysB2Bits] + [sysDecorator] + / + /[b_square][sysTransform] + / + /[b_square][sysTransform] + [sysDecorator] + > +/ + /[b_to_nx][sysTransform] +/ + /[n_to_bx][sysTransform] +[sysDecorator] + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/timesample.py b/timesample.py new file mode 100644 index 0000000..e85d4ac --- /dev/null +++ b/timesample.py @@ -0,0 +1,18 @@ +import time + + +class TimeSample: + level = 0 + + def __init__(self, *args): + self.args = args + + def __enter__(self): + TimeSample.level += 1 + self.__t = time.time() + + def __exit__(self, exc_type, exc_val, exc_tb): + TimeSample.level -= 1 + print(' ' * 4 * self.level, end='') + print(*self.args, time.time() - self.__t) + print()