lispython 0.3.3__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lispython-0.3.3 → lispython-0.4.1}/.gitignore +12 -1
- lispython-0.4.1/.vscode/settings.json +3 -0
- lispython-0.4.1/PKG-INFO +111 -0
- lispython-0.4.1/README.md +89 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/macros.md +39 -1
- lispython-0.4.1/docs/usage/getting-started.md +20 -0
- {lispython-0.3.3 → lispython-0.4.1}/pyproject.toml +3 -2
- lispython-0.4.1/src/lispy/core/builtins.py +19 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/meta_functions.py +1 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core_meta_functions.lpy +2 -1
- lispython-0.4.1/src/lispy/lsp/__init__.py +6 -0
- lispython-0.4.1/src/lispy/lsp/__main__.py +3 -0
- lispython-0.4.1/src/lispy/lsp/server.lpy +765 -0
- lispython-0.4.1/tests/test_gensym.py +78 -0
- {lispython-0.3.3 → lispython-0.4.1}/uv.lock +63 -1
- lispython-0.3.3/PKG-INFO +0 -78
- lispython-0.3.3/README.md +0 -57
- lispython-0.3.3/docs/usage/getting-started.md +0 -20
- {lispython-0.3.3 → lispython-0.4.1}/.claude/settings.local.json +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/.pre-commit-config.yaml +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/LICENSE.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/index.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/syntax/expressions.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/syntax/overview.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/syntax/statements.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/usage/cli.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/version_macro.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/docs/why-lispy.md +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/mkdocs.yml +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/__init__.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/compiler/__init__.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/compiler/expr.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/compiler/literal.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/compiler/stmt.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/compiler/utils.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/importer.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/macro.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/nodes.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/parser.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/core/utils.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/macros/__init__.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/macros/init.lpy +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/macros/sugar.lpy +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/src/lispy/tools.lpy +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/__init__.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/test_expr.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/test_include_meta.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/test_literal.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/test_meta_functions.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/test_parser.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/test_stmt.py +0 -0
- {lispython-0.3.3 → lispython-0.4.1}/tests/utils.py +0 -0
|
@@ -321,4 +321,15 @@ tags
|
|
|
321
321
|
|
|
322
322
|
poetry.lock
|
|
323
323
|
**test.hy
|
|
324
|
-
**temp*
|
|
324
|
+
**temp*
|
|
325
|
+
|
|
326
|
+
# AI agent instructions (per-user, not committed)
|
|
327
|
+
AGENTS.md
|
|
328
|
+
CLAUDE.md
|
|
329
|
+
GEMINI.md
|
|
330
|
+
|
|
331
|
+
# Git worktrees
|
|
332
|
+
.worktrees/
|
|
333
|
+
|
|
334
|
+
# Agent-generated docs (not mkdocs content)
|
|
335
|
+
docs/superpowers/
|
lispython-0.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lispython
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Lisp-like Syntax for Python with Lisp-like Macros
|
|
5
|
+
Project-URL: Homepage, https://jetack.github.io/lispython
|
|
6
|
+
Project-URL: Repository, https://github.com/jetack/lispython
|
|
7
|
+
Author-email: Jetack <jetack23@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE.md
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Requires-Dist: pygls>=1.0.0
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pre-commit>=3.6.0; extra == 'dev'
|
|
14
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
15
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
16
|
+
Requires-Dist: toml>=0.10.2; extra == 'dev'
|
|
17
|
+
Provides-Extra: docs
|
|
18
|
+
Requires-Dist: mike>=2.1.3; extra == 'docs'
|
|
19
|
+
Requires-Dist: mkdocs-macros-plugin>=1.3.7; extra == 'docs'
|
|
20
|
+
Requires-Dist: mkdocs-material>=9.6.14; extra == 'docs'
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# LisPython
|
|
24
|
+
[](https://badge.fury.io/py/lispython)
|
|
25
|
+
|
|
26
|
+
LisPython is a Lisp-flavored syntax for Python with Lisp-style macros. Source files (`.lpy`) are transpiled to Python and executed on the standard CPython runtime.
|
|
27
|
+
|
|
28
|
+
## Documentation
|
|
29
|
+
Full documentation lives at [https://jetack.github.io/lispython/](https://jetack.github.io/lispython/).
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
```lisp
|
|
33
|
+
(import math)
|
|
34
|
+
|
|
35
|
+
(def area [r]
|
|
36
|
+
(return (* math.pi (** r 2))))
|
|
37
|
+
|
|
38
|
+
(print (area 3))
|
|
39
|
+
```
|
|
40
|
+
```bash
|
|
41
|
+
lpy example.lpy
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
### Using pip
|
|
46
|
+
```bash
|
|
47
|
+
pip install lispython
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Manual Installation (for development)
|
|
51
|
+
```bash
|
|
52
|
+
uv sync # install dependencies
|
|
53
|
+
uv pip install -e . # for development
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## How to Run LisPython code
|
|
57
|
+
### Run from source
|
|
58
|
+
```bash
|
|
59
|
+
lpy {filename}.lpy
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Run REPL
|
|
63
|
+
```bash
|
|
64
|
+
lpy
|
|
65
|
+
# or
|
|
66
|
+
lpy -t # if you want to print python translation.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Show translation
|
|
70
|
+
```bash
|
|
71
|
+
l2py {filename}.lpy
|
|
72
|
+
```
|
|
73
|
+
Prints the translated Python to stdout. It does not execute the code.
|
|
74
|
+
|
|
75
|
+
### Run Tests
|
|
76
|
+
```bash
|
|
77
|
+
# in project root directory
|
|
78
|
+
pytest
|
|
79
|
+
# or
|
|
80
|
+
lpy -m pytest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## LSP Server
|
|
84
|
+
LisPython ships with a language server (`lpy-lsp`) that speaks LSP over stdio. It provides:
|
|
85
|
+
|
|
86
|
+
- Diagnostics (parse / compile errors)
|
|
87
|
+
- Hover documentation for special forms
|
|
88
|
+
- Document symbols
|
|
89
|
+
- Go-to-definition, including across `.lpy` files in the workspace
|
|
90
|
+
|
|
91
|
+
### Editor setup
|
|
92
|
+
Point your editor's LSP client at the `lpy-lsp` command for files with the `.lpy` extension. The server speaks LSP over stdio.
|
|
93
|
+
|
|
94
|
+
#### VSCode
|
|
95
|
+
Install the [LisPython](https://marketplace.visualstudio.com/items?itemName=jetack.vscode-lispython) extension from the VSCode Marketplace.
|
|
96
|
+
|
|
97
|
+
#### Emacs
|
|
98
|
+
Use [`lpy-mode`](https://github.com/jetack/lpy-mode) for syntax highlighting and LSP integration. For completion, install [`lpy-autocomplete`](https://github.com/jetack/lpy-autocomplete).
|
|
99
|
+
|
|
100
|
+
## Todo
|
|
101
|
+
### Environment
|
|
102
|
+
- [ ] Test on more python versions
|
|
103
|
+
- [ ] REPL should track history and arrow key navigation
|
|
104
|
+
- [ ] REPL multi-line input support
|
|
105
|
+
- [ ] Better compilation error messages
|
|
106
|
+
### Macro System
|
|
107
|
+
- [ ] `as->` macro for syntactic sugar
|
|
108
|
+
- [ ] `gensym` for avoiding name collision
|
|
109
|
+
### Python AST
|
|
110
|
+
- [ ] `type_comment` never considered. Later, it should be covered
|
|
111
|
+
- [ ] Any missing AST nodes in the version 3.12+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# LisPython
|
|
2
|
+
[](https://badge.fury.io/py/lispython)
|
|
3
|
+
|
|
4
|
+
LisPython is a Lisp-flavored syntax for Python with Lisp-style macros. Source files (`.lpy`) are transpiled to Python and executed on the standard CPython runtime.
|
|
5
|
+
|
|
6
|
+
## Documentation
|
|
7
|
+
Full documentation lives at [https://jetack.github.io/lispython/](https://jetack.github.io/lispython/).
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
```lisp
|
|
11
|
+
(import math)
|
|
12
|
+
|
|
13
|
+
(def area [r]
|
|
14
|
+
(return (* math.pi (** r 2))))
|
|
15
|
+
|
|
16
|
+
(print (area 3))
|
|
17
|
+
```
|
|
18
|
+
```bash
|
|
19
|
+
lpy example.lpy
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
### Using pip
|
|
24
|
+
```bash
|
|
25
|
+
pip install lispython
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Manual Installation (for development)
|
|
29
|
+
```bash
|
|
30
|
+
uv sync # install dependencies
|
|
31
|
+
uv pip install -e . # for development
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## How to Run LisPython code
|
|
35
|
+
### Run from source
|
|
36
|
+
```bash
|
|
37
|
+
lpy {filename}.lpy
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Run REPL
|
|
41
|
+
```bash
|
|
42
|
+
lpy
|
|
43
|
+
# or
|
|
44
|
+
lpy -t # if you want to print python translation.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Show translation
|
|
48
|
+
```bash
|
|
49
|
+
l2py {filename}.lpy
|
|
50
|
+
```
|
|
51
|
+
Prints the translated Python to stdout. It does not execute the code.
|
|
52
|
+
|
|
53
|
+
### Run Tests
|
|
54
|
+
```bash
|
|
55
|
+
# in project root directory
|
|
56
|
+
pytest
|
|
57
|
+
# or
|
|
58
|
+
lpy -m pytest
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## LSP Server
|
|
62
|
+
LisPython ships with a language server (`lpy-lsp`) that speaks LSP over stdio. It provides:
|
|
63
|
+
|
|
64
|
+
- Diagnostics (parse / compile errors)
|
|
65
|
+
- Hover documentation for special forms
|
|
66
|
+
- Document symbols
|
|
67
|
+
- Go-to-definition, including across `.lpy` files in the workspace
|
|
68
|
+
|
|
69
|
+
### Editor setup
|
|
70
|
+
Point your editor's LSP client at the `lpy-lsp` command for files with the `.lpy` extension. The server speaks LSP over stdio.
|
|
71
|
+
|
|
72
|
+
#### VSCode
|
|
73
|
+
Install the [LisPython](https://marketplace.visualstudio.com/items?itemName=jetack.vscode-lispython) extension from the VSCode Marketplace.
|
|
74
|
+
|
|
75
|
+
#### Emacs
|
|
76
|
+
Use [`lpy-mode`](https://github.com/jetack/lpy-mode) for syntax highlighting and LSP integration. For completion, install [`lpy-autocomplete`](https://github.com/jetack/lpy-autocomplete).
|
|
77
|
+
|
|
78
|
+
## Todo
|
|
79
|
+
### Environment
|
|
80
|
+
- [ ] Test on more python versions
|
|
81
|
+
- [ ] REPL should track history and arrow key navigation
|
|
82
|
+
- [ ] REPL multi-line input support
|
|
83
|
+
- [ ] Better compilation error messages
|
|
84
|
+
### Macro System
|
|
85
|
+
- [ ] `as->` macro for syntactic sugar
|
|
86
|
+
- [ ] `gensym` for avoiding name collision
|
|
87
|
+
### Python AST
|
|
88
|
+
- [ ] `type_comment` never considered. Later, it should be covered
|
|
89
|
+
- [ ] Any missing AST nodes in the version 3.12+
|
|
@@ -54,4 +54,42 @@ Just change `def` in function definition to `defmacro`. And macros usually retur
|
|
|
54
54
|
(return `(-> ~f ~@rest)))
|
|
55
55
|
(return `(-> (~f ~x) ~@rest))))
|
|
56
56
|
```
|
|
57
|
-
You can find more in `src/lispython/macros/sugar.lpy`.
|
|
57
|
+
You can find more in `src/lispython/macros/sugar.lpy`.
|
|
58
|
+
|
|
59
|
+
## gensym
|
|
60
|
+
`gensym` generates unique symbols to avoid variable name collisions in macros. It is automatically available inside `defmacro` bodies.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
(gensym) ;; => Symbol("__gensym_0")
|
|
64
|
+
(gensym "tmp") ;; => Symbol("__tmp_1")
|
|
65
|
+
(gensym 'tmp) ;; => Symbol("__tmp_2") (also accepts a quoted Symbol)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The prefix can be a string or a symbol. Each call increments a global counter, so every generated symbol is unique.
|
|
69
|
+
|
|
70
|
+
### Why gensym?
|
|
71
|
+
Without `gensym`, a macro that introduces a local variable can accidentally shadow a variable in the caller's scope:
|
|
72
|
+
```python
|
|
73
|
+
;; BAD: if the caller has a variable named `tmp`, this breaks
|
|
74
|
+
(defmacro broken-swap [a b]
|
|
75
|
+
(return `(do (= tmp ~a)
|
|
76
|
+
(= ~a ~b)
|
|
77
|
+
(= ~b tmp))))
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Using `gensym` prevents this:
|
|
81
|
+
```python
|
|
82
|
+
(defmacro swap [a b]
|
|
83
|
+
(= tmp (gensym "tmp"))
|
|
84
|
+
(return `(do (= ~tmp ~a)
|
|
85
|
+
(= ~a ~b)
|
|
86
|
+
(= ~b ~tmp))))
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Now `(swap x y)` expands to something like:
|
|
90
|
+
```python
|
|
91
|
+
__tmp_0 = x
|
|
92
|
+
x = y
|
|
93
|
+
y = __tmp_0
|
|
94
|
+
```
|
|
95
|
+
The generated name `__tmp_0` won't collide with user variables.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
## Simple Web REPL
|
|
3
|
+
You can try LisPy without installing at
|
|
4
|
+
[https://jetack.github.io/lispy-web/](https://jetack.github.io/lispy-web/).
|
|
5
|
+
## Installation
|
|
6
|
+
### Using pip
|
|
7
|
+
```bash
|
|
8
|
+
pip install lispython
|
|
9
|
+
```
|
|
10
|
+
### Manual Installation (for development)
|
|
11
|
+
```bash
|
|
12
|
+
uv sync # install dependencies
|
|
13
|
+
uv pip install -e . # for development
|
|
14
|
+
```
|
|
15
|
+
#### uv
|
|
16
|
+
I recommend using [uv](https://docs.astral.sh/uv/) for development.
|
|
17
|
+
It manages the virtual environment and dependencies from `pyproject.toml` / `uv.lock` automatically.
|
|
18
|
+
```bash
|
|
19
|
+
uv run lpy # run commands inside the project environment
|
|
20
|
+
```
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lispython"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
description = "Lisp-like Syntax for Python with Lisp-like Macros"
|
|
5
5
|
authors = [{ name = "Jetack", email = "jetack23@gmail.com" }]
|
|
6
6
|
license = { text = "MIT" }
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
requires-python = ">=3.11"
|
|
9
|
-
dependencies = []
|
|
9
|
+
dependencies = ["pygls>=1.0.0"]
|
|
10
10
|
|
|
11
11
|
[project.urls]
|
|
12
12
|
Homepage = "https://jetack.github.io/lispython"
|
|
@@ -15,6 +15,7 @@ Repository = "https://github.com/jetack/lispython"
|
|
|
15
15
|
[project.scripts]
|
|
16
16
|
lpy = "lispy:run"
|
|
17
17
|
l2py = "lispy:l2py"
|
|
18
|
+
lpy-lsp = "lispy.lsp:main"
|
|
18
19
|
test = "pytest:main"
|
|
19
20
|
|
|
20
21
|
[project.optional-dependencies]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from lispy.core.nodes import Symbol
|
|
2
|
+
|
|
3
|
+
_gensym_counter = 0
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def gensym(prefix="gensym"):
|
|
7
|
+
global _gensym_counter
|
|
8
|
+
if isinstance(prefix, Symbol):
|
|
9
|
+
prefix = prefix.name
|
|
10
|
+
elif not isinstance(prefix, str):
|
|
11
|
+
raise TypeError(f"gensym prefix must be a Symbol or string, got {type(prefix).__name__}")
|
|
12
|
+
sym = Symbol("__" + prefix + "_" + str(_gensym_counter))
|
|
13
|
+
_gensym_counter += 1
|
|
14
|
+
return sym
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def reset_gensym_counter():
|
|
18
|
+
global _gensym_counter
|
|
19
|
+
_gensym_counter = 0
|
|
@@ -9,6 +9,7 @@ def defmacro_transform(sexp):
|
|
|
9
9
|
return Paren(
|
|
10
10
|
Symbol("do"),
|
|
11
11
|
Paren(Symbol("from"), Symbol("lispy.core.nodes"), Symbol("*")),
|
|
12
|
+
Paren(Symbol("from"), Symbol("lispy.core.builtins"), Symbol("*")),
|
|
12
13
|
Paren(Symbol("def"), newname, *body),
|
|
13
14
|
Paren(
|
|
14
15
|
Symbol("="),
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
(from lispy.core.nodes *)
|
|
7
7
|
|
|
8
8
|
(def defmacro-transform [sexp]
|
|
9
|
-
(= [op macroname *body] sexp.list)
|
|
9
|
+
(= [op macroname *body] sexp.list)
|
|
10
10
|
(= macroname (str macroname))
|
|
11
11
|
(= newname (Symbol (+ "___defmacro_temp___" macroname)))
|
|
12
12
|
(return `(do (from lispy.core.nodes *)
|
|
13
|
+
(from lispy.core.builtins *)
|
|
13
14
|
(def ~newname ~@body)
|
|
14
15
|
(= (sub (.setdefault (globals) "__macro_namespace" {})
|
|
15
16
|
~macroname)
|