Compare commits
No commits in common. "master" and "issue40" have entirely different histories.
@ -1,2 +0,0 @@
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
168
Cargo.lock
generated
168
Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom 0.2.15",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
@ -127,9 +127,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.10"
|
||||
version = "1.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
|
||||
checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
@ -142,9 +142,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.27"
|
||||
version = "4.5.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
|
||||
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@ -152,9 +152,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.27"
|
||||
version = "4.5.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
|
||||
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@ -200,9 +200,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -334,15 +334,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.5.7"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
@ -380,19 +374,7 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.13.3+wasi-0.2.2",
|
||||
"windows-targets",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -407,14 +389,20 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
@ -449,9 +437,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.7.1"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
||||
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
@ -510,9 +498,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
@ -534,9 +522,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.22.1"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7047a26de42016abf8f181b46b398aef0b77ad46711df41847f6ed869a2a1d5b"
|
||||
checksum = "06093b57658c723a21da679530e061a8c25340fa5a6f98e313b542268c7e2a1f"
|
||||
dependencies = [
|
||||
"ascii-canvas",
|
||||
"bit-set",
|
||||
@ -556,9 +544,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop-util"
|
||||
version = "0.22.1"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8d05b3fe34b8bd562c338db725dfa9beb9451a48f65f129ccb9538b48d2c93b"
|
||||
checksum = "feee752d43abd0f4807a921958ab4131f692a44d4d599733d4419c5d586176ce"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
"rustversion",
|
||||
@ -668,7 +656,7 @@ name = "nac3core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.7.0",
|
||||
"indoc",
|
||||
"inkwell",
|
||||
"insta",
|
||||
@ -676,6 +664,7 @@ dependencies = [
|
||||
"nac3core_derive",
|
||||
"nac3parser",
|
||||
"parking_lot",
|
||||
"rayon",
|
||||
"regex",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
@ -763,12 +752,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.7.1"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
|
||||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -991,7 +980,27 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1041,9 +1050,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
version = "0.38.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
@ -1060,9 +1069,9 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.19"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@ -1081,9 +1090,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.25"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
|
||||
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
@ -1107,9 +1116,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.137"
|
||||
version = "1.0.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
|
||||
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
@ -1156,9 +1165,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.7.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
||||
checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
@ -1180,11 +1189,12 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "string-interner"
|
||||
version = "0.18.0"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a3275464d7a9f2d4cac57c89c2ef96a8524dba2864c8d6f82e3980baf136f9b"
|
||||
checksum = "1c6a0d765f5807e98a091107bae0a56ea3799f66a5de47b2c84c94a39c09974e"
|
||||
dependencies = [
|
||||
"hashbrown 0.15.2",
|
||||
"cfg-if",
|
||||
"hashbrown 0.14.5",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -1262,13 +1272,13 @@ checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.16.0"
|
||||
version = "3.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
|
||||
checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"getrandom 0.3.1",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
@ -1353,7 +1363,7 @@ version = "0.22.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.7.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@ -1362,9 +1372,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "trybuild"
|
||||
version = "1.0.103"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b812699e0c4f813b872b373a4471717d9eb550da14b311058a4d9cf4173cbca6"
|
||||
checksum = "8dcd332a5496c026f1e14b7f3d2b7bd98e509660c04239c58b0ba38a12daded4"
|
||||
dependencies = [
|
||||
"dissimilar",
|
||||
"glob",
|
||||
@ -1436,9 +1446,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
@ -1508,15 +1518,6 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.13.3+wasi-0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
@ -1610,22 +1611,13 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.25"
|
||||
version = "0.6.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310"
|
||||
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
|
6
flake.lock
generated
6
flake.lock
generated
@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1738680400,
|
||||
"narHash": "sha256-ooLh+XW8jfa+91F1nhf9OF7qhuA/y1ChLx6lXDNeY5U=",
|
||||
"lastModified": 1736798957,
|
||||
"narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "799ba5bffed04ced7067a91798353d360788b30d",
|
||||
"rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -41,7 +41,7 @@
|
||||
lockFile = ./Cargo.lock;
|
||||
};
|
||||
passthru.cargoLock = cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 (pkgs.wrapClangMulti pkgs.llvmPackages_14.clang) llvm-tools-irrt pkgs.llvmPackages_14.llvm.out pkgs.llvmPackages_14.bintools llvm-nac3 ];
|
||||
nativeBuildInputs = [ pkgs.python3 (pkgs.wrapClangMulti 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 =
|
||||
@ -85,7 +85,7 @@
|
||||
name = "nac3artiq-instrumented";
|
||||
src = self;
|
||||
inherit (nac3artiq) cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt pkgs.llvmPackages_14.bintools 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;
|
||||
@ -120,7 +120,6 @@
|
||||
buildInputs = [
|
||||
(python3-mimalloc.withPackages(ps: [ ps.numpy ps.scipy ps.jsonschema ps.lmdb ps.platformdirs nac3artiq-instrumented ]))
|
||||
pkgs.llvmPackages_14.llvm.out
|
||||
pkgs.llvmPackages_14.bintools
|
||||
];
|
||||
phases = [ "buildPhase" "installPhase" ];
|
||||
buildPhase =
|
||||
@ -148,7 +147,7 @@
|
||||
name = "nac3artiq-pgo";
|
||||
src = self;
|
||||
inherit (nac3artiq) cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt pkgs.llvmPackages_14.bintools 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" ];
|
||||
@ -169,7 +168,7 @@
|
||||
buildInputs = with pkgs; [
|
||||
# build dependencies
|
||||
packages.x86_64-linux.llvm-nac3
|
||||
(pkgs.wrapClangMulti llvmPackages_14.clang) llvmPackages_14.llvm.out llvmPackages_14.bintools # for running nac3standalone demos
|
||||
(pkgs.wrapClangMulti llvmPackages_14.clang) llvmPackages_14.llvm.out # for running nac3standalone demos
|
||||
packages.x86_64-linux.llvm-tools-irrt
|
||||
cargo
|
||||
rustc
|
||||
|
@ -9,10 +9,10 @@ name = "nac3artiq"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.14"
|
||||
itertools = "0.13"
|
||||
pyo3 = { version = "0.21", features = ["extension-module", "gil-refs"] }
|
||||
parking_lot = "0.12"
|
||||
tempfile = "3.16"
|
||||
tempfile = "3.13"
|
||||
nac3core = { path = "../nac3core" }
|
||||
nac3ld = { path = "../nac3ld" }
|
||||
|
||||
|
39
nac3artiq/demo/embedding_map.py
Normal file
39
nac3artiq/demo/embedding_map.py
Normal file
@ -0,0 +1,39 @@
|
||||
class EmbeddingMap:
|
||||
def __init__(self):
|
||||
self.object_inverse_map = {}
|
||||
self.object_map = {}
|
||||
self.string_map = {}
|
||||
self.string_reverse_map = {}
|
||||
self.function_map = {}
|
||||
self.attributes_writeback = []
|
||||
|
||||
def store_function(self, key, fun):
|
||||
self.function_map[key] = fun
|
||||
return key
|
||||
|
||||
def store_object(self, obj):
|
||||
obj_id = id(obj)
|
||||
if obj_id in self.object_inverse_map:
|
||||
return self.object_inverse_map[obj_id]
|
||||
key = len(self.object_map) + 1
|
||||
self.object_map[key] = obj
|
||||
self.object_inverse_map[obj_id] = key
|
||||
return key
|
||||
|
||||
def store_str(self, s):
|
||||
if s in self.string_reverse_map:
|
||||
return self.string_reverse_map[s]
|
||||
key = len(self.string_map)
|
||||
self.string_map[key] = s
|
||||
self.string_reverse_map[s] = key
|
||||
return key
|
||||
|
||||
def retrieve_function(self, key):
|
||||
return self.function_map[key]
|
||||
|
||||
def retrieve_object(self, key):
|
||||
return self.object_map[key]
|
||||
|
||||
def retrieve_str(self, key):
|
||||
return self.string_map[key]
|
||||
|
@ -6,6 +6,7 @@ from typing import Generic, TypeVar
|
||||
from math import floor, ceil
|
||||
|
||||
import nac3artiq
|
||||
from embedding_map import EmbeddingMap
|
||||
|
||||
|
||||
__all__ = [
|
||||
@ -192,46 +193,6 @@ def print_int64(x: int64):
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
class EmbeddingMap:
|
||||
def __init__(self):
|
||||
self.object_inverse_map = {}
|
||||
self.object_map = {}
|
||||
self.string_map = {}
|
||||
self.string_reverse_map = {}
|
||||
self.function_map = {}
|
||||
self.attributes_writeback = []
|
||||
|
||||
def store_function(self, key, fun):
|
||||
self.function_map[key] = fun
|
||||
return key
|
||||
|
||||
def store_object(self, obj):
|
||||
obj_id = id(obj)
|
||||
if obj_id in self.object_inverse_map:
|
||||
return self.object_inverse_map[obj_id]
|
||||
key = len(self.object_map) + 1
|
||||
self.object_map[key] = obj
|
||||
self.object_inverse_map[obj_id] = key
|
||||
return key
|
||||
|
||||
def store_str(self, s):
|
||||
if s in self.string_reverse_map:
|
||||
return self.string_reverse_map[s]
|
||||
key = len(self.string_map)
|
||||
self.string_map[key] = s
|
||||
self.string_reverse_map[s] = key
|
||||
return key
|
||||
|
||||
def retrieve_function(self, key):
|
||||
return self.function_map[key]
|
||||
|
||||
def retrieve_object(self, key):
|
||||
return self.object_map[key]
|
||||
|
||||
def retrieve_str(self, key):
|
||||
return self.string_map[key]
|
||||
|
||||
|
||||
@nac3
|
||||
class Core:
|
||||
ref_period: KernelInvariant[float]
|
||||
|
@ -1,26 +0,0 @@
|
||||
from min_artiq import *
|
||||
from numpy import int32
|
||||
|
||||
# Global Variable Definition
|
||||
X: Kernel[int32] = 1
|
||||
|
||||
# TopLevelFunction Defintion
|
||||
@kernel
|
||||
def display_X():
|
||||
print_int32(X)
|
||||
|
||||
# TopLevel Class Definition
|
||||
@nac3
|
||||
class A:
|
||||
@kernel
|
||||
def __init__(self):
|
||||
self.set_x(1)
|
||||
|
||||
@kernel
|
||||
def set_x(self, new_val: int32):
|
||||
global X
|
||||
X = new_val
|
||||
|
||||
@kernel
|
||||
def get_X(self) -> int32:
|
||||
return X
|
@ -1,5 +1,7 @@
|
||||
from min_artiq import *
|
||||
import module as module_definition
|
||||
import tests.string_attribute_issue337 as issue337
|
||||
import tests.support_class_attr_issue102 as issue102
|
||||
import tests.global_variables as global_variables
|
||||
|
||||
@nac3
|
||||
class TestModuleSupport:
|
||||
@ -11,16 +13,17 @@ class TestModuleSupport:
|
||||
@kernel
|
||||
def run(self):
|
||||
# Accessing classes
|
||||
obj = module_definition.A()
|
||||
obj.get_X()
|
||||
obj.set_x(2)
|
||||
issue337.Demo().run()
|
||||
obj = issue102.Demo()
|
||||
obj.attr3 = 3
|
||||
|
||||
# Calling functions
|
||||
module_definition.display_X()
|
||||
global_variables.inc_X()
|
||||
global_variables.display_X()
|
||||
|
||||
# Updating global variables
|
||||
module_definition.X = 9
|
||||
module_definition.display_X()
|
||||
global_variables.X = 9
|
||||
global_variables.display_X()
|
||||
|
||||
if __name__ == "__main__":
|
||||
TestModuleSupport().run()
|
14
nac3artiq/demo/tests/global_variables.py
Normal file
14
nac3artiq/demo/tests/global_variables.py
Normal file
@ -0,0 +1,14 @@
|
||||
from min_artiq import *
|
||||
from numpy import int32
|
||||
|
||||
X: Kernel[int32] = 1
|
||||
|
||||
@rpc
|
||||
def display_X():
|
||||
print_int32(X)
|
||||
|
||||
@kernel
|
||||
def inc_X():
|
||||
global X
|
||||
X += 1
|
||||
|
18
nac3artiq/demo/tests/string_attribute_issue337.py
Normal file
18
nac3artiq/demo/tests/string_attribute_issue337.py
Normal file
@ -0,0 +1,18 @@
|
||||
from min_artiq import *
|
||||
from numpy import int32
|
||||
|
||||
@nac3
|
||||
class Demo:
|
||||
attr1: Kernel[str]
|
||||
attr2: Kernel[int32]
|
||||
|
||||
@kernel
|
||||
def __init__(self):
|
||||
self.attr2 = 32
|
||||
self.attr1 = "SAMPLE"
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
print_int32(self.attr2)
|
||||
self.attr1
|
||||
|
37
nac3artiq/demo/tests/support_class_attr_issue102.py
Normal file
37
nac3artiq/demo/tests/support_class_attr_issue102.py
Normal file
@ -0,0 +1,37 @@
|
||||
from min_artiq import *
|
||||
from numpy import int32
|
||||
|
||||
@nac3
|
||||
class Demo:
|
||||
attr1: KernelInvariant[int32] = 2
|
||||
attr2: int32 = 4
|
||||
attr3: Kernel[int32]
|
||||
|
||||
@kernel
|
||||
def __init__(self):
|
||||
self.attr3 = 8
|
||||
|
||||
@nac3
|
||||
class NAC3Devices:
|
||||
core: KernelInvariant[Core]
|
||||
attr4: KernelInvariant[int32] = 16
|
||||
|
||||
def __init__(self):
|
||||
self.core = Core()
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
Demo.attr1 # Supported
|
||||
# Demo.attr2 # Field not accessible on Kernel
|
||||
# Demo.attr3 # Only attributes can be accessed in this way
|
||||
# Demo.attr1 = 2 # Attributes are immutable
|
||||
|
||||
self.attr4 # Attributes can be accessed within class
|
||||
|
||||
obj = Demo()
|
||||
obj.attr1 # Attributes can be accessed by class objects
|
||||
|
||||
NAC3Devices.attr4 # Attributes accessible for classes without __init__
|
||||
|
||||
if __name__ == "__main__":
|
||||
NAC3Devices().run()
|
@ -19,9 +19,9 @@ use nac3core::{
|
||||
llvm_intrinsics::{call_int_smax, call_memcpy, call_stackrestore, call_stacksave},
|
||||
stmt::{gen_block, gen_for_callback_incrementing, gen_if_callback, gen_with},
|
||||
type_aligned_alloca,
|
||||
types::{ndarray::NDArrayType, RangeType},
|
||||
types::ndarray::NDArrayType,
|
||||
values::{
|
||||
ArrayLikeIndexer, ArrayLikeValue, ArraySliceValue, ListValue, ProxyValue,
|
||||
ArrayLikeIndexer, ArrayLikeValue, ArraySliceValue, ListValue, ProxyValue, RangeValue,
|
||||
UntypedArrayLikeAccessor,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
@ -476,8 +476,8 @@ fn format_rpc_arg<'ctx>(
|
||||
let (elem_ty, ndims) = unpack_ndarray_var_tys(&mut ctx.unifier, arg_ty);
|
||||
let ndims = extract_ndims(&ctx.unifier, ndims);
|
||||
let dtype = ctx.get_llvm_type(generator, elem_ty);
|
||||
let ndarray = NDArrayType::new(ctx, dtype, ndims)
|
||||
.map_pointer_value(arg.into_pointer_value(), None);
|
||||
let ndarray =
|
||||
NDArrayType::new(ctx, dtype, ndims).map_value(arg.into_pointer_value(), None);
|
||||
|
||||
let ndims = llvm_usize.const_int(ndims, false);
|
||||
|
||||
@ -761,7 +761,7 @@ fn format_rpc_ret<'ctx>(
|
||||
ctx.builder.build_unconditional_branch(head_bb).unwrap();
|
||||
|
||||
ctx.builder.position_at_end(tail_bb);
|
||||
ndarray.as_abi_value(ctx).into()
|
||||
ndarray.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => {
|
||||
@ -1383,7 +1383,7 @@ fn polymorphic_print<'ctx>(
|
||||
|
||||
let (dtype, _) = unpack_ndarray_var_tys(&mut ctx.unifier, ty);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, ty)
|
||||
.map_pointer_value(value.into_pointer_value(), None);
|
||||
.map_value(value.into_pointer_value(), None);
|
||||
|
||||
let num_0 = llvm_usize.const_zero();
|
||||
|
||||
@ -1431,7 +1431,7 @@ fn polymorphic_print<'ctx>(
|
||||
fmt.push_str("range(");
|
||||
flush(ctx, generator, &mut fmt, &mut args);
|
||||
|
||||
let val = RangeType::new(ctx).map_pointer_value(value.into_pointer_value(), None);
|
||||
let val = RangeValue::from_pointer_value(value.into_pointer_value(), None);
|
||||
|
||||
let (start, stop, step) = destructure_range(ctx, val);
|
||||
|
||||
|
@ -16,7 +16,7 @@ use pyo3::{
|
||||
use super::PrimitivePythonId;
|
||||
use nac3core::{
|
||||
codegen::{
|
||||
types::{ndarray::NDArrayType, structure::StructProxyType, ProxyType},
|
||||
types::{ndarray::NDArrayType, ProxyType},
|
||||
values::ndarray::make_contiguous_strides,
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
@ -1146,7 +1146,7 @@ impl InnerResolver {
|
||||
if self.global_value_ids.read().contains_key(&id) {
|
||||
let global = ctx.module.get_global(&id_str).unwrap_or_else(|| {
|
||||
ctx.module.add_global(
|
||||
llvm_ndarray.as_abi_type().get_element_type().into_struct_type(),
|
||||
llvm_ndarray.as_base_type().get_element_type().into_struct_type(),
|
||||
Some(AddressSpace::default()),
|
||||
&id_str,
|
||||
)
|
||||
@ -1315,16 +1315,20 @@ impl InnerResolver {
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let ndarray = llvm_ndarray.get_struct_type().const_named_struct(&[
|
||||
ndarray_itemsize.into(),
|
||||
ndarray_ndims.into(),
|
||||
ndarray_shape.into(),
|
||||
ndarray_strides.into(),
|
||||
ndarray_data.into(),
|
||||
]);
|
||||
let ndarray = llvm_ndarray
|
||||
.as_base_type()
|
||||
.get_element_type()
|
||||
.into_struct_type()
|
||||
.const_named_struct(&[
|
||||
ndarray_itemsize.into(),
|
||||
ndarray_ndims.into(),
|
||||
ndarray_shape.into(),
|
||||
ndarray_strides.into(),
|
||||
ndarray_data.into(),
|
||||
]);
|
||||
|
||||
let ndarray_global = ctx.module.add_global(
|
||||
llvm_ndarray.as_abi_type().get_element_type().into_struct_type(),
|
||||
llvm_ndarray.as_base_type().get_element_type().into_struct_type(),
|
||||
Some(AddressSpace::default()),
|
||||
&id_str,
|
||||
);
|
||||
|
@ -11,5 +11,5 @@ fold = []
|
||||
|
||||
[dependencies]
|
||||
parking_lot = "0.12"
|
||||
string-interner = "0.18"
|
||||
string-interner = "0.17"
|
||||
fxhash = "0.2"
|
||||
|
@ -10,10 +10,11 @@ derive = ["dep:nac3core_derive"]
|
||||
no-escape-analysis = []
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.14"
|
||||
itertools = "0.13"
|
||||
crossbeam = "0.8"
|
||||
indexmap = "2.7"
|
||||
indexmap = "2.6"
|
||||
parking_lot = "0.12"
|
||||
rayon = "1.10"
|
||||
nac3core_derive = { path = "nac3core_derive", optional = true }
|
||||
nac3parser = { path = "../nac3parser" }
|
||||
strum = "0.26"
|
||||
@ -30,4 +31,4 @@ indoc = "2.0"
|
||||
insta = "=1.11.0"
|
||||
|
||||
[build-dependencies]
|
||||
regex = "1.11"
|
||||
regex = "1.10"
|
||||
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::BasicTypeEnum,
|
||||
values::{BasicValueEnum, IntValue},
|
||||
values::{BasicValue, BasicValueEnum, IntValue},
|
||||
FloatPredicate, IntPredicate, OptimizationLevel,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -11,10 +11,10 @@ use super::{
|
||||
irrt::calculate_len_for_slice_range,
|
||||
llvm_intrinsics,
|
||||
macros::codegen_unreachable,
|
||||
types::{ndarray::NDArrayType, ListType, RangeType, TupleType},
|
||||
types::{ndarray::NDArrayType, ListType, TupleType},
|
||||
values::{
|
||||
ndarray::{NDArrayOut, NDArrayValue, ScalarOrNDArray},
|
||||
ProxyValue, TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
|
||||
ProxyValue, RangeValue, TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
@ -47,14 +47,14 @@ pub fn call_len<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let range_ty = ctx.primitives.range;
|
||||
|
||||
Ok(if ctx.unifier.unioned(arg_ty, range_ty) {
|
||||
let arg = RangeType::new(ctx).map_pointer_value(arg.into_pointer_value(), Some("range"));
|
||||
let arg = RangeValue::from_pointer_value(arg.into_pointer_value(), Some("range"));
|
||||
let (start, end, step) = destructure_range(ctx, arg);
|
||||
calculate_len_for_slice_range(generator, ctx, start, end, step)
|
||||
} else {
|
||||
match &*ctx.unifier.get_ty_immutable(arg_ty) {
|
||||
TypeEnum::TTuple { .. } => {
|
||||
let tuple = TupleType::from_unifier_type(generator, ctx, arg_ty)
|
||||
.map_struct_value(arg.into_struct_value(), None);
|
||||
.map_value(arg.into_struct_value(), None);
|
||||
llvm_i32.const_int(tuple.get_type().num_elements().into(), false)
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ pub fn call_len<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if *obj_id == ctx.primitives.ndarray.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, arg_ty)
|
||||
.map_pointer_value(arg.into_pointer_value(), None);
|
||||
.map_value(arg.into_pointer_value(), None);
|
||||
ctx.builder
|
||||
.build_int_truncate_or_bit_cast(ndarray.len(ctx), llvm_i32, "len")
|
||||
.unwrap()
|
||||
@ -72,7 +72,7 @@ pub fn call_len<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if *obj_id == ctx.primitives.list.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let list = ListType::from_unifier_type(generator, ctx, arg_ty)
|
||||
.map_pointer_value(arg.into_pointer_value(), None);
|
||||
.map_value(arg.into_pointer_value(), None);
|
||||
ctx.builder
|
||||
.build_int_truncate_or_bit_cast(list.load_size(ctx, None), llvm_i32, "len")
|
||||
.unwrap()
|
||||
@ -126,8 +126,7 @@ pub fn call_int32<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -138,7 +137,7 @@ pub fn call_int32<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, "int32", &[n_ty]),
|
||||
@ -187,8 +186,7 @@ pub fn call_int64<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -199,7 +197,7 @@ pub fn call_int64<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, "int64", &[n_ty]),
|
||||
@ -264,8 +262,7 @@ pub fn call_uint32<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -276,7 +273,7 @@ pub fn call_uint32<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, "uint32", &[n_ty]),
|
||||
@ -330,8 +327,7 @@ pub fn call_uint64<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -342,7 +338,7 @@ pub fn call_uint64<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, "uint64", &[n_ty]),
|
||||
@ -395,8 +391,7 @@ pub fn call_float<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -407,7 +402,7 @@ pub fn call_float<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, "float", &[n_ty]),
|
||||
@ -440,8 +435,7 @@ pub fn call_round<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -454,7 +448,7 @@ pub fn call_round<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[n_ty]),
|
||||
@ -480,8 +474,7 @@ pub fn call_numpy_round<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -492,7 +485,7 @@ pub fn call_numpy_round<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[n_ty]),
|
||||
@ -543,8 +536,7 @@ pub fn call_bool<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -558,7 +550,7 @@ pub fn call_bool<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[n_ty]),
|
||||
@ -595,8 +587,7 @@ pub fn call_floor<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -609,7 +600,7 @@ pub fn call_floor<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[n_ty]),
|
||||
@ -646,8 +637,7 @@ pub fn call_ceil<'ctx, G: CodeGenerator + ?Sized>(
|
||||
if n_ty.obj_id(&ctx.unifier).is_some_and(|id| id == PrimDef::NDArray.id()) =>
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, n_ty);
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, n_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, n_ty).map_value(n, None);
|
||||
|
||||
let result = ndarray
|
||||
.map(
|
||||
@ -660,7 +650,7 @@ pub fn call_ceil<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[n_ty]),
|
||||
@ -777,7 +767,7 @@ pub fn call_numpy_minimum<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[x1_ty, x2_ty]),
|
||||
@ -868,8 +858,7 @@ pub fn call_numpy_max_min<'ctx, G: CodeGenerator + ?Sized>(
|
||||
{
|
||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, a_ty);
|
||||
|
||||
let ndarray =
|
||||
NDArrayType::from_unifier_type(generator, ctx, a_ty).map_pointer_value(n, None);
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, a_ty).map_value(n, None);
|
||||
let llvm_dtype = ndarray.get_type().element_type();
|
||||
|
||||
let zero = llvm_usize.const_zero();
|
||||
@ -1037,7 +1026,7 @@ pub fn call_numpy_maximum<'ctx, G: CodeGenerator + ?Sized>(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
result.as_abi_value(ctx).into()
|
||||
result.as_base_value().into()
|
||||
}
|
||||
|
||||
_ => unsupported_type(ctx, FN_NAME, &[x1_ty, x2_ty]),
|
||||
@ -1649,7 +1638,7 @@ pub fn call_np_linalg_cholesky<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -1664,11 +1653,11 @@ pub fn call_np_linalg_cholesky<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let out_c = out.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_np_linalg_cholesky(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
out_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
out_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
Ok(out.as_abi_value(ctx).into())
|
||||
Ok(out.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `np_linalg_qr` linalg function
|
||||
@ -1683,7 +1672,7 @@ pub fn call_np_linalg_qr<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -1710,20 +1699,20 @@ pub fn call_np_linalg_qr<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
extern_fns::call_np_linalg_qr(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
q_c.as_abi_value(ctx).into(),
|
||||
r_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
q_c.as_base_value().into(),
|
||||
r_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
let q = q.as_abi_value(ctx);
|
||||
let r = r.as_abi_value(ctx);
|
||||
let q = q.as_base_value().as_basic_value_enum();
|
||||
let r = r.as_base_value().as_basic_value_enum();
|
||||
let tuple = TupleType::new(ctx, &[q.get_type(), r.get_type()]).construct_from_objects(
|
||||
ctx,
|
||||
[q.into(), r.into()],
|
||||
[q, r],
|
||||
None,
|
||||
);
|
||||
Ok(tuple.as_abi_value(ctx).into())
|
||||
Ok(tuple.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `np_linalg_svd` linalg function
|
||||
@ -1738,7 +1727,7 @@ pub fn call_np_linalg_svd<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -1771,19 +1760,19 @@ pub fn call_np_linalg_svd<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
extern_fns::call_np_linalg_svd(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
u_c.as_abi_value(ctx).into(),
|
||||
s_c.as_abi_value(ctx).into(),
|
||||
vh_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
u_c.as_base_value().into(),
|
||||
s_c.as_base_value().into(),
|
||||
vh_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
let u = u.as_abi_value(ctx);
|
||||
let s = s.as_abi_value(ctx);
|
||||
let vh = vh.as_abi_value(ctx);
|
||||
let u = u.as_base_value().as_basic_value_enum();
|
||||
let s = s.as_base_value().as_basic_value_enum();
|
||||
let vh = vh.as_base_value().as_basic_value_enum();
|
||||
let tuple = TupleType::new(ctx, &[u.get_type(), s.get_type(), vh.get_type()])
|
||||
.construct_from_objects(ctx, [u.into(), s.into(), vh.into()], None);
|
||||
Ok(tuple.as_abi_value(ctx).into())
|
||||
.construct_from_objects(ctx, [u, s, vh], None);
|
||||
Ok(tuple.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `np_linalg_inv` linalg function
|
||||
@ -1796,7 +1785,7 @@ pub fn call_np_linalg_inv<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -1811,12 +1800,12 @@ pub fn call_np_linalg_inv<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let out_c = out.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_np_linalg_inv(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
out_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
out_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
Ok(out.as_abi_value(ctx).into())
|
||||
Ok(out.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `np_linalg_pinv` linalg function
|
||||
@ -1831,7 +1820,7 @@ pub fn call_np_linalg_pinv<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -1856,12 +1845,12 @@ pub fn call_np_linalg_pinv<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let out_c = out.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_np_linalg_pinv(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
out_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
out_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
Ok(out.as_abi_value(ctx).into())
|
||||
Ok(out.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `sp_linalg_lu` linalg function
|
||||
@ -1876,7 +1865,7 @@ pub fn call_sp_linalg_lu<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -1903,20 +1892,20 @@ pub fn call_sp_linalg_lu<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let u_c = u.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_sp_linalg_lu(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
l_c.as_abi_value(ctx).into(),
|
||||
u_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
l_c.as_base_value().into(),
|
||||
u_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
let l = l.as_abi_value(ctx);
|
||||
let u = u.as_abi_value(ctx);
|
||||
let l = l.as_base_value().as_basic_value_enum();
|
||||
let u = u.as_base_value().as_basic_value_enum();
|
||||
let tuple = TupleType::new(ctx, &[l.get_type(), u.get_type()]).construct_from_objects(
|
||||
ctx,
|
||||
[l.into(), u.into()],
|
||||
[l, u],
|
||||
None,
|
||||
);
|
||||
Ok(tuple.as_abi_value(ctx).into())
|
||||
Ok(tuple.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `np_linalg_matrix_power` linalg function
|
||||
@ -1964,13 +1953,13 @@ pub fn call_np_linalg_matrix_power<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
extern_fns::call_np_linalg_matrix_power(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
x2_c.as_abi_value(ctx).into(),
|
||||
out_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
x2_c.as_base_value().into(),
|
||||
out_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
Ok(out.as_abi_value(ctx).into())
|
||||
Ok(out.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `np_linalg_det` linalg function
|
||||
@ -1985,7 +1974,7 @@ pub fn call_np_linalg_det<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
unsupported_type(ctx, FN_NAME, &[x1_ty]);
|
||||
@ -2004,8 +1993,8 @@ pub fn call_np_linalg_det<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let out_c = det.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_np_linalg_det(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
out_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
out_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -2024,7 +2013,7 @@ pub fn call_sp_linalg_schur<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
assert_eq!(x1.get_type().ndims(), 2);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
@ -2046,20 +2035,20 @@ pub fn call_sp_linalg_schur<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let z_c = z.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_sp_linalg_schur(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
t_c.as_abi_value(ctx).into(),
|
||||
z_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
t_c.as_base_value().into(),
|
||||
z_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
let t = t.as_abi_value(ctx);
|
||||
let z = z.as_abi_value(ctx);
|
||||
let t = t.as_base_value().as_basic_value_enum();
|
||||
let z = z.as_base_value().as_basic_value_enum();
|
||||
let tuple = TupleType::new(ctx, &[t.get_type(), z.get_type()]).construct_from_objects(
|
||||
ctx,
|
||||
[t.into(), z.into()],
|
||||
[t, z],
|
||||
None,
|
||||
);
|
||||
Ok(tuple.as_abi_value(ctx).into())
|
||||
Ok(tuple.as_base_value().into())
|
||||
}
|
||||
|
||||
/// Invokes the `sp_linalg_hessenberg` linalg function
|
||||
@ -2072,7 +2061,7 @@ pub fn call_sp_linalg_hessenberg<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
let BasicValueEnum::PointerValue(x1) = x1 else { unsupported_type(ctx, FN_NAME, &[x1_ty]) };
|
||||
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(x1, None);
|
||||
let x1 = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(x1, None);
|
||||
assert_eq!(x1.get_type().ndims(), 2);
|
||||
|
||||
if !x1.get_type().element_type().is_float_type() {
|
||||
@ -2094,18 +2083,18 @@ pub fn call_sp_linalg_hessenberg<'ctx, G: CodeGenerator + ?Sized>(
|
||||
let q_c = q.make_contiguous_ndarray(generator, ctx);
|
||||
extern_fns::call_sp_linalg_hessenberg(
|
||||
ctx,
|
||||
x1_c.as_abi_value(ctx).into(),
|
||||
h_c.as_abi_value(ctx).into(),
|
||||
q_c.as_abi_value(ctx).into(),
|
||||
x1_c.as_base_value().into(),
|
||||
h_c.as_base_value().into(),
|
||||
q_c.as_base_value().into(),
|
||||
None,
|
||||
);
|
||||
|
||||
let h = h.as_abi_value(ctx);
|
||||
let q = q.as_abi_value(ctx);
|
||||
let h = h.as_base_value().as_basic_value_enum();
|
||||
let q = q.as_base_value().as_basic_value_enum();
|
||||
let tuple = TupleType::new(ctx, &[h.get_type(), q.get_type()]).construct_from_objects(
|
||||
ctx,
|
||||
[h.into(), q.into()],
|
||||
[h, q],
|
||||
None,
|
||||
);
|
||||
Ok(tuple.as_abi_value(ctx).into())
|
||||
Ok(tuple.as_base_value().into())
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ use super::{
|
||||
gen_for_callback_incrementing, gen_if_callback, gen_if_else_expr_callback, gen_raise,
|
||||
gen_var,
|
||||
},
|
||||
types::{ndarray::NDArrayType, ListType, RangeType},
|
||||
types::{ndarray::NDArrayType, ListType},
|
||||
values::{
|
||||
ndarray::{NDArrayOut, RustNDIndex, ScalarOrNDArray},
|
||||
ArrayLikeIndexer, ArrayLikeValue, ListValue, ProxyValue, RangeValue,
|
||||
@ -1151,7 +1151,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
|
||||
if *obj_id == ctx.primitives.range.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let iter_val =
|
||||
RangeType::new(ctx).map_pointer_value(iter_val.into_pointer_value(), Some("range"));
|
||||
RangeValue::from_pointer_value(iter_val.into_pointer_value(), Some("range"));
|
||||
let (start, stop, step) = destructure_range(ctx, iter_val);
|
||||
let diff = ctx.builder.build_int_sub(stop, start, "diff").unwrap();
|
||||
// add 1 to the length as the value is rounded to zero
|
||||
@ -1307,7 +1307,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
|
||||
|
||||
emit_cont_bb(ctx, list);
|
||||
|
||||
Ok(Some(list.as_abi_value(ctx).into()))
|
||||
Ok(Some(list.as_base_value().into()))
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for a binary operator expression using the [`Type`] and
|
||||
@ -1437,7 +1437,7 @@ pub fn gen_binop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
ctx.ctx.bool_type().const_zero(),
|
||||
);
|
||||
|
||||
Ok(Some(new_list.as_abi_value(ctx).into()))
|
||||
Ok(Some(new_list.as_base_value().into()))
|
||||
}
|
||||
|
||||
Operator::Mult => {
|
||||
@ -1524,7 +1524,7 @@ pub fn gen_binop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
llvm_usize.const_int(1, false),
|
||||
)?;
|
||||
|
||||
Ok(Some(new_list.as_abi_value(ctx).into()))
|
||||
Ok(Some(new_list.as_base_value().into()))
|
||||
}
|
||||
|
||||
_ => todo!("Operator not supported"),
|
||||
@ -1601,7 +1601,7 @@ pub fn gen_binop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
Ok(result)
|
||||
})
|
||||
.unwrap();
|
||||
Ok(Some(result.as_abi_value(ctx).into()))
|
||||
Ok(Some(result.as_base_value().into()))
|
||||
}
|
||||
} else {
|
||||
let left_ty_enum = ctx.unifier.get_ty_immutable(left_ty.unwrap());
|
||||
@ -1767,7 +1767,7 @@ pub fn gen_unaryop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
let (ndarray_dtype, _) = unpack_ndarray_var_tys(&mut ctx.unifier, ty);
|
||||
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, ty)
|
||||
.map_pointer_value(val.into_pointer_value(), None);
|
||||
.map_value(val.into_pointer_value(), None);
|
||||
|
||||
// ndarray uses `~` rather than `not` to perform elementwise inversion, convert it before
|
||||
// passing it to the elementwise codegen function
|
||||
@ -1796,7 +1796,7 @@ pub fn gen_unaryop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
},
|
||||
)?;
|
||||
|
||||
mapped_ndarray.as_abi_value(ctx).into()
|
||||
mapped_ndarray.as_base_value().into()
|
||||
} else {
|
||||
unimplemented!()
|
||||
}))
|
||||
@ -1883,7 +1883,7 @@ pub fn gen_cmpop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
},
|
||||
)?;
|
||||
|
||||
return Ok(Some(result_ndarray.as_abi_value(ctx).into()));
|
||||
return Ok(Some(result_ndarray.as_base_value().into()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2493,7 +2493,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
||||
);
|
||||
ctx.builder.build_store(elem_ptr, *v).unwrap();
|
||||
}
|
||||
arr_str_ptr.as_abi_value(ctx).into()
|
||||
arr_str_ptr.as_base_value().into()
|
||||
}
|
||||
ExprKind::Tuple { elts, .. } => {
|
||||
let elements_val = elts
|
||||
@ -2988,7 +2988,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
||||
v,
|
||||
(start, end, step),
|
||||
);
|
||||
res_array_ret.as_abi_value(ctx).into()
|
||||
res_array_ret.as_base_value().into()
|
||||
} else {
|
||||
let len = v.load_size(ctx, Some("len"));
|
||||
let raw_index = if let Some(v) = generator.gen_expr(ctx, slice)? {
|
||||
@ -3043,14 +3043,14 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
||||
let ndarray_ty = value.custom.unwrap();
|
||||
let ndarray = ndarray.to_basic_value_enum(ctx, generator, ndarray_ty)?;
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, ndarray_ty)
|
||||
.map_pointer_value(ndarray.into_pointer_value(), None);
|
||||
.map_value(ndarray.into_pointer_value(), None);
|
||||
|
||||
let indices = RustNDIndex::from_subscript_expr(generator, ctx, slice)?;
|
||||
let result = ndarray
|
||||
.index(generator, ctx, &indices)
|
||||
.split_unsized(generator, ctx)
|
||||
.to_basic_value_enum();
|
||||
return Ok(Some(result.into()));
|
||||
return Ok(Some(ValueEnum::Dynamic(result)));
|
||||
}
|
||||
TypeEnum::TTuple { .. } => {
|
||||
let index: u32 =
|
||||
|
@ -36,7 +36,7 @@ pub fn call_nac3_ndarray_array_set_and_validate_list_shape<'ctx, G: CodeGenerato
|
||||
ctx,
|
||||
&name,
|
||||
None,
|
||||
&[list.as_abi_value(ctx).into(), ndims.into(), shape.base_ptr(ctx, generator).into()],
|
||||
&[list.as_base_value().into(), ndims.into(), shape.base_ptr(ctx, generator).into()],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -65,7 +65,7 @@ pub fn call_nac3_ndarray_array_write_list_to_array<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
None,
|
||||
&[list.as_abi_value(ctx).into(), ndarray.as_abi_value(ctx).into()],
|
||||
&[list.as_base_value().into(), ndarray.as_base_value().into()],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@ -93,7 +93,7 @@ pub fn call_nac3_ndarray_size<'ctx>(
|
||||
ndarray: NDArrayValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let llvm_usize = ctx.get_size_type();
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
let name = get_usize_dependent_function_name(ctx, "__nac3_ndarray_size");
|
||||
|
||||
@ -101,7 +101,7 @@ pub fn call_nac3_ndarray_size<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
Some(llvm_usize.into()),
|
||||
&[(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into())],
|
||||
&[(llvm_ndarray.into(), ndarray.as_base_value().into())],
|
||||
Some("size"),
|
||||
None,
|
||||
)
|
||||
@ -118,7 +118,7 @@ pub fn call_nac3_ndarray_nbytes<'ctx>(
|
||||
ndarray: NDArrayValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let llvm_usize = ctx.get_size_type();
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
let name = get_usize_dependent_function_name(ctx, "__nac3_ndarray_nbytes");
|
||||
|
||||
@ -126,7 +126,7 @@ pub fn call_nac3_ndarray_nbytes<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
Some(llvm_usize.into()),
|
||||
&[(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into())],
|
||||
&[(llvm_ndarray.into(), ndarray.as_base_value().into())],
|
||||
Some("nbytes"),
|
||||
None,
|
||||
)
|
||||
@ -143,7 +143,7 @@ pub fn call_nac3_ndarray_len<'ctx>(
|
||||
ndarray: NDArrayValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let llvm_usize = ctx.get_size_type();
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
let name = get_usize_dependent_function_name(ctx, "__nac3_ndarray_len");
|
||||
|
||||
@ -151,7 +151,7 @@ pub fn call_nac3_ndarray_len<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
Some(llvm_usize.into()),
|
||||
&[(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into())],
|
||||
&[(llvm_ndarray.into(), ndarray.as_base_value().into())],
|
||||
Some("len"),
|
||||
None,
|
||||
)
|
||||
@ -167,7 +167,7 @@ pub fn call_nac3_ndarray_is_c_contiguous<'ctx>(
|
||||
ndarray: NDArrayValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
let llvm_i1 = ctx.ctx.bool_type();
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
let name = get_usize_dependent_function_name(ctx, "__nac3_ndarray_is_c_contiguous");
|
||||
|
||||
@ -175,7 +175,7 @@ pub fn call_nac3_ndarray_is_c_contiguous<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
Some(llvm_i1.into()),
|
||||
&[(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into())],
|
||||
&[(llvm_ndarray.into(), ndarray.as_base_value().into())],
|
||||
Some("is_c_contiguous"),
|
||||
None,
|
||||
)
|
||||
@ -194,7 +194,7 @@ pub fn call_nac3_ndarray_get_nth_pelement<'ctx>(
|
||||
let llvm_i8 = ctx.ctx.i8_type();
|
||||
let llvm_pi8 = llvm_i8.ptr_type(AddressSpace::default());
|
||||
let llvm_usize = ctx.get_size_type();
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
assert_eq!(index.get_type(), llvm_usize);
|
||||
|
||||
@ -204,10 +204,7 @@ pub fn call_nac3_ndarray_get_nth_pelement<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
Some(llvm_pi8.into()),
|
||||
&[
|
||||
(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into()),
|
||||
(llvm_usize.into(), index.into()),
|
||||
],
|
||||
&[(llvm_ndarray.into(), ndarray.as_base_value().into()), (llvm_usize.into(), index.into())],
|
||||
Some("pelement"),
|
||||
None,
|
||||
)
|
||||
@ -230,7 +227,7 @@ pub fn call_nac3_ndarray_get_pelement_by_indices<'ctx, G: CodeGenerator + ?Sized
|
||||
let llvm_pi8 = llvm_i8.ptr_type(AddressSpace::default());
|
||||
let llvm_usize = ctx.get_size_type();
|
||||
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
assert_eq!(
|
||||
BasicTypeEnum::try_from(indices.element_type(ctx, generator)).unwrap(),
|
||||
@ -244,7 +241,7 @@ pub fn call_nac3_ndarray_get_pelement_by_indices<'ctx, G: CodeGenerator + ?Sized
|
||||
&name,
|
||||
Some(llvm_pi8.into()),
|
||||
&[
|
||||
(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into()),
|
||||
(llvm_ndarray.into(), ndarray.as_base_value().into()),
|
||||
(llvm_pusize.into(), indices.base_ptr(ctx, generator).into()),
|
||||
],
|
||||
Some("pelement"),
|
||||
@ -261,7 +258,7 @@ pub fn call_nac3_ndarray_set_strides_by_shape<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
ndarray: NDArrayValue<'ctx>,
|
||||
) {
|
||||
let llvm_ndarray = ndarray.get_type();
|
||||
let llvm_ndarray = ndarray.get_type().as_base_type();
|
||||
|
||||
let name = get_usize_dependent_function_name(ctx, "__nac3_ndarray_set_strides_by_shape");
|
||||
|
||||
@ -269,7 +266,7 @@ pub fn call_nac3_ndarray_set_strides_by_shape<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
None,
|
||||
&[(llvm_ndarray.as_abi_type().into(), ndarray.as_abi_value(ctx).into())],
|
||||
&[(llvm_ndarray.into(), ndarray.as_base_value().into())],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -291,7 +288,7 @@ pub fn call_nac3_ndarray_copy_data<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
None,
|
||||
&[src_ndarray.as_abi_value(ctx).into(), dst_ndarray.as_abi_value(ctx).into()],
|
||||
&[src_ndarray.as_base_value().into(), dst_ndarray.as_base_value().into()],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@ -30,7 +30,7 @@ pub fn call_nac3_ndarray_broadcast_to<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
None,
|
||||
&[src_ndarray.as_abi_value(ctx).into(), dst_ndarray.as_abi_value(ctx).into()],
|
||||
&[src_ndarray.as_base_value().into(), dst_ndarray.as_base_value().into()],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -55,9 +55,10 @@ pub fn call_nac3_ndarray_broadcast_shapes<'ctx, G, Shape>(
|
||||
let llvm_usize = ctx.get_size_type();
|
||||
|
||||
assert_eq!(num_shape_entries.get_type(), llvm_usize);
|
||||
assert!(ShapeEntryType::is_representable(
|
||||
shape_entries.base_ptr(ctx, generator).get_type(),
|
||||
llvm_usize,
|
||||
assert!(ShapeEntryType::is_type(
|
||||
generator,
|
||||
ctx.ctx,
|
||||
shape_entries.base_ptr(ctx, generator).get_type()
|
||||
)
|
||||
.is_ok());
|
||||
assert_eq!(dst_ndims.get_type(), llvm_usize);
|
||||
|
@ -25,8 +25,8 @@ pub fn call_nac3_ndarray_index<'ctx, G: CodeGenerator + ?Sized>(
|
||||
&[
|
||||
indices.size(ctx, generator).into(),
|
||||
indices.base_ptr(ctx, generator).into(),
|
||||
src_ndarray.as_abi_value(ctx).into(),
|
||||
dst_ndarray.as_abi_value(ctx).into(),
|
||||
src_ndarray.as_base_value().into(),
|
||||
dst_ndarray.as_base_value().into(),
|
||||
],
|
||||
None,
|
||||
None,
|
||||
|
@ -40,8 +40,8 @@ pub fn call_nac3_nditer_initialize<'ctx, G: CodeGenerator + ?Sized>(
|
||||
&name,
|
||||
None,
|
||||
&[
|
||||
(iter.get_type().as_abi_type().into(), iter.as_abi_value(ctx).into()),
|
||||
(ndarray.get_type().as_abi_type().into(), ndarray.as_abi_value(ctx).into()),
|
||||
(iter.get_type().as_base_type().into(), iter.as_base_value().into()),
|
||||
(ndarray.get_type().as_base_type().into(), ndarray.as_base_value().into()),
|
||||
(llvm_pusize.into(), indices.base_ptr(ctx, generator).into()),
|
||||
],
|
||||
None,
|
||||
@ -63,7 +63,7 @@ pub fn call_nac3_nditer_has_element<'ctx>(
|
||||
ctx,
|
||||
&name,
|
||||
Some(ctx.ctx.bool_type().into()),
|
||||
&[iter.as_abi_value(ctx).into()],
|
||||
&[iter.as_base_value().into()],
|
||||
None,
|
||||
None,
|
||||
)
|
||||
@ -77,5 +77,5 @@ pub fn call_nac3_nditer_has_element<'ctx>(
|
||||
pub fn call_nac3_nditer_next<'ctx>(ctx: &CodeGenContext<'ctx, '_>, iter: NDIterValue<'ctx>) {
|
||||
let name = get_usize_dependent_function_name(ctx, "__nac3_nditer_next");
|
||||
|
||||
infer_and_call_function(ctx, &name, None, &[iter.as_abi_value(ctx).into()], None, None);
|
||||
infer_and_call_function(ctx, &name, None, &[iter.as_base_value().into()], None, None);
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ pub fn call_nac3_ndarray_transpose<'ctx, G: CodeGenerator + ?Sized>(
|
||||
&name,
|
||||
None,
|
||||
&[
|
||||
src_ndarray.as_abi_value(ctx).into(),
|
||||
dst_ndarray.as_abi_value(ctx).into(),
|
||||
src_ndarray.as_base_value().into(),
|
||||
dst_ndarray.as_base_value().into(),
|
||||
axes.map_or(llvm_usize.const_zero(), |axes| axes.size(ctx, generator)).into(),
|
||||
axes.map_or(llvm_usize.ptr_type(AddressSpace::default()).const_null(), |axes| {
|
||||
axes.base_ptr(ctx, generator)
|
||||
|
@ -562,7 +562,7 @@ fn get_llvm_type<'ctx, G: CodeGenerator + ?Sized>(
|
||||
*params.iter().next().unwrap().1,
|
||||
);
|
||||
|
||||
ListType::new_with_generator(generator, ctx, element_type).as_abi_type().into()
|
||||
ListType::new_with_generator(generator, ctx, element_type).as_base_type().into()
|
||||
}
|
||||
|
||||
TObj { obj_id, .. } if *obj_id == PrimDef::NDArray.id() => {
|
||||
@ -572,7 +572,7 @@ fn get_llvm_type<'ctx, G: CodeGenerator + ?Sized>(
|
||||
ctx, module, generator, unifier, top_level, type_cache, dtype,
|
||||
);
|
||||
|
||||
NDArrayType::new_with_generator(generator, ctx, element_type, ndims).as_abi_type().into()
|
||||
NDArrayType::new_with_generator(generator, ctx, element_type, ndims).as_base_type().into()
|
||||
}
|
||||
|
||||
_ => unreachable!(
|
||||
@ -626,7 +626,7 @@ fn get_llvm_type<'ctx, G: CodeGenerator + ?Sized>(
|
||||
get_llvm_type(ctx, module, generator, unifier, top_level, type_cache, *ty)
|
||||
})
|
||||
.collect_vec();
|
||||
TupleType::new_with_generator(generator, ctx, &fields).as_abi_type().into()
|
||||
TupleType::new_with_generator(generator, ctx, &fields).as_base_type().into()
|
||||
}
|
||||
TVirtual { .. } => unimplemented!(),
|
||||
_ => unreachable!("{}", ty_enum.get_type_name()),
|
||||
@ -800,7 +800,7 @@ pub fn gen_func_impl<
|
||||
Some(t) => t.as_basic_type_enum(),
|
||||
}
|
||||
}),
|
||||
(primitives.range, RangeType::new_with_generator(generator, context).as_abi_type().into()),
|
||||
(primitives.range, RangeType::new(context).as_base_type().into()),
|
||||
(primitives.exception, {
|
||||
let name = "Exception";
|
||||
if let Some(t) = module.get_struct_type(name) {
|
||||
|
@ -44,7 +44,7 @@ pub fn gen_ndarray_empty<'ctx>(
|
||||
|
||||
let ndarray = NDArrayType::new(context, llvm_dtype, ndims)
|
||||
.construct_numpy_empty(generator, context, &shape, None);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.zeros`.
|
||||
@ -69,7 +69,7 @@ pub fn gen_ndarray_zeros<'ctx>(
|
||||
|
||||
let ndarray = NDArrayType::new(context, llvm_dtype, ndims)
|
||||
.construct_numpy_zeros(generator, context, dtype, &shape, None);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.ones`.
|
||||
@ -94,7 +94,7 @@ pub fn gen_ndarray_ones<'ctx>(
|
||||
|
||||
let ndarray = NDArrayType::new(context, llvm_dtype, ndims)
|
||||
.construct_numpy_ones(generator, context, dtype, &shape, None);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.full`.
|
||||
@ -127,7 +127,7 @@ pub fn gen_ndarray_full<'ctx>(
|
||||
fill_value_arg,
|
||||
None,
|
||||
);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
pub fn gen_ndarray_array<'ctx>(
|
||||
@ -166,7 +166,7 @@ pub fn gen_ndarray_array<'ctx>(
|
||||
.construct_numpy_array(generator, context, (obj_ty, obj_arg), copy, None)
|
||||
.atleast_nd(generator, context, ndims);
|
||||
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.eye`.
|
||||
@ -225,7 +225,7 @@ pub fn gen_ndarray_eye<'ctx>(
|
||||
|
||||
let ndarray = NDArrayType::new(context, llvm_dtype, 2)
|
||||
.construct_numpy_eye(generator, context, dtype, nrows, ncols, offset, None);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.identity`.
|
||||
@ -253,7 +253,7 @@ pub fn gen_ndarray_identity<'ctx>(
|
||||
.unwrap();
|
||||
let ndarray = NDArrayType::new(context, llvm_dtype, 2)
|
||||
.construct_numpy_identity(generator, context, dtype, n, None);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.copy`.
|
||||
@ -272,9 +272,9 @@ pub fn gen_ndarray_copy<'ctx>(
|
||||
obj.as_ref().unwrap().1.clone().to_basic_value_enum(context, generator, this_ty)?;
|
||||
|
||||
let this = NDArrayType::from_unifier_type(generator, context, this_ty)
|
||||
.map_pointer_value(this_arg.into_pointer_value(), None);
|
||||
.map_value(this_arg.into_pointer_value(), None);
|
||||
let ndarray = this.make_copy(generator, context);
|
||||
Ok(ndarray.as_abi_value(context))
|
||||
Ok(ndarray.as_base_value())
|
||||
}
|
||||
|
||||
/// Generates LLVM IR for `ndarray.fill`.
|
||||
@ -295,7 +295,7 @@ pub fn gen_ndarray_fill<'ctx>(
|
||||
let value_arg = args[0].1.clone().to_basic_value_enum(context, generator, value_ty)?;
|
||||
|
||||
let this = NDArrayType::from_unifier_type(generator, context, this_ty)
|
||||
.map_pointer_value(this_arg.into_pointer_value(), None);
|
||||
.map_value(this_arg.into_pointer_value(), None);
|
||||
this.fill(generator, context, value_arg);
|
||||
Ok(())
|
||||
}
|
||||
@ -316,10 +316,8 @@ pub fn ndarray_dot<'ctx, G: CodeGenerator + ?Sized>(
|
||||
|
||||
match (x1, x2) {
|
||||
(BasicValueEnum::PointerValue(n1), BasicValueEnum::PointerValue(n2)) => {
|
||||
let a =
|
||||
NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_pointer_value(n1, None);
|
||||
let b =
|
||||
NDArrayType::from_unifier_type(generator, ctx, x2_ty).map_pointer_value(n2, None);
|
||||
let a = NDArrayType::from_unifier_type(generator, ctx, x1_ty).map_value(n1, None);
|
||||
let b = NDArrayType::from_unifier_type(generator, ctx, x2_ty).map_value(n2, None);
|
||||
|
||||
// TODO: General `np.dot()` https://numpy.org/doc/stable/reference/generated/numpy.dot.html.
|
||||
assert_eq!(a.get_type().ndims(), 1);
|
||||
|
@ -17,10 +17,10 @@ use super::{
|
||||
gen_in_range_check,
|
||||
irrt::{handle_slice_indices, list_slice_assignment},
|
||||
macros::codegen_unreachable,
|
||||
types::{ndarray::NDArrayType, RangeType},
|
||||
types::ndarray::NDArrayType,
|
||||
values::{
|
||||
ndarray::{RustNDIndex, ScalarOrNDArray},
|
||||
ArrayLikeIndexer, ArraySliceValue, ListValue, ProxyValue,
|
||||
ArrayLikeIndexer, ArraySliceValue, ListValue, ProxyValue, RangeValue,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
@ -440,7 +440,7 @@ pub fn gen_setitem<'ctx, G: CodeGenerator>(
|
||||
// ```
|
||||
|
||||
let target = NDArrayType::from_unifier_type(generator, ctx, target_ty)
|
||||
.map_pointer_value(target.into_pointer_value(), None);
|
||||
.map_value(target.into_pointer_value(), None);
|
||||
let target = target.index(generator, ctx, &key);
|
||||
|
||||
let value = ScalarOrNDArray::from_value(generator, ctx, (value_ty, value))
|
||||
@ -511,7 +511,7 @@ pub fn gen_for<G: CodeGenerator>(
|
||||
if *obj_id == ctx.primitives.range.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let iter_val =
|
||||
RangeType::new(ctx).map_pointer_value(iter_val.into_pointer_value(), Some("range"));
|
||||
RangeValue::from_pointer_value(iter_val.into_pointer_value(), Some("range"));
|
||||
// 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
|
||||
|
@ -447,18 +447,15 @@ fn test_classes_list_type_new() {
|
||||
let llvm_usize = generator.get_size_type(&ctx);
|
||||
|
||||
let llvm_list = ListType::new_with_generator(&generator, &ctx, llvm_i32.into());
|
||||
assert!(ListType::is_representable(llvm_list.as_abi_type(), llvm_usize).is_ok());
|
||||
assert!(ListType::is_representable(llvm_list.as_base_type(), llvm_usize).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_classes_range_type_new() {
|
||||
let ctx = inkwell::context::Context::create();
|
||||
let generator = DefaultCodeGenerator::new(String::new(), ctx.i64_type());
|
||||
|
||||
let llvm_usize = generator.get_size_type(&ctx);
|
||||
|
||||
let llvm_range = RangeType::new_with_generator(&generator, &ctx);
|
||||
assert!(RangeType::is_representable(llvm_range.as_abi_type(), llvm_usize).is_ok());
|
||||
let llvm_range = RangeType::new(&ctx);
|
||||
assert!(RangeType::is_representable(llvm_range.as_base_type()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -470,5 +467,5 @@ fn test_classes_ndarray_type_new() {
|
||||
let llvm_usize = generator.get_size_type(&ctx);
|
||||
|
||||
let llvm_ndarray = NDArrayType::new_with_generator(&generator, &ctx, llvm_i32.into(), 2);
|
||||
assert!(NDArrayType::is_representable(llvm_ndarray.as_abi_type(), llvm_usize).is_ok());
|
||||
assert!(NDArrayType::is_representable(llvm_ndarray.as_base_type(), llvm_usize).is_ok());
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace, IntPredicate, OptimizationLevel,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -13,9 +13,8 @@ use crate::{
|
||||
codegen::{
|
||||
types::structure::{
|
||||
check_struct_type_matches_fields, FieldIndexCounter, StructField, StructFields,
|
||||
StructProxyType,
|
||||
},
|
||||
values::ListValue,
|
||||
values::{ListValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::{iter_type_vars, Type, TypeEnum},
|
||||
@ -57,12 +56,47 @@ impl<'ctx> ListStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ListType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a `list` type, returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let llvm_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!("Expected struct type for `list` type, got {llvm_ty}"));
|
||||
};
|
||||
|
||||
let fields = ListStructFields::new(ctx, llvm_usize);
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
fields,
|
||||
llvm_ty,
|
||||
"list",
|
||||
&[(fields.items.name(), &|ty| {
|
||||
if ty.is_pointer_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected T* for `list.items`, got {ty}"))
|
||||
}
|
||||
})],
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`StructFields`] containing all field accessors for this type.
|
||||
#[must_use]
|
||||
fn fields(item: BasicTypeEnum<'ctx>, llvm_usize: IntType<'ctx>) -> ListStructFields<'ctx> {
|
||||
ListStructFields::new_typed(item, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`ListType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, _ctx: &impl AsContextRef<'ctx>) -> ListStructFields<'ctx> {
|
||||
Self::fields(self.item.unwrap_or(self.llvm_usize.into()), self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `List`.
|
||||
#[must_use]
|
||||
fn llvm_type(
|
||||
@ -147,16 +181,10 @@ impl<'ctx> ListType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, llvm_elem_type, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ListType`] from a [`StructType`].
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ListType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::is_representable(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
let ctx = ptr_ty.get_context();
|
||||
|
||||
@ -295,27 +323,9 @@ impl<'ctx> ListType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ListValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ListValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
@ -323,64 +333,36 @@ impl<'ctx> ListType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = ListValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let llvm_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!("Expected struct type for `list` type, got {llvm_ty}"));
|
||||
};
|
||||
|
||||
let fields = ListStructFields::new(ctx, llvm_usize);
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
fields,
|
||||
llvm_ty,
|
||||
"list",
|
||||
&[(fields.items.name(), &|ty| {
|
||||
if ty.is_pointer_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected T* for `list.items`, got {ty}"))
|
||||
}
|
||||
})],
|
||||
)
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for ListType<'ctx> {
|
||||
type StructFields = ListStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.item.unwrap_or(self.llvm_usize.into()), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<ListType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -17,7 +17,8 @@
|
||||
//! on the stack.
|
||||
|
||||
use inkwell::{
|
||||
types::{BasicType, IntType},
|
||||
context::Context,
|
||||
types::BasicType,
|
||||
values::{IntValue, PointerValue},
|
||||
};
|
||||
|
||||
@ -38,24 +39,25 @@ pub mod utils;
|
||||
|
||||
/// A LLVM type that is used to represent a corresponding type in NAC3.
|
||||
pub trait ProxyType<'ctx>: Into<Self::Base> {
|
||||
/// The ABI type of which values of this type possess.
|
||||
type ABI: BasicType<'ctx>;
|
||||
|
||||
/// The LLVM type of which values of this type possess.
|
||||
/// The LLVM type of which values of this type possess. This is usually a
|
||||
/// [LLVM pointer type][PointerType] for any non-primitive types.
|
||||
type Base: BasicType<'ctx>;
|
||||
|
||||
/// The type of values represented by this type.
|
||||
type Value: ProxyValue<'ctx, Type = Self>;
|
||||
|
||||
/// Checks whether `llvm_ty` can be represented by this [`ProxyType`].
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// Checks whether the type represented by `ty` expresses the same type represented by this
|
||||
/// [`ProxyType`].
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String>;
|
||||
/// Checks whether `llvm_ty` can be represented by this [`ProxyType`].
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// Returns the type that should be used in `alloca` IR statements.
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx>;
|
||||
@ -120,10 +122,4 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
|
||||
|
||||
/// Returns the [base type][Self::Base] of this proxy.
|
||||
fn as_base_type(&self) -> Self::Base;
|
||||
|
||||
/// Returns this proxy as its ABI type, i.e. the expected type representation if a value of this
|
||||
/// [`ProxyType`] is being passed into or returned from a function.
|
||||
///
|
||||
/// See [`CodeGenContext::get_llvm_abi_type`].
|
||||
fn as_abi_type(&self) -> Self::ABI;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
(list_ty, list),
|
||||
name,
|
||||
);
|
||||
Ok(Some(ndarray.as_abi_value(ctx)))
|
||||
Ok(Some(ndarray.as_base_value()))
|
||||
},
|
||||
|generator, ctx| {
|
||||
let ndarray = self.construct_numpy_array_from_list_copy_none_impl(
|
||||
@ -160,14 +160,14 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
(list_ty, list),
|
||||
name,
|
||||
);
|
||||
Ok(Some(ndarray.as_abi_value(ctx)))
|
||||
Ok(Some(ndarray.as_base_value()))
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
.map(BasicValueEnum::into_pointer_value)
|
||||
.unwrap();
|
||||
|
||||
NDArrayType::new(ctx, dtype, ndims).map_pointer_value(ndarray, None)
|
||||
NDArrayType::new(ctx, dtype, ndims).map_value(ndarray, None)
|
||||
}
|
||||
|
||||
/// Implementation of `np_array(<ndarray>, copy=copy)`.
|
||||
@ -189,18 +189,18 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
|_generator, _ctx| Ok(copy),
|
||||
|generator, ctx| {
|
||||
let ndarray = ndarray.make_copy(generator, ctx); // Force copy
|
||||
Ok(Some(ndarray.as_abi_value(ctx)))
|
||||
Ok(Some(ndarray.as_base_value()))
|
||||
},
|
||||
|_generator, ctx| {
|
||||
|_generator, _ctx| {
|
||||
// No need to copy. Return `ndarray` itself.
|
||||
Ok(Some(ndarray.as_abi_value(ctx)))
|
||||
Ok(Some(ndarray.as_base_value()))
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
.map(BasicValueEnum::into_pointer_value)
|
||||
.unwrap();
|
||||
|
||||
ndarray.get_type().map_pointer_value(ndarray_val, name)
|
||||
ndarray.get_type().map_value(ndarray_val, name)
|
||||
}
|
||||
|
||||
/// Create a new ndarray like
|
||||
@ -222,7 +222,7 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
if *obj_id == ctx.primitives.list.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let list = ListType::from_unifier_type(generator, ctx, object_ty)
|
||||
.map_pointer_value(object.into_pointer_value(), None);
|
||||
.map_value(object.into_pointer_value(), None);
|
||||
self.construct_numpy_array_list_impl(generator, ctx, (object_ty, list), copy, name)
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
if *obj_id == ctx.primitives.ndarray.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, object_ty)
|
||||
.map_pointer_value(object.into_pointer_value(), None);
|
||||
.map_value(object.into_pointer_value(), None);
|
||||
self.construct_numpy_array_ndarray_impl(generator, ctx, ndarray, copy, name)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -10,10 +10,10 @@ use nac3core_derive::StructFields;
|
||||
|
||||
use crate::codegen::{
|
||||
types::{
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields, StructProxyType},
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
ProxyType,
|
||||
},
|
||||
values::ndarray::ShapeEntryValue,
|
||||
values::{ndarray::ShapeEntryValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -32,6 +32,28 @@ pub struct ShapeEntryStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ShapeEntryType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a [`ShapeEntryType`], returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let llvm_ndarray_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ndarray_ty) = llvm_ndarray_ty else {
|
||||
return Err(format!(
|
||||
"Expected struct type for `ShapeEntry` type, got {llvm_ndarray_ty}"
|
||||
));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
Self::fields(ctx, llvm_usize),
|
||||
llvm_ndarray_ty,
|
||||
"NDArray",
|
||||
&[],
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`StructFields`] containing all field accessors for this type.
|
||||
#[must_use]
|
||||
fn fields(
|
||||
@ -41,6 +63,13 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
ShapeEntryStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`ShapeEntryStructFields::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, ctx: impl AsContextRef<'ctx>) -> ShapeEntryStructFields<'ctx> {
|
||||
Self::fields(ctx, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `ShapeEntry`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
@ -71,16 +100,10 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates a [`ShapeEntryType`] from a [`StructType`] representing an `ShapeEntry`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates a [`ShapeEntryType`] from a [`PointerType`] representing an `ShapeEntry`.
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::is_representable(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, llvm_usize }
|
||||
}
|
||||
@ -116,27 +139,9 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ShapeEntryValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ShapeEntryValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
@ -144,58 +149,36 @@ impl<'ctx> ShapeEntryType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for ShapeEntryType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = ShapeEntryValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let llvm_ndarray_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ndarray_ty) = llvm_ndarray_ty else {
|
||||
return Err(format!(
|
||||
"Expected struct type for `ShapeEntry` type, got {llvm_ndarray_ty}"
|
||||
));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
Self::fields(ctx, llvm_usize),
|
||||
llvm_ndarray_ty,
|
||||
"NDArray",
|
||||
&[],
|
||||
)
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for ShapeEntryType<'ctx> {
|
||||
type StructFields = ShapeEntryStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<ShapeEntryType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -13,11 +13,10 @@ use crate::{
|
||||
types::{
|
||||
structure::{
|
||||
check_struct_type_matches_fields, FieldIndexCounter, StructField, StructFields,
|
||||
StructProxyType,
|
||||
},
|
||||
ProxyType,
|
||||
},
|
||||
values::ndarray::ContiguousNDArrayValue,
|
||||
values::{ndarray::ContiguousNDArrayValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
toplevel::numpy::unpack_ndarray_var_tys,
|
||||
@ -59,6 +58,36 @@ impl<'ctx> ContiguousNDArrayStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a `ndarray` type, returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let llvm_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!(
|
||||
"Expected struct type for `ContiguousNDArray` type, got {llvm_ty}"
|
||||
));
|
||||
};
|
||||
|
||||
let fields = ContiguousNDArrayStructFields::new(ctx, llvm_usize);
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
fields,
|
||||
llvm_ty,
|
||||
"ContiguousNDArray",
|
||||
&[(fields.data.name(), &|ty| {
|
||||
if ty.is_pointer_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected T* for `ContiguousNDArray.data`, got {ty}"))
|
||||
}
|
||||
})],
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`StructFields`] containing all field accessors for this type.
|
||||
#[must_use]
|
||||
fn fields(
|
||||
@ -68,6 +97,13 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
ContiguousNDArrayStructFields::new_typed(item, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`NDArrayType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self) -> ContiguousNDArrayStructFields<'ctx> {
|
||||
Self::fields(self.item, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of an `NDArray`.
|
||||
#[must_use]
|
||||
fn llvm_type(
|
||||
@ -117,24 +153,14 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, llvm_dtype, ctx.get_size_type())
|
||||
}
|
||||
|
||||
/// Creates an [`ContiguousNDArrayType`] from a [`StructType`] representing an `NDArray`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(
|
||||
ty: StructType<'ctx>,
|
||||
item: BasicTypeEnum<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), item, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ContiguousNDArrayType`] from a [`PointerType`] representing an `NDArray`.
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(
|
||||
pub fn from_type(
|
||||
ptr_ty: PointerType<'ctx>,
|
||||
item: BasicTypeEnum<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, item, llvm_usize }
|
||||
}
|
||||
@ -178,28 +204,9 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ContiguousNDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.item,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ContiguousNDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
@ -212,66 +219,36 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for ContiguousNDArrayType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = ContiguousNDArrayValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let llvm_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!(
|
||||
"Expected struct type for `ContiguousNDArray` type, got {llvm_ty}"
|
||||
));
|
||||
};
|
||||
|
||||
let fields = ContiguousNDArrayStructFields::new(ctx, llvm_usize);
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
fields,
|
||||
llvm_ty,
|
||||
"ContiguousNDArray",
|
||||
&[(fields.data.name(), &|ty| {
|
||||
if ty.is_pointer_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected T* for `ContiguousNDArray.data`, got {ty}"))
|
||||
}
|
||||
})],
|
||||
)
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for ContiguousNDArrayType<'ctx> {
|
||||
type StructFields = ContiguousNDArrayStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.item, self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<ContiguousNDArrayType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -10,12 +10,12 @@ use nac3core_derive::StructFields;
|
||||
|
||||
use crate::codegen::{
|
||||
types::{
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields, StructProxyType},
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
ProxyType,
|
||||
},
|
||||
values::{
|
||||
ndarray::{NDIndexValue, RustNDIndex},
|
||||
ArrayLikeIndexer, ArraySliceValue,
|
||||
ArrayLikeIndexer, ArraySliceValue, ProxyValue,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
@ -35,6 +35,25 @@ pub struct NDIndexStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDIndexType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a `ndindex` type, returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let llvm_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!(
|
||||
"Expected struct type for `ContiguousNDArray` type, got {llvm_ty}"
|
||||
));
|
||||
};
|
||||
|
||||
let fields = NDIndexStructFields::new(ctx, llvm_usize);
|
||||
|
||||
check_struct_type_matches_fields(fields, llvm_ty, "NDIndex", &[])
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn fields(
|
||||
ctx: impl AsContextRef<'ctx>,
|
||||
@ -43,6 +62,11 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
NDIndexStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_fields(&self) -> NDIndexStructFields<'ctx> {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
let field_tys =
|
||||
@ -71,13 +95,8 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::is_representable(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, llvm_usize }
|
||||
}
|
||||
@ -148,26 +167,9 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
@ -175,55 +177,36 @@ impl<'ctx> NDIndexType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for NDIndexType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = NDIndexValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let llvm_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!(
|
||||
"Expected struct type for `ContiguousNDArray` type, got {llvm_ty}"
|
||||
));
|
||||
};
|
||||
|
||||
let fields = NDIndexStructFields::new(ctx, llvm_usize);
|
||||
|
||||
check_struct_type_matches_fields(fields, llvm_ty, "NDIndex", &[])
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for NDIndexType<'ctx> {
|
||||
type StructFields = NDIndexStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<NDIndexType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{BasicValue, IntValue, PointerValue, StructValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{BasicValue, IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -9,12 +9,12 @@ use itertools::Itertools;
|
||||
use nac3core_derive::StructFields;
|
||||
|
||||
use super::{
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields, StructProxyType},
|
||||
structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
ProxyType,
|
||||
};
|
||||
use crate::{
|
||||
codegen::{
|
||||
values::{ndarray::NDArrayValue, TypedArrayLikeMutator},
|
||||
values::{ndarray::NDArrayValue, ProxyValue, TypedArrayLikeMutator},
|
||||
{CodeGenContext, CodeGenerator},
|
||||
},
|
||||
toplevel::{helper::extract_ndims, numpy::unpack_ndarray_var_tys},
|
||||
@ -62,6 +62,26 @@ pub struct NDArrayStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDArrayType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a `ndarray` type, returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let llvm_ndarray_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ndarray_ty) = llvm_ndarray_ty else {
|
||||
return Err(format!("Expected struct type for `NDArray` type, got {llvm_ndarray_ty}"));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
Self::fields(ctx, llvm_usize),
|
||||
llvm_ndarray_ty,
|
||||
"NDArray",
|
||||
&[],
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`StructFields`] containing all field accessors for this type.
|
||||
#[must_use]
|
||||
fn fields(
|
||||
@ -71,6 +91,13 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
NDArrayStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`NDArrayType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, ctx: impl AsContextRef<'ctx>) -> NDArrayStructFields<'ctx> {
|
||||
Self::fields(ctx, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of an `NDArray`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
@ -176,26 +203,15 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, llvm_dtype, ndims, ctx.get_size_type())
|
||||
}
|
||||
|
||||
/// Creates an [`NDArrayType`] from a [`StructType`] representing an `NDArray`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(
|
||||
ty: StructType<'ctx>,
|
||||
dtype: BasicTypeEnum<'ctx>,
|
||||
ndims: u64,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), dtype, ndims, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`NDArrayType`] from a [`PointerType`] representing an `NDArray`.
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(
|
||||
pub fn from_type(
|
||||
ptr_ty: PointerType<'ctx>,
|
||||
dtype: BasicTypeEnum<'ctx>,
|
||||
ndims: u64,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
NDArrayType { ty: ptr_ty, dtype, ndims, llvm_usize }
|
||||
}
|
||||
@ -415,29 +431,9 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`NDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.dtype,
|
||||
self.ndims,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`NDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
@ -451,56 +447,36 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = NDArrayValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let llvm_ndarray_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ndarray_ty) = llvm_ndarray_ty else {
|
||||
return Err(format!("Expected struct type for `NDArray` type, got {llvm_ndarray_ty}"));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
Self::fields(ctx, llvm_usize),
|
||||
llvm_ndarray_ty,
|
||||
"NDArray",
|
||||
&[],
|
||||
)
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for NDArrayType<'ctx> {
|
||||
type StructFields = NDArrayStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<NDArrayType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -11,9 +11,7 @@ use nac3core_derive::StructFields;
|
||||
use super::ProxyType;
|
||||
use crate::codegen::{
|
||||
irrt,
|
||||
types::structure::{
|
||||
check_struct_type_matches_fields, StructField, StructFields, StructProxyType,
|
||||
},
|
||||
types::structure::{check_struct_type_matches_fields, StructField, StructFields},
|
||||
values::{
|
||||
ndarray::{NDArrayValue, NDIterValue},
|
||||
ArrayLikeValue, ArraySliceValue, ProxyValue, TypedArrayLikeAdapter,
|
||||
@ -46,12 +44,39 @@ pub struct NDIterStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDIterType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a `nditer` type, returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let llvm_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ndarray_ty) = llvm_ty else {
|
||||
return Err(format!("Expected struct type for `NDIter` type, got {llvm_ty}"));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
Self::fields(ctx, llvm_usize),
|
||||
llvm_ndarray_ty,
|
||||
"NDIter",
|
||||
&[],
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`StructFields`] containing all field accessors for this type.
|
||||
#[must_use]
|
||||
fn fields(ctx: impl AsContextRef<'ctx>, llvm_usize: IntType<'ctx>) -> NDIterStructFields<'ctx> {
|
||||
NDIterStructFields::new(ctx, llvm_usize)
|
||||
}
|
||||
|
||||
/// See [`NDIterType::fields`].
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self, ctx: impl AsContextRef<'ctx>) -> NDIterStructFields<'ctx> {
|
||||
Self::fields(ctx, self.llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of an `NDIter`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
@ -82,16 +107,10 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an [`NDIterType`] from a [`StructType`] representing an `NDIter`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`NDIterType`] from a [`PointerType`] representing an `NDIter`.
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::is_representable(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, llvm_usize }
|
||||
}
|
||||
@ -160,8 +179,7 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
let indices =
|
||||
TypedArrayLikeAdapter::from(indices, |_, _, v| v.into_int_value(), |_, _, v| v.into());
|
||||
|
||||
let nditer =
|
||||
self.map_pointer_value(nditer, ndarray, indices.as_slice_value(ctx, generator), None);
|
||||
let nditer = self.map_value(nditer, ndarray, indices.as_slice_value(ctx, generator), None);
|
||||
|
||||
irrt::ndarray::call_nac3_nditer_initialize(generator, ctx, nditer, ndarray, &indices);
|
||||
|
||||
@ -169,30 +187,9 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
parent: NDArrayValue<'ctx>,
|
||||
indices: ArraySliceValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
parent,
|
||||
indices,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
parent: NDArrayValue<'ctx>,
|
||||
indices: ArraySliceValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
@ -208,56 +205,36 @@ impl<'ctx> NDIterType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for NDIterType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = NDIterValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let llvm_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ndarray_ty) = llvm_ty else {
|
||||
return Err(format!("Expected struct type for `NDIter` type, got {llvm_ty}"));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
Self::fields(ctx, llvm_usize),
|
||||
llvm_ndarray_ty,
|
||||
"NDIter",
|
||||
&[],
|
||||
)
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for NDIterType<'ctx> {
|
||||
type StructFields = NDIterStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
Self::fields(self.ty.get_context(), self.llvm_usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<NDIterType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -1,167 +1,25 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{AnyTypeEnum, ArrayType, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::{ArrayValue, PointerValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
AddressSpace,
|
||||
};
|
||||
|
||||
use super::ProxyType;
|
||||
use crate::{
|
||||
codegen::{
|
||||
values::RangeValue,
|
||||
{CodeGenContext, CodeGenerator},
|
||||
},
|
||||
typecheck::typedef::{Type, TypeEnum},
|
||||
use crate::codegen::{
|
||||
values::{ProxyValue, RangeValue},
|
||||
{CodeGenContext, CodeGenerator},
|
||||
};
|
||||
|
||||
/// Proxy type for a `range` type in LLVM.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct RangeType<'ctx> {
|
||||
ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
}
|
||||
|
||||
impl<'ctx> RangeType<'ctx> {
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `Range`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context) -> PointerType<'ctx> {
|
||||
// typedef int32_t Range[3];
|
||||
let llvm_i32 = ctx.i32_type();
|
||||
llvm_i32.array_type(3).ptr_type(AddressSpace::default())
|
||||
}
|
||||
|
||||
fn new_impl(ctx: &'ctx Context, llvm_usize: IntType<'ctx>) -> Self {
|
||||
let llvm_range = Self::llvm_type(ctx);
|
||||
|
||||
RangeType { ty: llvm_range, llvm_usize }
|
||||
}
|
||||
|
||||
/// Creates an instance of [`RangeType`].
|
||||
#[must_use]
|
||||
pub fn new(ctx: &CodeGenContext<'ctx, '_>) -> Self {
|
||||
Self::new_impl(ctx.ctx, ctx.get_size_type())
|
||||
}
|
||||
|
||||
/// Creates an instance of [`RangeType`].
|
||||
#[must_use]
|
||||
pub fn new_with_generator<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
) -> Self {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an [`RangeType`] from a [unifier type][Type].
|
||||
#[must_use]
|
||||
pub fn from_unifier_type(ctx: &mut CodeGenContext<'ctx, '_>, ty: Type) -> Self {
|
||||
// Check unifier type
|
||||
assert!(
|
||||
matches!(&*ctx.unifier.get_ty_immutable(ty), TypeEnum::TObj { obj_id, .. } if *obj_id == ctx.primitives.range.obj_id(&ctx.unifier).unwrap())
|
||||
);
|
||||
|
||||
Self::new(ctx)
|
||||
}
|
||||
|
||||
/// Creates an [`RangeType`] from a [`ArrayType`].
|
||||
#[must_use]
|
||||
pub fn from_array_type(arr_ty: ArrayType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_pointer_type(arr_ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`RangeType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, llvm_usize).is_ok());
|
||||
|
||||
RangeType { ty: ptr_ty, llvm_usize }
|
||||
}
|
||||
|
||||
/// Returns the type of all fields of this `range` type.
|
||||
#[must_use]
|
||||
pub fn value_type(&self) -> IntType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_array_type().get_element_type().into_int_type()
|
||||
}
|
||||
|
||||
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
|
||||
///
|
||||
/// See [`ProxyType::raw_alloca`].
|
||||
#[must_use]
|
||||
pub fn alloca<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
self.raw_alloca(ctx, name),
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
|
||||
///
|
||||
/// See [`ProxyType::raw_alloca_var`].
|
||||
#[must_use]
|
||||
pub fn alloca_var<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
self.raw_alloca_var(generator, ctx, name),
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`RangeValue`].
|
||||
#[must_use]
|
||||
pub fn map_array_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: ArrayValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_array_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`RangeValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = RangeValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, _: IntType<'ctx>) -> Result<(), String> {
|
||||
let llvm_range_ty = ty.get_element_type();
|
||||
/// Checks whether `llvm_ty` represents a `range` type, returning [Err] if it does not.
|
||||
pub fn is_representable(llvm_ty: PointerType<'ctx>) -> Result<(), String> {
|
||||
let llvm_range_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::ArrayType(llvm_range_ty) = llvm_range_ty else {
|
||||
return Err(format!("Expected array type for `range` type, got {llvm_range_ty}"));
|
||||
};
|
||||
@ -188,17 +46,106 @@ impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `Range`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context) -> PointerType<'ctx> {
|
||||
// typedef int32_t Range[3];
|
||||
let llvm_i32 = ctx.i32_type();
|
||||
llvm_i32.array_type(3).ptr_type(AddressSpace::default())
|
||||
}
|
||||
|
||||
/// Creates an instance of [`RangeType`].
|
||||
#[must_use]
|
||||
pub fn new(ctx: &'ctx Context) -> Self {
|
||||
let llvm_range = Self::llvm_type(ctx);
|
||||
|
||||
RangeType::from_type(llvm_range)
|
||||
}
|
||||
|
||||
/// Creates an [`RangeType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_type(ptr_ty: PointerType<'ctx>) -> Self {
|
||||
debug_assert!(Self::is_representable(ptr_ty).is_ok());
|
||||
|
||||
RangeType { ty: ptr_ty }
|
||||
}
|
||||
|
||||
/// Returns the type of all fields of this `range` type.
|
||||
#[must_use]
|
||||
pub fn value_type(&self) -> IntType<'ctx> {
|
||||
self.as_base_type().get_element_type().into_array_type().get_element_type().into_int_type()
|
||||
}
|
||||
|
||||
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
|
||||
///
|
||||
/// See [`ProxyType::raw_alloca`].
|
||||
#[must_use]
|
||||
pub fn alloca<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(self.raw_alloca(ctx, name), name)
|
||||
}
|
||||
|
||||
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
|
||||
///
|
||||
/// See [`ProxyType::raw_alloca_var`].
|
||||
#[must_use]
|
||||
pub fn alloca_var<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
self.raw_alloca_var(generator, ctx, name),
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`RangeValue`].
|
||||
#[must_use]
|
||||
pub fn map_value(
|
||||
&self,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = RangeValue<'ctx>;
|
||||
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
_: &G,
|
||||
_: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty)
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<RangeType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -2,55 +2,13 @@ use std::marker::PhantomData;
|
||||
|
||||
use inkwell::{
|
||||
context::AsContextRef,
|
||||
types::{BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{AggregateValueEnum, BasicValue, BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
AddressSpace,
|
||||
types::{BasicTypeEnum, IntType, StructType},
|
||||
values::{BasicValue, BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::ProxyType;
|
||||
use crate::codegen::CodeGenContext;
|
||||
|
||||
/// A LLVM type that is used to represent a corresponding structure-like type in NAC3.
|
||||
pub trait StructProxyType<'ctx>: ProxyType<'ctx, Base = PointerType<'ctx>> {
|
||||
/// The concrete type of [`StructFields`].
|
||||
type StructFields: StructFields<'ctx>;
|
||||
|
||||
/// Whether this [`StructProxyType`] has the same LLVM type representation as
|
||||
/// [`llvm_ty`][StructType].
|
||||
fn has_same_struct_repr(
|
||||
llvm_ty: StructType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
Self::has_same_pointer_repr(llvm_ty.ptr_type(AddressSpace::default()), llvm_usize)
|
||||
}
|
||||
|
||||
/// Whether this [`StructProxyType`] has the same LLVM type representation as
|
||||
/// [`llvm_ty`][PointerType].
|
||||
fn has_same_pointer_repr(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
Self::has_same_repr(llvm_ty, llvm_usize)
|
||||
}
|
||||
|
||||
/// Returns the fields present in this [`StructProxyType`].
|
||||
#[must_use]
|
||||
fn get_fields(&self) -> Self::StructFields;
|
||||
|
||||
/// Returns the [`StructType`].
|
||||
#[must_use]
|
||||
fn get_struct_type(&self) -> StructType<'ctx> {
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
/// Returns the [`PointerType`] representing this type.
|
||||
#[must_use]
|
||||
fn get_pointer_type(&self) -> PointerType<'ctx> {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait indicating that the structure is a field-wise representation of an LLVM structure.
|
||||
///
|
||||
/// # Usage
|
||||
@ -203,38 +161,17 @@ where
|
||||
|
||||
/// Gets the value of this field for a given `obj`.
|
||||
#[must_use]
|
||||
pub fn extract_value(&self, ctx: &CodeGenContext<'ctx, '_>, obj: StructValue<'ctx>) -> Value {
|
||||
Value::try_from(
|
||||
ctx.builder
|
||||
.build_extract_value(
|
||||
obj,
|
||||
self.index,
|
||||
&format!("{}.{}", obj.get_name().to_str().unwrap(), self.name),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
pub fn get_from_value(&self, obj: StructValue<'ctx>) -> Value {
|
||||
obj.get_field_at_index(self.index).and_then(|value| Value::try_from(value).ok()).unwrap()
|
||||
}
|
||||
|
||||
/// Sets the value of this field for a given `obj`.
|
||||
#[must_use]
|
||||
pub fn insert_value(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
obj: StructValue<'ctx>,
|
||||
value: Value,
|
||||
) -> StructValue<'ctx> {
|
||||
let obj_name = obj.get_name().to_str().unwrap();
|
||||
let new_obj_name = if obj_name.chars().all(char::is_numeric) { "" } else { obj_name };
|
||||
|
||||
ctx.builder
|
||||
.build_insert_value(obj, value, self.index, new_obj_name)
|
||||
.map(AggregateValueEnum::into_struct_value)
|
||||
.unwrap()
|
||||
pub fn set_for_value(&self, obj: StructValue<'ctx>, value: Value) {
|
||||
obj.set_field_at_index(self.index, value);
|
||||
}
|
||||
|
||||
/// Loads the value of this field for a pointer-to-structure.
|
||||
pub fn load(
|
||||
/// Gets the value of this field for a pointer-to-structure.
|
||||
pub fn get(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pobj: PointerValue<'ctx>,
|
||||
@ -250,8 +187,8 @@ where
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Stores the value of this field for a pointer-to-structure.
|
||||
pub fn store(
|
||||
/// Sets the value of this field for a pointer-to-structure.
|
||||
pub fn set(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
pobj: PointerValue<'ctx>,
|
||||
|
@ -1,13 +1,16 @@
|
||||
use inkwell::{
|
||||
context::Context,
|
||||
types::{BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{BasicValueEnum, PointerValue, StructValue},
|
||||
types::{BasicType, BasicTypeEnum, IntType, StructType},
|
||||
values::BasicValueEnum,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::ProxyType;
|
||||
use crate::{
|
||||
codegen::{values::TupleValue, CodeGenContext, CodeGenerator},
|
||||
codegen::{
|
||||
values::{ProxyValue, TupleValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::{Type, TypeEnum},
|
||||
};
|
||||
|
||||
@ -18,6 +21,11 @@ pub struct TupleType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> TupleType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents any tuple type, returning [Err] if it does not.
|
||||
pub fn is_representable(_value: StructType<'ctx>) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a tuple.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, tys: &[BasicTypeEnum<'ctx>]) -> StructType<'ctx> {
|
||||
@ -74,18 +82,12 @@ impl<'ctx> TupleType<'ctx> {
|
||||
|
||||
/// Creates an [`TupleType`] from a [`StructType`].
|
||||
#[must_use]
|
||||
pub fn from_struct_type(struct_ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::has_same_repr(struct_ty, llvm_usize).is_ok());
|
||||
pub fn from_type(struct_ty: StructType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
debug_assert!(Self::is_representable(struct_ty).is_ok());
|
||||
|
||||
TupleType { ty: struct_ty, llvm_usize }
|
||||
}
|
||||
|
||||
/// Creates an [`TupleType`] from a [`PointerType`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(ptr_ty: PointerType<'ctx>, llvm_usize: IntType<'ctx>) -> Self {
|
||||
Self::from_struct_type(ptr_ty.get_element_type().into_struct_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Returns the number of elements present in this [`TupleType`].
|
||||
#[must_use]
|
||||
pub fn num_elements(&self) -> u32 {
|
||||
@ -120,10 +122,7 @@ impl<'ctx> TupleType<'ctx> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
self.map_struct_value(
|
||||
Self::llvm_type(ctx.ctx, &self.ty.get_field_types()).const_zero(),
|
||||
name,
|
||||
)
|
||||
self.map_value(Self::llvm_type(ctx.ctx, &self.ty.get_field_types()).const_zero(), name)
|
||||
}
|
||||
|
||||
/// Constructs a [`TupleValue`] from `objects`. The resulting tuple preserves the order of
|
||||
@ -153,44 +152,37 @@ impl<'ctx> TupleType<'ctx> {
|
||||
|
||||
/// Converts an existing value into a [`ListValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
value: StructValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(value, self.llvm_usize, name)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`TupleValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
value: PointerValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(ctx, value, self.llvm_usize, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for TupleType<'ctx> {
|
||||
type ABI = StructType<'ctx>;
|
||||
type Base = StructType<'ctx>;
|
||||
type Value = TupleValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::StructType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected struct type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(_: Self::Base, _: IntType<'ctx>) -> Result<(), String> {
|
||||
Ok(())
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
_generator: &G,
|
||||
_ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty)
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
@ -200,10 +192,6 @@ impl<'ctx> ProxyType<'ctx> for TupleType<'ctx> {
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<TupleType<'ctx>> for StructType<'ctx> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use inkwell::{
|
||||
context::{AsContextRef, Context, ContextRef},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||
values::IntValue,
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -12,11 +12,10 @@ use crate::codegen::{
|
||||
types::{
|
||||
structure::{
|
||||
check_struct_type_matches_fields, FieldIndexCounter, StructField, StructFields,
|
||||
StructProxyType,
|
||||
},
|
||||
ProxyType,
|
||||
},
|
||||
values::utils::SliceValue,
|
||||
values::{utils::SliceValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -28,7 +27,7 @@ pub struct SliceType<'ctx> {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, StructFields)]
|
||||
pub struct SliceStructFields<'ctx> {
|
||||
pub struct SliceFields<'ctx> {
|
||||
#[value_type(bool_type())]
|
||||
pub start_defined: StructField<'ctx, IntValue<'ctx>>,
|
||||
#[value_type(usize)]
|
||||
@ -43,14 +42,14 @@ pub struct SliceStructFields<'ctx> {
|
||||
pub step: StructField<'ctx, IntValue<'ctx>>,
|
||||
}
|
||||
|
||||
impl<'ctx> SliceStructFields<'ctx> {
|
||||
/// Creates a new instance of [`SliceStructFields`] with a custom integer type for its range values.
|
||||
impl<'ctx> SliceFields<'ctx> {
|
||||
/// Creates a new instance of [`SliceFields`] with a custom integer type for its range values.
|
||||
#[must_use]
|
||||
pub fn new_sized(ctx: &impl AsContextRef<'ctx>, int_ty: IntType<'ctx>) -> Self {
|
||||
let ctx = unsafe { ContextRef::new(ctx.as_ctx_ref()) };
|
||||
let mut counter = FieldIndexCounter::default();
|
||||
|
||||
SliceStructFields {
|
||||
SliceFields {
|
||||
start_defined: StructField::create(&mut counter, "start_defined", ctx.bool_type()),
|
||||
start: StructField::create(&mut counter, "start", int_ty),
|
||||
stop_defined: StructField::create(&mut counter, "stop_defined", ctx.bool_type()),
|
||||
@ -62,10 +61,60 @@ impl<'ctx> SliceStructFields<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> SliceType<'ctx> {
|
||||
/// Checks whether `llvm_ty` represents a `slice` type, returning [Err] if it does not.
|
||||
pub fn is_representable(
|
||||
llvm_ty: PointerType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
let ctx = llvm_ty.get_context();
|
||||
|
||||
let fields = SliceFields::new(ctx, llvm_usize);
|
||||
|
||||
let llvm_ty = llvm_ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!("Expected struct type for `Slice` type, got {llvm_ty}"));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
fields,
|
||||
llvm_ty,
|
||||
"Slice",
|
||||
&[
|
||||
(fields.start.name(), &|ty| {
|
||||
if ty.is_int_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected int type for `Slice.start`, got {ty}"))
|
||||
}
|
||||
}),
|
||||
(fields.stop.name(), &|ty| {
|
||||
if ty.is_int_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected int type for `Slice.stop`, got {ty}"))
|
||||
}
|
||||
}),
|
||||
(fields.step.name(), &|ty| {
|
||||
if ty.is_int_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected int type for `Slice.step`, got {ty}"))
|
||||
}
|
||||
}),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Move this into e.g. StructProxyType
|
||||
#[must_use]
|
||||
pub fn get_fields(&self) -> SliceFields<'ctx> {
|
||||
SliceFields::new_sized(&self.int_ty.get_context(), self.int_ty)
|
||||
}
|
||||
|
||||
/// Creates an LLVM type corresponding to the expected structure of a `Slice`.
|
||||
#[must_use]
|
||||
fn llvm_type(ctx: &'ctx Context, int_ty: IntType<'ctx>) -> PointerType<'ctx> {
|
||||
let field_tys = SliceStructFields::new_sized(&int_ty.get_context(), int_ty)
|
||||
let field_tys = SliceFields::new_sized(&int_ty.get_context(), int_ty)
|
||||
.into_iter()
|
||||
.map(|field| field.1)
|
||||
.collect_vec();
|
||||
@ -85,16 +134,6 @@ impl<'ctx> SliceType<'ctx> {
|
||||
Self::new_impl(ctx.ctx, int_ty, ctx.get_size_type())
|
||||
}
|
||||
|
||||
/// Creates an instance of [`SliceType`] with `int_ty` as its backing integer type.
|
||||
#[must_use]
|
||||
pub fn new_with_generator<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
int_ty: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::new_impl(ctx, int_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an instance of [`SliceType`] with `usize` as its backing integer type.
|
||||
#[must_use]
|
||||
pub fn new_usize(ctx: &CodeGenContext<'ctx, '_>) -> Self {
|
||||
@ -110,24 +149,14 @@ impl<'ctx> SliceType<'ctx> {
|
||||
Self::new_impl(ctx, generator.get_size_type(ctx), generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
/// Creates an [`SliceType`] from a [`StructType`] representing a `slice`.
|
||||
#[must_use]
|
||||
pub fn from_struct_type(
|
||||
ty: StructType<'ctx>,
|
||||
int_ty: IntType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
Self::from_pointer_type(ty.ptr_type(AddressSpace::default()), int_ty, llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`SliceType`] from a [`PointerType`] representing a `slice`.
|
||||
#[must_use]
|
||||
pub fn from_pointer_type(
|
||||
pub fn from_type(
|
||||
ptr_ty: PointerType<'ctx>,
|
||||
int_ty: IntType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::has_same_repr(ptr_ty, int_ty).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr_ty, int_ty).is_ok());
|
||||
|
||||
Self { ty: ptr_ty, int_ty, llvm_usize }
|
||||
}
|
||||
@ -172,30 +201,11 @@ impl<'ctx> SliceType<'ctx> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`SliceValue`].
|
||||
#[must_use]
|
||||
pub fn map_struct_value<G: CodeGenerator + ?Sized>(
|
||||
&self,
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
value: StructValue<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_struct_value(
|
||||
generator,
|
||||
ctx,
|
||||
value,
|
||||
self.int_ty,
|
||||
self.llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts an existing value into a [`ContiguousNDArrayValue`].
|
||||
#[must_use]
|
||||
pub fn map_pointer_value(
|
||||
pub fn map_value(
|
||||
&self,
|
||||
value: PointerValue<'ctx>,
|
||||
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||
name: Option<&'ctx str>,
|
||||
) -> <Self as ProxyType<'ctx>>::Value {
|
||||
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||
@ -208,80 +218,36 @@ impl<'ctx> SliceType<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyType<'ctx> for SliceType<'ctx> {
|
||||
type ABI = PointerType<'ctx>;
|
||||
type Base = PointerType<'ctx>;
|
||||
type Value = SliceValue<'ctx>;
|
||||
|
||||
fn is_representable(
|
||||
fn is_type<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: impl BasicType<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
if let BasicTypeEnum::PointerType(ty) = llvm_ty.as_basic_type_enum() {
|
||||
Self::has_same_repr(ty, llvm_usize)
|
||||
<Self as ProxyType<'ctx>>::is_representable(generator, ctx, ty)
|
||||
} else {
|
||||
Err(format!("Expected pointer type, got {llvm_ty:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_same_repr(ty: Self::Base, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
let ctx = ty.get_context();
|
||||
|
||||
let fields = SliceStructFields::new(ctx, llvm_usize);
|
||||
|
||||
let llvm_ty = ty.get_element_type();
|
||||
let AnyTypeEnum::StructType(llvm_ty) = llvm_ty else {
|
||||
return Err(format!("Expected struct type for `Slice` type, got {llvm_ty}"));
|
||||
};
|
||||
|
||||
check_struct_type_matches_fields(
|
||||
fields,
|
||||
llvm_ty,
|
||||
"Slice",
|
||||
&[
|
||||
(fields.start.name(), &|ty| {
|
||||
if ty.is_int_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected int type for `Slice.start`, got {ty}"))
|
||||
}
|
||||
}),
|
||||
(fields.stop.name(), &|ty| {
|
||||
if ty.is_int_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected int type for `Slice.stop`, got {ty}"))
|
||||
}
|
||||
}),
|
||||
(fields.step.name(), &|ty| {
|
||||
if ty.is_int_type() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Expected int type for `Slice.step`, got {ty}"))
|
||||
}
|
||||
}),
|
||||
],
|
||||
)
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
llvm_ty: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||
}
|
||||
|
||||
fn alloca_type(&self) -> impl BasicType<'ctx> {
|
||||
self.as_abi_type().get_element_type().into_struct_type()
|
||||
self.as_base_type().get_element_type().into_struct_type()
|
||||
}
|
||||
|
||||
fn as_base_type(&self) -> Self::Base {
|
||||
self.ty
|
||||
}
|
||||
|
||||
fn as_abi_type(&self) -> Self::ABI {
|
||||
self.as_base_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyType<'ctx> for SliceType<'ctx> {
|
||||
type StructFields = SliceStructFields<'ctx>;
|
||||
|
||||
fn get_fields(&self) -> Self::StructFields {
|
||||
SliceStructFields::new_sized(&self.ty.get_context(), self.int_ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<SliceType<'ctx>> for PointerType<'ctx> {
|
||||
|
@ -1,18 +1,14 @@
|
||||
use inkwell::{
|
||||
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType},
|
||||
values::{BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
values::{BasicValueEnum, IntValue, PointerValue},
|
||||
AddressSpace, IntPredicate,
|
||||
};
|
||||
|
||||
use super::{
|
||||
structure::StructProxyValue, ArrayLikeIndexer, ArrayLikeValue, ProxyValue,
|
||||
UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
||||
ArrayLikeIndexer, ArrayLikeValue, ProxyValue, UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
||||
};
|
||||
use crate::codegen::{
|
||||
types::{
|
||||
structure::{StructField, StructProxyType},
|
||||
ListType, ProxyType,
|
||||
},
|
||||
types::{structure::StructField, ListType, ProxyType},
|
||||
{CodeGenContext, CodeGenerator},
|
||||
};
|
||||
|
||||
@ -25,24 +21,13 @@ pub struct ListValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ListValue<'ctx> {
|
||||
/// Creates an [`ListValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
/// Checks whether `value` is an instance of `list`, returning [Err] if `value` is not an
|
||||
/// instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
ListType::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ListValue`] from a [`PointerValue`].
|
||||
@ -52,18 +37,24 @@ impl<'ctx> ListValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
ListValue { value: ptr, llvm_usize, name }
|
||||
}
|
||||
|
||||
fn items_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().items
|
||||
fn items_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(&ctx.ctx).items
|
||||
}
|
||||
|
||||
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
||||
/// on the field.
|
||||
fn pptr_to_data(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.items_field(ctx).ptr_by_gep(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
/// Stores the array of data elements `data` into this instance.
|
||||
fn store_data(&self, ctx: &CodeGenContext<'ctx, '_>, data: PointerValue<'ctx>) {
|
||||
self.items_field().store(ctx, self.value, data, self.name);
|
||||
self.items_field(ctx).set(ctx, self.value, data, self.name);
|
||||
}
|
||||
|
||||
/// Convenience method for creating a new array storing data elements with the given element
|
||||
@ -101,15 +92,15 @@ impl<'ctx> ListValue<'ctx> {
|
||||
ListDataProxy(self)
|
||||
}
|
||||
|
||||
fn len_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().len
|
||||
fn len_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(&ctx.ctx).len
|
||||
}
|
||||
|
||||
/// Stores the `size` of this `list` into this instance.
|
||||
pub fn store_size(&self, ctx: &CodeGenContext<'ctx, '_>, size: IntValue<'ctx>) {
|
||||
debug_assert_eq!(size.get_type(), ctx.get_size_type());
|
||||
|
||||
self.len_field().store(ctx, self.value, size, self.name);
|
||||
self.len_field(ctx).set(ctx, self.value, size, self.name);
|
||||
}
|
||||
|
||||
/// Returns the size of this `list` as a value.
|
||||
@ -118,7 +109,7 @@ impl<'ctx> ListValue<'ctx> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> IntValue<'ctx> {
|
||||
self.len_field().load(ctx, self.value, name)
|
||||
self.len_field(ctx).get(ctx, self.value, name)
|
||||
}
|
||||
|
||||
/// Returns an instance of [`ListValue`] with the `items` pointer cast to `i8*`.
|
||||
@ -128,7 +119,7 @@ impl<'ctx> ListValue<'ctx> {
|
||||
let llvm_list_i8 = <Self as ProxyValue>::Type::new(ctx, &llvm_i8);
|
||||
|
||||
Self::from_pointer_value(
|
||||
ctx.builder.build_pointer_cast(self.value, llvm_list_i8.as_abi_type(), "").unwrap(),
|
||||
ctx.builder.build_pointer_cast(self.value, llvm_list_i8.as_base_type(), "").unwrap(),
|
||||
self.llvm_usize,
|
||||
self.name,
|
||||
)
|
||||
@ -136,25 +127,18 @@ impl<'ctx> ListValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for ListValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = ListType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
ListType::from_pointer_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
ListType::from_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for ListValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<ListValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: ListValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
@ -179,7 +163,12 @@ impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx, '_> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
_: &G,
|
||||
) -> PointerValue<'ctx> {
|
||||
self.0.items_field().load(ctx, self.0.value, self.0.name)
|
||||
let var_name = self.0.name.map(|v| format!("{v}.data")).unwrap_or_default();
|
||||
|
||||
ctx.builder
|
||||
.build_load(self.0.pptr_to_data(ctx), var_name.as_str())
|
||||
.map(BasicValueEnum::into_pointer_value)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn size<G: CodeGenerator + ?Sized>(
|
||||
|
@ -1,6 +1,7 @@
|
||||
use inkwell::{types::IntType, values::BasicValue};
|
||||
use inkwell::{context::Context, values::BasicValue};
|
||||
|
||||
use super::{types::ProxyType, CodeGenContext};
|
||||
use super::types::ProxyType;
|
||||
use crate::codegen::CodeGenerator;
|
||||
pub use array::*;
|
||||
pub use list::*;
|
||||
pub use range::*;
|
||||
@ -10,24 +11,34 @@ mod array;
|
||||
mod list;
|
||||
pub mod ndarray;
|
||||
mod range;
|
||||
pub mod structure;
|
||||
mod tuple;
|
||||
pub mod utils;
|
||||
|
||||
/// A LLVM type that is used to represent a non-primitive value in NAC3.
|
||||
pub trait ProxyValue<'ctx>: Into<Self::Base> {
|
||||
/// The ABI type of LLVM values represented by this instance.
|
||||
type ABI: BasicValue<'ctx>;
|
||||
|
||||
/// The type of LLVM values represented by this instance.
|
||||
/// The type of LLVM values represented by this instance. This is usually the
|
||||
/// [LLVM pointer type][PointerValue].
|
||||
type Base: BasicValue<'ctx>;
|
||||
|
||||
/// The type of this value.
|
||||
type Type: ProxyType<'ctx, Value = Self>;
|
||||
|
||||
/// Checks whether `value` can be represented by this [`ProxyValue`].
|
||||
fn is_instance(value: impl BasicValue<'ctx>, llvm_usize: IntType<'ctx>) -> Result<(), String> {
|
||||
Self::Type::is_representable(value.as_basic_value_enum().get_type(), llvm_usize)
|
||||
fn is_instance<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
value: impl BasicValue<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
Self::Type::is_type(generator, ctx, value.as_basic_value_enum().get_type())
|
||||
}
|
||||
|
||||
/// Checks whether `value` can be represented by this [`ProxyValue`].
|
||||
fn is_representable<G: CodeGenerator + ?Sized>(
|
||||
generator: &G,
|
||||
ctx: &'ctx Context,
|
||||
value: Self::Base,
|
||||
) -> Result<(), String> {
|
||||
Self::is_instance(generator, ctx, value.as_basic_value_enum())
|
||||
}
|
||||
|
||||
/// Returns the [type][ProxyType] of this value.
|
||||
@ -35,10 +46,4 @@ pub trait ProxyValue<'ctx>: Into<Self::Base> {
|
||||
|
||||
/// Returns the [base value][Self::Base] of this proxy.
|
||||
fn as_base_value(&self) -> Self::Base;
|
||||
|
||||
/// Returns this proxy as its ABI value, i.e. the expected value representation if a value
|
||||
/// represented by this [`ProxyValue`] is being passed into or returned from a function.
|
||||
///
|
||||
/// See [`CodeGenContext::get_llvm_abi_type`].
|
||||
fn as_abi_value(&self, ctx: &CodeGenContext<'ctx, '_>) -> Self::ABI;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
values::{IntValue, PointerValue},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
@ -8,13 +8,12 @@ use crate::codegen::{
|
||||
irrt,
|
||||
types::{
|
||||
ndarray::{NDArrayType, ShapeEntryType},
|
||||
structure::{StructField, StructProxyType},
|
||||
structure::StructField,
|
||||
ProxyType,
|
||||
},
|
||||
values::{
|
||||
ndarray::NDArrayValue, structure::StructProxyValue, ArrayLikeIndexer, ArrayLikeValue,
|
||||
ArraySliceValue, ProxyValue, TypedArrayLikeAccessor, TypedArrayLikeAdapter,
|
||||
TypedArrayLikeMutator,
|
||||
ndarray::NDArrayValue, ArrayLikeIndexer, ArrayLikeValue, ArraySliceValue, ProxyValue,
|
||||
TypedArrayLikeAccessor, TypedArrayLikeAdapter, TypedArrayLikeMutator,
|
||||
},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
@ -27,24 +26,13 @@ pub struct ShapeEntryValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ShapeEntryValue<'ctx> {
|
||||
/// Creates an [`ShapeEntryValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
/// Checks whether `value` is an instance of `ShapeEntry`, returning [Err] if `value` is
|
||||
/// not an instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
<Self as ProxyValue<'ctx>>::Type::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ShapeEntryValue`] from a [`PointerValue`].
|
||||
@ -54,50 +42,43 @@ impl<'ctx> ShapeEntryValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
Self { value: ptr, llvm_usize, name }
|
||||
}
|
||||
|
||||
fn ndims_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().ndims
|
||||
self.get_type().get_fields(self.value.get_type().get_context()).ndims
|
||||
}
|
||||
|
||||
/// Stores the number of dimensions into this value.
|
||||
pub fn store_ndims(&self, ctx: &CodeGenContext<'ctx, '_>, value: IntValue<'ctx>) {
|
||||
self.ndims_field().store(ctx, self.value, value, self.name);
|
||||
self.ndims_field().set(ctx, self.value, value, self.name);
|
||||
}
|
||||
|
||||
fn shape_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().shape
|
||||
self.get_type().get_fields(self.value.get_type().get_context()).shape
|
||||
}
|
||||
|
||||
/// Stores the shape into this value.
|
||||
pub fn store_shape(&self, ctx: &CodeGenContext<'ctx, '_>, value: PointerValue<'ctx>) {
|
||||
self.shape_field().store(ctx, self.value, value, self.name);
|
||||
self.shape_field().set(ctx, self.value, value, self.name);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for ShapeEntryValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = ShapeEntryType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
Self::Type::from_pointer_type(self.value.get_type(), self.llvm_usize)
|
||||
Self::Type::from_type(self.value.get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for ShapeEntryValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<ShapeEntryValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: ShapeEntryValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
@ -186,7 +167,7 @@ fn broadcast_shapes<'ctx, G, Shape>(
|
||||
None,
|
||||
)
|
||||
};
|
||||
let shape_entry = llvm_shape_ty.map_pointer_value(pshape_entry, None);
|
||||
let shape_entry = llvm_shape_ty.map_value(pshape_entry, None);
|
||||
|
||||
let in_ndims = llvm_usize.const_int(*in_ndims, false);
|
||||
shape_entry.store_ndims(ctx, in_ndims);
|
||||
|
@ -1,17 +1,16 @@
|
||||
use inkwell::{
|
||||
types::{BasicType, BasicTypeEnum, IntType},
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
|
||||
use super::NDArrayValue;
|
||||
use super::{ArrayLikeValue, NDArrayValue, ProxyValue};
|
||||
use crate::codegen::{
|
||||
stmt::gen_if_callback,
|
||||
types::{
|
||||
ndarray::{ContiguousNDArrayType, NDArrayType},
|
||||
structure::{StructField, StructProxyType},
|
||||
structure::StructField,
|
||||
},
|
||||
values::{structure::StructProxyValue, ArrayLikeValue, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -24,25 +23,13 @@ pub struct ContiguousNDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ContiguousNDArrayValue<'ctx> {
|
||||
/// Creates an [`ContiguousNDArrayValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
dtype: BasicTypeEnum<'ctx>,
|
||||
/// Checks whether `value` is an instance of `ContiguousNDArray`, returning [Err] if `value` is
|
||||
/// not an instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, dtype, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
<Self as ProxyValue<'ctx>>::Type::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`ContiguousNDArrayValue`] from a [`PointerValue`].
|
||||
@ -53,7 +40,7 @@ impl<'ctx> ContiguousNDArrayValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
Self { value: ptr, item: dtype, llvm_usize, name }
|
||||
}
|
||||
@ -63,7 +50,7 @@ impl<'ctx> ContiguousNDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn store_ndims(&self, ctx: &CodeGenContext<'ctx, '_>, value: IntValue<'ctx>) {
|
||||
self.ndims_field().store(ctx, self.as_abi_value(ctx), value, self.name);
|
||||
self.ndims_field().set(ctx, self.as_base_value(), value, self.name);
|
||||
}
|
||||
|
||||
fn shape_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
@ -71,11 +58,11 @@ impl<'ctx> ContiguousNDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn store_shape(&self, ctx: &CodeGenContext<'ctx, '_>, value: PointerValue<'ctx>) {
|
||||
self.shape_field().store(ctx, self.as_abi_value(ctx), value, self.name);
|
||||
self.shape_field().set(ctx, self.as_base_value(), value, self.name);
|
||||
}
|
||||
|
||||
pub fn load_shape(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.shape_field().load(ctx, self.value, self.name)
|
||||
self.shape_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
fn data_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
@ -83,21 +70,20 @@ impl<'ctx> ContiguousNDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn store_data(&self, ctx: &CodeGenContext<'ctx, '_>, value: PointerValue<'ctx>) {
|
||||
self.data_field().store(ctx, self.as_abi_value(ctx), value, self.name);
|
||||
self.data_field().set(ctx, self.as_base_value(), value, self.name);
|
||||
}
|
||||
|
||||
pub fn load_data(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.data_field().load(ctx, self.value, self.name)
|
||||
self.data_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for ContiguousNDArrayValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = ContiguousNDArrayType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
<Self as ProxyValue<'ctx>>::Type::from_pointer_type(
|
||||
<Self as ProxyValue<'ctx>>::Type::from_type(
|
||||
self.as_base_value().get_type(),
|
||||
self.item,
|
||||
self.llvm_usize,
|
||||
@ -107,14 +93,8 @@ impl<'ctx> ProxyValue<'ctx> for ContiguousNDArrayValue<'ctx> {
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for ContiguousNDArrayValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<ContiguousNDArrayValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: ContiguousNDArrayValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
@ -153,7 +133,7 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||
|_, ctx| Ok(self.is_c_contiguous(ctx)),
|
||||
|_, ctx| {
|
||||
// This ndarray is contiguous.
|
||||
let data = self.data_field().load(ctx, self.as_abi_value(ctx), self.name);
|
||||
let data = self.data_field(ctx).get(ctx, self.as_base_value(), self.name);
|
||||
let data = ctx
|
||||
.builder
|
||||
.build_pointer_cast(data, result.item.ptr_type(AddressSpace::default()), "")
|
||||
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
values::{IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
@ -12,12 +12,10 @@ use crate::{
|
||||
irrt,
|
||||
types::{
|
||||
ndarray::{NDArrayType, NDIndexType},
|
||||
structure::{StructField, StructProxyType},
|
||||
structure::StructField,
|
||||
utils::SliceType,
|
||||
},
|
||||
values::{
|
||||
ndarray::NDArrayValue, structure::StructProxyValue, utils::RustSlice, ProxyValue,
|
||||
},
|
||||
values::{ndarray::NDArrayValue, utils::RustSlice, ProxyValue},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::Type,
|
||||
@ -32,24 +30,13 @@ pub struct NDIndexValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDIndexValue<'ctx> {
|
||||
/// Creates an [`NDIndexValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
/// Checks whether `value` is an instance of `ndindex`, returning [Err] if `value` is not an
|
||||
/// instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
<Self as ProxyValue<'ctx>>::Type::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`NDIndexValue`] from a [`PointerValue`].
|
||||
@ -59,7 +46,7 @@ impl<'ctx> NDIndexValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
Self { value: ptr, llvm_usize, name }
|
||||
}
|
||||
@ -69,11 +56,11 @@ impl<'ctx> NDIndexValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_type(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.type_field().load(ctx, self.value, self.name)
|
||||
self.type_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
pub fn store_type(&self, ctx: &CodeGenContext<'ctx, '_>, value: IntValue<'ctx>) {
|
||||
self.type_field().store(ctx, self.value, value, self.name);
|
||||
self.type_field().set(ctx, self.value, value, self.name);
|
||||
}
|
||||
|
||||
fn data_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
@ -81,34 +68,27 @@ impl<'ctx> NDIndexValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_data(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.data_field().load(ctx, self.value, self.name)
|
||||
self.data_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
pub fn store_data(&self, ctx: &CodeGenContext<'ctx, '_>, value: PointerValue<'ctx>) {
|
||||
self.data_field().store(ctx, self.value, value, self.name);
|
||||
self.data_field().set(ctx, self.value, value, self.name);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for NDIndexValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = NDIndexType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
Self::Type::from_pointer_type(self.value.get_type(), self.llvm_usize)
|
||||
Self::Type::from_type(self.value.get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for NDIndexValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<NDIndexValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: NDIndexValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -2,14 +2,14 @@ use std::iter::repeat_n;
|
||||
|
||||
use inkwell::{
|
||||
types::{AnyType, AnyTypeEnum, BasicType, BasicTypeEnum, IntType},
|
||||
values::{BasicValue, BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
values::{BasicValue, BasicValueEnum, IntValue, PointerValue},
|
||||
AddressSpace, IntPredicate,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::{
|
||||
structure::StructProxyValue, ArrayLikeIndexer, ArrayLikeValue, ProxyValue, TupleValue,
|
||||
TypedArrayLikeAccessor, TypedArrayLikeAdapter, TypedArrayLikeMutator, UntypedArrayLikeAccessor,
|
||||
ArrayLikeIndexer, ArrayLikeValue, ProxyValue, TupleValue, TypedArrayLikeAccessor,
|
||||
TypedArrayLikeAdapter, TypedArrayLikeMutator, UntypedArrayLikeAccessor,
|
||||
UntypedArrayLikeMutator,
|
||||
};
|
||||
use crate::{
|
||||
@ -18,11 +18,7 @@ use crate::{
|
||||
llvm_intrinsics::{call_int_umin, call_memcpy_generic_array},
|
||||
stmt::gen_for_callback_incrementing,
|
||||
type_aligned_alloca,
|
||||
types::{
|
||||
ndarray::NDArrayType,
|
||||
structure::{StructField, StructProxyType},
|
||||
TupleType,
|
||||
},
|
||||
types::{ndarray::NDArrayType, structure::StructField, TupleType},
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::{Type, TypeEnum},
|
||||
@ -53,26 +49,13 @@ pub struct NDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDArrayValue<'ctx> {
|
||||
/// Creates an [`NDArrayValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
dtype: BasicTypeEnum<'ctx>,
|
||||
ndims: u64,
|
||||
/// Checks whether `value` is an instance of `NDArray`, returning [Err] if `value` is not an
|
||||
/// instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, dtype, ndims, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
NDArrayType::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`NDArrayValue`] from a [`PointerValue`].
|
||||
@ -84,50 +67,57 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
NDArrayValue { value: ptr, dtype, ndims, llvm_usize, name }
|
||||
}
|
||||
|
||||
fn ndims_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().ndims
|
||||
fn ndims_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).ndims
|
||||
}
|
||||
|
||||
/// Returns the pointer to the field storing the number of dimensions of this `NDArray`.
|
||||
fn ptr_to_ndims(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.ndims_field(ctx).ptr_by_gep(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
/// Stores the number of dimensions `ndims` into this instance.
|
||||
pub fn store_ndims(&self, ctx: &CodeGenContext<'ctx, '_>, ndims: IntValue<'ctx>) {
|
||||
debug_assert_eq!(ndims.get_type(), ctx.get_size_type());
|
||||
|
||||
self.ndims_field().store(ctx, self.value, ndims, self.name);
|
||||
let pndims = self.ptr_to_ndims(ctx);
|
||||
ctx.builder.build_store(pndims, ndims).unwrap();
|
||||
}
|
||||
|
||||
/// Returns the number of dimensions of this `NDArray` as a value.
|
||||
pub fn load_ndims(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.ndims_field().load(ctx, self.value, self.name)
|
||||
let pndims = self.ptr_to_ndims(ctx);
|
||||
ctx.builder.build_load(pndims, "").map(BasicValueEnum::into_int_value).unwrap()
|
||||
}
|
||||
|
||||
fn itemsize_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().itemsize
|
||||
fn itemsize_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).itemsize
|
||||
}
|
||||
|
||||
/// Stores the size of each element `itemsize` into this instance.
|
||||
pub fn store_itemsize(&self, ctx: &CodeGenContext<'ctx, '_>, itemsize: IntValue<'ctx>) {
|
||||
debug_assert_eq!(itemsize.get_type(), ctx.get_size_type());
|
||||
|
||||
self.itemsize_field().store(ctx, self.value, itemsize, self.name);
|
||||
self.itemsize_field(ctx).set(ctx, self.value, itemsize, self.name);
|
||||
}
|
||||
|
||||
/// Returns the size of each element of this `NDArray` as a value.
|
||||
pub fn load_itemsize(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.itemsize_field().load(ctx, self.value, self.name)
|
||||
self.itemsize_field(ctx).get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
fn shape_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().shape
|
||||
fn shape_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).shape
|
||||
}
|
||||
|
||||
/// Stores the array of dimension sizes `dims` into this instance.
|
||||
fn store_shape(&self, ctx: &CodeGenContext<'ctx, '_>, dims: PointerValue<'ctx>) {
|
||||
self.shape_field().store(ctx, self.value, dims, self.name);
|
||||
self.shape_field(ctx).set(ctx, self.as_base_value(), dims, self.name);
|
||||
}
|
||||
|
||||
/// Convenience method for creating a new array storing dimension sizes with the given `size`.
|
||||
@ -146,13 +136,16 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||
NDArrayShapeProxy(self)
|
||||
}
|
||||
|
||||
fn strides_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().strides
|
||||
fn strides_field(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).strides
|
||||
}
|
||||
|
||||
/// Stores the array of stride sizes `strides` into this instance.
|
||||
fn store_strides(&self, ctx: &CodeGenContext<'ctx, '_>, strides: PointerValue<'ctx>) {
|
||||
self.strides_field().store(ctx, self.value, strides, self.name);
|
||||
self.strides_field(ctx).set(ctx, self.as_base_value(), strides, self.name);
|
||||
}
|
||||
|
||||
/// Convenience method for creating a new array storing the stride with the given `size`.
|
||||
@ -171,14 +164,14 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||
NDArrayStridesProxy(self)
|
||||
}
|
||||
|
||||
fn data_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().data
|
||||
fn data_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).data
|
||||
}
|
||||
|
||||
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
||||
/// on the field.
|
||||
pub fn ptr_to_data(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.data_field().ptr_by_gep(ctx, self.value, self.name)
|
||||
self.data_field(ctx).ptr_by_gep(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
/// Stores the array of data elements `data` into this instance.
|
||||
@ -187,7 +180,7 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||
.builder
|
||||
.build_bit_cast(data, ctx.ctx.i8_type().ptr_type(AddressSpace::default()), "")
|
||||
.unwrap();
|
||||
self.data_field().store(ctx, self.value, data.into_pointer_value(), self.name);
|
||||
self.data_field(ctx).set(ctx, self.as_base_value(), data.into_pointer_value(), self.name);
|
||||
}
|
||||
|
||||
/// Convenience method for creating a new array storing data elements with the given element
|
||||
@ -478,12 +471,11 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for NDArrayValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = NDArrayType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
NDArrayType::from_pointer_type(
|
||||
NDArrayType::from_type(
|
||||
self.as_base_value().get_type(),
|
||||
self.dtype,
|
||||
self.ndims,
|
||||
@ -494,14 +486,8 @@ impl<'ctx> ProxyValue<'ctx> for NDArrayValue<'ctx> {
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for NDArrayValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<NDArrayValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: NDArrayValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
@ -526,7 +512,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayShapeProxy<'ctx, '_> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
_: &G,
|
||||
) -> PointerValue<'ctx> {
|
||||
self.0.shape_field().load(ctx, self.0.value, self.0.name)
|
||||
self.0.shape_field(ctx).get(ctx, self.0.as_base_value(), self.0.name)
|
||||
}
|
||||
|
||||
fn size<G: CodeGenerator + ?Sized>(
|
||||
@ -624,7 +610,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayStridesProxy<'ctx, '_> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
_: &G,
|
||||
) -> PointerValue<'ctx> {
|
||||
self.0.strides_field().load(ctx, self.0.value, self.0.name)
|
||||
self.0.strides_field(ctx).get(ctx, self.0.as_base_value(), self.0.name)
|
||||
}
|
||||
|
||||
fn size<G: CodeGenerator + ?Sized>(
|
||||
@ -722,7 +708,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDataProxy<'ctx, '_> {
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
_: &G,
|
||||
) -> PointerValue<'ctx> {
|
||||
self.0.data_field().load(ctx, self.0.value, self.0.name)
|
||||
self.0.data_field(ctx).get(ctx, self.0.as_base_value(), self.0.name)
|
||||
}
|
||||
|
||||
fn size<G: CodeGenerator + ?Sized>(
|
||||
@ -976,7 +962,7 @@ impl<'ctx> ScalarOrNDArray<'ctx> {
|
||||
if *obj_id == ctx.primitives.ndarray.obj_id(&ctx.unifier).unwrap() =>
|
||||
{
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, object_ty)
|
||||
.map_pointer_value(object.into_pointer_value(), None);
|
||||
.map_value(object.into_pointer_value(), None);
|
||||
ScalarOrNDArray::NDArray(ndarray)
|
||||
}
|
||||
|
||||
@ -989,7 +975,7 @@ impl<'ctx> ScalarOrNDArray<'ctx> {
|
||||
pub fn to_basic_value_enum(self) -> BasicValueEnum<'ctx> {
|
||||
match self {
|
||||
ScalarOrNDArray::Scalar(scalar) => scalar,
|
||||
ScalarOrNDArray::NDArray(ndarray) => ndarray.value.into(),
|
||||
ScalarOrNDArray::NDArray(ndarray) => ndarray.as_base_value().into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,15 @@
|
||||
use inkwell::{
|
||||
types::{BasicType, IntType},
|
||||
values::{BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||
values::{BasicValueEnum, IntValue, PointerValue},
|
||||
AddressSpace,
|
||||
};
|
||||
|
||||
use super::NDArrayValue;
|
||||
use super::{NDArrayValue, ProxyValue};
|
||||
use crate::codegen::{
|
||||
irrt,
|
||||
stmt::{gen_for_callback, BreakContinueHooks},
|
||||
types::{
|
||||
ndarray::NDIterType,
|
||||
structure::{StructField, StructProxyType},
|
||||
},
|
||||
values::{structure::StructProxyValue, ArraySliceValue, ProxyValue, TypedArrayLikeAdapter},
|
||||
types::{ndarray::NDIterType, structure::StructField},
|
||||
values::{ArraySliceValue, TypedArrayLikeAdapter},
|
||||
CodeGenContext, CodeGenerator,
|
||||
};
|
||||
|
||||
@ -26,26 +23,13 @@ pub struct NDIterValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> NDIterValue<'ctx> {
|
||||
/// Creates an [`NDArrayValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
parent: NDArrayValue<'ctx>,
|
||||
indices: ArraySliceValue<'ctx>,
|
||||
/// Checks whether `value` is an instance of `NDArray`, returning [Err] if `value` is not an
|
||||
/// instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, parent, indices, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
<Self as ProxyValue>::Type::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`NDArrayValue`] from a [`PointerValue`].
|
||||
@ -57,7 +41,7 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
Self { value: ptr, parent, indices, llvm_usize, name }
|
||||
}
|
||||
@ -81,8 +65,11 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
irrt::ndarray::call_nac3_nditer_next(ctx, *self);
|
||||
}
|
||||
|
||||
fn element_field(&self) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields().element
|
||||
fn element_field(
|
||||
&self,
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
) -> StructField<'ctx, PointerValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).element
|
||||
}
|
||||
|
||||
/// Get pointer to the current element.
|
||||
@ -90,7 +77,7 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
pub fn get_pointer(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
let elem_ty = self.parent.dtype;
|
||||
|
||||
let p = self.element_field().load(ctx, self.as_abi_value(ctx), self.name);
|
||||
let p = self.element_field(ctx).get(ctx, self.as_base_value(), self.name);
|
||||
ctx.builder
|
||||
.build_pointer_cast(p, elem_ty.ptr_type(AddressSpace::default()), "element")
|
||||
.unwrap()
|
||||
@ -103,14 +90,14 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
ctx.builder.build_load(p, "value").unwrap()
|
||||
}
|
||||
|
||||
fn nth_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields().nth
|
||||
fn nth_field(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
self.get_type().get_fields(ctx.ctx).nth
|
||||
}
|
||||
|
||||
/// Get the index of the current element if this ndarray were a flat ndarray.
|
||||
#[must_use]
|
||||
pub fn get_index(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.nth_field().load(ctx, self.as_abi_value(ctx), self.name)
|
||||
self.nth_field(ctx).get(ctx, self.as_base_value(), self.name)
|
||||
}
|
||||
|
||||
/// Get the indices of the current element.
|
||||
@ -127,25 +114,18 @@ impl<'ctx> NDIterValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for NDIterValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = NDIterType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
NDIterType::from_pointer_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
NDIterType::from_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for NDIterValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<NDIterValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: NDIterValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -42,7 +42,7 @@ pub fn parse_numpy_int_sequence<'ctx, G: CodeGenerator + ?Sized>(
|
||||
// 1. A list of `int32`; e.g., `np.empty([600, 800, 3])`
|
||||
|
||||
let input_seq = ListType::from_unifier_type(generator, ctx, input_seq_ty)
|
||||
.map_pointer_value(input_seq.into_pointer_value(), None);
|
||||
.map_value(input_seq.into_pointer_value(), None);
|
||||
|
||||
let len = input_seq.load_size(ctx, None);
|
||||
// TODO: Find a way to remove this mid-BB allocation
|
||||
@ -86,7 +86,7 @@ pub fn parse_numpy_int_sequence<'ctx, G: CodeGenerator + ?Sized>(
|
||||
// 2. A tuple of ints; e.g., `np.empty((600, 800, 3))`
|
||||
|
||||
let input_seq = TupleType::from_unifier_type(generator, ctx, input_seq_ty)
|
||||
.map_struct_value(input_seq.into_struct_value(), None);
|
||||
.map_value(input_seq.into_struct_value(), None);
|
||||
|
||||
let len = input_seq.get_type().num_elements();
|
||||
|
||||
|
@ -1,50 +1,27 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{ArrayValue, BasicValueEnum, IntValue, PointerValue},
|
||||
};
|
||||
use inkwell::values::{BasicValueEnum, IntValue, PointerValue};
|
||||
|
||||
use super::ProxyValue;
|
||||
use crate::codegen::{types::RangeType, CodeGenContext, CodeGenerator};
|
||||
use crate::codegen::{types::RangeType, CodeGenContext};
|
||||
|
||||
/// Proxy type for accessing a `range` value in LLVM.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct RangeValue<'ctx> {
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
}
|
||||
|
||||
impl<'ctx> RangeValue<'ctx> {
|
||||
/// Creates an [`RangeValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_array_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: ArrayValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, llvm_usize, name)
|
||||
/// Checks whether `value` is an instance of `range`, returning [Err] if `value` is not an instance.
|
||||
pub fn is_representable(value: PointerValue<'ctx>) -> Result<(), String> {
|
||||
RangeType::is_representable(value.get_type())
|
||||
}
|
||||
|
||||
/// Creates an [`RangeValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
ptr: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
pub fn from_pointer_value(ptr: PointerValue<'ctx>, name: Option<&'ctx str>) -> Self {
|
||||
debug_assert!(Self::is_representable(ptr).is_ok());
|
||||
|
||||
RangeValue { value: ptr, llvm_usize, name }
|
||||
RangeValue { value: ptr, name }
|
||||
}
|
||||
|
||||
fn ptr_to_start(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
@ -54,7 +31,7 @@ impl<'ctx> RangeValue<'ctx> {
|
||||
unsafe {
|
||||
ctx.builder
|
||||
.build_in_bounds_gep(
|
||||
self.as_abi_value(ctx),
|
||||
self.as_base_value(),
|
||||
&[llvm_i32.const_zero(), llvm_i32.const_int(0, false)],
|
||||
var_name.as_str(),
|
||||
)
|
||||
@ -69,7 +46,7 @@ impl<'ctx> RangeValue<'ctx> {
|
||||
unsafe {
|
||||
ctx.builder
|
||||
.build_in_bounds_gep(
|
||||
self.as_abi_value(ctx),
|
||||
self.as_base_value(),
|
||||
&[llvm_i32.const_zero(), llvm_i32.const_int(1, false)],
|
||||
var_name.as_str(),
|
||||
)
|
||||
@ -84,7 +61,7 @@ impl<'ctx> RangeValue<'ctx> {
|
||||
unsafe {
|
||||
ctx.builder
|
||||
.build_in_bounds_gep(
|
||||
self.as_abi_value(ctx),
|
||||
self.as_base_value(),
|
||||
&[llvm_i32.const_zero(), llvm_i32.const_int(2, false)],
|
||||
var_name.as_str(),
|
||||
)
|
||||
@ -157,21 +134,16 @@ impl<'ctx> RangeValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for RangeValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = RangeType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
RangeType::from_pointer_type(self.value.get_type(), self.llvm_usize)
|
||||
RangeType::from_type(self.value.get_type())
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<RangeValue<'ctx>> for PointerValue<'ctx> {
|
||||
|
@ -1,24 +0,0 @@
|
||||
use inkwell::values::{BasicValueEnum, PointerValue, StructValue};
|
||||
|
||||
use super::ProxyValue;
|
||||
use crate::codegen::{types::structure::StructProxyType, CodeGenContext};
|
||||
|
||||
/// An LLVM value that is used to represent a corresponding structure-like value in NAC3.
|
||||
pub trait StructProxyValue<'ctx>:
|
||||
ProxyValue<'ctx, Base = PointerValue<'ctx>, Type: StructProxyType<'ctx, Value = Self>>
|
||||
{
|
||||
/// Returns this value as a [`StructValue`].
|
||||
#[must_use]
|
||||
fn get_struct_value(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructValue<'ctx> {
|
||||
ctx.builder
|
||||
.build_load(self.get_pointer_value(ctx), "")
|
||||
.map(BasicValueEnum::into_struct_value)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns this value as a [`PointerValue`].
|
||||
#[must_use]
|
||||
fn get_pointer_value(&self, _: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{BasicValue, BasicValueEnum, PointerValue, StructValue},
|
||||
values::{BasicValue, BasicValueEnum, StructValue},
|
||||
};
|
||||
|
||||
use super::ProxyValue;
|
||||
@ -14,6 +14,15 @@ pub struct TupleValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> TupleValue<'ctx> {
|
||||
/// Checks whether `value` is an instance of `tuple`, returning [Err] if `value` is not an
|
||||
/// instance.
|
||||
pub fn is_representable(
|
||||
value: StructValue<'ctx>,
|
||||
_llvm_usize: IntType<'ctx>,
|
||||
) -> Result<(), String> {
|
||||
TupleType::is_representable(value.get_type())
|
||||
}
|
||||
|
||||
/// Creates an [`TupleValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value(
|
||||
@ -21,29 +30,11 @@ impl<'ctx> TupleValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(value, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(value, llvm_usize).is_ok());
|
||||
|
||||
Self { value, llvm_usize, name }
|
||||
}
|
||||
|
||||
/// Creates an [`TupleValue`] from a [`PointerValue`].
|
||||
#[must_use]
|
||||
pub fn from_pointer_value(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
ptr: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
Self::from_struct_value(
|
||||
ctx.builder
|
||||
.build_load(ptr, name.unwrap_or_default())
|
||||
.map(BasicValueEnum::into_struct_value)
|
||||
.unwrap(),
|
||||
llvm_usize,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
/// Stores a value into the tuple element at the given `index`.
|
||||
pub fn store_element(
|
||||
&mut self,
|
||||
@ -75,21 +66,16 @@ impl<'ctx> TupleValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for TupleValue<'ctx> {
|
||||
type ABI = StructValue<'ctx>;
|
||||
type Base = StructValue<'ctx>;
|
||||
type Type = TupleType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
TupleType::from_struct_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
TupleType::from_type(self.as_base_value().get_type(), self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> From<TupleValue<'ctx>> for StructValue<'ctx> {
|
||||
|
@ -1,17 +1,14 @@
|
||||
use inkwell::{
|
||||
types::IntType,
|
||||
values::{IntValue, PointerValue, StructValue},
|
||||
values::{IntValue, PointerValue},
|
||||
};
|
||||
|
||||
use nac3parser::ast::Expr;
|
||||
|
||||
use crate::{
|
||||
codegen::{
|
||||
types::{
|
||||
structure::{StructField, StructProxyType},
|
||||
utils::SliceType,
|
||||
},
|
||||
values::{structure::StructProxyValue, ProxyValue},
|
||||
types::{structure::StructField, utils::SliceType},
|
||||
values::ProxyValue,
|
||||
CodeGenContext, CodeGenerator,
|
||||
},
|
||||
typecheck::typedef::Type,
|
||||
@ -27,25 +24,13 @@ pub struct SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> SliceValue<'ctx> {
|
||||
/// Creates an [`SliceValue`] from a [`StructValue`].
|
||||
#[must_use]
|
||||
pub fn from_struct_value<G: CodeGenerator + ?Sized>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
val: StructValue<'ctx>,
|
||||
int_ty: IntType<'ctx>,
|
||||
/// Checks whether `value` is an instance of `ContiguousNDArray`, returning [Err] if `value` is
|
||||
/// not an instance.
|
||||
pub fn is_representable(
|
||||
value: PointerValue<'ctx>,
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
let pval = generator
|
||||
.gen_var_alloc(
|
||||
ctx,
|
||||
val.get_type().into(),
|
||||
name.map(|name| format!("{name}.addr")).as_deref(),
|
||||
)
|
||||
.unwrap();
|
||||
ctx.builder.build_store(pval, val).unwrap();
|
||||
Self::from_pointer_value(pval, int_ty, llvm_usize, name)
|
||||
) -> Result<(), String> {
|
||||
<Self as ProxyValue<'ctx>>::Type::is_representable(value.get_type(), llvm_usize)
|
||||
}
|
||||
|
||||
/// Creates an [`SliceValue`] from a [`PointerValue`].
|
||||
@ -56,7 +41,7 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
llvm_usize: IntType<'ctx>,
|
||||
name: Option<&'ctx str>,
|
||||
) -> Self {
|
||||
debug_assert!(Self::is_instance(ptr, llvm_usize).is_ok());
|
||||
debug_assert!(Self::is_representable(ptr, llvm_usize).is_ok());
|
||||
|
||||
Self { value: ptr, int_ty, llvm_usize, name }
|
||||
}
|
||||
@ -66,7 +51,7 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_start_defined(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.start_defined_field().load(ctx, self.value, self.name)
|
||||
self.start_defined_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
fn start_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
@ -74,22 +59,22 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_start(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.start_field().load(ctx, self.value, self.name)
|
||||
self.start_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
pub fn store_start(&self, ctx: &CodeGenContext<'ctx, '_>, value: Option<IntValue<'ctx>>) {
|
||||
match value {
|
||||
Some(start) => {
|
||||
self.start_defined_field().store(
|
||||
self.start_defined_field().set(
|
||||
ctx,
|
||||
self.value,
|
||||
ctx.ctx.bool_type().const_all_ones(),
|
||||
self.name,
|
||||
);
|
||||
self.start_field().store(ctx, self.value, start, self.name);
|
||||
self.start_field().set(ctx, self.value, start, self.name);
|
||||
}
|
||||
|
||||
None => self.start_defined_field().store(
|
||||
None => self.start_defined_field().set(
|
||||
ctx,
|
||||
self.value,
|
||||
ctx.ctx.bool_type().const_zero(),
|
||||
@ -103,7 +88,7 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_stop_defined(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.stop_defined_field().load(ctx, self.value, self.name)
|
||||
self.stop_defined_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
fn stop_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
@ -111,22 +96,22 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_stop(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.stop_field().load(ctx, self.value, self.name)
|
||||
self.stop_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
pub fn store_stop(&self, ctx: &CodeGenContext<'ctx, '_>, value: Option<IntValue<'ctx>>) {
|
||||
match value {
|
||||
Some(stop) => {
|
||||
self.stop_defined_field().store(
|
||||
self.stop_defined_field().set(
|
||||
ctx,
|
||||
self.value,
|
||||
ctx.ctx.bool_type().const_all_ones(),
|
||||
self.name,
|
||||
);
|
||||
self.stop_field().store(ctx, self.value, stop, self.name);
|
||||
self.stop_field().set(ctx, self.value, stop, self.name);
|
||||
}
|
||||
|
||||
None => self.stop_defined_field().store(
|
||||
None => self.stop_defined_field().set(
|
||||
ctx,
|
||||
self.value,
|
||||
ctx.ctx.bool_type().const_zero(),
|
||||
@ -140,7 +125,7 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_step_defined(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.step_defined_field().load(ctx, self.value, self.name)
|
||||
self.step_defined_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
fn step_field(&self) -> StructField<'ctx, IntValue<'ctx>> {
|
||||
@ -148,22 +133,22 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
pub fn load_step(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
|
||||
self.step_field().load(ctx, self.value, self.name)
|
||||
self.step_field().get(ctx, self.value, self.name)
|
||||
}
|
||||
|
||||
pub fn store_step(&self, ctx: &CodeGenContext<'ctx, '_>, value: Option<IntValue<'ctx>>) {
|
||||
match value {
|
||||
Some(step) => {
|
||||
self.step_defined_field().store(
|
||||
self.step_defined_field().set(
|
||||
ctx,
|
||||
self.value,
|
||||
ctx.ctx.bool_type().const_all_ones(),
|
||||
self.name,
|
||||
);
|
||||
self.step_field().store(ctx, self.value, step, self.name);
|
||||
self.step_field().set(ctx, self.value, step, self.name);
|
||||
}
|
||||
|
||||
None => self.step_defined_field().store(
|
||||
None => self.step_defined_field().set(
|
||||
ctx,
|
||||
self.value,
|
||||
ctx.ctx.bool_type().const_zero(),
|
||||
@ -174,25 +159,18 @@ impl<'ctx> SliceValue<'ctx> {
|
||||
}
|
||||
|
||||
impl<'ctx> ProxyValue<'ctx> for SliceValue<'ctx> {
|
||||
type ABI = PointerValue<'ctx>;
|
||||
type Base = PointerValue<'ctx>;
|
||||
type Type = SliceType<'ctx>;
|
||||
|
||||
fn get_type(&self) -> Self::Type {
|
||||
Self::Type::from_pointer_type(self.value.get_type(), self.int_ty, self.llvm_usize)
|
||||
Self::Type::from_type(self.value.get_type(), self.int_ty, self.llvm_usize)
|
||||
}
|
||||
|
||||
fn as_base_value(&self) -> Self::Base {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn as_abi_value(&self, _: &CodeGenContext<'ctx, '_>) -> Self::ABI {
|
||||
self.as_base_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> StructProxyValue<'ctx> for SliceValue<'ctx> {}
|
||||
|
||||
impl<'ctx> From<SliceValue<'ctx>> for PointerValue<'ctx> {
|
||||
fn from(value: SliceValue<'ctx>) -> Self {
|
||||
value.as_base_value()
|
||||
|
@ -17,10 +17,10 @@ use crate::{
|
||||
builtin_fns,
|
||||
numpy::*,
|
||||
stmt::{exn_constructor, gen_if_callback},
|
||||
types::{ndarray::NDArrayType, RangeType},
|
||||
types::ndarray::NDArrayType,
|
||||
values::{
|
||||
ndarray::{shape::parse_numpy_int_sequence, ScalarOrNDArray},
|
||||
ProxyValue,
|
||||
ProxyValue, RangeValue,
|
||||
},
|
||||
},
|
||||
symbol_resolver::SymbolValue,
|
||||
@ -577,7 +577,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
let (zelf_ty, zelf) = obj.unwrap();
|
||||
let zelf =
|
||||
zelf.to_basic_value_enum(ctx, generator, zelf_ty)?.into_pointer_value();
|
||||
let zelf = RangeType::new(ctx).map_pointer_value(zelf, Some("range"));
|
||||
let zelf = RangeValue::from_pointer_value(zelf, Some("range"));
|
||||
|
||||
let mut start = None;
|
||||
let mut stop = None;
|
||||
@ -664,7 +664,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
zelf.store_end(ctx, stop);
|
||||
zelf.store_step(ctx, step);
|
||||
|
||||
Ok(Some(zelf.as_abi_value(ctx).into()))
|
||||
Ok(Some(zelf.as_base_value().into()))
|
||||
},
|
||||
)))),
|
||||
loc: None,
|
||||
@ -1280,7 +1280,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
let ndarray =
|
||||
args[0].1.clone().to_basic_value_enum(ctx, generator, ndarray_ty)?;
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, ndarray_ty)
|
||||
.map_pointer_value(ndarray.into_pointer_value(), None);
|
||||
.map_value(ndarray.into_pointer_value(), None);
|
||||
|
||||
let size = ctx
|
||||
.builder
|
||||
@ -1312,7 +1312,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
args[0].1.clone().to_basic_value_enum(ctx, generator, ndarray_ty)?;
|
||||
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, ndarray_ty)
|
||||
.map_pointer_value(ndarray.into_pointer_value(), None);
|
||||
.map_value(ndarray.into_pointer_value(), None);
|
||||
|
||||
let result_tuple = match prim {
|
||||
PrimDef::FunNpShape => ndarray.make_shape_tuple(generator, ctx),
|
||||
@ -1320,7 +1320,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Ok(Some(result_tuple.as_abi_value(ctx).into()))
|
||||
Ok(Some(result_tuple.as_base_value().into()))
|
||||
}),
|
||||
)
|
||||
}
|
||||
@ -1353,10 +1353,10 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
let arg_val = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
|
||||
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, arg_ty)
|
||||
.map_pointer_value(arg_val.into_pointer_value(), None);
|
||||
.map_value(arg_val.into_pointer_value(), None);
|
||||
|
||||
let ndarray = ndarray.transpose(generator, ctx, None); // TODO: Add axes argument
|
||||
Ok(Some(ndarray.as_abi_value(ctx).into()))
|
||||
Ok(Some(ndarray.as_base_value().into()))
|
||||
}),
|
||||
),
|
||||
|
||||
@ -1391,7 +1391,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
args[1].1.clone().to_basic_value_enum(ctx, generator, shape_ty)?;
|
||||
|
||||
let ndarray = NDArrayType::from_unifier_type(generator, ctx, ndarray_ty)
|
||||
.map_pointer_value(ndarray_val.into_pointer_value(), None);
|
||||
.map_value(ndarray_val.into_pointer_value(), None);
|
||||
|
||||
let shape = parse_numpy_int_sequence(generator, ctx, (shape_ty, shape_val));
|
||||
|
||||
@ -1410,7 +1410,7 @@ impl<'a> BuiltinBuilder<'a> {
|
||||
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Ok(Some(new_ndarray.as_abi_value(ctx).as_basic_value_enum()))
|
||||
Ok(Some(new_ndarray.as_base_value().as_basic_value_enum()))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ rm -f ./*.o ./*.bc demo
|
||||
if [ -z "$i686" ]; then
|
||||
$nac3standalone "${nac3args[@]}"
|
||||
clang -c -std=gnu11 -Wall -Wextra -O3 -o demo.o demo.c
|
||||
clang -o demo module.o demo.o $DEMO_LINALG_STUB -fuse-ld=lld -lm
|
||||
clang -o demo module.o demo.o $DEMO_LINALG_STUB -lm -Wl,--no-warn-search-mismatch
|
||||
else
|
||||
$nac3standalone --triple i686-unknown-linux-gnu --target-features +sse2 "${nac3args[@]}"
|
||||
clang -m32 -c -std=gnu11 -Wall -Wextra -O3 -msse2 -o demo.o demo.c
|
||||
|
@ -1,35 +0,0 @@
|
||||
@extern
|
||||
def output_int32(x: int32):
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_strln(x: str):
|
||||
...
|
||||
|
||||
|
||||
class A:
|
||||
a: int32 = 1
|
||||
b: int32
|
||||
c: str = "test"
|
||||
d: str
|
||||
|
||||
def __init__(self):
|
||||
self.b = 2
|
||||
self.d = "test"
|
||||
|
||||
output_int32(self.a) # Attributes can be accessed within class
|
||||
|
||||
|
||||
def run() -> int32:
|
||||
output_int32(A.a) # Attributes can be directly accessed with class name
|
||||
# A.b # Only attributes can be accessed in this way
|
||||
# A.a = 2 # Attributes are immutable
|
||||
|
||||
obj = A()
|
||||
output_int32(obj.a) # Attributes can be accessed by class objects
|
||||
|
||||
output_strln(obj.c)
|
||||
output_strln(obj.d)
|
||||
|
||||
return 0
|
||||
|
Loading…
Reference in New Issue
Block a user