Skip to content

Commit c2ba2c3

Browse files
Technologicatclaude
andcommitted
bf: document StepExpansion + viewing the compiled Python; require mcpyrate >= 4.1.1
Two intertwined changes: - Reorganize the bf-dialect doc with a "Reading the compiled Python" section that frames bf as a transpiler (pedagogic value lives in the output text) and documents two ways to actually see the compiled Python: programmatically via bf.compile, and live via mcpyrate.debug StepExpansion. The second method goes through the import machinery, which on first import requires path_stats to handle source-level dialect files — fixed in mcpyrate 4.1.1. - Bump unpythonic's mcpyrate dependency floor from >=4.1.0 to >=4.1.1 to make the StepExpansion path actually work (and to keep the bf docstring's "running the file under macropython" claim honest, which was technically broken until the mcpyrate hotfix even though we hadn't noticed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e500c7b commit c2ba2c3

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

doc/dialects/bf.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
- [BF: the classical human-incomprehensible automaton](#bf-the-classical-human-incomprehensible-automaton)
2323
- [Features](#features)
24+
- [Reading the compiled Python](#reading-the-compiled-python)
2425
- [What BF is](#what-bf-is)
2526
- [Comboability](#comboability)
2627
- [CAUTION](#caution)
@@ -56,16 +57,22 @@ from unpythonic.dialects.bf import dialects, BF # noqa: F401
5657
- A leading `# ` in the BF source is passed through cleanly, so both `# real comment` and bare `real comment` come out as `# real comment` in the compiled Python.
5758
- **`reset`**: a line whose stripped content is exactly `reset` compiles to `tape.clear(); ptr = 0`. This lets several BF programs share one file.
5859

59-
The same compiler is available as a plain function:
60+
## Reading the compiled Python
61+
62+
BF is a *transpiler*: it takes a BF program and emits human-readable Python that does the same thing. The compiled output is intentionally legible — `+++` becomes `tape[ptr] += 3`, `[…]` becomes `while tape[ptr]: …`, comments are preserved as Python comments — so reading the Python is a perfectly good way to understand a non-trivial BF program. The pedagogic value of the dialect lives in the output text, not in any stored knowledge of the input.
63+
64+
Two ways to actually see the compiled Python:
65+
66+
**1. Programmatically, via `bf.compile`.** Useful for offline inspection, ad-hoc experiments, and printing the compiled form into a notebook or a paper:
6067

6168
```python
6269
from unpythonic.dialects import bf
63-
print(bf.compile(bf_program_str))
64-
```
6570

66-
`bf.compile(src)` returns self-contained runnable Python — useful for reading a non-trivial BF program by rewriting it in a language a human can actually read. The qualified `bf.compile` form is recommended over `from … import compile` to avoid shadowing `builtins.compile` in the importer's namespace.
71+
src = "+++++++++++++[>+++++<-]>." # 'A' via a 5×13 multiplication loop
72+
print(bf.compile(src))
73+
```
6774

68-
For example, the program above compiles to:
75+
For the program above, this prints:
6976

7077
```python
7178
from sys import stdin, stdout
@@ -83,6 +90,21 @@ ptr += 1
8390
stdout.write(chr(tape[ptr])); stdout.flush()
8491
```
8592

93+
The qualified `bf.compile` form is recommended over `from … import compile` to avoid shadowing `builtins.compile` in the importer's namespace.
94+
95+
**2. Live, while running the dialect file, via `mcpyrate.debug.StepExpansion`.** When `StepExpansion` is the *first* dialect in the import chain, the dialect expander prints the source after each transformer pass — so for a BF file it shows the BF body before transformation and the generated Python afterward, then runs the result:
96+
97+
```python
98+
from mcpyrate.debug import dialects, StepExpansion
99+
from unpythonic.dialects.bf import dialects, BF
100+
101+
+++++++++++++[>+++++<-]>.
102+
```
103+
104+
Run via `macropython` (or by `import`-ing the file) and the BF→Python translation is printed to stderr alongside the program's normal execution. Useful when the BF source already lives inside a `.py` file and you'd rather not retype it as a string for `bf.compile`.
105+
106+
`StepExpansion` is documented in [`mcpyrate`'s troubleshooting guide](https://github.com/Technologicat/mcpyrate/blob/master/doc/troubleshooting.md). It works for any dialect, not just BF.
107+
86108
## What BF is
87109

88110
BF is a dialect ~of Python~ implemented as a whole-module *source-to-source* transform. The dialect definition lives in [`unpythonic.dialects.bf`](../../unpythonic/dialects/bf.py). Usage examples can be found in [the unit tests](../../unpythonic/dialects/tests/test_bf.py).

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ license = { text = "BSD" }
1919
dynamic = ["version"]
2020

2121
dependencies = [
22-
"mcpyrate>=4.1.0",
22+
"mcpyrate>=4.1.1",
2323
"sympy>=1.13"
2424
]
2525
keywords=["functional-programming", "language-extension", "syntactic-macros",

0 commit comments

Comments
 (0)