@greenpandastudios/aug-cli 0.19.0 → 0.21.0
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.
- package/README.md +9 -6
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/bin/aug.mjs +12 -2
- package/docs/about.md +27 -0
- package/docs/api/crypto.md +103 -69
- package/docs/api/io.md +35 -33
- package/docs/api/json.md +3 -3
- package/docs/api/memory.md +23 -19
- package/docs/api/time.md +10 -9
- package/docs/api/web.md +33 -38
- package/docs/assets/benchmarks/execution.svg +774 -637
- package/docs/assets/benchmarks/http.svg +278 -249
- package/docs/assets/benchmarks/improvements.svg +66 -66
- package/docs/assets/benchmarks/kernels-mobile.svg +1 -0
- package/docs/assets/benchmarks/kernels.svg +1 -0
- package/docs/assets/benchmarks/memory.svg +153 -153
- package/docs/benchmark-results.json +227089 -90363
- package/docs/compatibility.md +8 -8
- package/docs/contributing-benchmarks.md +68 -0
- package/docs/dev-containers.md +88 -0
- package/docs/dgx-consumers.json +122 -0
- package/docs/dgx-gyms.json +784 -0
- package/docs/dgx-kernels.json +1170 -0
- package/docs/dgx-performance.json +227849 -0
- package/docs/dgx-spark.md +64 -0
- package/docs/diagnostics.md +15 -5
- package/docs/docker.md +173 -12
- package/docs/editor.md +35 -0
- package/docs/example-projects.json +238 -24
- package/docs/examples/approved-design/counters.md +34 -126
- package/docs/examples/approved-design/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/approved-design/domain/app.md +13 -77
- package/docs/examples/approved-design/domain/export.md +5 -19
- package/docs/examples/approved-design/domain/models.md +4 -23
- package/docs/examples/approved-design/domain/numbers.md +24 -114
- package/docs/examples/approved-design/index.md +16 -7
- package/docs/examples/approved-design/main.md +19 -96
- package/docs/examples/benchmark/index.md +6 -5
- package/docs/examples/benchmark/main.md +7 -35
- package/docs/examples/calls-benchmark/index.md +36 -0
- package/docs/examples/calls-benchmark/main.md +78 -0
- package/docs/examples/calls-benchmark/operations.md +60 -0
- package/docs/examples/cli-args/index.md +6 -5
- package/docs/examples/cli-args/main.md +6 -31
- package/docs/examples/collections/index.md +6 -5
- package/docs/examples/collections/main.md +7 -35
- package/docs/examples/collections-benchmark/index.md +6 -5
- package/docs/examples/collections-benchmark/main.md +7 -35
- package/docs/examples/cpu-benchmark/index.md +6 -5
- package/docs/examples/cpu-benchmark/main.md +5 -24
- package/docs/examples/developer-workflow/calculator.md +39 -186
- package/docs/examples/developer-workflow/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/developer-workflow/index.md +16 -7
- package/docs/examples/developer-workflow/logging/console.md +10 -56
- package/docs/examples/developer-workflow/logging/export.md +4 -14
- package/docs/examples/developer-workflow/logging/logger.md +7 -43
- package/docs/examples/developer-workflow/main.md +17 -69
- package/docs/examples/drop/index.md +6 -5
- package/docs/examples/drop/main.md +7 -27
- package/docs/examples/drop/resource.md +7 -30
- package/docs/examples/errors/errors.md +7 -27
- package/docs/examples/errors/index.md +6 -5
- package/docs/examples/errors/main.md +7 -28
- package/docs/examples/errors-benchmark/index.md +36 -0
- package/docs/examples/errors-benchmark/main.md +92 -0
- package/docs/examples/errors-benchmark/operations.md +65 -0
- package/docs/examples/ffi/index.md +6 -5
- package/docs/examples/ffi/main.md +6 -20
- package/docs/examples/ffi/native.md +8 -34
- package/docs/examples/float-benchmark/index.md +35 -0
- package/docs/examples/float-benchmark/main.md +75 -0
- package/docs/examples/generic-di/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/generic-di/index.md +6 -5
- package/docs/examples/generic-di/main.md +9 -39
- package/docs/examples/generic-di/types.md +23 -92
- package/docs/examples/generics/index.md +6 -5
- package/docs/examples/generics/main.md +10 -47
- package/docs/examples/generics/types.md +25 -100
- package/docs/examples/hello/app/export.md +4 -12
- package/docs/examples/hello/app/greeter.md +13 -91
- package/docs/examples/hello/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/hello/index.md +17 -6
- package/docs/examples/hello/logging/console.md +10 -54
- package/docs/examples/hello/logging/export.md +4 -14
- package/docs/examples/hello/logging/logger.md +7 -45
- package/docs/examples/hello/main.md +9 -39
- package/docs/examples/http-benchmark/index.md +6 -5
- package/docs/examples/http-benchmark/main.md +6 -20
- package/docs/examples/http-benchmark/routes.md +9 -31
- package/docs/examples/index.md +63 -29
- package/docs/examples/interceptors/app.md +20 -139
- package/docs/examples/interceptors/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/interceptors/index.md +6 -5
- package/docs/examples/interceptors/interceptors.md +24 -148
- package/docs/examples/interceptors/logging.md +13 -76
- package/docs/examples/interceptors/main.md +10 -65
- package/docs/examples/json-benchmark/data.md +4 -20
- package/docs/examples/json-benchmark/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
- package/docs/examples/json-benchmark/index.md +7 -5
- package/docs/examples/json-benchmark/main-yaml.md +20 -0
- package/docs/examples/json-benchmark/main.md +10 -49
- package/docs/examples/list-benchmark/index.md +35 -0
- package/docs/examples/list-benchmark/main.md +78 -0
- package/docs/examples/map-churn-benchmark/index.md +35 -0
- package/docs/examples/map-churn-benchmark/main.md +106 -0
- package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/api.md +104 -0
- package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.md +54 -0
- package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/native.abi-json.md +48 -0
- package/docs/examples/native-blake3/hashing.md +93 -0
- package/docs/examples/native-blake3/index.md +38 -0
- package/docs/examples/native-blake3/main.md +73 -0
- package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/api.md +406 -0
- package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.md +51 -0
- package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.md +63 -0
- package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/native.abi-json.md +161 -0
- package/docs/examples/native-pytorch/index.md +38 -0
- package/docs/examples/native-pytorch/main.md +73 -0
- package/docs/examples/native-pytorch/tensors.md +123 -0
- package/docs/examples/native-sqlite/database.md +116 -0
- package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/api.md +284 -0
- package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.md +51 -0
- package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.md +75 -0
- package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/native.abi-json.md +119 -0
- package/docs/examples/native-sqlite/index.md +38 -0
- package/docs/examples/native-sqlite/main.md +73 -0
- package/docs/examples/native-zlib/compression.md +99 -0
- package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/api.md +153 -0
- package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.md +54 -0
- package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/native.abi-json.md +76 -0
- package/docs/examples/native-zlib/index.md +38 -0
- package/docs/examples/native-zlib/main.md +78 -0
- package/docs/examples/new-syntax/console.md +10 -52
- package/docs/examples/new-syntax/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/new-syntax/greeter.md +13 -71
- package/docs/examples/new-syntax/index.md +6 -5
- package/docs/examples/new-syntax/logger.md +7 -43
- package/docs/examples/new-syntax/main.md +10 -53
- package/docs/examples/new-syntax/math.md +6 -24
- package/docs/examples/oidc-login/client/contracts.md +10 -61
- package/docs/examples/oidc-login/client/endpoints.md +32 -154
- package/docs/examples/oidc-login/client/export.md +5 -23
- package/docs/examples/oidc-login/client/login.md +234 -344
- package/docs/examples/oidc-login/client/logout.md +38 -143
- package/docs/examples/oidc-login/client/protocol.md +183 -304
- package/docs/examples/oidc-login/client/session.md +41 -149
- package/docs/examples/oidc-login/client/views.md +13 -58
- package/docs/examples/oidc-login/common/export.md +6 -26
- package/docs/examples/oidc-login/common/headers.md +42 -72
- package/docs/examples/oidc-login/common/keys.md +40 -164
- package/docs/examples/oidc-login/common/settings.md +24 -40
- package/docs/examples/oidc-login/common/views.md +7 -28
- package/docs/examples/oidc-login/dependencies/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.md +205 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +67 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +267 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.md +415 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.md +271 -0
- package/docs/examples/oidc-login/dependencies/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.md +89 -0
- package/docs/examples/oidc-login/index.md +8 -7
- package/docs/examples/oidc-login/main-yaml.md +7 -0
- package/docs/examples/oidc-login/main.md +26 -153
- package/docs/examples/oidc-login/provider/authorization.md +232 -275
- package/docs/examples/oidc-login/provider/contracts.md +24 -146
- package/docs/examples/oidc-login/provider/credentials.md +24 -57
- package/docs/examples/oidc-login/provider/discovery.md +48 -122
- package/docs/examples/oidc-login/provider/export.md +11 -37
- package/docs/examples/oidc-login/provider/token.md +159 -237
- package/docs/examples/oidc-login/provider/userinfo.md +47 -102
- package/docs/examples/oidc-login/provider/views.md +13 -53
- package/docs/examples/ownership/counter.md +17 -63
- package/docs/examples/ownership/index.md +6 -5
- package/docs/examples/ownership/main.md +7 -30
- package/docs/examples/ownership-transfer/dependencies/august/0.21.0/io/contracts.md +178 -0
- package/docs/examples/ownership-transfer/index.md +6 -5
- package/docs/examples/ownership-transfer/main.md +10 -52
- package/docs/examples/ownership-transfer/resource.md +15 -67
- package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +12 -50
- package/docs/examples/packages-app/index.md +7 -6
- package/docs/examples/packages-app/main.md +7 -25
- package/docs/examples/packages-math/aug-package-json.md +1 -1
- package/docs/examples/packages-math/index.md +7 -6
- package/docs/examples/packages-math/src/arithmetic.md +12 -50
- package/docs/examples/packages-math/src/export.md +4 -12
- package/docs/examples/records-benchmark/data.md +55 -0
- package/docs/examples/records-benchmark/index.md +36 -0
- package/docs/examples/records-benchmark/main.md +85 -0
- package/docs/examples/startup-benchmark/index.md +6 -5
- package/docs/examples/startup-benchmark/main.md +5 -17
- package/docs/examples/strings-benchmark/index.md +35 -0
- package/docs/examples/strings-benchmark/main.md +76 -0
- package/docs/examples/tasks-benchmark/index.md +36 -0
- package/docs/examples/tasks-benchmark/main.md +89 -0
- package/docs/examples/tasks-benchmark/operations.md +58 -0
- package/docs/examples/visibility/counter.md +19 -67
- package/docs/examples/visibility/index.md +6 -5
- package/docs/examples/visibility/main.md +7 -31
- package/docs/examples/weather-api/forecasts.md +168 -0
- package/docs/examples/weather-api/index.md +42 -0
- package/docs/examples/weather-api/main-yaml.md +21 -0
- package/docs/examples/weather-api/main.md +65 -0
- package/docs/examples.json +10 -0
- package/docs/getting-started.md +105 -2
- package/docs/grammar.md +7 -5
- package/docs/guides/change-a-module.md +64 -0
- package/docs/guides/index.md +27 -0
- package/docs/gym-results.json +784 -0
- package/docs/implementation-map.md +6 -0
- package/docs/index.md +51 -29
- package/docs/kernel-results.json +1170 -0
- package/docs/language-conformance.md +7 -1
- package/docs/language-constructs.md +30 -22
- package/docs/language-design-audit.md +1 -1
- package/docs/learn/data-and-errors.md +77 -0
- package/docs/learn/index.md +30 -0
- package/docs/learn/modules-and-dependencies.md +73 -0
- package/docs/learn/state-and-tests.md +71 -0
- package/docs/learn/values-and-functions.md +62 -0
- package/docs/lesson-failures.json +8 -0
- package/docs/maintaining-docs.md +16 -4
- package/docs/native-implementation.md +276 -0
- package/docs/native-interop-llvm-plan.md +342 -0
- package/docs/native-package-examples.md +684 -0
- package/docs/native-packages.md +179 -0
- package/docs/packages.md +72 -126
- package/docs/performance.md +61 -68
- package/docs/production-readiness.md +16 -5
- package/docs/public/downloads/approved-design.zip +0 -0
- package/docs/public/downloads/benchmark.zip +0 -0
- package/docs/public/downloads/calls-benchmark.zip +0 -0
- package/docs/public/downloads/cli-args.zip +0 -0
- package/docs/public/downloads/collections-benchmark.zip +0 -0
- package/docs/public/downloads/collections.zip +0 -0
- package/docs/public/downloads/cpu-benchmark.zip +0 -0
- package/docs/public/downloads/developer-workflow.zip +0 -0
- package/docs/public/downloads/drop.zip +0 -0
- package/docs/public/downloads/errors-benchmark.zip +0 -0
- package/docs/public/downloads/errors.zip +0 -0
- package/docs/public/downloads/ffi.zip +0 -0
- package/docs/public/downloads/float-benchmark.zip +0 -0
- package/docs/public/downloads/generic-di.zip +0 -0
- package/docs/public/downloads/generics.zip +0 -0
- package/docs/public/downloads/hello.zip +0 -0
- package/docs/public/downloads/http-benchmark.zip +0 -0
- package/docs/public/downloads/interceptors.zip +0 -0
- package/docs/public/downloads/json-benchmark.zip +0 -0
- package/docs/public/downloads/list-benchmark.zip +0 -0
- package/docs/public/downloads/map-churn-benchmark.zip +0 -0
- package/docs/public/downloads/native-blake3.zip +0 -0
- package/docs/public/downloads/native-pytorch.zip +0 -0
- package/docs/public/downloads/native-sqlite.zip +0 -0
- package/docs/public/downloads/native-zlib.zip +0 -0
- package/docs/public/downloads/new-syntax.zip +0 -0
- package/docs/public/downloads/oidc-login.zip +0 -0
- package/docs/public/downloads/ownership-transfer.zip +0 -0
- package/docs/public/downloads/ownership.zip +0 -0
- package/docs/public/downloads/packages-app.zip +0 -0
- package/docs/public/downloads/packages-math.zip +0 -0
- package/docs/public/downloads/records-benchmark.zip +0 -0
- package/docs/public/downloads/startup-benchmark.zip +0 -0
- package/docs/public/downloads/strings-benchmark.zip +0 -0
- package/docs/public/downloads/tasks-benchmark.zip +0 -0
- package/docs/public/downloads/visibility.zip +0 -0
- package/docs/public/downloads/weather-api.zip +0 -0
- package/docs/qualification-results.md +66 -0
- package/docs/reference.md +47 -17
- package/docs/releasing.md +105 -16
- package/docs/research/code-to-natural-language.md +108 -0
- package/docs/research/ecosystem-workflow.md +41 -0
- package/docs/research/libtorch-native-qualification.md +115 -0
- package/docs/research/native-interop-llvm.md +197 -0
- package/docs/research/qualification-methods.md +15 -0
- package/docs/research/wiki-editorial-design.md +71 -0
- package/docs/roadmap.md +2 -1
- package/docs/safety-gyms.md +41 -0
- package/docs/specifications.md +27 -11
- package/docs/testing.md +19 -5
- package/docs/tooling.md +36 -22
- package/docs/weather-api.md +65 -0
- package/docs/web-library-gaps.md +1 -1
- package/docs/web.md +54 -18
- package/docs/writing-docs.md +49 -0
- package/examples/{hello/.aug-spec/august/0.19.0 → approved-design/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
- package/examples/approved-design/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/approved-design/.aug-spec/manifest.json +3 -3
- package/examples/approved-design/counters.aug +5 -4
- package/examples/approved-design/counters.aug.md +25 -132
- package/examples/approved-design/domain/app.aug +2 -1
- package/examples/approved-design/domain/app.aug.md +10 -80
- package/examples/approved-design/domain/export.aug +1 -0
- package/examples/approved-design/domain/export.aug.md +4 -20
- package/examples/approved-design/domain/models.aug +1 -0
- package/examples/approved-design/domain/models.aug.md +3 -25
- package/examples/approved-design/domain/numbers.aug +3 -2
- package/examples/approved-design/domain/numbers.aug.md +19 -116
- package/examples/approved-design/main.aug +1 -0
- package/examples/approved-design/main.aug.md +12 -95
- package/examples/benchmark/.aug-spec/manifest.json +1 -1
- package/examples/benchmark/main.aug +1 -0
- package/examples/benchmark/main.aug.md +6 -36
- package/examples/cli-args/.aug-spec/manifest.json +1 -1
- package/examples/cli-args/main.aug +1 -0
- package/examples/cli-args/main.aug.md +5 -32
- package/examples/collections/.aug-spec/manifest.json +1 -1
- package/examples/collections/main.aug +1 -0
- package/examples/collections/main.aug.md +6 -36
- package/examples/{generic-di/.aug-spec/august/0.19.0 → developer-workflow/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
- package/examples/developer-workflow/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/developer-workflow/.aug-spec/manifest.json +3 -3
- package/examples/developer-workflow/calculator.aug +3 -2
- package/examples/developer-workflow/calculator.aug.md +28 -189
- package/examples/developer-workflow/logging/console.aug +2 -1
- package/examples/developer-workflow/logging/console.aug.md +7 -57
- package/examples/developer-workflow/logging/export.aug +1 -0
- package/examples/developer-workflow/logging/export.aug.md +3 -15
- package/examples/developer-workflow/logging/logger.aug +1 -0
- package/examples/developer-workflow/logging/logger.aug.md +6 -46
- package/examples/developer-workflow/main.aug +1 -0
- package/examples/developer-workflow/main.aug.md +10 -68
- package/examples/drop/.aug-spec/manifest.json +1 -1
- package/examples/drop/main.aug +1 -0
- package/examples/drop/main.aug.md +6 -28
- package/examples/drop/resource.aug +1 -0
- package/examples/drop/resource.aug.md +6 -34
- package/examples/errors/.aug-spec/manifest.json +1 -1
- package/examples/errors/errors.aug +2 -1
- package/examples/errors/errors.aug.md +4 -27
- package/examples/errors/main.aug +1 -0
- package/examples/errors/main.aug.md +6 -29
- package/examples/ffi/.aug-spec/manifest.json +1 -1
- package/examples/ffi/main.aug +1 -0
- package/examples/ffi/main.aug.md +5 -21
- package/examples/ffi/native.aug +2 -1
- package/examples/ffi/native.aug.md +5 -35
- package/examples/{approved-design/.aug-spec/august/0.19.0 → generic-di/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
- package/examples/generic-di/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/generic-di/.aug-spec/manifest.json +3 -3
- package/examples/generic-di/main.aug +1 -0
- package/examples/generic-di/main.aug.md +8 -40
- package/examples/generic-di/types.aug +3 -2
- package/examples/generic-di/types.aug.md +18 -97
- package/examples/generics/.aug-spec/manifest.json +1 -1
- package/examples/generics/main.aug +1 -0
- package/examples/generics/main.aug.md +9 -48
- package/examples/generics/types.aug +4 -3
- package/examples/generics/types.aug.md +18 -104
- package/examples/{developer-workflow/.aug-spec/august/0.19.0 → hello/.aug-spec/august/0.21.0}/io/contracts.aug +4 -3
- package/examples/hello/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/hello/.aug-spec/manifest.json +3 -3
- package/examples/hello/app/export.aug +1 -0
- package/examples/hello/app/export.aug.md +3 -13
- package/examples/hello/app/greeter.aug +2 -1
- package/examples/hello/app/greeter.aug.md +10 -94
- package/examples/hello/logging/console.aug +2 -1
- package/examples/hello/logging/console.aug.md +7 -55
- package/examples/hello/logging/export.aug +1 -0
- package/examples/hello/logging/export.aug.md +3 -15
- package/examples/hello/logging/logger.aug +1 -0
- package/examples/hello/logging/logger.aug.md +6 -48
- package/examples/hello/main.aug +1 -0
- package/examples/hello/main.aug.md +8 -40
- package/examples/interceptors/.aug-spec/august/0.21.0/io/contracts.aug +37 -0
- package/examples/interceptors/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/interceptors/.aug-spec/manifest.json +3 -3
- package/examples/interceptors/app.aug +3 -2
- package/examples/interceptors/app.aug.md +15 -141
- package/examples/interceptors/interceptors.aug +3 -2
- package/examples/interceptors/interceptors.aug.md +19 -152
- package/examples/interceptors/logging.aug +2 -1
- package/examples/interceptors/logging.aug.md +10 -79
- package/examples/interceptors/main.aug +1 -0
- package/examples/interceptors/main.aug.md +9 -66
- package/examples/native-blake3/.aug-spec/manifest.json +16 -0
- package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.1/native.abi.json +29 -0
- package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/api.aug +14 -0
- package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/api.aug.md +34 -0
- package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.aug +4 -0
- package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.aug.md +8 -0
- package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/native.abi.json +29 -0
- package/examples/native-blake3/AGENTS.md +5 -0
- package/examples/native-blake3/aug.lock.json +253 -0
- package/examples/native-blake3/hashing.aug +11 -0
- package/examples/native-blake3/hashing.aug.md +25 -0
- package/examples/native-blake3/main.aug +8 -0
- package/examples/native-blake3/main.aug.md +13 -0
- package/examples/native-pytorch/.aug-spec/manifest.json +18 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.1/native.abi.json +142 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.3/native.abi.json +142 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/api.aug +101 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/api.aug.md +160 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.aug +3 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.aug.md +8 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.aug +6 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.aug.md +13 -0
- package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/native.abi.json +142 -0
- package/examples/native-pytorch/AGENTS.md +5 -0
- package/examples/native-pytorch/aug.lock.json +309 -0
- package/examples/native-pytorch/main.aug +8 -0
- package/examples/native-pytorch/main.aug.md +13 -0
- package/examples/native-pytorch/tensors.aug +23 -0
- package/examples/native-pytorch/tensors.aug.md +35 -0
- package/examples/native-sqlite/.aug-spec/manifest.json +18 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.2/native.abi.json +100 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/api.aug +48 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/api.aug.md +91 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.aug +3 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.aug.md +8 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.aug +8 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.aug.md +22 -0
- package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/native.abi.json +100 -0
- package/examples/native-sqlite/AGENTS.md +5 -0
- package/examples/native-sqlite/aug.lock.json +236 -0
- package/examples/native-sqlite/database.aug +15 -0
- package/examples/native-sqlite/database.aug.md +27 -0
- package/examples/native-sqlite/main.aug +8 -0
- package/examples/native-sqlite/main.aug.md +13 -0
- package/examples/native-zlib/.aug-spec/manifest.json +16 -0
- package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.1/native.abi.json +57 -0
- package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/api.aug +29 -0
- package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/api.aug.md +54 -0
- package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.aug +4 -0
- package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.aug.md +8 -0
- package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/native.abi.json +57 -0
- package/examples/native-zlib/AGENTS.md +5 -0
- package/examples/native-zlib/aug.lock.json +236 -0
- package/examples/native-zlib/compression.aug +15 -0
- package/examples/native-zlib/compression.aug.md +27 -0
- package/examples/native-zlib/main.aug +10 -0
- package/examples/native-zlib/main.aug.md +13 -0
- package/examples/new-syntax/.aug-spec/august/0.21.0/io/contracts.aug +37 -0
- package/examples/new-syntax/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/new-syntax/.aug-spec/manifest.json +3 -3
- package/examples/new-syntax/console.aug +2 -1
- package/examples/new-syntax/console.aug.md +7 -53
- package/examples/new-syntax/greeter.aug +2 -1
- package/examples/new-syntax/greeter.aug.md +10 -74
- package/examples/new-syntax/logger.aug +1 -0
- package/examples/new-syntax/logger.aug.md +6 -46
- package/examples/new-syntax/main.aug +1 -0
- package/examples/new-syntax/main.aug.md +9 -54
- package/examples/new-syntax/math.aug +2 -1
- package/examples/new-syntax/math.aug.md +3 -24
- package/examples/oidc-login/.aug-spec/manifest.json +13 -13
- package/examples/oidc-login/.aug-spec/packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/store.aug.md +71 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +17 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +125 -0
- package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/contracts.aug +12 -11
- package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/contracts.aug.md +244 -0
- package/examples/oidc-login/.aug-spec/{august/0.19.0/crypto → packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40}/jose.aug +6 -5
- package/examples/oidc-login/.aug-spec/packages/@git/url_9ef654c66d34ab8f5527/0.0.0-git.b14a0f9aa41f1ce58bd51133bcdc424033e40d40/jose.aug.md +71 -0
- package/examples/oidc-login/.aug-spec/packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301/contracts.aug.md +30 -0
- package/examples/oidc-login/aug.lock.json +100 -0
- package/examples/oidc-login/client/contracts.aug +1 -0
- package/examples/oidc-login/client/contracts.aug.md +9 -66
- package/examples/oidc-login/client/endpoints.aug +6 -5
- package/examples/oidc-login/client/endpoints.aug.md +13 -145
- package/examples/oidc-login/client/export.aug +1 -0
- package/examples/oidc-login/client/export.aug.md +4 -24
- package/examples/oidc-login/client/login.aug +7 -6
- package/examples/oidc-login/client/login.aug.md +25 -303
- package/examples/oidc-login/client/logout.aug +5 -4
- package/examples/oidc-login/client/logout.aug.md +13 -135
- package/examples/oidc-login/client/protocol.aug +7 -6
- package/examples/oidc-login/client/protocol.aug.md +36 -283
- package/examples/oidc-login/client/session.aug +5 -4
- package/examples/oidc-login/client/session.aug.md +12 -139
- package/examples/oidc-login/client/views.aug +3 -2
- package/examples/oidc-login/client/views.aug.md +8 -57
- package/examples/oidc-login/common/export.aug +1 -0
- package/examples/oidc-login/common/export.aug.md +5 -27
- package/examples/oidc-login/common/headers.aug +4 -3
- package/examples/oidc-login/common/headers.aug.md +9 -67
- package/examples/oidc-login/common/keys.aug +6 -5
- package/examples/oidc-login/common/keys.aug.md +29 -165
- package/examples/oidc-login/common/settings.aug +2 -1
- package/examples/oidc-login/common/settings.aug.md +5 -39
- package/examples/oidc-login/common/views.aug +2 -1
- package/examples/oidc-login/common/views.aug.md +4 -28
- package/examples/oidc-login/main.aug +6 -16
- package/examples/oidc-login/main.aug.md +17 -146
- package/examples/oidc-login/main.yaml +7 -0
- package/examples/oidc-login/provider/authorization.aug +7 -6
- package/examples/oidc-login/provider/authorization.aug.md +23 -238
- package/examples/oidc-login/provider/contracts.aug +1 -0
- package/examples/oidc-login/provider/contracts.aug.md +23 -158
- package/examples/oidc-login/provider/credentials.aug +3 -2
- package/examples/oidc-login/provider/credentials.aug.md +9 -53
- package/examples/oidc-login/provider/discovery.aug +4 -3
- package/examples/oidc-login/provider/discovery.aug.md +11 -118
- package/examples/oidc-login/provider/export.aug +1 -0
- package/examples/oidc-login/provider/export.aug.md +6 -34
- package/examples/oidc-login/provider/token.aug +6 -5
- package/examples/oidc-login/provider/token.aug.md +16 -204
- package/examples/oidc-login/provider/userinfo.aug +4 -3
- package/examples/oidc-login/provider/userinfo.aug.md +10 -92
- package/examples/oidc-login/provider/views.aug +3 -2
- package/examples/oidc-login/provider/views.aug.md +8 -52
- package/examples/ownership/.aug-spec/manifest.json +1 -1
- package/examples/ownership/counter.aug +3 -2
- package/examples/ownership/counter.aug.md +12 -66
- package/examples/ownership/main.aug +1 -0
- package/examples/ownership/main.aug.md +6 -31
- package/examples/ownership-transfer/.aug-spec/august/0.21.0/io/contracts.aug +37 -0
- package/examples/ownership-transfer/.aug-spec/august/0.21.0/io/contracts.aug.md +82 -0
- package/examples/ownership-transfer/.aug-spec/manifest.json +3 -3
- package/examples/ownership-transfer/main.aug +1 -0
- package/examples/ownership-transfer/main.aug.md +9 -53
- package/examples/ownership-transfer/resource.aug +2 -1
- package/examples/ownership-transfer/resource.aug.md +12 -71
- package/examples/packages/app/.aug-spec/manifest.json +1 -1
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +2 -1
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +9 -51
- package/examples/packages/app/main.aug +1 -0
- package/examples/packages/app/main.aug.md +6 -26
- package/examples/packages/math/.aug-spec/manifest.json +1 -1
- package/examples/packages/math/aug-package.json +1 -1
- package/examples/packages/math/src/arithmetic.aug +2 -1
- package/examples/packages/math/src/arithmetic.aug.md +9 -51
- package/examples/packages/math/src/export.aug +1 -0
- package/examples/packages/math/src/export.aug.md +3 -13
- package/examples/visibility/.aug-spec/manifest.json +1 -1
- package/examples/visibility/counter.aug +4 -3
- package/examples/visibility/counter.aug.md +12 -68
- package/examples/visibility/main.aug +1 -0
- package/examples/visibility/main.aug.md +6 -32
- package/examples/weather-api/.aug-spec/manifest.json +8 -0
- package/examples/weather-api/AGENTS.md +17 -0
- package/examples/weather-api/README.md +19 -0
- package/examples/weather-api/forecasts.aug +47 -0
- package/examples/weather-api/forecasts.aug.md +32 -0
- package/examples/weather-api/main.aug +4 -0
- package/examples/weather-api/main.aug.md +15 -0
- package/examples/weather-api/main.yaml +5 -0
- package/examples/weather-api/weather.http +5 -0
- package/native/compiler-packs.json +43 -0
- package/package.json +4 -4
- package/runtime/aug_http.c +48 -21
- package/runtime/aug_http_ir.c +30 -0
- package/runtime/aug_http_ir.h +18 -0
- package/runtime/aug_ir.c +209 -0
- package/runtime/aug_ir.h +89 -0
- package/runtime/aug_json.c +6 -1
- package/runtime/aug_runtime.c +82 -16
- package/runtime/aug_runtime.h +16 -2
- package/runtime/aug_tasks.c +38 -7
- package/runtime/aug_values.c +12 -6
- package/scripts/bootstrap-native.mjs +184 -106
- package/scripts/native-setup.mjs +98 -0
- package/scripts/native-toolchain.mjs +28 -0
- package/src/ast.js +1 -1
- package/src/builtins.js +1 -1
- package/src/checker.js +369 -100
- package/src/cli.js +198 -26
- package/src/codegen.js +32 -7
- package/src/compiler-packs.js +66 -0
- package/src/config.js +3 -3
- package/src/contracts.js +10 -0
- package/src/editor.js +86 -22
- package/src/fixes.js +90 -2
- package/src/formatter.js +23 -10
- package/src/git-http.js +137 -0
- package/src/git-packages.js +118 -0
- package/src/help.js +33 -24
- package/src/http-contracts.js +14 -0
- package/src/http-policies.js +5 -5
- package/src/ir-types.js +5 -0
- package/src/ir-verify.js +277 -0
- package/src/ir.js +962 -0
- package/src/libraries.js +1 -1
- package/src/llvm-debug.js +101 -0
- package/src/llvm-native.js +152 -0
- package/src/llvm-platform.js +20 -0
- package/src/llvm.js +781 -0
- package/src/lsp.js +14 -5
- package/src/native-artifacts.js +207 -0
- package/src/native-bindings.js +189 -0
- package/src/native-contracts.js +295 -0
- package/src/native-declarations.js +68 -0
- package/src/native-facts.js +63 -0
- package/src/native.js +19 -13
- package/src/navigation.js +4 -2
- package/src/openapi.js +5 -4
- package/src/package-locking.js +88 -0
- package/src/package-manager.js +267 -68
- package/src/parser.js +32 -6
- package/src/policies.js +3 -3
- package/src/project-init.js +78 -4
- package/src/project.js +11 -9
- package/src/runtime-abi.js +23 -0
- package/src/runtime-adapters.js +18 -0
- package/src/schemas.js +24 -17
- package/src/semantic.js +54 -5
- package/src/snippets.js +60 -0
- package/src/spec-hints.js +56 -0
- package/src/spec-tree.js +241 -0
- package/src/spec.js +669 -305
- package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +0 -103
- package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +0 -925
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +0 -434
- package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +0 -103
- package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +0 -374
- package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +0 -150
- package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +0 -532
- package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +0 -395
- package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +0 -791
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +0 -266
- package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +0 -55
- package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +0 -250
- package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +0 -96
- package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +0 -420
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +0 -36
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +0 -316
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/memory → packages/@git/url_0eb7c89453c87681ed15/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/store.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/json → packages/@git/url_2d3c37c690c0fa115be1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/web → packages/@git/url_897efafd565158fc4908/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
- /package/examples/oidc-login/.aug-spec/{august/0.19.0/time → packages/@git/url_c092cd151499c4e1d8a1/0.0.0-git.a39fc582565d4fca40be4f75fa304d71adc69301}/contracts.aug +0 -0
package/src/ir.js
ADDED
|
@@ -0,0 +1,962 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { relative, resolve } from 'node:path';
|
|
3
|
+
import { isStatement, fieldsOf, initializationOf } from "./ast.js";
|
|
4
|
+
import { typeName } from "./ast.js";
|
|
5
|
+
import { errorNames, builtinProperties } from "./builtins.js";
|
|
6
|
+
import { DataSchemas, schemaType } from "./schemas.js";
|
|
7
|
+
import { runtimeAdapters, adapterSymbol } from "./runtime-adapters.js";
|
|
8
|
+
import { generateOpenApi, apiExplorer, apiExplorerScript } from "./openapi.js";
|
|
9
|
+
import { actionSchema, actionTransport } from "./actions.js";
|
|
10
|
+
import { httpPolicyNames } from "./http-policies.js";
|
|
11
|
+
import { interceptorChain, InterceptorInvocation } from "./interceptors.js";
|
|
12
|
+
import { verifyIR } from "./ir-verify.js";
|
|
13
|
+
import { isIRScalar } from "./ir-types.js";
|
|
14
|
+
const dynamicType = { id: 'compiler:dynamic', name: 'Data', args: [], nullable: true, optional: false };
|
|
15
|
+
const scalarType = (name) => ({ id: 'builtin:' + name, name, args: [], nullable: false, optional: false });
|
|
16
|
+
const irType = (type) => ({ id: type.id, name: type.name, args: type.args.map(irType), nullable: type.nullable, optional: !!type.optional });
|
|
17
|
+
export class BackendUnsupported extends Error {
|
|
18
|
+
span;
|
|
19
|
+
code = 'BACKEND_UNSUPPORTED';
|
|
20
|
+
constructor(span, feature) { super('LLVM preview does not support ' + feature + '. No C fallback occurred.'); this.span = span; }
|
|
21
|
+
}
|
|
22
|
+
/** Checked, resolved execution IR. Source AST and semantic facts remain read-only. */
|
|
23
|
+
export function lowerToIR(checked, options = {}) {
|
|
24
|
+
if (checked.diagnostics.some(d => d.severity !== 'warning'))
|
|
25
|
+
throw new Error('Cannot lower a rejected August project');
|
|
26
|
+
const ir = new Lowering(checked, options).lower();
|
|
27
|
+
verifyIR(ir);
|
|
28
|
+
return ir;
|
|
29
|
+
}
|
|
30
|
+
class Lowering {
|
|
31
|
+
checked;
|
|
32
|
+
names = new Map();
|
|
33
|
+
functions = [];
|
|
34
|
+
schemas;
|
|
35
|
+
components = new Set();
|
|
36
|
+
routes = [];
|
|
37
|
+
coverage = new Map();
|
|
38
|
+
options;
|
|
39
|
+
constructor(checked, options) { this.checked = checked; this.options = options; let i = 0; for (const def of checked.project.definitions.values())
|
|
40
|
+
this.names.set(def.id, 'aug_fn_' + i++); this.schemas = new DataSchemas(checked.project, def => this.name(def)); }
|
|
41
|
+
name(def) { return this.names.get(def.id); }
|
|
42
|
+
method(def, name) { return this.name(def) + '_' + name; }
|
|
43
|
+
binding(key) { const i = this.checked.bindings.findIndex(b => b.key === key); if (i < 0)
|
|
44
|
+
throw new Error('Missing checked binding ' + key); return 'aug_resolve_' + i; }
|
|
45
|
+
definition(file, name) { return this.checked.project.scopes.get(file)?.get(name); }
|
|
46
|
+
lower() {
|
|
47
|
+
const active = new Set();
|
|
48
|
+
const visit = (file) => { if (active.has(file))
|
|
49
|
+
return; active.add(file); for (const item of this.checked.project.files.get(file)?.items ?? [])
|
|
50
|
+
if (item.kind === 'import')
|
|
51
|
+
for (const d of this.checked.project.imports.get(item) ?? [])
|
|
52
|
+
visit(d.file); };
|
|
53
|
+
for (const file of this.checked.project.files.values())
|
|
54
|
+
if (!file.builtin)
|
|
55
|
+
visit(file.path);
|
|
56
|
+
for (const def of this.checked.project.definitions.values()) {
|
|
57
|
+
if (!active.has(def.file))
|
|
58
|
+
continue;
|
|
59
|
+
const node = def.node;
|
|
60
|
+
if (node.kind === 'function') {
|
|
61
|
+
if (node.body)
|
|
62
|
+
this.add(def, this.name(def), node, node.params, node.body);
|
|
63
|
+
else if (node.externC && this.checked.interceptorPlans.get(node)?.length) {
|
|
64
|
+
const body = new FunctionLowering(this, def.file, node.span);
|
|
65
|
+
node.params.forEach((param, index) => body.parameter(param, index));
|
|
66
|
+
body.nativeBody(def);
|
|
67
|
+
this.functions.push(body.finish(interceptorChain(this.name(def), this.checked.interceptorPlans.get(node) ?? []).body));
|
|
68
|
+
this.layers(node, this.name(def), node.params, false);
|
|
69
|
+
}
|
|
70
|
+
if (node.endpoint) {
|
|
71
|
+
const body = new FunctionLowering(this, def.file, node.span);
|
|
72
|
+
body.endpoint(def);
|
|
73
|
+
this.functions.push(body.finish(this.name(def) + '_http'));
|
|
74
|
+
this.components.add('http');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (node.kind === 'class' || node.kind === 'interceptor') {
|
|
78
|
+
const methods = node.methods.filter(method => node.kind !== 'interceptor' || method.name !== 'around');
|
|
79
|
+
for (const entry of this.checked.defaults.get(def.id)?.values() ?? [])
|
|
80
|
+
if (!methods.some(m => m.name === entry.method.name))
|
|
81
|
+
methods.push(entry.method);
|
|
82
|
+
for (const method of methods)
|
|
83
|
+
if (method.body)
|
|
84
|
+
this.add(def, this.method(def, method.name), method, method.params, method.body, true);
|
|
85
|
+
const body = new FunctionLowering(this, def.file, node.span, def);
|
|
86
|
+
node.fields.forEach((param, i) => body.parameter(param, i));
|
|
87
|
+
body.instruction({ op: 'object', out: 0, type: def.id, fields: fieldsOf(node).map(f => f.name), owned: fieldsOf(node).map(f => f.ownership === 'own'), methods: methods.map(m => ({ name: m.name, function: this.method(def, m.name) })), record: node.kind === 'class' && !!node.record });
|
|
88
|
+
node.fields.forEach((param, i) => { body.runtime('SET_FIELD', [0, body.parameters[i]], undefined, i); if (param.ownership === 'own')
|
|
89
|
+
body.instruction({ op: 'clear', slot: body.parameters[i] }); });
|
|
90
|
+
node.fields.forEach(param => body.locals.delete(param.name));
|
|
91
|
+
body.locals.set('self', 0);
|
|
92
|
+
if (node.kind === 'class')
|
|
93
|
+
for (const stmt of initializationOf(node))
|
|
94
|
+
body.statement(stmt);
|
|
95
|
+
if (node.kind === 'class' && node.record)
|
|
96
|
+
body.runtime('FREEZE', [0]);
|
|
97
|
+
const chain = node.kind === 'class' ? interceptorChain(this.name(def), this.checked.interceptorPlans.get(node) ?? []) : { body: this.name(def) };
|
|
98
|
+
this.functions.push({ ...body.finish(chain.body), failedResult: true });
|
|
99
|
+
if (node.kind === 'class')
|
|
100
|
+
this.layers(node, this.name(def), node.fields, false);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.checked.bindings.forEach((binding, index) => {
|
|
104
|
+
const body = new FunctionLowering(this, binding.declaration.span.file, binding.declaration.span);
|
|
105
|
+
if (binding.lifetime !== 'fresh') {
|
|
106
|
+
body.instruction({ op: 'binding-get', out: 0, index });
|
|
107
|
+
const create = body.block(), done = body.block();
|
|
108
|
+
body.terminate({ op: 'null', input: 0, then: create, otherwise: done });
|
|
109
|
+
body.enter(done);
|
|
110
|
+
body.terminate({ op: 'jump', target: 'cleanup' });
|
|
111
|
+
body.enter(create);
|
|
112
|
+
}
|
|
113
|
+
const args = binding.constructorKeys.map(key => body.call(this.binding(key), []));
|
|
114
|
+
body.instruction({ op: 'call', out: 0, function: this.name(binding.target), args });
|
|
115
|
+
body.checkError();
|
|
116
|
+
if (binding.lifetime !== 'fresh')
|
|
117
|
+
body.instruction({ op: 'binding-set', input: 0, index });
|
|
118
|
+
this.functions.push(body.finish('aug_resolve_' + index));
|
|
119
|
+
});
|
|
120
|
+
const main = this.checked.project.main;
|
|
121
|
+
if (!main)
|
|
122
|
+
throw new Error('LLVM executable requires main.aug');
|
|
123
|
+
const body = new FunctionLowering(this, main.path, { file: main.path, start: 0, end: main.source.length, line: 1, column: 1 });
|
|
124
|
+
for (let index = 0; index <= main.items.length; index++) {
|
|
125
|
+
if (this.checked.project.testBodyStart === index)
|
|
126
|
+
body.runtime('TEST_CASE', []);
|
|
127
|
+
const stmt = main.items[index];
|
|
128
|
+
if (stmt && isStatement(stmt))
|
|
129
|
+
body.statement(stmt);
|
|
130
|
+
}
|
|
131
|
+
this.functions.push(body.finish('aug_main_body'));
|
|
132
|
+
const project = this.checked.project, scopes = [...project.packages.scopes.values()];
|
|
133
|
+
const hashes = [...project.files.values()].map(f => {
|
|
134
|
+
const scope = scopes.find(s => f.path.startsWith(s.sourceRoot + '/'));
|
|
135
|
+
const path = scope ? scope.name + '@' + scope.version + '/' + relative(scope.sourceRoot, f.path) : f.builtin ? 'august/' + relative(project.stdlibRoot, f.path) : relative(project.root, f.path);
|
|
136
|
+
return [path.replaceAll('\\', '/'), createHash('sha256').update(f.source).digest('hex')];
|
|
137
|
+
}).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
|
|
138
|
+
const dependencies = scopes.map(s => ({ name: s.name, version: s.version, digest: s.digest, native: s.native?.bindingsSha256 })).sort((a, b) => a.name.localeCompare(b.name, 'en'));
|
|
139
|
+
const web = project.config.web, tls = Object.fromEntries(Object.entries(web.tls).map(([key, value]) => [key, value ? resolve(project.root, value) : '']));
|
|
140
|
+
return { format: 1, sourceRevision: createHash('sha256').update(JSON.stringify({ sources: hashes, configuration: project.config, dependencies })).digest('hex'), functions: this.functions, main: 'aug_main_body', bindings: this.checked.bindings.map((b, i) => ({ function: 'aug_resolve_' + i, shared: b.lifetime === 'shared' })), scoped: this.checked.bindings.map(b => b.lifetime === 'scoped'), test: !!this.checked.project.testMode, schemas: this.schemas.nodes, components: [...this.components].sort(), routes: this.routes, web: { ...web, tls }, coverage: [...this.coverage.values()].sort((a, b) => a.file.localeCompare(b.file, 'en') || a.line - b.line) };
|
|
141
|
+
}
|
|
142
|
+
policy(plan) {
|
|
143
|
+
const options = plan.options;
|
|
144
|
+
return { kind: httpPolicyNames.indexOf(plan.name) + 1, permission: String(options.permission ?? ''), amount: Number(options.requests ?? options.milliseconds ?? 0), seconds: Number(options.seconds ?? 0), credentials: !!options.credentials, origins: (options.origins ?? []).join('\n'), headers: (options.headers ?? []).map(header => header.toLowerCase()).join(', ') };
|
|
145
|
+
}
|
|
146
|
+
routeTable(file, names) {
|
|
147
|
+
this.components.add('http');
|
|
148
|
+
const name = 'aug_routes_' + this.routes.length;
|
|
149
|
+
const items = names.map(name => {
|
|
150
|
+
const def = this.definition(file, name), fn = def.node, endpoint = fn.endpoint;
|
|
151
|
+
return { method: endpoint.method, path: endpoint.path, function: this.name(def) + '_http', stream: endpoint.streams ? fn.returns.name === 'ServerEvent' ? 1 : fn.returns.name === 'Bytes' ? 2 : 3 : 0, status: endpoint.status, policies: (this.checked.httpPolicies.get(fn) ?? []).map(plan => this.policy(plan)) };
|
|
152
|
+
});
|
|
153
|
+
// Reserve its name before adding generated documentation handlers.
|
|
154
|
+
this.routes.push({ name, items });
|
|
155
|
+
const config = this.checked.project.config.openapi;
|
|
156
|
+
const assets = config.enabled ? [
|
|
157
|
+
{ path: config.path, type: 'application/json', content: JSON.stringify(generateOpenApi(this.checked).document) },
|
|
158
|
+
{ path: config.docs, type: 'text/html; charset=utf-8', content: apiExplorer(config.path, config.docs + '/client.js') },
|
|
159
|
+
{ path: config.docs + '/client.js', type: 'application/javascript; charset=utf-8', content: apiExplorerScript }
|
|
160
|
+
] : [];
|
|
161
|
+
if (this.checked.actions.size)
|
|
162
|
+
assets.push({ path: '/__aug/actions.js', type: 'application/javascript; charset=utf-8', content: actionTransport });
|
|
163
|
+
assets.forEach((asset, index) => {
|
|
164
|
+
const body = new FunctionLowering(this, file, this.checked.project.main.items[0]?.span ?? { file, start: 0, end: 0, line: 1, column: 1 });
|
|
165
|
+
const bytes = body.runtime('STRING_BYTES', [body.literal(asset.content)]), headers = body.runtime('HTTP_HEADERS', []);
|
|
166
|
+
const typed = body.runtime('HTTP_HEADERS_WITH', [headers, body.literal('content-type'), body.literal(asset.type)]);
|
|
167
|
+
const result = body.runtime('HTTP_RESPONSE', [bytes, body.literal(null, { kind: 'int', text: '200' }), typed]);
|
|
168
|
+
body.instruction({ op: 'copy', out: 0, input: result });
|
|
169
|
+
const fn = name + '_asset_' + index;
|
|
170
|
+
this.functions.push(body.finish(fn));
|
|
171
|
+
items.push({ method: 'GET', path: asset.path, function: fn, stream: 0, status: 200, policies: [] });
|
|
172
|
+
});
|
|
173
|
+
return name;
|
|
174
|
+
}
|
|
175
|
+
add(def, name, method, params, stmts, receiver = false) {
|
|
176
|
+
const body = new FunctionLowering(this, method.span.file, method.span, receiver ? def : undefined);
|
|
177
|
+
body.sourceName = method.name;
|
|
178
|
+
if (receiver) {
|
|
179
|
+
body.receiver = body.slot();
|
|
180
|
+
body.locals.set('self', body.receiver);
|
|
181
|
+
}
|
|
182
|
+
params.forEach((p, i) => body.parameter(p, i));
|
|
183
|
+
stmts.forEach(s => body.statement(s));
|
|
184
|
+
this.functions.push(body.finish(interceptorChain(name, this.checked.interceptorPlans.get(method) ?? []).body));
|
|
185
|
+
this.layers(method, name, params, receiver);
|
|
186
|
+
}
|
|
187
|
+
layers(node, name, params, receiver) {
|
|
188
|
+
for (const entry of interceptorChain(name, this.checked.interceptorPlans.get(node) ?? []).entries) {
|
|
189
|
+
const body = new FunctionLowering(this, entry.layer.definition.file, entry.layer.around.span, entry.layer.definition);
|
|
190
|
+
body.sourceName = node.name + ' [' + entry.layer.definition.name + ']';
|
|
191
|
+
if (receiver) {
|
|
192
|
+
body.receiver = body.slot();
|
|
193
|
+
body.locals.set('self', body.receiver);
|
|
194
|
+
}
|
|
195
|
+
params.forEach((param, index) => body.parameter(param, index));
|
|
196
|
+
body.interceptor(entry.layer, params, entry.next);
|
|
197
|
+
entry.layer.around.body.forEach(stmt => body.statement(stmt));
|
|
198
|
+
this.functions.push(body.finish(entry.name));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
class FunctionLowering {
|
|
203
|
+
generator;
|
|
204
|
+
file;
|
|
205
|
+
span;
|
|
206
|
+
owner;
|
|
207
|
+
parameters = [];
|
|
208
|
+
receiver;
|
|
209
|
+
locals = new Map();
|
|
210
|
+
owned = new Set();
|
|
211
|
+
values = [];
|
|
212
|
+
variables = [];
|
|
213
|
+
scopes = [];
|
|
214
|
+
debugScope;
|
|
215
|
+
sourceName;
|
|
216
|
+
continuation;
|
|
217
|
+
constructionNext = false;
|
|
218
|
+
constructorResults = new Set();
|
|
219
|
+
slots = 1;
|
|
220
|
+
sequence = 0;
|
|
221
|
+
source;
|
|
222
|
+
error = 'cleanup';
|
|
223
|
+
returning = 'cleanup';
|
|
224
|
+
blocks = [];
|
|
225
|
+
current;
|
|
226
|
+
constructor(generator, file, span, owner) { this.generator = generator; this.file = file; this.span = span; this.source = span; this.owner = owner; this.values.push({ storage: 'rooted-value', type: dynamicType, span }); this.current = { name: 'entry_body', instructions: [] }; this.blocks.push(this.current); }
|
|
227
|
+
slot(type = dynamicType) { this.values.push({ storage: 'rooted-value', type, span: this.source }); return this.slots++; }
|
|
228
|
+
block() { return 'block_' + this.sequence++; }
|
|
229
|
+
enter(name) { this.current = { name, instructions: [] }; this.blocks.push(this.current); }
|
|
230
|
+
terminate(terminator) { this.current.terminator = terminator; }
|
|
231
|
+
instruction(value) { if (this.current.terminator)
|
|
232
|
+
this.enter(this.block()); this.current.instructions.push({ ...value, span: this.source, debugScope: this.debugScope }); }
|
|
233
|
+
local(name, slot, span, type = this.values[slot].type) {
|
|
234
|
+
this.locals.set(name, slot);
|
|
235
|
+
this.values[slot].type = type;
|
|
236
|
+
const variable = this.variables.length;
|
|
237
|
+
this.variables.push({ name, slot, span, type, scope: this.debugScope });
|
|
238
|
+
const source = this.source;
|
|
239
|
+
this.source = span;
|
|
240
|
+
this.instruction({ op: 'debug-variable', variable });
|
|
241
|
+
this.source = source;
|
|
242
|
+
}
|
|
243
|
+
parameter(param, index) { const type = irType(schemaType(this.generator.checked.project, param.type, this.file)), slot = this.slot(type); this.parameters[index] = slot; this.locals.set(param.name, slot); this.variables.push({ name: param.name, slot, span: param.span, type, argument: index + 1 }); if (param.ownership === 'own')
|
|
244
|
+
this.owned.add(slot); }
|
|
245
|
+
checkError() { const errors = this.block(), next = this.block(); this.terminate({ op: 'cancel', then: this.returning, otherwise: errors }); this.enter(errors); this.terminate({ op: 'error', failed: this.error, success: next }); this.enter(next); }
|
|
246
|
+
runtime(operation, args, text, number, check = true) {
|
|
247
|
+
if (operation.startsWith('HTTP_'))
|
|
248
|
+
this.generator.components.add('http');
|
|
249
|
+
const comparisons = ['==', '!=', '<', '>', '<=', '>='], integers = args.length === 2 && args.every(slot => isIRScalar(this.values[slot].type) && this.values[slot].type.name === 'int');
|
|
250
|
+
const binary = operation === 'BINARY' && integers && (comparisons.includes(text) || ['+', '-', '*', '/'].includes(text));
|
|
251
|
+
const integerResult = ['LIST_LENGTH', 'TUPLE_LENGTH', 'SET_LENGTH', 'MAP_LENGTH', 'STRING_LENGTH', 'BYTES_LENGTH', 'JSON_INTEGER'].includes(operation);
|
|
252
|
+
const booleanResult = ['SET_CONTAINS', 'MAP_CONTAINS', 'STRING_STARTS_WITH', 'STRING_IS_TOKEN', 'IS_TYPE', 'JSON_BOOLEAN'].includes(operation);
|
|
253
|
+
const out = this.slot(integerResult ? scalarType('int') : booleanResult ? scalarType('bool') : binary ? scalarType(comparisons.includes(text) ? 'bool' : 'int') : dynamicType);
|
|
254
|
+
this.instruction({ op: 'runtime', out, operation, args, text, number });
|
|
255
|
+
if (check && !(binary && text !== '/'))
|
|
256
|
+
this.checkError();
|
|
257
|
+
return out;
|
|
258
|
+
}
|
|
259
|
+
call(name, args, receiver) { const out = this.slot(); this.instruction({ op: 'call', out, function: name, args, receiver }); this.checkError(); return out; }
|
|
260
|
+
literal(value, numeric) { const out = this.slot(numeric ? scalarType(numeric.kind) : typeof value === 'boolean' ? scalarType('bool') : dynamicType); this.instruction({ op: 'literal', out, value, numeric }); return out; }
|
|
261
|
+
fieldIndex(object, name) {
|
|
262
|
+
const node = this.generator.checked.expressionTypes.get(object)?.def?.node;
|
|
263
|
+
if (node?.kind === 'class' || node?.kind === 'interceptor') {
|
|
264
|
+
const i = fieldsOf(node).findIndex(f => f.name === name);
|
|
265
|
+
if (i >= 0)
|
|
266
|
+
return i;
|
|
267
|
+
}
|
|
268
|
+
const type = this.generator.checked.expressionTypes.get(object);
|
|
269
|
+
if (type?.kind === 'builtin') {
|
|
270
|
+
const index = builtinProperties[type.name]?.findIndex(field => field.name === name);
|
|
271
|
+
if (index !== undefined && index >= 0)
|
|
272
|
+
return index;
|
|
273
|
+
}
|
|
274
|
+
if (name === 'code')
|
|
275
|
+
return 0;
|
|
276
|
+
if (name === 'message')
|
|
277
|
+
return 1;
|
|
278
|
+
throw new BackendUnsupported(object.span, 'field ' + name);
|
|
279
|
+
}
|
|
280
|
+
field(name) { const node = this.owner?.node; if (node?.kind !== 'class' && node?.kind !== 'interceptor')
|
|
281
|
+
return; const i = fieldsOf(node).findIndex(f => f.name === name); return i < 0 ? undefined : i; }
|
|
282
|
+
arguments(expr, plan) {
|
|
283
|
+
const source = expr.args.map(a => this.expression(a));
|
|
284
|
+
return plan ? plan.sourceIndices.map((index, i) => {
|
|
285
|
+
if (index !== undefined)
|
|
286
|
+
return source[index];
|
|
287
|
+
const injected = plan.injectionSources?.[i];
|
|
288
|
+
if (injected?.startsWith('self.'))
|
|
289
|
+
return this.runtime('FIELD', [this.locals.get('self')], undefined, this.field(injected.slice(5)));
|
|
290
|
+
if (injected) {
|
|
291
|
+
const slot = this.locals.get(injected);
|
|
292
|
+
if (slot !== undefined)
|
|
293
|
+
return slot;
|
|
294
|
+
}
|
|
295
|
+
return plan.bindingKeys[i] ? this.call(this.generator.binding(plan.bindingKeys[i]), []) : this.literal(null);
|
|
296
|
+
}) : source;
|
|
297
|
+
}
|
|
298
|
+
expression(expr) {
|
|
299
|
+
const firstNewSlot = this.slots, result = this.expressionValue(expr), type = this.generator.checked.expressionTypes.get(expr);
|
|
300
|
+
if (result >= firstNewSlot && type)
|
|
301
|
+
this.values[result].type = irType(type);
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
expressionValue(expr) {
|
|
305
|
+
this.source = expr.span;
|
|
306
|
+
if (expr.kind === 'handle') {
|
|
307
|
+
const plan = this.generator.checked.actions.get(expr), endpoint = plan.endpoint.node.endpoint;
|
|
308
|
+
const metadata = { method: endpoint.method, path: endpoint.path, parameters: plan.parameters.map(({ param, type, form }) => ({ name: param.source?.name ?? param.name, source: param.source?.kind, form, schema: actionSchema(this.generator.checked.project, type) })) };
|
|
309
|
+
const values = expr.call.args.map(argument => argument.kind === 'formInput' ? this.literal(null) : this.expression(argument));
|
|
310
|
+
const args = plan.parameters.map(parameter => parameter.form || parameter.source === undefined ? this.literal(null) : values[parameter.source]);
|
|
311
|
+
return this.runtime('HTTP_ACTION', args, JSON.stringify(metadata));
|
|
312
|
+
}
|
|
313
|
+
if (expr.kind === 'markupText')
|
|
314
|
+
return this.literal(expr.text);
|
|
315
|
+
if (expr.kind === 'markup') {
|
|
316
|
+
const component = this.generator.checked.markupCalls.get(expr);
|
|
317
|
+
if (component)
|
|
318
|
+
return this.expression(component);
|
|
319
|
+
this.generator.components.add('http');
|
|
320
|
+
const names = expr.attributes.map(attribute => this.literal(attribute.name));
|
|
321
|
+
const values = expr.attributes.map(attribute => this.expression(attribute.value)), children = expr.children.map(child => this.expression(child)), out = this.slot();
|
|
322
|
+
this.instruction({ op: 'html', out, tag: expr.tag, attributes: names.flatMap((name, index) => [name, values[index]]), children });
|
|
323
|
+
this.checkError();
|
|
324
|
+
return out;
|
|
325
|
+
}
|
|
326
|
+
if (expr.kind === 'literal')
|
|
327
|
+
return typeof expr.value === 'number' ? this.literal(null, { kind: expr.numericType ?? 'int', text: expr.numericText ?? String(expr.value) }) : this.literal(expr.value);
|
|
328
|
+
if (expr.kind === 'name') {
|
|
329
|
+
const slot = this.locals.get(expr.name);
|
|
330
|
+
if (slot !== undefined)
|
|
331
|
+
return slot;
|
|
332
|
+
const index = this.field(expr.name);
|
|
333
|
+
if (index !== undefined)
|
|
334
|
+
return this.runtime('FIELD', [this.locals.get('self')], undefined, index);
|
|
335
|
+
throw new BackendUnsupported(expr.span, 'unresolved value ' + expr.name);
|
|
336
|
+
}
|
|
337
|
+
if (expr.kind === 'resolve')
|
|
338
|
+
return this.call(this.generator.binding(expr.name + (expr.typeArgs.length ? '<' + expr.typeArgs.map(typeName).join(',') + '>' : '')), []);
|
|
339
|
+
if (expr.kind === 'member')
|
|
340
|
+
return this.runtime('FIELD', [this.expression(expr.object)], undefined, this.fieldIndex(expr.object, expr.name));
|
|
341
|
+
if (expr.kind === 'unary') {
|
|
342
|
+
const input = this.expression(expr.value), type = this.values[input].type;
|
|
343
|
+
const pure = isIRScalar(type) && (type.name === 'int' && expr.op === '-' || type.name === 'bool' && expr.op === '!');
|
|
344
|
+
return this.runtime('UNARY', [input], expr.op, undefined, !pure);
|
|
345
|
+
}
|
|
346
|
+
if (expr.kind === 'binary') {
|
|
347
|
+
const left = this.expression(expr.left);
|
|
348
|
+
if (expr.op === '&&' || expr.op === '||') {
|
|
349
|
+
const out = this.slot();
|
|
350
|
+
this.instruction({ op: 'copy', out, input: left });
|
|
351
|
+
const evaluate = this.block(), after = this.block();
|
|
352
|
+
this.terminate({ op: 'branch', condition: left, then: expr.op === '&&' ? evaluate : after, otherwise: expr.op === '&&' ? after : evaluate });
|
|
353
|
+
this.enter(evaluate);
|
|
354
|
+
const right = this.expression(expr.right);
|
|
355
|
+
this.instruction({ op: 'copy', out, input: right });
|
|
356
|
+
this.terminate({ op: 'jump', target: after });
|
|
357
|
+
this.enter(after);
|
|
358
|
+
return out;
|
|
359
|
+
}
|
|
360
|
+
const right = this.expression(expr.right), a = this.values[left].type, b = this.values[right].type;
|
|
361
|
+
const pure = isIRScalar(a) && isIRScalar(b) && (a.name === 'int' && b.name === 'int' && ['+', '-', '*', '==', '!=', '<', '>', '<=', '>='].includes(expr.op) || a.name === 'bool' && b.name === 'bool' && ['==', '!='].includes(expr.op));
|
|
362
|
+
return this.runtime('BINARY', [left, right], expr.op, undefined, !pure);
|
|
363
|
+
}
|
|
364
|
+
if (expr.kind === 'collection') {
|
|
365
|
+
const values = expr.items.map(item => this.expression(item)), kind = this.generator.checked.expressionTypes.get(expr)?.name ?? expr.collection;
|
|
366
|
+
if (kind === 'Map') {
|
|
367
|
+
const out = this.runtime('MAP', []);
|
|
368
|
+
for (let i = 0; i < values.length; i += 2)
|
|
369
|
+
this.runtime('MAP_SET', [out, values[i], values[i + 1]]);
|
|
370
|
+
return out;
|
|
371
|
+
}
|
|
372
|
+
return this.runtime(kind.toUpperCase(), values);
|
|
373
|
+
}
|
|
374
|
+
if (expr.kind === 'wait') {
|
|
375
|
+
const tasks = expr.tasks.map(task => this.expression(task)), out = this.slot();
|
|
376
|
+
this.instruction({ op: 'wait', out, tasks });
|
|
377
|
+
this.checkError();
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
380
|
+
if (expr.kind === 'start' && expr.call.kind === 'call') {
|
|
381
|
+
const call = expr.call, receiver = call.callee.kind === 'member' ? this.expression(call.callee.object) : undefined;
|
|
382
|
+
// Capture evaluation and injected dependencies in the parent. The child
|
|
383
|
+
// receives those values; it never reevaluates an argument or resolves DI.
|
|
384
|
+
const args = this.arguments(call, this.generator.checked.callPlans.get(call));
|
|
385
|
+
const thunk = new FunctionLowering(this.generator, this.file, expr.span, this.owner);
|
|
386
|
+
if (receiver !== undefined)
|
|
387
|
+
thunk.receiver = thunk.slot();
|
|
388
|
+
args.forEach((_, i) => {
|
|
389
|
+
const slot = thunk.slot();
|
|
390
|
+
thunk.parameters[i] = slot;
|
|
391
|
+
if (this.generator.checked.callPlans.get(call)?.ownerships?.[i] === 'own')
|
|
392
|
+
thunk.owned.add(slot);
|
|
393
|
+
});
|
|
394
|
+
const result = thunk.invoke(call, thunk.receiver, [...thunk.parameters]);
|
|
395
|
+
thunk.instruction({ op: 'copy', out: 0, input: result });
|
|
396
|
+
if (thunk.owned.has(result))
|
|
397
|
+
thunk.instruction({ op: 'clear', slot: result });
|
|
398
|
+
const name = 'aug_task_thunk_' + this.generator.functions.length;
|
|
399
|
+
this.generator.functions.push(thunk.finish(name));
|
|
400
|
+
const out = this.slot();
|
|
401
|
+
this.instruction({ op: 'start', out, function: name, receiver, args, owned: args.map((_, i) => this.generator.checked.callPlans.get(call)?.ownerships?.[i] === 'own') });
|
|
402
|
+
this.generator.checked.callPlans.get(call)?.ownerships?.forEach((mode, i) => { if (mode === 'own')
|
|
403
|
+
this.instruction({ op: 'clear', slot: args[i] }); });
|
|
404
|
+
this.checkError();
|
|
405
|
+
return out;
|
|
406
|
+
}
|
|
407
|
+
if (expr.kind !== 'call')
|
|
408
|
+
throw new BackendUnsupported(expr.span, expr.kind + ' expressions');
|
|
409
|
+
const receiver = expr.callee.kind === 'member' ? this.expression(expr.callee.object) : undefined;
|
|
410
|
+
const args = expr.callee.kind === 'name' && expr.callee.name === 'next' ? expr.args.map(arg => this.expression(arg)) : this.arguments(expr, this.generator.checked.callPlans.get(expr));
|
|
411
|
+
return this.invoke(expr, receiver, args);
|
|
412
|
+
}
|
|
413
|
+
invoke(expr, receiver, args, unwrapped = false) {
|
|
414
|
+
this.source = expr.span;
|
|
415
|
+
if (expr.callee.kind === 'member') {
|
|
416
|
+
const type = this.generator.checked.expressionTypes.get(expr.callee.object), name = expr.callee.name;
|
|
417
|
+
if (type.kind === 'builtin' && (type.name === 'Json' && name === 'decode' || type.name === 'HttpRequest' && name === 'form')) {
|
|
418
|
+
const out = this.slot(), schema = this.generator.schemas.request(this.generator.checked.expressionTypes.get(expr));
|
|
419
|
+
if (name === 'form')
|
|
420
|
+
this.generator.components.add('http');
|
|
421
|
+
this.instruction({ op: 'decode', out, input: receiver, schema, format: name === 'form' ? 'form' : 'json' });
|
|
422
|
+
this.checkError();
|
|
423
|
+
return out;
|
|
424
|
+
}
|
|
425
|
+
const operations = {
|
|
426
|
+
'List.length': 'LIST_LENGTH', 'List.get': 'LIST_GET', 'List.at': 'LIST_AT', 'List.append': 'LIST_APPEND', 'Tuple.length': 'TUPLE_LENGTH', 'Tuple.get': 'TUPLE_GET',
|
|
427
|
+
'Set.length': 'SET_LENGTH', 'Set.add': 'SET_ADD', 'Set.contains': 'SET_CONTAINS', 'Map.length': 'MAP_LENGTH', 'Map.get': 'MAP_GET', 'Map.take': 'MAP_TAKE', 'Map.contains': 'MAP_CONTAINS', 'Map.set': 'MAP_SET',
|
|
428
|
+
'string.length': 'STRING_LENGTH', 'string.bytes': 'STRING_BYTES', 'string.split': 'STRING_SPLIT', 'string.startsWith': 'STRING_STARTS_WITH', 'string.isToken': 'STRING_IS_TOKEN',
|
|
429
|
+
'Bytes.length': 'BYTES_LENGTH', 'Bytes.text': 'BYTES_TEXT', 'Bytes.base64url': 'BYTES_BASE64URL',
|
|
430
|
+
'Json.stringify': 'JSON_STRINGIFY', 'Json.get': 'JSON_GET', 'Json.require': 'JSON_REQUIRE', 'Json.string': 'JSON_STRING',
|
|
431
|
+
'Json.integer': 'JSON_INTEGER', 'Json.boolean': 'JSON_BOOLEAN', 'Json.items': 'JSON_ITEMS',
|
|
432
|
+
'Headers.with': 'HTTP_HEADERS_WITH', 'Headers.get': 'HTTP_HEADERS_GET', 'Headers.all': 'HTTP_HEADERS_ALL', 'HttpTestClient.request': 'HTTP_CLIENT_REQUEST'
|
|
433
|
+
};
|
|
434
|
+
const operation = operations[type.name + '.' + name];
|
|
435
|
+
if (operation) {
|
|
436
|
+
const noFailure = ['LIST_LENGTH', 'LIST_AT', 'LIST_APPEND', 'TUPLE_LENGTH', 'SET_LENGTH', 'SET_ADD', 'SET_CONTAINS', 'MAP_LENGTH', 'MAP_SET', 'MAP_GET', 'MAP_TAKE', 'MAP_CONTAINS', 'STRING_LENGTH', 'STRING_BYTES', 'STRING_SPLIT', 'STRING_STARTS_WITH', 'STRING_IS_TOKEN', 'BYTES_LENGTH', 'BYTES_BASE64URL'].includes(operation);
|
|
437
|
+
return this.runtime(operation, [receiver, ...args], undefined, undefined, !noFailure);
|
|
438
|
+
}
|
|
439
|
+
args = this.transferArguments(expr, args, false);
|
|
440
|
+
const out = this.slot();
|
|
441
|
+
this.instruction({ op: 'method', out, receiver: receiver, name, args });
|
|
442
|
+
if (this.generator.checked.callPlans.get(expr)?.returnOwnership === 'own')
|
|
443
|
+
this.owned.add(out);
|
|
444
|
+
this.checkError();
|
|
445
|
+
return out;
|
|
446
|
+
}
|
|
447
|
+
if (expr.callee.kind !== 'name')
|
|
448
|
+
throw new BackendUnsupported(expr.span, 'indirect callable values');
|
|
449
|
+
const name = expr.callee.name;
|
|
450
|
+
if (name === 'next') {
|
|
451
|
+
const next = this.continuation, plan = this.generator.checked.callPlans.get(expr);
|
|
452
|
+
const { args: forwarded, transfers } = next.forward(plan.sourceIndices, args);
|
|
453
|
+
const argumentsList = [...forwarded];
|
|
454
|
+
for (const { original, replacement } of transfers) {
|
|
455
|
+
const temporary = this.slot();
|
|
456
|
+
this.instruction({ op: 'copy', out: temporary, input: replacement });
|
|
457
|
+
argumentsList[this.parameters.indexOf(original)] = temporary;
|
|
458
|
+
if (replacement !== original)
|
|
459
|
+
this.instruction({ op: 'drop', slot: original });
|
|
460
|
+
this.instruction({ op: 'clear', slot: original });
|
|
461
|
+
if (replacement !== original && this.owned.has(replacement))
|
|
462
|
+
this.instruction({ op: 'clear', slot: replacement });
|
|
463
|
+
}
|
|
464
|
+
const out = this.call(next.target, argumentsList, next.receiver);
|
|
465
|
+
if (this.constructionNext)
|
|
466
|
+
this.constructorResults.add(out);
|
|
467
|
+
if (plan.returnOwnership === 'own')
|
|
468
|
+
this.owned.add(out);
|
|
469
|
+
return out;
|
|
470
|
+
}
|
|
471
|
+
if (name === 'assert') {
|
|
472
|
+
this.instruction({ op: 'assert', input: args[0], expression: this.generator.checked.project.files.get(this.file)?.source.slice(expr.args[0].span.start, expr.args[0].span.end) ?? 'assertion' });
|
|
473
|
+
this.checkError();
|
|
474
|
+
return this.literal(null);
|
|
475
|
+
}
|
|
476
|
+
if (name === 'int')
|
|
477
|
+
return args[0];
|
|
478
|
+
if (errorNames.includes(name)) {
|
|
479
|
+
const out = this.slot();
|
|
480
|
+
this.instruction({ op: 'object', out, type: name, fields: [], owned: [], methods: [], record: false });
|
|
481
|
+
return out;
|
|
482
|
+
}
|
|
483
|
+
if (name === 'Shared') {
|
|
484
|
+
const result = this.runtime('SHARED', [args[0]]);
|
|
485
|
+
if (this.owned.has(args[0]))
|
|
486
|
+
this.instruction({ op: 'clear', slot: args[0] });
|
|
487
|
+
return result;
|
|
488
|
+
}
|
|
489
|
+
if (name === 'HttpTestClient') {
|
|
490
|
+
const endpoint = this.generator.checked.project.testEndpoint, out = this.slot(), routes = this.generator.routeTable(endpoint.file, [endpoint.name]);
|
|
491
|
+
this.instruction({ op: 'routes', out, name: routes });
|
|
492
|
+
this.checkError();
|
|
493
|
+
return out;
|
|
494
|
+
}
|
|
495
|
+
const builtins = { exit: 'EXIT', print: 'PRINT', arguments: 'ARGUMENTS', c_int: 'C_INT', read_file: 'READ_FILE', write_file: 'WRITE_FILE', base64url_decode: 'BASE64URL_DECODE', Json: 'JSON_WRAP', Headers: 'HTTP_HEADERS', HttpResponse: 'HTTP_RESPONSE', ServerEvent: 'HTTP_EVENT' };
|
|
496
|
+
if (builtins[name])
|
|
497
|
+
return this.runtime(builtins[name], args);
|
|
498
|
+
if (['List', 'Tuple', 'Set', 'Map'].includes(name))
|
|
499
|
+
return this.runtime(name.toUpperCase(), args);
|
|
500
|
+
const def = this.generator.definition(this.file, name);
|
|
501
|
+
if (!def)
|
|
502
|
+
throw new BackendUnsupported(expr.span, 'builtin ' + name);
|
|
503
|
+
if (def.node.kind === 'function' && def.node.externC) {
|
|
504
|
+
if (!unwrapped && this.generator.checked.interceptorPlans.get(def.node)?.length) {
|
|
505
|
+
const result = this.call(this.generator.name(def), this.transferArguments(expr, args, false));
|
|
506
|
+
if (def.node.returnOwnership === 'own')
|
|
507
|
+
this.owned.add(result);
|
|
508
|
+
return result;
|
|
509
|
+
}
|
|
510
|
+
const binding = this.generator.checked.native.functions.get(def.node), out = this.slot();
|
|
511
|
+
if (binding) {
|
|
512
|
+
args = this.transferArguments(expr, args, true);
|
|
513
|
+
const resources = {};
|
|
514
|
+
for (const [node, resource] of this.generator.checked.native.resources) {
|
|
515
|
+
if (this.generator.checked.native.providers.get(node) !== this.generator.checked.native.providers.get(def.node))
|
|
516
|
+
continue;
|
|
517
|
+
const definition = this.generator.definition(node.span.file, node.name);
|
|
518
|
+
resources[resource.module + '.' + resource.name] = { id: definition.id, release: resource.release };
|
|
519
|
+
}
|
|
520
|
+
const error = this.generator.checked.native.errors.get(def.node);
|
|
521
|
+
this.instruction({ op: 'native', out, binding, args, resources, error: error?.id, errorFactory: error && this.generator.name(error) });
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
if (def.node.valueAbi) {
|
|
525
|
+
// Compiler-owned adapters use the target pack's pointer thunks. Arbitrary
|
|
526
|
+
// aggregate C declarations remain unsupported, even on an LLVM host.
|
|
527
|
+
const adapters = {
|
|
528
|
+
_aug_json_parse: { types: ['string'], result: 'Json', operation: 'JSON_PARSE' },
|
|
529
|
+
_aug_time_now: { types: [], result: 'int', operation: 'TIME_NOW' }
|
|
530
|
+
};
|
|
531
|
+
const adapter = adapters[def.node.name];
|
|
532
|
+
const plain = (type) => !type.nullable && !type.optional && !type.args.length;
|
|
533
|
+
if (adapter && plain(def.node.returns) && def.node.returns.name === adapter.result && def.node.params.length === adapter.types.length && def.node.params.every((param, i) => plain(param.type) && param.type.name === adapter.types[i]))
|
|
534
|
+
this.instruction({ op: 'runtime', out, operation: adapter.operation, args });
|
|
535
|
+
else {
|
|
536
|
+
const entry = runtimeAdapters.find(entry => entry.name === def.node.name);
|
|
537
|
+
if (!entry || def.node.typeParams.length || def.node.returnOwnership !== 'managed' || typeName(def.node.returns) !== entry.returns || def.node.params.length !== entry.parameters.length || def.node.params.some((param, i) => param.ownership !== 'managed' || typeName(param.type) !== entry.parameters[i]))
|
|
538
|
+
throw new BackendUnsupported(expr.span, 'legacy AugValue native adapter ' + def.node.name + ' with this signature');
|
|
539
|
+
this.generator.components.add(entry.component);
|
|
540
|
+
this.instruction({ op: 'adapter', out, name: adapterSymbol(entry), args });
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else
|
|
544
|
+
this.instruction({ op: 'extern', out, name: def.node.name, types: def.node.params.map(p => p.type.name), result: def.node.returns.name, args });
|
|
545
|
+
}
|
|
546
|
+
if (def.node.returnOwnership === 'own')
|
|
547
|
+
this.owned.add(out);
|
|
548
|
+
this.checkError();
|
|
549
|
+
return out;
|
|
550
|
+
}
|
|
551
|
+
args = this.transferArguments(expr, args, false);
|
|
552
|
+
const out = this.slot();
|
|
553
|
+
this.instruction({ op: 'call', out, function: this.generator.name(def), args });
|
|
554
|
+
if (def.node.kind === 'function' && def.node.returnOwnership === 'own')
|
|
555
|
+
this.owned.add(out);
|
|
556
|
+
this.checkError();
|
|
557
|
+
return out;
|
|
558
|
+
}
|
|
559
|
+
transferArguments(expr, args, native) {
|
|
560
|
+
const transferred = [...args], plan = this.generator.checked.callPlans.get(expr);
|
|
561
|
+
plan?.ownerships?.forEach((mode, i) => {
|
|
562
|
+
if (mode !== 'own')
|
|
563
|
+
return;
|
|
564
|
+
const temporary = this.slot();
|
|
565
|
+
this.instruction({ op: 'copy', out: temporary, input: args[i] });
|
|
566
|
+
this.instruction({ op: 'clear', slot: args[i] });
|
|
567
|
+
transferred[i] = temporary;
|
|
568
|
+
// Native marshalling can reject the input before ownership crosses the ABI.
|
|
569
|
+
// The move helper clears this slot only after every input is valid.
|
|
570
|
+
if (native)
|
|
571
|
+
this.owned.add(temporary);
|
|
572
|
+
});
|
|
573
|
+
return transferred;
|
|
574
|
+
}
|
|
575
|
+
interceptor(layer, params, next) {
|
|
576
|
+
this.constructionNext = layer.constructorResultFresh === true;
|
|
577
|
+
this.continuation = new InterceptorInvocation(layer, params, [...this.parameters], next, this.receiver);
|
|
578
|
+
const dependencies = this.continuation.dependencies().map(slot => slot ?? this.literal(null));
|
|
579
|
+
const self = this.call(this.generator.name(layer.definition), dependencies);
|
|
580
|
+
this.locals.set('self', self);
|
|
581
|
+
for (const input of this.continuation.inputs()) {
|
|
582
|
+
if (input.reuseOwnedSlot) {
|
|
583
|
+
this.locals.set(input.name, input.slot);
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
const slot = this.slot();
|
|
587
|
+
this.locals.set(input.name, slot);
|
|
588
|
+
this.instruction({ op: 'copy', out: slot, input: input.slot ?? this.literal(null) });
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
nativeBody(def) {
|
|
592
|
+
const call = { kind: 'call', callee: { kind: 'name', name: def.name, span: def.node.span }, args: [], argLabels: [], typeArgs: [], span: def.node.span };
|
|
593
|
+
const result = this.invoke(call, undefined, [...this.parameters], true);
|
|
594
|
+
this.instruction({ op: 'copy', out: 0, input: result });
|
|
595
|
+
if (this.owned.has(result))
|
|
596
|
+
this.instruction({ op: 'clear', slot: result });
|
|
597
|
+
}
|
|
598
|
+
scoped(stmts, composition = false, setup, span) {
|
|
599
|
+
const locals = new Map(this.locals), owned = new Set(this.owned), parent = this.debugScope;
|
|
600
|
+
const first = span ?? stmts[0]?.span ?? this.source, last = stmts.at(-1)?.span;
|
|
601
|
+
this.debugScope = 'scope_' + this.scopes.length;
|
|
602
|
+
this.scopes.push({ name: this.debugScope, parent, span: { ...first, end: last?.end ?? first.end } });
|
|
603
|
+
setup?.();
|
|
604
|
+
for (const stmt of stmts)
|
|
605
|
+
this.statement(stmt);
|
|
606
|
+
if (composition && !this.current.terminator)
|
|
607
|
+
this.instruction({ op: 'scope', action: 'join' });
|
|
608
|
+
if (!this.current.terminator)
|
|
609
|
+
for (const slot of this.owned)
|
|
610
|
+
if (!owned.has(slot))
|
|
611
|
+
this.instruction({ op: 'drop', slot });
|
|
612
|
+
this.locals.clear();
|
|
613
|
+
for (const [name, slot] of locals)
|
|
614
|
+
this.locals.set(name, slot);
|
|
615
|
+
this.debugScope = parent;
|
|
616
|
+
}
|
|
617
|
+
endpoint(def) {
|
|
618
|
+
const fn = def.node, endpoint = fn.endpoint, request = this.slot(), failed = this.block(), finished = this.block();
|
|
619
|
+
this.parameters.push(request);
|
|
620
|
+
this.error = failed;
|
|
621
|
+
this.returning = failed;
|
|
622
|
+
this.instruction({ op: 'scope', action: 'enter' });
|
|
623
|
+
const args = fn.params.map(() => this.slot());
|
|
624
|
+
fn.params.forEach((param, index) => {
|
|
625
|
+
if (!param.injected)
|
|
626
|
+
return;
|
|
627
|
+
const type = schemaType(this.generator.checked.project, param.type, def.file);
|
|
628
|
+
const key = type.name + (type.args.length ? '<' + type.args.map(arg => arg.name).join(',') + '>' : '');
|
|
629
|
+
const value = this.call(this.generator.binding(key), []);
|
|
630
|
+
this.instruction({ op: 'copy', out: args[index], input: value });
|
|
631
|
+
});
|
|
632
|
+
for (const policy of this.generator.checked.httpPolicies.get(fn) ?? []) {
|
|
633
|
+
this.instruction({ op: 'http-policy', policy: this.generator.policy(policy), args: [request, ...[0, 1].map(index => policy.dependencies[index] === undefined ? this.literal(null) : args[policy.dependencies[index]])] });
|
|
634
|
+
this.checkError();
|
|
635
|
+
}
|
|
636
|
+
fn.params.forEach((param, index) => {
|
|
637
|
+
if (param.injected)
|
|
638
|
+
return;
|
|
639
|
+
const schema = param.source.kind === 'request' ? undefined : this.generator.schemas.request(schemaType(this.generator.checked.project, param.type, def.file));
|
|
640
|
+
this.instruction({ op: 'http-bind', out: args[index], request, source: param.source.kind, name: param.source.name ?? param.name, schema });
|
|
641
|
+
this.checkError();
|
|
642
|
+
});
|
|
643
|
+
const result = this.call(this.generator.name(def), args), response = this.runtime('HTTP_RESPONSE_STATUS', [result, this.literal(null, { kind: 'int', text: String(endpoint.status) })]);
|
|
644
|
+
this.instruction({ op: 'copy', out: 0, input: response });
|
|
645
|
+
this.terminate({ op: 'jump', target: finished });
|
|
646
|
+
this.enter(failed);
|
|
647
|
+
this.instruction({ op: 'http-failure', out: 0, errors: endpoint.errors.map(error => ({ type: this.generator.definition(def.file, error.type.name)?.id ?? error.type.name, status: error.status })) });
|
|
648
|
+
this.terminate({ op: 'jump', target: finished });
|
|
649
|
+
this.enter(finished);
|
|
650
|
+
this.error = 'cleanup';
|
|
651
|
+
this.returning = 'cleanup';
|
|
652
|
+
const completed = this.runtime('HTTP_FINISH', [0]);
|
|
653
|
+
this.instruction({ op: 'copy', out: 0, input: completed });
|
|
654
|
+
}
|
|
655
|
+
tryAlways(stmt) {
|
|
656
|
+
const outerError = this.error, outerReturn = this.returning, owned = new Set(this.owned);
|
|
657
|
+
const caught = this.block(), failed = this.block(), returned = this.block(), cleanup = this.block(), finalized = this.block(), done = this.block();
|
|
658
|
+
const depth = this.slot(), locks = this.slot(), pending = this.slot(), cancelled = this.slot(), returning = this.slot(), failure = this.slot();
|
|
659
|
+
this.instruction({ op: 'scope-depth', out: depth });
|
|
660
|
+
this.instruction({ op: 'lock-depth', out: locks });
|
|
661
|
+
this.instruction({ op: 'copy', out: returning, input: this.literal(false) });
|
|
662
|
+
this.instruction({ op: 'copy', out: failure, input: this.literal(false) });
|
|
663
|
+
this.error = caught;
|
|
664
|
+
this.returning = returned;
|
|
665
|
+
this.scoped(stmt.body);
|
|
666
|
+
if (!this.current.terminator)
|
|
667
|
+
this.terminate({ op: 'jump', target: cleanup });
|
|
668
|
+
this.enter(caught);
|
|
669
|
+
this.instruction({ op: 'lock', action: 'restore', depth: locks });
|
|
670
|
+
this.instruction({ op: 'scope', action: 'join', depth });
|
|
671
|
+
for (const slot of this.owned)
|
|
672
|
+
if (!owned.has(slot))
|
|
673
|
+
this.instruction({ op: 'drop', slot });
|
|
674
|
+
this.instruction({ op: 'scope', action: 'restore', depth });
|
|
675
|
+
const handlers = this.block();
|
|
676
|
+
this.terminate({ op: 'cancel', then: failed, otherwise: handlers });
|
|
677
|
+
this.enter(handlers);
|
|
678
|
+
this.error = failed;
|
|
679
|
+
for (const clause of stmt.catches) {
|
|
680
|
+
const handler = this.block(), next = this.block();
|
|
681
|
+
this.terminate({ op: 'error-type', type: this.generator.definition(this.file, clause.type.name)?.id ?? clause.type.name, then: handler, otherwise: next });
|
|
682
|
+
this.enter(handler);
|
|
683
|
+
const error = this.slot();
|
|
684
|
+
this.instruction({ op: 'take-error', out: error });
|
|
685
|
+
this.scoped(clause.body, false, () => this.local(clause.name, error, clause.span, irType(schemaType(this.generator.checked.project, clause.type, this.file))), clause.span);
|
|
686
|
+
if (!this.current.terminator)
|
|
687
|
+
this.terminate({ op: 'jump', target: cleanup });
|
|
688
|
+
this.enter(next);
|
|
689
|
+
}
|
|
690
|
+
this.terminate({ op: 'jump', target: failed });
|
|
691
|
+
this.enter(failed);
|
|
692
|
+
this.instruction({ op: 'copy', out: failure, input: this.literal(true) });
|
|
693
|
+
this.terminate({ op: 'jump', target: cleanup });
|
|
694
|
+
this.enter(returned);
|
|
695
|
+
this.instruction({ op: 'copy', out: returning, input: this.literal(true) });
|
|
696
|
+
this.terminate({ op: 'jump', target: cleanup });
|
|
697
|
+
this.enter(cleanup);
|
|
698
|
+
this.instruction({ op: 'lock', action: 'restore', depth: locks });
|
|
699
|
+
this.instruction({ op: 'scope', action: 'join', depth });
|
|
700
|
+
for (const slot of this.owned)
|
|
701
|
+
if (!owned.has(slot))
|
|
702
|
+
this.instruction({ op: 'drop', slot });
|
|
703
|
+
this.instruction({ op: 'scope', action: 'restore', depth });
|
|
704
|
+
this.instruction({ op: 'error-state', action: 'save', error: pending, cancelled });
|
|
705
|
+
this.error = finalized;
|
|
706
|
+
this.returning = finalized;
|
|
707
|
+
this.scoped(stmt.always);
|
|
708
|
+
if (!this.current.terminator)
|
|
709
|
+
this.terminate({ op: 'jump', target: finalized });
|
|
710
|
+
this.enter(finalized);
|
|
711
|
+
this.instruction({ op: 'error-state', action: 'restore', error: pending, cancelled });
|
|
712
|
+
const returnedCheck = this.block(), errorCheck = this.block(), failedCheck = this.block();
|
|
713
|
+
this.terminate({ op: 'cancel', then: outerReturn, otherwise: returnedCheck });
|
|
714
|
+
this.enter(returnedCheck);
|
|
715
|
+
this.terminate({ op: 'branch', condition: returning, then: outerReturn, otherwise: errorCheck });
|
|
716
|
+
this.enter(errorCheck);
|
|
717
|
+
this.terminate({ op: 'error', failed: outerError, success: failedCheck });
|
|
718
|
+
this.enter(failedCheck);
|
|
719
|
+
this.terminate({ op: 'branch', condition: failure, then: outerError, otherwise: done });
|
|
720
|
+
this.enter(done);
|
|
721
|
+
this.error = outerError;
|
|
722
|
+
this.returning = outerReturn;
|
|
723
|
+
}
|
|
724
|
+
statement(stmt) {
|
|
725
|
+
this.source = stmt.span;
|
|
726
|
+
if (this.current.terminator)
|
|
727
|
+
this.enter(this.block());
|
|
728
|
+
if (this.generator.options.coverage && !this.generator.checked.project.files.get(stmt.span.file)?.builtin) {
|
|
729
|
+
this.generator.coverage.set(stmt.span.file + ':' + stmt.span.line, { file: stmt.span.file, line: stmt.span.line });
|
|
730
|
+
this.instruction({ op: 'cover', file: stmt.span.file, line: stmt.span.line });
|
|
731
|
+
}
|
|
732
|
+
if (stmt.kind === 'serve') {
|
|
733
|
+
const port = this.expression(stmt.port), routes = this.generator.routeTable(this.file, stmt.names);
|
|
734
|
+
this.instruction({ op: 'routes', name: routes, port });
|
|
735
|
+
this.checkError();
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
if (stmt.kind === 'yield') {
|
|
739
|
+
this.runtime('HTTP_YIELD', [this.expression(stmt.value)]);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (stmt.kind === 'expr') {
|
|
743
|
+
const value = this.expression(stmt.expr);
|
|
744
|
+
if (this.owned.has(value))
|
|
745
|
+
this.instruction({ op: 'drop', slot: value });
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (stmt.kind === 'assign') {
|
|
749
|
+
const value = this.expression(stmt.value);
|
|
750
|
+
this.source = stmt.span;
|
|
751
|
+
let targetOwns = stmt.ownership === 'own';
|
|
752
|
+
if (stmt.target.kind === 'name') {
|
|
753
|
+
const field = this.field(stmt.target.name);
|
|
754
|
+
if (!this.locals.has(stmt.target.name) && field !== undefined) {
|
|
755
|
+
targetOwns ||= this.owner?.node.kind === 'class' && fieldsOf(this.owner.node)[field].ownership === 'own';
|
|
756
|
+
this.runtime('SET_FIELD', [this.locals.get('self'), value], undefined, field);
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
let out = this.locals.get(stmt.target.name);
|
|
760
|
+
if (out === undefined) {
|
|
761
|
+
const type = stmt.declaredType ? irType(schemaType(this.generator.checked.project, stmt.declaredType, this.file)) : this.values[value].type;
|
|
762
|
+
out = this.slot(type);
|
|
763
|
+
this.local(stmt.target.name, out, stmt.span, type);
|
|
764
|
+
}
|
|
765
|
+
this.instruction({ op: 'copy', out, input: value });
|
|
766
|
+
if (stmt.ownership === 'own')
|
|
767
|
+
this.owned.add(out);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
else if (stmt.target.kind === 'member') {
|
|
771
|
+
const fieldName = stmt.target.name;
|
|
772
|
+
const node = this.generator.checked.expressionTypes.get(stmt.target.object)?.def?.node;
|
|
773
|
+
targetOwns ||= node?.kind === 'class' && fieldsOf(node).some(field => field.name === fieldName && field.ownership === 'own');
|
|
774
|
+
this.runtime('SET_FIELD', [this.expression(stmt.target.object), value], undefined, this.fieldIndex(stmt.target.object, stmt.target.name));
|
|
775
|
+
}
|
|
776
|
+
if (targetOwns && this.owned.has(value))
|
|
777
|
+
this.instruction({ op: 'clear', slot: value });
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
if (stmt.kind === 'return') {
|
|
781
|
+
if (stmt.value) {
|
|
782
|
+
const value = this.expression(stmt.value);
|
|
783
|
+
this.instruction({ op: 'copy', out: 0, input: value });
|
|
784
|
+
if (this.owned.has(value))
|
|
785
|
+
this.instruction({ op: 'clear', slot: value });
|
|
786
|
+
}
|
|
787
|
+
this.terminate({ op: 'jump', target: this.returning });
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
if (stmt.kind === 'throw') {
|
|
791
|
+
this.instruction({ op: 'throw', input: this.expression(stmt.value) });
|
|
792
|
+
this.terminate({ op: 'jump', target: this.error });
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
if (stmt.kind === 'unsafe' || stmt.kind === 'borrow') {
|
|
796
|
+
this.scoped(stmt.body);
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (stmt.kind === 'scope') {
|
|
800
|
+
this.instruction({ op: 'scope', action: 'enter' });
|
|
801
|
+
this.scoped(stmt.body, true);
|
|
802
|
+
if (!this.current.terminator) {
|
|
803
|
+
this.instruction({ op: 'scope', action: 'leave' });
|
|
804
|
+
this.checkError();
|
|
805
|
+
}
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (stmt.kind === 'lock') {
|
|
809
|
+
const value = this.runtime('SHARED_LOCK', [this.expression(stmt.value)]);
|
|
810
|
+
this.scoped(stmt.body, false, () => this.local(stmt.name, value, stmt.span), stmt.span);
|
|
811
|
+
if (!this.current.terminator) {
|
|
812
|
+
this.instruction({ op: 'lock', action: 'leave' });
|
|
813
|
+
this.checkError();
|
|
814
|
+
}
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
if (stmt.kind === 'if') {
|
|
818
|
+
const condition = this.expression(stmt.test), yes = this.block(), no = this.block(), done = this.block();
|
|
819
|
+
this.terminate({ op: 'branch', condition, then: yes, otherwise: no });
|
|
820
|
+
this.enter(yes);
|
|
821
|
+
this.scoped(stmt.then);
|
|
822
|
+
if (!this.current.terminator)
|
|
823
|
+
this.terminate({ op: 'jump', target: done });
|
|
824
|
+
this.enter(no);
|
|
825
|
+
this.scoped(stmt.otherwise);
|
|
826
|
+
if (!this.current.terminator)
|
|
827
|
+
this.terminate({ op: 'jump', target: done });
|
|
828
|
+
this.enter(done);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (stmt.kind === 'match') {
|
|
832
|
+
const value = this.expression(stmt.value), done = this.block();
|
|
833
|
+
// Match literals are checked constants. Keep the source ordering used by
|
|
834
|
+
// the reference backend, while evaluating the matched value only once.
|
|
835
|
+
const literals = stmt.cases.map(clause => clause.literal ? this.expression(clause.literal) : undefined);
|
|
836
|
+
for (const [index, clause] of stmt.cases.entries()) {
|
|
837
|
+
const body = this.block(), next = this.block();
|
|
838
|
+
if (clause.pattern === 'else')
|
|
839
|
+
this.terminate({ op: 'jump', target: body });
|
|
840
|
+
else if (clause.pattern === 'null' || clause.pattern === 'some')
|
|
841
|
+
this.terminate({ op: 'null', input: value, then: clause.pattern === 'null' ? body : next, otherwise: clause.pattern === 'null' ? next : body });
|
|
842
|
+
else {
|
|
843
|
+
const condition = clause.pattern === 'type' ? this.runtime('IS_TYPE', [value], this.generator.definition(this.file, clause.type.name)?.id ?? clause.type.name) : this.runtime('BINARY', [value, literals[index]], '==');
|
|
844
|
+
this.terminate({ op: 'branch', condition, then: body, otherwise: next });
|
|
845
|
+
}
|
|
846
|
+
this.enter(body);
|
|
847
|
+
this.scoped(clause.body, false, () => { if (clause.name)
|
|
848
|
+
this.local(clause.name, value, clause.span); }, clause.span);
|
|
849
|
+
if (!this.current.terminator)
|
|
850
|
+
this.terminate({ op: 'jump', target: done });
|
|
851
|
+
this.enter(next);
|
|
852
|
+
}
|
|
853
|
+
this.terminate({ op: 'jump', target: done });
|
|
854
|
+
this.enter(done);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (stmt.kind === 'while') {
|
|
858
|
+
const test = this.block(), body = this.block(), done = this.block();
|
|
859
|
+
this.terminate({ op: 'jump', target: test });
|
|
860
|
+
this.enter(test);
|
|
861
|
+
this.instruction({ op: 'checkpoint' });
|
|
862
|
+
this.checkError();
|
|
863
|
+
const condition = this.expression(stmt.test);
|
|
864
|
+
this.terminate({ op: 'branch', condition, then: body, otherwise: done });
|
|
865
|
+
this.enter(body);
|
|
866
|
+
this.scoped(stmt.body);
|
|
867
|
+
if (!this.current.terminator)
|
|
868
|
+
this.terminate({ op: 'jump', target: test });
|
|
869
|
+
this.enter(done);
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
if (stmt.kind === 'freeze') {
|
|
873
|
+
const value = this.expression(stmt.value), out = this.runtime('FREEZE', [value]);
|
|
874
|
+
this.local(stmt.name, out, stmt.span);
|
|
875
|
+
if (this.owned.has(value))
|
|
876
|
+
this.instruction({ op: 'clear', slot: value });
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
if (stmt.kind === 'destructure') {
|
|
880
|
+
const value = this.expression(stmt.value);
|
|
881
|
+
stmt.names.forEach((name, i) => this.local(name, this.runtime('TUPLE_GET', [value, this.literal(null, { kind: 'int', text: String(i) })]), stmt.span, this.values[value].type.args[i] ?? dynamicType));
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
if (stmt.kind === 'for') {
|
|
885
|
+
const iterable = this.expression(stmt.iterable), map = this.generator.checked.expressionTypes.get(stmt.iterable)?.name === 'Map' && stmt.names.length === 2;
|
|
886
|
+
const values = this.runtime(map ? 'MAP_ITER' : 'ITER', [iterable]), index = this.slot(scalarType('int')), one = this.literal(null, { kind: 'int', text: '1' });
|
|
887
|
+
this.instruction({ op: 'copy', out: index, input: this.literal(null, { kind: 'int', text: '0' }) });
|
|
888
|
+
const length = this.runtime('LIST_LENGTH', [values]), test = this.block(), body = this.block(), done = this.block();
|
|
889
|
+
this.terminate({ op: 'jump', target: test });
|
|
890
|
+
this.enter(test);
|
|
891
|
+
this.instruction({ op: 'checkpoint' });
|
|
892
|
+
this.checkError();
|
|
893
|
+
const condition = this.runtime('BINARY', [index, length], '<');
|
|
894
|
+
this.terminate({ op: 'branch', condition, then: body, otherwise: done });
|
|
895
|
+
this.enter(body);
|
|
896
|
+
this.scoped(stmt.body, false, () => {
|
|
897
|
+
// The private snapshot cannot be changed by source code. Its length
|
|
898
|
+
// guards this index; map snapshots contain an even number of cells.
|
|
899
|
+
// Source List.get still retains its checked bounds behavior.
|
|
900
|
+
if (map) {
|
|
901
|
+
stmt.names.forEach((name, i) => { this.local(name, this.runtime('LIST_AT', [values, index], undefined, undefined, false), stmt.span, this.values[iterable].type.args[i] ?? dynamicType); this.instruction({ op: 'copy', out: index, input: this.runtime('BINARY', [index, one], '+') }); });
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
const item = this.runtime('LIST_AT', [values, index], undefined, undefined, false);
|
|
905
|
+
stmt.names.forEach((name, i) => this.local(name, stmt.names.length === 1 ? item : this.runtime('TUPLE_GET', [item, this.literal(null, { kind: 'int', text: String(i) })]), stmt.span, (stmt.names.length === 1 ? this.values[iterable].type.args[0] : this.values[iterable].type.args[0]?.args[i]) ?? dynamicType));
|
|
906
|
+
this.instruction({ op: 'copy', out: index, input: this.runtime('BINARY', [index, one], '+') });
|
|
907
|
+
}
|
|
908
|
+
}, stmt.span);
|
|
909
|
+
if (!this.current.terminator)
|
|
910
|
+
this.terminate({ op: 'jump', target: test });
|
|
911
|
+
this.enter(done);
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
if (stmt.kind === 'try') {
|
|
915
|
+
if (stmt.always) {
|
|
916
|
+
this.tryAlways(stmt);
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
const outer = this.error, failed = this.block(), done = this.block(), owned = new Set(this.owned), depth = this.slot(), locks = this.slot();
|
|
920
|
+
this.instruction({ op: 'scope-depth', out: depth });
|
|
921
|
+
this.instruction({ op: 'lock-depth', out: locks });
|
|
922
|
+
this.error = failed;
|
|
923
|
+
this.scoped(stmt.body);
|
|
924
|
+
if (!this.current.terminator)
|
|
925
|
+
this.terminate({ op: 'jump', target: done });
|
|
926
|
+
this.enter(failed);
|
|
927
|
+
this.error = outer;
|
|
928
|
+
this.instruction({ op: 'lock', action: 'restore', depth: locks });
|
|
929
|
+
this.instruction({ op: 'scope', action: 'join', depth });
|
|
930
|
+
for (const slot of this.owned)
|
|
931
|
+
if (!owned.has(slot))
|
|
932
|
+
this.instruction({ op: 'drop', slot });
|
|
933
|
+
this.instruction({ op: 'scope', action: 'restore', depth });
|
|
934
|
+
stmt.catches.forEach(clause => {
|
|
935
|
+
const handler = this.block(), next = this.block();
|
|
936
|
+
this.terminate({ op: 'error-type', type: this.generator.definition(this.file, clause.type.name)?.id ?? clause.type.name, then: handler, otherwise: next });
|
|
937
|
+
this.enter(handler);
|
|
938
|
+
const error = this.slot();
|
|
939
|
+
this.instruction({ op: 'take-error', out: error });
|
|
940
|
+
this.scoped(clause.body, false, () => this.local(clause.name, error, clause.span, irType(schemaType(this.generator.checked.project, clause.type, this.file))), clause.span);
|
|
941
|
+
if (!this.current.terminator)
|
|
942
|
+
this.terminate({ op: 'jump', target: done });
|
|
943
|
+
this.enter(next);
|
|
944
|
+
});
|
|
945
|
+
this.terminate({ op: 'jump', target: outer });
|
|
946
|
+
this.enter(done);
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
const unreachable = stmt;
|
|
950
|
+
throw new Error('Unexpected August statement ' + JSON.stringify(unreachable));
|
|
951
|
+
}
|
|
952
|
+
finish(name) {
|
|
953
|
+
for (const value of this.values)
|
|
954
|
+
if (isIRScalar(value.type))
|
|
955
|
+
value.storage = 'scalar-value';
|
|
956
|
+
if (!this.current.terminator)
|
|
957
|
+
this.terminate({ op: 'jump', target: 'cleanup' });
|
|
958
|
+
this.enter('cleanup');
|
|
959
|
+
this.terminate({ op: 'return' });
|
|
960
|
+
return { name, sourceName: this.sourceName ?? this.owner?.name ?? (name === 'aug_main_body' ? 'main' : name), span: this.span, slots: this.slots, values: this.values, variables: this.variables, scopes: this.scopes, parameters: this.parameters, receiver: this.receiver, owned: [...this.owned], constructorResults: [...this.constructorResults], blocks: this.blocks };
|
|
961
|
+
}
|
|
962
|
+
}
|