snail-lang 0.7.0__tar.gz → 0.7.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.
- {snail_lang-0.7.0 → snail_lang-0.7.1}/Cargo.lock +5 -5
- {snail_lang-0.7.0 → snail_lang-0.7.1}/Cargo.toml +6 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/PKG-INFO +8 -7
- {snail_lang-0.7.0 → snail_lang-0.7.1}/README.md +5 -5
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-ast/Cargo.toml +1 -1
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-error/Cargo.toml +1 -1
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/Cargo.toml +1 -1
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/Cargo.toml +2 -2
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/expr.rs +57 -68
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/py_ast.rs +28 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/pyproject.toml +3 -2
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/__init__.py +2 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/cli.py +16 -5
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/__init__.py +2 -1
- {snail_lang-0.7.0 → snail_lang-0.7.1}/LICENSE +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-ast/README.md +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-ast/src/ast.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-ast/src/awk.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-ast/src/lib.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-error/README.md +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-error/src/lib.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/README.md +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/awk.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/expr.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/lib.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/literal.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/snail.pest +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/stmt.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/string.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/src/util.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/tests/common.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/tests/errors.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/tests/parser.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/tests/statements.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/tests/syntax_expressions.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-parser/tests/syntax_strings.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/build.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/compiler.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lib.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/linecache.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/awk.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/constants.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/desugar.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/helpers.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/map.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/mod.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/operators.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/program.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/stmt.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/lower/validate.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/crates/snail-python/src/profiling.rs +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/augmented.py +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/compact_try.py +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/lazy_file.py +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/lazy_text.py +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/regex.py +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/structured_accessor.py +0 -0
- {snail_lang-0.7.0 → snail_lang-0.7.1}/python/snail/runtime/subprocess.py +0 -0
|
@@ -312,25 +312,25 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
|
312
312
|
|
|
313
313
|
[[package]]
|
|
314
314
|
name = "snail-ast"
|
|
315
|
-
version = "0.7.
|
|
315
|
+
version = "0.7.1"
|
|
316
316
|
|
|
317
317
|
[[package]]
|
|
318
318
|
name = "snail-error"
|
|
319
|
-
version = "0.7.
|
|
319
|
+
version = "0.7.1"
|
|
320
320
|
dependencies = [
|
|
321
321
|
"snail-ast",
|
|
322
322
|
]
|
|
323
323
|
|
|
324
324
|
[[package]]
|
|
325
325
|
name = "snail-lower"
|
|
326
|
-
version = "0.7.
|
|
326
|
+
version = "0.7.1"
|
|
327
327
|
dependencies = [
|
|
328
328
|
"snail-python",
|
|
329
329
|
]
|
|
330
330
|
|
|
331
331
|
[[package]]
|
|
332
332
|
name = "snail-parser"
|
|
333
|
-
version = "0.7.
|
|
333
|
+
version = "0.7.1"
|
|
334
334
|
dependencies = [
|
|
335
335
|
"pest",
|
|
336
336
|
"pest_derive",
|
|
@@ -340,7 +340,7 @@ dependencies = [
|
|
|
340
340
|
|
|
341
341
|
[[package]]
|
|
342
342
|
name = "snail-python"
|
|
343
|
-
version = "0.7.
|
|
343
|
+
version = "0.7.1"
|
|
344
344
|
dependencies = [
|
|
345
345
|
"pyo3",
|
|
346
346
|
"snail-ast",
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snail-lang
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Requires-Dist: astunparse>=1.6.3 ; python_full_version < '3.9'
|
|
4
5
|
Requires-Dist: jmespath>=1.0.1
|
|
5
6
|
Requires-Dist: maturin>=1.5 ; extra == 'dev'
|
|
6
7
|
Requires-Dist: pytest ; extra == 'dev'
|
|
7
8
|
Provides-Extra: dev
|
|
8
9
|
License-File: LICENSE
|
|
9
10
|
Summary: Snail programming language interpreter
|
|
10
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.8
|
|
11
12
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
12
13
|
|
|
13
14
|
<p align="center">
|
|
@@ -26,10 +27,10 @@ way into something good, but its certainly not there yet.
|
|
|
26
27
|
|
|
27
28
|
## Installing Snail
|
|
28
29
|
|
|
29
|
-
Install [uv](https://docs.astral.sh/uv/getting-started/installation/) and then run:
|
|
30
|
-
|
|
31
30
|
```bash
|
|
32
|
-
|
|
31
|
+
pip install snail-lang
|
|
32
|
+
-or-
|
|
33
|
+
uv tool install snail-lang
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
That installs the `snail` CLI for your user; try it with `snail "print('hello')"` once the install completes.
|
|
@@ -243,7 +244,7 @@ names = js('{{"name": "Ada"}}\n{{"name": "Lin"}}') | $[[*].name]
|
|
|
243
244
|
### Full Python Interoperability
|
|
244
245
|
|
|
245
246
|
Snail compiles to Python AST—import any Python module, use any library, in any
|
|
246
|
-
environment. Assuming that you are using Python 3.
|
|
247
|
+
environment. Assuming that you are using Python 3.8 or later.
|
|
247
248
|
|
|
248
249
|
## 🚀 Quick Start
|
|
249
250
|
|
|
@@ -294,7 +295,7 @@ machine snail adds 5 ms of overhead above the regular python3 interpreter.
|
|
|
294
295
|
|
|
295
296
|
### Prerequisites
|
|
296
297
|
|
|
297
|
-
**Python 3.
|
|
298
|
+
**Python 3.8+** (required at runtime)
|
|
298
299
|
|
|
299
300
|
Snail runs in-process via a Pyo3 extension module, so it uses the active Python environment.
|
|
300
301
|
|
|
@@ -14,10 +14,10 @@ way into something good, but its certainly not there yet.
|
|
|
14
14
|
|
|
15
15
|
## Installing Snail
|
|
16
16
|
|
|
17
|
-
Install [uv](https://docs.astral.sh/uv/getting-started/installation/) and then run:
|
|
18
|
-
|
|
19
17
|
```bash
|
|
20
|
-
|
|
18
|
+
pip install snail-lang
|
|
19
|
+
-or-
|
|
20
|
+
uv tool install snail-lang
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
That installs the `snail` CLI for your user; try it with `snail "print('hello')"` once the install completes.
|
|
@@ -231,7 +231,7 @@ names = js('{{"name": "Ada"}}\n{{"name": "Lin"}}') | $[[*].name]
|
|
|
231
231
|
### Full Python Interoperability
|
|
232
232
|
|
|
233
233
|
Snail compiles to Python AST—import any Python module, use any library, in any
|
|
234
|
-
environment. Assuming that you are using Python 3.
|
|
234
|
+
environment. Assuming that you are using Python 3.8 or later.
|
|
235
235
|
|
|
236
236
|
## 🚀 Quick Start
|
|
237
237
|
|
|
@@ -282,7 +282,7 @@ machine snail adds 5 ms of overhead above the regular python3 interpreter.
|
|
|
282
282
|
|
|
283
283
|
### Prerequisites
|
|
284
284
|
|
|
285
|
-
**Python 3.
|
|
285
|
+
**Python 3.8+** (required at runtime)
|
|
286
286
|
|
|
287
287
|
Snail runs in-process via a Pyo3 extension module, so it uses the active Python environment.
|
|
288
288
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "snail-python"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.1"
|
|
4
4
|
edition.workspace = true
|
|
5
5
|
build = "build.rs"
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ name = "snail_python"
|
|
|
9
9
|
crate-type = ["cdylib", "rlib"]
|
|
10
10
|
|
|
11
11
|
[dependencies]
|
|
12
|
-
pyo3 = { version = "0.21", features = ["extension-module", "abi3-
|
|
12
|
+
pyo3 = { version = "0.21", features = ["extension-module", "abi3-py38"] }
|
|
13
13
|
snail-ast = { path = "../snail-ast" }
|
|
14
14
|
snail-error = { path = "../snail-error" }
|
|
15
15
|
snail-parser = { path = "../snail-parser" }
|
|
@@ -36,9 +36,7 @@ pub(crate) fn lower_assign_target(
|
|
|
36
36
|
AssignTarget::Index { value, index, span } => {
|
|
37
37
|
let value_expr = lower_expr_with_exception(builder, value, None)?;
|
|
38
38
|
let index_expr = lower_expr_with_exception(builder, index, None)?;
|
|
39
|
-
builder
|
|
40
|
-
.call_node("Subscript", vec![value_expr, index_expr, store_ctx], span)
|
|
41
|
-
.map_err(py_err_to_lower)
|
|
39
|
+
subscript_expr(builder, value_expr, index_expr, store_ctx, span)
|
|
42
40
|
}
|
|
43
41
|
AssignTarget::Starred { target, span } => {
|
|
44
42
|
let value = lower_assign_target(builder, target)?;
|
|
@@ -101,9 +99,7 @@ pub(crate) fn lower_delete_target(
|
|
|
101
99
|
AssignTarget::Index { value, index, span } => {
|
|
102
100
|
let value_expr = lower_expr_with_exception(builder, value, None)?;
|
|
103
101
|
let index_expr = lower_expr_with_exception(builder, index, None)?;
|
|
104
|
-
builder
|
|
105
|
-
.call_node("Subscript", vec![value_expr, index_expr, del_ctx], span)
|
|
106
|
-
.map_err(py_err_to_lower)
|
|
102
|
+
subscript_expr(builder, value_expr, index_expr, del_ctx, span)
|
|
107
103
|
}
|
|
108
104
|
AssignTarget::Starred { .. } => Err(LowerError::new(
|
|
109
105
|
"starred targets are not valid in del statements",
|
|
@@ -143,6 +139,19 @@ pub(crate) fn lower_delete_target(
|
|
|
143
139
|
}
|
|
144
140
|
}
|
|
145
141
|
|
|
142
|
+
fn subscript_expr(
|
|
143
|
+
builder: &AstBuilder<'_>,
|
|
144
|
+
value: PyObject,
|
|
145
|
+
index: PyObject,
|
|
146
|
+
ctx: PyObject,
|
|
147
|
+
span: &SourceSpan,
|
|
148
|
+
) -> Result<PyObject, LowerError> {
|
|
149
|
+
let slice = builder.wrap_index(index, span).map_err(py_err_to_lower)?;
|
|
150
|
+
builder
|
|
151
|
+
.call_node("Subscript", vec![value, slice, ctx], span)
|
|
152
|
+
.map_err(py_err_to_lower)
|
|
153
|
+
}
|
|
154
|
+
|
|
146
155
|
pub(crate) fn lower_regex_match(
|
|
147
156
|
builder: &AstBuilder<'_>,
|
|
148
157
|
value: &Expr,
|
|
@@ -450,17 +459,13 @@ pub(crate) fn lower_expr_with_exception(
|
|
|
450
459
|
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
451
460
|
)?;
|
|
452
461
|
let index_expr = number_expr(builder, &python_index.to_string(), span)?;
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
],
|
|
461
|
-
span,
|
|
462
|
-
)
|
|
463
|
-
.map_err(py_err_to_lower)
|
|
462
|
+
subscript_expr(
|
|
463
|
+
builder,
|
|
464
|
+
value,
|
|
465
|
+
index_expr,
|
|
466
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
467
|
+
span,
|
|
468
|
+
)
|
|
464
469
|
}
|
|
465
470
|
Expr::Number { value, span } => number_expr(builder, value, span),
|
|
466
471
|
Expr::String {
|
|
@@ -805,17 +810,13 @@ pub(crate) fn lower_expr_with_exception(
|
|
|
805
810
|
span,
|
|
806
811
|
)
|
|
807
812
|
.map_err(py_err_to_lower)?;
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
],
|
|
816
|
-
span,
|
|
817
|
-
)
|
|
818
|
-
.map_err(py_err_to_lower)
|
|
813
|
+
subscript_expr(
|
|
814
|
+
builder,
|
|
815
|
+
tuple_expr,
|
|
816
|
+
index_expr,
|
|
817
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
818
|
+
span,
|
|
819
|
+
)
|
|
819
820
|
}
|
|
820
821
|
Expr::Regex { pattern, span } => {
|
|
821
822
|
let func = name_expr(
|
|
@@ -908,17 +909,13 @@ pub(crate) fn lower_expr_with_exception(
|
|
|
908
909
|
.parse::<i32>()
|
|
909
910
|
.map_err(|_| LowerError::new(format!("Invalid match group index: .{attr}")))?;
|
|
910
911
|
let index_expr = number_expr(builder, &index.to_string(), span)?;
|
|
911
|
-
return
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
],
|
|
919
|
-
span,
|
|
920
|
-
)
|
|
921
|
-
.map_err(py_err_to_lower);
|
|
912
|
+
return subscript_expr(
|
|
913
|
+
builder,
|
|
914
|
+
value,
|
|
915
|
+
index_expr,
|
|
916
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
917
|
+
span,
|
|
918
|
+
);
|
|
922
919
|
}
|
|
923
920
|
builder
|
|
924
921
|
.call_node(
|
|
@@ -935,13 +932,13 @@ pub(crate) fn lower_expr_with_exception(
|
|
|
935
932
|
Expr::Index { value, index, span } => {
|
|
936
933
|
let value = lower_expr_with_exception(builder, value, exception_name)?;
|
|
937
934
|
let index = lower_expr_with_exception(builder, index, exception_name)?;
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
935
|
+
subscript_expr(
|
|
936
|
+
builder,
|
|
937
|
+
value,
|
|
938
|
+
index,
|
|
939
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
940
|
+
span,
|
|
941
|
+
)
|
|
945
942
|
}
|
|
946
943
|
Expr::Paren { expr, .. } => lower_expr_with_exception(builder, expr, exception_name),
|
|
947
944
|
Expr::List { elements, span } => {
|
|
@@ -1344,17 +1341,13 @@ fn lower_postfix_name_incr(
|
|
|
1344
1341
|
span,
|
|
1345
1342
|
)
|
|
1346
1343
|
.map_err(py_err_to_lower)?;
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
],
|
|
1355
|
-
span,
|
|
1356
|
-
)
|
|
1357
|
-
.map_err(py_err_to_lower)
|
|
1344
|
+
subscript_expr(
|
|
1345
|
+
builder,
|
|
1346
|
+
tuple_expr,
|
|
1347
|
+
index_expr,
|
|
1348
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
1349
|
+
span,
|
|
1350
|
+
)
|
|
1358
1351
|
}
|
|
1359
1352
|
|
|
1360
1353
|
fn incr_delta(op: IncrOp) -> &'static str {
|
|
@@ -1506,17 +1499,13 @@ fn lower_lambda_body_expr(
|
|
|
1506
1499
|
span,
|
|
1507
1500
|
)
|
|
1508
1501
|
.map_err(py_err_to_lower)?;
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
],
|
|
1517
|
-
span,
|
|
1518
|
-
)
|
|
1519
|
-
.map_err(py_err_to_lower)
|
|
1502
|
+
subscript_expr(
|
|
1503
|
+
builder,
|
|
1504
|
+
tuple_expr,
|
|
1505
|
+
index_expr,
|
|
1506
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
1507
|
+
span,
|
|
1508
|
+
)
|
|
1520
1509
|
}
|
|
1521
1510
|
|
|
1522
1511
|
fn lower_call_arguments(
|
|
@@ -6,13 +6,19 @@ use snail_error::LowerError;
|
|
|
6
6
|
pub struct AstBuilder<'py> {
|
|
7
7
|
py: Python<'py>,
|
|
8
8
|
ast: Bound<'py, PyModule>,
|
|
9
|
+
needs_index_wrapper: bool,
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
impl<'py> AstBuilder<'py> {
|
|
12
13
|
pub fn new(py: Python<'py>) -> PyResult<Self> {
|
|
14
|
+
let version_info = py.import_bound("sys")?.getattr("version_info")?;
|
|
15
|
+
let major: u8 = version_info.get_item(0)?.extract()?;
|
|
16
|
+
let minor: u8 = version_info.get_item(1)?.extract()?;
|
|
17
|
+
let needs_index_wrapper = major == 3 && minor < 9;
|
|
13
18
|
Ok(Self {
|
|
14
19
|
py,
|
|
15
20
|
ast: py.import_bound("ast")?,
|
|
21
|
+
needs_index_wrapper,
|
|
16
22
|
})
|
|
17
23
|
}
|
|
18
24
|
|
|
@@ -65,6 +71,28 @@ impl<'py> AstBuilder<'py> {
|
|
|
65
71
|
let node = self.ast.getattr(name)?.call1(tuple)?;
|
|
66
72
|
Ok(node.into_py(self.py))
|
|
67
73
|
}
|
|
74
|
+
|
|
75
|
+
pub fn wrap_index(&self, slice: PyObject, span: &SourceSpan) -> PyResult<PyObject> {
|
|
76
|
+
if self.needs_index_wrapper {
|
|
77
|
+
let slice_obj = slice.bind(self.py);
|
|
78
|
+
if let Ok(slice_type) = self.ast.getattr("Slice")
|
|
79
|
+
&& slice_obj.is_instance(&slice_type)?
|
|
80
|
+
{
|
|
81
|
+
return Ok(slice);
|
|
82
|
+
}
|
|
83
|
+
if let Ok(ext_slice_type) = self.ast.getattr("ExtSlice")
|
|
84
|
+
&& slice_obj.is_instance(&ext_slice_type)?
|
|
85
|
+
{
|
|
86
|
+
return Ok(slice);
|
|
87
|
+
}
|
|
88
|
+
if let Ok(index_type) = self.ast.getattr("Index") {
|
|
89
|
+
let index = index_type.call1((slice,))?;
|
|
90
|
+
set_location(&index, span)?;
|
|
91
|
+
return Ok(index.into_py(self.py));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
Ok(slice)
|
|
95
|
+
}
|
|
68
96
|
}
|
|
69
97
|
|
|
70
98
|
pub fn set_location(node: &Bound<'_, PyAny>, span: &SourceSpan) -> PyResult<()> {
|
|
@@ -4,12 +4,13 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "snail-lang"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.1"
|
|
8
8
|
description = "Snail programming language interpreter"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
11
|
license = { file = "LICENSE" }
|
|
12
12
|
dependencies = [
|
|
13
|
+
"astunparse>=1.6.3; python_version < '3.9'",
|
|
13
14
|
"jmespath>=1.0.1",
|
|
14
15
|
]
|
|
15
16
|
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
|
+
from typing import Optional
|
|
5
6
|
|
|
6
7
|
from . import __build_info__, compile_ast, exec
|
|
7
8
|
|
|
@@ -79,7 +80,11 @@ def _install_trimmed_excepthook() -> None:
|
|
|
79
80
|
colorize = _colorize.can_colorize(file=sys.stderr)
|
|
80
81
|
except Exception:
|
|
81
82
|
colorize = hasattr(sys.stderr, "isatty") and sys.stderr.isatty()
|
|
82
|
-
|
|
83
|
+
try:
|
|
84
|
+
formatted = tb_exc.format(colorize=colorize)
|
|
85
|
+
except TypeError:
|
|
86
|
+
formatted = tb_exc.format()
|
|
87
|
+
for line in formatted:
|
|
83
88
|
sys.stderr.write(line)
|
|
84
89
|
|
|
85
90
|
sys.excepthook = _snail_excepthook
|
|
@@ -87,7 +92,7 @@ def _install_trimmed_excepthook() -> None:
|
|
|
87
92
|
|
|
88
93
|
class _Args:
|
|
89
94
|
def __init__(self) -> None:
|
|
90
|
-
self.file: str
|
|
95
|
+
self.file: Optional[str] = None
|
|
91
96
|
self.awk = False
|
|
92
97
|
self.map = False
|
|
93
98
|
self.no_print = False
|
|
@@ -252,7 +257,7 @@ def _parse_args(argv: list[str]) -> _Args:
|
|
|
252
257
|
return args
|
|
253
258
|
|
|
254
259
|
|
|
255
|
-
def _format_version(version: str, build_info: dict[str, object]
|
|
260
|
+
def _format_version(version: str, build_info: Optional[dict[str, object]]) -> str:
|
|
256
261
|
display_version = version if version.startswith("v") else f"v{version}"
|
|
257
262
|
if not build_info:
|
|
258
263
|
return display_version
|
|
@@ -277,7 +282,7 @@ def _get_version() -> str:
|
|
|
277
282
|
return version
|
|
278
283
|
|
|
279
284
|
|
|
280
|
-
def main(argv: list[str]
|
|
285
|
+
def main(argv: Optional[list[str]] = None) -> int:
|
|
281
286
|
if argv is None:
|
|
282
287
|
_install_trimmed_excepthook()
|
|
283
288
|
argv = sys.argv[1:]
|
|
@@ -356,7 +361,13 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
356
361
|
end_code=namespace.end_code,
|
|
357
362
|
)
|
|
358
363
|
builtins.compile(python_ast, _display_filename(filename), "exec")
|
|
359
|
-
|
|
364
|
+
try:
|
|
365
|
+
output = ast.unparse(python_ast)
|
|
366
|
+
except AttributeError:
|
|
367
|
+
import astunparse
|
|
368
|
+
|
|
369
|
+
output = astunparse.unparse(python_ast).rstrip("\n")
|
|
370
|
+
print(output)
|
|
360
371
|
return 0
|
|
361
372
|
|
|
362
373
|
return exec(
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
|
+
from typing import Optional
|
|
4
5
|
|
|
5
6
|
__all__ = ["install_helpers", "AutoImportDict", "AUTO_IMPORT_NAMES"]
|
|
6
7
|
|
|
7
8
|
# Names that can be auto-imported when first referenced.
|
|
8
9
|
# Maps name -> (module, attribute) where attribute is None for whole-module imports.
|
|
9
|
-
AUTO_IMPORT_NAMES: dict[str, tuple[str, str
|
|
10
|
+
AUTO_IMPORT_NAMES: dict[str, tuple[str, Optional[str]]] = {
|
|
10
11
|
# Whole module imports: import X
|
|
11
12
|
"sys": ("sys", None),
|
|
12
13
|
"os": ("os", None),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|