This repository is a small Common Lisp system that provides a DSL and emitter for generating Python code from S-expressions. You describe Python programs as structured Lisp forms (often produced by macros), and the library emits syntactically-correct Python source (and also Jupyter notebooks).
emit-py: converts supported S-expression forms into Python text.write-source: writes generated Python to<name>.py(with a hash-table to avoid rewriting identical output).write-notebook: builds a.ipynbJSON file from(markdown ...)and(python ...)cells, then formats it viajq.
- Defines one ASDF system:
cl-py-generator - Depends on:
alexandria,jonathan,external-program - Components loaded in order (
:serial t):package.lisp,py.lisp, and conditionallypipe.lispon SBCL.
- Defines the
:cl-py-generatorpackage. - Exports:
- core API:
emit-py,write-source,write-notebook - the DSL “node names” that
emit-pyrecognizes: literals/containers (list,tuple,dict, ...), statements (def,class,if,for,while,with,try, ...), operators (:+,:==, ...), and helpers (dot,aref,slice,comments, ...).
- core API:
- Implements:
- Emitter:
emit-pyas a large dispatcher on the head symbol of each form. - Function parsing / typing:
consume-declare+parse-defunread leading(declare ...)forms and emit Python type annotations when available. - File output:
write-sourceemits code and writes only if output content has changed since last write. - Notebook output:
write-notebookbuilds notebook JSON (jonathan:to-json) and pretty-prints it withjq.
- Emitter:
- Starts a background
python3process and streams output. - Provides
runto send generated code (viaemit-py) into the running Python process.
- Documentation generated from test cases, showing:
- the input S-expression
- the expected generated Python (after formatting)
- Functions as both user reference and regression spec.
- Defines a table-driven test suite (
*test-cases*). - Normalizes expected/actual code using
ruff formatbefore comparison. - Optionally performs execution tests by running the generated Python with
python3. - Can generate
SUPPORTED_FORMS.mdviagenerate-documentation.
emit-pyis effectively a pretty-printer: it pattern-matches on known DSL heads (e.g.if,for,dict,dot) and emits Python syntax withformat.- Block forms emit a header (
...:) and then indent the body via(do ...)/(indent ...). defroutes throughparse-defunto handle lambda-lists and optional type annotations derived from(declare ...).
Add git ls-files output (or a top-level find . -maxdepth 2 -type f) and I’ll summarize the directory layout and how examples/tests are organized across the repo.