lispython 0.4.5__tar.gz → 0.4.7__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.4.5 → lispython-0.4.7}/.gitignore +3 -1
- {lispython-0.4.5 → lispython-0.4.7}/PKG-INFO +22 -11
- {lispython-0.4.5 → lispython-0.4.7}/README.md +21 -10
- {lispython-0.4.5 → lispython-0.4.7}/docs/syntax/expressions.md +2 -2
- lispython-0.4.7/docs/usage/cli.md +41 -0
- {lispython-0.4.5 → lispython-0.4.7}/mkdocs.yml +1 -1
- {lispython-0.4.5 → lispython-0.4.7}/pyproject.toml +1 -1
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/compiler/expr.py +2 -1
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/macro.py +13 -8
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/nodes.py +1 -1
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/lsp/server.lpy +79 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/macros/sugar.lpy +2 -2
- lispython-0.4.7/src/lispy/tools.lpy +726 -0
- {lispython-0.4.5 → lispython-0.4.7}/uv.lock +1 -1
- lispython-0.4.5/.claude/settings.local.json +0 -11
- lispython-0.4.5/docs/usage/cli.md +0 -22
- lispython-0.4.5/src/lispy/tools.lpy +0 -289
- {lispython-0.4.5 → lispython-0.4.7}/.pre-commit-config.yaml +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/.vscode/settings.json +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/LICENSE.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/index.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/macros.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/syntax/overview.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/syntax/statements.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/usage/getting-started.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/version_macro.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/docs/why-lispy.md +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/__init__.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/builtins.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/compiler/__init__.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/compiler/literal.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/compiler/stmt.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/compiler/utils.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/importer.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/meta_functions.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/parser.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core/utils.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/core_meta_functions.lpy +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/lsp/__init__.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/lsp/__main__.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/macros/__init__.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/src/lispy/macros/init.lpy +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/__init__.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_as_thread.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_expr.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_gensym.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_include_meta.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_literal.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_literal_unwrap.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_meta_functions.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_parser.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/test_stmt.py +0 -0
- {lispython-0.4.5 → lispython-0.4.7}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lispython
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
4
4
|
Summary: Lisp-like Syntax for Python with Lisp-like Macros
|
|
5
5
|
Project-URL: Homepage, https://jetack.github.io/lispython
|
|
6
6
|
Project-URL: Repository, https://github.com/jetack/lispython
|
|
@@ -85,25 +85,36 @@ lpy -m pytest
|
|
|
85
85
|
LisPython ships with a language server (`lpy-lsp`) that speaks LSP over stdio. It provides:
|
|
86
86
|
|
|
87
87
|
- Diagnostics (parse / compile errors)
|
|
88
|
-
-
|
|
88
|
+
- Completions (special forms, builtins, file/workspace symbols)
|
|
89
|
+
- Hover documentation for special forms and builtins
|
|
89
90
|
- Document symbols
|
|
90
91
|
- Go-to-definition, including across `.lpy` files in the workspace
|
|
91
92
|
|
|
93
|
+
## nREPL Server
|
|
94
|
+
LisPython includes an nREPL server for REPL-driven development:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
lpy --nrepl # start on a random port
|
|
98
|
+
lpy --nrepl 7888 # start on a specific port
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The server accepts newline-delimited JSON over TCP and supports:
|
|
102
|
+
- `eval` — evaluate LisPython code, return value/stdout/error
|
|
103
|
+
- `load-file` — load a `.lpy` file into the session
|
|
104
|
+
- `macroexpand` — expand macros and return the result
|
|
105
|
+
- `complete` — prefix and dot-completion from the live scope
|
|
106
|
+
- `docs` — signature and docstring for a symbol
|
|
107
|
+
- `annotate` — type tag (function/class/module/macro)
|
|
108
|
+
|
|
92
109
|
### Editor setup
|
|
93
|
-
Point your editor's LSP client at the `lpy-lsp` command for files with the `.lpy` extension. The server speaks LSP over stdio.
|
|
94
110
|
|
|
95
|
-
####
|
|
96
|
-
Install the [LisPython](https://marketplace.visualstudio.com/items?itemName=jetack.vscode-lispython) extension
|
|
111
|
+
#### VS Code
|
|
112
|
+
Install the [LisPython](https://marketplace.visualstudio.com/items?itemName=jetack.vscode-lispython) extension. It connects to both LSP and nREPL automatically.
|
|
97
113
|
|
|
98
114
|
#### Emacs
|
|
99
|
-
Use [`lpy-mode`](https://github.com/jetack/lpy-mode)
|
|
115
|
+
Use [`lpy-mode`](https://github.com/jetack/lpy-mode). It provides nREPL integration (eval, completion, eldoc, macroexpand) and LSP via eglot.
|
|
100
116
|
|
|
101
117
|
## Todo
|
|
102
|
-
### Environment
|
|
103
|
-
- [ ] Test on more python versions
|
|
104
|
-
- [ ] REPL should track history and arrow key navigation
|
|
105
|
-
- [ ] REPL multi-line input support
|
|
106
|
-
- [ ] Better compilation error messages
|
|
107
118
|
### Python AST
|
|
108
119
|
- [ ] `type_comment` never considered. Later, it should be covered
|
|
109
120
|
- [ ] Any missing AST nodes in the version 3.12+
|
|
@@ -62,25 +62,36 @@ lpy -m pytest
|
|
|
62
62
|
LisPython ships with a language server (`lpy-lsp`) that speaks LSP over stdio. It provides:
|
|
63
63
|
|
|
64
64
|
- Diagnostics (parse / compile errors)
|
|
65
|
-
-
|
|
65
|
+
- Completions (special forms, builtins, file/workspace symbols)
|
|
66
|
+
- Hover documentation for special forms and builtins
|
|
66
67
|
- Document symbols
|
|
67
68
|
- Go-to-definition, including across `.lpy` files in the workspace
|
|
68
69
|
|
|
70
|
+
## nREPL Server
|
|
71
|
+
LisPython includes an nREPL server for REPL-driven development:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
lpy --nrepl # start on a random port
|
|
75
|
+
lpy --nrepl 7888 # start on a specific port
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The server accepts newline-delimited JSON over TCP and supports:
|
|
79
|
+
- `eval` — evaluate LisPython code, return value/stdout/error
|
|
80
|
+
- `load-file` — load a `.lpy` file into the session
|
|
81
|
+
- `macroexpand` — expand macros and return the result
|
|
82
|
+
- `complete` — prefix and dot-completion from the live scope
|
|
83
|
+
- `docs` — signature and docstring for a symbol
|
|
84
|
+
- `annotate` — type tag (function/class/module/macro)
|
|
85
|
+
|
|
69
86
|
### 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
87
|
|
|
72
|
-
####
|
|
73
|
-
Install the [LisPython](https://marketplace.visualstudio.com/items?itemName=jetack.vscode-lispython) extension
|
|
88
|
+
#### VS Code
|
|
89
|
+
Install the [LisPython](https://marketplace.visualstudio.com/items?itemName=jetack.vscode-lispython) extension. It connects to both LSP and nREPL automatically.
|
|
74
90
|
|
|
75
91
|
#### Emacs
|
|
76
|
-
Use [`lpy-mode`](https://github.com/jetack/lpy-mode)
|
|
92
|
+
Use [`lpy-mode`](https://github.com/jetack/lpy-mode). It provides nREPL integration (eval, completion, eldoc, macroexpand) and LSP via eglot.
|
|
77
93
|
|
|
78
94
|
## 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
95
|
### Python AST
|
|
85
96
|
- [ ] `type_comment` never considered. Later, it should be covered
|
|
86
97
|
- [ ] Any missing AST nodes in the version 3.12+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## REPL
|
|
2
|
+
```shell
|
|
3
|
+
lpy
|
|
4
|
+
#or
|
|
5
|
+
lpy -t #if you want to print python translation.
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
The REPL features Emacs-style keybindings (C-a, C-e, C-b, C-f, M-b, M-f, etc.), arrow key navigation, and persistent command history saved to `~/.lpy_history`.
|
|
9
|
+
|
|
10
|
+
### Auto-closing pairs
|
|
11
|
+
|
|
12
|
+
The REPL automatically inserts closing brackets and quotes when you type an opening one:
|
|
13
|
+
|
|
14
|
+
| You type | REPL inserts | Cursor position |
|
|
15
|
+
|----------|-------------|-----------------|
|
|
16
|
+
| `(` | `()` | between `(` and `)` |
|
|
17
|
+
| `[` | `[]` | between `[` and `]` |
|
|
18
|
+
| `{` | `{}` | between `{` and `}` |
|
|
19
|
+
| `'` | `''` | between the quotes |
|
|
20
|
+
| `"` | `""` | between the quotes |
|
|
21
|
+
|
|
22
|
+
- Typing a closing character (`)`, `]`, `}`) when the cursor is already before one will skip over it instead of inserting a duplicate.
|
|
23
|
+
- Typing a quote (`'`, `"`) when the cursor is before the same quote will skip over it.
|
|
24
|
+
- Pressing backspace between an empty pair deletes both characters.
|
|
25
|
+
|
|
26
|
+
## Run from source
|
|
27
|
+
```shell
|
|
28
|
+
lpy {filename}.lpy
|
|
29
|
+
```
|
|
30
|
+
## Run translation
|
|
31
|
+
```shell
|
|
32
|
+
l2py {filename}.lpy
|
|
33
|
+
```
|
|
34
|
+
It just displays translation. (don't run it)
|
|
35
|
+
## Run Tests (for development)
|
|
36
|
+
```shell
|
|
37
|
+
# in project root directory
|
|
38
|
+
pytest
|
|
39
|
+
#or
|
|
40
|
+
lpy -m pytest
|
|
41
|
+
```
|
|
@@ -107,7 +107,8 @@ def ifexp_p(sexp):
|
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
def ifexp_compile(sexp):
|
|
110
|
-
[_, test, body,
|
|
110
|
+
[_, test, body, *rest] = sexp.list
|
|
111
|
+
orelse = rest[0] if rest else Constant("None", **sexp.position_info)
|
|
111
112
|
return ast.IfExp(
|
|
112
113
|
test=expr_compile(test),
|
|
113
114
|
body=expr_compile(body),
|
|
@@ -40,14 +40,19 @@ def define_macro(sexp, scope, include_meta=True):
|
|
|
40
40
|
|
|
41
41
|
def require_macro(sexp, scope, include_meta=True):
|
|
42
42
|
transformed = require_transform(sexp)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
try:
|
|
44
|
+
eval(
|
|
45
|
+
compile(
|
|
46
|
+
ast.Interactive(body=macroexpand_then_compile([transformed], include_meta=include_meta)),
|
|
47
|
+
"macro-requiring",
|
|
48
|
+
"single",
|
|
49
|
+
),
|
|
50
|
+
scope,
|
|
51
|
+
)
|
|
52
|
+
except (ModuleNotFoundError, ImportError):
|
|
53
|
+
import sys
|
|
54
|
+
module_name = str(sexp.list[1])
|
|
55
|
+
print(f"l2py: warning: could not load macros from '{module_name}' (module not found)", file=sys.stderr)
|
|
51
56
|
return transformed if include_meta else None
|
|
52
57
|
|
|
53
58
|
|
|
@@ -751,6 +751,85 @@
|
|
|
751
751
|
:range (make-range lineno 0 lineno 0))])))))
|
|
752
752
|
(return None)))
|
|
753
753
|
|
|
754
|
+
;; ---------------------------------------------------------------------------
|
|
755
|
+
;; Completion
|
|
756
|
+
;; ---------------------------------------------------------------------------
|
|
757
|
+
|
|
758
|
+
(= _LPY-KEYWORDS
|
|
759
|
+
["defn" "cond" "conde" "ife" "when" "unless"
|
|
760
|
+
"do" "deco" "require" "fn" "match" "case"
|
|
761
|
+
"async-def" "async-for" "async-with"
|
|
762
|
+
"yield-from" "except*"
|
|
763
|
+
"->" "->>" "as->"
|
|
764
|
+
"gensym" "pprint"])
|
|
765
|
+
|
|
766
|
+
(deco (server.feature
|
|
767
|
+
lsp.TEXT_DOCUMENT_COMPLETION
|
|
768
|
+
(lsp.CompletionOptions :trigger-characters ["." "-"]))
|
|
769
|
+
(def completion [ls params]
|
|
770
|
+
(= doc (.get-text-document ls.workspace params.text_document.uri))
|
|
771
|
+
(= pos params.position)
|
|
772
|
+
(= items [])
|
|
773
|
+
(= seen (set))
|
|
774
|
+
|
|
775
|
+
;; 1. Special forms
|
|
776
|
+
(for name in SPECIAL-FORM-DOCS
|
|
777
|
+
(if (not (in name seen))
|
|
778
|
+
(do (seen.add name)
|
|
779
|
+
(items.append
|
|
780
|
+
(lsp.CompletionItem
|
|
781
|
+
:label name
|
|
782
|
+
:kind lsp.CompletionItemKind.Keyword
|
|
783
|
+
:detail "special form")))))
|
|
784
|
+
|
|
785
|
+
;; 2. LisPython-specific keywords
|
|
786
|
+
(for name in _LPY-KEYWORDS
|
|
787
|
+
(if (not (in name seen))
|
|
788
|
+
(do (seen.add name)
|
|
789
|
+
(items.append
|
|
790
|
+
(lsp.CompletionItem
|
|
791
|
+
:label name
|
|
792
|
+
:kind lsp.CompletionItemKind.Keyword
|
|
793
|
+
:detail "keyword")))))
|
|
794
|
+
|
|
795
|
+
;; 3. Python builtins
|
|
796
|
+
(for [name info] in (BUILTIN-INFO.items)
|
|
797
|
+
(if (not (in name seen))
|
|
798
|
+
(do (seen.add name)
|
|
799
|
+
(= kind (ife (isinstance (getattr builtins name None) type)
|
|
800
|
+
lsp.CompletionItemKind.Class
|
|
801
|
+
lsp.CompletionItemKind.Function))
|
|
802
|
+
(items.append
|
|
803
|
+
(lsp.CompletionItem
|
|
804
|
+
:label name
|
|
805
|
+
:kind kind
|
|
806
|
+
:detail (or (.get info "signature") ""))))))
|
|
807
|
+
|
|
808
|
+
;; 4. Symbols from current file
|
|
809
|
+
(try
|
|
810
|
+
(= tree (parse doc.source))
|
|
811
|
+
(= defs (collect-definitions tree doc.uri))
|
|
812
|
+
(for name in defs
|
|
813
|
+
(if (not (in name seen))
|
|
814
|
+
(do (seen.add name)
|
|
815
|
+
(items.append
|
|
816
|
+
(lsp.CompletionItem
|
|
817
|
+
:label name
|
|
818
|
+
:kind lsp.CompletionItemKind.Variable)))))
|
|
819
|
+
(except [Exception] (pass)))
|
|
820
|
+
|
|
821
|
+
;; 5. Workspace symbols
|
|
822
|
+
(for name in WORKSPACE-INDEX
|
|
823
|
+
(if (not (in name seen))
|
|
824
|
+
(do (seen.add name)
|
|
825
|
+
(items.append
|
|
826
|
+
(lsp.CompletionItem
|
|
827
|
+
:label name
|
|
828
|
+
:kind lsp.CompletionItemKind.Variable
|
|
829
|
+
:detail "workspace")))))
|
|
830
|
+
|
|
831
|
+
(return (lsp.CompletionList :is-incomplete False :items items))))
|
|
832
|
+
|
|
754
833
|
(deco (server.feature lsp.TEXT_DOCUMENT_REFERENCES)
|
|
755
834
|
(def references [ls params]
|
|
756
835
|
(= doc (.get-text-document ls.workspace params.text_document.uri))
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
(return `(if ~test ~then (cond ~@orelse))))))
|
|
6
6
|
|
|
7
7
|
(defmacro conde [*body]
|
|
8
|
-
(if (
|
|
9
|
-
(return
|
|
8
|
+
(if (<= (len body) 2)
|
|
9
|
+
(return (sub body -1))
|
|
10
10
|
(do (= [test then *orelse] body)
|
|
11
11
|
(return `(ife ~test ~then (conde ~@orelse))))))
|
|
12
12
|
|