guppylang-internals 0.23.0__tar.gz → 0.24.0__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.
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/CHANGELOG.md +34 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/PKG-INFO +3 -3
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/README.md +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/pyproject.toml +2 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/__init__.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/core.py +8 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/expr_checker.py +10 -20
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/func_checker.py +170 -21
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/stmt_checker.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/decorator.py +124 -58
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/const.py +2 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/custom.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/declaration.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/extern.py +2 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/function.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/parameter.py +2 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/pytket_circuits.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/struct.py +10 -10
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/traced.py +1 -1
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/ty.py +6 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/wasm.py +2 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/engine.py +13 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/nodes.py +0 -23
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/tket_exts.py +3 -6
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/wasm.py +37 -26
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/function.py +13 -2
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/unpacking.py +18 -12
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/builtin.py +30 -11
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/errors.py +6 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/parsing.py +111 -125
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/.gitignore +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/LICENCE +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/ast_util.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/cfg/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/cfg/analysis.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/cfg/bb.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/cfg/builder.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/cfg/cfg.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/cfg_checker.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/errors/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/errors/comptime_errors.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/errors/generic.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/errors/linearity.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/errors/type_errors.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/errors/wasm.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/linearity_checker.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/cfg_compiler.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/core.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/expr_compiler.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/func_compiler.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/hugr_extension.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/qtm_platform_extension.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/compiler/stmt_compiler.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/common.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/overloaded.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/definition/value.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/diagnostic.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/dummy_decorator.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/error.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/experimental.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/ipython_inspect.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/py.typed +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/span.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/checker.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/arithmetic.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/array.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/either.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/frozenarray.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/futures.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/list.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/mem.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/option.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/prelude.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/qsystem.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/quantum.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler/tket_bool.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/compiler.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/debug.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/std/_internal/util.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/builtins_mock.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/frozenlist.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/object.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/state.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tracing/util.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/__init__.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/arg.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/common.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/const.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/param.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/printing.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/subst.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/ty.py +0 -0
- {guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/tys/var.py +0 -0
|
@@ -3,6 +3,40 @@
|
|
|
3
3
|
First release of `guppylang_internals` package containing refactored out internal components
|
|
4
4
|
from `guppylang`.
|
|
5
5
|
|
|
6
|
+
## [0.24.0](https://github.com/CQCL/guppylang/compare/guppylang-internals-v0.23.0...guppylang-internals-v0.24.0) (2025-09-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### ⚠ BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* `guppylang_internals.decorator.extend_type` now returns a `GuppyDefinition` by default. To get the previous behaviour of returning the annotated class unchanged, pass `return_class=True`.
|
|
12
|
+
* `TypeDef`s now require a `params` field
|
|
13
|
+
* guppylang_internals.ty.parsing.parse_function_io_types replaced with parse_function_arg_annotation and check_function_arg
|
|
14
|
+
* Significant changes to the WASM decorators, types and operations
|
|
15
|
+
* Deleted `guppylang_internals.nodes.{IterHasNext, IterEnd}`
|
|
16
|
+
* guppylang_internals.tracing.unpacking.update_packed_value now returns a bool signalling whether the operation was successful.
|
|
17
|
+
* `CompilationEngine` now initialises all it's fields
|
|
18
|
+
* Calling `CompilationEngine.reset` no longer nullifies `additional_extensions`
|
|
19
|
+
* `CompilationEngine.register_extension` no longer adds duplicates to the `additional_extensions` list
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* Infer type of `self` arguments ([#1192](https://github.com/CQCL/guppylang/issues/1192)) ([51f5a2b](https://github.com/CQCL/guppylang/commit/51f5a2b3a9b06bc4ab054f32a4d07f7395df8ff4))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* Add init to CompilationEngine; don't trash additional_extensions ([#1256](https://github.com/CQCL/guppylang/issues/1256)) ([e413748](https://github.com/CQCL/guppylang/commit/e413748532db3895cab4925a222177a4fa3fd61b))
|
|
29
|
+
* Allow generic specialization of methods ([#1206](https://github.com/CQCL/guppylang/issues/1206)) ([93936cc](https://github.com/CQCL/guppylang/commit/93936cc275c56dd856d11fabc7aac20176304147)), closes [#1182](https://github.com/CQCL/guppylang/issues/1182)
|
|
30
|
+
* Correctly update borrowed values after calls and catch cases where it's impossible ([#1253](https://github.com/CQCL/guppylang/issues/1253)) ([3ec5462](https://github.com/CQCL/guppylang/commit/3ec54627729b49689da006a743e9e2c359cd3728))
|
|
31
|
+
* Fix `nat` constructor in comptime functions ([#1258](https://github.com/CQCL/guppylang/issues/1258)) ([e257b6f](https://github.com/CQCL/guppylang/commit/e257b6fc2fe3793d6d8f63feca83bf5ed6643673))
|
|
32
|
+
* Fix incorrect leak error for borrowing functions in comptime ([#1252](https://github.com/CQCL/guppylang/issues/1252)) ([855244e](https://github.com/CQCL/guppylang/commit/855244e2d5e3aeb04c2028f9f2310dba0e74210a)), closes [#1249](https://github.com/CQCL/guppylang/issues/1249)
|
|
33
|
+
* wasm module updates based on tested lowering ([#1230](https://github.com/CQCL/guppylang/issues/1230)) ([657cea2](https://github.com/CQCL/guppylang/commit/657cea27af00a9c02e8d1a3190db535bbd1e7981))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Miscellaneous Chores
|
|
37
|
+
|
|
38
|
+
* Delete unused old iterator AST nodes ([#1215](https://github.com/CQCL/guppylang/issues/1215)) ([2310897](https://github.com/CQCL/guppylang/commit/231089750e33cf70754e5218feed64053c558c17))
|
|
39
|
+
|
|
6
40
|
## [0.23.0](https://github.com/CQCL/guppylang/compare/guppylang-internals-v0.22.0...guppylang-internals-v0.23.0) (2025-08-19)
|
|
7
41
|
|
|
8
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guppylang-internals
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.0
|
|
4
4
|
Summary: Compiler internals for `guppylang` package.
|
|
5
5
|
Author-email: Mark Koch <mark.koch@quantinuum.com>, TKET development team <tket-support@quantinuum.com>
|
|
6
6
|
Maintainer-email: Mark Koch <mark.koch@quantinuum.com>, TKET development team <tket-support@quantinuum.com>
|
|
@@ -220,7 +220,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
220
220
|
Classifier: Topic :: Software Development :: Compilers
|
|
221
221
|
Requires-Python: <4,>=3.10
|
|
222
222
|
Requires-Dist: hugr~=0.13.1
|
|
223
|
-
Requires-Dist: tket-exts~=0.
|
|
223
|
+
Requires-Dist: tket-exts~=0.11.0
|
|
224
224
|
Requires-Dist: typing-extensions<5,>=4.9.0
|
|
225
225
|
Provides-Extra: pytket
|
|
226
226
|
Requires-Dist: pytket>=1.34; extra == 'pytket'
|
|
@@ -228,7 +228,7 @@ Description-Content-Type: text/markdown
|
|
|
228
228
|
|
|
229
229
|
# guppylang-internals
|
|
230
230
|
|
|
231
|
-
This packages contains the internals of the Guppy compiler.
|
|
231
|
+
This packages contains the internals of the Guppy compiler.
|
|
232
232
|
|
|
233
233
|
See `guppylang` for the package providing the user-facing language frontend.
|
|
234
234
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "guppylang-internals"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.24.0"
|
|
4
4
|
requires-python = ">=3.10,<4"
|
|
5
5
|
description = "Compiler internals for `guppylang` package."
|
|
6
6
|
license = { file = "LICENCE" }
|
|
@@ -34,7 +34,7 @@ classifiers = [
|
|
|
34
34
|
|
|
35
35
|
dependencies = [
|
|
36
36
|
"typing-extensions >=4.9.0,<5",
|
|
37
|
-
"tket-exts ~= 0.
|
|
37
|
+
"tket-exts ~= 0.11.0",
|
|
38
38
|
"hugr ~= 0.13.1",
|
|
39
39
|
]
|
|
40
40
|
|
{guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/checker/core.py
RENAMED
|
@@ -54,6 +54,7 @@ from guppylang_internals.tys.ty import (
|
|
|
54
54
|
|
|
55
55
|
if TYPE_CHECKING:
|
|
56
56
|
from guppylang_internals.definition.struct import StructField
|
|
57
|
+
from guppylang_internals.tys.parsing import TypeParsingCtx
|
|
57
58
|
|
|
58
59
|
|
|
59
60
|
#: A "place" is a description for a storage location of a local value that users
|
|
@@ -507,6 +508,13 @@ class Context(NamedTuple):
|
|
|
507
508
|
locals: Locals[str, Variable]
|
|
508
509
|
generic_params: dict[str, Parameter]
|
|
509
510
|
|
|
511
|
+
@property
|
|
512
|
+
def parsing_ctx(self) -> "TypeParsingCtx":
|
|
513
|
+
"""A type parsing context derived from this checking context."""
|
|
514
|
+
from guppylang_internals.tys.parsing import TypeParsingCtx
|
|
515
|
+
|
|
516
|
+
return TypeParsingCtx(self.globals, self.generic_params)
|
|
517
|
+
|
|
510
518
|
|
|
511
519
|
class DummyEvalDict(dict[str, Any]):
|
|
512
520
|
"""A custom dict that can be passed to `eval` to give better error messages.
|
|
@@ -34,6 +34,7 @@ from guppylang_internals.ast_util import (
|
|
|
34
34
|
AstNode,
|
|
35
35
|
AstVisitor,
|
|
36
36
|
breaks_in_loop,
|
|
37
|
+
get_type,
|
|
37
38
|
get_type_opt,
|
|
38
39
|
return_nodes_in_ast,
|
|
39
40
|
with_loc,
|
|
@@ -101,8 +102,6 @@ from guppylang_internals.nodes import (
|
|
|
101
102
|
FieldAccessAndDrop,
|
|
102
103
|
GenericParamValue,
|
|
103
104
|
GlobalName,
|
|
104
|
-
IterEnd,
|
|
105
|
-
IterHasNext,
|
|
106
105
|
IterNext,
|
|
107
106
|
LocalCall,
|
|
108
107
|
MakeIter,
|
|
@@ -784,14 +783,6 @@ class ExprSynthesizer(AstVisitor[tuple[ast.expr, Type]]):
|
|
|
784
783
|
raise GuppyTypeError(err)
|
|
785
784
|
return expr, ty
|
|
786
785
|
|
|
787
|
-
def visit_IterHasNext(self, node: IterHasNext) -> tuple[ast.expr, Type]:
|
|
788
|
-
node.value, ty = self.synthesize(node.value)
|
|
789
|
-
flags = InputFlags.Owned if not ty.copyable else InputFlags.NoFlags
|
|
790
|
-
exp_sig = FunctionType([FuncInput(ty, flags)], TupleType([bool_type(), ty]))
|
|
791
|
-
return self.synthesize_instance_func(
|
|
792
|
-
node.value, [], "__hasnext__", "an iterator", exp_sig, True
|
|
793
|
-
)
|
|
794
|
-
|
|
795
786
|
def visit_IterNext(self, node: IterNext) -> tuple[ast.expr, Type]:
|
|
796
787
|
node.value, ty = self.synthesize(node.value)
|
|
797
788
|
flags = InputFlags.Owned if not ty.copyable else InputFlags.NoFlags
|
|
@@ -803,14 +794,6 @@ class ExprSynthesizer(AstVisitor[tuple[ast.expr, Type]]):
|
|
|
803
794
|
node.value, [], "__next__", "an iterator", exp_sig, True
|
|
804
795
|
)
|
|
805
796
|
|
|
806
|
-
def visit_IterEnd(self, node: IterEnd) -> tuple[ast.expr, Type]:
|
|
807
|
-
node.value, ty = self.synthesize(node.value)
|
|
808
|
-
flags = InputFlags.Owned if not ty.copyable else InputFlags.NoFlags
|
|
809
|
-
exp_sig = FunctionType([FuncInput(ty, flags)], NoneType())
|
|
810
|
-
return self.synthesize_instance_func(
|
|
811
|
-
node.value, [], "__end__", "an iterator", exp_sig, True
|
|
812
|
-
)
|
|
813
|
-
|
|
814
797
|
def visit_ListComp(self, node: ast.ListComp) -> tuple[ast.expr, Type]:
|
|
815
798
|
raise InternalGuppyError(
|
|
816
799
|
"BB contains `ListComp`. Should have been removed during CFG"
|
|
@@ -946,7 +929,7 @@ def check_type_apply(ty: FunctionType, node: ast.Subscript, ctx: Context) -> Ins
|
|
|
946
929
|
raise GuppyError(err)
|
|
947
930
|
|
|
948
931
|
return [
|
|
949
|
-
param.check_arg(arg_from_ast(arg_expr,
|
|
932
|
+
param.check_arg(arg_from_ast(arg_expr, ctx.parsing_ctx), arg_expr)
|
|
950
933
|
for arg_expr, param in zip(arg_exprs, ty.params, strict=True)
|
|
951
934
|
]
|
|
952
935
|
|
|
@@ -1232,7 +1215,14 @@ def instantiate_poly(node: ast.expr, ty: FunctionType, inst: Inst) -> ast.expr:
|
|
|
1232
1215
|
"""Instantiates quantified type arguments in a function."""
|
|
1233
1216
|
assert len(ty.params) == len(inst)
|
|
1234
1217
|
if len(inst) > 0:
|
|
1235
|
-
|
|
1218
|
+
# Partial applications need to be instantiated on the inside
|
|
1219
|
+
if isinstance(node, PartialApply):
|
|
1220
|
+
full_ty = get_type(node.func)
|
|
1221
|
+
assert isinstance(full_ty, FunctionType)
|
|
1222
|
+
assert full_ty.params == ty.params
|
|
1223
|
+
node.func = instantiate_poly(node.func, full_ty, inst)
|
|
1224
|
+
else:
|
|
1225
|
+
node = with_loc(node, TypeApply(value=with_type(ty, node), inst=inst))
|
|
1236
1226
|
return with_type(ty.instantiate(inst), node)
|
|
1237
1227
|
return with_type(ty, node)
|
|
1238
1228
|
|
|
@@ -7,8 +7,8 @@ node straight from the Python AST. We build a CFG, check it, and return a
|
|
|
7
7
|
|
|
8
8
|
import ast
|
|
9
9
|
import sys
|
|
10
|
-
from dataclasses import dataclass
|
|
11
|
-
from typing import TYPE_CHECKING, ClassVar
|
|
10
|
+
from dataclasses import dataclass, replace
|
|
11
|
+
from typing import TYPE_CHECKING, ClassVar, cast
|
|
12
12
|
|
|
13
13
|
from guppylang_internals.ast_util import return_nodes_in_ast, with_loc
|
|
14
14
|
from guppylang_internals.cfg.bb import BB
|
|
@@ -17,13 +17,28 @@ from guppylang_internals.checker.cfg_checker import CheckedCFG, check_cfg
|
|
|
17
17
|
from guppylang_internals.checker.core import Context, Globals, Place, Variable
|
|
18
18
|
from guppylang_internals.checker.errors.generic import UnsupportedError
|
|
19
19
|
from guppylang_internals.definition.common import DefId
|
|
20
|
+
from guppylang_internals.definition.ty import TypeDef
|
|
20
21
|
from guppylang_internals.diagnostic import Error, Help, Note
|
|
21
22
|
from guppylang_internals.engine import DEF_STORE, ENGINE
|
|
22
23
|
from guppylang_internals.error import GuppyError
|
|
23
24
|
from guppylang_internals.experimental import check_capturing_closures_enabled
|
|
24
25
|
from guppylang_internals.nodes import CheckedNestedFunctionDef, NestedFunctionDef
|
|
25
|
-
from guppylang_internals.tys.parsing import
|
|
26
|
-
|
|
26
|
+
from guppylang_internals.tys.parsing import (
|
|
27
|
+
TypeParsingCtx,
|
|
28
|
+
check_function_arg,
|
|
29
|
+
parse_function_arg_annotation,
|
|
30
|
+
type_from_ast,
|
|
31
|
+
type_with_flags_from_ast,
|
|
32
|
+
)
|
|
33
|
+
from guppylang_internals.tys.ty import (
|
|
34
|
+
ExistentialTypeVar,
|
|
35
|
+
FuncInput,
|
|
36
|
+
FunctionType,
|
|
37
|
+
InputFlags,
|
|
38
|
+
NoneType,
|
|
39
|
+
Type,
|
|
40
|
+
unify,
|
|
41
|
+
)
|
|
27
42
|
|
|
28
43
|
if sys.version_info >= (3, 12):
|
|
29
44
|
from guppylang_internals.tys.parsing import parse_parameter
|
|
@@ -53,6 +68,15 @@ class MissingArgAnnotationError(Error):
|
|
|
53
68
|
span_label: ClassVar[str] = "Argument requires a type annotation"
|
|
54
69
|
|
|
55
70
|
|
|
71
|
+
@dataclass(frozen=True)
|
|
72
|
+
class RecursiveSelfError(Error):
|
|
73
|
+
title: ClassVar[str] = "Recursive self annotation"
|
|
74
|
+
span_label: ClassVar[str] = (
|
|
75
|
+
"Type of `{self_arg}` cannot recursively refer to `Self`"
|
|
76
|
+
)
|
|
77
|
+
self_arg: str
|
|
78
|
+
|
|
79
|
+
|
|
56
80
|
@dataclass(frozen=True)
|
|
57
81
|
class MissingReturnAnnotationError(Error):
|
|
58
82
|
title: ClassVar[str] = "Missing type annotation"
|
|
@@ -67,6 +91,43 @@ class MissingReturnAnnotationError(Error):
|
|
|
67
91
|
func: str
|
|
68
92
|
|
|
69
93
|
|
|
94
|
+
@dataclass(frozen=True)
|
|
95
|
+
class InvalidSelfError(Error):
|
|
96
|
+
title: ClassVar[str] = "Invalid self annotation"
|
|
97
|
+
span_label: ClassVar[str] = "`{self_arg}` must be of type `{self_ty}`"
|
|
98
|
+
self_arg: str
|
|
99
|
+
self_ty: Type
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(frozen=True)
|
|
103
|
+
class SelfParamsShadowedError(Error):
|
|
104
|
+
title: ClassVar[str] = "Shadowed generic parameters"
|
|
105
|
+
span_label: ClassVar[str] = (
|
|
106
|
+
"Cannot infer type for `{self_arg}` since parameter `{param}` of "
|
|
107
|
+
"`{ty_defn.name}` is shadowed"
|
|
108
|
+
)
|
|
109
|
+
param: str
|
|
110
|
+
ty_defn: "TypeDef"
|
|
111
|
+
self_arg: str
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class ExplicitHelp(Help):
|
|
115
|
+
span_label: ClassVar[str] = (
|
|
116
|
+
"Consider specifying the type explicitly: `{suggestion}`"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def suggestion(self) -> str:
|
|
121
|
+
parent = self._parent
|
|
122
|
+
assert isinstance(parent, SelfParamsShadowedError)
|
|
123
|
+
params = (
|
|
124
|
+
f"[{', '.join(f'?{p.name}' for p in parent.ty_defn.params)}]"
|
|
125
|
+
if parent.ty_defn.params
|
|
126
|
+
else ""
|
|
127
|
+
)
|
|
128
|
+
return f'{parent.self_arg}: "{parent.ty_defn.name}{params}"'
|
|
129
|
+
|
|
130
|
+
|
|
70
131
|
def check_global_func_def(
|
|
71
132
|
func_def: ast.FunctionDef, ty: FunctionType, globals: Globals
|
|
72
133
|
) -> CheckedCFG[Place]:
|
|
@@ -176,9 +237,16 @@ def check_nested_func_def(
|
|
|
176
237
|
return with_loc(func_def, checked_def)
|
|
177
238
|
|
|
178
239
|
|
|
179
|
-
def check_signature(
|
|
240
|
+
def check_signature(
|
|
241
|
+
func_def: ast.FunctionDef, globals: Globals, def_id: DefId | None = None
|
|
242
|
+
) -> FunctionType:
|
|
180
243
|
"""Checks the signature of a function definition and returns the corresponding
|
|
181
|
-
Guppy type.
|
|
244
|
+
Guppy type.
|
|
245
|
+
|
|
246
|
+
If this is a method, then the `DefId` of the associated parent type should also be
|
|
247
|
+
passed. This will be used to check or infer the type annotation for the `self`
|
|
248
|
+
argument.
|
|
249
|
+
"""
|
|
182
250
|
if len(func_def.args.posonlyargs) != 0:
|
|
183
251
|
raise GuppyError(
|
|
184
252
|
UnsupportedError(func_def.args.posonlyargs[0], "Positional-only parameters")
|
|
@@ -211,23 +279,29 @@ def check_signature(func_def: ast.FunctionDef, globals: Globals) -> FunctionType
|
|
|
211
279
|
param = parse_parameter(param_node, i, globals)
|
|
212
280
|
param_var_mapping[param.name] = param
|
|
213
281
|
|
|
214
|
-
|
|
282
|
+
# Figure out if this is a method
|
|
283
|
+
self_defn: TypeDef | None = None
|
|
284
|
+
if def_id is not None and def_id in DEF_STORE.impl_parents:
|
|
285
|
+
self_defn = cast(TypeDef, ENGINE.get_checked(DEF_STORE.impl_parents[def_id]))
|
|
286
|
+
assert isinstance(self_defn, TypeDef)
|
|
287
|
+
|
|
288
|
+
inputs = []
|
|
215
289
|
input_names = []
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
290
|
+
ctx = TypeParsingCtx(globals, param_var_mapping, allow_free_vars=True)
|
|
291
|
+
for i, inp in enumerate(func_def.args.args):
|
|
292
|
+
# Special handling for `self` arguments. Note that `__new__` is excluded here
|
|
293
|
+
# since it's not a method so doesn't take `self`.
|
|
294
|
+
if self_defn and i == 0 and func_def.name != "__new__":
|
|
295
|
+
input = parse_self_arg(inp, self_defn, ctx)
|
|
296
|
+
ctx = replace(ctx, self_ty=input.ty)
|
|
297
|
+
else:
|
|
298
|
+
ty_ast = inp.annotation
|
|
299
|
+
if ty_ast is None:
|
|
300
|
+
raise GuppyError(MissingArgAnnotationError(inp))
|
|
301
|
+
input = parse_function_arg_annotation(ty_ast, inp.arg, ctx)
|
|
302
|
+
inputs.append(input)
|
|
221
303
|
input_names.append(inp.arg)
|
|
222
|
-
|
|
223
|
-
input_nodes,
|
|
224
|
-
func_def.returns,
|
|
225
|
-
input_names,
|
|
226
|
-
func_def,
|
|
227
|
-
globals,
|
|
228
|
-
param_var_mapping,
|
|
229
|
-
True,
|
|
230
|
-
)
|
|
304
|
+
output = type_from_ast(func_def.returns, ctx)
|
|
231
305
|
return FunctionType(
|
|
232
306
|
inputs,
|
|
233
307
|
output,
|
|
@@ -236,6 +310,81 @@ def check_signature(func_def: ast.FunctionDef, globals: Globals) -> FunctionType
|
|
|
236
310
|
)
|
|
237
311
|
|
|
238
312
|
|
|
313
|
+
def parse_self_arg(arg: ast.arg, self_defn: TypeDef, ctx: TypeParsingCtx) -> FuncInput:
|
|
314
|
+
"""Handles parsing of the `self` argument on methods.
|
|
315
|
+
|
|
316
|
+
This argument is special since its type annotation may be omitted. Furthermore, if a
|
|
317
|
+
type is provided then it must match the parent type.
|
|
318
|
+
"""
|
|
319
|
+
assert self_defn.params is not None
|
|
320
|
+
if arg.annotation is None:
|
|
321
|
+
return handle_implicit_self_arg(arg, self_defn, ctx)
|
|
322
|
+
|
|
323
|
+
# If the user has provided an annotation for `self`, then we go ahead and parse it.
|
|
324
|
+
# However, in the annotation the user is also allowed to use `Self`, so we have to
|
|
325
|
+
# specify a `self_ty` in the context.
|
|
326
|
+
self_ty_head = self_defn.check_instantiate(
|
|
327
|
+
[param.to_existential()[0] for param in self_defn.params]
|
|
328
|
+
)
|
|
329
|
+
self_ty_placeholder = ExistentialTypeVar.fresh(
|
|
330
|
+
"Self", copyable=self_ty_head.copyable, droppable=self_ty_head.droppable
|
|
331
|
+
)
|
|
332
|
+
assert ctx.self_ty is None
|
|
333
|
+
ctx = replace(ctx, self_ty=self_ty_placeholder)
|
|
334
|
+
user_ty, user_flags = type_with_flags_from_ast(arg.annotation, ctx)
|
|
335
|
+
|
|
336
|
+
# If the user just annotates `self: Self` then we can fall back to the case where
|
|
337
|
+
# no annotation is provided at all
|
|
338
|
+
if user_ty == self_ty_placeholder:
|
|
339
|
+
return handle_implicit_self_arg(arg, self_defn, ctx, user_flags)
|
|
340
|
+
|
|
341
|
+
# Annotations like `self: Foo[Self]` are not allowed (would be an infinite type)
|
|
342
|
+
if self_ty_placeholder in user_ty.unsolved_vars:
|
|
343
|
+
raise GuppyError(RecursiveSelfError(arg.annotation, arg.arg))
|
|
344
|
+
|
|
345
|
+
# Check that the annotation matches the parent type. We can do this by unifying with
|
|
346
|
+
# the expected self type where all params are instantiated with unification vars
|
|
347
|
+
subst = unify(user_ty, self_ty_head, {})
|
|
348
|
+
if subst is None:
|
|
349
|
+
raise GuppyError(InvalidSelfError(arg.annotation, arg.arg, self_ty_head))
|
|
350
|
+
|
|
351
|
+
return check_function_arg(user_ty, user_flags, arg, arg.arg, ctx)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def handle_implicit_self_arg(
|
|
355
|
+
arg: ast.arg,
|
|
356
|
+
self_defn: TypeDef,
|
|
357
|
+
ctx: TypeParsingCtx,
|
|
358
|
+
flags: InputFlags = InputFlags.NoFlags,
|
|
359
|
+
) -> FuncInput:
|
|
360
|
+
"""Handles the case where no annotation for `self` is provided.
|
|
361
|
+
|
|
362
|
+
Generates the most generic annotation that is possible by making the function as
|
|
363
|
+
generic as the parent type.
|
|
364
|
+
"""
|
|
365
|
+
# Check that the user hasn't shadowed some of the parent type parameters using a
|
|
366
|
+
# Python 3.12 style parameter declaration
|
|
367
|
+
assert self_defn.params is not None
|
|
368
|
+
shadowed_params = [
|
|
369
|
+
param for param in self_defn.params if param.name in ctx.param_var_mapping
|
|
370
|
+
]
|
|
371
|
+
if shadowed_params:
|
|
372
|
+
param = shadowed_params.pop()
|
|
373
|
+
err = SelfParamsShadowedError(arg, param.name, self_defn, arg.arg)
|
|
374
|
+
err.add_sub_diagnostic(SelfParamsShadowedError.ExplicitHelp(arg))
|
|
375
|
+
raise GuppyError(err)
|
|
376
|
+
|
|
377
|
+
# The generic params inherited from the parent type should appear first in the
|
|
378
|
+
# parameter list, so we have to shift the existing ones
|
|
379
|
+
for name, param in ctx.param_var_mapping.items():
|
|
380
|
+
ctx.param_var_mapping[name] = param.with_idx(param.idx + len(self_defn.params))
|
|
381
|
+
|
|
382
|
+
ctx.param_var_mapping.update({param.name: param for param in self_defn.params})
|
|
383
|
+
self_args = [param.to_bound() for param in self_defn.params]
|
|
384
|
+
self_ty = self_defn.check_instantiate(self_args, loc=arg)
|
|
385
|
+
return check_function_arg(self_ty, flags, arg, arg.arg, ctx)
|
|
386
|
+
|
|
387
|
+
|
|
239
388
|
def parse_function_with_docstring(
|
|
240
389
|
func_ast: ast.FunctionDef,
|
|
241
390
|
) -> tuple[ast.FunctionDef, str | None]:
|
|
@@ -356,7 +356,7 @@ class StmtChecker(AstVisitor[BBStatement]):
|
|
|
356
356
|
def visit_AnnAssign(self, node: ast.AnnAssign) -> ast.stmt:
|
|
357
357
|
if node.value is None:
|
|
358
358
|
raise GuppyError(UnsupportedError(node, "Variable declarations"))
|
|
359
|
-
ty = type_from_ast(node.annotation, self.ctx.
|
|
359
|
+
ty = type_from_ast(node.annotation, self.ctx.parsing_ctx)
|
|
360
360
|
node.value, subst = self._check_expr(node.value, ty)
|
|
361
361
|
assert not ty.unsolved_vars # `ty` must be closed!
|
|
362
362
|
assert len(subst) == 0
|
{guppylang_internals-0.23.0 → guppylang_internals-0.24.0}/src/guppylang_internals/decorator.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
|
-
from typing import TYPE_CHECKING, ParamSpec, TypeVar
|
|
4
|
+
from typing import TYPE_CHECKING, ParamSpec, TypeVar, overload
|
|
5
5
|
|
|
6
6
|
from hugr import ops
|
|
7
7
|
from hugr import tys as ht
|
|
@@ -42,6 +42,7 @@ from guppylang_internals.tys.ty import (
|
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
if TYPE_CHECKING:
|
|
45
|
+
import ast
|
|
45
46
|
import builtins
|
|
46
47
|
from collections.abc import Callable, Sequence
|
|
47
48
|
from types import FrameType
|
|
@@ -121,15 +122,19 @@ def hugr_op(
|
|
|
121
122
|
return custom_function(OpCompiler(op), checker, higher_order_value, name, signature)
|
|
122
123
|
|
|
123
124
|
|
|
124
|
-
def extend_type(defn: TypeDef) -> Callable[[type], type]:
|
|
125
|
-
"""Decorator to add new instance functions to a type.
|
|
125
|
+
def extend_type(defn: TypeDef, return_class: bool = False) -> Callable[[type], type]:
|
|
126
|
+
"""Decorator to add new instance functions to a type.
|
|
127
|
+
|
|
128
|
+
By default, returns a `GuppyDefinition` object referring to the type. Alternatively,
|
|
129
|
+
`return_class=True` can be set to return the decorated class unchanged.
|
|
130
|
+
"""
|
|
126
131
|
from guppylang.defs import GuppyDefinition
|
|
127
132
|
|
|
128
133
|
def dec(c: type) -> type:
|
|
129
134
|
for val in c.__dict__.values():
|
|
130
135
|
if isinstance(val, GuppyDefinition):
|
|
131
136
|
DEF_STORE.register_impl(defn.id, val.wrapped.name, val.id)
|
|
132
|
-
return c
|
|
137
|
+
return c if return_class else GuppyDefinition(defn) # type: ignore[return-value]
|
|
133
138
|
|
|
134
139
|
return dec
|
|
135
140
|
|
|
@@ -181,63 +186,124 @@ def custom_type(
|
|
|
181
186
|
|
|
182
187
|
|
|
183
188
|
def wasm_module(
|
|
184
|
-
filename: str,
|
|
189
|
+
filename: str,
|
|
185
190
|
) -> Callable[[builtins.type[T]], GuppyDefinition]:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
DEF_STORE.register_def(wasm_module, get_calling_frame())
|
|
201
|
-
for val in cls.__dict__.values():
|
|
202
|
-
if isinstance(val, GuppyDefinition):
|
|
203
|
-
DEF_STORE.register_impl(wasm_module.id, val.wrapped.name, val.id)
|
|
204
|
-
# Add a constructor to the class
|
|
205
|
-
call_method = CustomFunctionDef(
|
|
206
|
-
DefId.fresh(),
|
|
207
|
-
"__new__",
|
|
208
|
-
None,
|
|
209
|
-
FunctionType(
|
|
210
|
-
[FuncInput(NumericType(NumericType.Kind.Nat), flags=InputFlags.Owned)],
|
|
211
|
-
wasm_module_ty,
|
|
212
|
-
),
|
|
213
|
-
DefaultCallChecker(),
|
|
214
|
-
WasmModuleInitCompiler(),
|
|
215
|
-
True,
|
|
216
|
-
GlobalConstId.fresh(f"{cls.__name__}.__new__"),
|
|
217
|
-
True,
|
|
218
|
-
)
|
|
219
|
-
discard = CustomFunctionDef(
|
|
220
|
-
DefId.fresh(),
|
|
221
|
-
"discard",
|
|
222
|
-
None,
|
|
223
|
-
FunctionType([FuncInput(wasm_module_ty, InputFlags.Owned)], NoneType()),
|
|
224
|
-
DefaultCallChecker(),
|
|
225
|
-
WasmModuleDiscardCompiler(),
|
|
226
|
-
False,
|
|
227
|
-
GlobalConstId.fresh(f"{cls.__name__}.__discard__"),
|
|
228
|
-
True,
|
|
229
|
-
)
|
|
230
|
-
DEF_STORE.register_def(call_method, get_calling_frame())
|
|
231
|
-
DEF_STORE.register_impl(wasm_module.id, "__new__", call_method.id)
|
|
232
|
-
DEF_STORE.register_def(discard, get_calling_frame())
|
|
233
|
-
DEF_STORE.register_impl(wasm_module.id, "discard", discard.id)
|
|
191
|
+
def type_def_wrapper(
|
|
192
|
+
id: DefId,
|
|
193
|
+
name: str,
|
|
194
|
+
defined_at: ast.AST | None,
|
|
195
|
+
wasm_file: str,
|
|
196
|
+
config: str | None,
|
|
197
|
+
) -> OpaqueTypeDef:
|
|
198
|
+
assert config is None
|
|
199
|
+
return WasmModuleTypeDef(id, name, defined_at, wasm_file)
|
|
200
|
+
|
|
201
|
+
f = ext_module_decorator(
|
|
202
|
+
type_def_wrapper, WasmModuleInitCompiler(), WasmModuleDiscardCompiler(), True
|
|
203
|
+
)
|
|
204
|
+
return f(filename, None)
|
|
234
205
|
|
|
235
|
-
return GuppyDefinition(wasm_module)
|
|
236
|
-
|
|
237
|
-
return dec
|
|
238
206
|
|
|
207
|
+
def ext_module_decorator(
|
|
208
|
+
type_def: Callable[[DefId, str, ast.AST | None, str, str | None], OpaqueTypeDef],
|
|
209
|
+
init_compiler: CustomInoutCallCompiler,
|
|
210
|
+
discard_compiler: CustomInoutCallCompiler,
|
|
211
|
+
init_arg: bool, # Whether the init function should take a nat argument
|
|
212
|
+
) -> Callable[[str, str | None], Callable[[builtins.type[T]], GuppyDefinition]]:
|
|
213
|
+
from guppylang.defs import GuppyDefinition
|
|
239
214
|
|
|
240
|
-
def
|
|
215
|
+
def fun(
|
|
216
|
+
filename: str, module: str | None
|
|
217
|
+
) -> Callable[[builtins.type[T]], GuppyDefinition]:
|
|
218
|
+
def dec(cls: builtins.type[T]) -> GuppyDefinition:
|
|
219
|
+
# N.B. Only one module per file and vice-versa
|
|
220
|
+
ext_module = type_def(
|
|
221
|
+
DefId.fresh(),
|
|
222
|
+
cls.__name__,
|
|
223
|
+
None,
|
|
224
|
+
filename,
|
|
225
|
+
module,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
ext_module_ty = ext_module.check_instantiate([], None)
|
|
229
|
+
|
|
230
|
+
DEF_STORE.register_def(ext_module, get_calling_frame())
|
|
231
|
+
for val in cls.__dict__.values():
|
|
232
|
+
if isinstance(val, GuppyDefinition):
|
|
233
|
+
DEF_STORE.register_impl(ext_module.id, val.wrapped.name, val.id)
|
|
234
|
+
# Add a constructor to the class
|
|
235
|
+
if init_arg:
|
|
236
|
+
init_fn_ty = FunctionType(
|
|
237
|
+
[
|
|
238
|
+
FuncInput(
|
|
239
|
+
NumericType(NumericType.Kind.Nat),
|
|
240
|
+
flags=InputFlags.Owned,
|
|
241
|
+
)
|
|
242
|
+
],
|
|
243
|
+
ext_module_ty,
|
|
244
|
+
)
|
|
245
|
+
else:
|
|
246
|
+
init_fn_ty = FunctionType([], ext_module_ty)
|
|
247
|
+
|
|
248
|
+
call_method = CustomFunctionDef(
|
|
249
|
+
DefId.fresh(),
|
|
250
|
+
"__new__",
|
|
251
|
+
None,
|
|
252
|
+
init_fn_ty,
|
|
253
|
+
DefaultCallChecker(),
|
|
254
|
+
init_compiler,
|
|
255
|
+
True,
|
|
256
|
+
GlobalConstId.fresh(f"{cls.__name__}.__new__"),
|
|
257
|
+
True,
|
|
258
|
+
)
|
|
259
|
+
discard = CustomFunctionDef(
|
|
260
|
+
DefId.fresh(),
|
|
261
|
+
"discard",
|
|
262
|
+
None,
|
|
263
|
+
FunctionType([FuncInput(ext_module_ty, InputFlags.Owned)], NoneType()),
|
|
264
|
+
DefaultCallChecker(),
|
|
265
|
+
discard_compiler,
|
|
266
|
+
False,
|
|
267
|
+
GlobalConstId.fresh(f"{cls.__name__}.__discard__"),
|
|
268
|
+
True,
|
|
269
|
+
)
|
|
270
|
+
DEF_STORE.register_def(call_method, get_calling_frame())
|
|
271
|
+
DEF_STORE.register_impl(ext_module.id, "__new__", call_method.id)
|
|
272
|
+
DEF_STORE.register_def(discard, get_calling_frame())
|
|
273
|
+
DEF_STORE.register_impl(ext_module.id, "discard", discard.id)
|
|
274
|
+
|
|
275
|
+
return GuppyDefinition(ext_module)
|
|
276
|
+
|
|
277
|
+
return dec
|
|
278
|
+
|
|
279
|
+
return fun
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
@overload
|
|
283
|
+
def wasm(arg: Callable[P, T]) -> GuppyFunctionDefinition[P, T]: ...
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@overload
|
|
287
|
+
def wasm(arg: int) -> Callable[[Callable[P, T]], GuppyFunctionDefinition[P, T]]: ...
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def wasm(
|
|
291
|
+
arg: int | Callable[P, T],
|
|
292
|
+
) -> (
|
|
293
|
+
GuppyFunctionDefinition[P, T]
|
|
294
|
+
| Callable[[Callable[P, T]], GuppyFunctionDefinition[P, T]]
|
|
295
|
+
):
|
|
296
|
+
if isinstance(arg, int):
|
|
297
|
+
|
|
298
|
+
def wrapper(f: Callable[P, T]) -> GuppyFunctionDefinition[P, T]:
|
|
299
|
+
return wasm_helper(arg, f)
|
|
300
|
+
|
|
301
|
+
return wrapper
|
|
302
|
+
else:
|
|
303
|
+
return wasm_helper(None, arg)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def wasm_helper(fn_id: int | None, f: Callable[P, T]) -> GuppyFunctionDefinition[P, T]:
|
|
241
307
|
from guppylang.defs import GuppyFunctionDefinition
|
|
242
308
|
|
|
243
309
|
func = RawWasmFunctionDef(
|
|
@@ -246,7 +312,7 @@ def wasm(f: Callable[P, T]) -> GuppyFunctionDefinition[P, T]:
|
|
|
246
312
|
None,
|
|
247
313
|
f,
|
|
248
314
|
WasmCallChecker(),
|
|
249
|
-
WasmModuleCallCompiler(f.__name__),
|
|
315
|
+
WasmModuleCallCompiler(f.__name__, fn_id),
|
|
250
316
|
True,
|
|
251
317
|
signature=None,
|
|
252
318
|
)
|