Compare commits
12 Commits
30c6cffbad
...
275bbc26ab
Author | SHA1 | Date |
---|---|---|
David Mak | 275bbc26ab | |
David Mak | d75f970b4a | |
David Mak | 67a7b70df6 | |
David Mak | 97652c98b1 | |
David Mak | c3ab79ebd0 | |
David Mak | 503380b1ec | |
David Mak | 8df342db62 | |
David Mak | 021ce36e84 | |
David Mak | fad0a308a0 | |
David Mak | 347b944669 | |
David Mak | 0f2af3983b | |
David Mak | 75a7ed2f3b |
|
@ -122,9 +122,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.92"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41"
|
||||
checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -163,7 +163,7 @@ dependencies = [
|
|||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -275,9 +275,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.10.0"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
|
@ -426,7 +426,7 @@ checksum = "4fa4d8d74483041a882adaa9a29f633253a66dde85055f0495c121620ac484b2"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -517,7 +517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.4",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -746,7 +746,7 @@ dependencies = [
|
|||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -793,9 +793,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -847,7 +847,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -860,7 +860,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -980,9 +980,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.32"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
|
@ -1026,29 +1026,29 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
version = "1.0.198"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
version = "1.0.198"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.115"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
|
||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1128,9 +1128,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
version = "2.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1181,22 +1181,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
version = "1.0.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
version = "1.0.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1352,11 +1352,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1371,7 +1371,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1391,17 +1391,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.4",
|
||||
"windows_aarch64_msvc 0.52.4",
|
||||
"windows_i686_gnu 0.52.4",
|
||||
"windows_i686_msvc 0.52.4",
|
||||
"windows_x86_64_gnu 0.52.4",
|
||||
"windows_x86_64_gnullvm 0.52.4",
|
||||
"windows_x86_64_msvc 0.52.4",
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1412,9 +1413,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
|
@ -1424,9 +1425,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
|
@ -1436,9 +1437,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
|
@ -1448,9 +1455,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
|
@ -1460,9 +1467,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
|
@ -1472,9 +1479,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
|
@ -1484,9 +1491,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
|
@ -1514,5 +1521,5 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,613 @@
|
|||
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||
use inkwell::values::{BasicValueEnum, CallSiteValue, FloatValue, IntValue};
|
||||
use itertools::Either;
|
||||
|
||||
use crate::codegen::CodeGenContext;
|
||||
|
||||
/// Invokes the [`tan`](https://en.cppreference.com/w/c/numeric/math/tan) function.
|
||||
pub fn call_tan<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "tan";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`asin`](https://en.cppreference.com/w/c/numeric/math/asin) function.
|
||||
pub fn call_asin<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "asin";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`acos`](https://en.cppreference.com/w/c/numeric/math/acos) function.
|
||||
pub fn call_acos<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "acos";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`atan`](https://en.cppreference.com/w/c/numeric/math/atan) function.
|
||||
pub fn call_atan<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "atan";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`sinh`](https://en.cppreference.com/w/c/numeric/math/sinh) function.
|
||||
pub fn call_sinh<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "sinh";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`cosh`](https://en.cppreference.com/w/c/numeric/math/cosh) function.
|
||||
pub fn call_cosh<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "cosh";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`tanh`](https://en.cppreference.com/w/c/numeric/math/tanh) function.
|
||||
pub fn call_tanh<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "tanh";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`asinh`](https://en.cppreference.com/w/c/numeric/math/asinh) function.
|
||||
pub fn call_asinh<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "asinh";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`acosh`](https://en.cppreference.com/w/c/numeric/math/acosh) function.
|
||||
pub fn call_acosh<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "acosh";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`atanh`](https://en.cppreference.com/w/c/numeric/math/atanh) function.
|
||||
pub fn call_atanh<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "atanh";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`expm1`](https://en.cppreference.com/w/c/numeric/math/expm1) function.
|
||||
pub fn call_expm1<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "expm1";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`cbrt`](https://en.cppreference.com/w/c/numeric/math/cbrt) function.
|
||||
pub fn call_cbrt<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "cbrt";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nosync", "nounwind", "readonly", "willreturn"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`erf`](https://en.cppreference.com/w/c/numeric/math/erf) function.
|
||||
pub fn call_erf<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "erf";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0)
|
||||
);
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`erfc`](https://en.cppreference.com/w/c/numeric/math/erfc) function.
|
||||
pub fn call_erfc<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "erfc";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0)
|
||||
);
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`j1`](https://www.gnu.org/software/libc/manual/html_node/Special-Functions.html#index-j1)
|
||||
/// function.
|
||||
pub fn call_j1<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "j1";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0)
|
||||
);
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`atan2`](https://en.cppreference.com/w/c/numeric/math/atan2) function.
|
||||
pub fn call_atan2<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
y: FloatValue<'ctx>,
|
||||
x: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "atan2";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(y.get_type(), llvm_f64);
|
||||
debug_assert_eq!(x.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into(), llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[y.into(), x.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`ldexp`](https://en.cppreference.com/w/c/numeric/math/ldexp) function.
|
||||
pub fn call_ldexp<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
arg: FloatValue<'ctx>,
|
||||
exp: IntValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "ldexp";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
let llvm_i32 = ctx.ctx.i32_type();
|
||||
debug_assert_eq!(arg.get_type(), llvm_f64);
|
||||
debug_assert_eq!(exp.get_type(), llvm_i32);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into(), llvm_i32.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
for attr in ["mustprogress", "nofree", "nounwind", "willreturn"] {
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0)
|
||||
);
|
||||
}
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[arg.into(), exp.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`hypot`](https://en.cppreference.com/w/c/numeric/math/hypot) function.
|
||||
pub fn call_hypot<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
x: FloatValue<'ctx>,
|
||||
y: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "hypot";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(x.get_type(), llvm_f64);
|
||||
debug_assert_eq!(y.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into(), llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0)
|
||||
);
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[x.into(), y.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`nextafter`](https://en.cppreference.com/w/c/numeric/math/nextafter) function.
|
||||
pub fn call_nextafter<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
from: FloatValue<'ctx>,
|
||||
to: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
const FN_NAME: &str = "nextafter";
|
||||
|
||||
let llvm_f64 = ctx.ctx.f64_type();
|
||||
debug_assert_eq!(from.get_type(), llvm_f64);
|
||||
debug_assert_eq!(to.get_type(), llvm_f64);
|
||||
|
||||
let extern_fn = ctx.module.get_function(FN_NAME).unwrap_or_else(|| {
|
||||
let fn_type = llvm_f64.fn_type(&[llvm_f64.into(), llvm_f64.into()], false);
|
||||
let func = ctx.module.add_function(FN_NAME, fn_type, None);
|
||||
func.add_attribute(
|
||||
AttributeLoc::Function,
|
||||
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0)
|
||||
);
|
||||
|
||||
func
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(extern_fn, &[from.into(), to.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
|
@ -311,6 +311,29 @@ pub fn call_memcpy_generic<'ctx>(
|
|||
call_memcpy(ctx, dest, src, len, is_volatile);
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.sqrt`](https://llvm.org/docs/LangRef.html#llvm-sqrt-intrinsic) intrinsic.
|
||||
pub fn call_float_sqrt<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.sqrt.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.powi`](https://llvm.org/docs/LangRef.html#llvm-powi-intrinsic) intrinsic.
|
||||
pub fn call_float_powi<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
|
@ -340,6 +363,52 @@ pub fn call_float_powi<'ctx>(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.sin`](https://llvm.org/docs/LangRef.html#llvm-sin-intrinsic) intrinsic.
|
||||
pub fn call_float_sin<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.sin.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.cos`](https://llvm.org/docs/LangRef.html#llvm-cos-intrinsic) intrinsic.
|
||||
pub fn call_float_cos<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.cos.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.pow`](https://llvm.org/docs/LangRef.html#llvm-pow-intrinsic) intrinsic.
|
||||
pub fn call_float_pow<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
|
@ -366,6 +435,122 @@ pub fn call_float_pow<'ctx>(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.exp`](https://llvm.org/docs/LangRef.html#llvm-exp-intrinsic) intrinsic.
|
||||
pub fn call_float_exp<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.exp.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.exp2`](https://llvm.org/docs/LangRef.html#llvm-exp2-intrinsic) intrinsic.
|
||||
pub fn call_float_exp2<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.exp2.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
||||
/// Invokes the [`llvm.log`](https://llvm.org/docs/LangRef.html#llvm-log-intrinsic) intrinsic.
|
||||
pub fn call_float_log<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.log.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.log10`](https://llvm.org/docs/LangRef.html#llvm-log10-intrinsic) intrinsic.
|
||||
pub fn call_float_log10<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.log10.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.log2`](https://llvm.org/docs/LangRef.html#llvm-log2-intrinsic) intrinsic.
|
||||
pub fn call_float_log2<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
val: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
let llvm_float_t = val.get_type();
|
||||
|
||||
let fn_name = format!("llvm.log2.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[val.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.fabs`](https://llvm.org/docs/LangRef.html#llvm-fabs-intrinsic) intrinsic.
|
||||
pub fn call_float_fabs<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
|
@ -442,6 +627,32 @@ pub fn call_float_maxnum<'ctx>(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.copysign`](https://llvm.org/docs/LangRef.html#llvm-copysign-intrinsic) intrinsic.
|
||||
pub fn call_float_copysign<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
mag: FloatValue<'ctx>,
|
||||
sgn: FloatValue<'ctx>,
|
||||
name: Option<&str>,
|
||||
) -> FloatValue<'ctx> {
|
||||
debug_assert_eq!(mag.get_type(), sgn.get_type());
|
||||
|
||||
let llvm_float_t = mag.get_type();
|
||||
|
||||
let fn_name = format!("llvm.copysign.{}", get_float_intrinsic_repr(ctx.ctx, llvm_float_t));
|
||||
let intrinsic_fn = ctx.module.get_function(fn_name.as_str()).unwrap_or_else(|| {
|
||||
let fn_type = llvm_float_t.fn_type(&[llvm_float_t.into(), llvm_float_t.into()], false);
|
||||
|
||||
ctx.module.add_function(fn_name.as_str(), fn_type, None)
|
||||
});
|
||||
|
||||
ctx.builder
|
||||
.build_call(intrinsic_fn, &[mag.into(), sgn.into()], name.unwrap_or_default())
|
||||
.map(CallSiteValue::try_as_basic_value)
|
||||
.map(|v| v.map_left(BasicValueEnum::into_float_value))
|
||||
.map(Either::unwrap_left)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Invokes the [`llvm.floor`](https://llvm.org/docs/LangRef.html#llvm-floor-intrinsic) intrinsic.
|
||||
pub fn call_float_floor<'ctx>(
|
||||
ctx: &CodeGenContext<'ctx, '_>,
|
||||
|
|
|
@ -39,9 +39,11 @@ use std::sync::{
|
|||
};
|
||||
use std::thread;
|
||||
|
||||
pub mod builtin_fns;
|
||||
pub mod classes;
|
||||
pub mod concrete_type;
|
||||
pub mod expr;
|
||||
pub mod extern_fns;
|
||||
mod generator;
|
||||
pub mod irrt;
|
||||
pub mod llvm_intrinsics;
|
||||
|
|
|
@ -316,15 +316,15 @@ fn ndarray_fill_flattened<'ctx, 'a, G, ValueFn>(
|
|||
|
||||
/// Generates LLVM IR for populating the entire `NDArray` using a lambda with the dimension-indices
|
||||
/// as its input.
|
||||
fn ndarray_fill_indexed<'ctx, G, ValueFn>(
|
||||
fn ndarray_fill_indexed<'ctx, 'a, G, ValueFn>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
ndarray: NDArrayValue<'ctx>,
|
||||
value_fn: ValueFn,
|
||||
) -> Result<(), String>
|
||||
where
|
||||
G: CodeGenerator + ?Sized,
|
||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, &TypedArrayLikeAdapter<'ctx, IntValue<'ctx>>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, 'a>, &TypedArrayLikeAdapter<'ctx, IntValue<'ctx>>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
{
|
||||
ndarray_fill_flattened(
|
||||
generator,
|
||||
|
@ -343,16 +343,16 @@ fn ndarray_fill_indexed<'ctx, G, ValueFn>(
|
|||
)
|
||||
}
|
||||
|
||||
fn ndarray_fill_mapping<'ctx, G, MapFn>(
|
||||
fn ndarray_fill_mapping<'ctx, 'a, G, MapFn>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
src: NDArrayValue<'ctx>,
|
||||
dest: NDArrayValue<'ctx>,
|
||||
map_fn: MapFn,
|
||||
) -> Result<(), String>
|
||||
where
|
||||
G: CodeGenerator + ?Sized,
|
||||
MapFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
MapFn: Fn(&mut G, &mut CodeGenContext<'ctx, 'a>, BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
{
|
||||
ndarray_fill_flattened(
|
||||
generator,
|
||||
|
@ -391,9 +391,9 @@ fn ndarray_assert_is_broadcastable<'ctx, G: CodeGenerator + ?Sized>(
|
|||
|
||||
/// Generates the LLVM IR for populating the entire `NDArray` from two `ndarray` or scalar value
|
||||
/// with broadcast-compatible shapes.
|
||||
fn ndarray_broadcast_fill<'ctx, G, ValueFn>(
|
||||
fn ndarray_broadcast_fill<'ctx, 'a, G, ValueFn>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
res: NDArrayValue<'ctx>,
|
||||
lhs: (BasicValueEnum<'ctx>, bool),
|
||||
rhs: (BasicValueEnum<'ctx>, bool),
|
||||
|
@ -401,7 +401,7 @@ fn ndarray_broadcast_fill<'ctx, G, ValueFn>(
|
|||
) -> Result<NDArrayValue<'ctx>, String>
|
||||
where
|
||||
G: CodeGenerator + ?Sized,
|
||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, 'a>, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
{
|
||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
||||
|
||||
|
@ -451,8 +451,6 @@ fn ndarray_broadcast_fill<'ctx, G, ValueFn>(
|
|||
}
|
||||
};
|
||||
|
||||
debug_assert_eq!(lhs_elem.get_type(), rhs_elem.get_type());
|
||||
|
||||
value_fn(generator, ctx, (lhs_elem, rhs_elem))
|
||||
},
|
||||
)?;
|
||||
|
@ -684,17 +682,17 @@ fn ndarray_copy_impl<'ctx, G: CodeGenerator + ?Sized>(
|
|||
Ok(ndarray)
|
||||
}
|
||||
|
||||
pub fn ndarray_elementwise_unaryop_impl<'ctx, G, MapFn>(
|
||||
pub fn ndarray_elementwise_unaryop_impl<'ctx, 'a, G, MapFn>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
elem_ty: Type,
|
||||
res: Option<NDArrayValue<'ctx>>,
|
||||
operand: NDArrayValue<'ctx>,
|
||||
map_fn: MapFn,
|
||||
) -> Result<NDArrayValue<'ctx>, String>
|
||||
where
|
||||
G: CodeGenerator,
|
||||
MapFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
G: CodeGenerator + ?Sized,
|
||||
MapFn: Fn(&mut G, &mut CodeGenContext<'ctx, 'a>, BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
{
|
||||
let res = res.unwrap_or_else(|| {
|
||||
create_ndarray_dyn_shape(
|
||||
|
@ -745,9 +743,9 @@ pub fn ndarray_elementwise_unaryop_impl<'ctx, G, MapFn>(
|
|||
/// # Panic
|
||||
///
|
||||
/// This function will panic if neither input operands (`lhs` or `rhs`) is a `ndarray`.
|
||||
pub fn ndarray_elementwise_binop_impl<'ctx, G, ValueFn>(
|
||||
pub fn ndarray_elementwise_binop_impl<'ctx, 'a, G, ValueFn>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||
elem_ty: Type,
|
||||
res: Option<NDArrayValue<'ctx>>,
|
||||
lhs: (BasicValueEnum<'ctx>, bool),
|
||||
|
@ -755,8 +753,8 @@ pub fn ndarray_elementwise_binop_impl<'ctx, G, ValueFn>(
|
|||
value_fn: ValueFn,
|
||||
) -> Result<NDArrayValue<'ctx>, String>
|
||||
where
|
||||
G: CodeGenerator,
|
||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
G: CodeGenerator + ?Sized,
|
||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, 'a>, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
||||
{
|
||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -53,10 +53,8 @@ impl TopLevelComposer {
|
|||
core_config: ComposerConfig,
|
||||
size_t: u32,
|
||||
) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) {
|
||||
let mut primitives = Self::make_primitives(size_t);
|
||||
let mut definition_ast_list = builtins::get_builtins(&mut primitives);
|
||||
let primitives_ty = primitives.0;
|
||||
let mut unifier = primitives.1;
|
||||
let (primitives_ty, mut unifier) = Self::make_primitives(size_t);
|
||||
let mut definition_ast_list = builtins::get_builtins(&mut unifier, &primitives_ty);
|
||||
let mut keyword_list: HashSet<StrRef> = HashSet::from_iter(vec![
|
||||
"Generic".into(),
|
||||
"virtual".into(),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use crate::symbol_resolver::SymbolValue;
|
||||
use crate::toplevel::numpy::subst_ndarray_tvars;
|
||||
use crate::typecheck::typedef::{Mapping, VarMap};
|
||||
use nac3parser::ast::{Constant, Location};
|
||||
|
||||
|
@ -232,57 +231,11 @@ impl TopLevelComposer {
|
|||
(ndarray_ndims_tvar.1, ndarray_ndims_tvar.0),
|
||||
]),
|
||||
}));
|
||||
let ndarray_binop_fun_other_ty = unifier.get_fresh_var(None, None);
|
||||
let ndarray_binop_fun_ret_ty = unifier.get_fresh_var(None, None);
|
||||
let ndarray_binop_fun_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![
|
||||
FuncArg {
|
||||
name: "other".into(),
|
||||
ty: ndarray_binop_fun_other_ty.0,
|
||||
default_value: None,
|
||||
},
|
||||
],
|
||||
ret: ndarray_binop_fun_ret_ty.0,
|
||||
vars: VarMap::from([
|
||||
(ndarray_dtype_tvar.1, ndarray_dtype_tvar.0),
|
||||
(ndarray_ndims_tvar.1, ndarray_ndims_tvar.0),
|
||||
]),
|
||||
}));
|
||||
let ndarray_truediv_fun_other_ty = unifier.get_fresh_var(None, None);
|
||||
let ndarray_truediv_fun_ret_ty = unifier.get_fresh_var(None, None);
|
||||
let ndarray_truediv_fun_ty = unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![
|
||||
FuncArg {
|
||||
name: "other".into(),
|
||||
ty: ndarray_truediv_fun_other_ty.0,
|
||||
default_value: None,
|
||||
},
|
||||
],
|
||||
ret: ndarray_truediv_fun_ret_ty.0,
|
||||
vars: VarMap::from([
|
||||
(ndarray_dtype_tvar.1, ndarray_dtype_tvar.0),
|
||||
(ndarray_ndims_tvar.1, ndarray_ndims_tvar.0),
|
||||
]),
|
||||
}));
|
||||
let ndarray = unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: PRIMITIVE_DEF_IDS.ndarray,
|
||||
fields: Mapping::from([
|
||||
("copy".into(), (ndarray_copy_fun_ty, true)),
|
||||
("fill".into(), (ndarray_fill_fun_ty, true)),
|
||||
("__add__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__sub__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__mul__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__truediv__".into(), (ndarray_truediv_fun_ty, true)),
|
||||
("__floordiv__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__mod__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__pow__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__iadd__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__isub__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__imul__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__itruediv__".into(), (ndarray_truediv_fun_ty, true)),
|
||||
("__ifloordiv__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__imod__".into(), (ndarray_binop_fun_ty, true)),
|
||||
("__ipow__".into(), (ndarray_binop_fun_ty, true)),
|
||||
]),
|
||||
params: VarMap::from([
|
||||
(ndarray_dtype_tvar.1, ndarray_dtype_tvar.0),
|
||||
|
@ -290,16 +243,7 @@ impl TopLevelComposer {
|
|||
]),
|
||||
});
|
||||
|
||||
let ndarray_usized_ndims_tvar = unifier.get_fresh_const_generic_var(size_t_ty, Some("ndarray_ndims".into()), None);
|
||||
let ndarray_unsized = subst_ndarray_tvars(&mut unifier, ndarray, Some(ndarray_usized_ndims_tvar.0), None);
|
||||
|
||||
unifier.unify(ndarray_copy_fun_ret_ty.0, ndarray).unwrap();
|
||||
unifier.unify(ndarray_binop_fun_other_ty.0, ndarray_unsized).unwrap();
|
||||
unifier.unify(ndarray_binop_fun_ret_ty.0, ndarray).unwrap();
|
||||
|
||||
let ndarray_float = subst_ndarray_tvars(&mut unifier, ndarray, Some(float), None);
|
||||
unifier.unify(ndarray_truediv_fun_other_ty.0, ndarray).unwrap();
|
||||
unifier.unify(ndarray_truediv_fun_ret_ty.0, ndarray_float).unwrap();
|
||||
|
||||
let primitives = PrimitiveStore {
|
||||
int32,
|
||||
|
|
|
@ -32,7 +32,7 @@ use type_annotation::*;
|
|||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
type GenCallCallback = Box<
|
||||
type GenCallCallback =
|
||||
dyn for<'ctx, 'a> Fn(
|
||||
&mut CodeGenContext<'ctx, 'a>,
|
||||
Option<(Type, ValueEnum<'ctx>)>,
|
||||
|
@ -41,19 +41,25 @@ type GenCallCallback = Box<
|
|||
&mut dyn CodeGenerator,
|
||||
) -> Result<Option<BasicValueEnum<'ctx>>, String>
|
||||
+ Send
|
||||
+ Sync,
|
||||
>;
|
||||
+ Sync;
|
||||
|
||||
pub struct GenCall {
|
||||
fp: GenCallCallback,
|
||||
fp: Box<GenCallCallback>,
|
||||
}
|
||||
|
||||
impl GenCall {
|
||||
#[must_use]
|
||||
pub fn new(fp: GenCallCallback) -> GenCall {
|
||||
pub fn new(fp: Box<GenCallCallback>) -> GenCall {
|
||||
GenCall { fp }
|
||||
}
|
||||
|
||||
/// Creates a dummy instance of [`GenCall`], which invokes [`unreachable!()`] with the given
|
||||
/// `reason`.
|
||||
#[must_use]
|
||||
pub fn create_dummy(reason: String) -> GenCall {
|
||||
Self::new(Box::new(move |_, _, _, _, _| unreachable!("{reason}")))
|
||||
}
|
||||
|
||||
pub fn run<'ctx>(
|
||||
&self,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
|
|
|
@ -5,7 +5,7 @@ expression: res_vec
|
|||
[
|
||||
"Class {\nname: \"Generic_A\",\nancestors: [\"Generic_A[V]\", \"B\"],\nfields: [\"aa\", \"a\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"foo\", \"fn[[b:T], none]\"), (\"fun\", \"fn[[a:int32], V]\")],\ntype_vars: [\"V\"]\n}\n",
|
||||
"Function {\nname: \"Generic_A.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"Generic_A.fun\",\nsig: \"fn[[a:int32], V]\",\nvar_id: [156]\n}\n",
|
||||
"Function {\nname: \"Generic_A.fun\",\nsig: \"fn[[a:int32], V]\",\nvar_id: [127]\n}\n",
|
||||
"Class {\nname: \"B\",\nancestors: [\"B\"],\nfields: [\"aa\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"foo\", \"fn[[b:T], none]\")],\ntype_vars: []\n}\n",
|
||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"B.foo\",\nsig: \"fn[[b:T], none]\",\nvar_id: []\n}\n",
|
||||
|
|
|
@ -7,7 +7,7 @@ expression: res_vec
|
|||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[t:T], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"A.foo\",\nsig: \"fn[[c:C], none]\",\nvar_id: []\n}\n",
|
||||
"Class {\nname: \"B\",\nancestors: [\"B[typevar145]\", \"A[float]\"],\nfields: [\"a\", \"b\", \"c\", \"d\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: [\"typevar145\"]\n}\n",
|
||||
"Class {\nname: \"B\",\nancestors: [\"B[typevar116]\", \"A[float]\"],\nfields: [\"a\", \"b\", \"c\", \"d\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: [\"typevar116\"]\n}\n",
|
||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"B.fun\",\nsig: \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\",\nvar_id: []\n}\n",
|
||||
"Class {\nname: \"C\",\nancestors: [\"C\", \"B[bool]\", \"A[float]\"],\nfields: [\"a\", \"b\", \"c\", \"d\", \"e\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:int32, b:T], list[virtual[B[bool]]]]\"), (\"foo\", \"fn[[c:C], none]\")],\ntype_vars: []\n}\n",
|
||||
|
|
|
@ -5,8 +5,8 @@ expression: res_vec
|
|||
[
|
||||
"Function {\nname: \"foo\",\nsig: \"fn[[a:list[int32], b:tuple[T, float]], A[B, bool]]\",\nvar_id: []\n}\n",
|
||||
"Class {\nname: \"A\",\nancestors: [\"A[T, V]\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[v:V], none]\"), (\"fun\", \"fn[[a:T], V]\")],\ntype_vars: [\"T\", \"V\"]\n}\n",
|
||||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[v:V], none]\",\nvar_id: [158]\n}\n",
|
||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:T], V]\",\nvar_id: [163]\n}\n",
|
||||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[v:V], none]\",\nvar_id: [129]\n}\n",
|
||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:T], V]\",\nvar_id: [134]\n}\n",
|
||||
"Function {\nname: \"gfun\",\nsig: \"fn[[a:A[list[float], int32]], none]\",\nvar_id: []\n}\n",
|
||||
"Class {\nname: \"B\",\nancestors: [\"B\"],\nfields: [],\nmethods: [(\"__init__\", \"fn[[], none]\")],\ntype_vars: []\n}\n",
|
||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
|
|
|
@ -3,7 +3,7 @@ source: nac3core/src/toplevel/test.rs
|
|||
expression: res_vec
|
||||
---
|
||||
[
|
||||
"Class {\nname: \"A\",\nancestors: [\"A[typevar144, typevar145]\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[a:A[float, bool], b:B], none]\"), (\"fun\", \"fn[[a:A[float, bool]], A[bool, int32]]\")],\ntype_vars: [\"typevar144\", \"typevar145\"]\n}\n",
|
||||
"Class {\nname: \"A\",\nancestors: [\"A[typevar115, typevar116]\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[a:A[float, bool], b:B], none]\"), (\"fun\", \"fn[[a:A[float, bool]], A[bool, int32]]\")],\ntype_vars: [\"typevar115\", \"typevar116\"]\n}\n",
|
||||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[a:A[float, bool], b:B], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[a:A[float, bool]], A[bool, int32]]\",\nvar_id: []\n}\n",
|
||||
"Class {\nname: \"B\",\nancestors: [\"B\", \"A[int64, bool]\"],\nfields: [\"a\", \"b\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[a:A[float, bool]], A[bool, int32]]\"), (\"foo\", \"fn[[b:B], B]\"), (\"bar\", \"fn[[a:A[list[B], int32]], tuple[A[virtual[A[B, int32]], bool], B]]\")],\ntype_vars: []\n}\n",
|
||||
|
|
|
@ -6,12 +6,12 @@ expression: res_vec
|
|||
"Class {\nname: \"A\",\nancestors: [\"A\"],\nfields: [\"a\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[b:B], none]\"), (\"foo\", \"fn[[a:T, b:V], none]\")],\ntype_vars: []\n}\n",
|
||||
"Function {\nname: \"A.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"A.fun\",\nsig: \"fn[[b:B], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"A.foo\",\nsig: \"fn[[a:T, b:V], none]\",\nvar_id: [164]\n}\n",
|
||||
"Function {\nname: \"A.foo\",\nsig: \"fn[[a:T, b:V], none]\",\nvar_id: [135]\n}\n",
|
||||
"Class {\nname: \"B\",\nancestors: [\"B\", \"C\", \"A\"],\nfields: [\"a\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[b:B], none]\"), (\"foo\", \"fn[[a:T, b:V], none]\")],\ntype_vars: []\n}\n",
|
||||
"Function {\nname: \"B.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
"Class {\nname: \"C\",\nancestors: [\"C\", \"A\"],\nfields: [\"a\"],\nmethods: [(\"__init__\", \"fn[[], none]\"), (\"fun\", \"fn[[b:B], none]\"), (\"foo\", \"fn[[a:T, b:V], none]\")],\ntype_vars: []\n}\n",
|
||||
"Function {\nname: \"C.__init__\",\nsig: \"fn[[], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"C.fun\",\nsig: \"fn[[b:B], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"foo\",\nsig: \"fn[[a:A], none]\",\nvar_id: []\n}\n",
|
||||
"Function {\nname: \"ff\",\nsig: \"fn[[a:T], V]\",\nvar_id: [172]\n}\n",
|
||||
"Function {\nname: \"ff\",\nsig: \"fn[[a:T], V]\",\nvar_id: [143]\n}\n",
|
||||
]
|
||||
|
|
|
@ -291,7 +291,7 @@ pub fn impl_mod(
|
|||
impl_binop(unifier, store, ty, other_ty, ret_ty, &[Operator::Mod]);
|
||||
}
|
||||
|
||||
/// [Operator::MatMult]
|
||||
/// [`Operator::MatMult`]
|
||||
pub fn impl_matmul(
|
||||
unifier: &mut Unifier,
|
||||
store: &PrimitiveStore,
|
||||
|
@ -299,7 +299,7 @@ pub fn impl_matmul(
|
|||
other_ty: &[Type],
|
||||
ret_ty: Option<Type>,
|
||||
) {
|
||||
impl_binop(unifier, store, ty, other_ty, ret_ty, &[Operator::MatMult])
|
||||
impl_binop(unifier, store, ty, other_ty, ret_ty, &[Operator::MatMult]);
|
||||
}
|
||||
|
||||
/// `UAdd`, `USub`
|
||||
|
|
|
@ -14,17 +14,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
use itertools::{Itertools, izip};
|
||||
use nac3parser::ast::{
|
||||
self,
|
||||
fold::{self, Fold},
|
||||
Arguments,
|
||||
Comprehension,
|
||||
ExprContext,
|
||||
ExprKind,
|
||||
Located,
|
||||
Location,
|
||||
StrRef
|
||||
};
|
||||
use nac3parser::ast::{self, fold::{self, Fold}, Arguments, Comprehension, ExprContext, ExprKind, Located, Location, StrRef};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
@ -860,66 +850,238 @@ impl<'a> Inferencer<'a> {
|
|||
},
|
||||
}))
|
||||
}
|
||||
// int64 is special because its argument can be a constant larger than int32
|
||||
if id == &"int64".into() && args.len() == 1 {
|
||||
if let ExprKind::Constant { value: ast::Constant::Int(val), kind } =
|
||||
&args[0].node
|
||||
{
|
||||
let custom = Some(self.primitives.int64);
|
||||
let v: Result<i64, _> = (*val).try_into();
|
||||
return if v.is_ok() {
|
||||
Ok(Some(Located {
|
||||
location: args[0].location,
|
||||
custom,
|
||||
node: ExprKind::Constant {
|
||||
value: ast::Constant::Int(*val),
|
||||
kind: kind.clone(),
|
||||
},
|
||||
}))
|
||||
} else {
|
||||
report_error("Integer out of bound", args[0].location)
|
||||
}
|
||||
}
|
||||
|
||||
if [
|
||||
"int32",
|
||||
"float",
|
||||
"bool",
|
||||
"np_isnan",
|
||||
"np_isinf",
|
||||
].iter().any(|fun_id| id == &(*fun_id).into()) && args.len() == 1 {
|
||||
let target_ty = if id == &"int32".into() {
|
||||
self.primitives.int32
|
||||
} else if id == &"float".into() {
|
||||
self.primitives.float
|
||||
} else if id == &"bool".into() || id == &"np_isnan".into() || id == &"np_isinf".into() {
|
||||
self.primitives.bool
|
||||
} else { unreachable!() };
|
||||
|
||||
let arg0 = self.fold_expr(args.remove(0))?;
|
||||
let arg0_ty = arg0.custom.unwrap();
|
||||
|
||||
let ret = if arg0_ty.obj_id(self.unifier).is_some_and(|id| id == PRIMITIVE_DEF_IDS.ndarray) {
|
||||
let (_, ndarray_ndims) = unpack_ndarray_var_tys(self.unifier, arg0_ty);
|
||||
|
||||
make_ndarray_ty(self.unifier, self.primitives, Some(target_ty), Some(ndarray_ndims))
|
||||
} else {
|
||||
target_ty
|
||||
};
|
||||
|
||||
let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![
|
||||
FuncArg {
|
||||
name: "n".into(),
|
||||
ty: arg0.custom.unwrap(),
|
||||
default_value: None,
|
||||
},
|
||||
],
|
||||
ret,
|
||||
vars: VarMap::new(),
|
||||
}));
|
||||
|
||||
return Ok(Some(Located {
|
||||
location,
|
||||
custom: Some(ret),
|
||||
node: ExprKind::Call {
|
||||
func: Box::new(Located {
|
||||
custom: Some(custom),
|
||||
location: func.location,
|
||||
node: ExprKind::Name { id: *id, ctx: ctx.clone() },
|
||||
}),
|
||||
args: vec![arg0],
|
||||
keywords: vec![],
|
||||
},
|
||||
}))
|
||||
}
|
||||
if id == &"uint32".into() && args.len() == 1 {
|
||||
if let ExprKind::Constant { value: ast::Constant::Int(val), kind } =
|
||||
&args[0].node
|
||||
{
|
||||
let custom = Some(self.primitives.uint32);
|
||||
let v: Result<u32, _> = (*val).try_into();
|
||||
return if v.is_ok() {
|
||||
Ok(Some(Located {
|
||||
location: args[0].location,
|
||||
custom,
|
||||
node: ExprKind::Constant {
|
||||
value: ast::Constant::Int(*val),
|
||||
kind: kind.clone(),
|
||||
},
|
||||
}))
|
||||
} else {
|
||||
report_error("Integer out of bound", args[0].location)
|
||||
}
|
||||
|
||||
if [
|
||||
"np_arctan2",
|
||||
"np_copysign",
|
||||
"np_fmax",
|
||||
"np_fmin",
|
||||
"np_ldexp",
|
||||
"np_hypot",
|
||||
"np_nextafter",
|
||||
].iter().any(|fun_id| id == &(*fun_id).into()) && args.len() == 2 {
|
||||
let target_ty = self.primitives.float;
|
||||
|
||||
let arg0 = self.fold_expr(args.remove(0))?;
|
||||
let arg0_ty = arg0.custom.unwrap();
|
||||
let arg1 = self.fold_expr(args.remove(0))?;
|
||||
let arg1_ty = arg1.custom.unwrap();
|
||||
|
||||
let arg0_dtype = if arg0_ty.obj_id(self.unifier).is_some_and(|id| id == PRIMITIVE_DEF_IDS.ndarray) {
|
||||
unpack_ndarray_var_tys(self.unifier, arg0_ty).0
|
||||
} else {
|
||||
arg0_ty
|
||||
};
|
||||
|
||||
let arg1_dtype = if arg1_ty.obj_id(self.unifier).is_some_and(|id| id == PRIMITIVE_DEF_IDS.ndarray) {
|
||||
unpack_ndarray_var_tys(self.unifier, arg1_ty).0
|
||||
} else {
|
||||
arg1_ty
|
||||
};
|
||||
let expected_arg1_dtype = if id == &"np_ldexp".into() {
|
||||
self.primitives.int32
|
||||
} else {
|
||||
arg0_dtype
|
||||
};
|
||||
if !self.unifier.unioned(arg1_dtype, expected_arg1_dtype) {
|
||||
return report_error(
|
||||
format!(
|
||||
"Expected {} for second argument of {id}, got {}",
|
||||
self.unifier.stringify(expected_arg1_dtype),
|
||||
self.unifier.stringify(arg1_dtype),
|
||||
).as_str(),
|
||||
arg0.location,
|
||||
)
|
||||
}
|
||||
|
||||
let ret = if [
|
||||
&arg0_ty,
|
||||
&arg1_ty,
|
||||
].into_iter().any(|arg_ty| arg_ty.obj_id(self.unifier).is_some_and(|id| id == PRIMITIVE_DEF_IDS.ndarray)) {
|
||||
// typeof_ndarray_broadcast requires both dtypes to be the same, but ldexp accepts
|
||||
// (float, int32), so convert it to align with the dtype of the first arg
|
||||
let arg1_ty = if id == &"np_ldexp".into() {
|
||||
if arg1_ty.obj_id(self.unifier).is_some_and(|id| id == PRIMITIVE_DEF_IDS.ndarray) {
|
||||
let (_, ndims) = unpack_ndarray_var_tys(self.unifier, arg1_ty);
|
||||
|
||||
make_ndarray_ty(self.unifier, self.primitives, Some(target_ty), Some(ndims))
|
||||
} else {
|
||||
target_ty
|
||||
}
|
||||
} else {
|
||||
arg1_ty
|
||||
};
|
||||
|
||||
match typeof_ndarray_broadcast(self.unifier, self.primitives, arg0_ty, arg1_ty) {
|
||||
Ok(broadcasted_ty) => broadcasted_ty,
|
||||
Err(err) => return report_error(err.as_str(), location),
|
||||
}
|
||||
} else {
|
||||
target_ty
|
||||
};
|
||||
|
||||
let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![
|
||||
FuncArg {
|
||||
name: "x1".into(),
|
||||
ty: arg0.custom.unwrap(),
|
||||
default_value: None,
|
||||
},
|
||||
FuncArg {
|
||||
name: "x2".into(),
|
||||
ty: arg1.custom.unwrap(),
|
||||
default_value: None,
|
||||
},
|
||||
],
|
||||
ret,
|
||||
vars: VarMap::new(),
|
||||
}));
|
||||
|
||||
return Ok(Some(Located {
|
||||
location,
|
||||
custom: Some(ret),
|
||||
node: ExprKind::Call {
|
||||
func: Box::new(Located {
|
||||
custom: Some(custom),
|
||||
location: func.location,
|
||||
node: ExprKind::Name { id: *id, ctx: ctx.clone() },
|
||||
}),
|
||||
args: vec![arg0, arg1],
|
||||
keywords: vec![],
|
||||
},
|
||||
}))
|
||||
}
|
||||
if id == &"uint64".into() && args.len() == 1 {
|
||||
if let ExprKind::Constant { value: ast::Constant::Int(val), kind } =
|
||||
&args[0].node
|
||||
{
|
||||
let custom = Some(self.primitives.uint64);
|
||||
let v: Result<u64, _> = (*val).try_into();
|
||||
return if v.is_ok() {
|
||||
Ok(Some(Located {
|
||||
location: args[0].location,
|
||||
custom,
|
||||
node: ExprKind::Constant {
|
||||
value: ast::Constant::Int(*val),
|
||||
kind: kind.clone(),
|
||||
},
|
||||
}))
|
||||
} else {
|
||||
report_error("Integer out of bound", args[0].location)
|
||||
|
||||
// int64, uint32 and uint64 are special because their argument can be a constant outside the
|
||||
// range of int32s
|
||||
if [
|
||||
"int64",
|
||||
"uint32",
|
||||
"uint64",
|
||||
].iter().any(|fun_id| id == &(*fun_id).into()) && args.len() == 1 {
|
||||
let target_ty = if id == &"int64".into() {
|
||||
self.primitives.int64
|
||||
} else if id == &"uint32".into() {
|
||||
self.primitives.uint32
|
||||
} else if id == &"uint64".into() {
|
||||
self.primitives.uint64
|
||||
} else { unreachable!() };
|
||||
|
||||
let arg0 = self.fold_expr(args.remove(0))?;
|
||||
let arg0_ty = arg0.custom.unwrap();
|
||||
|
||||
let ret = if arg0_ty.obj_id(self.unifier).is_some_and(|id| id == PRIMITIVE_DEF_IDS.ndarray) {
|
||||
let (_, ndarray_ndims) = unpack_ndarray_var_tys(self.unifier, arg0_ty);
|
||||
|
||||
make_ndarray_ty(self.unifier, self.primitives, Some(target_ty), Some(ndarray_ndims))
|
||||
} else {
|
||||
if let ExprKind::Constant {
|
||||
value: ast::Constant::Int(val),
|
||||
kind
|
||||
} = &arg0.node {
|
||||
let conv_is_ok = if self.unifier.unioned(target_ty, self.primitives.int64) {
|
||||
i64::try_from(*val).is_ok()
|
||||
} else if self.unifier.unioned(target_ty, self.primitives.uint32) {
|
||||
u32::try_from(*val).is_ok()
|
||||
} else if self.unifier.unioned(target_ty, self.primitives.uint64) {
|
||||
u64::try_from(*val).is_ok()
|
||||
} else { unreachable!() };
|
||||
|
||||
return if conv_is_ok {
|
||||
Ok(Some(Located {
|
||||
location: arg0.location,
|
||||
custom: Some(target_ty),
|
||||
node: ExprKind::Constant {
|
||||
value: ast::Constant::Int(*val),
|
||||
kind: kind.clone(),
|
||||
},
|
||||
}))
|
||||
} else {
|
||||
report_error("Integer out of bound", arg0.location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target_ty
|
||||
};
|
||||
|
||||
let custom = self.unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![
|
||||
FuncArg {
|
||||
name: "n".into(),
|
||||
ty: arg0.custom.unwrap(),
|
||||
default_value: None,
|
||||
},
|
||||
],
|
||||
ret,
|
||||
vars: VarMap::new(),
|
||||
}));
|
||||
|
||||
return Ok(Some(Located {
|
||||
location,
|
||||
custom: Some(ret),
|
||||
node: ExprKind::Call {
|
||||
func: Box::new(Located {
|
||||
custom: Some(custom),
|
||||
location: func.location,
|
||||
node: ExprKind::Name { id: *id, ctx: ctx.clone() },
|
||||
}),
|
||||
args: vec![arg0],
|
||||
keywords: vec![],
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
// 1-argument ndarray n-dimensional creation functions
|
||||
|
|
|
@ -58,11 +58,38 @@ class _NDArrayDummy(Generic[T, N]):
|
|||
# https://stackoverflow.com/questions/67803260/how-to-create-a-type-alias-with-a-throw-away-generic
|
||||
NDArray = Union[npt.NDArray[T], _NDArrayDummy[T, N]]
|
||||
|
||||
def round_away_zero(x):
|
||||
if x >= 0.0:
|
||||
return math.floor(x + 0.5)
|
||||
def _bool(x):
|
||||
if isinstance(x, np.ndarray):
|
||||
return np.bool_(x)
|
||||
else:
|
||||
return math.ceil(x - 0.5)
|
||||
return bool(x)
|
||||
|
||||
def _float(x):
|
||||
if isinstance(x, np.ndarray):
|
||||
return np.float_(x)
|
||||
else:
|
||||
return float(x)
|
||||
|
||||
def round_away_zero(x):
|
||||
if isinstance(x, np.ndarray):
|
||||
return np.vectorize(round_away_zero)(x)
|
||||
else:
|
||||
if x >= 0.0:
|
||||
return math.floor(x + 0.5)
|
||||
else:
|
||||
return math.ceil(x - 0.5)
|
||||
|
||||
def _floor(x):
|
||||
if isinstance(x, np.ndarray):
|
||||
return np.vectorize(_floor)(x)
|
||||
else:
|
||||
return math.floor(x)
|
||||
|
||||
def _ceil(x):
|
||||
if isinstance(x, np.ndarray):
|
||||
return np.vectorize(_ceil)(x)
|
||||
else:
|
||||
return math.ceil(x)
|
||||
|
||||
def patch(module):
|
||||
def dbl_nan():
|
||||
|
@ -112,6 +139,8 @@ def patch(module):
|
|||
module.int64 = int64
|
||||
module.uint32 = uint32
|
||||
module.uint64 = uint64
|
||||
module.bool = _bool
|
||||
module.float = _float
|
||||
module.TypeVar = TypeVar
|
||||
module.ConstGeneric = ConstGeneric
|
||||
module.Generic = Generic
|
||||
|
@ -125,11 +154,11 @@ def patch(module):
|
|||
module.round = round_away_zero
|
||||
module.round64 = round_away_zero
|
||||
module.np_round = np.round
|
||||
module.floor = math.floor
|
||||
module.floor64 = math.floor
|
||||
module.floor = _floor
|
||||
module.floor64 = _floor
|
||||
module.np_floor = np.floor
|
||||
module.ceil = math.ceil
|
||||
module.ceil64 = math.ceil
|
||||
module.ceil = _ceil
|
||||
module.ceil64 = _ceil
|
||||
module.np_ceil = np.ceil
|
||||
|
||||
# NumPy ndarray functions
|
||||
|
|
|
@ -10,6 +10,10 @@ fi
|
|||
declare -a nac3args
|
||||
while [ $# -ge 1 ]; do
|
||||
case "$1" in
|
||||
--help)
|
||||
echo "Usage: run_demo.sh [--help] [--out OUTFILE] [--lli] [--debug] -- [NAC3ARGS...]"
|
||||
exit
|
||||
;;
|
||||
--out)
|
||||
shift
|
||||
outfile="$1"
|
||||
|
@ -20,13 +24,22 @@ while [ $# -ge 1 ]; do
|
|||
--debug)
|
||||
debug=1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
nac3args+=("$1")
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
while [ $# -ge 1 ]; do
|
||||
nac3args+=("$1")
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -n "$debug" ] && [ -e ../../target/debug/nac3standalone ]; then
|
||||
nac3standalone=../../target/debug/nac3standalone
|
||||
elif [ -e ../../target/release/nac3standalone ]; then
|
||||
|
|
|
@ -162,7 +162,7 @@ def test_np_expm1():
|
|||
|
||||
def test_np_cbrt():
|
||||
for x in [1.0, 8.0, 27.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(np_expm1(x))
|
||||
output_float64(np_cbrt(x))
|
||||
|
||||
def test_sp_spec_erf():
|
||||
for x in [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
@extern
|
||||
def dbl_nan() -> float:
|
||||
...
|
||||
|
||||
@extern
|
||||
def dbl_inf() -> float:
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_bool(x: bool):
|
||||
...
|
||||
|
@ -6,6 +14,18 @@ def output_bool(x: bool):
|
|||
def output_int32(x: int32):
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_int64(x: int64):
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_uint32(x: uint32):
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_uint64(x: uint64):
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_float64(x: float):
|
||||
...
|
||||
|
@ -24,6 +44,21 @@ def output_ndarray_int32_2(n: ndarray[int32, Literal[2]]):
|
|||
for c in range(len(n[r])):
|
||||
output_int32(n[r][c])
|
||||
|
||||
def output_ndarray_int64_2(n: ndarray[int64, Literal[2]]):
|
||||
for r in range(len(n)):
|
||||
for c in range(len(n[r])):
|
||||
output_int64(n[r][c])
|
||||
|
||||
def output_ndarray_uint32_2(n: ndarray[uint32, Literal[2]]):
|
||||
for r in range(len(n)):
|
||||
for c in range(len(n[r])):
|
||||
output_uint32(n[r][c])
|
||||
|
||||
def output_ndarray_uint64_2(n: ndarray[uint64, Literal[2]]):
|
||||
for r in range(len(n)):
|
||||
for c in range(len(n[r])):
|
||||
output_uint64(n[r][c])
|
||||
|
||||
def output_ndarray_float_1(n: ndarray[float, Literal[1]]):
|
||||
for i in range(len(n)):
|
||||
output_float64(n[i])
|
||||
|
@ -649,6 +684,586 @@ def test_ndarray_ge_broadcast_rhs_scalar():
|
|||
output_ndarray_float_2(x)
|
||||
output_ndarray_bool_2(y)
|
||||
|
||||
def test_ndarray_int32():
|
||||
x = np_identity(2)
|
||||
y = int32(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_int32_2(y)
|
||||
|
||||
def test_ndarray_int64():
|
||||
x = np_identity(2)
|
||||
y = int64(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_int64_2(y)
|
||||
|
||||
def test_ndarray_uint32():
|
||||
x = np_identity(2)
|
||||
y = uint32(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_uint32_2(y)
|
||||
|
||||
def test_ndarray_uint64():
|
||||
x = np_identity(2)
|
||||
y = uint64(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_uint64_2(y)
|
||||
|
||||
def test_ndarray_float():
|
||||
x = np_full([2, 2], 1)
|
||||
y = float(x)
|
||||
|
||||
output_ndarray_int32_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_bool():
|
||||
x = np_identity(2)
|
||||
y = bool(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_bool_2(y)
|
||||
|
||||
def test_ndarray_round():
|
||||
x = np_identity(2)
|
||||
xf32 = round(x)
|
||||
xf64 = round64(x)
|
||||
xff = np_round(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_int32_2(xf32)
|
||||
output_ndarray_int64_2(xf64)
|
||||
output_ndarray_float_2(xff)
|
||||
|
||||
def test_ndarray_floor():
|
||||
x = np_identity(2)
|
||||
xf32 = floor(x)
|
||||
xf64 = floor64(x)
|
||||
xff = np_floor(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_int32_2(xf32)
|
||||
output_ndarray_int64_2(xf64)
|
||||
output_ndarray_float_2(xff)
|
||||
|
||||
def test_ndarray_ceil():
|
||||
x = np_identity(2)
|
||||
xf32 = ceil(x)
|
||||
xf64 = ceil64(x)
|
||||
xff = np_ceil(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_int32_2(xf32)
|
||||
output_ndarray_int64_2(xf64)
|
||||
output_ndarray_float_2(xff)
|
||||
|
||||
def test_ndarray_abs():
|
||||
x = np_identity(2)
|
||||
y = abs(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_isnan():
|
||||
x = np_identity(2)
|
||||
x_isnan = np_isnan(x)
|
||||
y = np_full([2, 2], dbl_nan())
|
||||
y_isnan = np_isnan(y)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_bool_2(x_isnan)
|
||||
output_ndarray_float_2(y)
|
||||
output_ndarray_bool_2(y_isnan)
|
||||
|
||||
def test_ndarray_isinf():
|
||||
x = np_identity(2)
|
||||
x_isinf = np_isinf(x)
|
||||
y = np_full([2, 2], dbl_inf())
|
||||
y_isinf = np_isinf(y)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_bool_2(x_isinf)
|
||||
output_ndarray_float_2(y)
|
||||
output_ndarray_bool_2(y_isinf)
|
||||
|
||||
def test_ndarray_sin():
|
||||
x = np_identity(2)
|
||||
y = np_sin(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_cos():
|
||||
x = np_identity(2)
|
||||
y = np_cos(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_exp():
|
||||
x = np_identity(2)
|
||||
y = np_exp(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_exp2():
|
||||
x = np_identity(2)
|
||||
y = np_exp2(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_log():
|
||||
x = np_identity(2)
|
||||
y = np_log(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_log10():
|
||||
x = np_identity(2)
|
||||
y = np_log10(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_log2():
|
||||
x = np_identity(2)
|
||||
y = np_log2(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_fabs():
|
||||
x = -np_identity(2)
|
||||
y = np_fabs(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_sqrt():
|
||||
x = np_identity(2)
|
||||
y = np_sqrt(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_rint():
|
||||
x = np_identity(2)
|
||||
y = np_rint(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_tan():
|
||||
x = np_identity(2)
|
||||
y = np_tan(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arcsin():
|
||||
x = np_identity(2)
|
||||
y = np_arcsin(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arccos():
|
||||
x = np_identity(2)
|
||||
y = np_arccos(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arctan():
|
||||
x = np_identity(2)
|
||||
y = np_arctan(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_sinh():
|
||||
x = np_identity(2)
|
||||
y = np_sinh(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_cosh():
|
||||
x = np_identity(2)
|
||||
y = np_cosh(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_tanh():
|
||||
x = np_identity(2)
|
||||
y = np_tanh(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arcsinh():
|
||||
x = np_identity(2)
|
||||
y = np_arcsinh(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arccosh():
|
||||
x = np_identity(2)
|
||||
y = np_arccosh(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arctanh():
|
||||
x = np_identity(2)
|
||||
y = np_arctanh(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_expm1():
|
||||
x = np_identity(2)
|
||||
y = np_expm1(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_cbrt():
|
||||
x = np_identity(2)
|
||||
y = np_cbrt(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_erf():
|
||||
x = np_identity(2)
|
||||
y = sp_spec_erf(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_erfc():
|
||||
x = np_identity(2)
|
||||
y = sp_spec_erfc(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_gamma():
|
||||
x = np_identity(2)
|
||||
y = sp_spec_gamma(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_gammaln():
|
||||
x = np_identity(2)
|
||||
y = sp_spec_gammaln(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_j0():
|
||||
x = np_identity(2)
|
||||
y = sp_spec_j0(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_j1():
|
||||
x = np_identity(2)
|
||||
y = sp_spec_j1(x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(y)
|
||||
|
||||
def test_ndarray_arctan2():
|
||||
x = np_identity(2)
|
||||
zeros = np_zeros([2, 2])
|
||||
ones = np_ones([2, 2])
|
||||
atan2_x_zeros = np_arctan2(x, zeros)
|
||||
atan2_x_ones = np_arctan2(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(zeros)
|
||||
output_ndarray_float_2(ones)
|
||||
output_ndarray_float_2(atan2_x_zeros)
|
||||
output_ndarray_float_2(atan2_x_ones)
|
||||
|
||||
def test_ndarray_arctan2_broadcast():
|
||||
x = np_identity(2)
|
||||
atan2_x_zeros = np_arctan2(x, np_zeros([2]))
|
||||
atan2_x_ones = np_arctan2(x, np_ones([2]))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(atan2_x_zeros)
|
||||
output_ndarray_float_2(atan2_x_ones)
|
||||
|
||||
def test_ndarray_arctan2_broadcast_lhs_scalar():
|
||||
x = np_identity(2)
|
||||
atan2_x_zeros = np_arctan2(0.0, x)
|
||||
atan2_x_ones = np_arctan2(1.0, x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(atan2_x_zeros)
|
||||
output_ndarray_float_2(atan2_x_ones)
|
||||
|
||||
def test_ndarray_arctan2_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
atan2_x_zeros = np_arctan2(x, 0.0)
|
||||
atan2_x_ones = np_arctan2(x, 1.0)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(atan2_x_zeros)
|
||||
output_ndarray_float_2(atan2_x_ones)
|
||||
|
||||
def test_ndarray_copysign():
|
||||
x = np_identity(2)
|
||||
ones = np_ones([2, 2])
|
||||
negones = np_full([2, 2], -1.0)
|
||||
copysign_x_ones = np_copysign(x, ones)
|
||||
copysign_x_negones = np_copysign(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(ones)
|
||||
output_ndarray_float_2(negones)
|
||||
output_ndarray_float_2(copysign_x_ones)
|
||||
output_ndarray_float_2(copysign_x_negones)
|
||||
|
||||
def test_ndarray_copysign_broadcast():
|
||||
x = np_identity(2)
|
||||
copysign_x_ones = np_copysign(x, np_ones([2]))
|
||||
copysign_x_negones = np_copysign(x, np_full([2], -1.0))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(copysign_x_ones)
|
||||
output_ndarray_float_2(copysign_x_negones)
|
||||
|
||||
def test_ndarray_copysign_broadcast_lhs_scalar():
|
||||
x = np_identity(2)
|
||||
copysign_x_ones = np_copysign(1.0, x)
|
||||
copysign_x_negones = np_copysign(-1.0, x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(copysign_x_ones)
|
||||
output_ndarray_float_2(copysign_x_negones)
|
||||
|
||||
def test_ndarray_copysign_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
copysign_x_ones = np_copysign(x, 1.0)
|
||||
copysign_x_negones = np_copysign(x, -1.0)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(copysign_x_ones)
|
||||
output_ndarray_float_2(copysign_x_negones)
|
||||
|
||||
def test_ndarray_fmax():
|
||||
x = np_identity(2)
|
||||
ones = np_ones([2, 2])
|
||||
negones = np_full([2, 2], -1.0)
|
||||
fmax_x_ones = np_fmax(x, ones)
|
||||
fmax_x_negones = np_fmax(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(ones)
|
||||
output_ndarray_float_2(negones)
|
||||
output_ndarray_float_2(fmax_x_ones)
|
||||
output_ndarray_float_2(fmax_x_negones)
|
||||
|
||||
def test_ndarray_fmax_broadcast():
|
||||
x = np_identity(2)
|
||||
fmax_x_ones = np_fmax(x, np_ones([2]))
|
||||
fmax_x_negones = np_fmax(x, np_full([2], -1.0))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(fmax_x_ones)
|
||||
output_ndarray_float_2(fmax_x_negones)
|
||||
|
||||
def test_ndarray_fmax_broadcast_lhs_scalar():
|
||||
x = np_identity(2)
|
||||
fmax_x_ones = np_fmax(1.0, x)
|
||||
fmax_x_negones = np_fmax(-1.0, x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(fmax_x_ones)
|
||||
output_ndarray_float_2(fmax_x_negones)
|
||||
|
||||
def test_ndarray_fmax_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
fmax_x_ones = np_fmax(x, 1.0)
|
||||
fmax_x_negones = np_fmax(x, -1.0)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(fmax_x_ones)
|
||||
output_ndarray_float_2(fmax_x_negones)
|
||||
|
||||
def test_ndarray_fmin():
|
||||
x = np_identity(2)
|
||||
ones = np_ones([2, 2])
|
||||
negones = np_full([2, 2], -1.0)
|
||||
fmin_x_ones = np_fmin(x, ones)
|
||||
fmin_x_negones = np_fmin(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(ones)
|
||||
output_ndarray_float_2(negones)
|
||||
output_ndarray_float_2(fmin_x_ones)
|
||||
output_ndarray_float_2(fmin_x_negones)
|
||||
|
||||
def test_ndarray_fmin_broadcast():
|
||||
x = np_identity(2)
|
||||
fmin_x_ones = np_fmin(x, np_ones([2]))
|
||||
fmin_x_negones = np_fmin(x, np_full([2], -1.0))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(fmin_x_ones)
|
||||
output_ndarray_float_2(fmin_x_negones)
|
||||
|
||||
def test_ndarray_fmin_broadcast_lhs_scalar():
|
||||
x = np_identity(2)
|
||||
fmin_x_ones = np_fmin(1.0, x)
|
||||
fmin_x_negones = np_fmin(-1.0, x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(fmin_x_ones)
|
||||
output_ndarray_float_2(fmin_x_negones)
|
||||
|
||||
def test_ndarray_fmin_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
fmin_x_ones = np_fmin(x, 1.0)
|
||||
fmin_x_negones = np_fmin(x, -1.0)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(fmin_x_ones)
|
||||
output_ndarray_float_2(fmin_x_negones)
|
||||
|
||||
def test_ndarray_ldexp():
|
||||
x = np_identity(2)
|
||||
zeros = np_full([2, 2], 0)
|
||||
ones = np_full([2, 2], 1)
|
||||
ldexp_x_zeros = np_ldexp(x, zeros)
|
||||
ldexp_x_ones = np_ldexp(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_int32_2(zeros)
|
||||
output_ndarray_int32_2(ones)
|
||||
output_ndarray_float_2(ldexp_x_zeros)
|
||||
output_ndarray_float_2(ldexp_x_ones)
|
||||
|
||||
def test_ndarray_ldexp_broadcast():
|
||||
x = np_identity(2)
|
||||
ldexp_x_zeros = np_ldexp(x, np_full([2], 0))
|
||||
ldexp_x_ones = np_ldexp(x, np_full([2], 1))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(ldexp_x_zeros)
|
||||
output_ndarray_float_2(ldexp_x_ones)
|
||||
|
||||
def test_ndarray_ldexp_broadcast_lhs_scalar():
|
||||
x = int32(np_identity(2))
|
||||
ldexp_x_zeros = np_ldexp(0.0, x)
|
||||
ldexp_x_ones = np_ldexp(1.0, x)
|
||||
|
||||
output_ndarray_int32_2(x)
|
||||
output_ndarray_float_2(ldexp_x_zeros)
|
||||
output_ndarray_float_2(ldexp_x_ones)
|
||||
|
||||
def test_ndarray_ldexp_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
ldexp_x_zeros = np_ldexp(x, 0)
|
||||
ldexp_x_ones = np_ldexp(x, 1)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(ldexp_x_zeros)
|
||||
output_ndarray_float_2(ldexp_x_ones)
|
||||
|
||||
def test_ndarray_hypot():
|
||||
x = np_identity(2)
|
||||
zeros = np_zeros([2, 2])
|
||||
ones = np_ones([2, 2])
|
||||
hypot_x_zeros = np_hypot(x, zeros)
|
||||
hypot_x_ones = np_hypot(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(zeros)
|
||||
output_ndarray_float_2(ones)
|
||||
output_ndarray_float_2(hypot_x_zeros)
|
||||
output_ndarray_float_2(hypot_x_ones)
|
||||
|
||||
def test_ndarray_hypot_broadcast():
|
||||
x = np_identity(2)
|
||||
hypot_x_zeros = np_hypot(x, np_zeros([2]))
|
||||
hypot_x_ones = np_hypot(x, np_ones([2]))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(hypot_x_zeros)
|
||||
output_ndarray_float_2(hypot_x_ones)
|
||||
|
||||
def test_ndarray_hypot_broadcast_lhs_scalar():
|
||||
x = np_identity(2)
|
||||
hypot_x_zeros = np_hypot(0.0, x)
|
||||
hypot_x_ones = np_hypot(1.0, x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(hypot_x_zeros)
|
||||
output_ndarray_float_2(hypot_x_ones)
|
||||
|
||||
def test_ndarray_hypot_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
hypot_x_zeros = np_hypot(x, 0.0)
|
||||
hypot_x_ones = np_hypot(x, 1.0)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(hypot_x_zeros)
|
||||
output_ndarray_float_2(hypot_x_ones)
|
||||
|
||||
def test_ndarray_nextafter():
|
||||
x = np_identity(2)
|
||||
zeros = np_zeros([2, 2])
|
||||
ones = np_ones([2, 2])
|
||||
nextafter_x_zeros = np_nextafter(x, zeros)
|
||||
nextafter_x_ones = np_nextafter(x, ones)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(zeros)
|
||||
output_ndarray_float_2(ones)
|
||||
output_ndarray_float_2(nextafter_x_zeros)
|
||||
output_ndarray_float_2(nextafter_x_ones)
|
||||
|
||||
def test_ndarray_nextafter_broadcast():
|
||||
x = np_identity(2)
|
||||
nextafter_x_zeros = np_nextafter(x, np_zeros([2]))
|
||||
nextafter_x_ones = np_nextafter(x, np_ones([2]))
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(nextafter_x_zeros)
|
||||
output_ndarray_float_2(nextafter_x_ones)
|
||||
|
||||
def test_ndarray_nextafter_broadcast_lhs_scalar():
|
||||
x = np_identity(2)
|
||||
nextafter_x_zeros = np_nextafter(0.0, x)
|
||||
nextafter_x_ones = np_nextafter(1.0, x)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(nextafter_x_zeros)
|
||||
output_ndarray_float_2(nextafter_x_ones)
|
||||
|
||||
def test_ndarray_nextafter_broadcast_rhs_scalar():
|
||||
x = np_identity(2)
|
||||
nextafter_x_zeros = np_nextafter(x, 0.0)
|
||||
nextafter_x_ones = np_nextafter(x, 1.0)
|
||||
|
||||
output_ndarray_float_2(x)
|
||||
output_ndarray_float_2(nextafter_x_zeros)
|
||||
output_ndarray_float_2(nextafter_x_ones)
|
||||
|
||||
def run() -> int32:
|
||||
test_ndarray_ctor()
|
||||
test_ndarray_empty()
|
||||
|
@ -739,4 +1354,76 @@ def run() -> int32:
|
|||
test_ndarray_ge_broadcast_lhs_scalar()
|
||||
test_ndarray_ge_broadcast_rhs_scalar()
|
||||
|
||||
test_ndarray_int32()
|
||||
test_ndarray_int64()
|
||||
test_ndarray_uint32()
|
||||
test_ndarray_uint64()
|
||||
test_ndarray_float()
|
||||
test_ndarray_bool()
|
||||
|
||||
test_ndarray_round()
|
||||
test_ndarray_floor()
|
||||
test_ndarray_abs()
|
||||
test_ndarray_isnan()
|
||||
test_ndarray_isinf()
|
||||
|
||||
test_ndarray_sin()
|
||||
test_ndarray_cos()
|
||||
test_ndarray_exp()
|
||||
test_ndarray_exp2()
|
||||
test_ndarray_log()
|
||||
test_ndarray_log10()
|
||||
test_ndarray_log2()
|
||||
test_ndarray_fabs()
|
||||
test_ndarray_sqrt()
|
||||
test_ndarray_rint()
|
||||
test_ndarray_tan()
|
||||
test_ndarray_arcsin()
|
||||
test_ndarray_arccos()
|
||||
test_ndarray_arctan()
|
||||
test_ndarray_sinh()
|
||||
test_ndarray_cosh()
|
||||
test_ndarray_tanh()
|
||||
test_ndarray_arcsinh()
|
||||
test_ndarray_arccosh()
|
||||
test_ndarray_arctanh()
|
||||
test_ndarray_expm1()
|
||||
test_ndarray_cbrt()
|
||||
|
||||
test_ndarray_erf()
|
||||
test_ndarray_erfc()
|
||||
test_ndarray_gamma()
|
||||
test_ndarray_gammaln()
|
||||
test_ndarray_j0()
|
||||
test_ndarray_j1()
|
||||
|
||||
test_ndarray_arctan2()
|
||||
test_ndarray_arctan2_broadcast()
|
||||
test_ndarray_arctan2_broadcast_lhs_scalar()
|
||||
test_ndarray_arctan2_broadcast_rhs_scalar()
|
||||
test_ndarray_copysign()
|
||||
test_ndarray_copysign_broadcast()
|
||||
test_ndarray_copysign_broadcast_lhs_scalar()
|
||||
test_ndarray_copysign_broadcast_rhs_scalar()
|
||||
test_ndarray_fmax()
|
||||
test_ndarray_fmax_broadcast()
|
||||
test_ndarray_fmax_broadcast_lhs_scalar()
|
||||
test_ndarray_fmax_broadcast_rhs_scalar()
|
||||
test_ndarray_fmin()
|
||||
test_ndarray_fmin_broadcast()
|
||||
test_ndarray_fmin_broadcast_lhs_scalar()
|
||||
test_ndarray_fmin_broadcast_rhs_scalar()
|
||||
test_ndarray_ldexp()
|
||||
test_ndarray_ldexp_broadcast()
|
||||
test_ndarray_ldexp_broadcast_lhs_scalar()
|
||||
test_ndarray_ldexp_broadcast_rhs_scalar()
|
||||
test_ndarray_hypot()
|
||||
test_ndarray_hypot_broadcast()
|
||||
test_ndarray_hypot_broadcast_lhs_scalar()
|
||||
test_ndarray_hypot_broadcast_rhs_scalar()
|
||||
test_ndarray_nextafter()
|
||||
test_ndarray_nextafter_broadcast()
|
||||
test_ndarray_nextafter_broadcast_lhs_scalar()
|
||||
test_ndarray_nextafter_broadcast_rhs_scalar()
|
||||
|
||||
return 0
|
||||
|
|
Loading…
Reference in New Issue