snail-lang 0.2.0__tar.gz → 0.3.6__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.
- {snail_lang-0.2.0 → snail_lang-0.3.6}/Cargo.lock +26 -43
- {snail_lang-0.2.0 → snail_lang-0.3.6}/PKG-INFO +13 -9
- {snail_lang-0.2.0 → snail_lang-0.3.6}/README.md +12 -8
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-ast/Cargo.toml +1 -1
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-ast/README.md +1 -3
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-core/Cargo.toml +2 -3
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-core/README.md +5 -9
- snail_lang-0.3.6/crates/snail-core/src/lib.rs +36 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-error/Cargo.toml +1 -1
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-lower/Cargo.toml +2 -2
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-lower/README.md +7 -8
- snail_lang-0.3.6/crates/snail-lower/src/awk.rs +470 -0
- snail_lang-0.3.6/crates/snail-lower/src/expr.rs +923 -0
- snail_lang-0.3.6/crates/snail-lower/src/helpers.rs +103 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-lower/src/lib.rs +5 -2
- snail_lang-0.3.6/crates/snail-lower/src/operators.rs +69 -0
- snail_lang-0.3.6/crates/snail-lower/src/program.rs +176 -0
- snail_lang-0.3.6/crates/snail-lower/src/py_ast.rs +80 -0
- snail_lang-0.3.6/crates/snail-lower/src/stmt.rs +686 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/Cargo.toml +1 -1
- snail_lang-0.3.6/crates/snail-parser/src/lib.rs +417 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/tests/parser.rs +18 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-python/Cargo.toml +1 -1
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-python/src/lib.rs +13 -7
- {snail_lang-0.2.0 → snail_lang-0.3.6}/pyproject.toml +1 -1
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/__init__.py +1 -1
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/runtime/__init__.py +2 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/runtime/structured_accessor.py +47 -3
- snail_lang-0.2.0/crates/snail-codegen/Cargo.toml +0 -9
- snail_lang-0.2.0/crates/snail-codegen/README.md +0 -41
- snail_lang-0.2.0/crates/snail-codegen/src/expr.rs +0 -483
- snail_lang-0.2.0/crates/snail-codegen/src/lib.rs +0 -58
- snail_lang-0.2.0/crates/snail-codegen/src/writer.rs +0 -217
- snail_lang-0.2.0/crates/snail-core/src/lib.rs +0 -33
- snail_lang-0.2.0/crates/snail-lower/src/awk.rs +0 -360
- snail_lang-0.2.0/crates/snail-lower/src/expr.rs +0 -560
- snail_lang-0.2.0/crates/snail-lower/src/helpers.rs +0 -49
- snail_lang-0.2.0/crates/snail-lower/src/operators.rs +0 -42
- snail_lang-0.2.0/crates/snail-lower/src/program.rs +0 -87
- snail_lang-0.2.0/crates/snail-lower/src/span.rs +0 -65
- snail_lang-0.2.0/crates/snail-lower/src/stmt.rs +0 -270
- snail_lang-0.2.0/crates/snail-parser/src/lib.rs +0 -85
- snail_lang-0.2.0/crates/snail-python-ast/Cargo.toml +0 -8
- snail_lang-0.2.0/crates/snail-python-ast/README.md +0 -32
- snail_lang-0.2.0/crates/snail-python-ast/src/lib.rs +0 -311
- {snail_lang-0.2.0 → snail_lang-0.3.6}/Cargo.toml +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/LICENSE +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-ast/src/ast.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-ast/src/awk.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-ast/src/lib.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-error/README.md +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-error/src/lib.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-lower/src/constants.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/README.md +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/awk.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/expr.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/literal.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/snail.pest +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/stmt.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/string.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/crates/snail-parser/src/util.rs +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/cli.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/runtime/compact_try.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/runtime/regex.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/runtime/subprocess.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/__init__.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/LICENSE +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/__init__.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/ast.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/compat.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/exceptions.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/functions.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/lexer.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/parser.py +0 -0
- {snail_lang-0.2.0 → snail_lang-0.3.6}/python/snail/vendor/jmespath/visitor.py +0 -0
|
@@ -134,9 +134,9 @@ dependencies = [
|
|
|
134
134
|
|
|
135
135
|
[[package]]
|
|
136
136
|
name = "libc"
|
|
137
|
-
version = "0.2.
|
|
137
|
+
version = "0.2.180"
|
|
138
138
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
139
|
-
checksum = "
|
|
139
|
+
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
|
140
140
|
|
|
141
141
|
[[package]]
|
|
142
142
|
name = "linux-raw-sys"
|
|
@@ -208,9 +208,9 @@ dependencies = [
|
|
|
208
208
|
|
|
209
209
|
[[package]]
|
|
210
210
|
name = "pest"
|
|
211
|
-
version = "2.8.
|
|
211
|
+
version = "2.8.5"
|
|
212
212
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
213
|
-
checksum = "
|
|
213
|
+
checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7"
|
|
214
214
|
dependencies = [
|
|
215
215
|
"memchr",
|
|
216
216
|
"ucd-trie",
|
|
@@ -218,9 +218,9 @@ dependencies = [
|
|
|
218
218
|
|
|
219
219
|
[[package]]
|
|
220
220
|
name = "pest_derive"
|
|
221
|
-
version = "2.8.
|
|
221
|
+
version = "2.8.5"
|
|
222
222
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
223
|
-
checksum = "
|
|
223
|
+
checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed"
|
|
224
224
|
dependencies = [
|
|
225
225
|
"pest",
|
|
226
226
|
"pest_generator",
|
|
@@ -228,9 +228,9 @@ dependencies = [
|
|
|
228
228
|
|
|
229
229
|
[[package]]
|
|
230
230
|
name = "pest_generator"
|
|
231
|
-
version = "2.8.
|
|
231
|
+
version = "2.8.5"
|
|
232
232
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
233
|
-
checksum = "
|
|
233
|
+
checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5"
|
|
234
234
|
dependencies = [
|
|
235
235
|
"pest",
|
|
236
236
|
"pest_meta",
|
|
@@ -241,9 +241,9 @@ dependencies = [
|
|
|
241
241
|
|
|
242
242
|
[[package]]
|
|
243
243
|
name = "pest_meta"
|
|
244
|
-
version = "2.8.
|
|
244
|
+
version = "2.8.5"
|
|
245
245
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
246
|
-
checksum = "
|
|
246
|
+
checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365"
|
|
247
247
|
dependencies = [
|
|
248
248
|
"pest",
|
|
249
249
|
"sha2",
|
|
@@ -266,9 +266,9 @@ dependencies = [
|
|
|
266
266
|
|
|
267
267
|
[[package]]
|
|
268
268
|
name = "proc-macro2"
|
|
269
|
-
version = "1.0.
|
|
269
|
+
version = "1.0.105"
|
|
270
270
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
271
|
-
checksum = "
|
|
271
|
+
checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7"
|
|
272
272
|
dependencies = [
|
|
273
273
|
"unicode-ident",
|
|
274
274
|
]
|
|
@@ -363,9 +363,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
|
|
363
363
|
|
|
364
364
|
[[package]]
|
|
365
365
|
name = "quote"
|
|
366
|
-
version = "1.0.
|
|
366
|
+
version = "1.0.43"
|
|
367
367
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
368
|
-
checksum = "
|
|
368
|
+
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
|
369
369
|
dependencies = [
|
|
370
370
|
"proc-macro2",
|
|
371
371
|
]
|
|
@@ -485,47 +485,38 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
|
485
485
|
|
|
486
486
|
[[package]]
|
|
487
487
|
name = "snail-ast"
|
|
488
|
-
version = "0.
|
|
489
|
-
|
|
490
|
-
[[package]]
|
|
491
|
-
name = "snail-codegen"
|
|
492
|
-
version = "0.2.0"
|
|
493
|
-
dependencies = [
|
|
494
|
-
"snail-ast",
|
|
495
|
-
"snail-python-ast",
|
|
496
|
-
]
|
|
488
|
+
version = "0.3.6"
|
|
497
489
|
|
|
498
490
|
[[package]]
|
|
499
491
|
name = "snail-core"
|
|
500
|
-
version = "0.
|
|
492
|
+
version = "0.3.6"
|
|
501
493
|
dependencies = [
|
|
494
|
+
"pyo3",
|
|
502
495
|
"snail-ast",
|
|
503
|
-
"snail-codegen",
|
|
504
496
|
"snail-error",
|
|
505
497
|
"snail-lower",
|
|
506
498
|
"snail-parser",
|
|
507
|
-
"snail-python-ast",
|
|
508
499
|
]
|
|
509
500
|
|
|
510
501
|
[[package]]
|
|
511
502
|
name = "snail-error"
|
|
512
|
-
version = "0.
|
|
503
|
+
version = "0.3.6"
|
|
513
504
|
dependencies = [
|
|
514
505
|
"snail-ast",
|
|
515
506
|
]
|
|
516
507
|
|
|
517
508
|
[[package]]
|
|
518
509
|
name = "snail-lower"
|
|
519
|
-
version = "0.
|
|
510
|
+
version = "0.3.6"
|
|
520
511
|
dependencies = [
|
|
512
|
+
"pyo3",
|
|
521
513
|
"snail-ast",
|
|
522
514
|
"snail-error",
|
|
523
|
-
"snail-python-ast",
|
|
524
515
|
]
|
|
525
516
|
|
|
526
517
|
[[package]]
|
|
527
518
|
name = "snail-parser"
|
|
528
|
-
version = "0.
|
|
519
|
+
version = "0.3.6"
|
|
529
520
|
dependencies = [
|
|
530
521
|
"pest",
|
|
531
522
|
"pest_derive",
|
|
@@ -535,39 +526,31 @@ dependencies = [
|
|
|
535
526
|
|
|
536
527
|
[[package]]
|
|
537
528
|
name = "snail-proptest"
|
|
538
|
-
version = "0.
|
|
529
|
+
version = "0.3.6"
|
|
539
530
|
dependencies = [
|
|
540
531
|
"proptest",
|
|
532
|
+
"pyo3",
|
|
541
533
|
"snail-ast",
|
|
542
|
-
"snail-codegen",
|
|
543
534
|
"snail-core",
|
|
544
535
|
"snail-error",
|
|
545
536
|
"snail-lower",
|
|
546
537
|
"snail-parser",
|
|
547
|
-
"snail-python-ast",
|
|
548
538
|
"tempfile",
|
|
549
539
|
]
|
|
550
540
|
|
|
551
541
|
[[package]]
|
|
552
542
|
name = "snail-python"
|
|
553
|
-
version = "0.
|
|
543
|
+
version = "0.3.6"
|
|
554
544
|
dependencies = [
|
|
555
545
|
"pyo3",
|
|
556
546
|
"snail-core",
|
|
557
547
|
]
|
|
558
548
|
|
|
559
|
-
[[package]]
|
|
560
|
-
name = "snail-python-ast"
|
|
561
|
-
version = "0.2.0"
|
|
562
|
-
dependencies = [
|
|
563
|
-
"snail-ast",
|
|
564
|
-
]
|
|
565
|
-
|
|
566
549
|
[[package]]
|
|
567
550
|
name = "syn"
|
|
568
|
-
version = "2.0.
|
|
551
|
+
version = "2.0.114"
|
|
569
552
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
570
|
-
checksum = "
|
|
553
|
+
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
|
571
554
|
dependencies = [
|
|
572
555
|
"proc-macro2",
|
|
573
556
|
"quote",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snail-lang
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Requires-Dist: maturin>=1.5 ; extra == 'dev'
|
|
5
5
|
Requires-Dist: pytest ; extra == 'dev'
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -115,6 +115,9 @@ class Doubler {
|
|
|
115
115
|
def __pipeline__(self, x) { return x * 2 }
|
|
116
116
|
}
|
|
117
117
|
doubled = 21 | Doubler() # yields 42
|
|
118
|
+
|
|
119
|
+
# Join list items with a separator
|
|
120
|
+
joined = ["a", "b"] | join(" ") # yields "a b"
|
|
118
121
|
```
|
|
119
122
|
|
|
120
123
|
### JSON Queries with JMESPath
|
|
@@ -129,6 +132,9 @@ first_email = data | $[users[0].email]
|
|
|
129
132
|
|
|
130
133
|
# Inline parsing and querying
|
|
131
134
|
result = json('{"foo": 12}') | $[foo]
|
|
135
|
+
|
|
136
|
+
# JSONL parsing returns a list
|
|
137
|
+
names = json('{"name": "Ada"}\n{"name": "Lin"}') | $[[*].name]
|
|
132
138
|
```
|
|
133
139
|
|
|
134
140
|
### Full Python Interoperability
|
|
@@ -147,7 +153,7 @@ filtered = df[df["value"] > 100]
|
|
|
147
153
|
|
|
148
154
|
```bash
|
|
149
155
|
# Install from PyPI
|
|
150
|
-
pip install snail
|
|
156
|
+
pip install snail-lang
|
|
151
157
|
|
|
152
158
|
# Run a one-liner
|
|
153
159
|
snail "print('Hello, Snail!')"
|
|
@@ -179,10 +185,9 @@ flowchart TB
|
|
|
179
185
|
C2[crates/snail-ast/src/awk.rs<br/>AwkProgram AST]
|
|
180
186
|
end
|
|
181
187
|
|
|
182
|
-
subgraph Lowering["Lowering
|
|
188
|
+
subgraph Lowering["Lowering"]
|
|
183
189
|
D1[crates/snail-lower/<br/>AST → Python AST Transform]
|
|
184
190
|
D2[python/snail/runtime/<br/>Runtime Helpers]
|
|
185
|
-
D3[crates/snail-codegen/<br/>Python AST → Source Code]
|
|
186
191
|
end
|
|
187
192
|
|
|
188
193
|
subgraph Execution
|
|
@@ -198,9 +203,8 @@ flowchart TB
|
|
|
198
203
|
C1 --> D1
|
|
199
204
|
C2 --> D1
|
|
200
205
|
D1 --> D2
|
|
201
|
-
D1 -->
|
|
202
|
-
D2 -->
|
|
203
|
-
D3 --> E1
|
|
206
|
+
D1 --> E1
|
|
207
|
+
D2 --> E1
|
|
204
208
|
E1 --> E2
|
|
205
209
|
E2 --> F[Python Execution]
|
|
206
210
|
|
|
@@ -218,7 +222,7 @@ flowchart TB
|
|
|
218
222
|
- `$(cmd)` subprocess capture → `__SnailSubprocessCapture`
|
|
219
223
|
- `@(cmd)` subprocess status → `__SnailSubprocessStatus`
|
|
220
224
|
- Regex literals → `__snail_regex_search` and `__snail_regex_compile`
|
|
221
|
-
- **
|
|
225
|
+
- **Execution**: Compiles Python AST directly for in-process execution
|
|
222
226
|
- **CLI**: Python wrapper (`python/snail/cli.py`) that executes via the extension module
|
|
223
227
|
|
|
224
228
|
## 📚 Documentation
|
|
@@ -333,7 +337,7 @@ python3 -m venv myenv
|
|
|
333
337
|
source myenv/bin/activate # On Windows: myenv\Scripts\activate
|
|
334
338
|
|
|
335
339
|
# Install and run
|
|
336
|
-
pip install snail
|
|
340
|
+
pip install snail-lang
|
|
337
341
|
snail "import sys; print(sys.prefix)"
|
|
338
342
|
```
|
|
339
343
|
|
|
@@ -104,6 +104,9 @@ class Doubler {
|
|
|
104
104
|
def __pipeline__(self, x) { return x * 2 }
|
|
105
105
|
}
|
|
106
106
|
doubled = 21 | Doubler() # yields 42
|
|
107
|
+
|
|
108
|
+
# Join list items with a separator
|
|
109
|
+
joined = ["a", "b"] | join(" ") # yields "a b"
|
|
107
110
|
```
|
|
108
111
|
|
|
109
112
|
### JSON Queries with JMESPath
|
|
@@ -118,6 +121,9 @@ first_email = data | $[users[0].email]
|
|
|
118
121
|
|
|
119
122
|
# Inline parsing and querying
|
|
120
123
|
result = json('{"foo": 12}') | $[foo]
|
|
124
|
+
|
|
125
|
+
# JSONL parsing returns a list
|
|
126
|
+
names = json('{"name": "Ada"}\n{"name": "Lin"}') | $[[*].name]
|
|
121
127
|
```
|
|
122
128
|
|
|
123
129
|
### Full Python Interoperability
|
|
@@ -136,7 +142,7 @@ filtered = df[df["value"] > 100]
|
|
|
136
142
|
|
|
137
143
|
```bash
|
|
138
144
|
# Install from PyPI
|
|
139
|
-
pip install snail
|
|
145
|
+
pip install snail-lang
|
|
140
146
|
|
|
141
147
|
# Run a one-liner
|
|
142
148
|
snail "print('Hello, Snail!')"
|
|
@@ -168,10 +174,9 @@ flowchart TB
|
|
|
168
174
|
C2[crates/snail-ast/src/awk.rs<br/>AwkProgram AST]
|
|
169
175
|
end
|
|
170
176
|
|
|
171
|
-
subgraph Lowering["Lowering
|
|
177
|
+
subgraph Lowering["Lowering"]
|
|
172
178
|
D1[crates/snail-lower/<br/>AST → Python AST Transform]
|
|
173
179
|
D2[python/snail/runtime/<br/>Runtime Helpers]
|
|
174
|
-
D3[crates/snail-codegen/<br/>Python AST → Source Code]
|
|
175
180
|
end
|
|
176
181
|
|
|
177
182
|
subgraph Execution
|
|
@@ -187,9 +192,8 @@ flowchart TB
|
|
|
187
192
|
C1 --> D1
|
|
188
193
|
C2 --> D1
|
|
189
194
|
D1 --> D2
|
|
190
|
-
D1 -->
|
|
191
|
-
D2 -->
|
|
192
|
-
D3 --> E1
|
|
195
|
+
D1 --> E1
|
|
196
|
+
D2 --> E1
|
|
193
197
|
E1 --> E2
|
|
194
198
|
E2 --> F[Python Execution]
|
|
195
199
|
|
|
@@ -207,7 +211,7 @@ flowchart TB
|
|
|
207
211
|
- `$(cmd)` subprocess capture → `__SnailSubprocessCapture`
|
|
208
212
|
- `@(cmd)` subprocess status → `__SnailSubprocessStatus`
|
|
209
213
|
- Regex literals → `__snail_regex_search` and `__snail_regex_compile`
|
|
210
|
-
- **
|
|
214
|
+
- **Execution**: Compiles Python AST directly for in-process execution
|
|
211
215
|
- **CLI**: Python wrapper (`python/snail/cli.py`) that executes via the extension module
|
|
212
216
|
|
|
213
217
|
## 📚 Documentation
|
|
@@ -322,7 +326,7 @@ python3 -m venv myenv
|
|
|
322
326
|
source myenv/bin/activate # On Windows: myenv\Scripts\activate
|
|
323
327
|
|
|
324
328
|
# Install and run
|
|
325
|
-
pip install snail
|
|
329
|
+
pip install snail-lang
|
|
326
330
|
snail "import sys; print(sys.prefix)"
|
|
327
331
|
```
|
|
328
332
|
|
|
@@ -21,11 +21,9 @@ None - this crate has no dependencies and provides pure data structures.
|
|
|
21
21
|
|
|
22
22
|
## Used By
|
|
23
23
|
|
|
24
|
-
- **snail-python-ast**: Uses `SourceSpan` and `StringDelimiter` for its own AST nodes
|
|
25
24
|
- **snail-error**: Uses `SourceSpan` for error reporting with source locations
|
|
26
25
|
- **snail-parser**: Produces `Program` and `AwkProgram` as output
|
|
27
|
-
- **snail-lower**: Consumes Snail AST and transforms it to Python
|
|
28
|
-
- **snail-codegen**: Uses `StringDelimiter` for string literal formatting
|
|
26
|
+
- **snail-lower**: Consumes Snail AST and transforms it to Python `ast` nodes via pyo3
|
|
29
27
|
- **snail-core**: Re-exports all types for the unified API
|
|
30
28
|
|
|
31
29
|
## Design
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "snail-core"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.6"
|
|
4
4
|
edition.workspace = true
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
|
|
7
7
|
[dependencies]
|
|
8
8
|
snail-ast = { path = "../snail-ast" }
|
|
9
|
-
snail-python-ast = { path = "../snail-python-ast" }
|
|
10
9
|
snail-error = { path = "../snail-error" }
|
|
11
10
|
snail-parser = { path = "../snail-parser" }
|
|
12
11
|
snail-lower = { path = "../snail-lower" }
|
|
13
|
-
|
|
12
|
+
pyo3 = { version = "0.21", features = ["abi3-py310"] }
|
|
@@ -4,27 +4,24 @@ Unified compilation API for the Snail programming language.
|
|
|
4
4
|
|
|
5
5
|
## Purpose
|
|
6
6
|
|
|
7
|
-
This crate serves as the main entry point for Snail compilation. It re-exports
|
|
7
|
+
This crate serves as the main entry point for Snail compilation. It re-exports types from the workspace crates and provides high-level compilation functions that orchestrate the complete pipeline from source code to Python `ast` nodes.
|
|
8
8
|
|
|
9
9
|
## Key Components
|
|
10
10
|
|
|
11
|
-
- **compile_snail_source()**: One-step compilation from Snail source to Python
|
|
11
|
+
- **compile_snail_source()**: One-step compilation from Snail source to Python `ast` module
|
|
12
12
|
- **compile_snail_source_with_auto_print()**: Compilation with optional auto-print for CLI usage
|
|
13
|
-
- Re-exports from
|
|
13
|
+
- Re-exports from workspace crates:
|
|
14
14
|
- `snail-ast`: All AST types
|
|
15
|
-
- `snail-python-ast`: All Python AST types
|
|
16
15
|
- `snail-error`: Error types and formatting
|
|
17
16
|
- `snail-parser`: Parsing functions
|
|
18
17
|
- `snail-lower`: Lowering functions
|
|
19
|
-
- `snail-codegen`: Code generation functions
|
|
20
18
|
|
|
21
19
|
## Compilation Pipeline
|
|
22
20
|
|
|
23
21
|
The `compile_snail_source()` function orchestrates the complete compilation:
|
|
24
22
|
|
|
25
23
|
1. **Parse**: `parse_program()` or `parse_awk_program()` → Snail AST
|
|
26
|
-
2. **Lower**: `lower_program()` or `lower_awk_program()` → Python
|
|
27
|
-
3. **Codegen**: `python_source()` → Python source string
|
|
24
|
+
2. **Lower**: `lower_program()` or `lower_awk_program()` → Python `ast.Module`
|
|
28
25
|
|
|
29
26
|
Each stage can fail with appropriate error types (`ParseError` or `LowerError`), wrapped in the unified `SnailError` type.
|
|
30
27
|
|
|
@@ -45,11 +42,10 @@ This enables REPL-like behavior for interactive use and CLI one-liners.
|
|
|
45
42
|
## Dependencies
|
|
46
43
|
|
|
47
44
|
- **snail-ast**: Core AST types
|
|
48
|
-
- **snail-python-ast**: Python AST types
|
|
49
45
|
- **snail-error**: Error handling
|
|
50
46
|
- **snail-parser**: Parsing logic
|
|
51
47
|
- **snail-lower**: AST transformation
|
|
52
|
-
- **
|
|
48
|
+
- **pyo3**: Python AST construction
|
|
53
49
|
|
|
54
50
|
## Used By
|
|
55
51
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
use pyo3::prelude::*;
|
|
2
|
+
|
|
3
|
+
// Re-export all workspace crates for unified API
|
|
4
|
+
pub use snail_ast::*;
|
|
5
|
+
pub use snail_error::*;
|
|
6
|
+
pub use snail_lower::*;
|
|
7
|
+
pub use snail_parser::*;
|
|
8
|
+
|
|
9
|
+
/// Compilation API
|
|
10
|
+
pub fn compile_snail_source(
|
|
11
|
+
py: Python<'_>,
|
|
12
|
+
source: &str,
|
|
13
|
+
mode: CompileMode,
|
|
14
|
+
) -> Result<PyObject, SnailError> {
|
|
15
|
+
compile_snail_source_with_auto_print(py, source, mode, false)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
pub fn compile_snail_source_with_auto_print(
|
|
19
|
+
py: Python<'_>,
|
|
20
|
+
source: &str,
|
|
21
|
+
mode: CompileMode,
|
|
22
|
+
auto_print_last: bool,
|
|
23
|
+
) -> Result<PyObject, SnailError> {
|
|
24
|
+
match mode {
|
|
25
|
+
CompileMode::Snail => {
|
|
26
|
+
let program = parse_program(source)?;
|
|
27
|
+
let module = lower_program_with_auto_print(py, &program, auto_print_last)?;
|
|
28
|
+
Ok(module)
|
|
29
|
+
}
|
|
30
|
+
CompileMode::Awk => {
|
|
31
|
+
let program = parse_awk_program(source)?;
|
|
32
|
+
let module = lower_awk_program_with_auto_print(py, &program, auto_print_last)?;
|
|
33
|
+
Ok(module)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "snail-lower"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.6"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
|
|
7
7
|
[dependencies]
|
|
8
8
|
snail-ast = { path = "../snail-ast" }
|
|
9
|
-
snail-python-ast = { path = "../snail-python-ast" }
|
|
10
9
|
snail-error = { path = "../snail-error" }
|
|
10
|
+
pyo3 = { version = "0.21", features = ["abi3-py310"] }
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# snail-lower
|
|
2
2
|
|
|
3
|
-
AST transformation layer that lowers Snail AST to Python
|
|
3
|
+
AST transformation layer that lowers Snail AST to Python `ast` nodes via pyo3.
|
|
4
4
|
|
|
5
5
|
## Purpose
|
|
6
6
|
|
|
7
|
-
This crate is the semantic transformation core of the Snail compiler. It takes Snail AST nodes and transforms them into equivalent Python
|
|
7
|
+
This crate is the semantic transformation core of the Snail compiler. It takes Snail AST nodes and transforms them into equivalent Python `ast` nodes, handling all Snail-specific features by generating appropriate Python AST patterns and helper function calls.
|
|
8
8
|
|
|
9
9
|
## Key Components
|
|
10
10
|
|
|
11
|
-
- **lower_program()**: Transforms a regular `Program` to `
|
|
12
|
-
- **lower_awk_program()**: Transforms an `AwkProgram` to `
|
|
11
|
+
- **lower_program()**: Transforms a regular `Program` to a Python `ast.Module`
|
|
12
|
+
- **lower_awk_program()**: Transforms an `AwkProgram` to a Python `ast.Module` with awk runtime
|
|
13
13
|
- **lower_awk_program_with_auto_print()**: Awk lowering with optional auto-print
|
|
14
14
|
- Helper constants for generated Python code:
|
|
15
15
|
- `SNAIL_TRY_HELPER`: Name for the `?` operator helper function
|
|
@@ -31,7 +31,7 @@ This crate is the semantic transformation core of the Snail compiler. It takes S
|
|
|
31
31
|
|
|
32
32
|
## Awk Mode Lowering
|
|
33
33
|
|
|
34
|
-
When lowering awk programs, generates a complete Python
|
|
34
|
+
When lowering awk programs, generates a complete Python AST that:
|
|
35
35
|
1. Imports `sys` for accessing command-line arguments and stdin
|
|
36
36
|
2. Executes BEGIN blocks before processing input
|
|
37
37
|
3. Creates a main loop that reads lines from files or stdin
|
|
@@ -42,15 +42,14 @@ When lowering awk programs, generates a complete Python program that:
|
|
|
42
42
|
## Dependencies
|
|
43
43
|
|
|
44
44
|
- **snail-ast**: Consumes Snail `Program` and `AwkProgram`
|
|
45
|
-
- **
|
|
45
|
+
- **pyo3**: Constructs Python `ast` nodes
|
|
46
46
|
- **snail-error**: Returns `LowerError` on transformation failures
|
|
47
47
|
|
|
48
48
|
## Used By
|
|
49
49
|
|
|
50
|
-
- **snail-codegen**: Consumes the Python AST to generate source code
|
|
51
50
|
- **snail-core**: Calls lowering functions as part of the compilation pipeline
|
|
52
51
|
- Tests validate transformation correctness
|
|
53
52
|
|
|
54
53
|
## Design
|
|
55
54
|
|
|
56
|
-
The lowering process preserves Python semantics exactly - only syntax differs.
|
|
55
|
+
The lowering process preserves Python semantics exactly - only syntax differs. `SourceSpan` information is used to populate Python AST location metadata for accurate error reporting.
|