snail-lang 0.7.6__tar.gz → 0.7.8__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.6 → snail_lang-0.7.8}/Cargo.lock +5 -5
- {snail_lang-0.7.6 → snail_lang-0.7.8}/PKG-INFO +6 -2
- {snail_lang-0.7.6 → snail_lang-0.7.8}/README.md +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-ast/Cargo.toml +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-error/Cargo.toml +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/Cargo.toml +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/lib.rs +8 -2
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/snail.pest +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/Cargo.toml +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/awk.rs +120 -68
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/constants.rs +0 -2
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/program.rs +9 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/pyproject.toml +29 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/cli.py +15 -5
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/__init__.py +8 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/structured_accessor.py +1 -1
- {snail_lang-0.7.6 → snail_lang-0.7.8}/Cargo.toml +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/LICENSE +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-ast/README.md +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-ast/src/ast.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-ast/src/awk.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-ast/src/lib.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-error/README.md +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-error/src/lib.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/README.md +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/awk.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/expr.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/literal.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/stmt.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/string.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/src/util.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/tests/common.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/tests/errors.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/tests/parser.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/tests/statements.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/tests/syntax_expressions.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-parser/tests/syntax_strings.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/build.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/compiler.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lib.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/linecache.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/desugar.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/expr.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/helpers.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/map.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/mod.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/operators.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/py_ast.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/stmt.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/lower/validate.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/crates/snail-python/src/profiling.rs +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/__init__.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/augmented.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/compact_try.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/env.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/lazy_file.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/lazy_text.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/python/snail/runtime/regex.py +0 -0
- {snail_lang-0.7.6 → snail_lang-0.7.8}/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.8"
|
|
316
316
|
|
|
317
317
|
[[package]]
|
|
318
318
|
name = "snail-error"
|
|
319
|
-
version = "0.7.
|
|
319
|
+
version = "0.7.8"
|
|
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.8"
|
|
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.8"
|
|
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.8"
|
|
344
344
|
dependencies = [
|
|
345
345
|
"pyo3",
|
|
346
346
|
"snail-ast",
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snail-lang
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.8
|
|
4
4
|
Requires-Dist: astunparse>=1.6.3 ; python_full_version < '3.9'
|
|
5
5
|
Requires-Dist: jmespath>=1.0.1
|
|
6
6
|
Requires-Dist: maturin>=1.5 ; extra == 'dev'
|
|
7
|
+
Requires-Dist: black ; extra == 'dev'
|
|
8
|
+
Requires-Dist: isort ; extra == 'dev'
|
|
9
|
+
Requires-Dist: mypy ; extra == 'dev'
|
|
7
10
|
Requires-Dist: pytest ; extra == 'dev'
|
|
11
|
+
Requires-Dist: ruff ; extra == 'dev'
|
|
8
12
|
Provides-Extra: dev
|
|
9
13
|
License-File: LICENSE
|
|
10
14
|
Summary: Snail programming language interpreter
|
|
@@ -73,7 +77,7 @@ END { print("done") }
|
|
|
73
77
|
| `$f` | All fields as a list |
|
|
74
78
|
| `$n` | Global line number (across all files) |
|
|
75
79
|
| `$fn` | Per-file line number |
|
|
76
|
-
| `$
|
|
80
|
+
| `$src` | Current file path |
|
|
77
81
|
| `$m` | Last regex match object |
|
|
78
82
|
|
|
79
83
|
|
|
@@ -159,11 +159,14 @@ pub fn parse_awk_program_with_begin_end(
|
|
|
159
159
|
Ok(program)
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
const AWK_ONLY_NAMES: [&str;
|
|
162
|
+
const AWK_ONLY_NAMES: [&str; 4] = ["$n", "$fn", "$m", "$f"];
|
|
163
163
|
const AWK_ONLY_MESSAGE: &str = "awk variables are only valid in awk mode; use --awk";
|
|
164
164
|
|
|
165
|
-
const MAP_ONLY_NAMES: [&str;
|
|
165
|
+
const MAP_ONLY_NAMES: [&str; 2] = ["$fd", "$text"];
|
|
166
166
|
const MAP_ONLY_MESSAGE: &str = "map variables are only valid in map mode; use --map";
|
|
167
|
+
const MAP_OR_AWK_NAMES: [&str; 1] = ["$src"];
|
|
168
|
+
const MAP_OR_AWK_MESSAGE: &str =
|
|
169
|
+
"map/awk variables are only valid in map or awk mode; use --map or --awk";
|
|
167
170
|
|
|
168
171
|
/// Parses a map program that processes files one at a time.
|
|
169
172
|
/// Allows map variables ($src, $fd, $text) but rejects awk variables.
|
|
@@ -933,6 +936,9 @@ fn validate_expr(expr: &Expr, source: &str) -> Result<(), ParseError> {
|
|
|
933
936
|
if MAP_ONLY_NAMES.contains(&name.as_str()) {
|
|
934
937
|
return Err(error_with_span(MAP_ONLY_MESSAGE, span.clone(), source));
|
|
935
938
|
}
|
|
939
|
+
if MAP_OR_AWK_NAMES.contains(&name.as_str()) {
|
|
940
|
+
return Err(error_with_span(MAP_OR_AWK_MESSAGE, span.clone(), source));
|
|
941
|
+
}
|
|
936
942
|
}
|
|
937
943
|
Expr::Placeholder { .. } => {}
|
|
938
944
|
Expr::FieldIndex { span, .. } => {
|
|
@@ -259,7 +259,7 @@ none = { "None" }
|
|
|
259
259
|
// Special variables: exception, AWK fields, map vars, injected vars
|
|
260
260
|
exception_var = { "$e" ~ !ident_continue }
|
|
261
261
|
field_index_var = @{ "$" ~ ASCII_DIGIT+ }
|
|
262
|
-
injected_var = { "$text" | "$src" | "$env" | "$fn" | "$fd" | "$n" | "$
|
|
262
|
+
injected_var = { "$text" | "$src" | "$env" | "$fn" | "$fd" | "$n" | "$m" | "$f" }
|
|
263
263
|
|
|
264
264
|
// Number, string, and regex literals
|
|
265
265
|
number = @{ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
|
|
@@ -23,41 +23,27 @@ pub(crate) fn lower_awk_file_loop_with_auto_print(
|
|
|
23
23
|
span,
|
|
24
24
|
)?);
|
|
25
25
|
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
span,
|
|
38
|
-
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
39
|
-
)?,
|
|
40
|
-
"stdin".to_string().into_py(builder.py()),
|
|
26
|
+
let stdin_assign = assign_name(
|
|
27
|
+
builder,
|
|
28
|
+
"__snail_file",
|
|
29
|
+
builder
|
|
30
|
+
.call_node(
|
|
31
|
+
"Attribute",
|
|
32
|
+
vec![
|
|
33
|
+
name_expr(
|
|
34
|
+
builder,
|
|
35
|
+
"sys",
|
|
36
|
+
span,
|
|
41
37
|
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
span,
|
|
47
|
-
)?,
|
|
48
|
-
lower_awk_line_loop_with_auto_print(
|
|
49
|
-
builder,
|
|
50
|
-
program,
|
|
51
|
-
span,
|
|
52
|
-
name_expr(
|
|
53
|
-
builder,
|
|
54
|
-
"__snail_file",
|
|
38
|
+
)?,
|
|
39
|
+
"stdin".to_string().into_py(builder.py()),
|
|
40
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
41
|
+
],
|
|
55
42
|
span,
|
|
56
|
-
|
|
57
|
-
)?,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
];
|
|
43
|
+
)
|
|
44
|
+
.map_err(py_err_to_lower)?,
|
|
45
|
+
span,
|
|
46
|
+
)?;
|
|
61
47
|
|
|
62
48
|
let open_call = builder
|
|
63
49
|
.call_node(
|
|
@@ -85,46 +71,35 @@ pub(crate) fn lower_awk_file_loop_with_auto_print(
|
|
|
85
71
|
)
|
|
86
72
|
.map_err(py_err_to_lower)?;
|
|
87
73
|
|
|
88
|
-
let
|
|
89
|
-
.call_node_no_loc(
|
|
90
|
-
"withitem",
|
|
91
|
-
vec![
|
|
92
|
-
open_call,
|
|
93
|
-
name_expr(
|
|
94
|
-
builder,
|
|
95
|
-
"__snail_file",
|
|
96
|
-
span,
|
|
97
|
-
builder.store_ctx().map_err(py_err_to_lower)?,
|
|
98
|
-
)?,
|
|
99
|
-
],
|
|
100
|
-
)
|
|
101
|
-
.map_err(py_err_to_lower)?;
|
|
102
|
-
let with_stmt = builder
|
|
74
|
+
let enter_context_call = builder
|
|
103
75
|
.call_node(
|
|
104
|
-
"
|
|
76
|
+
"Call",
|
|
105
77
|
vec![
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
78
|
+
builder
|
|
79
|
+
.call_node(
|
|
80
|
+
"Attribute",
|
|
81
|
+
vec![
|
|
82
|
+
name_expr(
|
|
83
|
+
builder,
|
|
84
|
+
"__snail_stack",
|
|
85
|
+
span,
|
|
86
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
87
|
+
)?,
|
|
88
|
+
"enter_context".to_string().into_py(builder.py()),
|
|
117
89
|
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
.into_py(builder.py()),
|
|
90
|
+
],
|
|
91
|
+
span,
|
|
92
|
+
)
|
|
93
|
+
.map_err(py_err_to_lower)?,
|
|
94
|
+
PyList::new_bound(builder.py(), vec![open_call]).into_py(builder.py()),
|
|
95
|
+
PyList::empty_bound(builder.py()).into_py(builder.py()),
|
|
123
96
|
],
|
|
124
97
|
span,
|
|
125
98
|
)
|
|
126
99
|
.map_err(py_err_to_lower)?;
|
|
127
100
|
|
|
101
|
+
let file_assign = assign_name(builder, "__snail_file", enter_context_call, span)?;
|
|
102
|
+
|
|
128
103
|
let test = builder
|
|
129
104
|
.call_node(
|
|
130
105
|
"Compare",
|
|
@@ -161,14 +136,80 @@ pub(crate) fn lower_awk_file_loop_with_auto_print(
|
|
|
161
136
|
"If",
|
|
162
137
|
vec![
|
|
163
138
|
test,
|
|
164
|
-
PyList::new_bound(builder.py(),
|
|
165
|
-
PyList::new_bound(builder.py(), vec![
|
|
139
|
+
PyList::new_bound(builder.py(), vec![stdin_assign]).into_py(builder.py()),
|
|
140
|
+
PyList::new_bound(builder.py(), vec![file_assign]).into_py(builder.py()),
|
|
166
141
|
],
|
|
167
142
|
span,
|
|
168
143
|
)
|
|
169
144
|
.map_err(py_err_to_lower)?;
|
|
170
145
|
|
|
171
|
-
|
|
146
|
+
let exit_stack_call = builder
|
|
147
|
+
.call_node(
|
|
148
|
+
"Call",
|
|
149
|
+
vec![
|
|
150
|
+
builder
|
|
151
|
+
.call_node(
|
|
152
|
+
"Attribute",
|
|
153
|
+
vec![
|
|
154
|
+
name_expr(
|
|
155
|
+
builder,
|
|
156
|
+
"contextlib",
|
|
157
|
+
span,
|
|
158
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
159
|
+
)?,
|
|
160
|
+
"ExitStack".to_string().into_py(builder.py()),
|
|
161
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
162
|
+
],
|
|
163
|
+
span,
|
|
164
|
+
)
|
|
165
|
+
.map_err(py_err_to_lower)?,
|
|
166
|
+
PyList::empty_bound(builder.py()).into_py(builder.py()),
|
|
167
|
+
PyList::empty_bound(builder.py()).into_py(builder.py()),
|
|
168
|
+
],
|
|
169
|
+
span,
|
|
170
|
+
)
|
|
171
|
+
.map_err(py_err_to_lower)?;
|
|
172
|
+
|
|
173
|
+
let with_item = builder
|
|
174
|
+
.call_node_no_loc(
|
|
175
|
+
"withitem",
|
|
176
|
+
vec![
|
|
177
|
+
exit_stack_call,
|
|
178
|
+
name_expr(
|
|
179
|
+
builder,
|
|
180
|
+
"__snail_stack",
|
|
181
|
+
span,
|
|
182
|
+
builder.store_ctx().map_err(py_err_to_lower)?,
|
|
183
|
+
)?,
|
|
184
|
+
],
|
|
185
|
+
)
|
|
186
|
+
.map_err(py_err_to_lower)?;
|
|
187
|
+
|
|
188
|
+
let line_loop = lower_awk_line_loop_with_auto_print(
|
|
189
|
+
builder,
|
|
190
|
+
program,
|
|
191
|
+
span,
|
|
192
|
+
name_expr(
|
|
193
|
+
builder,
|
|
194
|
+
"__snail_file",
|
|
195
|
+
span,
|
|
196
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
197
|
+
)?,
|
|
198
|
+
auto_print,
|
|
199
|
+
)?;
|
|
200
|
+
|
|
201
|
+
let with_stmt = builder
|
|
202
|
+
.call_node(
|
|
203
|
+
"With",
|
|
204
|
+
vec![
|
|
205
|
+
PyList::new_bound(builder.py(), vec![with_item]).into_py(builder.py()),
|
|
206
|
+
PyList::new_bound(builder.py(), vec![if_stmt, line_loop]).into_py(builder.py()),
|
|
207
|
+
],
|
|
208
|
+
span,
|
|
209
|
+
)
|
|
210
|
+
.map_err(py_err_to_lower)?;
|
|
211
|
+
|
|
212
|
+
file_loop.push(with_stmt);
|
|
172
213
|
Ok(file_loop)
|
|
173
214
|
}
|
|
174
215
|
|
|
@@ -344,6 +385,17 @@ pub(crate) fn lower_awk_line_loop_with_auto_print(
|
|
|
344
385
|
)?,
|
|
345
386
|
span,
|
|
346
387
|
)?);
|
|
388
|
+
loop_body.push(assign_name(
|
|
389
|
+
builder,
|
|
390
|
+
SNAIL_MAP_SRC_PYVAR,
|
|
391
|
+
name_expr(
|
|
392
|
+
builder,
|
|
393
|
+
"__snail_path",
|
|
394
|
+
span,
|
|
395
|
+
builder.load_ctx().map_err(py_err_to_lower)?,
|
|
396
|
+
)?,
|
|
397
|
+
span,
|
|
398
|
+
)?);
|
|
347
399
|
|
|
348
400
|
loop_body.extend(lower_awk_rules_with_auto_print(
|
|
349
401
|
builder,
|
|
@@ -24,7 +24,6 @@ pub(crate) const SNAIL_INCR_TMP: &str = "__snail_incr_tmp";
|
|
|
24
24
|
// Awk-related constants (public within crate)
|
|
25
25
|
pub(crate) const SNAIL_AWK_NR: &str = "$n";
|
|
26
26
|
pub(crate) const SNAIL_AWK_FNR: &str = "$fn";
|
|
27
|
-
pub(crate) const SNAIL_AWK_PATH: &str = "$p";
|
|
28
27
|
pub(crate) const SNAIL_AWK_MATCH: &str = "$m";
|
|
29
28
|
pub(crate) const SNAIL_AWK_FIELDS: &str = "$f";
|
|
30
29
|
pub(crate) const SNAIL_AWK_LINE_PYVAR: &str = "__snail_line";
|
|
@@ -53,7 +52,6 @@ pub(crate) fn injected_py_name(name: &str) -> Option<&'static str> {
|
|
|
53
52
|
// Awk variables
|
|
54
53
|
SNAIL_AWK_NR => Some(SNAIL_AWK_NR_PYVAR),
|
|
55
54
|
SNAIL_AWK_FNR => Some(SNAIL_AWK_FNR_PYVAR),
|
|
56
|
-
SNAIL_AWK_PATH => Some(SNAIL_AWK_PATH_PYVAR),
|
|
57
55
|
SNAIL_AWK_MATCH => Some(SNAIL_AWK_MATCH_PYVAR),
|
|
58
56
|
SNAIL_AWK_FIELDS => Some(SNAIL_AWK_FIELDS_PYVAR),
|
|
59
57
|
// Map variables
|
|
@@ -98,6 +98,15 @@ pub fn lower_awk_program_with_auto_print(
|
|
|
98
98
|
],
|
|
99
99
|
)
|
|
100
100
|
.map_err(py_err_to_lower)?,
|
|
101
|
+
builder
|
|
102
|
+
.call_node_no_loc(
|
|
103
|
+
"alias",
|
|
104
|
+
vec![
|
|
105
|
+
"contextlib".to_string().into_py(builder.py()),
|
|
106
|
+
builder.py().None().into_py(builder.py()),
|
|
107
|
+
],
|
|
108
|
+
)
|
|
109
|
+
.map_err(py_err_to_lower)?,
|
|
101
110
|
],
|
|
102
111
|
)
|
|
103
112
|
.into_py(builder.py()),
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "snail-lang"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.8"
|
|
8
8
|
description = "Snail programming language interpreter"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -17,7 +17,11 @@ dependencies = [
|
|
|
17
17
|
[project.optional-dependencies]
|
|
18
18
|
dev = [
|
|
19
19
|
"maturin>=1.5",
|
|
20
|
+
"black",
|
|
21
|
+
"isort",
|
|
22
|
+
"mypy",
|
|
20
23
|
"pytest",
|
|
24
|
+
"ruff",
|
|
21
25
|
]
|
|
22
26
|
|
|
23
27
|
[project.scripts]
|
|
@@ -28,3 +32,27 @@ bindings = "pyo3"
|
|
|
28
32
|
python-source = "python"
|
|
29
33
|
module-name = "snail._native"
|
|
30
34
|
manifest-path = "crates/snail-python/Cargo.toml"
|
|
35
|
+
|
|
36
|
+
[tool.black]
|
|
37
|
+
line-length = 88
|
|
38
|
+
target-version = ["py38"]
|
|
39
|
+
|
|
40
|
+
[tool.isort]
|
|
41
|
+
profile = "black"
|
|
42
|
+
line_length = 88
|
|
43
|
+
src_paths = ["python"]
|
|
44
|
+
|
|
45
|
+
[tool.ruff]
|
|
46
|
+
line-length = 88
|
|
47
|
+
target-version = "py38"
|
|
48
|
+
src = ["python"]
|
|
49
|
+
exclude = ["target", ".venv", "build", "dist"]
|
|
50
|
+
|
|
51
|
+
[tool.mypy]
|
|
52
|
+
python_version = "3.12"
|
|
53
|
+
show_error_codes = true
|
|
54
|
+
warn_unused_ignores = true
|
|
55
|
+
|
|
56
|
+
[[tool.mypy.overrides]]
|
|
57
|
+
module = ["snail._native"]
|
|
58
|
+
ignore_missing_imports = true
|
|
@@ -2,7 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
|
-
from
|
|
5
|
+
from types import TracebackType
|
|
6
|
+
from typing import Any, Iterable, Optional, cast
|
|
6
7
|
|
|
7
8
|
from . import __build_info__, compile_ast, exec
|
|
8
9
|
|
|
@@ -58,7 +59,7 @@ def _install_trimmed_excepthook() -> None:
|
|
|
58
59
|
def _snail_excepthook(
|
|
59
60
|
exc_type: type[BaseException],
|
|
60
61
|
exc: BaseException,
|
|
61
|
-
tb:
|
|
62
|
+
tb: TracebackType | None,
|
|
62
63
|
) -> None:
|
|
63
64
|
if exc_type is KeyboardInterrupt:
|
|
64
65
|
return original_excepthook(exc_type, exc, tb)
|
|
@@ -72,13 +73,13 @@ def _install_trimmed_excepthook() -> None:
|
|
|
72
73
|
)
|
|
73
74
|
_trim_traceback_exception(tb_exc, internal_files)
|
|
74
75
|
try:
|
|
75
|
-
import _colorize
|
|
76
|
+
import _colorize # type: ignore[import-not-found]
|
|
76
77
|
|
|
77
78
|
colorize = _colorize.can_colorize(file=sys.stderr)
|
|
78
79
|
except Exception:
|
|
79
80
|
colorize = hasattr(sys.stderr, "isatty") and sys.stderr.isatty()
|
|
80
81
|
try:
|
|
81
|
-
formatted = tb_exc.format(colorize=colorize)
|
|
82
|
+
formatted = cast(Iterable[str], cast(Any, tb_exc).format(colorize=colorize))
|
|
82
83
|
except TypeError:
|
|
83
84
|
formatted = tb_exc.format()
|
|
84
85
|
for line in formatted:
|
|
@@ -407,12 +408,21 @@ def main(argv: Optional[list[str]] = None) -> int:
|
|
|
407
408
|
try:
|
|
408
409
|
output = ast.unparse(python_ast)
|
|
409
410
|
except AttributeError:
|
|
410
|
-
import astunparse
|
|
411
|
+
import astunparse # type: ignore[import-not-found]
|
|
411
412
|
|
|
412
413
|
output = astunparse.unparse(python_ast).rstrip("\n")
|
|
413
414
|
print(output)
|
|
414
415
|
return 0
|
|
415
416
|
|
|
417
|
+
if mode == "awk" and not args[1:]:
|
|
418
|
+
try:
|
|
419
|
+
is_tty = sys.stdin.isatty()
|
|
420
|
+
except Exception:
|
|
421
|
+
is_tty = False
|
|
422
|
+
if is_tty:
|
|
423
|
+
print('Missing input (see "snail --help")', file=sys.stderr)
|
|
424
|
+
return 1
|
|
425
|
+
|
|
416
426
|
separators = "".join(namespace.field_separators)
|
|
417
427
|
field_separators = separators if separators else None
|
|
418
428
|
include_whitespace = namespace.include_whitespace or field_separators is None
|
|
@@ -223,7 +223,9 @@ def _lazy_aug_index(obj, index, value, op: str):
|
|
|
223
223
|
return _get_aug_index()(obj, index, value, op)
|
|
224
224
|
|
|
225
225
|
|
|
226
|
-
def
|
|
226
|
+
def __snail_awk_split_internal(
|
|
227
|
+
line: str, separators: Optional[str], include_whitespace: bool
|
|
228
|
+
):
|
|
227
229
|
if not separators:
|
|
228
230
|
return line.split()
|
|
229
231
|
if not include_whitespace:
|
|
@@ -245,6 +247,11 @@ def __snail_awk_split(line: str, separators: Optional[str], include_whitespace:
|
|
|
245
247
|
return regex.split(stripped)
|
|
246
248
|
|
|
247
249
|
|
|
250
|
+
def __snail_awk_split(line: str, separators: Optional[str], include_whitespace: bool):
|
|
251
|
+
fields = __snail_awk_split_internal(line, separators, include_whitespace)
|
|
252
|
+
return [f for f in fields if f]
|
|
253
|
+
|
|
254
|
+
|
|
248
255
|
def __snail_partial(func, /, *args, **kwargs):
|
|
249
256
|
import functools
|
|
250
257
|
|
|
@@ -100,7 +100,7 @@ def __snail_jmespath_query(query: str):
|
|
|
100
100
|
Used by the $[query] syntax which lowers to __snail_jmespath_query(query).
|
|
101
101
|
"""
|
|
102
102
|
|
|
103
|
-
import jmespath as _jmespath
|
|
103
|
+
import jmespath as _jmespath # type: ignore[import-untyped]
|
|
104
104
|
|
|
105
105
|
transpiled = _transpile_jmespath_query(query)
|
|
106
106
|
|
|
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
|