diff --git a/README.md b/README.md index 0fc13c0..08394fe 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,95 @@ # Lamb: A Lambda Calculus Engine +![Lamb screenshot](./misc/screenshot.png) + +## Installation + +### Method 1: PyPi (not yet) +1. Put this on PyPi +2. Write these instructions + +### 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 .`` + +------------------------------------------------- + +## Usage + +Type lambda expressions into the prompt, and Lamb will evaluate them. \ +Use your `\` (backslash) key to type a `λ`. \ +To define macros, use `=`. For example, +``` +~~> T = λab.a +~~> F = λab.a +~~> NOT = λa.a F T +``` + +Note that there are spaces in `λa.a F T`. With no spaces, `aFT` will be parsed as one variable. \ +Lambda functions can only take single-letter, lowercase arguments. `λA.A` is not valid syntax. \ +Unbound variables (upper and lower case) that aren't macros will become free variables. + +Be careful, macros are case-sensitive. If you define a macro `MAC` and accidentally write `mac` in the prompt, `mac` will become a free variable. + +Numbers will automatically be converted to Church numerals. For example, the following line will reduce to `T`. +``` +~~> 3 NOT F +``` + +If an expression takes too long to evaluate, you may interrupt reduction with `Ctrl-C`. + +------------------------------------------------- + +## Commands + +Lamb comes with a few commands. Prefix them with a `:` + +`:help` Prints a help message + +`:clear` Clear the screen + +`:rlimit [int | None]` Set maximum reduction limit. `:rlimit none` sets no limit. + +`:macros` List macros in the current environment. + +`:mdel [macro]` Delete a macro + +`:save [filename]`\ +`:load [filename]` Save or load the current environment to a file. The lines in a file look exactly the same as regular entries in the prompt, but must only contain macro definitions. + +------------------------------------------------- + +## Internals + +Lamb treats each λ expression as a binary tree. Variable binding and reduction are all simple operations on that tree. All the magic happens inside [`nodes.py`](./lamb/nodes.py). + +**Highlights:** + - `TreeWalker` is the iterator we (usually) use to traverse our tree. It walks the "perimeter" of the tree, visiting some nodes multiple times. + - `Node` is the base class for all nodes. Any node has `.left` and `.right` elements, which may be `None` (empty). `Node`s also reference their parent and their direction relative to their parent, to make tree traversal easy. + - Before any reduction is done, variables are bound via `bind_variables`. This prevents accidental conflicts common in many lambda parsers. + +------------------------------------------------- + ## Todo (pre-release): - - $\alpha$-equivalence check - - Prettyprint functions (rename bound variables) - - Write a nice README - - Fix colors - - Print macro content if only a macro is typed + - Make command output accessible in prompt + - Prettyprint functions and rename bound variables + - Prettier colors + - Prevent macro-chaining recursion + - step-by-step reduction + - Show a warning when a free variable is created + - PyPi package + ## Todo: - - History accessible in prompt - - Command and macro autocomplete - - step-by-step reduction - - Syntax highlighting: parenthesis, bound variables, macros, etc - - PyPi package + - Command-line options (load a file, run a set of commands) + - $\alpha$-equivalence check + - Unchurch macro: make church numerals human-readable + - Full-reduce option (expand all macros) + - Print macro content if only a macro is typed - Smart alignment in all printouts - - Full-reduce option - - Free variable warning + - Syntax highlighting: parenthesis, bound variables, macros, etc -## Mention in Docs - - lambda functions only work with single-letter arguments - - church numerals - - how to install \ No newline at end of file diff --git a/misc/screenshot.png b/misc/screenshot.png new file mode 100644 index 0000000..5439d02 Binary files /dev/null and b/misc/screenshot.png differ diff --git a/pyproject.toml b/pyproject.toml index 43e9cb6..5a4af68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,21 @@ [project] name = "Lamb" description = "A lambda calculus engine" -version = "0.0.0" + +# 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 = "0.1.0" + dependencies = [ "prompt-toolkit==3.0.31", "pyparsing==3.0.9"