diff --git a/README.md b/README.md index 4d02b30..8f2e59b 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,22 @@ # Lamb: A Lambda Calculus Engine +If you're reading this on PyPi, go [here](https://git.betalupi.com/Mark/lamb). + ![Lamb screenshot](./misc/screenshot.png) + ## Installation -### Method 1: PyPi (not yet) -1. Put this on PyPi -2. Write these instructions +### Method 1: PyPi [here](https://pypi.org/project/lamb-engine) +1. `pip install lamb-engine` +2. `lamb` ### Method 2: Git 1. Clone this repository. 2. Make and enter a [virtual environment](https://docs.python.org/3/library/venv.html). 3. ``cd`` into this directory 4. Run ``pip install .`` -5. Run ``python .`` +5. Run ``lamb`` ------------------------------------------------- @@ -43,7 +46,7 @@ Numbers will automatically be converted to Church numerals. For example, the fol If an expression takes too long to evaluate, you may interrupt reduction with `Ctrl-C`. \ Exit the prompt with `Ctrl-C` or `Ctrl-D`. -There are many useful macros in [macros.lamb](./macros.lamb). Load them with the `:load` command: +There are many useful macros in [macros.lamb](./macros.lamb). Download the file, then load them with the `:load` command: ``` ==> :load macros.lamb ``` @@ -86,20 +89,12 @@ The lines in a file look exactly the same as regular entries in the prompt, but ------------------------------------------------- - -## Todo (pre-release, in this order): - - Write "how it works" - - PyPi package - - ## Todo: - Prevent macro-chaining recursion - Cleanup warnings - Truncate long expressions in warnings - - History indexing - - Show history command - Loop detection - - $\alpha$-equivalence check + - α-equivalence check - Command-line options (load a file) - Unchurch command: make church numerals human-readable - Better Syntax highlighting diff --git a/lamb_engine/__init__.py b/lamb_engine/__init__.py index 38688c1..1329954 100644 --- a/lamb_engine/__init__.py +++ b/lamb_engine/__init__.py @@ -3,4 +3,6 @@ from . import nodes from . import parser from .runner import Runner -from .runner import StopReason \ No newline at end of file +from .runner import StopReason + +from .__main__ import main \ No newline at end of file diff --git a/lamb_engine/__main__.py b/lamb_engine/__main__.py index 5ff8972..d386dbc 100755 --- a/lamb_engine/__main__.py +++ b/lamb_engine/__main__.py @@ -1,6 +1,3 @@ -if __name__ != "__main__": - raise ImportError("lamb_engine.__main__ should never be imported. Run it directly.") - from prompt_toolkit import PromptSession from prompt_toolkit import print_formatted_text as printf from prompt_toolkit.formatted_text import FormattedText @@ -9,53 +6,57 @@ from pyparsing import exceptions as ppx import lamb_engine +def main(): -lamb_engine.utils.show_greeting() + lamb_engine.utils.show_greeting() -r = lamb_engine.Runner( - prompt_session = PromptSession( - style = lamb_engine.utils.style, - lexer = lamb_engine.utils.LambdaLexer(), - key_bindings = lamb_engine.utils.bindings - ), - prompt_message = FormattedText([ - ("class:prompt", "==> ") - ]) -) + r = lamb_engine.Runner( + prompt_session = PromptSession( + style = lamb_engine.utils.style, + lexer = lamb_engine.utils.LambdaLexer(), + key_bindings = lamb_engine.utils.bindings + ), + prompt_message = FormattedText([ + ("class:prompt", "==> ") + ]) + ) -while True: - try: - i = r.prompt() + while True: + try: + i = r.prompt() - # Catch Ctrl-C and Ctrl-D - except KeyboardInterrupt: - printf("\n\nGoodbye.\n") - break - except EOFError: - printf("\n\nGoodbye.\n") - break + # Catch Ctrl-C and Ctrl-D + except KeyboardInterrupt: + printf("\n\nGoodbye.\n") + break + except EOFError: + printf("\n\nGoodbye.\n") + break - # Skip empty lines - if i.strip() == "": - continue + # Skip empty lines + if i.strip() == "": + continue - # Try to run an input line. - # Catch parse errors and point them out. - try: - x = r.run(i) - except ppx.ParseException as e: - l = len(to_plain_text(r.prompt_session.message)) - printf(FormattedText([ - ("class:err", " "*(e.loc + l) + "^\n"), - ("class:err", f"Syntax error at char {e.loc}."), - ("class:text", "\n") - ]), style = lamb_engine.utils.style) - continue - except lamb_engine.nodes.ReductionError as e: - printf(FormattedText([ - ("class:err", f"{e.msg}\n") - ]), style = lamb_engine.utils.style) - continue + # Try to run an input line. + # Catch parse errors and point them out. + try: + x = r.run(i) + except ppx.ParseException as e: + l = len(to_plain_text(r.prompt_session.message)) + printf(FormattedText([ + ("class:err", " "*(e.loc + l) + "^\n"), + ("class:err", f"Syntax error at char {e.loc}."), + ("class:text", "\n") + ]), style = lamb_engine.utils.style) + continue + except lamb_engine.nodes.ReductionError as e: + printf(FormattedText([ + ("class:err", f"{e.msg}\n") + ]), style = lamb_engine.utils.style) + continue - printf("") + printf("") + +if __name__ == "__main__": + main() diff --git a/lamb_engine/utils.py b/lamb_engine/utils.py index 5647e7f..d797347 100644 --- a/lamb_engine/utils.py +++ b/lamb_engine/utils.py @@ -101,7 +101,7 @@ def show_greeting(): "", "<_h> | _.._ _.|_", " |_(_|| | ||_)", - f" <_v>{version('lamb')}", + f" <_v>{version('lamb_engine')}", " __ __", " ,-` `` `,", " (` <_l>\\ )", diff --git a/pyproject.toml b/pyproject.toml index 165c41f..1a6d33d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,30 +1,28 @@ +[build-system] +requires = [ "setuptools>=61.0" ] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +where = [ "." ] +include = ["lamb_engine*"] +namespaces = false + +[project.scripts] +lamb = "lamb_engine:main" + + + [project] -name = "Lamb" +name = "lamb_engine" description = "A lambda calculus engine" - -# We use the standard semantic versioning: -# maj.min.pat -# -# Major release: -# 1.0.0 is the first stable release. -# Incremented on BIG breaking changes. -# -# Minor release: -# Large bug fixes, new features -# -# Patch release: -# Small, compatible fixes. -version = "1.1.4" - +version = "1.1.5" dependencies = [ "prompt-toolkit==3.0.31", "pyparsing==3.0.9" ] - authors = [ { name="Mark", email="mark@betalupi.com" } ] - readme = "README.md" requires-python = ">=3.7" license = {text = "GNU General Public License v3 (GPLv3)"} @@ -35,16 +33,10 @@ classifiers = [ "Environment :: Console" ] - [project.urls] "Homepage" = "https://git.betalupi.com/Mark/lamb" - -[build-system] -requires = [ "setuptools>=61.0" ] -build-backend = "setuptools.build_meta" - -[tool.setuptools.packages.find] -where = ["lamb_engine"] -include = ["lamb_engine*"] -namespaces = false \ No newline at end of file +# To build: +# pip install build twine +# python -m build +# python -m twine upload dist/* \ No newline at end of file