Compare commits
22 Commits
0d9db5525c
...
2244f347c3
Author | SHA1 | Date |
---|---|---|
David Mak | 2244f347c3 | |
David Mak | ad183ae21c | |
David Mak | f97ce5aacb | |
Sebastien Bourdeauducq | 68556da5fd | |
David Mak | 983f080ea7 | |
David Mak | 031e660f18 | |
David Mak | b6dfcfcc38 | |
David Mak | c93ad152d7 | |
David Mak | 68b97347b1 | |
David Mak | 875d534de4 | |
Sebastien Bourdeauducq | adadf56e2b | |
Sebastien Bourdeauducq | 9f610745b7 | |
Sebastien Bourdeauducq | 98199768e3 | |
Sebastien Bourdeauducq | bfa9ceaae3 | |
Sebastien Bourdeauducq | 120f8da5c7 | |
Sebastien Bourdeauducq | cee62aa6c5 | |
Sebastien Bourdeauducq | fcda360ad6 | |
Sebastien Bourdeauducq | 87c20ada48 | |
Sebastien Bourdeauducq | 38e968cff6 | |
David Mak | 5c5620692f | |
David Mak | 0af1e37e99 | |
David Mak | 854e33ed48 |
|
@ -1,3 +1,3 @@
|
|||
__pycache__
|
||||
/target
|
||||
windows/msys2
|
||||
nix/windows/msys2
|
||||
|
|
|
@ -148,9 +148,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.7"
|
||||
version = "4.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
|
||||
checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -158,9 +158,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.7"
|
||||
version = "4.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
|
||||
checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -333,12 +333,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
|||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.6"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -399,9 +399,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
|||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
|
@ -432,7 +432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.2",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -588,15 +588,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
|||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.11"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
|
||||
|
||||
[[package]]
|
||||
name = "llvm-sys"
|
||||
version = "140.1.2"
|
||||
version = "140.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69b285f8682531b9b394dd9891977a2a28c47006e491bda944e1ca62ebab2664"
|
||||
checksum = "e3dc78e9857c0231ec11e3bdccf63870493fdc7d0570b0ea7d50bf5df0cb1a0c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lazy_static",
|
||||
|
@ -835,9 +835,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -1026,15 +1026,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.21"
|
||||
version = "0.38.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
|
||||
checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1063,18 +1063,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.192"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.192"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1118,9 +1118,9 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.1"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||
|
||||
[[package]]
|
||||
name = "string-interner"
|
||||
|
@ -1419,6 +1419,15 @@ dependencies = [
|
|||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
|
@ -1449,6 +1458,21 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -1461,6 +1485,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -1473,6 +1503,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -1485,6 +1521,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -1497,6 +1539,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -1509,6 +1557,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -1521,6 +1575,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -1533,6 +1593,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
|
@ -1544,18 +1610,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.25"
|
||||
version = "0.7.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557"
|
||||
checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.25"
|
||||
version = "0.7.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b"
|
||||
checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -23,7 +23,7 @@ After setting up Nix as above, use ``nix shell git+https://github.com/m-labs/art
|
|||
|
||||
### Windows
|
||||
|
||||
Install [MSYS2](https://www.msys2.org/), and open "MSYS2 MinGW x64". Edit ``/etc/pacman.conf`` to add:
|
||||
Install [MSYS2](https://www.msys2.org/), and open "MSYS2 CLANG64". Edit ``/etc/pacman.conf`` to add:
|
||||
```
|
||||
[artiq]
|
||||
SigLevel = Optional TrustAll
|
||||
|
@ -33,11 +33,9 @@ Server = https://msys2.m-labs.hk/artiq-nac3
|
|||
Then run the following commands:
|
||||
```
|
||||
pacman -Syu
|
||||
pacman -S mingw-w64-x86_64-artiq
|
||||
pacman -S mingw-w64-clang-x86_64-artiq
|
||||
```
|
||||
|
||||
Note: This build of NAC3 cannot be used with Anaconda Python nor the python.org binaries for Windows. Those Python versions are compiled with Visual Studio (MSVC) and their ABI is incompatible with the GNU ABI used in this build. We have no plans to support Visual Studio nor the MSVC ABI. If you need a MSVC build, please install the requisite bloated spyware from Microsoft and compile NAC3 yourself.
|
||||
|
||||
## For developers
|
||||
|
||||
This repository contains:
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1699343069,
|
||||
"narHash": "sha256-s7BBhyLA6MI6FuJgs4F/SgpntHBzz40/qV0xLPW6A1Q=",
|
||||
"lastModified": 1701389149,
|
||||
"narHash": "sha256-rU1suTIEd5DGCaAXKW6yHoCfR1mnYjOXQFOaH7M23js=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ec750fd01963ab6b20ee1f0cb488754e8036d89d",
|
||||
"rev": "5de0b32be6e85dc1a9404c75131316e4ffbc634c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"ref": "nixos-23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
22
flake.nix
22
flake.nix
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
description = "The third-generation ARTIQ compiler";
|
||||
|
||||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixpkgs-unstable;
|
||||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-23.11;
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
|
@ -9,7 +9,12 @@
|
|||
in rec {
|
||||
packages.x86_64-linux = rec {
|
||||
llvm-nac3 = pkgs.callPackage ./nix/llvm {};
|
||||
clang-unwrapped = pkgs.runCommandNoCC "clang-unwrapped" {} "mkdir -p $out/bin; ln -s ${pkgs.llvmPackages_14.clang-unwrapped}/bin/clang $out/bin/clang-unwrapped";
|
||||
llvm-tools-irrt = pkgs.runCommandNoCC "llvm-tools-irrt" {}
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
ln -s ${pkgs.llvmPackages_14.clang-unwrapped}/bin/clang $out/bin/clang-irrt
|
||||
ln -s ${pkgs.llvmPackages_14.llvm.out}/bin/llvm-as $out/bin/llvm-as-irrt
|
||||
'';
|
||||
nac3artiq = pkgs.python3Packages.toPythonModule (
|
||||
pkgs.rustPlatform.buildRustPackage rec {
|
||||
name = "nac3artiq";
|
||||
|
@ -19,7 +24,7 @@
|
|||
lockFile = ./Cargo.lock;
|
||||
};
|
||||
passthru.cargoLock = cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_14.clang packages.x86_64-linux.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3 ];
|
||||
nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_14.clang llvm-tools-irrt pkgs.llvmPackages_14.llvm.out llvm-nac3 ];
|
||||
buildInputs = [ pkgs.python3 llvm-nac3 ];
|
||||
checkInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy ps.scipy ])) ];
|
||||
checkPhase =
|
||||
|
@ -59,7 +64,7 @@
|
|||
name = "nac3artiq-instrumented";
|
||||
src = self;
|
||||
inherit (nac3artiq) cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3-instrumented ];
|
||||
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt llvm-nac3-instrumented ];
|
||||
buildInputs = [ pkgs.python3 llvm-nac3-instrumented ];
|
||||
cargoBuildFlags = [ "--package" "nac3artiq" "--features" "init-llvm-profile" ];
|
||||
doCheck = false;
|
||||
|
@ -87,8 +92,8 @@
|
|||
(pkgs.fetchFromGitHub {
|
||||
owner = "m-labs";
|
||||
repo = "artiq";
|
||||
rev = "5bbac04bef170cddb608b5dc8d9e6778cc7b31e8";
|
||||
sha256 = "sha256-TnRS2NrQaDiDzUsmfjkZh69xi2XC9v+4hnkedycAo0k=";
|
||||
rev = "4c189f8c0576111733bb6ff934035c080c8ccc58";
|
||||
sha256 = "sha256-gYGzmfaIoftKFDwn8AybUenYtIpux+tHGMu51WgwA8A=";
|
||||
})
|
||||
];
|
||||
buildInputs = [
|
||||
|
@ -121,7 +126,7 @@
|
|||
name = "nac3artiq-pgo";
|
||||
src = self;
|
||||
inherit (nac3artiq) cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3-pgo ];
|
||||
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt llvm-nac3-pgo ];
|
||||
buildInputs = [ pkgs.python3 llvm-nac3-pgo ];
|
||||
cargoBuildFlags = [ "--package" "nac3artiq" ];
|
||||
cargoTestFlags = [ "--package" "nac3ast" "--package" "nac3parser" "--package" "nac3core" "--package" "nac3artiq" ];
|
||||
|
@ -143,8 +148,7 @@
|
|||
# build dependencies
|
||||
packages.x86_64-linux.llvm-nac3
|
||||
llvmPackages_14.clang # demo
|
||||
packages.x86_64-linux.clang-unwrapped # IRRT
|
||||
pkgs.llvmPackages_14.llvm.out # IRRT
|
||||
packages.x86_64-linux.llvm-tools-irrt
|
||||
cargo
|
||||
rustc
|
||||
# runtime dependencies
|
||||
|
|
|
@ -10,7 +10,7 @@ from embedding_map import EmbeddingMap
|
|||
|
||||
|
||||
__all__ = [
|
||||
"Kernel", "KernelInvariant", "virtual",
|
||||
"Kernel", "KernelInvariant", "virtual", "ConstGeneric",
|
||||
"Option", "Some", "none", "UnwrapNoneError",
|
||||
"round64", "floor64", "ceil64",
|
||||
"extern", "kernel", "portable", "nac3",
|
||||
|
@ -67,6 +67,12 @@ def Some(v: T) -> Option[T]:
|
|||
|
||||
none = Option(None)
|
||||
|
||||
class _ConstGenericMarker:
|
||||
pass
|
||||
|
||||
def ConstGeneric(name, constraint):
|
||||
return TypeVar(name, _ConstGenericMarker, constraint)
|
||||
|
||||
def round64(x):
|
||||
return round(x)
|
||||
|
||||
|
|
|
@ -145,7 +145,8 @@ impl<'a> ArtiqCodeGenerator<'a> {
|
|||
let end_store = self.gen_store_target(
|
||||
ctx,
|
||||
&end,
|
||||
store_name.map(|name| format!("{name}.addr")).as_deref())?;
|
||||
store_name.map(|name| format!("{name}.addr")).as_deref())?
|
||||
.unwrap();
|
||||
ctx.builder.build_store(end_store, max);
|
||||
}
|
||||
|
||||
|
@ -261,7 +262,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||
node: ExprKind::Name { id: start, ctx: name_ctx.clone() },
|
||||
custom: Some(ctx.primitives.int64),
|
||||
};
|
||||
let start = self.gen_store_target(ctx, &start_expr, Some("start.addr"))?;
|
||||
let start = self
|
||||
.gen_store_target(ctx, &start_expr, Some("start.addr"))?
|
||||
.unwrap();
|
||||
ctx.builder.build_store(start, now);
|
||||
Ok(Some(start_expr)) as Result<_, String>
|
||||
},
|
||||
|
@ -274,7 +277,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||
node: ExprKind::Name { id: end, ctx: name_ctx.clone() },
|
||||
custom: Some(ctx.primitives.int64),
|
||||
};
|
||||
let end = self.gen_store_target(ctx, &end_expr, Some("end.addr"))?;
|
||||
let end = self
|
||||
.gen_store_target(ctx, &end_expr, Some("end.addr"))?
|
||||
.unwrap();
|
||||
ctx.builder.build_store(end, now);
|
||||
self.end = Some(end_expr);
|
||||
self.name_counter += 1;
|
||||
|
|
|
@ -75,6 +75,7 @@ pub struct PrimitivePythonId {
|
|||
list: u64,
|
||||
tuple: u64,
|
||||
typevar: u64,
|
||||
const_generic_dummy: u64,
|
||||
none: u64,
|
||||
exception: u64,
|
||||
generic_alias: (u64, u64),
|
||||
|
@ -877,6 +878,15 @@ impl Nac3 {
|
|||
.extract()
|
||||
.unwrap(),
|
||||
typevar: get_attr_id(typing_mod, "TypeVar"),
|
||||
const_generic_dummy: id_fn
|
||||
.call1((
|
||||
builtins_mod.getattr("globals")
|
||||
.and_then(|v| v.call0())
|
||||
.and_then(|v| v.get_item("_ConstGenericMarker"))
|
||||
.unwrap(),
|
||||
))
|
||||
.and_then(|v| v.extract())
|
||||
.unwrap(),
|
||||
int: get_attr_id(builtins_mod, "int"),
|
||||
int32: get_attr_id(numpy_mod, "int32"),
|
||||
int64: get_attr_id(numpy_mod, "int64"),
|
||||
|
|
|
@ -266,10 +266,12 @@ impl InnerResolver {
|
|||
Ok(Ok(ty))
|
||||
}
|
||||
|
||||
// handle python objects that represent types themselves
|
||||
// primitives and class types should be themselves, use `ty_id` to check,
|
||||
// TypeVars and GenericAlias(`A[int, bool]`) should use `ty_ty_id` to check
|
||||
// the `bool` value returned indicates whether they are instantiated or not
|
||||
/// handle python objects that represent types themselves
|
||||
///
|
||||
/// primitives and class types should be themselves, use `ty_id` to check,
|
||||
/// TypeVars and GenericAlias(`A[int, bool]`) should use `ty_ty_id` to check
|
||||
///
|
||||
/// the `bool` value returned indicates whether they are instantiated or not
|
||||
fn get_pyty_obj_type(
|
||||
&self,
|
||||
py: Python,
|
||||
|
@ -345,13 +347,21 @@ impl InnerResolver {
|
|||
}
|
||||
} else if ty_ty_id == self.primitive_ids.typevar {
|
||||
let name: &str = pyty.getattr("__name__").unwrap().extract().unwrap();
|
||||
let constraint_types = {
|
||||
let (constraint_types, is_const_generic) = {
|
||||
let constraints = pyty.getattr("__constraints__").unwrap();
|
||||
let mut result: Vec<Type> = vec![];
|
||||
let needs_defer = self.deferred_eval_store.needs_defer.load(Relaxed);
|
||||
|
||||
let mut is_const_generic = false;
|
||||
for i in 0usize.. {
|
||||
if let Ok(constr) = constraints.get_item(i) {
|
||||
if needs_defer {
|
||||
let constr_id: u64 = self.helper.id_fn.call1(py, (constr,))?.extract(py)?;
|
||||
if constr_id == self.primitive_ids.const_generic_dummy {
|
||||
is_const_generic = true;
|
||||
continue
|
||||
}
|
||||
|
||||
if !is_const_generic && needs_defer {
|
||||
result.push(unifier.get_dummy_var().0);
|
||||
} else {
|
||||
result.push({
|
||||
|
@ -375,17 +385,28 @@ impl InnerResolver {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if needs_defer {
|
||||
|
||||
if !is_const_generic && needs_defer {
|
||||
self.deferred_eval_store.store.write()
|
||||
.push((result.clone(),
|
||||
constraints.extract()?,
|
||||
pyty.getattr("__name__")?.extract::<String>()?
|
||||
))
|
||||
}
|
||||
result
|
||||
|
||||
(result, is_const_generic)
|
||||
};
|
||||
let res =
|
||||
unifier.get_fresh_var_with_range(&constraint_types, Some(name.into()), None).0;
|
||||
|
||||
let res = if is_const_generic {
|
||||
if constraint_types.len() != 1 {
|
||||
return Ok(Err(format!("ConstGeneric expects 1 argument, got {}", constraint_types.len())))
|
||||
}
|
||||
|
||||
unifier.get_fresh_const_generic_var(constraint_types[0], Some(name.into()), None).0
|
||||
} else {
|
||||
unifier.get_fresh_var_with_range(&constraint_types, Some(name.into()), None).0
|
||||
};
|
||||
|
||||
Ok(Ok((res, true)))
|
||||
} else if ty_ty_id == self.primitive_ids.generic_alias.0
|
||||
|| ty_ty_id == self.primitive_ids.generic_alias.1
|
||||
|
|
|
@ -26,7 +26,7 @@ pub struct Location {
|
|||
|
||||
impl fmt::Display for Location {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}: line {} column {}", self.file.0, self.row, self.column)
|
||||
write!(f, "{}:{}:{}", self.file.0, self.row, self.column)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ fn main() {
|
|||
"-o",
|
||||
"-",
|
||||
];
|
||||
let output = Command::new("clang-unwrapped")
|
||||
let output = Command::new("clang-irrt")
|
||||
.args(FLAG)
|
||||
.output()
|
||||
.map(|o| {
|
||||
|
@ -61,7 +61,7 @@ fn main() {
|
|||
file.write_all(filtered_output.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
let mut llvm_as = Command::new("llvm-as")
|
||||
let mut llvm_as = Command::new("llvm-as-irrt")
|
||||
.stdin(Stdio::piped())
|
||||
.arg("-o")
|
||||
.arg(out_path.join("irrt.bc"))
|
||||
|
|
|
@ -207,12 +207,12 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
generator: &mut dyn CodeGenerator,
|
||||
value: &Constant,
|
||||
ty: Type,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
) -> Option<BasicValueEnum<'ctx>> {
|
||||
match value {
|
||||
Constant::Bool(v) => {
|
||||
assert!(self.unifier.unioned(ty, self.primitives.bool));
|
||||
let ty = self.ctx.i8_type();
|
||||
ty.const_int(if *v { 1 } else { 0 }, false).into()
|
||||
Some(ty.const_int(if *v { 1 } else { 0 }, false).into())
|
||||
}
|
||||
Constant::Int(val) => {
|
||||
let ty = if self.unifier.unioned(ty, self.primitives.int32)
|
||||
|
@ -226,28 +226,33 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
ty.const_int(*val as u64, false).into()
|
||||
Some(ty.const_int(*val as u64, false).into())
|
||||
}
|
||||
Constant::Float(v) => {
|
||||
assert!(self.unifier.unioned(ty, self.primitives.float));
|
||||
let ty = self.ctx.f64_type();
|
||||
ty.const_float(*v).into()
|
||||
Some(ty.const_float(*v).into())
|
||||
}
|
||||
Constant::Tuple(v) => {
|
||||
let ty = self.unifier.get_ty(ty);
|
||||
let types =
|
||||
if let TypeEnum::TTuple { ty } = &*ty { ty.clone() } else { unreachable!() };
|
||||
let values = zip(types.into_iter(), v.iter())
|
||||
.map(|(ty, v)| self.gen_const(generator, v, ty))
|
||||
.map_while(|(ty, v)| self.gen_const(generator, v, ty))
|
||||
.collect_vec();
|
||||
let types = values.iter().map(BasicValueEnum::get_type).collect_vec();
|
||||
let ty = self.ctx.struct_type(&types, false);
|
||||
ty.const_named_struct(&values).into()
|
||||
|
||||
if values.len() == v.len() {
|
||||
let types = values.iter().map(BasicValueEnum::get_type).collect_vec();
|
||||
let ty = self.ctx.struct_type(&types, false);
|
||||
Some(ty.const_named_struct(&values).into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Constant::Str(v) => {
|
||||
assert!(self.unifier.unioned(ty, self.primitives.str));
|
||||
if let Some(v) = self.const_strings.get(v) {
|
||||
*v
|
||||
Some(*v)
|
||||
} else {
|
||||
let str_ptr =
|
||||
self.builder.build_global_string_ptr(v, "const").as_pointer_value().into();
|
||||
|
@ -256,9 +261,22 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
let val =
|
||||
ty.into_struct_type().const_named_struct(&[str_ptr, size.into()]).into();
|
||||
self.const_strings.insert(v.to_string(), val);
|
||||
val
|
||||
Some(val)
|
||||
}
|
||||
}
|
||||
Constant::Ellipsis => {
|
||||
let msg = self.gen_string(generator, "NotImplementedError");
|
||||
|
||||
self.raise_exn(
|
||||
generator,
|
||||
"0:NotImplementedError",
|
||||
msg,
|
||||
[None, None, None],
|
||||
self.current_loc,
|
||||
);
|
||||
|
||||
None
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -481,7 +499,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
generator: &mut dyn CodeGenerator,
|
||||
s: S,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
self.gen_const(generator, &nac3parser::ast::Constant::Str(s.into()), self.primitives.str)
|
||||
self.gen_const(generator, &nac3parser::ast::Constant::Str(s.into()), self.primitives.str).unwrap()
|
||||
}
|
||||
|
||||
pub fn raise_exn(
|
||||
|
@ -935,7 +953,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
expr: &Expr<Option<Type>>,
|
||||
) -> Result<BasicValueEnum<'ctx>, String> {
|
||||
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
|
||||
if let ExprKind::ListComp { elt, generators } = &expr.node {
|
||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||
|
||||
|
@ -949,9 +967,16 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(init_bb);
|
||||
|
||||
let Comprehension { target, iter, ifs, .. } = &generators[0];
|
||||
let iter_val = generator.gen_expr(ctx, iter)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, iter.custom.unwrap())?;
|
||||
let iter_val = if let Some(v) = generator.gen_expr(ctx, iter)? {
|
||||
v.to_basic_value_enum(ctx, generator, iter.custom.unwrap())?
|
||||
} else {
|
||||
for bb in [test_bb, body_bb, cont_bb] {
|
||||
ctx.builder.position_at_end(bb);
|
||||
ctx.builder.build_unreachable();
|
||||
}
|
||||
|
||||
return Ok(None)
|
||||
};
|
||||
let int32 = ctx.ctx.i32_type();
|
||||
let size_t = generator.get_size_type(ctx.ctx);
|
||||
let zero_size_t = size_t.const_zero();
|
||||
|
@ -994,7 +1019,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
list_content = ctx.build_gep_and_load(list, &[zero_size_t, zero_32], Some("listcomp.data.addr"))
|
||||
.into_pointer_value();
|
||||
|
||||
let i = generator.gen_store_target(ctx, target, Some("i.addr"))?;
|
||||
let i = generator.gen_store_target(ctx, target, Some("i.addr"))?.unwrap();
|
||||
ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init"));
|
||||
|
||||
ctx.builder.build_conditional_branch(
|
||||
|
@ -1049,12 +1074,25 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
generator.gen_assign(ctx, target, val.into())?;
|
||||
}
|
||||
|
||||
// Emits the content of `cont_bb`
|
||||
let emit_cont_bb = |ctx: &CodeGenContext| {
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
let len_ptr = unsafe {
|
||||
ctx.builder.build_gep(list, &[zero_size_t, int32.const_int(1, false)], "length")
|
||||
};
|
||||
ctx.builder.build_store(len_ptr, ctx.builder.build_load(index, "index"));
|
||||
};
|
||||
|
||||
for cond in ifs.iter() {
|
||||
let result = generator
|
||||
.gen_expr(ctx, cond)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, cond.custom.unwrap())?
|
||||
.into_int_value();
|
||||
let result = if let Some(v) = generator.gen_expr(ctx, cond)? {
|
||||
v.to_basic_value_enum(ctx, generator, cond.custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
// Bail if the predicate is an ellipsis - Emit cont_bb contents in case the
|
||||
// no element matches the predicate
|
||||
emit_cont_bb(ctx);
|
||||
|
||||
return Ok(None)
|
||||
};
|
||||
let result = generator.bool_to_i1(ctx, result);
|
||||
let succ = ctx.ctx.append_basic_block(current, "then");
|
||||
ctx.builder.build_conditional_branch(result, succ, test_bb);
|
||||
|
@ -1062,7 +1100,12 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(succ);
|
||||
}
|
||||
|
||||
let elem = generator.gen_expr(ctx, elt)?.unwrap();
|
||||
let Some(elem) = generator.gen_expr(ctx, elt)? else {
|
||||
// Similarly, bail if the generator expression is an ellipsis, but keep cont_bb contents
|
||||
emit_cont_bb(ctx);
|
||||
|
||||
return Ok(None)
|
||||
};
|
||||
let i = ctx.builder.build_load(index, "i").into_int_value();
|
||||
let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") };
|
||||
let val = elem.to_basic_value_enum(ctx, generator, elt.custom.unwrap())?;
|
||||
|
@ -1071,13 +1114,9 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
|||
.build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc"));
|
||||
ctx.builder.build_unconditional_branch(test_bb);
|
||||
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
let len_ptr = unsafe {
|
||||
ctx.builder.build_gep(list, &[zero_size_t, int32.const_int(1, false)], "length")
|
||||
};
|
||||
ctx.builder.build_store(len_ptr, ctx.builder.build_load(index, "index"));
|
||||
emit_cont_bb(ctx);
|
||||
|
||||
Ok(list.into())
|
||||
Ok(Some(list.into()))
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -1101,14 +1140,16 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||
let ty1 = ctx.unifier.get_representative(left.custom.unwrap());
|
||||
let ty2 = ctx.unifier.get_representative(right.custom.unwrap());
|
||||
let left_val = generator
|
||||
.gen_expr(ctx, left)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, left.custom.unwrap())?;
|
||||
let right_val = generator
|
||||
.gen_expr(ctx, right)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, right.custom.unwrap())?;
|
||||
let left_val = if let Some(v) = generator.gen_expr(ctx, left)? {
|
||||
v.to_basic_value_enum(ctx, generator, left.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let right_val = if let Some(v) = generator.gen_expr(ctx, right)? {
|
||||
v.to_basic_value_enum(ctx, generator, right.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
|
||||
// we can directly compare the types, because we've got their representatives
|
||||
// which would be unchanged until further unification, which we would never do
|
||||
|
@ -1211,7 +1252,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
Ok(Some(match &expr.node {
|
||||
ExprKind::Constant { value, .. } => {
|
||||
let ty = expr.custom.unwrap();
|
||||
ctx.gen_const(generator, value, ty).into()
|
||||
let Some(const_val) = ctx.gen_const(generator, value, ty) else {
|
||||
return Ok(None)
|
||||
};
|
||||
const_val.into()
|
||||
}
|
||||
ExprKind::Name { id, .. } if id == &"none".into() => {
|
||||
match (
|
||||
|
@ -1242,15 +1286,17 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
// we should use memcpy for that instead of generating thousands of stores
|
||||
let elements = elts
|
||||
.iter()
|
||||
.map(|x| {
|
||||
generator
|
||||
.gen_expr(ctx, x)
|
||||
.map_or_else(
|
||||
Err,
|
||||
|v| v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap())
|
||||
)
|
||||
})
|
||||
.map(|x| generator.gen_expr(ctx, x))
|
||||
.take_while(|v| !matches!(v, Ok(None)))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let elements = elements.into_iter().zip(elts)
|
||||
.map(|(v, x)| v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap()))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
if elements.len() < elts.len() {
|
||||
return Ok(None)
|
||||
}
|
||||
|
||||
let ty = if elements.is_empty() {
|
||||
if let TypeEnum::TList { ty } = &*ctx.unifier.get_ty(expr.custom.unwrap()) {
|
||||
ctx.get_llvm_type(generator, *ty)
|
||||
|
@ -1277,14 +1323,19 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
arr_str_ptr.into()
|
||||
}
|
||||
ExprKind::Tuple { elts, .. } => {
|
||||
let element_val = elts
|
||||
let elements_val = elts
|
||||
.iter()
|
||||
.map(|x| {
|
||||
generator
|
||||
.gen_expr(ctx, x)
|
||||
.map_or_else(Err, |v| v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap()))
|
||||
})
|
||||
.map(|x| generator.gen_expr(ctx, x))
|
||||
.take_while(|v| !matches!(v, Ok(None)))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let element_val = elements_val.into_iter().zip(elts)
|
||||
.map(|(v, x)| v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap()))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
if element_val.len() < elts.len() {
|
||||
return Ok(None)
|
||||
}
|
||||
|
||||
let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec();
|
||||
let tuple_ty = ctx.ctx.struct_type(&element_ty, false);
|
||||
let tuple_ptr = ctx.builder.build_alloca(tuple_ty, "tuple");
|
||||
|
@ -1302,8 +1353,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
ExprKind::Attribute { value, attr, .. } => {
|
||||
// note that we would handle class methods directly in calls
|
||||
match generator.gen_expr(ctx, value)?.unwrap() {
|
||||
ValueEnum::Static(v) => v.get_field(*attr, ctx).map_or_else(|| {
|
||||
match generator.gen_expr(ctx, value)? {
|
||||
Some(ValueEnum::Static(v)) => v.get_field(*attr, ctx).map_or_else(|| {
|
||||
let v = v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?;
|
||||
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
||||
Ok(ValueEnum::Dynamic(ctx.build_gep_and_load(
|
||||
|
@ -1312,7 +1363,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
None,
|
||||
))) as Result<_, String>
|
||||
}, Ok)?,
|
||||
ValueEnum::Dynamic(v) => {
|
||||
Some(ValueEnum::Dynamic(v)) => {
|
||||
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
||||
ValueEnum::Dynamic(ctx.build_gep_and_load(
|
||||
v.into_pointer_value(),
|
||||
|
@ -1320,15 +1371,16 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
None,
|
||||
))
|
||||
}
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
ExprKind::BoolOp { op, values } => {
|
||||
// requires conditional branches for short-circuiting...
|
||||
let left = generator
|
||||
.gen_expr(ctx, &values[0])?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, values[0].custom.unwrap())?
|
||||
.into_int_value();
|
||||
let left = if let Some(v) = generator.gen_expr(ctx, &values[0])? {
|
||||
v.to_basic_value_enum(ctx, generator, values[0].custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let left = generator.bool_to_i1(ctx, left);
|
||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||
let a_bb = ctx.ctx.append_basic_block(current, "a");
|
||||
|
@ -1340,45 +1392,62 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.builder.position_at_end(a_bb);
|
||||
let a = ctx.ctx.i8_type().const_int(1, false);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
ctx.builder.position_at_end(b_bb);
|
||||
let b = generator
|
||||
.gen_expr(ctx, &values[1])?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?
|
||||
.into_int_value();
|
||||
let b = generator.bool_to_i8(ctx, b);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
(a, b)
|
||||
let b = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
|
||||
let b = v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?.into_int_value();
|
||||
let b = generator.bool_to_i8(ctx, b);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
Some(b)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(Some(a), b)
|
||||
}
|
||||
Boolop::And => {
|
||||
ctx.builder.position_at_end(a_bb);
|
||||
let a = generator
|
||||
.gen_expr(ctx, &values[1])?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?
|
||||
.into_int_value();
|
||||
let a = generator.bool_to_i8(ctx, a);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
let a = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
|
||||
let a = v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?.into_int_value();
|
||||
let a = generator.bool_to_i8(ctx, a);
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
|
||||
Some(a)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
ctx.builder.position_at_end(b_bb);
|
||||
let b = ctx.ctx.i8_type().const_zero();
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
(a, b)
|
||||
|
||||
(a, Some(b))
|
||||
}
|
||||
};
|
||||
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "");
|
||||
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
|
||||
phi.as_basic_value().into()
|
||||
match (a, b) {
|
||||
(Some(a), Some(b)) => {
|
||||
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "");
|
||||
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
|
||||
phi.as_basic_value().into()
|
||||
}
|
||||
(Some(a), None) => a.into(),
|
||||
(None, Some(b)) => b.into(),
|
||||
(None, None) => unreachable!(),
|
||||
}
|
||||
}
|
||||
ExprKind::BinOp { op, left, right } => {
|
||||
return gen_binop_expr(generator, ctx, left, op, right, expr.location, false);
|
||||
}
|
||||
ExprKind::UnaryOp { op, operand } => {
|
||||
let ty = ctx.unifier.get_representative(operand.custom.unwrap());
|
||||
let val =
|
||||
generator.gen_expr(ctx, operand)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, operand.custom.unwrap())?;
|
||||
let val = if let Some(v) = generator.gen_expr(ctx, operand)? {
|
||||
v.to_basic_value_enum(ctx, generator, operand.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
if ty == ctx.primitives.bool {
|
||||
let val = val.into_int_value();
|
||||
match op {
|
||||
|
@ -1415,7 +1484,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
}
|
||||
ExprKind::Compare { left, ops, comparators } => {
|
||||
izip!(chain(once(left.as_ref()), comparators.iter()), comparators.iter(), ops.iter(),)
|
||||
let cmp_val = izip!(chain(once(left.as_ref()), comparators.iter()), comparators.iter(), ops.iter(),)
|
||||
.fold(Ok(None), |prev: Result<Option<_>, String>, (lhs, rhs, op)| {
|
||||
let ty = ctx.unifier.get_representative(lhs.custom.unwrap());
|
||||
let current =
|
||||
|
@ -1427,23 +1496,15 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx.primitives.uint64,
|
||||
].contains(&ty);
|
||||
|
||||
let (lhs, rhs) = if let (
|
||||
BasicValueEnum::IntValue(lhs),
|
||||
BasicValueEnum::IntValue(rhs),
|
||||
) = (
|
||||
generator
|
||||
.gen_expr(ctx, lhs)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?,
|
||||
generator
|
||||
.gen_expr(ctx, rhs)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, rhs.custom.unwrap())?,
|
||||
) {
|
||||
(lhs, rhs)
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
let BasicValueEnum::IntValue(lhs) = (match generator.gen_expr(ctx, lhs)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
}) else { unreachable!() };
|
||||
|
||||
let BasicValueEnum::IntValue(rhs) = (match generator.gen_expr(ctx, rhs)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, rhs.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
}) else { unreachable!() };
|
||||
|
||||
let op = match op {
|
||||
ast::Cmpop::Eq | ast::Cmpop::Is => IntPredicate::EQ,
|
||||
|
@ -1474,23 +1535,16 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
|
||||
ctx.builder.build_int_compare(op, lhs, rhs, "cmp")
|
||||
} else if ty == ctx.primitives.float {
|
||||
let (lhs, rhs) = if let (
|
||||
BasicValueEnum::FloatValue(lhs),
|
||||
BasicValueEnum::FloatValue(rhs),
|
||||
) = (
|
||||
generator
|
||||
.gen_expr(ctx, lhs)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?,
|
||||
generator
|
||||
.gen_expr(ctx, rhs)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, rhs.custom.unwrap())?,
|
||||
) {
|
||||
(lhs, rhs)
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
let BasicValueEnum::FloatValue(lhs) = (match generator.gen_expr(ctx, lhs)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
}) else { unreachable!() };
|
||||
|
||||
let BasicValueEnum::FloatValue(rhs) = (match generator.gen_expr(ctx, rhs)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, rhs.custom.unwrap())?,
|
||||
None => return Ok(None),
|
||||
}) else { unreachable!() };
|
||||
|
||||
let op = match op {
|
||||
ast::Cmpop::Eq | ast::Cmpop::Is => inkwell::FloatPredicate::OEQ,
|
||||
ast::Cmpop::NotEq => inkwell::FloatPredicate::ONE,
|
||||
|
@ -1505,16 +1559,18 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
unimplemented!()
|
||||
};
|
||||
Ok(prev?.map(|v| ctx.builder.build_and(v, current, "cmp")).or(Some(current)))
|
||||
})?
|
||||
.unwrap()
|
||||
.into() // as there should be at least 1 element, it should never be none
|
||||
})?;
|
||||
|
||||
match cmp_val {
|
||||
Some(v) => v.into(),
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
ExprKind::IfExp { test, body, orelse } => {
|
||||
let test = generator
|
||||
.gen_expr(ctx, test)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, test.custom.unwrap())?
|
||||
.into_int_value();
|
||||
let test = match generator.gen_expr(ctx, test)? {
|
||||
Some(v) => v.to_basic_value_enum(ctx, generator, test.custom.unwrap())?.into_int_value(),
|
||||
None => return Ok(None),
|
||||
};
|
||||
let test = generator.bool_to_i1(ctx, test);
|
||||
let body_ty = body.custom.unwrap();
|
||||
let is_none = ctx.unifier.get_representative(body_ty) == ctx.primitives.none;
|
||||
|
@ -1529,37 +1585,52 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
let else_bb = ctx.ctx.append_basic_block(current, "else");
|
||||
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
||||
ctx.builder.build_conditional_branch(test, then_bb, else_bb);
|
||||
|
||||
ctx.builder.position_at_end(then_bb);
|
||||
let a = generator.gen_expr(ctx, body)?;
|
||||
match result {
|
||||
None => None,
|
||||
Some(v) => {
|
||||
let a = a.unwrap().to_basic_value_enum(ctx, generator, body.custom.unwrap())?;
|
||||
Some(ctx.builder.build_store(v, a))
|
||||
}
|
||||
};
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
if let Some(a) = a {
|
||||
match result {
|
||||
None => None,
|
||||
Some(v) => {
|
||||
let a = a.to_basic_value_enum(ctx, generator, body.custom.unwrap())?;
|
||||
Some(ctx.builder.build_store(v, a))
|
||||
}
|
||||
};
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
}
|
||||
|
||||
ctx.builder.position_at_end(else_bb);
|
||||
let b = generator.gen_expr(ctx, orelse)?;
|
||||
match result {
|
||||
None => None,
|
||||
Some(v) => {
|
||||
let b = b.unwrap().to_basic_value_enum(ctx, generator, orelse.custom.unwrap())?;
|
||||
Some(ctx.builder.build_store(v, b))
|
||||
}
|
||||
};
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
if let Some(b) = b {
|
||||
match result {
|
||||
None => None,
|
||||
Some(v) => {
|
||||
let b = b.to_basic_value_enum(ctx, generator, orelse.custom.unwrap())?;
|
||||
Some(ctx.builder.build_store(v, b))
|
||||
}
|
||||
};
|
||||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
}
|
||||
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
match result {
|
||||
None => return Ok(None),
|
||||
Some(v) => return Ok(Some(ctx.builder.build_load(v, "if_exp_val_load").into()))
|
||||
if let Some(v) = result {
|
||||
ctx.builder.build_load(v, "if_exp_val_load").into()
|
||||
} else {
|
||||
return Ok(None)
|
||||
}
|
||||
}
|
||||
ExprKind::Call { func, args, keywords } => {
|
||||
let mut params = args
|
||||
.iter()
|
||||
.map(|arg| Ok((None, generator.gen_expr(ctx, arg)?.unwrap())) as Result<_, String>)
|
||||
.map(|arg| generator.gen_expr(ctx, arg))
|
||||
.take_while(|expr| !matches!(expr, Ok(None)))
|
||||
.map(|expr| Ok((None, expr?.unwrap())) as Result<_, String>)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
if params.len() < args.len() {
|
||||
return Ok(None)
|
||||
}
|
||||
|
||||
let kw_iter = keywords.iter().map(|kw| {
|
||||
Ok((
|
||||
Some(*kw.node.arg.as_ref().unwrap()),
|
||||
|
@ -1593,7 +1664,11 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
.map(|v| v.into()));
|
||||
}
|
||||
ExprKind::Attribute { value, attr, .. } => {
|
||||
let val = generator.gen_expr(ctx, value)?.unwrap();
|
||||
let val = match generator.gen_expr(ctx, value)? {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let id = if let TypeEnum::TObj { obj_id, .. } =
|
||||
&*ctx.unifier.get_ty(value.custom.unwrap())
|
||||
{
|
||||
|
@ -1691,18 +1766,20 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
ExprKind::Subscript { value, slice, .. } => {
|
||||
if let TypeEnum::TList { ty } = &*ctx.unifier.get_ty(value.custom.unwrap()) {
|
||||
let v = generator
|
||||
.gen_expr(ctx, value)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, value.custom.unwrap())?
|
||||
.into_pointer_value();
|
||||
let v = if let Some(v) = generator.gen_expr(ctx, value)? {
|
||||
v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?.into_pointer_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let ty = ctx.get_llvm_type(generator, *ty);
|
||||
let arr_ptr = ctx.build_gep_and_load(v, &[zero, zero], Some("arr.addr"))
|
||||
.into_pointer_value();
|
||||
if let ExprKind::Slice { lower, upper, step } = &slice.node {
|
||||
let one = int32.const_int(1, false);
|
||||
let (start, end, step) =
|
||||
handle_slice_indices(lower, upper, step, ctx, generator, v)?;
|
||||
let Some((start, end, step)) =
|
||||
handle_slice_indices(lower, upper, step, ctx, generator, v)? else {
|
||||
return Ok(None)
|
||||
};
|
||||
let length = calculate_len_for_slice_range(
|
||||
generator,
|
||||
ctx,
|
||||
|
@ -1723,8 +1800,10 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
step,
|
||||
);
|
||||
let res_array_ret = allocate_list(generator, ctx, ty, length, Some("ret"));
|
||||
let res_ind =
|
||||
handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)?;
|
||||
let Some(res_ind) =
|
||||
handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)? else {
|
||||
return Ok(None)
|
||||
};
|
||||
list_slice_assignment(
|
||||
generator,
|
||||
ctx,
|
||||
|
@ -1739,11 +1818,11 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
let len = ctx
|
||||
.build_gep_and_load(v, &[zero, int32.const_int(1, false)], Some("len"))
|
||||
.into_int_value();
|
||||
let raw_index = generator
|
||||
.gen_expr(ctx, slice)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?
|
||||
.into_int_value();
|
||||
let raw_index = if let Some(v) = generator.gen_expr(ctx, slice)? {
|
||||
v.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let raw_index = ctx.builder.build_int_s_extend(
|
||||
raw_index,
|
||||
generator.get_size_type(ctx.ctx),
|
||||
|
@ -1786,15 +1865,12 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
} else {
|
||||
unreachable!("tuple subscript must be const int after type check");
|
||||
};
|
||||
let v = generator
|
||||
.gen_expr(ctx, value)?
|
||||
.unwrap();
|
||||
match v {
|
||||
ValueEnum::Dynamic(v) => {
|
||||
match generator.gen_expr(ctx, value)? {
|
||||
Some(ValueEnum::Dynamic(v)) => {
|
||||
let v = v.into_struct_value();
|
||||
ctx.builder.build_extract_value(v, index, "tup_elem").unwrap().into()
|
||||
}
|
||||
ValueEnum::Static(v) => {
|
||||
Some(ValueEnum::Static(v)) => {
|
||||
match v.get_tuple_element(index) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
|
@ -1805,12 +1881,19 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
}
|
||||
}
|
||||
None => return Ok(None),
|
||||
}
|
||||
} else {
|
||||
unreachable!("should not be other subscriptable types after type check");
|
||||
}
|
||||
},
|
||||
ExprKind::ListComp { .. } => gen_comprehension(generator, ctx, expr)?.into(),
|
||||
ExprKind::ListComp { .. } => {
|
||||
if let Some(v) = gen_comprehension(generator, ctx, expr)? {
|
||||
v.into()
|
||||
} else {
|
||||
return Ok(None)
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ pub trait CodeGenerator {
|
|||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
pattern: &Expr<Option<Type>>,
|
||||
name: Option<&str>,
|
||||
) -> Result<PointerValue<'ctx>, String>
|
||||
) -> Result<Option<PointerValue<'ctx>>, String>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
|
|
@ -158,33 +158,41 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
generator: &mut G,
|
||||
list: PointerValue<'ctx>,
|
||||
) -> Result<(IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>), String> {
|
||||
) -> Result<Option<(IntValue<'ctx>, IntValue<'ctx>, IntValue<'ctx>)>, String> {
|
||||
let int32 = ctx.ctx.i32_type();
|
||||
let zero = int32.const_zero();
|
||||
let one = int32.const_int(1, false);
|
||||
let length = ctx.build_gep_and_load(list, &[zero, one], Some("length")).into_int_value();
|
||||
let length = ctx.builder.build_int_truncate_or_bit_cast(length, int32, "leni32");
|
||||
Ok(match (start, end, step) {
|
||||
Ok(Some(match (start, end, step) {
|
||||
(s, e, None) => (
|
||||
s.as_ref().map_or_else(
|
||||
|| Ok(int32.const_zero()),
|
||||
|s| handle_slice_index_bound(s, ctx, generator, length),
|
||||
)?,
|
||||
if let Some(s) = s.as_ref() {
|
||||
match handle_slice_index_bound(s, ctx, generator, length)? {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
}
|
||||
} else {
|
||||
int32.const_zero()
|
||||
},
|
||||
{
|
||||
let e = e.as_ref().map_or_else(
|
||||
|| Ok(length),
|
||||
|e| handle_slice_index_bound(e, ctx, generator, length),
|
||||
)?;
|
||||
let e = if let Some(s) = e.as_ref() {
|
||||
match handle_slice_index_bound(s, ctx, generator, length)? {
|
||||
Some(v) => v,
|
||||
None => return Ok(None),
|
||||
}
|
||||
} else {
|
||||
length
|
||||
};
|
||||
ctx.builder.build_int_sub(e, one, "final_end")
|
||||
},
|
||||
one,
|
||||
),
|
||||
(s, e, Some(step)) => {
|
||||
let step = generator
|
||||
.gen_expr(ctx, step)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, ctx.primitives.int32)?
|
||||
.into_int_value();
|
||||
let step = if let Some(v) = generator.gen_expr(ctx, step)? {
|
||||
v.to_basic_value_enum(ctx, generator, ctx.primitives.int32)?.into_int_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
// assert step != 0, throw exception if not
|
||||
let not_zero = ctx.builder.build_int_compare(
|
||||
IntPredicate::NE,
|
||||
|
@ -205,7 +213,9 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||
(
|
||||
match s {
|
||||
Some(s) => {
|
||||
let s = handle_slice_index_bound(s, ctx, generator, length)?;
|
||||
let Some(s) = handle_slice_index_bound(s, ctx, generator, length)? else {
|
||||
return Ok(None)
|
||||
};
|
||||
ctx.builder
|
||||
.build_select(
|
||||
ctx.builder.build_and(
|
||||
|
@ -228,7 +238,9 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||
},
|
||||
match e {
|
||||
Some(e) => {
|
||||
let e = handle_slice_index_bound(e, ctx, generator, length)?;
|
||||
let Some(e) = handle_slice_index_bound(e, ctx, generator, length)? else {
|
||||
return Ok(None)
|
||||
};
|
||||
ctx.builder
|
||||
.build_select(
|
||||
neg,
|
||||
|
@ -243,7 +255,7 @@ pub fn handle_slice_indices<'a, 'ctx, G: CodeGenerator>(
|
|||
step,
|
||||
)
|
||||
}
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
/// this function allows index out of range, since python
|
||||
|
@ -253,7 +265,7 @@ pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>(
|
|||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
generator: &mut G,
|
||||
length: IntValue<'ctx>,
|
||||
) -> Result<IntValue<'ctx>, String> {
|
||||
) -> Result<Option<IntValue<'ctx>>, String> {
|
||||
const SYMBOL: &str = "__nac3_slice_index_bound";
|
||||
let func = ctx.module.get_function(SYMBOL).unwrap_or_else(|| {
|
||||
let i32_t = ctx.ctx.i32_type();
|
||||
|
@ -261,14 +273,18 @@ pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>(
|
|||
ctx.module.add_function(SYMBOL, fn_t, None)
|
||||
});
|
||||
|
||||
let i = generator.gen_expr(ctx, i)?.unwrap().to_basic_value_enum(ctx, generator, i.custom.unwrap())?;
|
||||
Ok(ctx
|
||||
let i = if let Some(v) = generator.gen_expr(ctx, i)? {
|
||||
v.to_basic_value_enum(ctx, generator, i.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
Ok(Some(ctx
|
||||
.builder
|
||||
.build_call(func, &[i.into(), length.into()], "bounded_ind")
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap()
|
||||
.into_int_value())
|
||||
.into_int_value()))
|
||||
}
|
||||
|
||||
/// This function handles 'end' **inclusively**.
|
||||
|
|
|
@ -60,10 +60,10 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
pattern: &Expr<Option<Type>>,
|
||||
name: Option<&str>,
|
||||
) -> Result<PointerValue<'ctx>, String> {
|
||||
) -> Result<Option<PointerValue<'ctx>>, String> {
|
||||
// very similar to gen_expr, but we don't do an extra load at the end
|
||||
// and we flatten nested tuples
|
||||
Ok(match &pattern.node {
|
||||
Ok(Some(match &pattern.node {
|
||||
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
|
||||
None => {
|
||||
let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap());
|
||||
|
@ -79,11 +79,11 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
ExprKind::Attribute { value, attr, .. } => {
|
||||
let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
|
||||
let val = generator.gen_expr(ctx, value)?.unwrap().to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
value.custom.unwrap(),
|
||||
)?;
|
||||
let val = if let Some(v) = generator.gen_expr(ctx, value)? {
|
||||
v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let ptr = if let BasicValueEnum::PointerValue(v) = val {
|
||||
v
|
||||
} else {
|
||||
|
@ -107,19 +107,19 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||
));
|
||||
let i32_type = ctx.ctx.i32_type();
|
||||
let zero = i32_type.const_zero();
|
||||
let v = generator
|
||||
.gen_expr(ctx, value)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, value.custom.unwrap())?
|
||||
.into_pointer_value();
|
||||
let v = if let Some(v) = generator.gen_expr(ctx, value)? {
|
||||
v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?.into_pointer_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let len = ctx
|
||||
.build_gep_and_load(v, &[zero, i32_type.const_int(1, false)], Some("len"))
|
||||
.into_int_value();
|
||||
let raw_index = generator
|
||||
.gen_expr(ctx, slice)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?
|
||||
.into_int_value();
|
||||
let raw_index = if let Some(v) = generator.gen_expr(ctx, slice)? {
|
||||
v.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?.into_int_value()
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
let raw_index = ctx.builder.build_int_s_extend(
|
||||
raw_index,
|
||||
generator.get_size_type(ctx.ctx),
|
||||
|
@ -161,7 +161,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
/// See [CodeGenerator::gen_assign].
|
||||
|
@ -196,8 +196,10 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
|||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, ls.custom.unwrap())?
|
||||
.into_pointer_value();
|
||||
let (start, end, step) =
|
||||
handle_slice_indices(lower, upper, step, ctx, generator, ls)?;
|
||||
let Some((start, end, step)) =
|
||||
handle_slice_indices(lower, upper, step, ctx, generator, ls)? else {
|
||||
return Ok(())
|
||||
};
|
||||
let value = value
|
||||
.to_basic_value_enum(ctx, generator, target.custom.unwrap())?
|
||||
.into_pointer_value();
|
||||
|
@ -207,7 +209,9 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
|||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
let src_ind = handle_slice_indices(&None, &None, &None, ctx, generator, value)?;
|
||||
let Some(src_ind) = handle_slice_indices(&None, &None, &None, ctx, generator, value)? else {
|
||||
return Ok(())
|
||||
};
|
||||
list_slice_assignment(generator, ctx, ty, ls, (start, end, step), value, src_ind)
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -219,7 +223,9 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
|
|||
} else {
|
||||
String::from("target.addr")
|
||||
};
|
||||
let ptr = generator.gen_store_target(ctx, target, Some(name.as_str()))?;
|
||||
let Some(ptr) = generator.gen_store_target(ctx, target, Some(name.as_str()))? else {
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
if let ExprKind::Name { id, .. } = &target.node {
|
||||
let (_, static_value, counter) = ctx.var_assignment.get_mut(id).unwrap();
|
||||
|
@ -270,17 +276,23 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
|||
// store loop bb information and restore it later
|
||||
let loop_bb = ctx.loop_target.replace((incr_bb, cont_bb));
|
||||
|
||||
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
iter.custom.unwrap(),
|
||||
)?;
|
||||
let iter_val = if let Some(v) = generator.gen_expr(ctx, iter)? {
|
||||
v.to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
iter.custom.unwrap(),
|
||||
)?
|
||||
} else {
|
||||
return Ok(())
|
||||
};
|
||||
if is_iterable_range_expr {
|
||||
let iter_val = iter_val.into_pointer_value();
|
||||
// Internal variable for loop; Cannot be assigned
|
||||
let i = generator.gen_var_alloc(ctx, int32.into(), Some("for.i.addr"))?;
|
||||
// Variable declared in "target" expression of the loop; Can be reassigned *or* shadowed
|
||||
let target_i = generator.gen_store_target(ctx, target, Some("for.target.addr"))?;
|
||||
let Some(target_i) = generator.gen_store_target(ctx, target, Some("for.target.addr"))? else {
|
||||
unreachable!()
|
||||
};
|
||||
let (start, stop, step) = destructure_range(ctx, iter_val);
|
||||
|
||||
ctx.builder.build_store(i, start);
|
||||
|
@ -412,11 +424,16 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
|||
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
||||
ctx.builder.build_unconditional_branch(test_bb);
|
||||
ctx.builder.position_at_end(test_bb);
|
||||
let test = generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
test.custom.unwrap(),
|
||||
)?;
|
||||
let test = if let Some(v) = generator.gen_expr(ctx, test)? {
|
||||
v.to_basic_value_enum(ctx, generator, test.custom.unwrap())?
|
||||
} else {
|
||||
for bb in [body_bb, cont_bb] {
|
||||
ctx.builder.position_at_end(bb);
|
||||
ctx.builder.build_unreachable();
|
||||
}
|
||||
|
||||
return Ok(())
|
||||
};
|
||||
if let BasicValueEnum::IntValue(test) = test {
|
||||
ctx.builder.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb);
|
||||
} else {
|
||||
|
@ -478,13 +495,11 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
|||
};
|
||||
ctx.builder.build_unconditional_branch(test_bb);
|
||||
ctx.builder.position_at_end(test_bb);
|
||||
let test = generator.gen_expr(ctx, test)?
|
||||
.unwrap()
|
||||
.to_basic_value_enum(ctx, generator, test.custom.unwrap())?;
|
||||
if let BasicValueEnum::IntValue(test) = test {
|
||||
let test = generator
|
||||
.gen_expr(ctx, test)
|
||||
.and_then(|v| v.map(|v| v.to_basic_value_enum(ctx, generator, test.custom.unwrap())).transpose())?;
|
||||
if let Some(BasicValueEnum::IntValue(test)) = test {
|
||||
ctx.builder.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb);
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
ctx.builder.position_at_end(body_bb);
|
||||
generator.gen_block(ctx, body.iter())?;
|
||||
|
@ -604,7 +619,7 @@ pub fn exn_constructor<'ctx, 'a>(
|
|||
let msg = if !args.is_empty() {
|
||||
args.remove(0).1.to_basic_value_enum(ctx, generator, ctx.primitives.str)?
|
||||
} else {
|
||||
empty_string
|
||||
empty_string.unwrap()
|
||||
};
|
||||
ctx.builder.build_store(ptr, msg);
|
||||
for i in [6, 7, 8].iter() {
|
||||
|
@ -627,7 +642,7 @@ pub fn exn_constructor<'ctx, 'a>(
|
|||
&[zero, int32.const_int(*i, false)],
|
||||
"exn.str",
|
||||
);
|
||||
ctx.builder.build_store(ptr, empty_string);
|
||||
ctx.builder.build_store(ptr, empty_string.unwrap());
|
||||
}
|
||||
// set ints to zero
|
||||
for i in [2, 3].iter() {
|
||||
|
@ -1036,14 +1051,17 @@ pub fn gen_return<'ctx, 'a, G: CodeGenerator>(
|
|||
value: &Option<Box<Expr<Option<Type>>>>,
|
||||
) -> Result<(), String> {
|
||||
let func = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap();
|
||||
let value = value
|
||||
.as_ref()
|
||||
.map(|v_expr| {
|
||||
generator.gen_expr(ctx, v_expr).and_then(|v| {
|
||||
v.unwrap().to_basic_value_enum(ctx, generator, v_expr.custom.unwrap())
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
let value = if let Some(v_expr) = value.as_ref() {
|
||||
if let Some(v) = generator.gen_expr(ctx, v_expr).transpose() {
|
||||
Some(
|
||||
v.and_then(|v| v.to_basic_value_enum(ctx, generator, v_expr.custom.unwrap()))?
|
||||
)
|
||||
} else {
|
||||
return Ok(())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(return_target) = ctx.return_target {
|
||||
if let Some(value) = value {
|
||||
ctx.builder.build_store(ctx.return_buffer.unwrap(), value);
|
||||
|
@ -1105,12 +1123,16 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
|
|||
}
|
||||
StmtKind::AnnAssign { target, value, .. } => {
|
||||
if let Some(value) = value {
|
||||
let value = generator.gen_expr(ctx, value)?.unwrap();
|
||||
let Some(value) = generator.gen_expr(ctx, value)? else {
|
||||
return Ok(())
|
||||
};
|
||||
generator.gen_assign(ctx, target, value)?;
|
||||
}
|
||||
}
|
||||
StmtKind::Assign { targets, value, .. } => {
|
||||
let value = generator.gen_expr(ctx, value)?.unwrap();
|
||||
let Some(value) = generator.gen_expr(ctx, value)? else {
|
||||
return Ok(())
|
||||
};
|
||||
for target in targets.iter() {
|
||||
generator.gen_assign(ctx, target, value.clone())?;
|
||||
}
|
||||
|
@ -1132,28 +1154,28 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
|
|||
StmtKind::Try { .. } => gen_try(generator, ctx, stmt)?,
|
||||
StmtKind::Raise { exc, .. } => {
|
||||
if let Some(exc) = exc {
|
||||
let exc = generator.gen_expr(ctx, exc)?.unwrap().to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
exc.custom.unwrap(),
|
||||
)?;
|
||||
let exc = if let Some(v) = generator.gen_expr(ctx, exc)? {
|
||||
v.to_basic_value_enum(ctx, generator, exc.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(())
|
||||
};
|
||||
gen_raise(generator, ctx, Some(&exc), stmt.location);
|
||||
} else {
|
||||
gen_raise(generator, ctx, None, stmt.location);
|
||||
}
|
||||
}
|
||||
StmtKind::Assert { test, msg, .. } => {
|
||||
let test = generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
test.custom.unwrap(),
|
||||
)?;
|
||||
let test = if let Some(v) = generator.gen_expr(ctx, test)? {
|
||||
v.to_basic_value_enum(ctx, generator, test.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(())
|
||||
};
|
||||
let err_msg = match msg {
|
||||
Some(msg) => generator.gen_expr(ctx, msg)?.unwrap().to_basic_value_enum(
|
||||
ctx,
|
||||
generator,
|
||||
msg.custom.unwrap(),
|
||||
)?,
|
||||
Some(msg) => if let Some(v) = generator.gen_expr(ctx, msg)? {
|
||||
v.to_basic_value_enum(ctx, generator, msg.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(())
|
||||
},
|
||||
None => ctx.gen_string(generator, ""),
|
||||
};
|
||||
ctx.make_assert_impl(
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
use std::{collections::HashMap, fmt::Display};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::typecheck::typedef::TypeEnum;
|
||||
use crate::{
|
||||
codegen::CodeGenContext,
|
||||
toplevel::{DefinitionId, TopLevelDef},
|
||||
toplevel::{DefinitionId, TopLevelDef, type_annotation::TypeAnnotation},
|
||||
};
|
||||
use crate::{
|
||||
codegen::CodeGenerator,
|
||||
|
@ -16,7 +17,7 @@ use crate::{
|
|||
};
|
||||
use inkwell::values::{BasicValueEnum, FloatValue, IntValue, PointerValue, StructValue};
|
||||
use itertools::{chain, izip};
|
||||
use nac3parser::ast::{Expr, Location, StrRef};
|
||||
use nac3parser::ast::{Constant, Expr, Location, StrRef};
|
||||
use parking_lot::RwLock;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
|
@ -33,6 +34,147 @@ pub enum SymbolValue {
|
|||
OptionNone,
|
||||
}
|
||||
|
||||
impl SymbolValue {
|
||||
/// Creates a [SymbolValue] from a [Constant].
|
||||
///
|
||||
/// * `constant` - The constant to create the value from.
|
||||
/// * `expected_ty` - The expected type of the [SymbolValue].
|
||||
pub fn from_constant(
|
||||
constant: &Constant,
|
||||
expected_ty: Type,
|
||||
primitives: &PrimitiveStore,
|
||||
unifier: &mut Unifier
|
||||
) -> Result<Self, String> {
|
||||
match constant {
|
||||
Constant::None => {
|
||||
if unifier.unioned(expected_ty, primitives.option) {
|
||||
Ok(SymbolValue::OptionNone)
|
||||
} else {
|
||||
Err(format!("Expected {:?}, but got Option", expected_ty))
|
||||
}
|
||||
}
|
||||
Constant::Bool(b) => {
|
||||
if unifier.unioned(expected_ty, primitives.bool) {
|
||||
Ok(SymbolValue::Bool(*b))
|
||||
} else {
|
||||
Err(format!("Expected {:?}, but got bool", expected_ty))
|
||||
}
|
||||
}
|
||||
Constant::Str(s) => {
|
||||
if unifier.unioned(expected_ty, primitives.str) {
|
||||
Ok(SymbolValue::Str(s.to_string()))
|
||||
} else {
|
||||
Err(format!("Expected {:?}, but got str", expected_ty))
|
||||
}
|
||||
},
|
||||
Constant::Int(i) => {
|
||||
if unifier.unioned(expected_ty, primitives.int32) {
|
||||
i32::try_from(*i)
|
||||
.map(|val| SymbolValue::I32(val))
|
||||
.map_err(|e| e.to_string())
|
||||
} else if unifier.unioned(expected_ty, primitives.int64) {
|
||||
i64::try_from(*i)
|
||||
.map(|val| SymbolValue::I64(val))
|
||||
.map_err(|e| e.to_string())
|
||||
} else if unifier.unioned(expected_ty, primitives.uint32) {
|
||||
u32::try_from(*i)
|
||||
.map(|val| SymbolValue::U32(val))
|
||||
.map_err(|e| e.to_string())
|
||||
} else if unifier.unioned(expected_ty, primitives.uint64) {
|
||||
u64::try_from(*i)
|
||||
.map(|val| SymbolValue::U64(val))
|
||||
.map_err(|e| e.to_string())
|
||||
} else {
|
||||
Err(format!("Expected {}, but got int", unifier.stringify(expected_ty)))
|
||||
}
|
||||
}
|
||||
Constant::Tuple(t) => {
|
||||
let expected_ty = unifier.get_ty(expected_ty);
|
||||
let TypeEnum::TTuple { ty } = expected_ty.as_ref() else {
|
||||
return Err(format!("Expected {:?}, but got Tuple", expected_ty.get_type_name()))
|
||||
};
|
||||
|
||||
assert_eq!(ty.len(), t.len());
|
||||
|
||||
let elems = t.into_iter()
|
||||
.zip(ty)
|
||||
.map(|(constant, ty)| Self::from_constant(constant, *ty, primitives, unifier))
|
||||
.collect::<Result<Vec<SymbolValue>, _>>()?;
|
||||
Ok(SymbolValue::Tuple(elems))
|
||||
}
|
||||
Constant::Float(f) => {
|
||||
if unifier.unioned(expected_ty, primitives.float) {
|
||||
Ok(SymbolValue::Double(*f))
|
||||
} else {
|
||||
Err(format!("Expected {:?}, but got float", expected_ty))
|
||||
}
|
||||
},
|
||||
_ => Err(format!("Unsupported value type {:?}", constant)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [Type] representing the data type of this value.
|
||||
pub fn get_type(&self, primitives: &PrimitiveStore, unifier: &mut Unifier) -> Type {
|
||||
match self {
|
||||
SymbolValue::I32(_) => primitives.int32,
|
||||
SymbolValue::I64(_) => primitives.int64,
|
||||
SymbolValue::U32(_) => primitives.uint32,
|
||||
SymbolValue::U64(_) => primitives.uint64,
|
||||
SymbolValue::Str(_) => primitives.str,
|
||||
SymbolValue::Double(_) => primitives.float,
|
||||
SymbolValue::Bool(_) => primitives.bool,
|
||||
SymbolValue::Tuple(vs) => {
|
||||
let vs_tys = vs
|
||||
.iter()
|
||||
.map(|v| v.get_type(primitives, unifier))
|
||||
.collect::<Vec<_>>();
|
||||
unifier.add_ty(TypeEnum::TTuple {
|
||||
ty: vs_tys,
|
||||
})
|
||||
}
|
||||
SymbolValue::OptionSome(_) => primitives.option,
|
||||
SymbolValue::OptionNone => primitives.option,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [TypeAnnotation] representing the data type of this value.
|
||||
pub fn get_type_annotation(&self, primitives: &PrimitiveStore, unifier: &mut Unifier) -> TypeAnnotation {
|
||||
match self {
|
||||
SymbolValue::Bool(..) => TypeAnnotation::Primitive(primitives.bool),
|
||||
SymbolValue::Double(..) => TypeAnnotation::Primitive(primitives.float),
|
||||
SymbolValue::I32(..) => TypeAnnotation::Primitive(primitives.int32),
|
||||
SymbolValue::I64(..) => TypeAnnotation::Primitive(primitives.int64),
|
||||
SymbolValue::U32(..) => TypeAnnotation::Primitive(primitives.uint32),
|
||||
SymbolValue::U64(..) => TypeAnnotation::Primitive(primitives.uint64),
|
||||
SymbolValue::Str(..) => TypeAnnotation::Primitive(primitives.str),
|
||||
SymbolValue::Tuple(vs) => {
|
||||
let vs_tys = vs
|
||||
.iter()
|
||||
.map(|v| v.get_type_annotation(primitives, unifier))
|
||||
.collect::<Vec<_>>();
|
||||
TypeAnnotation::Tuple(vs_tys)
|
||||
}
|
||||
SymbolValue::OptionNone => TypeAnnotation::CustomClass {
|
||||
id: primitives.option.get_obj_id(unifier),
|
||||
params: Default::default(),
|
||||
},
|
||||
SymbolValue::OptionSome(v) => {
|
||||
let ty = v.get_type_annotation(primitives, unifier);
|
||||
TypeAnnotation::CustomClass {
|
||||
id: primitives.option.get_obj_id(unifier),
|
||||
params: vec![ty],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [TypeEnum] representing the data type of this value.
|
||||
pub fn get_type_enum(&self, primitives: &PrimitiveStore, unifier: &mut Unifier) -> Rc<TypeEnum> {
|
||||
let ty = self.get_type(primitives, unifier);
|
||||
unifier.get_ty(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SymbolValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
|
|
@ -22,7 +22,7 @@ use inkwell::{
|
|||
IntPredicate
|
||||
};
|
||||
|
||||
type BuiltinInfo = (Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>, &'static [&'static str]);
|
||||
type BuiltinInfo = Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>;
|
||||
|
||||
pub fn get_exn_constructor(
|
||||
name: &str,
|
||||
|
@ -881,6 +881,33 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
Ok(Some(val_toint.into()))
|
||||
}),
|
||||
),
|
||||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"np_round",
|
||||
float,
|
||||
&[(float, "n")],
|
||||
Box::new(|ctx, _, _, args, generator| {
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
|
||||
let arg = args[0].1.clone()
|
||||
.to_basic_value_enum(ctx, generator, ctx.primitives.float)?;
|
||||
|
||||
let intrinsic_fn = ctx.module.get_function("llvm.roundeven.f64").unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
|
||||
ctx.module.add_function("llvm.roundeven.f64", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx
|
||||
.builder
|
||||
.build_call(intrinsic_fn, &[arg.into()], "")
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap();
|
||||
Ok(Some(val.into()))
|
||||
}),
|
||||
),
|
||||
Arc::new(RwLock::new(TopLevelDef::Function {
|
||||
name: "range".into(),
|
||||
simple_name: "range".into(),
|
||||
|
@ -1123,6 +1150,33 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
Ok(Some(val_toint.into()))
|
||||
}),
|
||||
),
|
||||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"np_floor",
|
||||
float,
|
||||
&[(float, "n")],
|
||||
Box::new(|ctx, _, _, args, generator| {
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
|
||||
let arg = args[0].1.clone()
|
||||
.to_basic_value_enum(ctx, generator, ctx.primitives.float)?;
|
||||
|
||||
let intrinsic_fn = ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
|
||||
ctx.module.add_function("llvm.floor.f64", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx
|
||||
.builder
|
||||
.build_call(intrinsic_fn, &[arg.into()], "")
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap();
|
||||
Ok(Some(val.into()))
|
||||
}),
|
||||
),
|
||||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
|
@ -1183,6 +1237,33 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
Ok(Some(val_toint.into()))
|
||||
}),
|
||||
),
|
||||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"np_ceil",
|
||||
float,
|
||||
&[(float, "n")],
|
||||
Box::new(|ctx, _, _, args, generator| {
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
|
||||
let arg = args[0].1.clone()
|
||||
.to_basic_value_enum(ctx, generator, ctx.primitives.float)?;
|
||||
|
||||
let intrinsic_fn = ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
|
||||
ctx.module.add_function("llvm.ceil.f64", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx
|
||||
.builder
|
||||
.build_call(intrinsic_fn, &[arg.into()], "")
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap();
|
||||
Ok(Some(val.into()))
|
||||
}),
|
||||
),
|
||||
Arc::new(RwLock::new({
|
||||
let list_var = primitives.1.get_fresh_var(Some("L".into()), None);
|
||||
let list = primitives.1.add_ty(TypeEnum::TList { ty: list_var.0 });
|
||||
|
@ -1431,7 +1512,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"isnan",
|
||||
"np_isnan",
|
||||
boolean,
|
||||
&[(float, "x")],
|
||||
Box::new(|ctx, _, fun, args, generator| {
|
||||
|
@ -1451,7 +1532,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"isinf",
|
||||
"np_isinf",
|
||||
boolean,
|
||||
&[(float, "x")],
|
||||
Box::new(|ctx, _, fun, args, generator| {
|
||||
|
@ -1471,7 +1552,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"sin",
|
||||
"np_sin",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.sin.f64",
|
||||
|
@ -1479,7 +1560,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"cos",
|
||||
"np_cos",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.cos.f64",
|
||||
|
@ -1487,7 +1568,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"exp",
|
||||
"np_exp",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.exp.f64",
|
||||
|
@ -1495,7 +1576,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"exp2",
|
||||
"np_exp2",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.exp2.f64",
|
||||
|
@ -1503,7 +1584,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"log",
|
||||
"np_log",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.log.f64",
|
||||
|
@ -1511,7 +1592,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"log10",
|
||||
"np_log10",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.log10.f64",
|
||||
|
@ -1519,7 +1600,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"log2",
|
||||
"np_log2",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.log2.f64",
|
||||
|
@ -1527,7 +1608,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"fabs",
|
||||
"np_fabs",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.fabs.f64",
|
||||
|
@ -1535,7 +1616,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"sqrt",
|
||||
"np_sqrt",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.sqrt.f64",
|
||||
|
@ -1543,7 +1624,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"rint",
|
||||
"np_rint",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"llvm.roundeven.f64",
|
||||
|
@ -1551,7 +1632,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"tan",
|
||||
"np_tan",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"tan",
|
||||
|
@ -1560,7 +1641,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arcsin",
|
||||
"np_arcsin",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"asin",
|
||||
|
@ -1569,7 +1650,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arccos",
|
||||
"np_arccos",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"acos",
|
||||
|
@ -1578,7 +1659,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arctan",
|
||||
"np_arctan",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"atan",
|
||||
|
@ -1587,7 +1668,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"sinh",
|
||||
"np_sinh",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"sinh",
|
||||
|
@ -1596,7 +1677,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"cosh",
|
||||
"np_cosh",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"cosh",
|
||||
|
@ -1605,7 +1686,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"tanh",
|
||||
"np_tanh",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"tanh",
|
||||
|
@ -1614,7 +1695,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arcsinh",
|
||||
"np_arcsinh",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"asinh",
|
||||
|
@ -1623,7 +1704,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arccosh",
|
||||
"np_arccosh",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"acosh",
|
||||
|
@ -1632,7 +1713,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arctanh",
|
||||
"np_arctanh",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"atanh",
|
||||
|
@ -1641,7 +1722,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"expm1",
|
||||
"np_expm1",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"expm1",
|
||||
|
@ -1650,7 +1731,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"cbrt",
|
||||
"np_cbrt",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"cbrt",
|
||||
|
@ -1659,7 +1740,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"erf",
|
||||
"sp_spec_erf",
|
||||
float,
|
||||
&[(float, "z")],
|
||||
"erf",
|
||||
|
@ -1668,7 +1749,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"erfc",
|
||||
"sp_spec_erfc",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"erfc",
|
||||
|
@ -1677,7 +1758,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"gamma",
|
||||
"sp_spec_gamma",
|
||||
float,
|
||||
&[(float, "z")],
|
||||
Box::new(|ctx, _, fun, args, generator| {
|
||||
|
@ -1695,7 +1776,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"gammaln",
|
||||
"sp_spec_gammaln",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
Box::new(|ctx, _, fun, args, generator| {
|
||||
|
@ -1713,7 +1794,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_codegen(
|
||||
primitives,
|
||||
&var_map,
|
||||
"j0",
|
||||
"sp_spec_j0",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
Box::new(|ctx, _, fun, args, generator| {
|
||||
|
@ -1731,7 +1812,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"j1",
|
||||
"sp_spec_j1",
|
||||
float,
|
||||
&[(float, "x")],
|
||||
"j1",
|
||||
|
@ -1741,7 +1822,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"arctan2",
|
||||
"np_arctan2",
|
||||
float,
|
||||
&[(float, "x1"), (float, "x2")],
|
||||
"atan2",
|
||||
|
@ -1750,7 +1831,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"copysign",
|
||||
"np_copysign",
|
||||
float,
|
||||
&[(float, "x1"), (float, "x2")],
|
||||
"llvm.copysign.f64",
|
||||
|
@ -1758,7 +1839,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"fmax",
|
||||
"np_fmax",
|
||||
float,
|
||||
&[(float, "x1"), (float, "x2")],
|
||||
"llvm.maxnum.f64",
|
||||
|
@ -1766,7 +1847,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_intrinsic(
|
||||
primitives,
|
||||
&var_map,
|
||||
"fmin",
|
||||
"np_fmin",
|
||||
float,
|
||||
&[(float, "x1"), (float, "x2")],
|
||||
"llvm.minnum.f64",
|
||||
|
@ -1774,7 +1855,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"ldexp",
|
||||
"np_ldexp",
|
||||
float,
|
||||
&[(float, "x1"), (int32, "x2")],
|
||||
"ldexp",
|
||||
|
@ -1783,7 +1864,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"hypot",
|
||||
"np_hypot",
|
||||
float,
|
||||
&[(float, "x1"), (float, "x2")],
|
||||
"hypot",
|
||||
|
@ -1792,7 +1873,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
create_fn_by_extern(
|
||||
primitives,
|
||||
&var_map,
|
||||
"nextafter",
|
||||
"np_nextafter",
|
||||
float,
|
||||
&[(float, "x1"), (float, "x2")],
|
||||
"nextafter",
|
||||
|
@ -1825,65 +1906,6 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||
|
||||
let ast_list: Vec<Option<ast::Stmt<()>>> =
|
||||
(0..top_level_def_list.len()).map(|_| None).collect();
|
||||
(
|
||||
izip!(top_level_def_list, ast_list).collect_vec(),
|
||||
&[
|
||||
"int32",
|
||||
"int64",
|
||||
"uint32",
|
||||
"uint64",
|
||||
"float",
|
||||
"round",
|
||||
"round64",
|
||||
"range",
|
||||
"str",
|
||||
"bool",
|
||||
"floor",
|
||||
"floor64",
|
||||
"ceil",
|
||||
"ceil64",
|
||||
"len",
|
||||
"min",
|
||||
"max",
|
||||
"abs",
|
||||
"isnan",
|
||||
"isinf",
|
||||
"sin",
|
||||
"cos",
|
||||
"exp",
|
||||
"exp2",
|
||||
"log",
|
||||
"log10",
|
||||
"log2",
|
||||
"fabs",
|
||||
"sqrt",
|
||||
"rint",
|
||||
"tan",
|
||||
"arcsin",
|
||||
"arccos",
|
||||
"arctan",
|
||||
"sinh",
|
||||
"cosh",
|
||||
"tanh",
|
||||
"arcsinh",
|
||||
"arccosh",
|
||||
"arctanh",
|
||||
"expm1",
|
||||
"cbrt",
|
||||
"erf",
|
||||
"erfc",
|
||||
"gamma",
|
||||
"gammaln",
|
||||
"j0",
|
||||
"j1",
|
||||
"arctan2",
|
||||
"copysign",
|
||||
"fmax",
|
||||
"fmin",
|
||||
"ldexp",
|
||||
"hypot",
|
||||
"nextafter",
|
||||
"Some",
|
||||
],
|
||||
)
|
||||
|
||||
izip!(top_level_def_list, ast_list).collect_vec()
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ impl TopLevelComposer {
|
|||
core_config: ComposerConfig,
|
||||
) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) {
|
||||
let mut primitives = Self::make_primitives();
|
||||
let (mut definition_ast_list, builtin_name_list) = builtins::get_builtins(&mut primitives);
|
||||
let mut definition_ast_list = builtins::get_builtins(&mut primitives);
|
||||
let primitives_ty = primitives.0;
|
||||
let mut unifier = primitives.1;
|
||||
let mut keyword_list: HashSet<StrRef> = HashSet::from_iter(vec![
|
||||
|
@ -83,12 +83,26 @@ impl TopLevelComposer {
|
|||
let mut builtin_id: HashMap<StrRef, DefinitionId> = Default::default();
|
||||
let mut builtin_ty: HashMap<StrRef, Type> = Default::default();
|
||||
|
||||
for (id, name) in builtin_name_list.iter().rev().enumerate() {
|
||||
let builtin_name_list = definition_ast_list.iter()
|
||||
.map(|def_ast| match *def_ast.0.read() {
|
||||
TopLevelDef::Class { name, .. } => name.to_string(),
|
||||
TopLevelDef::Function { simple_name, .. } => simple_name.to_string(),
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
for (id, name) in builtin_name_list.iter().enumerate() {
|
||||
let name = (**name).into();
|
||||
let id = definition_ast_list.len() - id - 1;
|
||||
let def = definition_ast_list[id].0.read();
|
||||
if let TopLevelDef::Function { simple_name, signature, .. } = &*def {
|
||||
assert!(name == *simple_name);
|
||||
if let TopLevelDef::Function { name: func_name, simple_name, signature, .. } = &*def {
|
||||
assert_eq!(name, *simple_name, "Simple name of builtin function should match builtin name list");
|
||||
|
||||
// Do not add member functions into the list of builtin IDs;
|
||||
// Here we assume that all builtin top-level functions have the same name and simple
|
||||
// name, and all member functions have something prefixed to its name
|
||||
if *func_name != simple_name.to_string() {
|
||||
continue
|
||||
}
|
||||
|
||||
builtin_ty.insert(name, *signature);
|
||||
builtin_id.insert(name, DefinitionId(id));
|
||||
} else if let TopLevelDef::Class { name, constructor, object_id, .. } = &*def
|
||||
|
@ -546,6 +560,7 @@ impl TopLevelComposer {
|
|||
&primitive_types,
|
||||
b,
|
||||
vec![(*class_def_id, class_type_vars.clone())].into_iter().collect(),
|
||||
None,
|
||||
)?;
|
||||
|
||||
if let TypeAnnotation::CustomClass { .. } = &base_ty {
|
||||
|
@ -880,6 +895,7 @@ impl TopLevelComposer {
|
|||
// NOTE: since only class need this, for function
|
||||
// it should be fine to be empty map
|
||||
HashMap::new(),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let type_vars_within =
|
||||
|
@ -947,6 +963,7 @@ impl TopLevelComposer {
|
|||
// NOTE: since only class need this, for function
|
||||
// it should be fine to be empty map
|
||||
HashMap::new(),
|
||||
None,
|
||||
)?
|
||||
};
|
||||
|
||||
|
@ -1144,6 +1161,7 @@ impl TopLevelComposer {
|
|||
vec![(class_id, class_type_vars_def.clone())]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
None,
|
||||
)?
|
||||
};
|
||||
// find type vars within this method parameter type annotation
|
||||
|
@ -1207,6 +1225,7 @@ impl TopLevelComposer {
|
|||
primitives,
|
||||
result,
|
||||
vec![(class_id, class_type_vars_def.clone())].into_iter().collect(),
|
||||
None,
|
||||
)?;
|
||||
// find type vars within this return type annotation
|
||||
let type_vars_within =
|
||||
|
@ -1303,6 +1322,7 @@ impl TopLevelComposer {
|
|||
primitives,
|
||||
annotation.as_ref(),
|
||||
vec![(class_id, class_type_vars_def.clone())].into_iter().collect(),
|
||||
None,
|
||||
)?;
|
||||
// find type vars within this return type annotation
|
||||
let type_vars_within =
|
||||
|
@ -1721,7 +1741,7 @@ impl TopLevelComposer {
|
|||
.iter()
|
||||
.map(|(_, ty)| {
|
||||
unifier.get_instantiations(*ty).unwrap_or_else(|| {
|
||||
if let TypeEnum::TVar { name, loc, .. } = &*unifier.get_ty(*ty)
|
||||
if let TypeEnum::TVar { name, loc, is_const_generic: false, .. } = &*unifier.get_ty(*ty)
|
||||
{
|
||||
let rigid = unifier.get_fresh_rigid_var(*name, *loc).0;
|
||||
no_ranges.push(rigid);
|
||||
|
|
|
@ -416,40 +416,6 @@ impl TopLevelComposer {
|
|||
primitive: &PrimitiveStore,
|
||||
unifier: &mut Unifier,
|
||||
) -> Result<(), String> {
|
||||
fn type_default_param(
|
||||
val: &SymbolValue,
|
||||
primitive: &PrimitiveStore,
|
||||
unifier: &mut Unifier,
|
||||
) -> TypeAnnotation {
|
||||
match val {
|
||||
SymbolValue::Bool(..) => TypeAnnotation::Primitive(primitive.bool),
|
||||
SymbolValue::Double(..) => TypeAnnotation::Primitive(primitive.float),
|
||||
SymbolValue::I32(..) => TypeAnnotation::Primitive(primitive.int32),
|
||||
SymbolValue::I64(..) => TypeAnnotation::Primitive(primitive.int64),
|
||||
SymbolValue::U32(..) => TypeAnnotation::Primitive(primitive.uint32),
|
||||
SymbolValue::U64(..) => TypeAnnotation::Primitive(primitive.uint64),
|
||||
SymbolValue::Str(..) => TypeAnnotation::Primitive(primitive.str),
|
||||
SymbolValue::Tuple(vs) => {
|
||||
let vs_tys = vs
|
||||
.iter()
|
||||
.map(|v| type_default_param(v, primitive, unifier))
|
||||
.collect::<Vec<_>>();
|
||||
TypeAnnotation::Tuple(vs_tys)
|
||||
}
|
||||
SymbolValue::OptionNone => TypeAnnotation::CustomClass {
|
||||
id: primitive.option.get_obj_id(unifier),
|
||||
params: Default::default(),
|
||||
},
|
||||
SymbolValue::OptionSome(v) => {
|
||||
let ty = type_default_param(v, primitive, unifier);
|
||||
TypeAnnotation::CustomClass {
|
||||
id: primitive.option.get_obj_id(unifier),
|
||||
params: vec![ty],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_compatible(
|
||||
found: &TypeAnnotation,
|
||||
expect: &TypeAnnotation,
|
||||
|
@ -481,7 +447,7 @@ impl TopLevelComposer {
|
|||
}
|
||||
}
|
||||
|
||||
let found = type_default_param(val, primitive, unifier);
|
||||
let found = val.get_type_annotation(primitive, unifier);
|
||||
if !is_compatible(&found, ty, unifier, primitive) {
|
||||
Err(format!(
|
||||
"incompatible default parameter type, expect {}, found {}",
|
||||
|
|
|
@ -361,7 +361,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
|||
pass
|
||||
"}
|
||||
],
|
||||
vec!["application of type vars to generic class is not currently supported (at unknown: line 4 column 24)"];
|
||||
vec!["application of type vars to generic class is not currently supported (at unknown:4:24)"];
|
||||
"err no type var in generic app"
|
||||
)]
|
||||
#[test_case(
|
||||
|
@ -417,7 +417,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
|||
def __init__():
|
||||
pass
|
||||
"}],
|
||||
vec!["__init__ method must have a `self` parameter (at unknown: line 2 column 5)"];
|
||||
vec!["__init__ method must have a `self` parameter (at unknown:2:5)"];
|
||||
"err no self_1"
|
||||
)]
|
||||
#[test_case(
|
||||
|
@ -439,7 +439,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
|||
"}
|
||||
|
||||
],
|
||||
vec!["a class definition can only have at most one base class declaration and one generic declaration (at unknown: line 1 column 24)"];
|
||||
vec!["a class definition can only have at most one base class declaration and one generic declaration (at unknown:1:24)"];
|
||||
"err multiple inheritance"
|
||||
)]
|
||||
#[test_case(
|
||||
|
@ -507,7 +507,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
|||
pass
|
||||
"}
|
||||
],
|
||||
vec!["duplicate definition of class `A` (at unknown: line 1 column 1)"];
|
||||
vec!["duplicate definition of class `A` (at unknown:1:1)"];
|
||||
"class same name"
|
||||
)]
|
||||
fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::symbol_resolver::SymbolValue;
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -12,6 +13,16 @@ pub enum TypeAnnotation {
|
|||
// can only be CustomClassKind
|
||||
Virtual(Box<TypeAnnotation>),
|
||||
TypeVar(Type),
|
||||
/// A constant used in the context of a const-generic variable.
|
||||
Constant {
|
||||
/// The non-type variable associated with this constant.
|
||||
///
|
||||
/// Invoking [Unifier::get_ty] on this type will return a [TypeEnum::TVar] representing the
|
||||
/// const generic variable of which this constant is associated with.
|
||||
ty: Type,
|
||||
/// The constant value of this constant.
|
||||
value: SymbolValue
|
||||
},
|
||||
List(Box<TypeAnnotation>),
|
||||
Tuple(Vec<TypeAnnotation>),
|
||||
}
|
||||
|
@ -47,6 +58,7 @@ impl TypeAnnotation {
|
|||
}
|
||||
)
|
||||
}
|
||||
Constant { value, .. } => format!("Const({value})"),
|
||||
Virtual(ty) => format!("virtual[{}]", ty.stringify(unifier)),
|
||||
List(ty) => format!("list[{}]", ty.stringify(unifier)),
|
||||
Tuple(types) => {
|
||||
|
@ -56,6 +68,12 @@ impl TypeAnnotation {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses an AST expression `expr` into a [TypeAnnotation].
|
||||
///
|
||||
/// * `locked` - A [HashMap] containing the IDs of known definitions, mapped to a [Vec] of all
|
||||
/// generic variables associated with the definition.
|
||||
/// * `type_var` - The type variable associated with the type argument currently being parsed. Pass
|
||||
/// [None] when this function is invoked externally.
|
||||
pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||
resolver: &(dyn SymbolResolver + Send + Sync),
|
||||
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
||||
|
@ -64,6 +82,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
expr: &ast::Expr<T>,
|
||||
// the key stores the type_var of this topleveldef::class, we only need this field here
|
||||
locked: HashMap<DefinitionId, Vec<Type>>,
|
||||
type_var: Option<Type>,
|
||||
) -> Result<TypeAnnotation, String> {
|
||||
let name_handle = |id: &StrRef,
|
||||
unifier: &mut Unifier,
|
||||
|
@ -127,7 +146,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
slice: &ast::Expr<T>,
|
||||
unifier: &mut Unifier,
|
||||
mut locked: HashMap<DefinitionId, Vec<Type>>| {
|
||||
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into()].contains(id)
|
||||
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into(), "Option".into()].contains(id)
|
||||
{
|
||||
return Err(format!("keywords cannot be class name (at {})", expr.location));
|
||||
}
|
||||
|
@ -161,7 +180,8 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
}
|
||||
let result = params_ast
|
||||
.iter()
|
||||
.map(|x| {
|
||||
.enumerate()
|
||||
.map(|(idx, x)| {
|
||||
parse_ast_to_type_annotation_kinds(
|
||||
resolver,
|
||||
top_level_defs,
|
||||
|
@ -172,6 +192,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
locked.insert(obj_id, type_vars.clone());
|
||||
locked.clone()
|
||||
},
|
||||
Some(type_vars[idx]),
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
@ -190,6 +211,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
};
|
||||
Ok(TypeAnnotation::CustomClass { id: obj_id, params: param_type_infos })
|
||||
};
|
||||
|
||||
match &expr.node {
|
||||
ast::ExprKind::Name { id, .. } => name_handle(id, unifier, locked),
|
||||
// virtual
|
||||
|
@ -205,6 +227,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
primitives,
|
||||
slice.as_ref(),
|
||||
locked,
|
||||
None,
|
||||
)?;
|
||||
if !matches!(def, TypeAnnotation::CustomClass { .. }) {
|
||||
unreachable!("must be concretized custom class kind in the virtual")
|
||||
|
@ -225,6 +248,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
primitives,
|
||||
slice.as_ref(),
|
||||
locked,
|
||||
None,
|
||||
)?;
|
||||
Ok(TypeAnnotation::List(def_ann.into()))
|
||||
}
|
||||
|
@ -242,6 +266,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
primitives,
|
||||
slice.as_ref(),
|
||||
locked,
|
||||
None,
|
||||
)?;
|
||||
let id =
|
||||
if let TypeEnum::TObj { obj_id, .. } = unifier.get_ty(primitives.option).as_ref() {
|
||||
|
@ -275,6 +300,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
primitives,
|
||||
e,
|
||||
locked.clone(),
|
||||
None,
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
@ -290,6 +316,31 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||
}
|
||||
}
|
||||
|
||||
ast::ExprKind::Constant { value, .. } => {
|
||||
let type_var = type_var.expect("Expect type variable to be present");
|
||||
|
||||
let ntv_ty_enum = unifier.get_ty_immutable(type_var);
|
||||
let TypeEnum::TVar { range: underlying_ty, .. } = ntv_ty_enum.as_ref() else {
|
||||
unreachable!()
|
||||
};
|
||||
let underlying_ty = underlying_ty[0];
|
||||
|
||||
let value = SymbolValue::from_constant(value, underlying_ty, primitives, unifier)?;
|
||||
|
||||
if matches!(value, SymbolValue::Str(_) | SymbolValue::Tuple(_) | SymbolValue::OptionSome(_)) {
|
||||
return Err(format!(
|
||||
"expression {} is not allowed for constant type annotation (at {})",
|
||||
value.to_string(),
|
||||
expr.location
|
||||
))
|
||||
}
|
||||
|
||||
Ok(TypeAnnotation::Constant {
|
||||
ty: type_var,
|
||||
value,
|
||||
})
|
||||
}
|
||||
|
||||
_ => Err(format!("unsupported expression for type annotation (at {})", expr.location)),
|
||||
}
|
||||
}
|
||||
|
@ -308,94 +359,130 @@ pub fn get_type_from_type_annotation_kinds(
|
|||
TypeAnnotation::CustomClass { id: obj_id, params } => {
|
||||
let def_read = top_level_defs[obj_id.0].read();
|
||||
let class_def: &TopLevelDef = def_read.deref();
|
||||
if let TopLevelDef::Class { fields, methods, type_vars, .. } = class_def {
|
||||
if type_vars.len() != params.len() {
|
||||
Err(format!(
|
||||
"unexpected number of type parameters: expected {} but got {}",
|
||||
type_vars.len(),
|
||||
params.len()
|
||||
))
|
||||
} else {
|
||||
let param_ty = params
|
||||
.iter()
|
||||
.map(|x| {
|
||||
get_type_from_type_annotation_kinds(
|
||||
top_level_defs,
|
||||
unifier,
|
||||
primitives,
|
||||
x,
|
||||
subst_list
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let TopLevelDef::Class { fields, methods, type_vars, .. } = class_def else {
|
||||
unreachable!("should be class def here")
|
||||
};
|
||||
|
||||
let subst = {
|
||||
// check for compatible range
|
||||
// TODO: if allow type var to be applied(now this disallowed in the parse_to_type_annotation), need more check
|
||||
let mut result: HashMap<u32, Type> = HashMap::new();
|
||||
for (tvar, p) in type_vars.iter().zip(param_ty) {
|
||||
if let TypeEnum::TVar { id, range, fields: None, name, loc } =
|
||||
unifier.get_ty(*tvar).as_ref()
|
||||
{
|
||||
let ok: bool = {
|
||||
// create a temp type var and unify to check compatibility
|
||||
p == *tvar || {
|
||||
let temp = unifier.get_fresh_var_with_range(
|
||||
range.as_slice(),
|
||||
*name,
|
||||
*loc,
|
||||
);
|
||||
unifier.unify(temp.0, p).is_ok()
|
||||
}
|
||||
};
|
||||
if ok {
|
||||
result.insert(*id, p);
|
||||
} else {
|
||||
return Err(format!(
|
||||
"cannot apply type {} to type variable with id {:?}",
|
||||
unifier.internal_stringify(
|
||||
p,
|
||||
&mut |id| format!("class{}", id),
|
||||
&mut |id| format!("typevar{}", id),
|
||||
&mut None
|
||||
),
|
||||
*id
|
||||
));
|
||||
if type_vars.len() != params.len() {
|
||||
return Err(format!(
|
||||
"unexpected number of type parameters: expected {} but got {}",
|
||||
type_vars.len(),
|
||||
params.len()
|
||||
))
|
||||
}
|
||||
|
||||
let param_ty = params
|
||||
.iter()
|
||||
.map(|x| {
|
||||
get_type_from_type_annotation_kinds(
|
||||
top_level_defs,
|
||||
unifier,
|
||||
primitives,
|
||||
x,
|
||||
subst_list
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let subst = {
|
||||
// check for compatible range
|
||||
// TODO: if allow type var to be applied(now this disallowed in the parse_to_type_annotation), need more check
|
||||
let mut result: HashMap<u32, Type> = HashMap::new();
|
||||
for (tvar, p) in type_vars.iter().zip(param_ty) {
|
||||
match unifier.get_ty(*tvar).as_ref() {
|
||||
TypeEnum::TVar { id, range, fields: None, name, loc, is_const_generic: false } => {
|
||||
let ok: bool = {
|
||||
// create a temp type var and unify to check compatibility
|
||||
p == *tvar || {
|
||||
let temp = unifier.get_fresh_var_with_range(
|
||||
range.as_slice(),
|
||||
*name,
|
||||
*loc,
|
||||
);
|
||||
unifier.unify(temp.0, p).is_ok()
|
||||
}
|
||||
};
|
||||
if ok {
|
||||
result.insert(*id, p);
|
||||
} else {
|
||||
unreachable!("must be generic type var")
|
||||
return Err(format!(
|
||||
"cannot apply type {} to type variable with id {:?}",
|
||||
unifier.internal_stringify(
|
||||
p,
|
||||
&mut |id| format!("class{}", id),
|
||||
&mut |id| format!("typevar{}", id),
|
||||
&mut None
|
||||
),
|
||||
*id
|
||||
));
|
||||
}
|
||||
}
|
||||
result
|
||||
};
|
||||
let mut tobj_fields = methods
|
||||
.iter()
|
||||
.map(|(name, ty, _)| {
|
||||
let subst_ty = unifier.subst(*ty, &subst).unwrap_or(*ty);
|
||||
// methods are immutable
|
||||
(*name, (subst_ty, false))
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
tobj_fields.extend(fields.iter().map(|(name, ty, mutability)| {
|
||||
let subst_ty = unifier.subst(*ty, &subst).unwrap_or(*ty);
|
||||
(*name, (subst_ty, *mutability))
|
||||
}));
|
||||
let need_subst = !subst.is_empty();
|
||||
let ty = unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: *obj_id,
|
||||
fields: tobj_fields,
|
||||
params: subst,
|
||||
});
|
||||
if need_subst {
|
||||
subst_list.as_mut().map(|wl| wl.push(ty));
|
||||
|
||||
TypeEnum::TVar { id, range, name, loc, is_const_generic: true, .. } => {
|
||||
let ty = range[0];
|
||||
let ok: bool = {
|
||||
// create a temp type var and unify to check compatibility
|
||||
p == *tvar || {
|
||||
let temp = unifier.get_fresh_const_generic_var(
|
||||
ty,
|
||||
*name,
|
||||
*loc,
|
||||
);
|
||||
unifier.unify(temp.0, p).is_ok()
|
||||
}
|
||||
};
|
||||
if ok {
|
||||
result.insert(*id, p);
|
||||
} else {
|
||||
return Err(format!(
|
||||
"cannot apply type {} to type variable {}",
|
||||
unifier.stringify(p),
|
||||
name.unwrap_or_else(|| format!("typevar{id}").into()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
_ => unreachable!("must be generic type var"),
|
||||
}
|
||||
Ok(ty)
|
||||
}
|
||||
} else {
|
||||
unreachable!("should be class def here")
|
||||
result
|
||||
};
|
||||
let mut tobj_fields = methods
|
||||
.iter()
|
||||
.map(|(name, ty, _)| {
|
||||
let subst_ty = unifier.subst(*ty, &subst).unwrap_or(*ty);
|
||||
// methods are immutable
|
||||
(*name, (subst_ty, false))
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
tobj_fields.extend(fields.iter().map(|(name, ty, mutability)| {
|
||||
let subst_ty = unifier.subst(*ty, &subst).unwrap_or(*ty);
|
||||
(*name, (subst_ty, *mutability))
|
||||
}));
|
||||
let need_subst = !subst.is_empty();
|
||||
let ty = unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: *obj_id,
|
||||
fields: tobj_fields,
|
||||
params: subst,
|
||||
});
|
||||
if need_subst {
|
||||
subst_list.as_mut().map(|wl| wl.push(ty));
|
||||
}
|
||||
Ok(ty)
|
||||
}
|
||||
TypeAnnotation::Primitive(ty) | TypeAnnotation::TypeVar(ty) => Ok(*ty),
|
||||
TypeAnnotation::Constant { ty, value, .. } => {
|
||||
let ty_enum = unifier.get_ty(*ty);
|
||||
let (ty, loc) = match &*ty_enum {
|
||||
TypeEnum::TVar { range: ntv_underlying_ty, loc, is_const_generic: true, .. } => {
|
||||
(ntv_underlying_ty[0], loc)
|
||||
}
|
||||
_ => unreachable!("{} ({})", unifier.stringify(*ty), ty_enum.get_type_name()),
|
||||
};
|
||||
|
||||
let var = unifier.get_fresh_constant(value.clone(), ty, *loc);
|
||||
Ok(var)
|
||||
}
|
||||
TypeAnnotation::Virtual(ty) => {
|
||||
let ty = get_type_from_type_annotation_kinds(
|
||||
top_level_defs,
|
||||
|
@ -470,7 +557,7 @@ pub fn get_type_var_contained_in_type_annotation(ann: &TypeAnnotation) -> Vec<Ty
|
|||
result.extend(get_type_var_contained_in_type_annotation(a));
|
||||
}
|
||||
}
|
||||
TypeAnnotation::Primitive(..) => {}
|
||||
TypeAnnotation::Primitive(..) | TypeAnnotation::Constant { .. } => {}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ impl<'a> Inferencer<'a> {
|
|||
) -> Result<(), String> {
|
||||
// there are some cases where the custom field is None
|
||||
if let Some(ty) = &expr.custom {
|
||||
if !self.unifier.is_concrete(*ty, &self.function_data.bound_variables) {
|
||||
if !matches!(&expr.node, ExprKind::Constant { value: Constant::Ellipsis, .. }) && !self.unifier.is_concrete(*ty, &self.function_data.bound_variables) {
|
||||
return Err(format!(
|
||||
"expected concrete type at {} but got {}",
|
||||
expr.location,
|
||||
|
|
|
@ -964,6 +964,7 @@ impl<'a> Inferencer<'a> {
|
|||
ast::Constant::Str(_) => Ok(self.primitives.str),
|
||||
ast::Constant::None
|
||||
=> report_error("CPython `None` not supported (nac3 uses `none` instead)", *loc),
|
||||
ast::Constant::Ellipsis => Ok(self.unifier.get_fresh_var(None, None).0),
|
||||
_ => report_error("not supported", *loc),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,6 +134,17 @@ pub enum TypeEnum {
|
|||
range: Vec<Type>,
|
||||
name: Option<StrRef>,
|
||||
loc: Option<Location>,
|
||||
/// Whether this type variable refers to a const-generic variable.
|
||||
is_const_generic: bool,
|
||||
},
|
||||
|
||||
/// A constant for substitution into a const generic variable.
|
||||
TConstant {
|
||||
/// The value of the constant.
|
||||
value: SymbolValue,
|
||||
/// The underlying type of the value.
|
||||
ty: Type,
|
||||
loc: Option<Location>,
|
||||
},
|
||||
|
||||
/// A tuple type.
|
||||
|
@ -178,6 +189,7 @@ impl TypeEnum {
|
|||
match self {
|
||||
TypeEnum::TRigidVar { .. } => "TRigidVar",
|
||||
TypeEnum::TVar { .. } => "TVar",
|
||||
TypeEnum::TConstant { .. } => "TConstant",
|
||||
TypeEnum::TTuple { .. } => "TTuple",
|
||||
TypeEnum::TList { .. } => "TList",
|
||||
TypeEnum::TObj { .. } => "TObj",
|
||||
|
@ -263,6 +275,7 @@ impl Unifier {
|
|||
fields: Some(fields),
|
||||
name: None,
|
||||
loc: None,
|
||||
is_const_generic: false,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -336,7 +349,33 @@ impl Unifier {
|
|||
let id = self.var_id + 1;
|
||||
self.var_id += 1;
|
||||
let range = range.to_vec();
|
||||
(self.add_ty(TypeEnum::TVar { id, range, fields: None, name, loc }), id)
|
||||
(self.add_ty(TypeEnum::TVar { id, range, fields: None, name, loc, is_const_generic: false }), id)
|
||||
}
|
||||
|
||||
/// Returns a fresh type representing a constant generic variable with the given underlying type
|
||||
/// `ty`.
|
||||
pub fn get_fresh_const_generic_var(
|
||||
&mut self,
|
||||
ty: Type,
|
||||
name: Option<StrRef>,
|
||||
loc: Option<Location>,
|
||||
) -> (Type, u32) {
|
||||
let id = self.var_id + 1;
|
||||
self.var_id += 1;
|
||||
(self.add_ty(TypeEnum::TVar { id, range: vec![ty], fields: None, name, loc, is_const_generic: true }), id)
|
||||
}
|
||||
|
||||
/// Returns a fresh type representing a [fresh constant][TypeEnum::TConstant] with the given
|
||||
/// `value` and type `ty`.
|
||||
pub fn get_fresh_constant(
|
||||
&mut self,
|
||||
value: SymbolValue,
|
||||
ty: Type,
|
||||
loc: Option<Location>,
|
||||
) -> Type {
|
||||
assert!(matches!(self.get_ty(ty).as_ref(), TypeEnum::TObj { .. }));
|
||||
|
||||
self.add_ty(TypeEnum::TConstant { ty, value, loc })
|
||||
}
|
||||
|
||||
/// Unification would not unify rigid variables with other types, but we want to do this for
|
||||
|
@ -412,7 +451,7 @@ impl Unifier {
|
|||
pub fn is_concrete(&mut self, a: Type, allowed_typevars: &[Type]) -> bool {
|
||||
use TypeEnum::*;
|
||||
match &*self.get_ty(a) {
|
||||
TRigidVar { .. } => true,
|
||||
TRigidVar { .. } | TConstant { .. } => true,
|
||||
TVar { .. } => allowed_typevars.iter().any(|b| self.unification_table.unioned(a, *b)),
|
||||
TCall { .. } => false,
|
||||
TList { ty } => self.is_concrete(*ty, allowed_typevars),
|
||||
|
@ -560,8 +599,8 @@ impl Unifier {
|
|||
};
|
||||
match (&*ty_a, &*ty_b) {
|
||||
(
|
||||
TVar { fields: fields1, id, name: name1, loc: loc1, .. },
|
||||
TVar { fields: fields2, id: id2, name: name2, loc: loc2, .. },
|
||||
TVar { fields: fields1, id, name: name1, loc: loc1, is_const_generic: false, .. },
|
||||
TVar { fields: fields2, id: id2, name: name2, loc: loc2, is_const_generic: false, .. },
|
||||
) => {
|
||||
let new_fields = match (fields1, fields2) {
|
||||
(None, None) => None,
|
||||
|
@ -616,10 +655,11 @@ impl Unifier {
|
|||
range,
|
||||
name: name1.or(*name2),
|
||||
loc: loc1.or(*loc2),
|
||||
is_const_generic: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
(TVar { fields: None, range, .. }, _) => {
|
||||
(TVar { fields: None, range, is_const_generic: false, .. }, _) => {
|
||||
// We check for the range of the type variable to see if unification is allowed.
|
||||
// Note that although b may be compatible with a, we may have to constrain type
|
||||
// variables in b to make sure that instantiations of b would always be compatible
|
||||
|
@ -636,7 +676,7 @@ impl Unifier {
|
|||
self.unify_impl(x, b, false)?;
|
||||
self.set_a_to_b(a, x);
|
||||
}
|
||||
(TVar { fields: Some(fields), range, .. }, TTuple { ty }) => {
|
||||
(TVar { fields: Some(fields), range, is_const_generic: false, .. }, TTuple { ty }) => {
|
||||
let len = ty.len() as i32;
|
||||
for (k, v) in fields.iter() {
|
||||
match *k {
|
||||
|
@ -666,7 +706,7 @@ impl Unifier {
|
|||
self.unify_impl(x, b, false)?;
|
||||
self.set_a_to_b(a, x);
|
||||
}
|
||||
(TVar { fields: Some(fields), range, .. }, TList { ty }) => {
|
||||
(TVar { fields: Some(fields), range, is_const_generic: false, .. }, TList { ty }) => {
|
||||
for (k, v) in fields.iter() {
|
||||
match *k {
|
||||
RecordKey::Int(_) => {
|
||||
|
@ -681,6 +721,35 @@ impl Unifier {
|
|||
self.unify_impl(x, b, false)?;
|
||||
self.set_a_to_b(a, x);
|
||||
}
|
||||
|
||||
(TVar { id: id1, range: ty1, is_const_generic: true, .. }, TVar { id: id2, range: ty2, .. }) => {
|
||||
let ty1 = ty1[0];
|
||||
let ty2 = ty2[0];
|
||||
|
||||
if id1 != id2 {
|
||||
self.unify_impl(ty1, ty2, false)?;
|
||||
}
|
||||
|
||||
self.set_a_to_b(a, b);
|
||||
}
|
||||
|
||||
(TVar { range: ty1, is_const_generic: true, .. }, TConstant { ty: ty2, .. }) => {
|
||||
let ty1 = ty1[0];
|
||||
|
||||
self.unify_impl(ty1, *ty2, false)?;
|
||||
self.set_a_to_b(a, b);
|
||||
}
|
||||
|
||||
(TConstant { value: val1, ty: ty1, .. }, TConstant { value: val2, ty: ty2, .. }) => {
|
||||
if val1 != val2 {
|
||||
eprintln!("VALUE MISMATCH: lhs={val1:?} rhs={val2:?} eq={}", val1 == val2);
|
||||
return self.incompatible_types(a, b)
|
||||
}
|
||||
self.unify_impl(*ty1, *ty2, false)?;
|
||||
|
||||
self.set_a_to_b(a, b);
|
||||
}
|
||||
|
||||
(TTuple { ty: ty1 }, TTuple { ty: ty2 }) => {
|
||||
if ty1.len() != ty2.len() {
|
||||
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
|
||||
|
@ -775,7 +844,14 @@ impl Unifier {
|
|||
if id1 != id2 {
|
||||
self.incompatible_types(a, b)?;
|
||||
}
|
||||
for (x, y) in zip(params1.values(), params2.values()) {
|
||||
|
||||
// Sort the type arguments by its UnificationKey first, since `HashMap::iter` visits
|
||||
// all K-V pairs "in arbitrary order"
|
||||
let (tv1, tv2) = (
|
||||
params1.iter().sorted_by_key(|(k, _)| *k).map(|(_, v)| v).collect_vec(),
|
||||
params2.iter().sorted_by_key(|(k, _)| *k).map(|(_, v)| v).collect_vec(),
|
||||
);
|
||||
for (x, y) in zip(tv1, tv2) {
|
||||
if self.unify_impl(*x, *y, false).is_err() {
|
||||
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
|
||||
};
|
||||
|
@ -928,6 +1004,9 @@ impl Unifier {
|
|||
};
|
||||
n
|
||||
}
|
||||
TypeEnum::TConstant { value, .. } => {
|
||||
format!("const({value})")
|
||||
}
|
||||
TypeEnum::TTuple { ty } => {
|
||||
let mut fields =
|
||||
ty.iter().map(|v| self.internal_stringify(*v, obj_to_name, var_to_name, notes));
|
||||
|
@ -983,8 +1062,8 @@ impl Unifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// Unifies `a` and `b` together, and set the value to the value of `b`.
|
||||
fn set_a_to_b(&mut self, a: Type, b: Type) {
|
||||
// unify a and b together, and set the value to b's value.
|
||||
let table = &mut self.unification_table;
|
||||
let ty_b = table.probe_value(b).clone();
|
||||
table.unify(a, b);
|
||||
|
@ -1207,6 +1286,7 @@ impl Unifier {
|
|||
range,
|
||||
name: name2.or(*name),
|
||||
loc: loc2.or(*loc),
|
||||
is_const_generic: false,
|
||||
};
|
||||
Ok(Some(self.unification_table.new_key(ty.into())))
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ void output_int32(int32_t x) {
|
|||
}
|
||||
|
||||
void output_int64(int64_t x) {
|
||||
printf("%ld\n", x);
|
||||
printf("%lld\n", x);
|
||||
}
|
||||
|
||||
void output_uint32(uint32_t x) {
|
||||
|
@ -38,7 +38,7 @@ void output_uint32(uint32_t x) {
|
|||
}
|
||||
|
||||
void output_uint64(uint64_t x) {
|
||||
printf("%lu\n", x);
|
||||
printf("%llu\n", x);
|
||||
}
|
||||
|
||||
void output_float64(double x) {
|
||||
|
|
|
@ -6,9 +6,9 @@ import importlib.machinery
|
|||
import math
|
||||
import numpy as np
|
||||
import pathlib
|
||||
import scipy
|
||||
|
||||
from numpy import int32, int64, uint32, uint64
|
||||
from scipy import special
|
||||
from typing import TypeVar, Generic
|
||||
|
||||
T = TypeVar('T')
|
||||
|
@ -44,6 +44,12 @@ def Some(v: T) -> Option[T]:
|
|||
|
||||
none = Option(None)
|
||||
|
||||
class _ConstGenericMarker:
|
||||
pass
|
||||
|
||||
def ConstGeneric(name, constraint):
|
||||
return TypeVar(name, _ConstGenericMarker, constraint)
|
||||
|
||||
def round_away_zero(x):
|
||||
if x >= 0.0:
|
||||
return math.floor(x + 0.5)
|
||||
|
@ -99,6 +105,7 @@ def patch(module):
|
|||
module.uint32 = uint32
|
||||
module.uint64 = uint64
|
||||
module.TypeVar = TypeVar
|
||||
module.ConstGeneric = ConstGeneric
|
||||
module.Generic = Generic
|
||||
module.extern = extern
|
||||
module.Option = Option
|
||||
|
@ -108,52 +115,55 @@ def patch(module):
|
|||
# Builtin Math functions
|
||||
module.round = round_away_zero
|
||||
module.round64 = round_away_zero
|
||||
module.np_round = np.round
|
||||
module.floor = math.floor
|
||||
module.floor64 = math.floor
|
||||
module.np_floor = np.floor
|
||||
module.ceil = math.ceil
|
||||
module.ceil64 = math.ceil
|
||||
module.np_ceil = np.ceil
|
||||
|
||||
# NumPy Math functions
|
||||
module.isnan = np.isnan
|
||||
module.isinf = np.isinf
|
||||
module.sin = np.sin
|
||||
module.cos = np.cos
|
||||
module.exp = np.exp
|
||||
module.exp2 = np.exp2
|
||||
module.log = np.log
|
||||
module.log10 = np.log10
|
||||
module.log2 = np.log2
|
||||
module.fabs = np.fabs
|
||||
module.trunc = np.trunc
|
||||
module.sqrt = np.sqrt
|
||||
module.rint = np.rint
|
||||
module.tan = np.tan
|
||||
module.arcsin = np.arcsin
|
||||
module.arccos = np.arccos
|
||||
module.arctan = np.arctan
|
||||
module.sinh = np.sinh
|
||||
module.cosh = np.cosh
|
||||
module.tanh = np.tanh
|
||||
module.arcsinh = np.arcsinh
|
||||
module.arccosh = np.arccosh
|
||||
module.arctanh = np.arctanh
|
||||
module.expm1 = np.expm1
|
||||
module.cbrt = np.cbrt
|
||||
module.arctan2 = np.arctan2
|
||||
module.copysign = np.copysign
|
||||
module.fmax = np.fmax
|
||||
module.fmin = np.fmin
|
||||
module.ldexp = np.ldexp
|
||||
module.hypot = np.hypot
|
||||
module.nextafter = np.nextafter
|
||||
module.np_isnan = np.isnan
|
||||
module.np_isinf = np.isinf
|
||||
module.np_sin = np.sin
|
||||
module.np_cos = np.cos
|
||||
module.np_exp = np.exp
|
||||
module.np_exp2 = np.exp2
|
||||
module.np_log = np.log
|
||||
module.np_log10 = np.log10
|
||||
module.np_log2 = np.log2
|
||||
module.np_fabs = np.fabs
|
||||
module.np_trunc = np.trunc
|
||||
module.np_sqrt = np.sqrt
|
||||
module.np_rint = np.rint
|
||||
module.np_tan = np.tan
|
||||
module.np_arcsin = np.arcsin
|
||||
module.np_arccos = np.arccos
|
||||
module.np_arctan = np.arctan
|
||||
module.np_sinh = np.sinh
|
||||
module.np_cosh = np.cosh
|
||||
module.np_tanh = np.tanh
|
||||
module.np_arcsinh = np.arcsinh
|
||||
module.np_arccosh = np.arccosh
|
||||
module.np_arctanh = np.arctanh
|
||||
module.np_expm1 = np.expm1
|
||||
module.np_cbrt = np.cbrt
|
||||
module.np_arctan2 = np.arctan2
|
||||
module.np_copysign = np.copysign
|
||||
module.np_fmax = np.fmax
|
||||
module.np_fmin = np.fmin
|
||||
module.np_ldexp = np.ldexp
|
||||
module.np_hypot = np.hypot
|
||||
module.np_nextafter = np.nextafter
|
||||
|
||||
# SciPy Math Functions
|
||||
module.erf = scipy.special.erf
|
||||
module.erfc = scipy.special.erfc
|
||||
module.gamma = scipy.special.gamma
|
||||
module.gammaln = scipy.special.gammaln
|
||||
module.j0 = scipy.special.j0
|
||||
module.j1 = scipy.special.j1
|
||||
module.sp_spec_erf = special.erf
|
||||
module.sp_spec_erfc = special.erfc
|
||||
module.sp_spec_gamma = special.gamma
|
||||
module.sp_spec_gammaln = special.gammaln
|
||||
module.sp_spec_j0 = special.j0
|
||||
module.sp_spec_j1 = special.j1
|
||||
|
||||
|
||||
def file_import(filename, prefix="file_import_"):
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
A = ConstGeneric("A", int32)
|
||||
B = ConstGeneric("B", uint32)
|
||||
T = TypeVar("T")
|
||||
|
||||
class ConstGenericClass(Generic[A]):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
class ConstGeneric2Class(Generic[A, B]):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
class HybridGenericClass2(Generic[A, T]):
|
||||
pass
|
||||
|
||||
class HybridGenericClass3(Generic[T, A, B]):
|
||||
pass
|
||||
|
||||
def make_generic_2() -> ConstGenericClass[2]:
|
||||
return ...
|
||||
|
||||
def make_generic2_1_2() -> ConstGeneric2Class[1, 2]:
|
||||
return ...
|
||||
|
||||
def make_hybrid_class_2_int32() -> HybridGenericClass2[2, int32]:
|
||||
return ...
|
||||
|
||||
def make_hybrid_class_i32_0_1() -> HybridGenericClass3[int32, 0, 1]:
|
||||
return ...
|
||||
|
||||
def consume_generic_2(instance: ConstGenericClass[2]):
|
||||
pass
|
||||
|
||||
def consume_generic2_1_2(instance: ConstGeneric2Class[1, 2]):
|
||||
pass
|
||||
|
||||
def consume_hybrid_class_2_i32(instance: HybridGenericClass2[2, int32]):
|
||||
pass
|
||||
|
||||
def consume_hybrid_class_i32_0_1(instance: HybridGenericClass3[int32, 0, 1]):
|
||||
pass
|
||||
|
||||
def f():
|
||||
consume_generic_2(make_generic_2())
|
||||
consume_generic2_1_2(make_generic2_1_2())
|
||||
consume_hybrid_class_2_i32(make_hybrid_class_2_int32())
|
||||
consume_hybrid_class_i32_0_1(make_hybrid_class_i32_0_1())
|
||||
|
||||
def run() -> int32:
|
||||
return 0
|
|
@ -36,48 +36,52 @@ def test_round64():
|
|||
for x in [-1.5, -0.5, 0.5, 1.5]:
|
||||
output_int64(round64(x))
|
||||
|
||||
def test_isnan():
|
||||
def test_np_round():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(np_round(x))
|
||||
|
||||
def test_np_isnan():
|
||||
for x in [dbl_nan(), 0.0, dbl_inf()]:
|
||||
output_bool(isnan(x))
|
||||
output_bool(np_isnan(x))
|
||||
|
||||
def test_isinf():
|
||||
def test_np_isinf():
|
||||
for x in [dbl_inf(), -dbl_inf(), 0.0, dbl_nan()]:
|
||||
output_bool(isinf(x))
|
||||
output_bool(np_isinf(x))
|
||||
|
||||
def test_sin():
|
||||
def test_np_sin():
|
||||
pi = dbl_pi()
|
||||
for x in [-pi, -pi / 2.0, -pi / 4.0, 0.0, pi / 4.0, pi / 2.0, pi, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(sin(x))
|
||||
output_float64(np_sin(x))
|
||||
|
||||
def test_cos():
|
||||
def test_np_cos():
|
||||
pi = dbl_pi()
|
||||
for x in [-pi, -pi / 2.0, -pi / 4.0, 0.0, pi / 4.0, pi / 2.0, pi, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(cos(x))
|
||||
output_float64(np_cos(x))
|
||||
|
||||
def test_exp():
|
||||
def test_np_exp():
|
||||
for x in [0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(exp(x))
|
||||
output_float64(np_exp(x))
|
||||
|
||||
def test_exp2():
|
||||
def test_np_exp2():
|
||||
for x in [0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(exp2(x))
|
||||
output_float64(np_exp2(x))
|
||||
|
||||
def test_log():
|
||||
def test_np_log():
|
||||
e = dbl_e()
|
||||
for x in [1.0, e, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(log(x))
|
||||
output_float64(np_log(x))
|
||||
|
||||
def test_log10():
|
||||
def test_np_log10():
|
||||
for x in [1.0, 10.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(log10(x))
|
||||
output_float64(np_log10(x))
|
||||
|
||||
def test_log2():
|
||||
def test_np_log2():
|
||||
for x in [1.0, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(log2(x))
|
||||
output_float64(np_log2(x))
|
||||
|
||||
def test_fabs():
|
||||
def test_np_fabs():
|
||||
for x in [-1.0, 0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(fabs(x))
|
||||
output_float64(np_fabs(x))
|
||||
|
||||
def test_floor():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5]:
|
||||
|
@ -87,6 +91,10 @@ def test_floor64():
|
|||
for x in [-1.5, -0.5, 0.5, 1.5]:
|
||||
output_int64(floor64(x))
|
||||
|
||||
def test_np_floor():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(np_floor(x))
|
||||
|
||||
def test_ceil():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5]:
|
||||
output_int32(ceil(x))
|
||||
|
@ -95,165 +103,172 @@ def test_ceil64():
|
|||
for x in [-1.5, -0.5, 0.5, 1.5]:
|
||||
output_int64(ceil64(x))
|
||||
|
||||
def test_sqrt():
|
||||
for x in [1.0, 2.0, 4.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(sqrt(x))
|
||||
|
||||
def test_rint():
|
||||
def test_np_ceil():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(rint(x))
|
||||
output_float64(np_ceil(x))
|
||||
|
||||
def test_tan():
|
||||
def test_np_sqrt():
|
||||
for x in [1.0, 2.0, 4.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(np_sqrt(x))
|
||||
|
||||
def test_np_rint():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(np_rint(x))
|
||||
|
||||
def test_np_tan():
|
||||
pi = dbl_pi()
|
||||
for x in [-pi, -pi / 2.0, -pi / 4.0, 0.0, pi / 4.0, pi / 2.0, pi, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(tan(x))
|
||||
output_float64(np_tan(x))
|
||||
|
||||
def test_arcsin():
|
||||
def test_np_arcsin():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arcsin(x))
|
||||
output_float64(np_arcsin(x))
|
||||
|
||||
def test_arccos():
|
||||
def test_np_arccos():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arccos(x))
|
||||
output_float64(np_arccos(x))
|
||||
|
||||
def test_arctan():
|
||||
def test_np_arctan():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arctan(x))
|
||||
output_float64(np_arctan(x))
|
||||
|
||||
def test_sinh():
|
||||
def test_np_sinh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(sinh(x))
|
||||
output_float64(np_sinh(x))
|
||||
|
||||
def test_cosh():
|
||||
def test_np_cosh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(cosh(x))
|
||||
output_float64(np_cosh(x))
|
||||
|
||||
def test_tanh():
|
||||
def test_np_tanh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(tanh(x))
|
||||
output_float64(np_tanh(x))
|
||||
|
||||
def test_arcsinh():
|
||||
def test_np_arcsinh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arcsinh(x))
|
||||
output_float64(np_arcsinh(x))
|
||||
|
||||
def test_arccosh():
|
||||
def test_np_arccosh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arccosh(x))
|
||||
output_float64(np_arccosh(x))
|
||||
|
||||
def test_arctanh():
|
||||
def test_np_arctanh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arctanh(x))
|
||||
output_float64(np_arctanh(x))
|
||||
|
||||
def test_expm1():
|
||||
def test_np_expm1():
|
||||
for x in [0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(expm1(x))
|
||||
output_float64(np_expm1(x))
|
||||
|
||||
def test_cbrt():
|
||||
def test_np_cbrt():
|
||||
for x in [1.0, 8.0, 27.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(expm1(x))
|
||||
output_float64(np_expm1(x))
|
||||
|
||||
def test_erf():
|
||||
def test_sp_spec_erf():
|
||||
for x in [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(erf(x))
|
||||
output_float64(sp_spec_erf(x))
|
||||
|
||||
def test_erfc():
|
||||
def test_sp_spec_erfc():
|
||||
for x in [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(erfc(x))
|
||||
output_float64(sp_spec_erfc(x))
|
||||
|
||||
def test_gamma():
|
||||
def test_sp_spec_gamma():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(gamma(x))
|
||||
output_float64(sp_spec_gamma(x))
|
||||
|
||||
def test_gammaln():
|
||||
def test_sp_spec_gammaln():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(gammaln(x))
|
||||
output_float64(sp_spec_gammaln(x))
|
||||
|
||||
def test_j0():
|
||||
def test_sp_spec_j0():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(j0(x))
|
||||
output_float64(sp_spec_j0(x))
|
||||
|
||||
def test_j1():
|
||||
def test_sp_spec_j1():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0]:
|
||||
output_float64(j1(x))
|
||||
output_float64(sp_spec_j1(x))
|
||||
|
||||
def test_arctan2():
|
||||
def test_np_arctan2():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arctan2(x1, x2))
|
||||
output_float64(np_arctan2(x1, x2))
|
||||
|
||||
def test_copysign():
|
||||
def test_np_copysign():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(copysign(x1, x2))
|
||||
output_float64(np_copysign(x1, x2))
|
||||
|
||||
def test_fmax():
|
||||
def test_np_fmax():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(fmax(x1, x2))
|
||||
output_float64(np_fmax(x1, x2))
|
||||
|
||||
def test_fmin():
|
||||
def test_np_fmin():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(fmin(x1, x2))
|
||||
output_float64(np_fmin(x1, x2))
|
||||
|
||||
def test_ldexp():
|
||||
def test_np_ldexp():
|
||||
for x1 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-2, -1, 0, 1, 2]:
|
||||
output_float64(ldexp(x1, x2))
|
||||
output_float64(np_ldexp(x1, x2))
|
||||
|
||||
def test_hypot():
|
||||
def test_np_hypot():
|
||||
for x1 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(hypot(x1, x2))
|
||||
output_float64(np_hypot(x1, x2))
|
||||
|
||||
def test_nextafter():
|
||||
def test_np_nextafter():
|
||||
for x1 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(nextafter(x1, x2))
|
||||
output_float64(np_nextafter(x1, x2))
|
||||
|
||||
def run() -> int32:
|
||||
test_round()
|
||||
test_round64()
|
||||
test_isnan()
|
||||
test_isinf()
|
||||
test_sin()
|
||||
test_cos()
|
||||
test_exp()
|
||||
test_exp2()
|
||||
test_log()
|
||||
test_log10()
|
||||
test_log2()
|
||||
test_fabs()
|
||||
test_np_round()
|
||||
test_np_isnan()
|
||||
test_np_isinf()
|
||||
test_np_sin()
|
||||
test_np_cos()
|
||||
test_np_exp()
|
||||
test_np_exp2()
|
||||
test_np_log()
|
||||
test_np_log10()
|
||||
test_np_log2()
|
||||
test_np_fabs()
|
||||
test_floor()
|
||||
test_floor64()
|
||||
test_np_floor()
|
||||
test_ceil()
|
||||
test_ceil64()
|
||||
test_sqrt()
|
||||
test_rint()
|
||||
test_tan()
|
||||
test_arcsin()
|
||||
test_arccos()
|
||||
test_arctan()
|
||||
test_sinh()
|
||||
test_cosh()
|
||||
test_tanh()
|
||||
test_arcsinh()
|
||||
test_arccosh()
|
||||
test_arctanh()
|
||||
test_expm1()
|
||||
test_cbrt()
|
||||
test_erf()
|
||||
test_erfc()
|
||||
test_gamma()
|
||||
test_gammaln()
|
||||
test_j0()
|
||||
test_j1()
|
||||
test_arctan2()
|
||||
test_copysign()
|
||||
test_fmax()
|
||||
test_fmin()
|
||||
test_ldexp()
|
||||
test_hypot()
|
||||
test_nextafter()
|
||||
test_np_ceil()
|
||||
test_np_sqrt()
|
||||
test_np_rint()
|
||||
test_np_tan()
|
||||
test_np_arcsin()
|
||||
test_np_arccos()
|
||||
test_np_arctan()
|
||||
test_np_sinh()
|
||||
test_np_cosh()
|
||||
test_np_tanh()
|
||||
test_np_arcsinh()
|
||||
test_np_arccosh()
|
||||
test_np_arctanh()
|
||||
test_np_expm1()
|
||||
test_np_cbrt()
|
||||
test_sp_spec_erf()
|
||||
test_sp_spec_erfc()
|
||||
test_sp_spec_gamma()
|
||||
test_sp_spec_gammaln()
|
||||
test_sp_spec_j0()
|
||||
test_sp_spec_j1()
|
||||
test_np_arctan2()
|
||||
test_np_copysign()
|
||||
test_np_fmax()
|
||||
test_np_fmin()
|
||||
test_np_ldexp()
|
||||
test_np_hypot()
|
||||
test_np_nextafter()
|
||||
|
||||
return 0
|
|
@ -0,0 +1,26 @@
|
|||
def run() -> int32:
|
||||
# Numeric Primitives
|
||||
b: bool = False
|
||||
i32: int32 = 0
|
||||
i64: int64 = int64(0)
|
||||
u32: uint32 = uint32(0)
|
||||
u64: uint64 = uint64(0)
|
||||
f64: float = 0.0
|
||||
|
||||
# String
|
||||
s: str = ""
|
||||
|
||||
# List
|
||||
l_i32: list[int32] = []
|
||||
l_f64: list[float] = []
|
||||
l_str: list[str] = []
|
||||
|
||||
# Option
|
||||
o_some: Option[int32] = Some(0)
|
||||
o_none: Option[int32] = none
|
||||
|
||||
# Tuple
|
||||
t_i32_i32: tuple[int32, int32] = (0, 0)
|
||||
t_i32_f64: tuple[int32, float] = (0, 0.0)
|
||||
|
||||
return 0
|
|
@ -7,7 +7,7 @@ use inkwell::{
|
|||
OptimizationLevel,
|
||||
};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use std::{borrow::Borrow, collections::HashMap, fs, path::Path, sync::Arc};
|
||||
use std::{collections::HashMap, fs, path::Path, sync::Arc};
|
||||
|
||||
use nac3core::{
|
||||
codegen::{
|
||||
|
@ -25,7 +25,7 @@ use nac3core::{
|
|||
},
|
||||
};
|
||||
use nac3parser::{
|
||||
ast::{Expr, ExprKind, StmtKind},
|
||||
ast::{Constant, Expr, ExprKind, StmtKind, StrRef},
|
||||
parser,
|
||||
};
|
||||
|
||||
|
@ -77,8 +77,20 @@ fn handle_typevar_definition(
|
|||
unifier: &mut Unifier,
|
||||
primitives: &PrimitiveStore,
|
||||
) -> Result<Type, String> {
|
||||
if let ExprKind::Call { func, args, .. } = &var.node {
|
||||
if matches!(&func.node, ExprKind::Name { id, .. } if id == &"TypeVar".into()) {
|
||||
let ExprKind::Call { func, args, .. } = &var.node else {
|
||||
return Err(format!(
|
||||
"expression {:?} cannot be handled as a generic parameter in global scope",
|
||||
var
|
||||
))
|
||||
};
|
||||
|
||||
match &func.node {
|
||||
ExprKind::Name { id, .. } if id == &"TypeVar".into() => {
|
||||
let ExprKind::Constant { value: Constant::Str(ty_name), .. } = &args[0].node else {
|
||||
return Err(format!("Expected string constant for first parameter of `TypeVar`, got {:?}", &args[0].node))
|
||||
};
|
||||
let generic_name: StrRef = ty_name.to_string().into();
|
||||
|
||||
let constraints = args
|
||||
.iter()
|
||||
.skip(1)
|
||||
|
@ -90,22 +102,54 @@ fn handle_typevar_definition(
|
|||
primitives,
|
||||
x,
|
||||
Default::default(),
|
||||
None,
|
||||
)?;
|
||||
get_type_from_type_annotation_kinds(
|
||||
def_list, unifier, primitives, &ty, &mut None
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(unifier.get_fresh_var_with_range(&constraints, None, None).0)
|
||||
} else {
|
||||
Err(format!(
|
||||
"expression {:?} cannot be handled as a TypeVar in global scope",
|
||||
var
|
||||
))
|
||||
let loc = func.location;
|
||||
|
||||
if constraints.len() == 1 {
|
||||
return Err(format!("A single constraint is not allowed (at {})", loc))
|
||||
}
|
||||
|
||||
Ok(unifier.get_fresh_var_with_range(&constraints, Some(generic_name), Some(loc)).0)
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"expression {:?} cannot be handled as a TypeVar in global scope",
|
||||
|
||||
ExprKind::Name { id, .. } if id == &"ConstGeneric".into() => {
|
||||
if args.len() != 2 {
|
||||
return Err(format!("Expected 2 arguments for `ConstGeneric`, got {}", args.len()))
|
||||
}
|
||||
|
||||
let ExprKind::Constant { value: Constant::Str(ty_name), .. } = &args[0].node else {
|
||||
return Err(format!(
|
||||
"Expected string constant for first parameter of `ConstGeneric`, got {:?}",
|
||||
&args[0].node
|
||||
))
|
||||
};
|
||||
let generic_name: StrRef = ty_name.to_string().into();
|
||||
|
||||
let ty = parse_ast_to_type_annotation_kinds(
|
||||
resolver,
|
||||
def_list,
|
||||
unifier,
|
||||
primitives,
|
||||
&args[1],
|
||||
Default::default(),
|
||||
None,
|
||||
)?;
|
||||
let constraint = get_type_from_type_annotation_kinds(
|
||||
def_list, unifier, primitives, &ty, &mut None
|
||||
)?;
|
||||
let loc = func.location;
|
||||
|
||||
Ok(unifier.get_fresh_const_generic_var(constraint, Some(generic_name), Some(loc)).0)
|
||||
}
|
||||
|
||||
_ => Err(format!(
|
||||
"expression {:?} cannot be handled as a generic parameter in global scope",
|
||||
var
|
||||
))
|
||||
}
|
||||
|
@ -124,7 +168,7 @@ fn handle_assignment_pattern(
|
|||
match &targets[0].node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
if let Ok(var) = handle_typevar_definition(
|
||||
value.borrow(),
|
||||
value,
|
||||
resolver,
|
||||
def_list,
|
||||
unifier,
|
||||
|
@ -133,12 +177,12 @@ fn handle_assignment_pattern(
|
|||
internal_resolver.add_id_type(*id, var);
|
||||
Ok(())
|
||||
} else if let Ok(val) =
|
||||
parse_parameter_default_value(value.borrow(), resolver)
|
||||
parse_parameter_default_value(value, resolver)
|
||||
{
|
||||
internal_resolver.add_module_global(*id, val);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("fails to evaluate this expression `{:?}` as a constant or TypeVar at {}",
|
||||
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
|
||||
targets[0].node,
|
||||
targets[0].location,
|
||||
))
|
||||
|
@ -324,6 +368,7 @@ fn main() {
|
|||
triple,
|
||||
cpu: mcpu,
|
||||
features: target_features,
|
||||
reloc_mode: RelocMode::PIC,
|
||||
..host_target_machine
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
pkgbase="mingw-w64-nac3artiq"
|
||||
pkgname="mingw-w64-x86_64-nac3artiq"
|
||||
pkgname="mingw-w64-clang-x86_64-nac3artiq"
|
||||
pkgver=1.0
|
||||
pkgrel=1
|
||||
pkgdesc="New ARTIQ compiler 3"
|
||||
arch=("any")
|
||||
mingw_arch=("mingw64")
|
||||
mingw_arch=("clang64")
|
||||
url="https://m-labs.hk"
|
||||
license=("LGPL")
|
||||
source=("nac3artiq.pyd")
|
||||
noextract=("nac3artiq.pyd")
|
||||
sha256sums=("SKIP")
|
||||
depends=("mingw-w64-x86_64-python")
|
||||
depends=("mingw-w64-clang-x86_64-python")
|
||||
|
||||
prepare() {
|
||||
true
|
||||
|
@ -21,6 +21,6 @@ build() {
|
|||
}
|
||||
|
||||
package() {
|
||||
mkdir -p $pkgdir/mingw64/lib/python3.11/site-packages
|
||||
cp ${srcdir}/nac3artiq.pyd $pkgdir/mingw64/lib/python3.11/site-packages
|
||||
mkdir -p $pkgdir/clang64/lib/python3.11/site-packages
|
||||
cp ${srcdir}/nac3artiq.pyd $pkgdir/clang64/lib/python3.11/site-packages
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ let
|
|||
shared=true
|
||||
abi3=false
|
||||
lib_name=python3.11
|
||||
lib_dir=${msys2-env}/mingw64/lib
|
||||
lib_dir=${msys2-env}/clang64/lib
|
||||
pointer_width=64
|
||||
build_flags=WITH_THREAD
|
||||
suppress_build_script_link_lines=false
|
||||
|
@ -61,7 +61,7 @@ in rec {
|
|||
''
|
||||
export HOME=`mktemp -d`
|
||||
export WINEDEBUG=-all
|
||||
export WINEPATH=Z:${msys2-env}/mingw64/bin
|
||||
export WINEPATH=Z:${msys2-env}/clang64/bin
|
||||
${silenceFontconfig}
|
||||
mkdir build
|
||||
cd build
|
||||
|
@ -77,7 +77,12 @@ in rec {
|
|||
'';
|
||||
dontFixup = true;
|
||||
};
|
||||
clang-unwrapped = pkgs.runCommandNoCC "clang-unwrapped" {} "mkdir -p $out/bin; ln -s ${llvm-nac3}/bin/clang.exe $out/bin/clang-unwrapped.exe";
|
||||
llvm-tools-irrt = pkgs.runCommandNoCC "llvm-tools-irrt" {}
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
ln -s ${llvm-nac3}/bin/clang.exe $out/bin/clang-irrt.exe
|
||||
ln -s ${llvm-nac3}/bin/llvm-as.exe $out/bin/llvm-as-irrt.exe
|
||||
'';
|
||||
nac3artiq = pkgs.rustPlatform.buildRustPackage {
|
||||
name = "nac3artiq-msys2";
|
||||
src = ../../.;
|
||||
|
@ -89,9 +94,11 @@ in rec {
|
|||
''
|
||||
export HOME=`mktemp -d`
|
||||
export WINEDEBUG=-all
|
||||
export WINEPATH=Z:${msys2-env}/mingw64/bin\;Z:${llvm-nac3}/bin\;Z:${clang-unwrapped}/bin
|
||||
export WINEPATH=Z:${msys2-env}/clang64/bin\;Z:${llvm-nac3}/bin\;Z:${llvm-tools-irrt}/bin
|
||||
${silenceFontconfig}
|
||||
export PYO3_CONFIG_FILE=Z:${pyo3-mingw-config}
|
||||
export CC=clang
|
||||
export LLVM_SYS_140_PREFIX=Z:${llvm-nac3}
|
||||
wine64 cargo build --release -p nac3artiq
|
||||
'';
|
||||
installPhase =
|
||||
|
@ -100,6 +107,7 @@ in rec {
|
|||
cp target/release/nac3artiq.dll $out/nac3artiq.pyd
|
||||
echo file binary-dist $out/nac3artiq.pyd >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
doCheck = false; # https://git.m-labs.hk/M-Labs/nac3/issues/358
|
||||
checkPhase =
|
||||
''
|
||||
wine64 cargo test --release
|
||||
|
@ -127,7 +135,7 @@ in rec {
|
|||
wine-msys2 = pkgs.writeShellScriptBin "wine-msys2"
|
||||
''
|
||||
export WINEDEBUG=-all
|
||||
export WINEPATH=Z:${msys2-env}/mingw64/bin\;Z:${llvm-nac3}/bin\;Z:${clang-unwrapped}/bin
|
||||
export WINEPATH=Z:${msys2-env}/clang64/bin\;Z:${llvm-nac3}/bin\;Z:${llvm-tools-irrt}/bin
|
||||
export PYO3_CONFIG_FILE=Z:${pyo3-mingw-config}
|
||||
exec ${pkgs.wineWowPackages.stable}/bin/wine64 cmd
|
||||
'';
|
||||
|
@ -135,7 +143,7 @@ in rec {
|
|||
''
|
||||
export HOME=`mktemp -d`
|
||||
export WINEDEBUG=-all
|
||||
export WINEPATH=Z:${msys2-env}/mingw64/bin
|
||||
export WINEPATH=Z:${msys2-env}/clang64/bin
|
||||
${silenceFontconfig}
|
||||
exec ${pkgs.wineWowPackages.stable}/bin/wine64 $@
|
||||
'';
|
||||
|
|
|
@ -10,7 +10,7 @@ curl -L https://mirror.msys2.org/msys/x86_64/pacman-mirrors-20220205-1-any.pkg.t
|
|||
curl -L https://raw.githubusercontent.com/msys2/MSYS2-packages/master/pacman/pacman.conf | sed "s|SigLevel = Required|SigLevel = Never|g" | sed "s|/etc/pacman.d|$MSYS2DIR/etc/pacman.d|g" > $MSYS2DIR/etc/pacman.conf
|
||||
|
||||
fakeroot pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf -Syy
|
||||
pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf --cachedir $MSYS2DIR/msys/cache -Sp mingw-w64-x86_64-rust mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-python3.11 mingw-w64-x86_64-python-numpy mingw-w64-x86_64-python-setuptools > $MSYS2DIR/packages.txt
|
||||
pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf --cachedir $MSYS2DIR/msys/cache -Sp mingw-w64-clang-x86_64-rust mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-ninja mingw-w64-clang-x86_64-python3.11 mingw-w64-clang-x86_64-python-numpy mingw-w64-clang-x86_64-python-setuptools > $MSYS2DIR/packages.txt
|
||||
|
||||
echo "{ pkgs } : [" > msys2_packages.nix
|
||||
while read package; do
|
||||
|
|
|
@ -1,350 +1,344 @@
|
|||
{ pkgs } : [
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libwinpthread-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
sha256 = "1zv1s7jamj6m4b7l05s185cslyiclp1r5vhxv7lj16gz21n800vg";
|
||||
name = "mingw-w64-x86_64-libwinpthread-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libffi-3.4.4-1-any.pkg.tar.zst";
|
||||
sha256 = "0mws1g7w11riczc168x7kzb8nl74iry4bzkb72nspw1vmlblxfy6";
|
||||
name = "mingw-w64-clang-x86_64-libffi-3.4.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libs-13.2.0-2-any.pkg.tar.zst";
|
||||
sha256 = "0bxdyy0w0ld437skyl6wmp9d1j2jj71s8sw7wcysgv40y72b9jxc";
|
||||
name = "mingw-w64-x86_64-gcc-libs-13.2.0-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libunwind-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "1748ncih1zj4vnj9c0gcp5rf21gm2pn9xdy2hrigp2pvfchrnmwn";
|
||||
name = "mingw-w64-clang-x86_64-libunwind-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-zstd-1.5.5-1-any.pkg.tar.zst";
|
||||
sha256 = "19jr14l5anl1qr1lvcmdpnpgyxghf2mds2j7iiq4j99kfg7ig2s0";
|
||||
name = "mingw-w64-x86_64-zstd-1.5.5-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libc++-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "00waw5qmpycib7xhk6aywqgqg8y26q2xbm8m4za7mpy04g2alav4";
|
||||
name = "mingw-w64-clang-x86_64-libc++-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-binutils-2.41-2-any.pkg.tar.zst";
|
||||
sha256 = "1r2pf8sdhhs8mlyzagfl209d6xa92yqf0nzqvbd0ggapijni02ga";
|
||||
name = "mingw-w64-x86_64-binutils-2.41-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-zlib-1.3-1-any.pkg.tar.zst";
|
||||
sha256 = "0rfwz7czvwa8clickjw1kd114miyifxf1s2v9mxffkaivm45f62v";
|
||||
name = "mingw-w64-clang-x86_64-zlib-1.3-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-headers-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
sha256 = "19sgcf61vrs5cpzxskb6g279srsc49mhq4840snf45lrsxfrk6ja";
|
||||
name = "mingw-w64-x86_64-headers-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libiconv-1.17-3-any.pkg.tar.zst";
|
||||
sha256 = "1hxmdgivb86h7wz9hcp0had99ngv157w1fbjg7cgy068zv787m8w";
|
||||
name = "mingw-w64-clang-x86_64-libiconv-1.17-3-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-crt-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
sha256 = "04717li07m2f3q608ir83vqayixw38mkr9sjk2xjhaam5hhl96lq";
|
||||
name = "mingw-w64-x86_64-crt-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-expat-2.5.0-1-any.pkg.tar.zst";
|
||||
sha256 = "1gi9ckh48k64gras307f6pf5y558hj80izlxri8cnwvzzmmra8dg";
|
||||
name = "mingw-w64-clang-x86_64-expat-2.5.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gmp-6.3.0-2-any.pkg.tar.zst";
|
||||
sha256 = "1k0ma22hyn5m2m8kflpmscwm2p1v53pzd93fnind9bf4fhwl6949";
|
||||
name = "mingw-w64-x86_64-gmp-6.3.0-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-gettext-0.22.4-3-any.pkg.tar.zst";
|
||||
sha256 = "0i2gbhzvcy8cq7gnd9zsjw47jmn8gsq5pam5j3yn84jn578f3mfi";
|
||||
name = "mingw-w64-clang-x86_64-gettext-0.22.4-3-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-isl-0.26-1-any.pkg.tar.zst";
|
||||
sha256 = "0hfycibi23xkah9sw60n4ka786l8vmlc67d2waw9mwqqljdmx7pr";
|
||||
name = "mingw-w64-x86_64-isl-0.26-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-xz-5.4.5-1-any.pkg.tar.zst";
|
||||
sha256 = "1niky9s7qq0434ljma3f9m8yybcifkvkxwhk580crzb2ifpmqxc3";
|
||||
name = "mingw-w64-clang-x86_64-xz-5.4.5-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libiconv-1.17-3-any.pkg.tar.zst";
|
||||
sha256 = "061dlpg69ph2205xabshya827m6dqchxxn3jvhnnicja6bsb8ivh";
|
||||
name = "mingw-w64-x86_64-libiconv-1.17-3-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libxml2-2.12.1-1-any.pkg.tar.zst";
|
||||
sha256 = "0lajdhkqv3hrfmnf9wa0ddqpr9z8rvb037rv0ss60g2n0b92s5gk";
|
||||
name = "mingw-w64-clang-x86_64-libxml2-2.12.1-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpfr-4.2.1-2-any.pkg.tar.zst";
|
||||
sha256 = "1j96kipr7mzawngjhi9m0rh2lhylmggg1mkgkipw9ssrsxxf7g97";
|
||||
name = "mingw-w64-x86_64-mpfr-4.2.1-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-zstd-1.5.5-1-any.pkg.tar.zst";
|
||||
sha256 = "07739wmwgxf0d6db4p8w302a6jwcm01aafr1s8jvcl5k1h5a1m2m";
|
||||
name = "mingw-w64-clang-x86_64-zstd-1.5.5-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpc-1.3.1-2-any.pkg.tar.zst";
|
||||
sha256 = "04md7pzz6rwvlsxzgxn8zc6l5lmqn1w2dg9f5xdf13qbl9zfm615";
|
||||
name = "mingw-w64-x86_64-mpc-1.3.1-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-libs-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "13gpp9ah8g4ggzmgsskwcrck16rvjwp464i5vyw9zwm88bdhmz93";
|
||||
name = "mingw-w64-clang-x86_64-llvm-libs-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-windows-default-manifest-6.4-4-any.pkg.tar.zst";
|
||||
sha256 = "1ylipf8k9j7bgmwndkib2l29mds394i7jcij7a6ciag4kynlhsvi";
|
||||
name = "mingw-w64-x86_64-windows-default-manifest-6.4-4-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "103zfg4ypmzhy0gd02arjydca2l4ak2mai3g1xrck83l15v85f9h";
|
||||
name = "mingw-w64-clang-x86_64-llvm-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-winpthreads-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
sha256 = "171blcxd721pp0881blbid8vdbc18fx2lwyzk2prsnjhlf9yampj";
|
||||
name = "mingw-w64-x86_64-winpthreads-git-11.0.0.r198.g93ca95b32-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-compiler-rt-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "0n38jb9gl3zmy7f07bqzpk70k00hdrnasrclhcxgbn4ylzlca07w";
|
||||
name = "mingw-w64-clang-x86_64-compiler-rt-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-zlib-1.3-1-any.pkg.tar.zst";
|
||||
sha256 = "167g32vk257sbfmz85azgjs01cnfkjip0gks6y3vgl97i9d6qji5";
|
||||
name = "mingw-w64-x86_64-zlib-1.3-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-headers-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
sha256 = "1wisa5j86xn8fanx4ks5pkj2hx0k89cippcap6c6yf6d3qmj4mvr";
|
||||
name = "mingw-w64-clang-x86_64-headers-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-13.2.0-2-any.pkg.tar.zst";
|
||||
sha256 = "09v6iz3iyp8w3ynw7wrs2qh54vr2kjpwfbv5rya8dskdx4sp2bvd";
|
||||
name = "mingw-w64-x86_64-gcc-13.2.0-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-crt-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
sha256 = "0x1x3rnxivm58sqjx5v5smnzl5hdinx4qrjgkn59nylcd24fvnk4";
|
||||
name = "mingw-w64-clang-x86_64-crt-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-c-ares-1.19.1-1-any.pkg.tar.zst";
|
||||
sha256 = "0mnkybl3ymxljvg4z5lnww14k29axyxg6ww30mxz6p5i2kqb0vik";
|
||||
name = "mingw-w64-x86_64-c-ares-1.19.1-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-lld-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "1028iymsay6smk856xfyccl7pkcxzigqlrhj4sgz4xxqij7xqnp0";
|
||||
name = "mingw-w64-clang-x86_64-lld-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-brotli-1.1.0-1-any.pkg.tar.zst";
|
||||
sha256 = "1ix63yg59k6wq32xgs64i3i2hqsi9f5qj5qw5apsfr1sgy9zlppm";
|
||||
name = "mingw-w64-x86_64-brotli-1.1.0-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libwinpthread-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
sha256 = "01q7r8mvn60yc0bxlhfbb1rx8w6lbvf1bd0xfaycqmc25b8vnfnp";
|
||||
name = "mingw-w64-clang-x86_64-libwinpthread-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-expat-2.5.0-1-any.pkg.tar.zst";
|
||||
sha256 = "09hrzvdfkr2zaq239z87m1j3zyq0pvjhsyikg65wrbljrir6wc6r";
|
||||
name = "mingw-w64-x86_64-expat-2.5.0-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-winpthreads-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
sha256 = "0f5828injyxhy8vxkv02wmk4fh6x5gsqnkr97p50vz692fxkwk48";
|
||||
name = "mingw-w64-clang-x86_64-winpthreads-git-11.0.0.r404.g3a137bd87-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gettext-0.21.1-2-any.pkg.tar.zst";
|
||||
sha256 = "0gj9qgxph9qw1x3y9ijacxi4ia90vzgkmg5jvl99pdq55h3xxl9x";
|
||||
name = "mingw-w64-x86_64-gettext-0.21.1-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-clang-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "1adfijlky02waz6gm2rx32rd413ws5rphkpybihpc8hi11yag761";
|
||||
name = "mingw-w64-clang-x86_64-clang-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libunistring-1.1-1-any.pkg.tar.zst";
|
||||
sha256 = "1zpmarlb2j0q2hcv30xl6c0mm3pwdjp7fh9mqpb6y0yygj1ivcza";
|
||||
name = "mingw-w64-x86_64-libunistring-1.1-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-c-ares-1.22.1-1-any.pkg.tar.zst";
|
||||
sha256 = "0bv8n3862krxhlmz0lxqq71y40dy4flpjvb7adl5a96jixgsbxav";
|
||||
name = "mingw-w64-clang-x86_64-c-ares-1.22.1-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libidn2-2.3.4-1-any.pkg.tar.zst";
|
||||
sha256 = "0z926vsxz61m5zxdarah3zc4n253ksykxvb72qg86kcxcl3z0ppc";
|
||||
name = "mingw-w64-x86_64-libidn2-2.3.4-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-brotli-1.1.0-1-any.pkg.tar.zst";
|
||||
sha256 = "113mha41q53cx0hw13cq1xdf7zbsd58sh8cl1cd7xzg1q69n60w2";
|
||||
name = "mingw-w64-clang-x86_64-brotli-1.1.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libpsl-0.21.2-4-any.pkg.tar.zst";
|
||||
sha256 = "0scpar3qp91y920c065y7jcvzfpmxx5vva9ybgxkk4df8a8mrbs9";
|
||||
name = "mingw-w64-x86_64-libpsl-0.21.2-4-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libunistring-1.1-1-any.pkg.tar.zst";
|
||||
sha256 = "16myvbg33q5s7jl30w5qd8n8f1r05335ms8r61234vn52n32l2c4";
|
||||
name = "mingw-w64-clang-x86_64-libunistring-1.1-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libtasn1-4.19.0-1-any.pkg.tar.zst";
|
||||
sha256 = "09bgm2y25jyjm0pwn2imnr30nxzdd7j71ifmxkpabaqkpsfa5av5";
|
||||
name = "mingw-w64-x86_64-libtasn1-4.19.0-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libidn2-2.3.4-1-any.pkg.tar.zst";
|
||||
sha256 = "105valrldri39sx7d5zdscxgsz9px382f8vbbl2zpr2xzb3jq8p8";
|
||||
name = "mingw-w64-clang-x86_64-libidn2-2.3.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libffi-3.4.4-1-any.pkg.tar.zst";
|
||||
sha256 = "1na3giynh9f3i0xg2mr0dm4bm6zhv8h908rrrv4kcxfawr8nyjdy";
|
||||
name = "mingw-w64-x86_64-libffi-3.4.4-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libpsl-0.21.2-4-any.pkg.tar.zst";
|
||||
sha256 = "0h4inq6prhiipl3h5k9br9rz5mih123b8n12wiwp2qck0h2q3x98";
|
||||
name = "mingw-w64-clang-x86_64-libpsl-0.21.2-4-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-p11-kit-0.25.0-2-any.pkg.tar.zst";
|
||||
sha256 = "0j6w4hijyclv2av8wxldqdznyyycsmx00kshbs8kpk2wd5gz1scs";
|
||||
name = "mingw-w64-x86_64-p11-kit-0.25.0-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libtasn1-4.19.0-1-any.pkg.tar.zst";
|
||||
sha256 = "19m59mjxww26ah2gk9c0i512fmqpyaj6r5na564kmg6wpwvkihcj";
|
||||
name = "mingw-w64-clang-x86_64-libtasn1-4.19.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ca-certificates-20230311-1-any.pkg.tar.zst";
|
||||
sha256 = "1rcxxlpmvian8c2d9bmnx5hldzvzz4wybz5wp9pjryps1rmzylyx";
|
||||
name = "mingw-w64-x86_64-ca-certificates-20230311-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-p11-kit-0.25.3-1-any.pkg.tar.zst";
|
||||
sha256 = "19330k2jxpzm552m7j116hz8qrn2d14h9ybi0lcmkj4c1l25m6mf";
|
||||
name = "mingw-w64-clang-x86_64-p11-kit-0.25.3-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-openssl-3.1.3-1-any.pkg.tar.zst";
|
||||
sha256 = "1vi1zxb5lvgxpmk80giqahqrjh2lv06r2ah4hf55jzjsi1mmcard";
|
||||
name = "mingw-w64-x86_64-openssl-3.1.3-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-ca-certificates-20230311-1-any.pkg.tar.zst";
|
||||
sha256 = "00hdl239695xi5bgld7a1ssp6kapkb9az02dpx80vmz7mqg6wwxx";
|
||||
name = "mingw-w64-clang-x86_64-ca-certificates-20230311-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libssh2-1.11.0-2-any.pkg.tar.zst";
|
||||
sha256 = "0h4hfsig3n7grp7hn7vn16af6x122hc220llpmd8aii3d3jwc8d1";
|
||||
name = "mingw-w64-x86_64-libssh2-1.11.0-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-openssl-3.2.0-1-any.pkg.tar.zst";
|
||||
sha256 = "1623bkf4bjwf4cs1j5f6c37gwj4z775kjk4jswwy58r61yimwnd5";
|
||||
name = "mingw-w64-clang-x86_64-openssl-3.2.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-nghttp2-1.56.0-1-any.pkg.tar.zst";
|
||||
sha256 = "1jxn8g0w5qlkfb30bllwsm8vjfnk5952x8z8rq3wbawdncwsgvmk";
|
||||
name = "mingw-w64-x86_64-nghttp2-1.56.0-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libssh2-1.11.0-2-any.pkg.tar.zst";
|
||||
sha256 = "0l2m823gm1rvnjmqm5ads17mxz1bhpzai5ixyhnkpzrsjxd1ygy5";
|
||||
name = "mingw-w64-clang-x86_64-libssh2-1.11.0-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-curl-8.3.0-1-any.pkg.tar.zst";
|
||||
sha256 = "03gkb36fp079gd2hi980qk1k2baly17ca457ah1gjcmc6p56jx6d";
|
||||
name = "mingw-w64-x86_64-curl-8.3.0-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-nghttp2-1.58.0-1-any.pkg.tar.zst";
|
||||
sha256 = "00f7raqmky43v9h2356yzfbvbhkbsjpc17n6ksgpv66h31svna6q";
|
||||
name = "mingw-w64-clang-x86_64-nghttp2-1.58.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-xz-5.4.4-1-any.pkg.tar.zst";
|
||||
sha256 = "0drcmy0x3dydl19slxv64aw8f29a1kxyzx7zj25nnr47qg1w5ycp";
|
||||
name = "mingw-w64-x86_64-xz-5.4.4-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-curl-8.4.0-2-any.pkg.tar.zst";
|
||||
sha256 = "1qi446lq1qqq45xn7fmasfb914jhahqc0cvpnqi8vrp9vlk9dsw3";
|
||||
name = "mingw-w64-clang-x86_64-curl-8.4.0-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libxml2-2.11.5-1-any.pkg.tar.zst";
|
||||
sha256 = "0z1nynr2ip1js3p8rlj5da1sfrm1071s6cn22qwpzk3j6zfjzanv";
|
||||
name = "mingw-w64-x86_64-libxml2-2.11.5-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-rust-1.74.0-1-any.pkg.tar.zst";
|
||||
sha256 = "071xpmfsnr7j7ycf6w8kyg41fxs3dclnjrcp7grinck5bb5zxn6s";
|
||||
name = "mingw-w64-clang-x86_64-rust-1.74.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-rust-1.72.1-1-any.pkg.tar.zst";
|
||||
sha256 = "0dq01ah76ra5y64kp1xwjhy5rsv7fxh1hnfjzr6l3x26d1hjwgsi";
|
||||
name = "mingw-w64-x86_64-rust-1.72.1-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-pkgconf-1~2.1.0-1-any.pkg.tar.zst";
|
||||
sha256 = "04y364mzx2sj984cdxq187fg73hzkrzvbpsr5d86xfzrag789nh3";
|
||||
name = "mingw-w64-clang-x86_64-pkgconf-12.1.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-pkgconf-1~2.0.3-2-any.pkg.tar.zst";
|
||||
sha256 = "0wkgwk57d6kyljjs0zvlrjp7k87s9b061cvzy0b8iy7r8wql31py";
|
||||
name = "mingw-w64-x86_64-pkgconf-12.0.3-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-jsoncpp-1.9.5-2-any.pkg.tar.zst";
|
||||
sha256 = "0cpy76crngj5dfg9f4l216ry0wcavp0nabyc0b9g676rg6400qas";
|
||||
name = "mingw-w64-clang-x86_64-jsoncpp-1.9.5-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-jsoncpp-1.9.5-2-any.pkg.tar.zst";
|
||||
sha256 = "0wjf5cycjxwbaxvk4xmzhj4hnpl1mq6ddqj5lcbdcrvsc13nj8ll";
|
||||
name = "mingw-w64-x86_64-jsoncpp-1.9.5-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-bzip2-1.0.8-3-any.pkg.tar.zst";
|
||||
sha256 = "1n8zf2kk1xj7wiszp6mjchy1yzpalddbj0cj17qm625ags2vzflm";
|
||||
name = "mingw-w64-clang-x86_64-bzip2-1.0.8-3-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-bzip2-1.0.8-3-any.pkg.tar.zst";
|
||||
sha256 = "1dki26kz4pmr9q3gp3dirrvrwkcv38b9sjrb9slrq4yw31ycjgk5";
|
||||
name = "mingw-w64-x86_64-bzip2-1.0.8-3-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libb2-0.98.1-2-any.pkg.tar.zst";
|
||||
sha256 = "0555dvb2xs6695sz5ndrx6y0cz3qa5cg0m5v8q1md13ssg76vlh6";
|
||||
name = "mingw-w64-clang-x86_64-libb2-0.98.1-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libb2-0.98.1-2-any.pkg.tar.zst";
|
||||
sha256 = "1nj669rn1i6fxrwmsqmr9n49p34wxvhn0xlsn9spr6aq1hz73b41";
|
||||
name = "mingw-w64-x86_64-libb2-0.98.1-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-lz4-1.9.4-1-any.pkg.tar.zst";
|
||||
sha256 = "0nn7cy25j53q5ckkx4n4f77w00xdwwf5wjswm374shvvs58nlln0";
|
||||
name = "mingw-w64-clang-x86_64-lz4-1.9.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lz4-1.9.4-1-any.pkg.tar.zst";
|
||||
sha256 = "1mwyd94pwp1j3pgaa7j2i37d1xid1ynr0a42fl2pxgfmcj6hmqfi";
|
||||
name = "mingw-w64-x86_64-lz4-1.9.4-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libtre-git-r128.6fb7206-2-any.pkg.tar.zst";
|
||||
sha256 = "0bmdla75k0q88l93ql9ajbfag4vhdhyp0glzymljvcc7ir0r6f9r";
|
||||
name = "mingw-w64-clang-x86_64-libtre-git-r128.6fb7206-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libtre-git-r128.6fb7206-2-any.pkg.tar.xz";
|
||||
sha256 = "0dp3ca83j8jlx32gml2qvqpwp5b42q8r98gf6hyiki45d910wb7x";
|
||||
name = "mingw-w64-x86_64-libtre-git-r128.6fb7206-2-any.pkg.tar.xz";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libsystre-1.0.1-4-any.pkg.tar.zst";
|
||||
sha256 = "0x5ns8ld08gd9r5a98sqi3sm0vz588caaqw10ciix16sgyisfpdh";
|
||||
name = "mingw-w64-clang-x86_64-libsystre-1.0.1-4-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libsystre-1.0.1-4-any.pkg.tar.xz";
|
||||
sha256 = "037gkzaaj8kp5nspcbc8ll64s9b3mj8d6m663lk1za94bq2axff1";
|
||||
name = "mingw-w64-x86_64-libsystre-1.0.1-4-any.pkg.tar.xz";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libarchive-3.7.2-1-any.pkg.tar.zst";
|
||||
sha256 = "1p84yh6yzkdpmr02vyvgz16x5gycckah25jkdc2py09l7iw96bmw";
|
||||
name = "mingw-w64-clang-x86_64-libarchive-3.7.2-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libarchive-3.7.2-1-any.pkg.tar.zst";
|
||||
sha256 = "0p302zs5jgbbrv368yyjvbjmj4bmc1qxb0dp7s4wwafwnjqfm3vw";
|
||||
name = "mingw-w64-x86_64-libarchive-3.7.2-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libuv-1.47.0-1-any.pkg.tar.zst";
|
||||
sha256 = "1ch8g0mp13dmwi7sc6qxjcx18s1w0bsdl5lhkjmx5ccz55sspnyf";
|
||||
name = "mingw-w64-clang-x86_64-libuv-1.47.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libuv-1.46.0-1-any.pkg.tar.zst";
|
||||
sha256 = "1pasn07awq2mrqzsf1162aa5xlq81745mxkzir0z7cx6smrfqiwb";
|
||||
name = "mingw-w64-x86_64-libuv-1.46.0-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-ninja-1.11.1-3-any.pkg.tar.zst";
|
||||
sha256 = "13wjfmyfr952n3ydpldjlwx1nla5xpyvr96ng8pfbyw4z900v5ms";
|
||||
name = "mingw-w64-clang-x86_64-ninja-1.11.1-3-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ninja-1.11.1-3-any.pkg.tar.zst";
|
||||
sha256 = "0494d54qxax9d2gz11vhm7342311k4s6mf6zy5yq2ka07qfzckcg";
|
||||
name = "mingw-w64-x86_64-ninja-1.11.1-3-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-rhash-1.4.3-1-any.pkg.tar.zst";
|
||||
sha256 = "16ghg6894gb3lcrcpc8g1jd7524djnsjrqcr3krqlzskfv51hgj6";
|
||||
name = "mingw-w64-clang-x86_64-rhash-1.4.3-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-rhash-1.4.3-1-any.pkg.tar.zst";
|
||||
sha256 = "1nd0iqlx1vmn079i24i07r4kqfr3yr0apnzsgcx8qd5cyvwnl7w6";
|
||||
name = "mingw-w64-x86_64-rhash-1.4.3-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-cmake-3.27.8-1-any.pkg.tar.zst";
|
||||
sha256 = "1hm5975q0kfd0z502qpxq1imwvby3qb93jzhbvrg2fz9zf5d31rg";
|
||||
name = "mingw-w64-clang-x86_64-cmake-3.27.8-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-cmake-3.27.6-1-any.pkg.tar.zst";
|
||||
sha256 = "0vhnij28yk7i068b65m1gsmswz0r8nl3vzvx3c9n3cncv6h6m5hs";
|
||||
name = "mingw-w64-x86_64-cmake-3.27.6-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-mpdecimal-2.5.1-1-any.pkg.tar.zst";
|
||||
sha256 = "0zm9pqcgjk9a8ql6hxcxh477wvvyimndcisd6zrr6y8m5vvklsdi";
|
||||
name = "mingw-w64-clang-x86_64-mpdecimal-2.5.1-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpdecimal-2.5.1-1-any.pkg.tar.zst";
|
||||
sha256 = "0cpyacmciyzbsar1aka5y592g2gpa4i6a58j3bjdmfjdnpm0j08a";
|
||||
name = "mingw-w64-x86_64-mpdecimal-2.5.1-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-ncurses-6.4.20230708-1-any.pkg.tar.zst";
|
||||
sha256 = "0l960cf4m558kx6dwahl9z2zdb9vlqd7qgk39kg924mzrfjrsvv5";
|
||||
name = "mingw-w64-clang-x86_64-ncurses-6.4.20230708-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ncurses-6.4.20230708-1-any.pkg.tar.zst";
|
||||
sha256 = "1bpjn6rv85q3rdcdgs7fml140aar93hv649hhqx47za26mjnsdiv";
|
||||
name = "mingw-w64-x86_64-ncurses-6.4.20230708-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-termcap-1.3.1-7-any.pkg.tar.zst";
|
||||
sha256 = "17ha468qavwin800cc3b7c3xdggwk2gakasfxg7jdx7616d99l0n";
|
||||
name = "mingw-w64-clang-x86_64-termcap-1.3.1-7-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-termcap-1.3.1-7-any.pkg.tar.zst";
|
||||
sha256 = "1s51i2fwy1mrzmxsgr1vv87wlmb3bk88yipqalfldvy3xdgjgjh4";
|
||||
name = "mingw-w64-x86_64-termcap-1.3.1-7-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-readline-8.2.001-6-any.pkg.tar.zst";
|
||||
sha256 = "1aw1qxjvifkzxnn52l6hba1kcj2dci8llzzj29zbvbq5hgllf6dv";
|
||||
name = "mingw-w64-clang-x86_64-readline-8.2.001-6-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-readline-8.2.001-6-any.pkg.tar.zst";
|
||||
sha256 = "0a6s6kq2hmz96cg7hxzcgldh16sk7dvpzfdfqchq3c07rwzhqhiq";
|
||||
name = "mingw-w64-x86_64-readline-8.2.001-6-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-tcl-8.6.12-2-any.pkg.tar.zst";
|
||||
sha256 = "06r7ni7m1vf83ms8ha3glalc5rfriiffh7v644jmnvzs5g9x0pzb";
|
||||
name = "mingw-w64-clang-x86_64-tcl-8.6.12-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-tcl-8.6.12-2-any.pkg.tar.zst";
|
||||
sha256 = "17lyrkyh76lh0ghk19d91kwicms6lxshhhb6n3zh748awfvihknm";
|
||||
name = "mingw-w64-x86_64-tcl-8.6.12-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-sqlite3-3.44.0-1-any.pkg.tar.zst";
|
||||
sha256 = "022vy54ph6kxmgafbsmgpclvd55ljarvc4k7497ka03g7465zq6j";
|
||||
name = "mingw-w64-clang-x86_64-sqlite3-3.44.0-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-sqlite3-3.43.1-1-any.pkg.tar.zst";
|
||||
sha256 = "05csh3sa6g5nnfmry50w6p2j4v7fqylmlgnny5cimm350ppmmkka";
|
||||
name = "mingw-w64-x86_64-sqlite3-3.43.1-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-tk-8.6.12-2-any.pkg.tar.zst";
|
||||
sha256 = "0pi74q91vl6vw8vvmmwnvrgai3b1aanp0zhca5qsmv8ljh2wdgzx";
|
||||
name = "mingw-w64-clang-x86_64-tk-8.6.12-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-tk-8.6.12-2-any.pkg.tar.zst";
|
||||
sha256 = "0j6nvwc0a1cc2k4akq3095r1rfhprslf8jpr07ypcjb91q5s3yfi";
|
||||
name = "mingw-w64-x86_64-tk-8.6.12-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-tzdata-2023c-1-any.pkg.tar.zst";
|
||||
sha256 = "018qw8lk5r7gqvavnl1414gmbd4bx22528a7bjk4injfr3cib9c2";
|
||||
name = "mingw-w64-clang-x86_64-tzdata-2023c-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-tzdata-2023c-1-any.pkg.tar.zst";
|
||||
sha256 = "0ifavpqi1ykn9962ic4sh5l18y2mvz9pj6742fgw85s9wixbj7fl";
|
||||
name = "mingw-w64-x86_64-tzdata-2023c-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-3.11.6-2-any.pkg.tar.zst";
|
||||
sha256 = "0j6wkjjay52f4mgvfagi7xql4v74dizhmwdx07n2fixr7j1lg6n7";
|
||||
name = "mingw-w64-clang-x86_64-python-3.11.6-2-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.11.6-1-any.pkg.tar.zst";
|
||||
sha256 = "0s4z65i3p0arwjry877q9q154h58b3wd35svifpj2c1j7frr41vi";
|
||||
name = "mingw-w64-x86_64-python-3.11.6-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-openmp-17.0.4-1-any.pkg.tar.zst";
|
||||
sha256 = "1y2cf43fcyb1qv4kn0h0mzljmibaqklcj167krwxq5ymfbipy1yw";
|
||||
name = "mingw-w64-clang-x86_64-openmp-17.0.4-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libgfortran-13.2.0-2-any.pkg.tar.zst";
|
||||
sha256 = "150k73v8g71wrp855f747mal009cf34lbpv8xzbibj50m3g6yxvv";
|
||||
name = "mingw-w64-x86_64-gcc-libgfortran-13.2.0-2-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-openblas-0.3.25-1-any.pkg.tar.zst";
|
||||
sha256 = "1789hd7sc249vbzppqqg56i080c8kc6bj6qngn9rjvzcdllh0d07";
|
||||
name = "mingw-w64-clang-x86_64-openblas-0.3.25-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-openblas-0.3.24-1-any.pkg.tar.zst";
|
||||
sha256 = "0j2aka8bml2j2aszxsjy5gp8xqvdxw3s292pd7iarzn1kliwv84j";
|
||||
name = "mingw-w64-x86_64-openblas-0.3.24-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-numpy-1.26.2-1-any.pkg.tar.zst";
|
||||
sha256 = "1njbxlxha05c8fzm7yl3ksjlpanh5jxn1z1s06iv9knx2zmqjk6f";
|
||||
name = "mingw-w64-clang-x86_64-python-numpy-1.26.2-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-numpy-1.25.2-1-any.pkg.tar.zst";
|
||||
sha256 = "0vjb2qps0kzzcjhjrh11h661i9q1hmzi08jvirqyslayp3jmbkd9";
|
||||
name = "mingw-w64-x86_64-python-numpy-1.25.2-1-any.pkg.tar.zst";
|
||||
})
|
||||
|
||||
(pkgs.fetchurl {
|
||||
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-setuptools-68.2.2-1-any.pkg.tar.zst";
|
||||
sha256 = "0hci3vran7cw4hnr17b04xcpwl322ffvxf9sgv3793rpx7fx5h7a";
|
||||
name = "mingw-w64-x86_64-python-setuptools-68.2.2-1-any.pkg.tar.zst";
|
||||
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-setuptools-68.2.2-1-any.pkg.tar.zst";
|
||||
sha256 = "16m1ph7yq3mqzaaaka5vij27jzaw59lpxwbmpdxkcp8lb6h5xcn9";
|
||||
name = "mingw-w64-clang-x86_64-python-setuptools-68.2.2-1-any.pkg.tar.zst";
|
||||
})
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue