shellsim 0.1.8__tar.gz → 0.1.10__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.
- {shellsim-0.1.8 → shellsim-0.1.10}/Cargo.lock +1 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/Cargo.toml +1 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/PKG-INFO +1 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/python/native/Cargo.lock +2 -2
- {shellsim-0.1.8 → shellsim-0.1.10}/python/native/Cargo.toml +1 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/ast.rs +17 -3
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/bytecode.rs +13 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/compiler.rs +223 -10
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/heap.rs +8 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/lexer.rs +2 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/mod.rs +444 -28
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/native.rs +10 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/object_model.rs +4 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/parser.rs +47 -9
- shellsim-0.1.10/src/python/stdlib/asyncio.rs +47 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/core.rs +45 -2
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/frozen.rs +2 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/mod.rs +3 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/pytest.rs +4 -4
- shellsim-0.1.10/src/python/stdlib/source/asyncio.py +364 -0
- shellsim-0.1.10/src/python/stdlib/source/pytest.py +36 -0
- shellsim-0.1.10/src/python/stdlib/typing.rs +136 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/token.rs +2 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/calls.rs +2 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/dispatch.rs +65 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/iteration.rs +27 -4
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/namespace.rs +10 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/native_runtime.rs +99 -1
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/objects.rs +26 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm.rs +4 -0
- shellsim-0.1.8/src/python/stdlib/typing.rs +0 -45
- {shellsim-0.1.8 → shellsim-0.1.10}/LICENSE +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/README.md +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/pyproject.toml +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/native/src/lib.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/shellsim/__init__.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/shellsim/__main__.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/shellsim/_api.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/shellsim/_cli.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/shellsim/py.typed +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/python/shellsim/python.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/rust-toolchain.toml +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/bin/shellsim-python.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/clock.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/archives.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/awk/ast.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/awk/eval.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/awk/lexer.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/awk/parser.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/awk.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/builtins.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/dd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/echo.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/find.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/fs.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/apply.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/commit.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/compare.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/config.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/conflict.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/diff.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/ignore.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/import.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/log.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/merge.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/mod.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/plumbing.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/rebase.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/refs.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/repo.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/stash.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/switch.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/git/worktree.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/hashing.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/makecmd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/mod.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/net.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/options.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/patch.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/pkg.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/printf.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/proc.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/regex_compat.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/rgcmd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/sed.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/sort.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/system.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/tarcmd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/text.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/unavailable.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/util.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/commands/zipcmd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/descriptors.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/exec.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/expand.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/harness.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/harness_manager.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/hashes.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/host_ingest.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/interp.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/jqcmd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/lib.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/main.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/mcp.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/net.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/netcmd.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/process.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/pseudo_fs.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/filesystem.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/http.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/mapping.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/number.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/process.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/protocol.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/slice.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/source.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/argparse.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/base64.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/bisect.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/collections.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/dataclasses.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/enum.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/functools.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/hashlib.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/heapq.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/http.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/importlib.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/itertools.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/json.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/math.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/numpy.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/os.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/re.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/abc.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/base64.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/cmath.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/codecs.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/collections.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/complex.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/copy.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/csv.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/datetime.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/glob.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/hashlib.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/http.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/http_client.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/importlib.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/io.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/json.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/logging.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/numpy_random.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/os.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/pathlib.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/random.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/shutil.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/statistics.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/struct.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/subprocess.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/tempfile.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/textwrap.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/urllib.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/urllib_error.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/urllib_request.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/uuid.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/zipfile.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/source/zlib.py +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/string.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/struct.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/subprocess.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/sys.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/time.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/unittest.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/vfs.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/stdlib/zlib.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/string.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/host.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/python/vm/operations.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/resources.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/sandbox.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/scenario.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/scheduler.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/shell.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/telemetry.rs +0 -0
- {shellsim-0.1.8 → shellsim-0.1.10}/src/vfs.rs +0 -0
|
@@ -406,7 +406,7 @@ dependencies = [
|
|
|
406
406
|
|
|
407
407
|
[[package]]
|
|
408
408
|
name = "shellsim"
|
|
409
|
-
version = "0.1.
|
|
409
|
+
version = "0.1.10"
|
|
410
410
|
dependencies = [
|
|
411
411
|
"base64",
|
|
412
412
|
"crc32fast",
|
|
@@ -427,7 +427,7 @@ dependencies = [
|
|
|
427
427
|
|
|
428
428
|
[[package]]
|
|
429
429
|
name = "shellsim-python-bindings"
|
|
430
|
-
version = "0.1.
|
|
430
|
+
version = "0.1.10"
|
|
431
431
|
dependencies = [
|
|
432
432
|
"pyo3",
|
|
433
433
|
"serde",
|
|
@@ -50,10 +50,17 @@ pub enum StatementKind {
|
|
|
50
50
|
body: Vec<Statement>,
|
|
51
51
|
otherwise: Vec<Statement>,
|
|
52
52
|
},
|
|
53
|
+
AsyncFor {
|
|
54
|
+
target: AssignmentTarget,
|
|
55
|
+
iterable: Expression,
|
|
56
|
+
body: Vec<Statement>,
|
|
57
|
+
otherwise: Vec<Statement>,
|
|
58
|
+
},
|
|
53
59
|
Function {
|
|
54
60
|
name: String,
|
|
55
61
|
parameters: Vec<Parameter>,
|
|
56
62
|
body: Vec<Statement>,
|
|
63
|
+
is_async: bool,
|
|
57
64
|
},
|
|
58
65
|
Class {
|
|
59
66
|
name: String,
|
|
@@ -91,6 +98,11 @@ pub enum StatementKind {
|
|
|
91
98
|
target: Option<AssignmentTarget>,
|
|
92
99
|
body: Vec<Statement>,
|
|
93
100
|
},
|
|
101
|
+
AsyncWith {
|
|
102
|
+
context: Expression,
|
|
103
|
+
target: Option<AssignmentTarget>,
|
|
104
|
+
body: Vec<Statement>,
|
|
105
|
+
},
|
|
94
106
|
}
|
|
95
107
|
|
|
96
108
|
#[derive(Clone, Debug, PartialEq)]
|
|
@@ -122,11 +134,13 @@ impl StatementKind {
|
|
|
122
134
|
Self::If { .. }
|
|
123
135
|
| Self::While { .. }
|
|
124
136
|
| Self::For { .. }
|
|
137
|
+
| Self::AsyncFor { .. }
|
|
125
138
|
| Self::Function { .. }
|
|
126
139
|
| Self::Class { .. }
|
|
127
140
|
| Self::Decorated { .. }
|
|
128
141
|
| Self::Try { .. }
|
|
129
142
|
| Self::With { .. }
|
|
143
|
+
| Self::AsyncWith { .. }
|
|
130
144
|
)
|
|
131
145
|
}
|
|
132
146
|
}
|
|
@@ -173,14 +187,14 @@ pub enum ExpressionKind {
|
|
|
173
187
|
value: Box<Expression>,
|
|
174
188
|
clauses: Vec<ComprehensionClause>,
|
|
175
189
|
},
|
|
176
|
-
///
|
|
177
|
-
/// generator expressions an ordinary iterable and isolated comprehension
|
|
178
|
-
/// scope while keeping the bounded-resource contract simple and explicit.
|
|
190
|
+
/// A lazy comprehension evaluated in its own generator frame.
|
|
179
191
|
GeneratorExpression {
|
|
180
192
|
element: Box<Expression>,
|
|
181
193
|
clauses: Vec<ComprehensionClause>,
|
|
182
194
|
},
|
|
183
195
|
Yield(Option<Box<Expression>>),
|
|
196
|
+
YieldFrom(Box<Expression>),
|
|
197
|
+
Await(Box<Expression>),
|
|
184
198
|
Attribute {
|
|
185
199
|
value: Box<Expression>,
|
|
186
200
|
name: String,
|
|
@@ -65,6 +65,7 @@ pub struct Code {
|
|
|
65
65
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
66
66
|
pub struct CallSignature {
|
|
67
67
|
pub is_generator: bool,
|
|
68
|
+
pub is_coroutine: bool,
|
|
68
69
|
pub positional_count: usize,
|
|
69
70
|
pub variadic_slot: Option<usize>,
|
|
70
71
|
pub default_slots: Box<[usize]>,
|
|
@@ -223,9 +224,12 @@ pub enum Opcode {
|
|
|
223
224
|
Reraise,
|
|
224
225
|
Raise(bool),
|
|
225
226
|
Yield,
|
|
227
|
+
AwaitResult,
|
|
226
228
|
WithEnter,
|
|
227
229
|
WithExit,
|
|
228
230
|
WithExitException,
|
|
231
|
+
AsyncWithExitException,
|
|
232
|
+
AsyncWithFinishException,
|
|
229
233
|
PopExpression,
|
|
230
234
|
Halt,
|
|
231
235
|
}
|
|
@@ -321,9 +325,13 @@ pub enum Operation {
|
|
|
321
325
|
Raise(bool),
|
|
322
326
|
/// Suspend a generator frame and return the value on top of the stack.
|
|
323
327
|
Yield,
|
|
328
|
+
/// Unwrap the scheduler outcome sent into a suspended coroutine.
|
|
329
|
+
AwaitResult,
|
|
324
330
|
WithEnter,
|
|
325
331
|
WithExit,
|
|
326
332
|
WithExitException,
|
|
333
|
+
AsyncWithExitException,
|
|
334
|
+
AsyncWithFinishException,
|
|
327
335
|
PopExpression,
|
|
328
336
|
Halt,
|
|
329
337
|
}
|
|
@@ -489,9 +497,12 @@ impl CodeBuilder {
|
|
|
489
497
|
Operation::Reraise => Opcode::Reraise,
|
|
490
498
|
Operation::Raise(cause) => Opcode::Raise(cause),
|
|
491
499
|
Operation::Yield => Opcode::Yield,
|
|
500
|
+
Operation::AwaitResult => Opcode::AwaitResult,
|
|
492
501
|
Operation::WithEnter => Opcode::WithEnter,
|
|
493
502
|
Operation::WithExit => Opcode::WithExit,
|
|
494
503
|
Operation::WithExitException => Opcode::WithExitException,
|
|
504
|
+
Operation::AsyncWithExitException => Opcode::AsyncWithExitException,
|
|
505
|
+
Operation::AsyncWithFinishException => Opcode::AsyncWithFinishException,
|
|
495
506
|
Operation::PopExpression => Opcode::PopExpression,
|
|
496
507
|
Operation::Halt => Opcode::Halt,
|
|
497
508
|
}
|
|
@@ -503,6 +514,7 @@ impl CodeBuilder {
|
|
|
503
514
|
spans: Vec<Span>,
|
|
504
515
|
parameters: Vec<Parameter>,
|
|
505
516
|
local_names: Vec<String>,
|
|
517
|
+
is_coroutine: bool,
|
|
506
518
|
) -> CodeRef {
|
|
507
519
|
let positional_count = parameters
|
|
508
520
|
.iter()
|
|
@@ -512,6 +524,7 @@ impl CodeBuilder {
|
|
|
512
524
|
is_generator: instructions
|
|
513
525
|
.iter()
|
|
514
526
|
.any(|instruction| matches!(instruction.opcode, Opcode::Yield)),
|
|
527
|
+
is_coroutine,
|
|
515
528
|
positional_count,
|
|
516
529
|
variadic_slot: parameters.iter().position(|parameter| parameter.variadic),
|
|
517
530
|
default_slots: parameters
|
|
@@ -15,6 +15,7 @@ pub fn compile(program: Program) -> CodeRef {
|
|
|
15
15
|
finalizers: Vec::new(),
|
|
16
16
|
protected_regions: Vec::new(),
|
|
17
17
|
in_function: false,
|
|
18
|
+
is_coroutine: false,
|
|
18
19
|
globals: HashSet::new(),
|
|
19
20
|
nonlocals: HashSet::new(),
|
|
20
21
|
named_expression: NamedExpressionContext::local(),
|
|
@@ -38,6 +39,7 @@ struct Compiler {
|
|
|
38
39
|
/// at compile time rather than losing that state in a suspended generator.
|
|
39
40
|
protected_regions: Vec<&'static str>,
|
|
40
41
|
in_function: bool,
|
|
42
|
+
is_coroutine: bool,
|
|
41
43
|
globals: HashSet<String>,
|
|
42
44
|
nonlocals: HashSet<String>,
|
|
43
45
|
named_expression: NamedExpressionContext,
|
|
@@ -155,7 +157,7 @@ impl Compiler {
|
|
|
155
157
|
});
|
|
156
158
|
spans.push(instruction.span);
|
|
157
159
|
}
|
|
158
|
-
builder.finish(bytecode, spans, parameters, local_names)
|
|
160
|
+
builder.finish(bytecode, spans, parameters, local_names, self.is_coroutine)
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
fn statements(&mut self, statements: Vec<Statement>) {
|
|
@@ -320,10 +322,70 @@ impl Compiler {
|
|
|
320
322
|
let finished = self.instructions.len();
|
|
321
323
|
self.finish_loop(finished);
|
|
322
324
|
}
|
|
325
|
+
StatementKind::AsyncFor {
|
|
326
|
+
target,
|
|
327
|
+
iterable,
|
|
328
|
+
body,
|
|
329
|
+
otherwise,
|
|
330
|
+
} => {
|
|
331
|
+
let iterator_name =
|
|
332
|
+
format!("$__shellsim_async_iterator_{}", self.instructions.len());
|
|
333
|
+
self.expression(iterable);
|
|
334
|
+
self.emit(Operation::LoadAttribute("__aiter__".into()), span);
|
|
335
|
+
self.emit(
|
|
336
|
+
Operation::Call {
|
|
337
|
+
positional: 0,
|
|
338
|
+
keywords: Vec::new(),
|
|
339
|
+
starred: Vec::new(),
|
|
340
|
+
},
|
|
341
|
+
span,
|
|
342
|
+
);
|
|
343
|
+
self.emit(Operation::StoreName(iterator_name.clone()), span);
|
|
344
|
+
let next = self.instructions.len();
|
|
345
|
+
let begin = self.emit(Operation::TryBegin(usize::MAX), span);
|
|
346
|
+
self.emit(Operation::LoadName(iterator_name), span);
|
|
347
|
+
self.emit(Operation::LoadAttribute("__anext__".into()), span);
|
|
348
|
+
self.emit(
|
|
349
|
+
Operation::Call {
|
|
350
|
+
positional: 0,
|
|
351
|
+
keywords: Vec::new(),
|
|
352
|
+
starred: Vec::new(),
|
|
353
|
+
},
|
|
354
|
+
span,
|
|
355
|
+
);
|
|
356
|
+
self.emit(Operation::Yield, span);
|
|
357
|
+
self.emit(Operation::AwaitResult, span);
|
|
358
|
+
self.emit(Operation::TryEnd, span);
|
|
359
|
+
self.store_target(target, span);
|
|
360
|
+
self.loops.push(LoopContext {
|
|
361
|
+
continue_target: next,
|
|
362
|
+
iterator_on_stack: false,
|
|
363
|
+
finalizer_depth: self.finalizers.len(),
|
|
364
|
+
breaks: Vec::new(),
|
|
365
|
+
});
|
|
366
|
+
self.statements(body);
|
|
367
|
+
self.emit(Operation::Jump(next), span);
|
|
368
|
+
let handler = self.instructions.len();
|
|
369
|
+
self.patch_try_begin(begin, handler);
|
|
370
|
+
self.emit(Operation::LoadName("StopAsyncIteration".into()), span);
|
|
371
|
+
self.emit(Operation::MatchException { typed: true }, span);
|
|
372
|
+
let rethrow = self.emit(Operation::PopJumpIfFalse(usize::MAX), span);
|
|
373
|
+
self.emit(Operation::PopTop, span);
|
|
374
|
+
self.emit(Operation::ClearException, span);
|
|
375
|
+
self.statements(otherwise);
|
|
376
|
+
let done = self.emit(Operation::Jump(usize::MAX), span);
|
|
377
|
+
self.patch_jump(rethrow, self.instructions.len());
|
|
378
|
+
self.emit(Operation::PopTop, span);
|
|
379
|
+
self.emit(Operation::Reraise, span);
|
|
380
|
+
let finished = self.instructions.len();
|
|
381
|
+
self.patch_jump(done, finished);
|
|
382
|
+
self.finish_loop(finished);
|
|
383
|
+
}
|
|
323
384
|
StatementKind::Function {
|
|
324
385
|
name,
|
|
325
386
|
parameters,
|
|
326
387
|
body,
|
|
388
|
+
is_async,
|
|
327
389
|
} => {
|
|
328
390
|
let defaults = parameters
|
|
329
391
|
.iter()
|
|
@@ -338,6 +400,7 @@ impl Compiler {
|
|
|
338
400
|
finalizers: Vec::new(),
|
|
339
401
|
protected_regions: Vec::new(),
|
|
340
402
|
in_function: true,
|
|
403
|
+
is_coroutine: is_async,
|
|
341
404
|
globals: HashSet::new(),
|
|
342
405
|
nonlocals: HashSet::new(),
|
|
343
406
|
named_expression: NamedExpressionContext::local(),
|
|
@@ -391,6 +454,7 @@ impl Compiler {
|
|
|
391
454
|
finalizers: Vec::new(),
|
|
392
455
|
protected_regions: Vec::new(),
|
|
393
456
|
in_function: false,
|
|
457
|
+
is_coroutine: false,
|
|
394
458
|
globals: HashSet::new(),
|
|
395
459
|
nonlocals: HashSet::new(),
|
|
396
460
|
named_expression: NamedExpressionContext::local(),
|
|
@@ -660,6 +724,60 @@ impl Compiler {
|
|
|
660
724
|
self.emit(Operation::WithExitException, span);
|
|
661
725
|
self.patch_jump(done, self.instructions.len());
|
|
662
726
|
}
|
|
727
|
+
StatementKind::AsyncWith {
|
|
728
|
+
context,
|
|
729
|
+
target,
|
|
730
|
+
body,
|
|
731
|
+
} => {
|
|
732
|
+
let context_name = format!("$__shellsim_async_context_{}", self.instructions.len());
|
|
733
|
+
self.expression(context);
|
|
734
|
+
self.emit(Operation::StoreName(context_name.clone()), span);
|
|
735
|
+
self.emit(Operation::LoadName(context_name.clone()), span);
|
|
736
|
+
self.emit(Operation::LoadAttribute("__aenter__".into()), span);
|
|
737
|
+
self.emit(
|
|
738
|
+
Operation::Call {
|
|
739
|
+
positional: 0,
|
|
740
|
+
keywords: Vec::new(),
|
|
741
|
+
starred: Vec::new(),
|
|
742
|
+
},
|
|
743
|
+
span,
|
|
744
|
+
);
|
|
745
|
+
self.emit(Operation::Yield, span);
|
|
746
|
+
self.emit(Operation::AwaitResult, span);
|
|
747
|
+
if let Some(target) = target {
|
|
748
|
+
self.store_target(target, span);
|
|
749
|
+
} else {
|
|
750
|
+
self.emit(Operation::PopTop, span);
|
|
751
|
+
}
|
|
752
|
+
let begin = self.emit(Operation::TryBegin(usize::MAX), span);
|
|
753
|
+
self.statements(body);
|
|
754
|
+
self.emit(Operation::TryEnd, span);
|
|
755
|
+
self.emit(Operation::LoadName(context_name.clone()), span);
|
|
756
|
+
self.emit(Operation::LoadAttribute("__aexit__".into()), span);
|
|
757
|
+
for _ in 0..3 {
|
|
758
|
+
self.emit(Operation::LoadConstant(Constant::None), span);
|
|
759
|
+
}
|
|
760
|
+
self.emit(
|
|
761
|
+
Operation::Call {
|
|
762
|
+
positional: 3,
|
|
763
|
+
keywords: Vec::new(),
|
|
764
|
+
starred: vec![false; 3],
|
|
765
|
+
},
|
|
766
|
+
span,
|
|
767
|
+
);
|
|
768
|
+
self.emit(Operation::Yield, span);
|
|
769
|
+
self.emit(Operation::AwaitResult, span);
|
|
770
|
+
self.emit(Operation::PopTop, span);
|
|
771
|
+
let done = self.emit(Operation::Jump(usize::MAX), span);
|
|
772
|
+
let handler = self.instructions.len();
|
|
773
|
+
self.patch_try_begin(begin, handler);
|
|
774
|
+
self.emit(Operation::LoadName(context_name), span);
|
|
775
|
+
self.emit(Operation::AsyncWithExitException, span);
|
|
776
|
+
self.emit(Operation::Yield, span);
|
|
777
|
+
self.emit(Operation::AwaitResult, span);
|
|
778
|
+
self.emit(Operation::AsyncWithFinishException, span);
|
|
779
|
+
self.patch_jump(done, self.instructions.len());
|
|
780
|
+
}
|
|
663
781
|
}
|
|
664
782
|
}
|
|
665
783
|
|
|
@@ -936,10 +1054,7 @@ impl Compiler {
|
|
|
936
1054
|
self.emit_dict_comprehension(*key, *value, clauses, span);
|
|
937
1055
|
}
|
|
938
1056
|
ExpressionKind::GeneratorExpression { element, clauses } => {
|
|
939
|
-
|
|
940
|
-
// It is still a separate function scope (like CPython's generator frame), and
|
|
941
|
-
// all iteration remains metered by the ordinary bytecode loop.
|
|
942
|
-
self.emit_comprehension(ComprehensionKind::List, *element, clauses, span);
|
|
1057
|
+
self.emit_generator_expression(*element, clauses, span);
|
|
943
1058
|
}
|
|
944
1059
|
ExpressionKind::Yield(value) => {
|
|
945
1060
|
if !self.in_function {
|
|
@@ -947,11 +1062,6 @@ impl Compiler {
|
|
|
947
1062
|
Operation::RuntimeError("'yield' outside function".into()),
|
|
948
1063
|
span,
|
|
949
1064
|
);
|
|
950
|
-
} else if let Some(region) = self.protected_regions.last() {
|
|
951
|
-
self.emit(
|
|
952
|
-
Operation::RuntimeError(format!("yield is not supported inside a {region} cleanup region; suspending here would lose exception or context-manager state")),
|
|
953
|
-
span,
|
|
954
|
-
);
|
|
955
1065
|
} else {
|
|
956
1066
|
if let Some(value) = value {
|
|
957
1067
|
self.expression(*value);
|
|
@@ -961,6 +1071,36 @@ impl Compiler {
|
|
|
961
1071
|
self.emit(Operation::Yield, span);
|
|
962
1072
|
}
|
|
963
1073
|
}
|
|
1074
|
+
ExpressionKind::YieldFrom(value) => {
|
|
1075
|
+
if !self.in_function {
|
|
1076
|
+
self.emit(
|
|
1077
|
+
Operation::RuntimeError("'yield from' outside function".into()),
|
|
1078
|
+
span,
|
|
1079
|
+
);
|
|
1080
|
+
} else {
|
|
1081
|
+
self.expression(*value);
|
|
1082
|
+
self.emit(Operation::GetIterator, span);
|
|
1083
|
+
let next = self.emit(Operation::ForIterator(usize::MAX), span);
|
|
1084
|
+
self.emit(Operation::Yield, span);
|
|
1085
|
+
self.emit(Operation::PopTop, span);
|
|
1086
|
+
self.emit(Operation::Jump(next), span);
|
|
1087
|
+
let exhausted = self.instructions.len();
|
|
1088
|
+
self.patch_jump(next, exhausted);
|
|
1089
|
+
self.emit(Operation::LoadConstant(Constant::None), span);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
ExpressionKind::Await(value) => {
|
|
1093
|
+
if !self.is_coroutine {
|
|
1094
|
+
self.emit(
|
|
1095
|
+
Operation::RuntimeError("'await' outside async function".into()),
|
|
1096
|
+
span,
|
|
1097
|
+
);
|
|
1098
|
+
} else {
|
|
1099
|
+
self.expression(*value);
|
|
1100
|
+
self.emit(Operation::Yield, span);
|
|
1101
|
+
self.emit(Operation::AwaitResult, span);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
964
1104
|
ExpressionKind::Attribute { value, name } => {
|
|
965
1105
|
self.expression(*value);
|
|
966
1106
|
self.emit(Operation::LoadAttribute(name), span);
|
|
@@ -1032,6 +1172,7 @@ impl Compiler {
|
|
|
1032
1172
|
finalizers: Vec::new(),
|
|
1033
1173
|
protected_regions: Vec::new(),
|
|
1034
1174
|
in_function: true,
|
|
1175
|
+
is_coroutine: false,
|
|
1035
1176
|
globals: HashSet::new(),
|
|
1036
1177
|
nonlocals: HashSet::new(),
|
|
1037
1178
|
named_expression: NamedExpressionContext::local(),
|
|
@@ -1180,6 +1321,7 @@ impl Compiler {
|
|
|
1180
1321
|
finalizers: Vec::new(),
|
|
1181
1322
|
protected_regions: Vec::new(),
|
|
1182
1323
|
in_function: true,
|
|
1324
|
+
is_coroutine: false,
|
|
1183
1325
|
globals: HashSet::new(),
|
|
1184
1326
|
nonlocals: HashSet::new(),
|
|
1185
1327
|
named_expression,
|
|
@@ -1216,6 +1358,47 @@ impl Compiler {
|
|
|
1216
1358
|
);
|
|
1217
1359
|
}
|
|
1218
1360
|
|
|
1361
|
+
fn emit_generator_expression(
|
|
1362
|
+
&mut self,
|
|
1363
|
+
element: Expression,
|
|
1364
|
+
clauses: Vec<ComprehensionClause>,
|
|
1365
|
+
span: Span,
|
|
1366
|
+
) {
|
|
1367
|
+
let named_expression = self.comprehension_named_expression_context();
|
|
1368
|
+
let mut nested = Compiler {
|
|
1369
|
+
instructions: Vec::new(),
|
|
1370
|
+
loops: Vec::new(),
|
|
1371
|
+
finalizers: Vec::new(),
|
|
1372
|
+
protected_regions: Vec::new(),
|
|
1373
|
+
in_function: true,
|
|
1374
|
+
is_coroutine: false,
|
|
1375
|
+
globals: HashSet::new(),
|
|
1376
|
+
nonlocals: HashSet::new(),
|
|
1377
|
+
named_expression,
|
|
1378
|
+
is_class_scope: false,
|
|
1379
|
+
structural_depth: self.structural_depth,
|
|
1380
|
+
};
|
|
1381
|
+
nested.emit_generator_comprehension_body(&clauses, 0, &element, span);
|
|
1382
|
+
nested.emit(Operation::LoadConstant(Constant::None), span);
|
|
1383
|
+
nested.emit(Operation::Return, span);
|
|
1384
|
+
self.emit(
|
|
1385
|
+
Operation::MakeFunction {
|
|
1386
|
+
name: "<genexpr>".into(),
|
|
1387
|
+
code: nested.finish(Vec::new()),
|
|
1388
|
+
defaults: 0,
|
|
1389
|
+
},
|
|
1390
|
+
span,
|
|
1391
|
+
);
|
|
1392
|
+
self.emit(
|
|
1393
|
+
Operation::Call {
|
|
1394
|
+
positional: 0,
|
|
1395
|
+
keywords: Vec::new(),
|
|
1396
|
+
starred: Vec::new(),
|
|
1397
|
+
},
|
|
1398
|
+
span,
|
|
1399
|
+
);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1219
1402
|
fn emit_dict_comprehension(
|
|
1220
1403
|
&mut self,
|
|
1221
1404
|
key: Expression,
|
|
@@ -1230,6 +1413,7 @@ impl Compiler {
|
|
|
1230
1413
|
finalizers: Vec::new(),
|
|
1231
1414
|
protected_regions: Vec::new(),
|
|
1232
1415
|
in_function: true,
|
|
1416
|
+
is_coroutine: false,
|
|
1233
1417
|
globals: HashSet::new(),
|
|
1234
1418
|
nonlocals: HashSet::new(),
|
|
1235
1419
|
named_expression,
|
|
@@ -1307,6 +1491,35 @@ impl Compiler {
|
|
|
1307
1491
|
self.patch_jump(next, exhausted);
|
|
1308
1492
|
}
|
|
1309
1493
|
|
|
1494
|
+
fn emit_generator_comprehension_body(
|
|
1495
|
+
&mut self,
|
|
1496
|
+
clauses: &[ComprehensionClause],
|
|
1497
|
+
index: usize,
|
|
1498
|
+
element: &Expression,
|
|
1499
|
+
span: Span,
|
|
1500
|
+
) {
|
|
1501
|
+
let clause = &clauses[index];
|
|
1502
|
+
self.expression(clause.iterable.clone());
|
|
1503
|
+
self.emit(Operation::GetIterator, span);
|
|
1504
|
+
let next = self.emit(Operation::ForIterator(usize::MAX), span);
|
|
1505
|
+
self.store_target(clause.target.clone(), span);
|
|
1506
|
+
for condition in &clause.conditions {
|
|
1507
|
+
self.expression(condition.clone());
|
|
1508
|
+
let skip = self.emit(Operation::PopJumpIfFalse(usize::MAX), span);
|
|
1509
|
+
self.patch_jump(skip, next);
|
|
1510
|
+
}
|
|
1511
|
+
if index + 1 < clauses.len() {
|
|
1512
|
+
self.emit_generator_comprehension_body(clauses, index + 1, element, span);
|
|
1513
|
+
} else {
|
|
1514
|
+
self.expression(element.clone());
|
|
1515
|
+
self.emit(Operation::Yield, span);
|
|
1516
|
+
self.emit(Operation::PopTop, span);
|
|
1517
|
+
}
|
|
1518
|
+
self.emit(Operation::Jump(next), span);
|
|
1519
|
+
let exhausted = self.instructions.len();
|
|
1520
|
+
self.patch_jump(next, exhausted);
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1310
1523
|
fn emit_dict_comprehension_body(
|
|
1311
1524
|
&mut self,
|
|
1312
1525
|
clauses: &[ComprehensionClause],
|
|
@@ -212,6 +212,7 @@ pub enum Object {
|
|
|
212
212
|
stack: Vec<Value>,
|
|
213
213
|
exhausted: bool,
|
|
214
214
|
running: bool,
|
|
215
|
+
return_value: Value,
|
|
215
216
|
},
|
|
216
217
|
Module {
|
|
217
218
|
name: String,
|
|
@@ -1430,9 +1431,15 @@ fn trace_object(
|
|
|
1430
1431
|
trace_value(*callable, object_work);
|
|
1431
1432
|
trace_value(*sentinel, object_work);
|
|
1432
1433
|
}
|
|
1433
|
-
Object::Generator {
|
|
1434
|
+
Object::Generator {
|
|
1435
|
+
scope,
|
|
1436
|
+
stack,
|
|
1437
|
+
return_value,
|
|
1438
|
+
..
|
|
1439
|
+
} => {
|
|
1434
1440
|
scope_work.push(*scope);
|
|
1435
1441
|
trace_values(stack.iter().copied(), object_work);
|
|
1442
|
+
trace_value(*return_value, object_work);
|
|
1436
1443
|
}
|
|
1437
1444
|
Object::Module { scope, .. } => scope_work.push(*scope),
|
|
1438
1445
|
Object::Array { storage, .. } => object_work.push(*storage),
|