diff --git a/.cargo/config b/.cargo/config index c1ca86b..b8239db 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,3 @@ -[build] -target = "x86_64-unknown-linux-musl" \ No newline at end of file +#[build] +# disabled to allow dynamic library loading +#target = "x86_64-unknown-linux-musl" diff --git a/.github/workflows/latest.yml b/.github/workflows/latest.yml index b5a2b75..bf278d8 100644 --- a/.github/workflows/latest.yml +++ b/.github/workflows/latest.yml @@ -15,7 +15,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: toolchain: stable - targets: x86_64-unknown-linux-musl + # targets: x86_64-unknown-linux-musl - run: cargo test --verbose -- --nocapture docker: needs: test diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index c8d6e94..7cbab78 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -15,7 +15,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: toolchain: stable - targets: x86_64-unknown-linux-musl + # targets: x86_64-unknown-linux-musl - run: cargo test --verbose -- --nocapture - run: cargo clippy --all-targets --all-features -- -D warnings - run: cargo publish --dry-run diff --git a/Cargo.lock b/Cargo.lock index 6a4e240..3b6e6be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "ctrlc", "dirs", "env_logger", + "libloading", "log", "nom", "nu-ansi-term", @@ -27,11 +28,12 @@ dependencies = [ [[package]] name = "adana-script-core" -version = "0.13.36" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e72e54f36994db91607a6809768eb01183541d2ce9965abdfa011297d716420" +checksum = "fc751b4cbe44cc3a2f50bc2b8a46d1712d566de867f60ba26eea051841a580c7" dependencies = [ "anyhow", + "libloading", "serde", "serde_derive", "strum", @@ -39,9 +41,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -75,15 +77,18 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -114,9 +119,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", "hashbrown", @@ -163,9 +168,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -194,9 +199,9 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.12" +version = "3.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ae6b3d9530211fb3b12a95374b8b0823be812f53d09e18c5675c0146b09642" +checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", "rustix", @@ -293,9 +298,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "heck" @@ -303,12 +308,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - [[package]] name = "home" version = "0.5.5" @@ -318,22 +317,11 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "lazy_static" @@ -347,11 +335,21 @@ version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +[[package]] +name = "libloading" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +dependencies = [ + "cfg-if", + "windows-sys", +] + [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" @@ -392,14 +390,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "static_assertions", ] [[package]] @@ -408,7 +405,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "cfg-if", "libc", ] @@ -469,9 +466,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -481,18 +478,18 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -567,13 +564,12 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -581,9 +577,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rustyline" @@ -591,7 +587,7 @@ version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "994eca4bca05c87e86e15d90fc7a91d1be64b4482b38cb2d27474568fe7c9db9" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "cfg-if", "clipboard-win", "fd-lock", @@ -599,7 +595,7 @@ dependencies = [ "libc", "log", "memchr", - "nix 0.26.2", + "nix 0.26.4", "radix_trie", "scopeguard", "unicode-segmentation", @@ -621,15 +617,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" @@ -689,9 +685,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -707,9 +703,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "snowflake" @@ -717,12 +713,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27207bb65232eda1f588cf46db2fee75c0808d557f6b3cf19a75f5d6d7c94df1" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "str-buf" version = "1.0.6" @@ -740,9 +730,9 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" dependencies = [ "heck", "proc-macro2", @@ -753,9 +743,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -764,18 +754,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", @@ -784,9 +774,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" @@ -796,9 +786,9 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "utf8parse" @@ -845,9 +835,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -860,42 +850,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 2933275..0cc1656 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [package] name = "adana" +rust-version = "1.72" + version = "0.13.35" edition = "2021" authors = ["Nordine Bittich"] @@ -32,7 +34,11 @@ serde_json = "1.0.107" slab_tree = "0.3.2" strum = { version = "0.25.0", features = ["derive"] } ctrlc = "3.4.1" -adana-script-core = "0.13.36" + +#adana-script-core = { git = "https://github.com/nbittich/adana-script-core.git" } +adana-script-core = "0.14.0" + +libloading = "0.8.0" [dependencies.env_logger] default-features = false version = "0.10.0" diff --git a/Dockerfile b/Dockerfile index a563bbc..19e64f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ COPY ./Cargo.toml ./Cargo.lock ./ COPY .cargo/config .cargo/config -ENV RUSTFLAGS='-C link-arg=-s' +# ENV RUSTFLAGS='-C link-arg=-s' RUN cargo build --release @@ -20,16 +20,16 @@ RUN rm -rf ./src COPY ./src/ ./src -RUN rm ./target/x86_64-unknown-linux-musl/release/deps/adana* +RUN rm ./target/release/deps/adana* RUN cargo build --release -FROM alpine +FROM rust:1.72.1-bullseye ENV RUST_LOG=info VOLUME /root/.local/share -COPY --from=builder /app/adana/target/x86_64-unknown-linux-musl/release/adana . +COPY --from=builder /app/adana/target/release/adana . ENTRYPOINT [ "/adana" ] diff --git a/README.md b/README.md index b4ed21b..7b6537b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Scripting programming language, repl and namespaced aliases for commands. - [Operators and constants](#operators-and-constants) - [Variable definition](#variable-definition) - [Memory Management](#memory-management) + - [Plugins](#plugins) - [Loops](#loops) - [Ranges](#ranges) - [Conditions](#conditions) @@ -54,11 +55,7 @@ My favorite dish 😋 ## Installation -1. Static binary - - Download the latest statically linked binary available in `static_binaries` - (only tested with Linux) - - make the binary executable : `chmod a+x adana-` -2. Docker +1. Docker - From the docker hub: - `docker run -it nbittich/adana # latest from master` - `docker run -it nbittich/adana:0.13.23 # latest release` @@ -66,13 +63,13 @@ My favorite dish 😋 - clone the repo - build the docker image: `docker build -t adana .` - `docker run -it adana` -3. Cargo +2. Cargo - From crate.io: - `cargo install adana` - `adana` - Manually: - `cargo build --release` - - `./target/x86_64-unknown-linux-musl/release/adana` + - `./target/release/adana`
@@ -293,6 +290,40 @@ x = 100 # now y == 100
+### Plugins + +It is possible to load plugins written in rust dyanmically. +Because Rust doesn't have a stable ABI yet, the plugin must be built with the same version that +was used to build adana. + +The rust version is specified when running the repl. + +To load a dynamic library, you can either specify a relative path, or an +absolute path. In case of a relative path, it should be relative to the +shared lib path (by default: `$HOME/.local/share/.libs_adana`). + +You can override this by providing a path when starting the repl (e.g: `adana --slp /tmp`). + +If the path is a directory, it will try to build it using `cargo`, so you +need to have rust installed on your machine. + +If it is an `.so` file, it will automatically load it. + +An example of plugin can be found in this repo (`dynamic_lib/example_lib_src`). + +For example: + +- Copy the SO file in tmp: `cp dynamic_lib/libplugin_example.so /tmp/` +- Run and override the lib path: `adana -slp /tmp` +- Execute the following: + +```python + lib = require("libplugin_example.so") + text = lib.hello("Nordine", "la", "forme?") +``` + +
+ ### Loops There are two loops, the while loop and the for-each loop. @@ -749,3 +780,8 @@ adana --inmemory adana --dbpath /tmp/mydb.db --historypath /tmp/myhistory.txt --nofb ``` + +``` +# specify shared lib path +adana -slp /tmp/shared +``` diff --git a/README.old.md b/README.old.md deleted file mode 100644 index 911eef8..0000000 --- a/README.old.md +++ /dev/null @@ -1,54 +0,0 @@ -# Adana - repl / scripting language / namespaced command line aliases - -- use help for help -- scripting: check file_tests for syntax and examples - - -Static build using MUSL: - -``` -cargo build --release -``` - -should print "statically linked": - -``` -ldd target/x86_64-unknown-linux-musl/release/adana - -``` - -### install using cargo - -``` -cargo install adana --target x86_64-unknown-linux-musl -``` - -### logs -RUST_LOG=info adana - - -### docker - -``` -docker build -t adana . - -docker run -it adana - -``` - -### Args - override - -``` -# open an in memory db - -adana --inmemory - -``` - -``` -# override db path & history path + fallback in memory in case of an error (default to false) -# path must exist! file doesn't have to. - -adana --dbpath /tmp/mydb.db --historypath /tmp/myhistory.txt --fallback - -``` \ No newline at end of file diff --git a/TODO.md b/TODO.md index 7700f20..9ab730c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,20 +1,16 @@ -## Todo +## Todo + +- check abi_stable crate +- make a std library - stabilize, more tests - better error -- make a std library -- import/require => like include but scoped context & functions - - could be like - ``` - std = import("/path/to/std") - std.read_file_to_string("/path/to/file") # call to a function - pi = std.PI # get a variable - ``` - update readme - less cloning ## In progress ## Done + - Foreach - Context scope - break should not be a primitive @@ -27,9 +23,16 @@ - function & function call - rename project - string to array (split? or just each character as a single string in an array) -- variable should start with a letter but can have alphanumeric and maybe _ in it +- variable should start with a letter but can have alphanumeric and maybe \_ in it - array len function - array / index - tests array index - return the Primitive::Error, implement display - else / else if + +- import/require => like include but scoped context & functions - could be like +` std = import("/path/to/std") + std.read_file_to_string("/path/to/file") # call to a function + pi = std.PI # get a variable + ` + diff --git a/build_musl.sh b/build_musl.sh deleted file mode 100755 index 763715d..0000000 --- a/build_musl.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -set -e - -if [[ -z "$1" ]] -then - echo "version mut be provided" - exit 1; -fi - -mkdir -p static_binaries -cargo build --release -cp target/x86_64-unknown-linux-musl/release/adana static_binaries/adana-$1 diff --git a/dynamic_lib/example_lib_src/.gitignore b/dynamic_lib/example_lib_src/.gitignore new file mode 100644 index 0000000..f00b4de --- /dev/null +++ b/dynamic_lib/example_lib_src/.gitignore @@ -0,0 +1,3 @@ +/target +.idea +.history \ No newline at end of file diff --git a/dynamic_lib/example_lib_src/Cargo.lock b/dynamic_lib/example_lib_src/Cargo.lock new file mode 100644 index 0000000..f46bc8c --- /dev/null +++ b/dynamic_lib/example_lib_src/Cargo.lock @@ -0,0 +1,201 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adana-script-core" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc751b4cbe44cc3a2f50bc2b8a46d1712d566de867f60ba26eea051841a580c7" +dependencies = [ + "anyhow", + "libloading", + "serde", + "serde_derive", + "strum", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "libloading" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "plugin_example" +version = "0.1.0" +dependencies = [ + "adana-script-core", + "anyhow", +] + +[[package]] +name = "proc-macro2" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/dynamic_lib/example_lib_src/Cargo.toml b/dynamic_lib/example_lib_src/Cargo.toml new file mode 100644 index 0000000..3302794 --- /dev/null +++ b/dynamic_lib/example_lib_src/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "plugin_example" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["dylib"] + +[dependencies] +adana-script-core = "0.14.0" +anyhow = "1.0.75" + +[profile.release] +opt-level = 'z' # Optimize for size. +lto = true # Link Time Optimization (LTO) +codegen-units = 1 # Set this to 1 to allow for maximum size reduction optimizations: +panic = 'abort' # removes the need for this extra unwinding code. +strip = "symbols" diff --git a/dynamic_lib/example_lib_src/src/lib.rs b/dynamic_lib/example_lib_src/src/lib.rs new file mode 100644 index 0000000..686447a --- /dev/null +++ b/dynamic_lib/example_lib_src/src/lib.rs @@ -0,0 +1,39 @@ +use std::collections::BTreeMap; + +use adana_script_core::{ + primitive::{Compiler, NativeFunctionCallResult, Primitive}, + Value, +}; +use anyhow::Context; + +#[no_mangle] +pub fn hello( + params: Vec, + _compiler: Box, +) -> NativeFunctionCallResult { + let mut s = String::from("Hello"); + for p in params.iter() { + s.push(' '); + s.push_str(&p.to_string()); + } + Ok(Primitive::String(s)) +} +#[no_mangle] +pub fn callback( + mut params: Vec, + mut compiler: Box, +) -> NativeFunctionCallResult { + let s = String::from("Hello"); + + let res = Primitive::String(s); + let prim = params.get_mut(0).context("missing function parameters")?; + let prim_callback = prim.clone().to_value()?; + let fn_call = Value::FunctionCall { + parameters: Box::new(Value::BlockParen(vec![res.to_value()?])), + function: Box::new(prim_callback), + }; + + let ctx = BTreeMap::new(); + let r = compiler(fn_call, ctx)?; + Ok(r) +} diff --git a/dynamic_lib/libplugin_example.so b/dynamic_lib/libplugin_example.so new file mode 100755 index 0000000..325e507 Binary files /dev/null and b/dynamic_lib/libplugin_example.so differ diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 2583790..ac8ea95 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,3 @@ [toolchain] channel = "stable" host = "1.72.1" -targets = ["x86_64-unknown-linux-musl"] diff --git a/sample.json b/sample.json index 4d15410..551c825 100644 --- a/sample.json +++ b/sample.json @@ -40,9 +40,7 @@ "name": "misc", "values": { "bash": "bash", - "buildmusl": "bash build_musl.sh", "cloc": "cloc", - "distls": "ls -alh ./dist/musl", "drc": "docker-compose", "ls": "ls", "nu": "nu", @@ -85,4 +83,5 @@ "tree": "cargo tree", "vim": "nvim" } - }] \ No newline at end of file + } +] diff --git a/src/adana_script/compute.rs b/src/adana_script/compute.rs index 64de2ae..32fd668 100644 --- a/src/adana_script/compute.rs +++ b/src/adana_script/compute.rs @@ -6,12 +6,13 @@ use std::{ fs::{read_to_string, File}, io::{BufRead, BufReader}, path::{Path, PathBuf}, + rc::Rc, sync::Arc, }; use crate::{adana_script::parser::parse_instructions, prelude::BTreeMap}; -use super::ast::to_ast; +use super::{ast::to_ast, require_dynamic_lib::require_dynamic_lib}; use adana_script_core::{ primitive::{ Abs, Add, And, Array, Cos, Div, Logarithm, Mul, Neg, Not, Or, Pow, @@ -24,6 +25,7 @@ use adana_script_core::{ fn compute_recur( node: Option>, ctx: &mut BTreeMap, + shared_lib: impl AsRef + Copy, ) -> anyhow::Result { if let Some(node) = node { match node.data() { @@ -33,23 +35,23 @@ fn compute_recur( "only one value allowed, no '!' possible", )); } - let left = compute_recur(node.first_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; Ok(left.not()) } TreeNodeValue::Ops(Operator::Add) => { if node.children().count() == 1 { - return compute_recur(node.first_child(), ctx); + return compute_recur(node.first_child(), ctx, shared_lib); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.add(&right)) } TreeNodeValue::Ops(Operator::Mult) => { if node.children().count() == 1 { - return compute_recur(node.first_child(), ctx); + return compute_recur(node.first_child(), ctx, shared_lib); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.mul(&right)) } TreeNodeValue::VariableRef(name) => { @@ -69,26 +71,31 @@ fn compute_recur( } TreeNodeValue::Ops(Operator::Mod) => { if node.children().count() == 1 { - return compute_recur(node.first_child(), ctx); + return compute_recur(node.first_child(), ctx, shared_lib); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.rem(&right)) } TreeNodeValue::Ops(Operator::Subtr) => { if node.children().count() == 1 { - return Ok(compute_recur(node.first_child(), ctx)?.neg()); - } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + return Ok(compute_recur( + node.first_child(), + ctx, + shared_lib, + )? + .neg()); + } + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.sub(&right)) } TreeNodeValue::Ops(Operator::Pow) => { if node.children().count() == 1 { - return compute_recur(node.first_child(), ctx); + return compute_recur(node.first_child(), ctx, shared_lib); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.pow(&right)) } TreeNodeValue::Ops(Operator::Pow2) => { @@ -99,10 +106,10 @@ fn compute_recur( } TreeNodeValue::Ops(Operator::Div) => { if node.children().count() == 1 { - return compute_recur(node.first_child(), ctx); + return compute_recur(node.first_child(), ctx, shared_lib); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.div(&right)) } TreeNodeValue::Ops(Operator::And) => { @@ -111,8 +118,8 @@ fn compute_recur( "only one value, no '&&' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.and(&right)) } TreeNodeValue::VariableUnused => { @@ -121,7 +128,8 @@ fn compute_recur( TreeNodeValue::FString(p, parameters) => { let mut s = String::from(p); for (key, param) in parameters { - let primitive = compute_lazy(param.clone(), ctx)?; + let primitive = + compute_lazy(param.clone(), ctx, shared_lib)?; if let err @ Primitive::Error(_) = primitive { return Ok(err); } @@ -137,8 +145,8 @@ fn compute_recur( "only one value, no '||' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.or(&right)) } TreeNodeValue::Ops(Operator::Equal) => { @@ -147,8 +155,8 @@ fn compute_recur( "only one value, no '==' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.is_equal(&right)) } TreeNodeValue::Ops(Operator::NotEqual) => { @@ -157,8 +165,8 @@ fn compute_recur( "only one value, no '!=' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.is_equal(&right).not()) } TreeNodeValue::Ops(Operator::Less) => { @@ -167,8 +175,8 @@ fn compute_recur( "only one value, no '<' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.is_less_than(&right)) } TreeNodeValue::Ops(Operator::Greater) => { @@ -177,8 +185,8 @@ fn compute_recur( "only one value, no '>' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.is_greater_than(&right)) } TreeNodeValue::Ops(Operator::GreaterOrEqual) => { @@ -187,8 +195,8 @@ fn compute_recur( "only one value, no '>=' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.is_greater_or_equal(&right)) } TreeNodeValue::Ops(Operator::LessOrEqual) => { @@ -197,13 +205,13 @@ fn compute_recur( "only one value, no '<=' comparison possible", )); } - let left = compute_recur(node.first_child(), ctx)?; - let right = compute_recur(node.last_child(), ctx)?; + let left = compute_recur(node.first_child(), ctx, shared_lib)?; + let right = compute_recur(node.last_child(), ctx, shared_lib)?; Ok(left.is_less_or_equal(&right)) } TreeNodeValue::Primitive(p) => Ok(p.clone()), TreeNodeValue::VariableAssign(name) => { - let v = compute_recur(node.first_child(), ctx)?; + let v = compute_recur(node.first_child(), ctx, shared_lib)?; if !matches!(v, Primitive::Error(_)) { if let Some(name) = name { let old = ctx @@ -225,7 +233,7 @@ fn compute_recur( Ok(v) } TreeNodeValue::BuiltInFunction(fn_type) => { - let v = compute_recur(node.first_child(), ctx)?; + let v = compute_recur(node.first_child(), ctx, shared_lib)?; match fn_type { adana_script_core::BuiltInFunctionType::Sqrt => { Ok(v.sqrt()) @@ -237,7 +245,7 @@ fn compute_recur( adana_script_core::BuiltInFunctionType::Cos => Ok(v.cos()), adana_script_core::BuiltInFunctionType::Eval => { if let Primitive::String(script) = v { - compute(&script, ctx) + compute(&script, ctx, shared_lib) } else { Ok(Primitive::Error(format!("invalid script {v}"))) } @@ -266,6 +274,22 @@ fn compute_recur( print!("{v}"); Ok(Primitive::Unit) } + adana_script_core::BuiltInFunctionType::Require => { + match v { + Primitive::String(file_path) => { + let native_lib = require_dynamic_lib( + file_path.as_str(), + shared_lib, + )?; + Ok(Primitive::NativeLibrary(Rc::new( + native_lib, + ))) + } + _ => Ok(Primitive::Error( + "wrong include call".to_string(), + )), + } + } adana_script_core::BuiltInFunctionType::Include => { match v { Primitive::String(file_path) => { @@ -292,7 +316,9 @@ fn compute_recur( read_to_string(p) .map_err(anyhow::Error::new) }) - .and_then(move |file| compute(&file, ctx)); + .and_then(move |file| { + compute(&file, ctx, shared_lib) + }); std::env::set_current_dir(curr_path)?; // todo this might be quiet fragile res } @@ -331,20 +357,33 @@ fn compute_recur( } TreeNodeValue::IfExpr(v) => { let mut scoped_ctx = ctx.clone(); - compute_instructions(vec![v.clone()], &mut scoped_ctx) + compute_instructions( + vec![v.clone()], + &mut scoped_ctx, + shared_lib, + ) } TreeNodeValue::WhileExpr(v) => { let mut scoped_ctx = ctx.clone(); - compute_instructions(vec![v.clone()], &mut scoped_ctx) + compute_instructions( + vec![v.clone()], + &mut scoped_ctx, + shared_lib, + ) } TreeNodeValue::Foreach(v) => { let mut scoped_ctx = ctx.clone(); - compute_instructions(vec![v.clone()], &mut scoped_ctx) + compute_instructions( + vec![v.clone()], + &mut scoped_ctx, + shared_lib, + ) } TreeNodeValue::Array(arr) => { let mut primitives = vec![]; for v in arr { - let primitive = compute_instructions(vec![v.clone()], ctx)?; + let primitive = + compute_instructions(vec![v.clone()], ctx, shared_lib)?; match primitive { v @ Primitive::Error(_) => return Ok(v), Primitive::Unit => { @@ -365,7 +404,8 @@ fn compute_recur( }; match (array, index) { (Value::Variable(v), index) => { - let index = compute_lazy(index.clone(), ctx)?; + let index = + compute_lazy(index.clone(), ctx, shared_lib)?; let array = ctx .get(v) .context("array not found in context")? @@ -379,12 +419,13 @@ fn compute_recur( } (Value::String(v), index) => { let v = Primitive::String(v.clone()); - let index = compute_lazy(index.clone(), ctx)?; + let index = + compute_lazy(index.clone(), ctx, shared_lib)?; Ok(v.index_at(&index)) } (Value::Array(array), index) => { let Primitive::Int(index) = - compute_lazy(index.clone(), ctx)? + compute_lazy(index.clone(), ctx, shared_lib)? else { return Err(anyhow::format_err!( "COMPUTE: illegal array access! {index:?}" @@ -394,8 +435,11 @@ fn compute_recur( let index = index as usize; let value = array.get(index).context(error_message())?; if index < array.len() { - let primitive = - compute_instructions(vec![value.clone()], ctx)?; + let primitive = compute_instructions( + vec![value.clone()], + ctx, + shared_lib, + )?; return Ok(primitive); } Err(anyhow::Error::msg(error_message())) @@ -405,8 +449,9 @@ fn compute_recur( | v @ Value::StructAccess { struc: _, key: _ }, index, ) => { - let v = compute_lazy(v.clone(), ctx)?; - let index = compute_lazy(index.clone(), ctx)?; + let v = compute_lazy(v.clone(), ctx, shared_lib)?; + let index = + compute_lazy(index.clone(), ctx, shared_lib)?; match v { p @ Primitive::Array(_) => Ok(p.index_at(&index)), @@ -420,8 +465,11 @@ fn compute_recur( let mut primitives = BTreeMap::new(); for (k, v) in struc { if !k.starts_with('_') { - let primitive = - compute_instructions(vec![v.clone()], ctx)?; + let primitive = compute_instructions( + vec![v.clone()], + ctx, + shared_lib, + )?; match primitive { v @ Primitive::Error(_) => return Ok(v), Primitive::Unit => { @@ -438,7 +486,10 @@ fn compute_recur( Ok(Primitive::Struct(primitives)) } TreeNodeValue::StructAccess { struc, key } => match (struc, key) { - (Value::Variable(v), key @ Primitive::String(_)) => { + (Value::Variable(v), key @ Primitive::String(k)) => { + if cfg!(test) { + dbg!(&ctx); + } let struc = ctx .get(v) .context("struct not found in context")? @@ -446,7 +497,11 @@ fn compute_recur( .map_err(|e| { anyhow::format_err!("could not acquire lock {e}") })?; - Ok(struc.index_at(key)) + if let Primitive::NativeLibrary(lib) = struc.as_ref_ok()? { + Ok(Primitive::NativeFunction(k.clone(), lib.clone())) + } else { + Ok(struc.index_at(key)) + } } (s @ Value::Struct(_), key @ Primitive::String(_)) | ( @@ -457,7 +512,7 @@ fn compute_recur( s @ Value::ArrayAccess { arr: _, index: _ }, key @ Primitive::String(_), ) => { - let prim_s = compute_lazy(s.clone(), ctx)?; + let prim_s = compute_lazy(s.clone(), ctx, shared_lib)?; Ok(prim_s.index_at(key)) } _ => Ok(Primitive::Error(format!( @@ -465,8 +520,8 @@ fn compute_recur( ))), }, TreeNodeValue::VariableArrayAssign { name, index } => { - let index = compute_lazy(index.clone(), ctx)?; - let mut v = compute_recur(node.first_child(), ctx)?; + let index = compute_lazy(index.clone(), ctx, shared_lib)?; + let mut v = compute_recur(node.first_child(), ctx, shared_lib)?; let mut array = ctx .get_mut(name) .context("array not found in context")? @@ -499,11 +554,14 @@ fn compute_recur( } TreeNodeValue::FunctionCall(Value::FunctionCall { parameters, - function, + ref function, }) => { if let Value::BlockParen(param_values) = parameters.borrow() { - let mut function = - compute_instructions(vec![*function.clone()], ctx)?; + let mut function = compute_instructions( + vec![*function.clone()], + ctx, + shared_lib, + )?; // FIXME clone again if let Primitive::Ref(r) = function { @@ -533,6 +591,7 @@ fn compute_recur( if matches!( *maybe_fn, Primitive::Function { parameters: _, exprs: _ } + | Primitive::NativeLibrary(_) ) { scope_ctx.insert(k.to_string(), p.clone()); } @@ -544,8 +603,11 @@ fn compute_recur( if let Value::Variable(variable_from_fn_def) = param { - let variable_from_fn_call = - compute_lazy(value.clone(), ctx)?; + let variable_from_fn_call = compute_lazy( + value.clone(), + ctx, + shared_lib, + )?; scope_ctx.insert( variable_from_fn_def.clone(), variable_from_fn_call.ref_prim(), @@ -567,12 +629,66 @@ fn compute_recur( // "something wrong: {e:?}" // )) // })??; - let res = compute_instructions(exprs, &mut scope_ctx)?; + let res = compute_instructions( + exprs, + &mut scope_ctx, + shared_lib, + )?; if let Primitive::EarlyReturn(v) = res { return Ok(*v); } Ok(res) + } else if let Primitive::NativeLibrary(lib) = function { + if cfg!(test) { + dbg!(&lib); + } + let mut parameters = vec![]; + for (_i, param) in param_values.iter().enumerate() { + if let Value::Variable(_) = param { + let variable_from_fn_call = compute_lazy( + param.clone(), + ctx, + shared_lib, + )?; + parameters.push(variable_from_fn_call); + } + } + if cfg!(test) { + dbg!(¶meters); + } + Ok(Primitive::Error("debug".into())) + //Ok(function(vec![Primitive::String("s".into())])) + } else if let Primitive::NativeFunction(key, lib) = function + { + if cfg!(test) { + dbg!(&key, &lib); + } + let mut parameters = vec![]; + + for (_i, param) in param_values.iter().enumerate() { + let variable_from_fn_call = + compute_lazy(param.clone(), ctx, shared_lib)?; + parameters.push(variable_from_fn_call); + } + if cfg!(test) { + dbg!(¶meters); + } + + let mut cloned_ctx = ctx.clone(); + let slb = shared_lib.as_ref().to_path_buf(); + let fun = move |v, extra_ctx| { + cloned_ctx.extend(extra_ctx); + compute_lazy(v, &mut cloned_ctx, &slb) + }; + unsafe { + lib.call_function( + key.as_str(), + parameters, + Box::new(fun), + ) + } + //Ok(function(vec![Primitive::String("s".into())])) } else { Ok(Primitive::Error(format!( " not a function: {function}" @@ -638,7 +754,8 @@ fn compute_recur( } TreeNodeValue::EarlyReturn(v) => { if let Some(v) = v { - let p = compute_instructions(vec![v.clone()], ctx)?; + let p = + compute_instructions(vec![v.clone()], ctx, shared_lib)?; Ok(Primitive::EarlyReturn(Box::new(p))) } else { Ok(Primitive::EarlyReturn(Box::new(Primitive::Null))) @@ -672,23 +789,25 @@ fn value_to_tree( fn compute_lazy( instruction: Value, ctx: &mut BTreeMap, + shared_lib: impl AsRef + Copy, ) -> anyhow::Result { let tree = value_to_tree(instruction, ctx)?; let root = tree.root(); - compute_recur(root, ctx) + compute_recur(root, ctx, shared_lib) } fn compute_instructions( instructions: Vec, ctx: &mut BTreeMap, + shared_lib: impl AsRef + Copy, ) -> anyhow::Result { let mut result = Primitive::Unit; for instruction in instructions { match instruction { v @ Value::EarlyReturn(_) => { - let res = compute_lazy(v, ctx)?; + let res = compute_lazy(v, ctx, shared_lib)?; if let Primitive::EarlyReturn(r) = res { return Ok(*r); } else { @@ -696,7 +815,7 @@ fn compute_instructions( } } Value::IfExpr { cond, exprs, else_expr } => { - let cond = compute_lazy(*cond, ctx)?; + let cond = compute_lazy(*cond, ctx, shared_lib)?; if matches!(cond, Primitive::Error(_)) { return Ok(cond); } @@ -707,6 +826,7 @@ fn compute_instructions( match compute_lazy( instruction.clone(), &mut scoped_ctx, + shared_lib, )? { v @ Primitive::EarlyReturn(_) | v @ Primitive::Error(_) => return Ok(v), @@ -720,6 +840,7 @@ fn compute_instructions( match compute_lazy( instruction.clone(), &mut scoped_ctx, + shared_lib, )? { v @ Primitive::EarlyReturn(_) | v @ Primitive::Error(_) => return Ok(v), @@ -732,13 +853,14 @@ fn compute_instructions( let mut scoped_ctx = ctx.clone(); 'while_loop: while matches!( - compute_lazy(*cond.clone(), &mut scoped_ctx)?, + compute_lazy(*cond.clone(), &mut scoped_ctx, shared_lib)?, Primitive::Bool(true) ) { for instruction in &exprs { match compute_lazy( instruction.clone(), &mut scoped_ctx, + shared_lib, )? { Primitive::NoReturn => break 'while_loop, v @ Primitive::EarlyReturn(_) @@ -749,7 +871,7 @@ fn compute_instructions( } } Value::ForeachExpr { var, index_var, iterator, exprs } => { - let iterator = compute_lazy(*iterator, ctx)?; + let iterator = compute_lazy(*iterator, ctx, shared_lib)?; let mut scoped_ctx = ctx.clone(); let arr = match iterator { @@ -790,6 +912,7 @@ fn compute_instructions( match compute_lazy( instruction.clone(), &mut scoped_ctx, + shared_lib, )? { Primitive::NoReturn => break 'foreach_loop, v @ Primitive::EarlyReturn(_) @@ -800,7 +923,7 @@ fn compute_instructions( } } _ => { - result = compute_lazy(instruction, ctx)?; + result = compute_lazy(instruction, ctx, shared_lib)?; } } if let Primitive::EarlyReturn(p) = result { @@ -817,6 +940,7 @@ fn compute_instructions( pub fn compute( s: &str, ctx: &mut BTreeMap, + shared_lib: impl AsRef + Copy, ) -> anyhow::Result { let (rest, instructions) = parse_instructions(s).map_err(|e| { anyhow::Error::msg(format!( @@ -838,5 +962,5 @@ pub fn compute( ) ); - compute_instructions(instructions, ctx) + compute_instructions(instructions, ctx, shared_lib) } diff --git a/src/adana_script/mod.rs b/src/adana_script/mod.rs index db1f0ec..937ec03 100644 --- a/src/adana_script/mod.rs +++ b/src/adana_script/mod.rs @@ -1,8 +1,8 @@ mod ast; mod compute; mod parser; +mod require_dynamic_lib; mod string_parser; - use std::collections::BTreeMap; use adana_script_core::TreeNodeValue; diff --git a/src/adana_script/parser.rs b/src/adana_script/parser.rs index d341885..7a8c13e 100644 --- a/src/adana_script/parser.rs +++ b/src/adana_script/parser.rs @@ -212,7 +212,13 @@ fn parse_fn_call(s: &str) -> Res { parse_fn, map( many1(preceded(multispace0, parse_value)), - Value::Expression, + |mut v| { + if v.len() == 1 { + v.remove(0) + } else { + Value::Expression(v) + } + }, ), )), ), @@ -323,6 +329,7 @@ fn parse_builtin_fn(s: &str) -> Res { parse_builtin(BuiltInFunctionType::Print), parse_builtin(BuiltInFunctionType::Length), parse_builtin(BuiltInFunctionType::Include), + parse_builtin(BuiltInFunctionType::Require), parse_builtin(BuiltInFunctionType::ReadLines), ))(s) } diff --git a/src/adana_script/require_dynamic_lib.rs b/src/adana_script/require_dynamic_lib.rs new file mode 100644 index 0000000..ac658d0 --- /dev/null +++ b/src/adana_script/require_dynamic_lib.rs @@ -0,0 +1,84 @@ +use std::{ + path::Path, + process::{Command, Stdio}, +}; + +use adana_script_core::primitive::NativeLibrary; +use anyhow::{anyhow, Context}; + +pub fn require_dynamic_lib( + path: &str, + shared_lib: impl AsRef + Copy, +) -> anyhow::Result { + try_from_path(path, shared_lib) +} + +fn try_from_path( + file_path: &str, + shared_lib: impl AsRef + Copy, +) -> anyhow::Result { + let curr_path = + std::env::current_dir().context("no current dir! wasn't expected")?; + if cfg!(test) { + dbg!(&curr_path); + } + let temp_path = Path::new(&file_path); + + if cfg!(test) { + dbg!(&temp_path); + } + + let mut file_path = { + let mut parent = temp_path + .parent() + .filter(|p| p.is_dir()) + .map(|p| p.to_path_buf()) + .or_else(|| Some(shared_lib.as_ref().to_path_buf())) + .and_then(|p| p.canonicalize().ok()) + .context("parent or shared lib doesn't exist")?; + if cfg!(test) { + dbg!(&parent); + } + parent.push(temp_path.file_name().context("file name not found")?); + parent + }; + if file_path.is_dir() && file_path.exists() { + std::env::set_current_dir(&file_path) + .map_err(|e| anyhow!("could not change dir: {e}"))?; + println!("building lib {file_path:?}..."); + let mut handle = Command::new("cargo") + .args(["build", "--release"]) + .stdout(Stdio::null()) + .stderr(Stdio::inherit()) + .spawn()?; + + let status_code = handle.wait()?; + + std::env::set_current_dir(curr_path) + .map_err(|e| anyhow!("could not change dir: {e}"))?; + + if !status_code.success() { + return Err(anyhow!("could not build library")); + } + file_path.push("target/release"); + if cfg!(test) { + dbg!(&file_path); + } + for f in std::fs::read_dir(&file_path)? { + let f = f?; + let p = f.path(); + if let Some("so") = p.extension().and_then(|p| p.to_str()) { + file_path.push(p); + break; + } + } + } + + if file_path.extension().and_then(|e| e.to_str()) != Some("so") { + return Err(anyhow!("not a shared object!")); + } + println!("loading {file_path:?}"); + unsafe { NativeLibrary::new(file_path.as_path()) } +} +#[cfg(test)] +mod test {} diff --git a/src/adana_script/tests/builtin.rs b/src/adana_script/tests/builtin.rs index b14d81a..6135d19 100644 --- a/src/adana_script/tests/builtin.rs +++ b/src/adana_script/tests/builtin.rs @@ -5,43 +5,43 @@ use adana_script_core::primitive::Primitive; #[test] fn test_builtin_to_int() { let mut ctx = BTreeMap::new(); - let res = compute("to_int(2)", &mut ctx).unwrap(); + let res = compute("to_int(2)", &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Int(2)); - let res = compute(r#"to_int("2")"#, &mut ctx).unwrap(); + let res = compute(r#"to_int("2")"#, &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Int(2)); ctx.insert( "a".to_string(), Primitive::String("123".to_string()).ref_prim(), ); - let res = compute("to_int(a)", &mut ctx).unwrap(); + let res = compute("to_int(a)", &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Int(123)); } #[test] fn test_builtin_to_double() { let mut ctx = BTreeMap::new(); - let res = compute("to_double(2)", &mut ctx).unwrap(); + let res = compute("to_double(2)", &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Double(2.0)); - let res = compute(r#"to_double("2.1")"#, &mut ctx).unwrap(); + let res = compute(r#"to_double("2.1")"#, &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Double(2.1)); } #[test] fn test_builtin_to_bool() { let mut ctx = BTreeMap::new(); - let res = compute("to_bool(2)", &mut ctx).unwrap(); + let res = compute("to_bool(2)", &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Bool(true)); - let res = compute(r#"to_bool("false")"#, &mut ctx).unwrap(); + let res = compute(r#"to_bool("false")"#, &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Bool(false)); ctx.insert("a".to_string(), Primitive::Double(0.0).ref_prim()); - let res = compute("to_bool(a)", &mut ctx).unwrap(); + let res = compute("to_bool(a)", &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Bool(false)); } #[test] fn test_eval() { let mut ctx = BTreeMap::new(); - let _ = compute(r#"eval("z = sqrt(9)")"#, &mut ctx).unwrap(); + let _ = compute(r#"eval("z = sqrt(9)")"#, &mut ctx, "N/A").unwrap(); assert_eq!(*ctx["z"].read().unwrap(), Primitive::Double(3.0)); } @@ -67,42 +67,42 @@ fn test_type_of() { ); assert_eq!( Primitive::String("int".to_string()), - compute(r#"type_of(x)"#, &mut ctx).unwrap() + compute(r#"type_of(x)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("double".to_string()), - compute(r#"type_of(y)"#, &mut ctx).unwrap() + compute(r#"type_of(y)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("function".to_string()), - compute(r#"type_of(z)"#, &mut ctx).unwrap() + compute(r#"type_of(z)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("error".to_string()), - compute(r#"type_of(a)"#, &mut ctx).unwrap() + compute(r#"type_of(a)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("array".to_string()), - compute(r#"type_of(b)"#, &mut ctx).unwrap() + compute(r#"type_of(b)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("bool".to_string()), - compute(r#"type_of(c)"#, &mut ctx).unwrap() + compute(r#"type_of(c)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("string".to_string()), - compute(r#"type_of(d)"#, &mut ctx).unwrap() + compute(r#"type_of(d)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("unit".to_string()), - compute(r#"type_of(e)"#, &mut ctx).unwrap() + compute(r#"type_of(e)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("!".to_string()), - compute(r#"type_of(f)"#, &mut ctx).unwrap() + compute(r#"type_of(f)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("int".to_string()), - compute(r#"type_of(g)"#, &mut ctx).unwrap() + compute(r#"type_of(g)"#, &mut ctx, "N/A").unwrap() ); } diff --git a/src/adana_script/tests/dynload.rs b/src/adana_script/tests/dynload.rs new file mode 100644 index 0000000..9b4cd15 --- /dev/null +++ b/src/adana_script/tests/dynload.rs @@ -0,0 +1,84 @@ +use std::collections::BTreeMap; + +use adana_script_core::primitive::Primitive; +use serial_test::serial; + +use crate::adana_script::compute; + +#[test] +#[serial] +fn load_dynamic_lib_test() { + let file_path = r#" + lib = require("libplugin_example.so") + text = lib.hello("Nordine", "la", "forme?") + "#; + let mut ctx = BTreeMap::new(); + let res = compute(file_path, &mut ctx, "dynamic_lib").unwrap(); + + assert_eq!( + Primitive::String("Hello Nordine la forme?".to_string()), + ctx["text"].read().unwrap().clone() + ); + + dbg!(ctx); + println!("{res:?}"); +} +#[test] +#[serial] +fn callback_dynamic_lib_test() { + let file_path = r#" + lib = require("libplugin_example.so") + callback = (input) => {input + " Nordine! ca va?"} + text = lib.callback(callback) + "#; + let mut ctx = BTreeMap::new(); + let res = compute(file_path, &mut ctx, "dynamic_lib").unwrap(); + + assert_eq!( + Primitive::String("Hello Nordine! ca va?".to_string()), + ctx["text"].read().unwrap().clone() + ); + + dbg!(ctx); + println!("{res:?}"); +} + +#[test] +#[serial] +fn complex_callback_dynamic_lib_test() { + let file_path = r#" + lib = require("libplugin_example.so") + callback = (input) => {lib.hello(input,"Nordine!","ca", "va?")} + text = lib.callback(callback) + "#; + let mut ctx = BTreeMap::new(); + let res = compute(file_path, &mut ctx, "dynamic_lib").unwrap(); + + assert_eq!( + Primitive::String("Hello Hello Nordine! ca va?".to_string()), + ctx["text"].read().unwrap().clone() + ); + + dbg!(ctx); + println!("{res:?}"); +} + +#[test] +#[serial] +fn build_from_adana_dynamic_lib_test() { + let file_path = r#" + lib = require("example_lib_src") + callback = (input) => {lib.hello(input,"Nordine!","ca", "va?")} + text = lib.callback(callback) + "#; + let mut ctx = BTreeMap::new(); + let res = compute(file_path, &mut ctx, "dynamic_lib").unwrap(); + + assert_eq!( + Primitive::String("Hello Hello Nordine! ca va?".to_string()), + ctx["text"].read().unwrap().clone() + ); + + dbg!(ctx); + println!("{res:?}"); +} diff --git a/src/adana_script/tests/examples.rs b/src/adana_script/tests/examples.rs index 6899234..33f5bd9 100644 --- a/src/adana_script/tests/examples.rs +++ b/src/adana_script/tests/examples.rs @@ -8,7 +8,7 @@ fn test_example1() { let expr = include_str!("../../../examples/example1.adana"); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["students"].read().unwrap().clone(), @@ -58,7 +58,10 @@ fn test_example1() { fn test_example2() { let mut ctx = BTreeMap::new(); let expr = include_str!("../../../examples/example2.adana"); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(res, Array(vec![Int(15), Int(1), Int(11), Int(22)])); - assert_eq!(compute("fun([1])", &mut ctx).unwrap(), Array(vec![Int(0)])); + assert_eq!( + compute("fun([1])", &mut ctx, "N/A").unwrap(), + Array(vec![Int(0)]) + ); } diff --git a/src/adana_script/tests/foreach.rs b/src/adana_script/tests/foreach.rs index 5200fc2..f11e9ff 100644 --- a/src/adana_script/tests/foreach.rs +++ b/src/adana_script/tests/foreach.rs @@ -13,7 +13,7 @@ fn simple_foreach() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); } @@ -31,7 +31,7 @@ fn simple_foreach_string() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(43), ctx["total"].read().unwrap().clone()); assert_eq!( Array(vec![ @@ -96,7 +96,7 @@ fn simple_foreach_not_assigned() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String("Hello World How Are Ya ?".into()), ctx["message"].read().unwrap().clone() @@ -113,7 +113,7 @@ fn simple_foreach_string_not_assigned() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String("Hello World How Are Ya ?".into()), ctx["message"].read().unwrap().clone() @@ -137,7 +137,7 @@ fn simple_foreach_break() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String("Hello World How Are Ya".into()), ctx["message"].read().unwrap().clone() @@ -161,7 +161,7 @@ fn simple_foreach_return() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String("Hello World How Are".into()), ctx["message"].read().unwrap().clone() @@ -184,7 +184,7 @@ fn simple_foreach_two_depth() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::Array(vec![ Primitive::Array(vec![ @@ -245,7 +245,7 @@ fn simple_foreach_with_idx() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert_eq!(Primitive::Int(6), ctx["idx_total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); @@ -262,7 +262,7 @@ fn simple_foreach_with_idx_from_fn() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert_eq!(Primitive::Int(6), ctx["idx_total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); @@ -281,7 +281,7 @@ fn simple_foreach_with_idx_from_struct() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert_eq!(Primitive::Int(6), ctx["idx_total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); @@ -297,7 +297,7 @@ fn simple_foreach_with_paren() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); } @@ -314,7 +314,7 @@ fn simple_foreach_with_idx_with_paren() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert_eq!(Primitive::Int(6), ctx["idx_total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); @@ -334,7 +334,7 @@ fn simple_foreach_with_idx_from_struct_with_paren() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert_eq!(Primitive::Int(6), ctx["idx_total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); @@ -350,7 +350,7 @@ fn test_handle_error() { "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Error("not an iterable Int(1)".into()), r); } @@ -369,7 +369,7 @@ fn test_foreach_struct() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); let result = ctx["result"].read().unwrap(); let _expected = vec![ diff --git a/src/adana_script/tests/funct.rs b/src/adana_script/tests/funct.rs index 3146d63..6dd5a53 100644 --- a/src/adana_script/tests/funct.rs +++ b/src/adana_script/tests/funct.rs @@ -12,7 +12,7 @@ fn test_anon_func_call() { }(2, 3) "#; - let res = compute(s, &mut ctx).unwrap(); + let res = compute(s, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(5), res); let s = r#" z = (a,b) => { @@ -22,7 +22,7 @@ fn test_anon_func_call() { z(2,3) "#; - let res = compute(s, &mut ctx).unwrap(); + let res = compute(s, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(14), res); assert_eq!( @@ -56,7 +56,7 @@ fn test_anon_func_call() { }(a, b) "#; - let res = compute(s, &mut ctx).unwrap(); + let res = compute(s, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(5), res); let s = r#" @@ -73,7 +73,7 @@ fn test_anon_func_call() { }(a, b, c) "#; - let res = compute(s, &mut ctx).unwrap(); + let res = compute(s, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(600), res); } @@ -88,7 +88,7 @@ fn test_basic_map() { "#; let mut ctx = BTreeMap::new(); - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(34), res); let script = r#" include("file_tests/test_fn.adana") @@ -98,7 +98,7 @@ fn test_basic_map() { "#; let mut ctx = BTreeMap::new(); - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Null, res); // todo change that with null or smth } @@ -114,7 +114,7 @@ fn test_override_map() { "#; let mut ctx = BTreeMap::new(); - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(35), res); assert_eq!( @@ -139,7 +139,7 @@ fn test_drop() { "#; let mut ctx = BTreeMap::new(); - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Unit, res); assert_eq!(*ctx["z"].read().unwrap(), Primitive::Int(35,)); @@ -155,7 +155,7 @@ fn test_inline_fn() { null "#; let mut ctx = BTreeMap::new(); - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Null, res); @@ -171,10 +171,10 @@ fn test_inline_fn() { let script = "hello = (name) => { \"hello \" + name}"; let mut ctx = BTreeMap::new(); - let _ = compute(script, &mut ctx).unwrap(); + let _ = compute(script, &mut ctx, "N/A").unwrap(); let script = "hello_me = hello(\"nordine\")"; - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::String("hello nordine".into()), res); assert_eq!( @@ -183,7 +183,7 @@ fn test_inline_fn() { ); let script = "hello_world = hello(\"world\")"; - let res = compute(script, &mut ctx).unwrap(); + let res = compute(script, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::String("hello world".into()), res); assert_eq!( @@ -200,7 +200,7 @@ fn test_recursive() { fact6 = fact(6) "#; let mut ctx = BTreeMap::new(); - let r = compute(s, &mut ctx).unwrap(); + let r = compute(s, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(720), r); } @@ -223,7 +223,7 @@ fn test_fn_param() { "#; let mut ctx = BTreeMap::new(); - let r = compute(s, &mut ctx).unwrap(); + let r = compute(s, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::Array(vec![ Primitive::Int(2), @@ -242,7 +242,7 @@ fn test_if_else_file() { res = split("kekeke=lekeke=meme=me", "=") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!( r, @@ -258,7 +258,7 @@ fn test_if_else_file() { res = split("kekeke=akalekeke=meme=me", "=") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::Array(vec![Primitive::String("aka".into()),])); @@ -267,7 +267,7 @@ fn test_if_else_file() { res = split("kekeke=akalekeke=meme=me", "") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::Null,); @@ -276,7 +276,7 @@ fn test_if_else_file() { res = split("", "k") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::Null,); @@ -285,7 +285,7 @@ fn test_if_else_file() { res = split(null, "k") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::Null,); @@ -294,7 +294,7 @@ fn test_if_else_file() { res = split("sksksksk", null) "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::Null,); } @@ -310,7 +310,7 @@ fn test_array_access_fn_call() { s[5]("nordine2") "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("hello nordine2".into())); assert_eq!(*ctx["z"].read().unwrap(), Primitive::Int(6)); assert_eq!( diff --git a/src/adana_script/tests/misc.rs b/src/adana_script/tests/misc.rs index 65a8f2f..7c5d838 100644 --- a/src/adana_script/tests/misc.rs +++ b/src/adana_script/tests/misc.rs @@ -10,7 +10,7 @@ fn test_expr_invalid() { let expr = "uze example"; let mut ctx = BTreeMap::from([("x".to_string(), Primitive::Double(2.).ref_prim())]); - compute(expr, &mut ctx).unwrap(); + compute(expr, &mut ctx, "N/A").unwrap(); } #[test] #[should_panic(expected = "invalid expression!")] @@ -18,7 +18,7 @@ fn test_expr_invalid_drc() { let expr = "drc logs -f triplestore"; let mut ctx = BTreeMap::from([("x".to_string(), Primitive::Double(2.).ref_prim())]); - compute(expr, &mut ctx).unwrap(); + compute(expr, &mut ctx, "N/A").unwrap(); } #[test] @@ -27,7 +27,7 @@ fn test_op_invalid() { let expr = "use example = wesh"; let mut ctx = BTreeMap::from([("x".to_string(), Primitive::Double(2.).ref_prim())]); - compute(expr, &mut ctx).unwrap(); + compute(expr, &mut ctx, "N/A").unwrap(); } #[test] @@ -36,7 +36,7 @@ fn test_compute_with_ctx() { let mut ctx = BTreeMap::from([("x".to_string(), Primitive::Double(2.).ref_prim())]); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Double(10.), res); } #[test] @@ -45,7 +45,7 @@ fn test_compute_assign_with_ctx() { let mut ctx = BTreeMap::from([("x".to_string(), Primitive::Double(2.).ref_prim())]); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Double(10.), res); assert_eq!(ctx["y"].read().unwrap().clone(), Primitive::Double(10.)); @@ -118,19 +118,30 @@ fn test_variable_expr_2() { #[test] fn test_modulo() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(1), compute("3%2", &mut ctx).unwrap()); - assert_eq!(Primitive::Double(1.), compute("3%2.", &mut ctx).unwrap()); - assert_eq!(Primitive::Double(0.625), compute("5/8.%2", &mut ctx).unwrap()); + assert_eq!(Primitive::Int(1), compute("3%2", &mut ctx, "N/A").unwrap()); + assert_eq!( + Primitive::Double(1.), + compute("3%2.", &mut ctx, "N/A").unwrap() + ); + assert_eq!( + Primitive::Double(0.625), + compute("5/8.%2", &mut ctx, "N/A").unwrap() + ); assert_eq!( Primitive::Double(3278.9), - compute("2 * (9 *(5-(1 /2.) ) )² -1 / 5. * 8 - 4 %4", &mut ctx) - .unwrap() + compute( + "2 * (9 *(5-(1 /2.) ) )² -1 / 5. * 8 - 4 %4", + &mut ctx, + "N/A" + ) + .unwrap() ); assert_eq!( Primitive::Double(-1.1), compute( " 2* (9 *(5-(1 /2.) ))² %2 -1 /5. * 8 - 4 %4", - &mut ctx + &mut ctx, + "N/A" ) .unwrap() ); @@ -141,44 +152,53 @@ fn test_compute() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(3280.3), - compute("x=2* (9*(5-(1./ 2.) ))² -1 / 5.", &mut ctx).unwrap() + compute("x=2* (9*(5-(1./ 2.) ))² -1 / 5.", &mut ctx, "N/A") + .unwrap() ); assert_eq!( Primitive::Double(3274.9), - compute("y = 2* (9*(5-(1/2.)))² -1 / 5. * 8 - 4", &mut ctx).unwrap() + compute("y = 2* (9*(5-(1/2.)))² -1 / 5. * 8 - 4", &mut ctx, "N/A") + .unwrap() ); assert_eq!( Primitive::Double(-670.9548307564088), - compute("z = 78/5.-4.5*(9+7^2.5)-12*4+1-8/3.*4-5", &mut ctx).unwrap() + compute("z = 78/5.-4.5*(9+7^2.5)-12*4+1-8/3.*4-5", &mut ctx, "N/A") + .unwrap() ); assert_eq!( Primitive::Int(37737), - compute("f = 1988*19-(((((((9*2))))+2*4)-3))/6-1^2*1000/(7-4*(3/9-(9+3/2-4)))", &mut ctx).unwrap() + compute("f = 1988*19-(((((((9*2))))+2*4)-3))/6-1^2*1000/(7-4*(3/9-(9+3/2-4)))", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(37736.587719298244), - compute("f = 1988*19-(((((((9*2))))+2*4)-3))/6.-1^2*1000/(7-4*(3/9.-(9+3/2.-4)))", &mut ctx).unwrap() + compute("f = 1988*19-(((((((9*2))))+2*4)-3))/6.-1^2*1000/(7-4*(3/9.-(9+3/2.-4)))", &mut ctx, "N/A").unwrap() ); - assert_eq!(Primitive::Int(0), compute("0", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(9), compute("9", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(-9), compute("-9", &mut ctx).unwrap()); + assert_eq!(Primitive::Int(0), compute("0", &mut ctx, "N/A").unwrap()); + assert_eq!(Primitive::Int(9), compute("9", &mut ctx, "N/A").unwrap()); + assert_eq!(Primitive::Int(-9), compute("-9", &mut ctx, "N/A").unwrap()); assert_eq!( Primitive::Int(6 / 2 * (2 + 1)), - compute("6/2*(2+1)", &mut ctx).unwrap() + compute("6/2*(2+1)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(2. - 1. / 5.), - compute("2 -1 / 5.", &mut ctx).unwrap() + compute("2 -1 / 5.", &mut ctx, "N/A").unwrap() ); // todo maybe should panic in these cases - assert_eq!(Primitive::Int(2 * 4), compute("2* * *4", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(2 * 4), compute("2* ** *4", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(4), compute("*4", &mut ctx).unwrap()); + assert_eq!( + Primitive::Int(2 * 4), + compute("2* * *4", &mut ctx, "N/A").unwrap() + ); + assert_eq!( + Primitive::Int(2 * 4), + compute("2* ** *4", &mut ctx, "N/A").unwrap() + ); + assert_eq!(Primitive::Int(4), compute("*4", &mut ctx, "N/A").unwrap()); // compute with variables assert_eq!( Primitive::Double(-4765.37866215695), - compute("f = 555*19-(((((((9*2))))+2f)-x))/6.-1^2y/(z-4*(3/9.-(9+3/2.-4))) - x", &mut ctx).unwrap() + compute("f = 555*19-(((((((9*2))))+2f)-x))/6.-1^2y/(z-4*(3/9.-(9+3/2.-4))) - x", &mut ctx, "N/A").unwrap() ); assert_eq!( @@ -196,19 +216,34 @@ fn test_compute() { #[test] fn test_negate() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(-5 / -1), compute("-5/-1", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(5 / -1), compute("5/-1", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(5), compute("--5", &mut ctx).unwrap()); + assert_eq!( + Primitive::Int(-5 / -1), + compute("-5/-1", &mut ctx, "N/A").unwrap() + ); + assert_eq!( + Primitive::Int(5 / -1), + compute("5/-1", &mut ctx, "N/A").unwrap() + ); + assert_eq!(Primitive::Int(5), compute("--5", &mut ctx, "N/A").unwrap()); } #[test] fn test_pow() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Double(-0.5), compute("-2^-1", &mut ctx).unwrap()); - assert_eq!(Primitive::Double(-0.04), compute("-5^-2", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(-25), compute("-5^2", &mut ctx).unwrap()); - assert_eq!(Primitive::Double(0.04), compute("5^-2", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(3125), compute("5^5", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(1), compute("5^0", &mut ctx).unwrap()); + assert_eq!( + Primitive::Double(-0.5), + compute("-2^-1", &mut ctx, "N/A").unwrap() + ); + assert_eq!( + Primitive::Double(-0.04), + compute("-5^-2", &mut ctx, "N/A").unwrap() + ); + assert_eq!(Primitive::Int(-25), compute("-5^2", &mut ctx, "N/A").unwrap()); + assert_eq!( + Primitive::Double(0.04), + compute("5^-2", &mut ctx, "N/A").unwrap() + ); + assert_eq!(Primitive::Int(3125), compute("5^5", &mut ctx, "N/A").unwrap()); + assert_eq!(Primitive::Int(1), compute("5^0", &mut ctx, "N/A").unwrap()); } #[test] @@ -216,19 +251,19 @@ fn test_consts() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(std::f64::consts::PI), - compute("Ï€", &mut ctx).unwrap() + compute("Ï€", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(std::f64::consts::PI * 2.), - compute("Ï€*2", &mut ctx).unwrap() + compute("Ï€*2", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(std::f64::consts::E), - compute("γ", &mut ctx).unwrap() + compute("γ", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(std::f64::consts::TAU), - compute("Ï„", &mut ctx).unwrap() + compute("Ï„", &mut ctx, "N/A").unwrap() ); } #[test] @@ -236,23 +271,29 @@ fn test_fn_sqrt() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(2.23606797749979), - compute("sqrt(5)", &mut ctx).unwrap() + compute("sqrt(5)", &mut ctx, "N/A").unwrap() + ); + assert_eq!( + Primitive::Double(5.), + compute("sqrt(5*5)", &mut ctx, "N/A").unwrap() ); - assert_eq!(Primitive::Double(5.), compute("sqrt(5*5)", &mut ctx).unwrap()); assert_eq!( Primitive::Double(8983.719357816115), - compute("sqrt(2*(3/4.-12%5 +7^9) --6/12.*4)", &mut ctx).unwrap() + compute("sqrt(2*(3/4.-12%5 +7^9) --6/12.*4)", &mut ctx, "N/A").unwrap() ); } #[test] fn test_fn_abs() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(5), compute("abs(5)", &mut ctx).unwrap()); - assert_eq!(Primitive::Int(25), compute("abs(-5*5)", &mut ctx).unwrap()); + assert_eq!(Primitive::Int(5), compute("abs(5)", &mut ctx, "N/A").unwrap()); + assert_eq!( + Primitive::Int(25), + compute("abs(-5*5)", &mut ctx, "N/A").unwrap() + ); assert_eq!( Primitive::Double(80707209.5), - compute("abs(-2*(3/4.-12%5 +7^9) --6/12.*4)", &mut ctx).unwrap() + compute("abs(-2*(3/4.-12%5 +7^9) --6/12.*4)", &mut ctx, "N/A").unwrap() ); } #[test] @@ -260,15 +301,16 @@ fn test_fn_log() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(0.6989700043360189), - compute("log(5)", &mut ctx).unwrap() + compute("log(5)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(1.3979400086720377), - compute("log(abs(-5*5))", &mut ctx).unwrap() + compute("log(abs(-5*5))", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(7.906912331577292), - compute("log(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx).unwrap() + compute("log(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx, "N/A") + .unwrap() ); } @@ -277,15 +319,16 @@ fn test_fn_ln() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(1.6094379124341003), - compute("ln(5)", &mut ctx).unwrap() + compute("ln(5)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(3.2188758248682006), - compute("ln(abs(-5*5))", &mut ctx).unwrap() + compute("ln(abs(-5*5))", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(18.206338466300664), - compute("ln(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx).unwrap() + compute("ln(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx, "N/A") + .unwrap() ); } #[test] @@ -293,15 +336,15 @@ fn test_fn_sin() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(-0.9589242746631385), - compute("sin(5)", &mut ctx).unwrap() + compute("sin(5)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(0.13235175009777303), - compute("sin(-5*5)", &mut ctx).unwrap() + compute("sin(-5*5)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(-0.8604918893688305), - compute("sin(-2*(3/4.-12%5 +7^9) --6/12.*4)", &mut ctx).unwrap() + compute("sin(-2*(3/4.-12%5 +7^9) --6/12.*4)", &mut ctx, "N/A").unwrap() ); } #[test] @@ -309,15 +352,16 @@ fn test_fn_cos() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(0.28366218546322625), - compute("cos(5)", &mut ctx).unwrap() + compute("cos(5)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(0.9912028118634736), - compute("cos(abs(-5*5))", &mut ctx).unwrap() + compute("cos(abs(-5*5))", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(-0.509464138414531), - compute("cos(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx).unwrap() + compute("cos(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx, "N/A") + .unwrap() ); } @@ -326,15 +370,16 @@ fn test_fn_tan() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(-3.380515006246586), - compute("tan(5)", &mut ctx).unwrap() + compute("tan(5)", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(-0.13352640702153587), - compute("tan(abs(-5*5))", &mut ctx).unwrap() + compute("tan(abs(-5*5))", &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Double(-1.6890136606017243), - compute("tan(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx).unwrap() + compute("tan(abs(-2*(3/4.-12%5 +7^9) --6/12.*4))", &mut ctx, "N/A") + .unwrap() ); } @@ -343,7 +388,8 @@ fn test_extra() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::Double(44721.45950030539), - compute("sqrt((2*10^9-5*abs(8/9.))) + abs(1/10.)", &mut ctx).unwrap() + compute("sqrt((2*10^9-5*abs(8/9.))) + abs(1/10.)", &mut ctx, "N/A") + .unwrap() ); assert_eq!( @@ -357,7 +403,8 @@ fn test_extra() { abs(-2*(3/4.-12%5 +7^9) -6/12.*4 / sqrt(5)) } ", - &mut ctx + &mut ctx, + "N/A" ) .unwrap() ); @@ -373,7 +420,8 @@ fn test_extra() { } ", - &mut ctx + &mut ctx, + "N/A" ) .unwrap() ); @@ -389,86 +437,117 @@ fn test_extra() { } ", - &mut ctx + &mut ctx, + "N/A" ) .unwrap() ); - assert_eq!(Primitive::Double(-1.), compute("cos(Ï€)", &mut ctx).unwrap()); + assert_eq!( + Primitive::Double(-1.), + compute("cos(Ï€)", &mut ctx, "N/A").unwrap() + ); } #[test] fn test_simple_bool() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Bool(true), compute("g = true", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(true), + compute("g = true", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(true), ctx["g"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(false), compute("g = false", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(false), + compute("g = false", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(false), ctx["g"].read().unwrap().clone()); } #[test] fn test_simple_condition() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Bool(true), compute("g = 5 < 9", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(true), + compute("g = 5 < 9", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(true), ctx["g"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(false), compute("b = 5 < 1", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(false), + compute("b = 5 < 1", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(false), ctx["b"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(false), compute("x = 5 > 9", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(false), + compute("x = 5 > 9", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(false), ctx["x"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(true), compute("x = 9 > 5", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(true), + compute("x = 9 > 5", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(true), ctx["x"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(true), compute("m = 9 >= 9", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(true), + compute("m = 9 >= 9", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(true), ctx["m"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(false), compute("z = 9 > 9", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(false), + compute("z = 9 > 9", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(false), ctx["z"].read().unwrap().clone()); - assert_eq!(Primitive::Bool(true), compute("t = 9 == 9", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(true), + compute("t = 9 == 9", &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Bool(true), ctx["t"].read().unwrap().clone()); assert_eq!( Primitive::Bool(false), - compute("et = 9 != 9", &mut ctx).unwrap() + compute("et = 9 != 9", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(false), ctx["et"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("zet = 9 != 1", &mut ctx).unwrap() + compute("zet = 9 != 1", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["zet"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("bzet = 9 <= 9", &mut ctx).unwrap() + compute("bzet = 9 <= 9", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["bzet"].read().unwrap().clone()); assert_eq!( Primitive::Bool(false), - compute("rbzet = 9 < 9", &mut ctx).unwrap() + compute("rbzet = 9 < 9", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(false), ctx["rbzet"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("ab = true == true", &mut ctx).unwrap() + compute("ab = true == true", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["ab"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("bcd = true == ab", &mut ctx).unwrap() + compute("bcd = true == ab", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["bcd"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("bcxkcdd = bcd != !ab", &mut ctx).unwrap() + compute("bcxkcdd = bcd != !ab", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["bcxkcdd"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("mmm = !bcd == !ab", &mut ctx).unwrap() + compute("mmm = !bcd == !ab", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["bcxkcdd"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("xxx = !bcd == (5^2 < 1)", &mut ctx).unwrap() + compute("xxx = !bcd == (5^2 < 1)", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["xxx"].read().unwrap().clone()); assert_eq!( Primitive::Bool(false), - compute("rrr = !bcd != (5^2 < 1)", &mut ctx).unwrap() + compute("rrr = !bcd != (5^2 < 1)", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(false), ctx["rrr"].read().unwrap().clone()); } @@ -479,32 +558,32 @@ fn test_simple_logical_and_or() { assert_eq!( Primitive::Bool(false), - compute("s = true && false", &mut ctx).unwrap() + compute("s = true && false", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(false), ctx["s"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("s = 1^1 == 1. && true", &mut ctx).unwrap() + compute("s = 1^1 == 1. && true", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["s"].read().unwrap().clone()); assert_eq!( Primitive::Bool(false), - compute("s = 1^1 == 1. && !true", &mut ctx).unwrap() + compute("s = 1^1 == 1. && !true", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(false), ctx["s"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("s = 1^1 == 1. || !true", &mut ctx).unwrap() + compute("s = 1^1 == 1. || !true", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["s"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute("s = !(1^1 == 1.) || true", &mut ctx).unwrap() + compute("s = !(1^1 == 1.) || true", &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Bool(true), ctx["s"].read().unwrap().clone()); assert_eq!( Primitive::Bool(true), - compute(" 5 < 3 || 4 < 8 && 9*5 == 45", &mut ctx).unwrap() + compute(" 5 < 3 || 4 < 8 && 9*5 == 45", &mut ctx, "N/A").unwrap() ); } @@ -513,42 +592,51 @@ fn test_str() { let mut ctx = BTreeMap::new(); assert_eq!( Primitive::String("aaaaa".to_string()), - compute(r#""a"*5"#, &mut ctx).unwrap() + compute(r#""a"*5"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("a5".to_string()), - compute(r#""a"+5"#, &mut ctx).unwrap() + compute(r#""a"+5"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::String("a5.1".to_string()), - compute(r#""a"+5.1"#, &mut ctx).unwrap() + compute(r#""a"+5.1"#, &mut ctx, "N/A").unwrap() ); } #[test] fn test_op_pow_sugar() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(4), compute(r#"2²"#, &mut ctx).unwrap()); - assert_eq!(Primitive::Int(8), compute(r#"2³"#, &mut ctx).unwrap()); + assert_eq!(Primitive::Int(4), compute(r#"2²"#, &mut ctx, "N/A").unwrap()); + assert_eq!(Primitive::Int(8), compute(r#"2³"#, &mut ctx, "N/A").unwrap()); let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(4), compute(r#"x = 2²"#, &mut ctx).unwrap()); - assert_eq!(Primitive::Int(8), compute(r#"y =2³"#, &mut ctx).unwrap()); + assert_eq!( + Primitive::Int(4), + compute(r#"x = 2²"#, &mut ctx, "N/A").unwrap() + ); + assert_eq!( + Primitive::Int(8), + compute(r#"y =2³"#, &mut ctx, "N/A").unwrap() + ); assert_eq!(Primitive::Int(4), ctx["x"].clone().read().unwrap().clone()); assert_eq!(Primitive::Int(8), ctx["y"].clone().read().unwrap().clone()); let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(25), compute(r#"x = (2-7)²"#, &mut ctx).unwrap()); + assert_eq!( + Primitive::Int(25), + compute(r#"x = (2-7)²"#, &mut ctx, "N/A").unwrap() + ); assert_eq!( Primitive::Int(-125), - compute(r#"y =(2-7)³"#, &mut ctx).unwrap() + compute(r#"y =(2-7)³"#, &mut ctx, "N/A").unwrap() ); assert_eq!(Primitive::Int(25), ctx["x"].clone().read().unwrap().clone()); assert_eq!(Primitive::Int(-125), ctx["y"].clone().read().unwrap().clone()); assert_eq!( Primitive::Int(624250225), - compute(r#"z = (2-7)² * ( 3-2³ * x²)² "#, &mut ctx).unwrap() + compute(r#"z = (2-7)² * ( 3-2³ * x²)² "#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Int(624250225), @@ -559,29 +647,35 @@ fn test_op_pow_sugar() { #[test] fn test_implicit_multiply() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Int(2), compute(r#"x = 2"#, &mut ctx).unwrap()); - assert_eq!(Primitive::Int(4), compute(r#"2x"#, &mut ctx).unwrap()); - assert_eq!(Primitive::Double(1.), compute(r#"0.5x"#, &mut ctx).unwrap()); + assert_eq!( + Primitive::Int(2), + compute(r#"x = 2"#, &mut ctx, "N/A").unwrap() + ); + assert_eq!(Primitive::Int(4), compute(r#"2x"#, &mut ctx, "N/A").unwrap()); + assert_eq!( + Primitive::Double(1.), + compute(r#"0.5x"#, &mut ctx, "N/A").unwrap() + ); assert_eq!( Primitive::Bool(true), - compute(r#"x² == 2x"#, &mut ctx).unwrap() + compute(r#"x² == 2x"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Bool(true), - compute(r#"x² == 2x^(0.5x)"#, &mut ctx).unwrap() + compute(r#"x² == 2x^(0.5x)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Bool(true), - compute(r#"3x²+2x== x*(3*x+2)"#, &mut ctx).unwrap() + compute(r#"3x²+2x== x*(3*x+2)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Bool(true), - compute(r#"3x²+2x== x*(3x+2)"#, &mut ctx).unwrap() + compute(r#"3x²+2x== x*(3x+2)"#, &mut ctx, "N/A").unwrap() ); assert_eq!( Primitive::Bool(true), - compute(r#"2*2^0.5*2== 2x^0.5x"#, &mut ctx).unwrap() + compute(r#"2*2^0.5*2== 2x^0.5x"#, &mut ctx, "N/A").unwrap() ); } @@ -592,13 +686,13 @@ fn test_bug_pow_sugar() { x = 2 4==2x²-2x "#; - assert_eq!(Primitive::Bool(true), compute(expr, &mut ctx).unwrap()); + assert_eq!(Primitive::Bool(true), compute(expr, &mut ctx, "N/A").unwrap()); let mut ctx = BTreeMap::new(); let expr = r#" x = 2 12==2x³-2x "#; - assert_eq!(Primitive::Bool(true), compute(expr, &mut ctx).unwrap()); + assert_eq!(Primitive::Bool(true), compute(expr, &mut ctx, "N/A").unwrap()); let expr = r#" multiline { @@ -613,21 +707,27 @@ fn test_bug_pow_sugar() { * 400 % 2 - (1 * 10^3) } "#; - assert_eq!(Primitive::Bool(true), compute(expr, &mut ctx).unwrap()); + assert_eq!(Primitive::Bool(true), compute(expr, &mut ctx, "N/A").unwrap()); assert_eq!( Primitive::Bool(true), - compute("2x² --2x == 2x²+2x", &mut ctx).unwrap() + compute("2x² --2x == 2x²+2x", &mut ctx, "N/A").unwrap() ); } #[test] fn bug_javascript_meme() { let mut ctx = BTreeMap::new(); - assert_eq!(Primitive::Bool(true), compute("3<2<1", &mut ctx).unwrap()); // FIXME - // python returns false - // which is correct - // *mathematically* - assert_eq!(Primitive::Bool(false), compute("3>2>1<3", &mut ctx).unwrap()); + assert_eq!( + Primitive::Bool(true), + compute("3<2<1", &mut ctx, "N/A").unwrap() + ); // FIXME + // python returns false + // which is correct + // *mathematically* + assert_eq!( + Primitive::Bool(false), + compute("3>2>1<3", &mut ctx, "N/A").unwrap() + ); } #[test] @@ -642,5 +742,8 @@ fn recur_early_return() { } fact(6) "#; - assert_eq!(Primitive::Int(720i128), compute(script, &mut ctx).unwrap()); + assert_eq!( + Primitive::Int(720i128), + compute(script, &mut ctx, "N/A").unwrap() + ); } diff --git a/src/adana_script/tests/mod.rs b/src/adana_script/tests/mod.rs index 1ffa690..b74ab7b 100644 --- a/src/adana_script/tests/mod.rs +++ b/src/adana_script/tests/mod.rs @@ -1,4 +1,5 @@ mod builtin; +mod dynload; mod examples; mod foreach; mod funct; diff --git a/src/adana_script/tests/range.rs b/src/adana_script/tests/range.rs index c9323c9..50d480d 100644 --- a/src/adana_script/tests/range.rs +++ b/src/adana_script/tests/range.rs @@ -12,7 +12,7 @@ fn simple_foreach_range() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(10), ctx["total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); } @@ -22,7 +22,7 @@ fn simple_range() { arr = 1..5 "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::Array(vec![ Primitive::Int(1), @@ -41,7 +41,7 @@ fn simple_range_in_array() { arr2 = [ 9, 1, 3, true, 1..=5 ] "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::Array(vec![ Primitive::Int(9), @@ -83,7 +83,7 @@ fn simple_range_in_function() { arr2 = y() "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::Array(vec![ Primitive::Int(1), @@ -116,7 +116,7 @@ fn simple_range_struct() { }#end "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::Struct(BTreeMap::from([ ( @@ -154,7 +154,7 @@ fn simple_foreach_range_both_end() { } "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(15), ctx["total"].read().unwrap().clone()); assert!(ctx.get("a").is_none()); } diff --git a/src/adana_script/tests/strings.rs b/src/adana_script/tests/strings.rs index 30c79b1..1ff0cae 100644 --- a/src/adana_script/tests/strings.rs +++ b/src/adana_script/tests/strings.rs @@ -12,7 +12,7 @@ fn test_string_block2() { there, nothing will stop you""" "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String( r#"For strings, you can use string blocks: @@ -30,7 +30,7 @@ fn test_string_escape() { s = "\"gipitou engine, gipitou\"" "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String(r#""gipitou engine, gipitou""#.to_string()), ctx["s"].read().unwrap().clone() @@ -45,7 +45,7 @@ fn test_string_block_with_parameters() { s = """Hello ${name}! You are ${age} years old.""" "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String( r#"Hello nordine! You are 34 years old."#.to_string() @@ -72,7 +72,7 @@ fn test_string_block_with_parameters_struct() { s = """Hello ${person.name}! You are ${person.age} years old. ${person.wasup(person.age)}""" "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String( r#"Hello nordine! You are 34 years old. you are old!"#.to_string() @@ -112,7 +112,7 @@ fn test_string_block_complete() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String( r#"Hello nordine! You are 34 years old. you are old!"#.to_string() @@ -161,7 +161,7 @@ fn parse_multi_values() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String( r#"Hello nordine! You are 34 years old. @@ -206,7 +206,7 @@ fn parse_f_strings_fn() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( Primitive::String( r#"Hello nordine! You are 34 years old. diff --git a/src/adana_script/tests/struc.rs b/src/adana_script/tests/struc.rs index a689411..f6e6876 100644 --- a/src/adana_script/tests/struc.rs +++ b/src/adana_script/tests/struc.rs @@ -10,7 +10,7 @@ use adana_script_core::{primitive::Primitive, Value}; fn test_simple_struc() { let mut ctx = BTreeMap::new(); let expr = "x = struct {x: 8}"; - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(ctx.len(), 1); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -30,7 +30,7 @@ fn test_simple_struc_with_more_stuff_in_it() { y: "hello;", z: ()=> {println("hello")} }"#; - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(ctx.len(), 1); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -73,7 +73,7 @@ fn test_struct_eq() { } x == y "#; - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Bool(true), res); let expr = r#" @@ -88,7 +88,7 @@ fn test_struct_eq() { } x == y "#; - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Bool(false), res); } @@ -103,7 +103,7 @@ fn test_struct_access() { } person.age "#; - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Int(20)); } @@ -119,7 +119,7 @@ fn test_struct_variable_assign() { person.age = 34 person.age "#; - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(res, Primitive::Int(34)); } #[test] @@ -159,7 +159,7 @@ fn test_struct_complex_ish() { test5 = person_service.boom(person) test6 = person_service["boom"](person) "#; - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["test1"].read().unwrap().clone(), Primitive::String("hi hello".to_string()) @@ -198,7 +198,7 @@ fn test_struct_access_key() { s["name"] "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("nordine".into())); } #[test] @@ -212,7 +212,7 @@ fn test_struct_access_key2() { }["name"] "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("nordine".into())); } @@ -227,7 +227,7 @@ fn test_struct_access_key3() { }.name "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("nordine".into())); } @@ -242,7 +242,7 @@ fn test_struct_access_key4() { }.name() "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("nordine".into())); } @@ -257,7 +257,7 @@ fn test_struct_access_key5() { }["name"]() "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("nordine".into())); } @@ -269,6 +269,6 @@ fn test_struct_empty() { s.x = "nordine" s.x "#; - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::String("nordine".into())); } diff --git a/src/adana_script/tests/test_array.rs b/src/adana_script/tests/test_array.rs index 69a3164..bfb3871 100644 --- a/src/adana_script/tests/test_array.rs +++ b/src/adana_script/tests/test_array.rs @@ -14,7 +14,7 @@ fn test_simple_array() { include("file_tests/test_simple_array.adana") "#; let mut ctx = BTreeMap::new(); - let _ = compute(file_path, &mut ctx).unwrap(); + let _ = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(ctx.len(), 4); let ctx: BTreeMap = ctx .iter() @@ -69,7 +69,7 @@ fn test_file_array() { include("file_tests/test_array.adana") "#; let mut ctx = BTreeMap::new(); - let _ = compute(file_path, &mut ctx).unwrap(); + let _ = compute(file_path, &mut ctx, "N/A").unwrap(); assert_eq!(ctx["arrlen"].read().unwrap().clone(), Int(18)); let arr = Array(vec![ @@ -126,7 +126,7 @@ fn test_file_array() { ]); assert_eq!(ctx["list"].read().unwrap().clone(), fancy_list); - let res = compute("arr[2]", &mut ctx).unwrap(); + let res = compute("arr[2]", &mut ctx, "N/A").unwrap(); assert_eq!(Str("bababa".to_string()), res) } @@ -138,7 +138,7 @@ fn test_string_array() { include("file_tests/test_string_arr.adana") "#; let mut ctx = BTreeMap::new(); - let _ = compute(file_path, &mut ctx).unwrap(); + let _ = compute(file_path, &mut ctx, "N/A").unwrap(); let ctx: BTreeMap = ctx .iter() .map(|(k, v)| (k.to_string(), v.read().unwrap().clone())) @@ -162,7 +162,7 @@ fn test_array_expr_access() { x = [1, 2, 3][0] "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(ctx["x"].read().unwrap().clone(), Primitive::Int(1)); assert_eq!(r, Primitive::Int(1)); } @@ -174,7 +174,7 @@ fn test_array_expr_access_not_assigned() { [1, 2, 3][1] "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(r, Primitive::Int(2)); } #[test] @@ -188,7 +188,7 @@ fn test_array_access_expr() { arr_str = sort(arr_str) "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["arr_ints"].read().unwrap().clone(), diff --git a/src/adana_script/tests/test_chaining.rs b/src/adana_script/tests/test_chaining.rs index 0540bce..04baf59 100644 --- a/src/adana_script/tests/test_chaining.rs +++ b/src/adana_script/tests/test_chaining.rs @@ -13,7 +13,7 @@ fn complex_struct_array() { "#; let mut ctx = BTreeMap::new(); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -32,7 +32,7 @@ fn complex_struct_array_struct() { "#; let mut ctx = BTreeMap::new(); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -58,7 +58,7 @@ fn complex_struct_struct_struct() { "#; let mut ctx = BTreeMap::new(); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -84,7 +84,7 @@ fn complex_struct_struct_struct_fn() { "#; let mut ctx = BTreeMap::new(); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -110,7 +110,7 @@ fn complex_struct_struct_struct_fn2() { "#; let mut ctx = BTreeMap::new(); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), @@ -126,7 +126,7 @@ fn simple_array_two_depth() { x = (z[2] + z[3][1] + z[3][2]) # FIXME requires parenthesises "#; let mut ctx = BTreeMap::new(); - let res = compute(expr, &mut ctx).unwrap(); + let res = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), diff --git a/src/adana_script/tests/test_drop.rs b/src/adana_script/tests/test_drop.rs index 1f4d6d3..b2a59b9 100644 --- a/src/adana_script/tests/test_drop.rs +++ b/src/adana_script/tests/test_drop.rs @@ -12,7 +12,7 @@ fn test_drop_arr_access() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(exp, &mut ctx).unwrap(); + let _ = compute(exp, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["arr"].read().unwrap().clone(), Primitive::Array(vec![ @@ -30,7 +30,7 @@ fn test_drop_string() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(exp, &mut ctx).unwrap(); + let _ = compute(exp, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["arr"].read().unwrap().clone(), Primitive::String("ello".to_string()) @@ -48,7 +48,7 @@ fn test_drop_struct_access() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(exp, &mut ctx).unwrap(); + let _ = compute(exp, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["s"].read().unwrap().clone(), Primitive::Struct(BTreeMap::from([ @@ -85,7 +85,7 @@ fn test_drop_struct_access_alt() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(exp, &mut ctx).unwrap(); + let _ = compute(exp, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["s"].read().unwrap().clone(), Primitive::Struct(BTreeMap::from([ diff --git a/src/adana_script/tests/test_parser.rs b/src/adana_script/tests/test_parser.rs index 9e9da8c..5c4a19e 100644 --- a/src/adana_script/tests/test_parser.rs +++ b/src/adana_script/tests/test_parser.rs @@ -465,9 +465,9 @@ fn test_array_fn_access() { ])) }, Value::FunctionCall { - parameters: Box::new(Value::BlockParen(vec![ - Value::Expression(vec![Value::Integer(5)]) - ])), + parameters: Box::new(Value::BlockParen(vec![Value::Integer( + 5 + )])), function: Box::new(Value::ArrayAccess { arr: Box::new(Value::Variable("n".into())), index: Box::new(Value::Integer(2)) diff --git a/src/adana_script/tests/test_reference.rs b/src/adana_script/tests/test_reference.rs index 14ae168..aeb481f 100644 --- a/src/adana_script/tests/test_reference.rs +++ b/src/adana_script/tests/test_reference.rs @@ -12,7 +12,7 @@ fn test_simple() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), ctx["y"].read().unwrap().clone() @@ -29,7 +29,7 @@ fn test_simple_modify() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), ctx["y"].read().unwrap().clone() @@ -49,7 +49,7 @@ fn test_simple_struct_ref() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), ctx["y"].read().unwrap().clone() @@ -69,7 +69,7 @@ fn test_simple_array_ref() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), ctx["y"].read().unwrap().clone() @@ -93,7 +93,7 @@ fn test_forin_range_ref() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), ctx["y"].read().unwrap().clone() @@ -115,7 +115,7 @@ fn test_forin_range_ref2() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!( ctx["x"].read().unwrap().clone(), ctx["y"].read().unwrap().clone() diff --git a/src/adana_script/tests/test_scope_ctx.rs b/src/adana_script/tests/test_scope_ctx.rs index e47e8c9..1c1183d 100644 --- a/src/adana_script/tests/test_scope_ctx.rs +++ b/src/adana_script/tests/test_scope_ctx.rs @@ -14,7 +14,7 @@ fn test_if_scope_simple() { z = 8 } "#; - let _ = compute(program, &mut ctx).unwrap(); + let _ = compute(program, &mut ctx, "N/A").unwrap(); assert!(!ctx.contains_key("z")); assert_eq!(Primitive::Int(4), ctx["x"].read().unwrap().clone()); } @@ -32,7 +32,7 @@ fn test_if_else_scope_simple() { x = x +1 } "#; - let _ = compute(program, &mut ctx).unwrap(); + let _ = compute(program, &mut ctx, "N/A").unwrap(); assert_eq!(Primitive::Int(5), ctx["x"].read().unwrap().clone()); assert!(!ctx.contains_key("z")); assert!(!ctx.contains_key("b")); @@ -60,7 +60,7 @@ fn test_if_scope_complex() { z = 8 } "#; - let _ = compute(program, &mut ctx).unwrap(); + let _ = compute(program, &mut ctx, "N/A").unwrap(); assert!(!ctx.contains_key("z")); assert!(!ctx.contains_key("l")); assert!(!ctx.contains_key("h")); @@ -99,7 +99,7 @@ fn test_if_else_scope_complex() { z = 8 } "#; - let _ = compute(program, &mut ctx).unwrap(); + let _ = compute(program, &mut ctx, "N/A").unwrap(); assert!(!ctx.contains_key("z")); assert!(!ctx.contains_key("l")); assert!(!ctx.contains_key("h")); @@ -119,7 +119,7 @@ fn test_while_scope_simple() { z = 8 } "#; - let _ = compute(program, &mut ctx).unwrap(); + let _ = compute(program, &mut ctx, "N/A").unwrap(); assert!(!ctx.contains_key("z")); assert_eq!(Primitive::Int(4), ctx["x"].read().unwrap().clone()); } @@ -144,7 +144,7 @@ fn test_while_scope_complex() { } "#; - let _ = compute(program, &mut ctx).unwrap(); + let _ = compute(program, &mut ctx, "N/A").unwrap(); assert!(!ctx.contains_key("z")); assert!(!ctx.contains_key("p")); assert!(!ctx.contains_key("d")); diff --git a/src/adana_script/tests/tests_file.rs b/src/adana_script/tests/tests_file.rs index 0cb3cde..fdfe3cc 100644 --- a/src/adana_script/tests/tests_file.rs +++ b/src/adana_script/tests/tests_file.rs @@ -12,7 +12,7 @@ fn test_simple_file() { include("file_tests/test1.adana") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); let ctx: BTreeMap = ctx .iter() @@ -37,7 +37,7 @@ fn test_if_statement() { include("file_tests/test2.adana") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); let ctx: BTreeMap = ctx .iter() @@ -79,7 +79,7 @@ fn test_while_statement() { for n in 0..=10 { ctx.insert("n".to_string(), Primitive::Int(n).ref_prim()); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); let fibonacci = fib(n); assert_eq!(Primitive::Int(fibonacci), ctx["c"].read().unwrap().clone()); assert_eq!(Primitive::Int(fibonacci), r); @@ -101,7 +101,7 @@ fn test_nested_file() { include("file_tests/test_nested.adana") "#; let mut ctx = BTreeMap::new(); - let r = compute(file_path, &mut ctx).unwrap(); + let r = compute(file_path, &mut ctx, "N/A").unwrap(); let ctx: BTreeMap = ctx .iter() @@ -127,7 +127,7 @@ fn test_fizz_buzz() { include("file_tests/test_fizzbuzz.adana") "#; let mut ctx = BTreeMap::new(); - let _ = compute(file_path, &mut ctx); + let _ = compute(file_path, &mut ctx, "N/A"); assert_eq!( Primitive::String("100 = Buzz".to_string()), @@ -142,7 +142,7 @@ fn test_includes() { let file_path = r#" include("file_tests/includes/reverse.adana") "#; - let _ = compute(file_path, &mut ctx).unwrap(); + let _ = compute(file_path, &mut ctx, "N/A").unwrap(); let ctx: BTreeMap = ctx .iter() @@ -185,7 +185,7 @@ fn test_multiline_file() { include("file_tests/test_multiline.adana") "#; let mut ctx = BTreeMap::new(); - let _ = compute(file_path, &mut ctx); + let _ = compute(file_path, &mut ctx, "N/A"); let ctx: BTreeMap = ctx .iter() @@ -215,16 +215,16 @@ fn test_if_else_file() { "#; let mut ctx = BTreeMap::new(); ctx.insert("count".to_string(), Primitive::Int(102).ref_prim()); - let _ = compute(file_path, &mut ctx); + let _ = compute(file_path, &mut ctx, "N/A"); assert_eq!(ctx["count"].read().unwrap().clone(), Primitive::Int(101)); - let _ = compute(file_path, &mut ctx); + let _ = compute(file_path, &mut ctx, "N/A"); assert_eq!(ctx["count"].read().unwrap().clone(), Primitive::Int(51)); let file_path = r#" include("file_tests/test_fizzbuzz_else.adana") "#; let mut ctx = BTreeMap::new(); - let _ = compute(file_path, &mut ctx); + let _ = compute(file_path, &mut ctx, "N/A"); assert_eq!( Primitive::String("100 = Buzz".to_string()), diff --git a/src/adana_script/tests/unused.rs b/src/adana_script/tests/unused.rs index f3172f7..b54ae25 100644 --- a/src/adana_script/tests/unused.rs +++ b/src/adana_script/tests/unused.rs @@ -10,7 +10,7 @@ fn test_simple_unused_array() { _ = [1,2,3,4] "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -29,7 +29,7 @@ fn test_simple_unused_range() { _ = 1..=4 "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -49,7 +49,7 @@ fn test_simple_unused_fn_call_range() { _ = (n) => { 1..=n }(4) "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -69,7 +69,7 @@ fn test_simple_unused_fn_parameter() { _ = (_) => { 1..=4 }(4) "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -88,7 +88,7 @@ fn test_simple_unused_fn_multiple_parameters() { _ = (_,n) => { 1..=n }("hello",4) "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -107,7 +107,7 @@ fn test_simple_unused_fn_multiple_parameters2() { _ = (n,_) => { 1..=n }(4,"hello") "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -132,7 +132,7 @@ fn test_simple_unused_struct() { } # more comments "#; let mut ctx = BTreeMap::new(); - let r = compute(expr, &mut ctx).unwrap(); + let r = compute(expr, &mut ctx, "N/A").unwrap(); assert!(ctx.is_empty()); assert_eq!( @@ -159,7 +159,7 @@ fn test_simple_unused_foreach() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(ctx.len(), 1); assert_eq!( @@ -183,7 +183,7 @@ fn test_simple_unused_foreach_index() { "#; let mut ctx = BTreeMap::new(); - let _ = compute(expr, &mut ctx).unwrap(); + let _ = compute(expr, &mut ctx, "N/A").unwrap(); assert_eq!(ctx.len(), 1); assert_eq!( diff --git a/src/args.rs b/src/args.rs index f08375f..0d65cce 100644 --- a/src/args.rs +++ b/src/args.rs @@ -5,6 +5,7 @@ pub enum Argument { DbPath(String), NoFallbackInMemory, HistoryPath(String), + SharedLibPath(String), DefaultCache(String), } @@ -56,6 +57,17 @@ pub fn parse_args( let path = args.next().context("history path missing!!")?; arguments.push(Argument::HistoryPath(path)); } + + "--sharedlibpath" | "-slp" => { + anyhow::ensure!( + !arguments + .iter() + .any(|a| matches!(a, Argument::SharedLibPath(_))), + "shared lib path should be specified only once!" + ); + let path = args.next().context("shared lib path missing!!")?; + arguments.push(Argument::SharedLibPath(path)); + } "--cache" | "-c" => { let default_cache = args.next().context("default cache missing!!")?; diff --git a/src/main.rs b/src/main.rs index 37b5c2f..033cd3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,12 @@ mod prelude; mod reserved_keywords; use adana_script_core::primitive::Primitive; +use anyhow::Context; use args::*; use db::DbOp; use log::debug; use rustyline::error::ReadlineError; -use std::path::Path; +use std::path::{Path, PathBuf}; use prelude::{colors::LightBlue, colors::Style, BTreeMap}; @@ -19,20 +20,23 @@ use crate::{ adana_script::compute, cache_command::{clear_terminal, get_default_cache, process_command}, db::{Config, Db}, + prelude::get_path_to_shared_libraries, }; const VERSION: &str = env!("CARGO_PKG_VERSION"); +const RUST_VERSION: &str = std::env!("CARGO_PKG_RUST_VERSION"); const PKG_NAME: &str = env!("CARGO_PKG_NAME"); fn main() -> anyhow::Result<()> { env_logger::init(); + ctrlc::set_handler(|| { debug!("catch CTRL-C! DO NOT REMOVE this. receive ctrl+c signal 2") })?; let args = parse_args(std::env::args())?; clear_terminal(); - println!("{PKG_NAME} v{VERSION}"); + println!("{PKG_NAME} v{VERSION} (rust version: {RUST_VERSION})"); let config = if args.is_empty() { Config::default() @@ -65,14 +69,38 @@ fn main() -> anyhow::Result<()> { None } }); - println!(); + let path_to_shared_lib: PathBuf = args + .iter() + .find_map(|a| { + if let Argument::SharedLibPath(slp) = a { + Some(PathBuf::from(&slp)) + } else { + None + } + }) + .or_else(|| { + let path_so = get_path_to_shared_libraries() + .context("couldn't determine shared library path") + .unwrap(); + if !path_so.exists() { + std::fs::create_dir_all(path_so.as_path()) + .context("could not create directory for shared lib") + .unwrap(); + } + Some(path_so) + }) + .context("ERR: shared lib path could not be built")?; + + println!("shared lib path: {path_to_shared_lib:?}"); + + println!(); match Db::open(config) { Ok(Db::InMemory(mut db)) => { - start_app(&mut db, history_path, default_cache) + start_app(&mut db, history_path, &path_to_shared_lib, default_cache) } Ok(Db::FileBased(mut db)) => { - start_app(&mut db, history_path, default_cache) + start_app(&mut db, history_path, &path_to_shared_lib, default_cache) } Err(e) => Err(e), } @@ -81,6 +109,7 @@ fn main() -> anyhow::Result<()> { fn start_app( db: &mut impl DbOp, history_path: Option + Copy>, + shared_lib_path: impl AsRef + Copy, default_cache: Option, ) -> anyhow::Result<()> { let mut current_cache = { @@ -109,7 +138,7 @@ fn start_app( } let script_res = { - match compute(&line, &mut script_context) { + match compute(&line, &mut script_context, shared_lib_path) { Ok(Primitive::Error(e)) => Err(anyhow::Error::msg(e)), Ok(calc) => Ok(calc), e @ Err(_) => e, @@ -119,6 +148,7 @@ fn start_app( Ok(Primitive::Unit) => {} Ok(calc) => println!("{calc}"), Err(calc_err) => { + eprintln!("Error: {calc_err:?}"); match process_command( db, &mut script_context, @@ -128,7 +158,6 @@ fn start_app( ) { Ok(_) => (), Err(err) => { - eprintln!("{calc_err}"); eprintln!("Err: {err}"); } } diff --git a/src/prelude.rs b/src/prelude.rs index dd683b5..de6e7fe 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -48,3 +48,12 @@ pub mod colors { pub use nu_ansi_term::Style; } pub use serde::{Deserialize, Serialize}; + +pub const SHARED_LIB_DIR: &str = ".libs_adana"; + +pub fn get_path_to_shared_libraries() -> Option { + dirs::data_dir().or_else(dirs::home_dir).map(|mut pb| { + pb.push(PathBuf::from(SHARED_LIB_DIR)); + pb + }) +} diff --git a/src/reserved_keywords.rs b/src/reserved_keywords.rs index 9535f88..70c3809 100644 --- a/src/reserved_keywords.rs +++ b/src/reserved_keywords.rs @@ -36,6 +36,7 @@ pub const FORBIDDEN_VARIABLE_NAME: &[&str] = &[ INCLUDE, WHILE, ELSE, + REQUIRE, MULTILINE, STRUCT, Operator::Add.as_str(), diff --git a/static_binaries/adana-0.13.2 b/static_binaries/adana-0.13.2 deleted file mode 100755 index 336d45d..0000000 Binary files a/static_binaries/adana-0.13.2 and /dev/null differ diff --git a/static_binaries/adana-0.13.23 b/static_binaries/adana-0.13.23 deleted file mode 100755 index d4d14fa..0000000 Binary files a/static_binaries/adana-0.13.23 and /dev/null differ diff --git a/static_binaries/adana-0.13.24 b/static_binaries/adana-0.13.24 deleted file mode 100755 index 3fcbc11..0000000 Binary files a/static_binaries/adana-0.13.24 and /dev/null differ diff --git a/static_binaries/adana-0.13.26 b/static_binaries/adana-0.13.26 deleted file mode 100755 index 9e578e6..0000000 Binary files a/static_binaries/adana-0.13.26 and /dev/null differ diff --git a/static_binaries/adana-0.13.27 b/static_binaries/adana-0.13.27 deleted file mode 100755 index 74b1937..0000000 Binary files a/static_binaries/adana-0.13.27 and /dev/null differ diff --git a/static_binaries/adana-0.13.29 b/static_binaries/adana-0.13.29 deleted file mode 100755 index 8497db8..0000000 Binary files a/static_binaries/adana-0.13.29 and /dev/null differ diff --git a/static_binaries/adana-0.13.30 b/static_binaries/adana-0.13.30 deleted file mode 100755 index 95c11d6..0000000 Binary files a/static_binaries/adana-0.13.30 and /dev/null differ diff --git a/static_binaries/adana-0.13.31 b/static_binaries/adana-0.13.31 deleted file mode 100755 index 9f79cb0..0000000 Binary files a/static_binaries/adana-0.13.31 and /dev/null differ