diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2361dcec..7ec3a051 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,7 +20,7 @@ jobs:
- { os: macos-11, rust-version: stable, shell: bash, target: 'x86_64-apple-darwin' }
- { os: ubuntu-20.04, rust-version: stable, shell: bash, extra: true, target: 'x86_64-unknown-linux-gnu' }
- { os: ubuntu-20.04, rust-version: stable, shell: bash, target: 'i686-unknown-linux-gnu' }
- - { os: ubuntu-20.04, rust-version: 1.65, shell: bash, target: 'x86_64-unknown-linux-gnu'}
+ - { os: ubuntu-20.04, rust-version: "1.70", shell: bash, target: 'x86_64-unknown-linux-gnu'}
- { os: ubuntu-20.04, rust-version: beta, shell: bash, target: 'x86_64-unknown-linux-gnu'}
- { os: ubuntu-20.04, rust-version: nightly, shell: bash, target: 'x86_64-unknown-linux-gnu'}
defaults:
@@ -54,6 +54,9 @@ jobs:
~/.cargo/git/db/
target/
key: ${{ matrix.os }}_${{ matrix.target }}_rustc-${{ steps.toolchain.outputs.cachekey }}_cargo-${{ hashFiles('**/Cargo.lock') }}
+ - name: Install wasm-pack
+ if: matrix.extra
+ run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
# Build and test.
- name: Build library
@@ -97,12 +100,22 @@ jobs:
run: |
cargo rustc --target ${{ matrix.target }} --verbose --bin scryer-prolog --release -- -D warnings
echo "$PWD/target/release" >> $GITHUB_PATH
+ - name: Build wasm
+ if: matrix.extra
+ run: |
+ wasm-pack build --target web -- --no-default-features
- name: Publish release binary artifact
if: contains(matrix.rust-version,'stable')
uses: actions/upload-artifact@v3
with:
path: target/${{ matrix.target }}/release/scryer-prolog*
name: scryer-prolog_${{ matrix.os }}_${{ matrix.target }}
+ - name: Publish wasm artifact
+ if: matrix.extra
+ uses: actions/upload-artifact@v3
+ with:
+ path: pkg/*
+ name: scryer-prolog_unknown_wasm32
logtalk-test:
runs-on: ubuntu-20.04
@@ -162,6 +175,7 @@ jobs:
zip scryer-prolog_macos-11.zip ./scryer-prolog_macos-11_x86_64-apple-darwin/scryer-prolog
zip scryer-prolog_ubuntu-20.04.zip ./scryer-prolog_ubuntu-20.04_x86_64-unknown-linux-gnu/scryer-prolog
zip scryer-prolog_windows-latest.zip ./scryer-prolog_windows-latest_x86_64-pc-windows-gnu/scryer-prolog.exe
+ zip -r scryer-prolog_unknown-wasm32.zip ./scryer-prolog_unknown_wasm32
- name: Release
uses: softprops/action-gh-release@v1
with:
@@ -169,3 +183,4 @@ jobs:
scryer-prolog_macos-11.zip
scryer-prolog_ubuntu-20.04.zip
scryer-prolog_windows-latest.zip
+ scryer-prolog_unknown-wasm32.zip
diff --git a/Cargo.lock b/Cargo.lock
index fd3211c1..c05e1975 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -260,6 +260,26 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "console_error_panic_hook"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "console_log"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f"
+dependencies = [
+ "log",
+ "web-sys",
+]
+
[[package]]
name = "core-foundation"
version = "0.9.3"
@@ -378,7 +398,7 @@ dependencies = [
[[package]]
name = "dashu"
version = "0.3.1"
-source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23"
+source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [
"dashu-base",
"dashu-float",
@@ -390,37 +410,36 @@ dependencies = [
[[package]]
name = "dashu-base"
version = "0.3.1"
-source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23"
+source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
[[package]]
name = "dashu-float"
version = "0.3.2"
-source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23"
+source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [
"dashu-base",
"dashu-int",
+ "num-modular",
"num-order",
- "num-traits",
"static_assertions",
]
[[package]]
name = "dashu-int"
version = "0.3.1"
-source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23"
+source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [
"cfg-if",
"dashu-base",
- "num-modular 0.5.2",
+ "num-modular",
"num-order",
- "num-traits",
"static_assertions",
]
[[package]]
name = "dashu-macros"
version = "0.3.1"
-source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23"
+source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [
"dashu-base",
"dashu-float",
@@ -433,13 +452,13 @@ dependencies = [
[[package]]
name = "dashu-ratio"
version = "0.3.2"
-source = "git+https://github.com/coasys/dashu.git#f9342190be9062630124e666b001077bb5f02f23"
+source = "git+https://github.com/cmpute/dashu.git#9d1ba4ac98a4675f294e2f2c072bf47f96d33e9b"
dependencies = [
"dashu-base",
"dashu-float",
"dashu-int",
+ "num-modular",
"num-order",
- "num-traits",
]
[[package]]
@@ -683,7 +702,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -1343,39 +1362,19 @@ dependencies = [
"winapi",
]
-[[package]]
-name = "num-integer"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
[[package]]
name = "num-modular"
-version = "0.5.1"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119"
-dependencies = [
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-modular"
-version = "0.5.2"
-source = "git+https://github.com/coasys/num-modular.git#1ae06248ec69390370def3a229b3bf4c209aa6c7"
+checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f"
[[package]]
name = "num-order"
-version = "1.0.4"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e81e321057a0370997b13e6638bba6bd7f6f426e1f8e9a2562490a28eb23e1bc"
+checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6"
dependencies = [
- "num-modular 0.5.1",
- "num-traits",
+ "num-modular",
]
[[package]]
@@ -1441,7 +1440,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -1624,7 +1623,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -2001,6 +2000,8 @@ dependencies = [
"blake2 0.8.1",
"bytes",
"chrono",
+ "console_error_panic_hook",
+ "console_log",
"cpu-time",
"crossterm",
"crrl",
@@ -2026,6 +2027,7 @@ dependencies = [
"maplit",
"modular-bitfield",
"native-tls",
+ "num-order",
"ordered-float",
"phf 0.9.0",
"predicates-core",
@@ -2042,17 +2044,21 @@ dependencies = [
"rustyline",
"ryu",
"select",
+ "serde-wasm-bindgen",
"serial_test",
"sha3 0.8.2",
"smallvec",
"static_assertions",
"strum",
"strum_macros",
- "syn 1.0.109",
+ "syn 2.0.32",
"to-syn-value",
"to-syn-value_derive",
"tokio",
"walkdir",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
]
[[package]]
@@ -2098,6 +2104,17 @@ dependencies = [
"serde_derive",
]
+[[package]]
+name = "serde-wasm-bindgen"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
+dependencies = [
+ "js-sys",
+ "serde",
+ "wasm-bindgen",
+]
+
[[package]]
name = "serde_derive"
version = "1.0.188"
@@ -2106,7 +2123,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -2154,7 +2171,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -2350,9 +2367,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.29"
+version = "2.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
+checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
dependencies = [
"proc-macro2",
"quote",
@@ -2412,7 +2429,7 @@ checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -2443,23 +2460,23 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "to-syn-value"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45dcb7b4108a4793bdd74aa3714296c6eaf43663edf73fa8625d0d7621e68447"
+checksum = "dfcc684f2ceaec3b4e8689657c9e0944b07bf5e34563e0bd758c4d42c05c82ed"
dependencies = [
- "syn 1.0.109",
+ "syn 2.0.32",
"to-syn-value_derive",
]
[[package]]
name = "to-syn-value_derive"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd4fdec6de01b568c1d3721c9d46a352623c536cd55a8a5acfefb63d1fccccbc"
+checksum = "3dfffda778de8443144ff3b042ddf14e8bc5445f0fd9fe937c3d252535dc9212"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.32",
]
[[package]]
@@ -2489,7 +2506,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
]
[[package]]
@@ -2712,7 +2729,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
"wasm-bindgen-shared",
]
@@ -2746,7 +2763,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.32",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
diff --git a/Cargo.toml b/Cargo.toml
index 7c257008..47e26ecc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,16 +10,20 @@ license = "BSD-3-Clause"
keywords = ["prolog", "prolog-interpreter", "prolog-system"]
categories = ["command-line-utilities"]
build = "build/main.rs"
-rust-version = "1.63"
+rust-version = "1.70"
+
+[lib]
+crate-type = ["cdylib", "rlib"]
[features]
-multi_thread = []
-default = ["ffi", "repl", "hostname", "tls", "http"]
+default = ["ffi", "repl", "hostname", "tls", "http", "crypto-full"]
ffi = ["dep:libffi"]
repl = ["dep:crossterm", "dep:ctrlc", "dep:rustyline"]
hostname = ["dep:hostname"]
tls = ["dep:native-tls"]
http = ["dep:hyper", "dep:reqwest"]
+rust_beta_channel = []
+crypto-full = []
[build-dependencies]
indexmap = "1.0.2"
@@ -27,9 +31,9 @@ proc-macro2 = "1.0.36"
quote = "1.0.15"
strum = "0.23"
strum_macros = "0.23"
-syn = { version = "1.0.88", features = ['full', 'visit', 'extra-traits'] }
-to-syn-value = "0.1.0"
-to-syn-value_derive = "0.1.0"
+syn = { version = "2.0.32", features = ['full', 'visit', 'extra-traits'] }
+to-syn-value = "0.1.1"
+to-syn-value_derive = "0.1.1"
walkdir = "2"
[dependencies]
@@ -65,7 +69,8 @@ libloading = "0.7"
derive_deref = "1.1.1"
http-body-util = "0.1.0-rc.2"
bytes = "1"
-dashu = { git = "https://github.com/coasys/dashu.git", version = "0.3.1" }
+dashu = { version = "0.3.1", git = "https://github.com/cmpute/dashu.git" }
+num-order = { version = "1.2.0" }
rand = "0.8.5"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
@@ -84,6 +89,18 @@ tokio = { version = "1.28.2", features = ["full"] }
getrandom = { version = "0.2.10", features = ["js"] }
tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt", "time"] }
+[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
+console_error_panic_hook = "0.1"
+console_log = "1.0"
+wasm-bindgen = "0.2.87"
+wasm-bindgen-futures = "0.4"
+serde-wasm-bindgen = "0.5"
+web-sys = { version = "0.3", features = [
+ "Document",
+ "Window",
+ "Element",
+]}
+
[target.'cfg(target_os = "wasi")'.dependencies]
ring-wasi = { version = "0.16.25" }
diff --git a/Dockerfile b/Dockerfile
index 0c1195ac..9aaac9c0 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,7 +20,12 @@ COPY --from=cacher /scryer-prolog/target target
COPY --from=cacher $CARGO_HOME $CARGO_HOME
RUN cargo build --release --bin scryer-prolog
-FROM debian:stable-slim
+# Newer versions of Debian (i.e. bookworm) contain libssl3 instead of libssl1.1
+# which we depend on.
+FROM debian:bullseye-slim
COPY --from=builder /scryer-prolog/target/release/scryer-prolog /usr/local/bin
ENV RUST_BACKTRACE=1
+# Sanity check the binary: if it can't be executed (e.g. if there are missing libraries)
+# then fail the build
+RUN scryer-prolog --version
ENTRYPOINT ["/usr/local/bin/scryer-prolog"]
diff --git a/INDEX.dj b/INDEX.dj
index c7cf6a11..fcea18de 100644
--- a/INDEX.dj
+++ b/INDEX.dj
@@ -26,9 +26,13 @@ Some of the Scryer Prolog features are:
* Compact string representation
* Network libraries ([TCP sockets](/sockets.html), [HTTP server](/http/http_server.html), [HTTP client](/http/http_open.html), ...)
* [Cryptographical predicates](/crypto.html)
+* [Foreign Function Interface](/ffi.html)
+* WebAssembly support
* WAM based engine, cross-platform made in Rust
* _and more..._
+Try Scryer Prolog without any installation! Use [Scryer Playground](https://play.scryer.pl), which uses the WASM version of Scryer Prolog.
+
## What is Prolog?
Prolog is a logic programming language created by [Alain Colmerauer](https://en.wikipedia.org/wiki/Alain_Colmerauer) and [Robert Kowalski](https://en.wikipedia.org/wiki/Robert_Kowalski) in 1972.
@@ -57,9 +61,13 @@ the builtin Prolog modules and libraries in Scryer, check the documentation site
## Downloads
-The latest version of Scryer Prolog is *0.9.1*. And it's already useful for lots of tasks.
+The latest version of Scryer Prolog is *0.9.2*. And it's already useful for lots of tasks.
-Scryer Prolog can be compiled from source, instructions are on the [GitHub README](https://github.com/mthom/scryer-prolog). It runs on Linux, macOS and Windows. Other operating systems may work but they're not regularly tested.
+| Windows | [Download](https://github.com/mthom/scryer-prolog/releases/download/v0.9.2/scryer-prolog_windows-latest.zip) |
+| macOS (Intel) | [Download](https://github.com/mthom/scryer-prolog/releases/download/v0.9.2/scryer-prolog_macos-11.zip) |
+| Linux | [Download](https://github.com/mthom/scryer-prolog/releases/download/v0.9.2/scryer-prolog_ubuntu-20.04.zip) |
+
+Scryer Prolog can also be compiled from source, instructions are on the [GitHub README](https://github.com/mthom/scryer-prolog). It runs on Linux, macOS and Windows. Other operating systems may work but they're not regularly tested.
If you're in Linux, maybe your distribution already has an Scryer Prolog package.
diff --git a/README.md b/README.md
index 0f889c9b..4ba1f9d6 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,14 @@ strings.
## Installing Scryer Prolog
-### Native Install
+### Binaries
+
+Precompiled binaries for several platforms are available for download
+at:
+
+**https://github.com/mthom/scryer-prolog/releases/tag/v0.9.2**
+
+### Native Compilation
First, install the latest stable version of
[Rust](https://www.rust-lang.org/en-US/install.html) using your
@@ -143,7 +150,78 @@ light.exe scryer-prolog.wixobj
```
It will generate a very basic MSI file which installs the main executable and a shortcut in the Start Menu. It can be installed with a double-click. To uninstall, go to the Control Panel and uninstall as usual.
-Scryer Prolog must be built with **Rust 1.63 and up**.
+Scryer Prolog must be built with **Rust 1.70 and up**.
+
+### Building WebAssembly
+
+Scryer Prolog has basic WebAssembly support. You can follow `wasm-pack`'s [official instructions](https://rustwasm.github.io/docs/wasm-pack/quickstart.html) to install `wasm-pack` and build it in any way you like.
+
+However, none of the [default features](https://doc.rust-lang.org/cargo/reference/features.html#the-default-feature) are currently supported. The preferred way of disabling them is passing [extra options](https://rustwasm.github.io/wasm-pack/book/commands/build.html#extra-options) to `wasm-pack`.
+
+For example, if you want a minimal working package without using any bundler like `webpack`, you can do this:
+```
+wasm-pack build --target web -- --no-default-features
+```
+Then a `pkg` directory will be created, containing everything you need for a webapp. You can test whether the package is successfully built by creating an html file, adapted from `wasm-bindgen`'s [official example](https://rustwasm.github.io/wasm-bindgen/examples/without-a-bundler.html) like this:
+
+```html
+
+
+
+
+ Scryer Prolog - Sudoku Solver Example
+
+
+
+
+```
+
+Then you can serve it with your favorite http server like `python -m http.server` or `npx serve`, and access the page with your browser.
### Docker Install
@@ -285,14 +363,14 @@ innovations of Scryer Prolog. This means that terms which appear as
lists of characters to Prolog programs are stored in packed
UTF-8 encoding by the engine.
-Without this innovation, storing a list of characters in memory
-would use one memory cell per character, one memory cell per
-list constructor, and one memory cell for each tail that occurs
-in the list. Since one memory cell takes 8 bytes on 64-bit
-machines, the packed representation used by Scryer Prolog yields
-an up to **24-fold reduction** of memory usage, and
-corresponding reduction of memory accesses when creating and
-processing strings.
+Without this innovation, storing a list of characters in memory would
+use one WAM memory cell per character, one cell per list
+constructor, and one cell for each tail that occurs in the list. Since
+one cell takes 8 bytes in the WAM as implemented by
+Scryer Prolog, the packed representation yields an up to
+**24-fold reduction** of memory usage, and corresponding
+reduction of memory accesses when creating and processing
+strings.
Scryer Prolog's compact internal string representation makes it
ideally suited for the use case Prolog was originally developed for:
diff --git a/build/instructions_template.rs b/build/instructions_template.rs
index 52fcd8b7..f0a5a49f 100644
--- a/build/instructions_template.rs
+++ b/build/instructions_template.rs
@@ -306,7 +306,7 @@ enum SystemClauseType {
GetBValue,
#[strum_discriminants(strum(props(Arity = "3", Name = "$get_cont_chunk")))]
GetContinuationChunk,
- #[strum_discriminants(strum(props(Arity = "7", Name = "$get_next_op_db_ref")))]
+ #[strum_discriminants(strum(props(Arity = "4", Name = "$get_next_op_db_ref")))]
GetNextOpDBRef,
#[strum_discriminants(strum(props(Arity = "3", Name = "$lookup_db_ref")))]
LookupDBRef,
@@ -496,22 +496,28 @@ enum SystemClauseType {
CryptoDataHKDF,
#[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_password_hash")))]
CryptoPasswordHash,
- #[strum_discriminants(strum(props(Arity = "7", Name = "$crypto_data_encrypt")))]
- CryptoDataEncrypt,
- #[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))]
- CryptoDataDecrypt,
#[strum_discriminants(strum(props(Arity = "4", Name = "$crypto_curve_scalar_mult")))]
CryptoCurveScalarMult,
- #[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign")))]
- Ed25519Sign,
- #[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_verify")))]
- Ed25519Verify,
- #[strum_discriminants(strum(props(Arity = "1", Name = "$ed25519_new_keypair")))]
- Ed25519NewKeyPair,
- #[strum_discriminants(strum(props(Arity = "2", Name = "$ed25519_keypair_public_key")))]
- Ed25519KeyPairPublicKey,
#[strum_discriminants(strum(props(Arity = "3", Name = "$curve25519_scalar_mult")))]
Curve25519ScalarMult,
+ #[cfg(feature = "crypto-full")]
+ #[strum_discriminants(strum(props(Arity = "7", Name = "$crypto_data_encrypt")))]
+ CryptoDataEncrypt,
+ #[cfg(feature = "crypto-full")]
+ #[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))]
+ CryptoDataDecrypt,
+ #[cfg(feature = "crypto-full")]
+ #[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign")))]
+ Ed25519Sign,
+ #[cfg(feature = "crypto-full")]
+ #[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_verify")))]
+ Ed25519Verify,
+ #[cfg(feature = "crypto-full")]
+ #[strum_discriminants(strum(props(Arity = "1", Name = "$ed25519_new_keypair")))]
+ Ed25519NewKeyPair,
+ #[cfg(feature = "crypto-full")]
+ #[strum_discriminants(strum(props(Arity = "2", Name = "$ed25519_keypair_public_key")))]
+ Ed25519KeyPairPublicKey,
#[strum_discriminants(strum(props(Arity = "2", Name = "$first_non_octet")))]
FirstNonOctet,
#[strum_discriminants(strum(props(Arity = "3", Name = "$load_html")))]
@@ -590,7 +596,10 @@ enum SystemClauseType {
UnattributedVar,
#[strum_discriminants(strum(props(Arity = "4", Name = "$get_db_refs")))]
GetDBRefs,
- #[strum_discriminants(strum(props(Arity = "2", Name = "$keysort_with_constant_var_ordering")))]
+ #[strum_discriminants(strum(props(
+ Arity = "2",
+ Name = "$keysort_with_constant_var_ordering"
+ )))]
KeySortWithConstantVarOrdering,
REPL(REPLCodePtr),
}
@@ -801,7 +810,7 @@ enum InstructionTemplate {
}
fn derive_input(ty: &Type) -> Option {
- let clause_type: Type = parse_quote!{ ClauseType };
+ let clause_type: Type = parse_quote! { ClauseType };
let built_in_clause_type: Type = parse_quote! { BuiltInClauseType };
let inlined_clause_type: Type = parse_quote! { InlinedClauseType };
let system_clause_type: Type = parse_quote! { SystemClauseType };
@@ -847,7 +856,8 @@ fn add_discriminant_data(
prefix: &'static str,
variant_data: &mut Vec<(&'static str, Arity, Variant)>,
) -> (&'static str, Arity)
- where DiscriminantT: FromStr + strum::EnumProperty + std::fmt::Debug
+where
+ DiscriminantT: FromStr + strum::EnumProperty + std::fmt::Debug,
{
let name = prop_from_ident::(&variant.ident, "Name");
let arity = Arity::from(prop_from_ident::(&variant.ident, "Arity"));
@@ -948,7 +958,9 @@ fn generate_instruction_preface() -> TokenStream {
#[derive(Clone, Copy, Debug)]
pub enum IndexedChoiceInstruction {
Retry(usize),
+ DefaultRetry(usize),
Trust(usize),
+ DefaultTrust(usize),
Try(usize),
}
@@ -958,6 +970,8 @@ fn generate_instruction_preface() -> TokenStream {
&IndexedChoiceInstruction::Retry(offset) => offset,
&IndexedChoiceInstruction::Trust(offset) => offset,
&IndexedChoiceInstruction::Try(offset) => offset,
+ &IndexedChoiceInstruction::DefaultRetry(offset) => offset,
+ &IndexedChoiceInstruction::DefaultTrust(offset) => offset,
}
}
@@ -972,6 +986,12 @@ fn generate_instruction_preface() -> TokenStream {
&IndexedChoiceInstruction::Retry(offset) => {
functor!(atom!("retry"), [fixnum(offset)])
}
+ &IndexedChoiceInstruction::DefaultTrust(offset) => {
+ functor!(atom!("default_trust"), [fixnum(offset)])
+ }
+ &IndexedChoiceInstruction::DefaultRetry(offset) => {
+ functor!(atom!("default_retry"), [fixnum(offset)])
+ }
}
}
}
@@ -1689,7 +1709,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::CallMakeDirectoryPath |
&Instruction::CallDeleteFile |
&Instruction::CallRenameFile |
- &Instruction::CallFileCopy |
+ &Instruction::CallFileCopy |
&Instruction::CallWorkingDirectory |
&Instruction::CallDeleteDirectory |
&Instruction::CallPathCanonical |
@@ -1783,9 +1803,9 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::CallHttpListen |
&Instruction::CallHttpAccept |
&Instruction::CallHttpAnswer |
- &Instruction::CallLoadForeignLib |
- &Instruction::CallForeignCall |
- &Instruction::CallDefineForeignStruct |
+ &Instruction::CallLoadForeignLib |
+ &Instruction::CallForeignCall |
+ &Instruction::CallDefineForeignStruct |
&Instruction::CallPredicateDefined |
&Instruction::CallStripModule |
&Instruction::CallCurrentTime |
@@ -1828,13 +1848,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::CallCryptoDataHash |
&Instruction::CallCryptoDataHKDF |
&Instruction::CallCryptoPasswordHash |
- &Instruction::CallCryptoDataEncrypt |
- &Instruction::CallCryptoDataDecrypt |
&Instruction::CallCryptoCurveScalarMult |
- &Instruction::CallEd25519Sign |
- &Instruction::CallEd25519Verify |
- &Instruction::CallEd25519NewKeyPair |
- &Instruction::CallEd25519KeyPairPublicKey |
&Instruction::CallCurve25519ScalarMult |
&Instruction::CallFirstNonOctet |
&Instruction::CallLoadHTML |
@@ -1891,6 +1905,17 @@ fn generate_instruction_preface() -> TokenStream {
functor!(atom!("call"), [atom(name), fixnum(arity)])
}
//
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallCryptoDataEncrypt |
+ &Instruction::CallCryptoDataDecrypt |
+ &Instruction::CallEd25519Sign |
+ &Instruction::CallEd25519Verify |
+ &Instruction::CallEd25519NewKeyPair |
+ &Instruction::CallEd25519KeyPairPublicKey => {
+ let (name, arity) = self.to_name_and_arity();
+ functor!(atom!("call"), [atom(name), fixnum(arity)])
+ }
+ //
&Instruction::ExecuteAtomChars |
&Instruction::ExecuteAtomCodes |
&Instruction::ExecuteAtomLength |
@@ -1917,7 +1942,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::ExecuteMakeDirectoryPath |
&Instruction::ExecuteDeleteFile |
&Instruction::ExecuteRenameFile |
- &Instruction::ExecuteFileCopy |
+ &Instruction::ExecuteFileCopy |
&Instruction::ExecuteWorkingDirectory |
&Instruction::ExecuteDeleteDirectory |
&Instruction::ExecutePathCanonical |
@@ -2011,9 +2036,9 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::ExecuteHttpListen |
&Instruction::ExecuteHttpAccept |
&Instruction::ExecuteHttpAnswer |
- &Instruction::ExecuteLoadForeignLib |
- &Instruction::ExecuteForeignCall |
- &Instruction::ExecuteDefineForeignStruct |
+ &Instruction::ExecuteLoadForeignLib |
+ &Instruction::ExecuteForeignCall |
+ &Instruction::ExecuteDefineForeignStruct |
&Instruction::ExecutePredicateDefined |
&Instruction::ExecuteStripModule |
&Instruction::ExecuteCurrentTime |
@@ -2056,13 +2081,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::ExecuteCryptoDataHash |
&Instruction::ExecuteCryptoDataHKDF |
&Instruction::ExecuteCryptoPasswordHash |
- &Instruction::ExecuteCryptoDataEncrypt |
- &Instruction::ExecuteCryptoDataDecrypt |
&Instruction::ExecuteCryptoCurveScalarMult |
- &Instruction::ExecuteEd25519Sign |
- &Instruction::ExecuteEd25519Verify |
- &Instruction::ExecuteEd25519NewKeyPair |
- &Instruction::ExecuteEd25519KeyPairPublicKey |
&Instruction::ExecuteCurve25519ScalarMult |
&Instruction::ExecuteFirstNonOctet |
&Instruction::ExecuteLoadHTML |
@@ -2119,6 +2138,17 @@ fn generate_instruction_preface() -> TokenStream {
functor!(atom!("execute"), [atom(name), fixnum(arity)])
}
//
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteCryptoDataEncrypt |
+ &Instruction::ExecuteCryptoDataDecrypt |
+ &Instruction::ExecuteEd25519Sign |
+ &Instruction::ExecuteEd25519Verify |
+ &Instruction::ExecuteEd25519NewKeyPair |
+ &Instruction::ExecuteEd25519KeyPairPublicKey => {
+ let (name, arity) = self.to_name_and_arity();
+ functor!(atom!("execute"), [atom(name), fixnum(arity)])
+ }
+ //
&Instruction::Deallocate => {
functor!(atom!("deallocate"))
}
@@ -2290,7 +2320,8 @@ pub fn generate_instructions_rs() -> TokenStream {
instr_data.generate_instruction_enum_loop(input);
- let instr_variants: Vec<_> = instr_data.instr_variants
+ let instr_variants: Vec<_> = instr_data
+ .instr_variants
.iter()
.cloned()
.map(|(_, _, _, variant)| variant)
@@ -2329,7 +2360,8 @@ pub fn generate_instructions_rs() -> TokenStream {
for (name, arity, variant) in instr_data.compare_number_variants {
let ident = variant.ident.clone();
- let variant_fields: Vec<_> = variant.fields
+ let variant_fields: Vec<_> = variant
+ .fields
.into_iter()
.map(|field| {
let ty = field.ty;
@@ -2368,29 +2400,23 @@ pub fn generate_instructions_rs() -> TokenStream {
let ident = variant.ident;
let instr_ident = format_ident!("Call{}", ident);
- let placeholder_ids: Vec<_> = (0 .. variant_fields.len())
+ let placeholder_ids: Vec<_> = (0..variant_fields.len())
.map(|n| format_ident!("f_{}", n))
.collect();
- clause_type_to_instr_arms.push(
- quote! {
- ClauseType::Inlined(
- InlinedClauseType::CompareNumber(CompareNumber::#ident(#(#placeholder_ids),*))
- ) => Instruction::#instr_ident(#(*#placeholder_ids),*)
- }
- );
+ clause_type_to_instr_arms.push(quote! {
+ ClauseType::Inlined(
+ InlinedClauseType::CompareNumber(CompareNumber::#ident(#(#placeholder_ids),*))
+ ) => Instruction::#instr_ident(#(*#placeholder_ids),*)
+ });
- is_inbuilt_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inbuilt_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
- is_inlined_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inlined_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
}
for (name, arity, variant) in instr_data.compare_term_variants {
@@ -2402,36 +2428,31 @@ pub fn generate_instructions_rs() -> TokenStream {
)
});
- clause_type_name_arms.push(
- quote! {
- ClauseType::BuiltIn(
- BuiltInClauseType::CompareTerm(CompareTerm::#ident)
- ) => atom!(#name)
- }
- );
+ clause_type_name_arms.push(quote! {
+ ClauseType::BuiltIn(
+ BuiltInClauseType::CompareTerm(CompareTerm::#ident)
+ ) => atom!(#name)
+ });
let ident = variant.ident;
let instr_ident = format_ident!("Call{}", ident);
- clause_type_to_instr_arms.push(
- quote! {
- ClauseType::BuiltIn(
- BuiltInClauseType::CompareTerm(CompareTerm::#ident)
- ) => Instruction::#instr_ident
- }
- );
+ clause_type_to_instr_arms.push(quote! {
+ ClauseType::BuiltIn(
+ BuiltInClauseType::CompareTerm(CompareTerm::#ident)
+ ) => Instruction::#instr_ident
+ });
- is_inbuilt_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inbuilt_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
}
for (name, arity, variant) in instr_data.builtin_type_variants {
let ident = variant.ident.clone();
- let variant_fields: Vec<_> = variant.fields
+ let variant_fields: Vec<_> = variant
+ .fields
.into_iter()
.map(|field| {
let ty = field.ty;
@@ -2470,7 +2491,7 @@ pub fn generate_instructions_rs() -> TokenStream {
let ident = variant.ident;
let instr_ident = format_ident!("Call{}", ident);
- let placeholder_ids: Vec<_> = (0 .. variant_fields.len())
+ let placeholder_ids: Vec<_> = (0..variant_fields.len())
.map(|n| format_ident!("f_{}", n))
.collect();
@@ -2488,17 +2509,16 @@ pub fn generate_instructions_rs() -> TokenStream {
}
});
- is_inbuilt_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inbuilt_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
}
for (name, arity, variant) in instr_data.inlined_type_variants {
let ident = variant.ident.clone();
- let variant_fields: Vec<_> = variant.fields
+ let variant_fields: Vec<_> = variant
+ .fields
.into_iter()
.map(|field| {
if field.ty.type_id() == TypeId::of::() {
@@ -2541,35 +2561,30 @@ pub fn generate_instructions_rs() -> TokenStream {
let ident = variant.ident;
let instr_ident = format_ident!("Call{}", ident);
- let placeholder_ids: Vec<_> = (0 .. variant_fields.len())
+ let placeholder_ids: Vec<_> = (0..variant_fields.len())
.map(|n| format_ident!("f_{}", n))
.collect();
- clause_type_to_instr_arms.push(
- quote! {
- ClauseType::Inlined(
- InlinedClauseType::#ident(#(#placeholder_ids),*)
- ) => Instruction::#instr_ident(*#(#placeholder_ids),*)
- }
- );
+ clause_type_to_instr_arms.push(quote! {
+ ClauseType::Inlined(
+ InlinedClauseType::#ident(#(#placeholder_ids),*)
+ ) => Instruction::#instr_ident(*#(#placeholder_ids),*)
+ });
- is_inbuilt_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inbuilt_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
- is_inlined_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inlined_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
}
for (name, arity, variant) in instr_data.system_clause_type_variants {
let ident = variant.ident.clone();
- let variant_fields: Vec<_> = variant.fields
+ let variant_fields: Vec<_> = variant
+ .fields
.into_iter()
.map(|field| {
if field.ty == parse_quote! { usize } {
@@ -2637,7 +2652,7 @@ pub fn generate_instructions_rs() -> TokenStream {
ident.clone()
};
- let placeholder_ids: Vec<_> = (0 .. variant_fields.len())
+ let placeholder_ids: Vec<_> = (0..variant_fields.len())
.map(|n| format_ident!("f_{}", n))
.collect();
@@ -2655,23 +2670,22 @@ pub fn generate_instructions_rs() -> TokenStream {
}
});
- is_inbuilt_arms.push(
- if let Arity::Ident("arity") = &arity {
- quote! {
- (atom!(#name), _arity) => true
- }
- } else {
- quote! {
- (atom!(#name), #arity) => true
- }
+ is_inbuilt_arms.push(if let Arity::Ident("arity") = &arity {
+ quote! {
+ (atom!(#name), _arity) => true
}
- );
+ } else {
+ quote! {
+ (atom!(#name), #arity) => true
+ }
+ });
}
for (name, arity, variant) in instr_data.repl_code_ptr_variants {
let ident = variant.ident.clone();
- let variant_fields: Vec<_> = variant.fields
+ let variant_fields: Vec<_> = variant
+ .fields
.into_iter()
.map(|field| {
if field.ty.type_id() == TypeId::of::() {
@@ -2714,7 +2728,7 @@ pub fn generate_instructions_rs() -> TokenStream {
let ident = variant.ident;
let instr_ident = format_ident!("Call{}", ident);
- let placeholder_ids: Vec<_> = (0 .. variant_fields.len())
+ let placeholder_ids: Vec<_> = (0..variant_fields.len())
.map(|n| format_ident!("f_{}", n))
.collect();
@@ -2732,11 +2746,9 @@ pub fn generate_instructions_rs() -> TokenStream {
}
});
- is_inbuilt_arms.push(
- quote! {
- (atom!(#name), #arity) => true
- }
- );
+ is_inbuilt_arms.push(quote! {
+ (atom!(#name), #arity) => true
+ });
}
for (name, arity, variant) in instr_data.clause_type_variants {
@@ -2758,7 +2770,8 @@ pub fn generate_instructions_rs() -> TokenStream {
continue;
}
- let variant_fields: Vec<_> = variant.fields
+ let variant_fields: Vec<_> = variant
+ .fields
.into_iter()
.map(|field| {
if field.ty == parse_quote! { usize } {
@@ -2792,7 +2805,7 @@ pub fn generate_instructions_rs() -> TokenStream {
let ident = variant.ident;
- let placeholder_ids: Vec<_> = (0 .. variant_fields.len())
+ let placeholder_ids: Vec<_> = (0..variant_fields.len())
.map(|n| format_ident!("f_{}", n))
.collect();
@@ -2807,14 +2820,13 @@ pub fn generate_instructions_rs() -> TokenStream {
}
});
- is_inbuilt_arms.push(
- quote! {
- (atom!(#name), _arity) => true
- }
- );
+ is_inbuilt_arms.push(quote! {
+ (atom!(#name), _arity) => true
+ });
}
- let to_execute_arms: Vec<_> = instr_data.instr_variants
+ let to_execute_arms: Vec<_> = instr_data
+ .instr_variants
.iter()
.cloned()
.filter_map(|(_, _, _, variant)| {
@@ -2827,12 +2839,11 @@ pub fn generate_instructions_rs() -> TokenStream {
0
};
- let placeholder_ids: Vec<_> = (0 .. enum_arity)
- .map(|n| format_ident!("f_{}", n))
- .collect();
+ let placeholder_ids: Vec<_> =
+ (0..enum_arity).map(|n| format_ident!("f_{}", n)).collect();
if variant_string.starts_with("Call") {
- let execute_ident = format_ident!("Execute{}", variant_string["Call".len() ..]);
+ let execute_ident = format_ident!("Execute{}", variant_string["Call".len()..]);
Some(if enum_arity == 0 {
quote! {
@@ -2847,7 +2858,7 @@ pub fn generate_instructions_rs() -> TokenStream {
})
} else if variant_string.starts_with("DefaultCall") {
let execute_ident =
- format_ident!("DefaultExecute{}", variant_string["DefaultCall".len() ..]);
+ format_ident!("DefaultExecute{}", variant_string["DefaultCall".len()..]);
Some(if enum_arity == 0 {
quote! {
@@ -2866,7 +2877,8 @@ pub fn generate_instructions_rs() -> TokenStream {
})
.collect();
- let is_execute_arms: Vec<_> = instr_data.instr_variants
+ let is_execute_arms: Vec<_> = instr_data
+ .instr_variants
.iter()
.cloned()
.filter_map(|(_, _, _, variant)| {
@@ -2909,7 +2921,8 @@ pub fn generate_instructions_rs() -> TokenStream {
})
.collect();
- let to_default_arms: Vec<_> = instr_data.instr_variants
+ let to_default_arms: Vec<_> = instr_data
+ .instr_variants
.iter()
.cloned()
.filter_map(|(_, _, countable_inference, variant)| {
@@ -2926,9 +2939,8 @@ pub fn generate_instructions_rs() -> TokenStream {
0
};
- let placeholder_ids: Vec<_> = (0 .. enum_arity)
- .map(|n| format_ident!("f_{}", n))
- .collect();
+ let placeholder_ids: Vec<_> =
+ (0..enum_arity).map(|n| format_ident!("f_{}", n)).collect();
Some(if enum_arity == 0 {
quote! {
@@ -2947,7 +2959,8 @@ pub fn generate_instructions_rs() -> TokenStream {
})
.collect();
- let control_flow_arms: Vec<_> = instr_data.instr_variants
+ let control_flow_arms: Vec<_> = instr_data
+ .instr_variants
.iter()
.cloned()
.filter_map(|(_, _, _, variant)| {
@@ -2975,7 +2988,8 @@ pub fn generate_instructions_rs() -> TokenStream {
})
.collect();
- let instr_macro_arms: Vec<_> = instr_data.instr_variants
+ let instr_macro_arms: Vec<_> = instr_data
+ .instr_variants
.iter()
.rev() // produce default, execute & default & execute cases first.
.cloned()
@@ -2984,7 +2998,7 @@ pub fn generate_instructions_rs() -> TokenStream {
let variant_string = variant.ident.to_string();
let arity = match arity {
Arity::Static(arity) => arity,
- _ => 1
+ _ => 1,
};
Some(if variant_string.starts_with("Execute") {
@@ -3061,9 +3075,10 @@ pub fn generate_instructions_rs() -> TokenStream {
})
.collect();
- let name_and_arity_arms: Vec<_> = instr_data.instr_variants
+ let name_and_arity_arms: Vec<_> = instr_data
+ .instr_variants
.into_iter()
- .map(|(name,arity,_,variant)| {
+ .map(|(name, arity, _, variant)| {
let ident = &variant.ident;
let enum_arity = if let Fields::Unnamed(fields) = &variant.fields {
@@ -3293,8 +3308,10 @@ pub fn generate_instructions_rs() -> TokenStream {
fn is_callable(id: &Ident) -> bool {
let id = id.to_string();
- id.starts_with("Call") || id.starts_with("Execute") || id.starts_with("DefaultCall") ||
- id.starts_with("DefaultExecute")
+ id.starts_with("Call")
+ || id.starts_with("Execute")
+ || id.starts_with("DefaultCall")
+ || id.starts_with("DefaultExecute")
}
fn is_non_default_callable(id: &Ident) -> bool {
@@ -3315,7 +3332,8 @@ fn create_instr_variant(id: Ident, mut variant: Variant) -> Variant {
}
fn prop_from_ident(id: &Ident, key: &'static str) -> &'static str
- where DiscriminantT: FromStr + strum::EnumProperty + std::fmt::Debug
+where
+ DiscriminantT: FromStr + strum::EnumProperty + std::fmt::Debug,
{
let disc = match DiscriminantT::from_str(id.to_string().as_str()) {
Ok(disc) => disc,
@@ -3335,7 +3353,7 @@ fn prop_from_ident(id: &Ident, key: &'static str) -> &'static str
#[derive(Clone, Copy)]
enum Arity {
Static(usize),
- Ident(&'static str)
+ Ident(&'static str),
}
impl From<&'static str> for Arity {
@@ -3427,9 +3445,13 @@ impl InstructionData {
(name, arity, CountableInference::NotCounted)
} else if id == "InstructionTemplate" {
- ( prop_from_ident::(&variant.ident, "Name"),
- Arity::from(prop_from_ident::(&variant.ident, "Arity")),
- CountableInference::NotCounted
+ (
+ prop_from_ident::(&variant.ident, "Name"),
+ Arity::from(prop_from_ident::(
+ &variant.ident,
+ "Arity",
+ )),
+ CountableInference::NotCounted,
)
} else if id == "ClauseType" {
let (name, arity) = add_discriminant_data::(
@@ -3446,19 +3468,16 @@ impl InstructionData {
let v_string = variant.ident.to_string();
let v_ident = if v_string.starts_with("Call") {
- format_ident!("{}", v_string["Call".len() ..])
+ format_ident!("{}", v_string["Call".len()..])
} else {
variant.ident.clone()
};
- let generated_variant = create_instr_variant(
- format_ident!("{}{}", prefix, v_ident),
- variant.clone(),
- );
+ let generated_variant =
+ create_instr_variant(format_ident!("{}{}", prefix, v_ident), variant.clone());
- self.instr_variants.push(
- (name, arity, countable_inference, generated_variant)
- );
+ self.instr_variants
+ .push((name, arity, countable_inference, generated_variant));
}
fn generate_instruction_enum_loop(&mut self, input: syn::DeriveInput) {
@@ -3480,10 +3499,10 @@ impl InstructionData {
self.label_variant(&input.ident, "Call", variant.clone());
self.label_variant(&input.ident, "Execute", variant.clone());
- if input.ident == "BuiltInClauseType" ||
- input.ident == "CompareNumber" ||
- input.ident == "CompareTerm" ||
- input.ident == "ClauseType"
+ if input.ident == "BuiltInClauseType"
+ || input.ident == "CompareNumber"
+ || input.ident == "CompareTerm"
+ || input.ident == "ClauseType"
{
self.label_variant(&input.ident, "DefaultCall", variant.clone());
self.label_variant(&input.ident, "DefaultExecute", variant);
diff --git a/build/static_string_indexing.rs b/build/static_string_indexing.rs
index 15f0441f..43bd813e 100644
--- a/build/static_string_indexing.rs
+++ b/build/static_string_indexing.rs
@@ -1,7 +1,7 @@
use proc_macro2::TokenStream;
-use syn::*;
use syn::parse::*;
use syn::visit::*;
+use syn::*;
use indexmap::IndexSet;
@@ -11,7 +11,9 @@ struct StaticStrVisitor {
impl StaticStrVisitor {
fn new() -> Self {
- Self { static_strs: IndexSet::new() }
+ Self {
+ static_strs: IndexSet::new(),
+ }
}
}
diff --git a/flamegraph.svg b/flamegraph.svg
new file mode 100644
index 00000000..99729113
--- /dev/null
+++ b/flamegraph.svg
@@ -0,0 +1,491 @@
+
\ No newline at end of file
diff --git a/src/arena.rs b/src/arena.rs
index 9434b28d..20763b8c 100644
--- a/src/arena.rs
+++ b/src/arena.rs
@@ -4,12 +4,16 @@ use crate::machine::loader::LiveLoadState;
use crate::machine::machine_indices::*;
use crate::machine::streams::*;
use crate::raw_block::*;
+use crate::rcu::Rcu;
+use crate::rcu::RcuRef;
use crate::read::*;
-use ordered_float::OrderedFloat;
use crate::parser::dashu::{Integer, Rational};
+use ordered_float::OrderedFloat;
+use tokio::sync::RwLock;
use std::alloc;
+use std::cell::UnsafeCell;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
@@ -22,7 +26,9 @@ macro_rules! arena_alloc {
($e:expr, $arena:expr) => {{
let result = $e;
#[allow(unused_unsafe)]
- unsafe { ArenaAllocated::alloc($arena, result) }
+ unsafe {
+ ArenaAllocated::alloc($arena, result)
+ }
}};
}
@@ -31,24 +37,36 @@ macro_rules! float_alloc {
($e:expr, $arena:expr) => {{
let result = $e;
#[allow(unused_unsafe)]
- unsafe { $arena.f64_tbl.build_with(result) }
+ unsafe {
+ $arena.f64_tbl.build_with(result).as_ptr()
+ }
}};
}
-#[cfg(test)]
-use std::cell::RefCell;
+use std::sync::Arc;
+use std::sync::Mutex;
+use std::sync::Weak;
const F64_TABLE_INIT_SIZE: usize = 1 << 16;
const F64_TABLE_ALIGN: usize = 8;
-#[cfg(test)]
-thread_local! {
- static F64_TABLE_BUF_BASE: RefCell<*const u8> = RefCell::new(ptr::null_mut());
+#[inline(always)]
+fn global_f64table() -> &'static RwLock> {
+ #[cfg(feature = "rust_beta_channel")]
+ {
+ // const Weak::new will be stabilized in 1.73 which is currently in beta,
+ // till then we need a OnceLock for initialization
+ static GLOBAL_ATOM_TABLE: RwLock> = RwLock::const_new(Weak::new());
+ &GLOBAL_ATOM_TABLE
+ }
+ #[cfg(not(feature = "rust_beta_channel"))]
+ {
+ use std::sync::OnceLock;
+ static GLOBAL_ATOM_TABLE: OnceLock>> = OnceLock::new();
+ GLOBAL_ATOM_TABLE.get_or_init(|| RwLock::new(Weak::new()))
+ }
}
-#[cfg(not(test))]
-static mut F64_TABLE_BUF_BASE: *const u8 = ptr::null_mut();
-
impl RawBlockTraits for F64Table {
#[inline]
fn init_size() -> usize {
@@ -63,69 +81,86 @@ impl RawBlockTraits for F64Table {
#[derive(Debug)]
pub struct F64Table {
- block: RawBlock,
-}
-
-impl Drop for F64Table {
- fn drop(&mut self) {
- self.block.deallocate();
- }
-}
-
-#[cfg(test)]
-fn set_f64_tbl_buf_base(ptr: *const u8) {
- F64_TABLE_BUF_BASE.with(|f64_table_buf_base| {
- *f64_table_buf_base.borrow_mut() = ptr;
- });
-}
-
-#[cfg(test)]
-pub(crate) fn get_f64_tbl_buf_base() -> *const u8 {
- F64_TABLE_BUF_BASE.with(|f64_table_buf_base| *f64_table_buf_base.borrow())
-}
-
-#[cfg(not(test))]
-fn set_f64_tbl_buf_base(ptr: *const u8) {
- unsafe {
- F64_TABLE_BUF_BASE = ptr;
- }
-}
-
-#[cfg(not(test))]
-pub(crate) fn get_f64_tbl_buf_base() -> *const u8 {
- unsafe { F64_TABLE_BUF_BASE }
+ block: Rcu>,
+ update: Mutex<()>,
}
#[inline(always)]
-pub fn lookup_float(offset: usize) -> *mut OrderedFloat {
- let base = get_f64_tbl_buf_base() as usize;
- (base + offset) as *mut _
+pub fn lookup_float(
+ offset: F64Offset,
+) -> RcuRef, UnsafeCell>> {
+ let f64table = global_f64table()
+ .blocking_read()
+ .upgrade()
+ .expect("We should only be looking up floats while there is a float table");
+
+ RcuRef::try_map(f64table.block.active_epoch(), |raw_block| unsafe {
+ raw_block
+ .base
+ .offset(offset.0 as isize)
+ .cast_mut()
+ .cast::>>()
+ .as_ref()
+ })
+ .expect("The offset should result in a non-null pointer")
}
impl F64Table {
#[inline]
- pub fn new() -> Self {
- let table = Self { block: RawBlock::new() };
- set_f64_tbl_buf_base(table.block.base);
- table
+ pub fn new() -> Arc {
+ let upgraded = global_f64table().blocking_read().upgrade();
+ // don't inline upgraded, otherwise temporary will be dropped too late in case of None
+ if let Some(atom_table) = upgraded {
+ atom_table
+ } else {
+ let mut guard = global_f64table().blocking_write();
+ // try to upgrade again in case we lost the race on the write lock
+ if let Some(atom_table) = guard.upgrade() {
+ atom_table
+ } else {
+ let atom_table = Arc::new(Self {
+ block: Rcu::new(RawBlock::new()),
+ update: Mutex::new(()),
+ });
+ *guard = Arc::downgrade(&atom_table);
+ atom_table
+ }
+ }
}
- pub unsafe fn build_with(&mut self, value: f64) -> F64Ptr {
+ pub unsafe fn build_with(&self, value: f64) -> F64Offset {
+ let update_guard = self.update.lock();
+
+ // we don't have an index table for lookups as AtomTable does so
+ // just get the epoch after we take the upgrade lock
+ let mut block_epoch = self.block.active_epoch();
+
let mut ptr;
loop {
- ptr = self.block.alloc(mem::size_of::());
+ ptr = block_epoch.alloc(mem::size_of::());
if ptr.is_null() {
- self.block.grow();
- set_f64_tbl_buf_base(self.block.base);
+ let new_block = block_epoch.grow_new().unwrap();
+ self.block.replace(new_block);
+ block_epoch = self.block.active_epoch();
} else {
break;
}
}
ptr::write(ptr as *mut OrderedFloat, OrderedFloat(value));
- F64Ptr(ptr::NonNull::new_unchecked(ptr as *mut _))
+
+ let float = F64Offset {
+ 0: ptr as usize - block_epoch.base as usize,
+ };
+
+ // atometable would have to update the index table at this point
+
+ // expicit drop to ensure we don't accidentally drop it early
+ drop(update_guard);
+
+ float
}
}
@@ -134,14 +169,13 @@ impl F64Table {
pub enum ArenaHeaderTag {
Integer = 0b10,
Rational = 0b11,
- OssifiedOpDir = 0b0000100,
LiveLoadState = 0b0001000,
InactiveLoadState = 0b1011000,
InputFileStream = 0b10000,
OutputFileStream = 0b10100,
NamedTcpStream = 0b011100,
NamedTlsStream = 0b100000,
- HttpReadStream = 0b100001,
+ HttpReadStream = 0b100001,
HttpWriteStream = 0b100010,
ReadlineStream = 0b110000,
StaticStringStream = 0b110100,
@@ -276,7 +310,9 @@ impl TypedArenaPtr {
#[inline]
pub fn set_tag(&mut self, tag: ArenaHeaderTag) {
- unsafe { (*self.header_ptr_mut()).set_tag(tag); }
+ unsafe {
+ (*self.header_ptr_mut()).set_tag(tag);
+ }
}
#[inline]
@@ -313,10 +349,10 @@ pub trait ArenaAllocated: Sized {
unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
let size = value.size() + mem::size_of::();
- #[cfg(target_pointer_width="32")]
+ #[cfg(target_pointer_width = "32")]
let align = mem::align_of::() * 2;
- #[cfg(target_pointer_width="64")]
+ #[cfg(target_pointer_width = "64")]
let align = mem::align_of::();
let layout = alloc::Layout::from_size_align_unchecked(size, align);
@@ -334,12 +370,18 @@ pub trait ArenaAllocated: Sized {
}
}
-#[derive(Copy, Clone, Debug)]
-pub struct F64Ptr(pub ptr::NonNull>);
+#[derive(Debug)]
+pub struct F64Ptr(RcuRef, UnsafeCell>>);
+
+impl Clone for F64Ptr {
+ fn clone(&self) -> Self {
+ Self(RcuRef::clone(&self.0))
+ }
+}
impl PartialEq for F64Ptr {
fn eq(&self, other: &F64Ptr) -> bool {
- self.0 == other.0 || &**self == &**other
+ RcuRef::ptr_eq(&self.0, &other.0) || self.deref() == other.deref()
}
}
@@ -375,28 +417,26 @@ impl Deref for F64Ptr {
#[inline]
fn deref(&self) -> &Self::Target {
- unsafe { &*self.0.as_ptr() }
+ unsafe { &*self.0.get().as_ref().unwrap() }
}
}
impl DerefMut for F64Ptr {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
- unsafe { &mut *self.0.as_ptr() }
+ unsafe { &mut *self.0.get().as_mut().unwrap() }
}
}
impl F64Ptr {
#[inline(always)]
- pub fn from_offset(offset: usize) -> Self {
- unsafe {
- F64Ptr(ptr::NonNull::new_unchecked(lookup_float(offset)))
- }
+ pub fn from_offset(offset: F64Offset) -> Self {
+ Self(lookup_float(offset))
}
#[inline(always)]
pub fn as_offset(&self) -> F64Offset {
- F64Offset(self.0.as_ptr() as usize - get_f64_tbl_buf_base() as usize)
+ F64Offset(self.0.get() as usize - RcuRef::get_root(&self.0).base as usize)
}
}
@@ -416,7 +456,7 @@ impl F64Offset {
#[inline(always)]
pub fn as_ptr(self) -> F64Ptr {
- F64Ptr::from_offset(self.0)
+ F64Ptr::from_offset(self)
}
#[inline(always)]
@@ -505,28 +545,6 @@ impl ArenaAllocated for Rational {
}
}
-impl ArenaAllocated for OssifiedOpDir {
- type PtrToAllocated = TypedArenaPtr;
-
- #[inline]
- fn tag() -> ArenaHeaderTag {
- ArenaHeaderTag::OssifiedOpDir
- }
-
- #[inline]
- fn size(&self) -> usize {
- mem::size_of::()
- }
-
- #[inline]
- fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
- unsafe {
- ptr::write(dst, self);
- TypedArenaPtr::new(dst as *mut Self)
- }
- }
-}
-
impl ArenaAllocated for LiveLoadState {
type PtrToAllocated = TypedArenaPtr;
@@ -577,20 +595,20 @@ impl ArenaAllocated for HttpListener {
#[inline]
fn tag() -> ArenaHeaderTag {
- ArenaHeaderTag::HttpListener
+ ArenaHeaderTag::HttpListener
}
#[inline]
fn size(&self) -> usize {
- mem::size_of::()
+ mem::size_of::()
}
#[inline]
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
- unsafe {
- ptr::write(dst, self);
- TypedArenaPtr::new(dst as *mut Self)
- }
+ unsafe {
+ ptr::write(dst, self);
+ TypedArenaPtr::new(dst as *mut Self)
+ }
}
}
@@ -600,20 +618,20 @@ impl ArenaAllocated for HttpResponse {
#[inline]
fn tag() -> ArenaHeaderTag {
- ArenaHeaderTag::HttpResponse
+ ArenaHeaderTag::HttpResponse
}
#[inline]
fn size(&self) -> usize {
- mem::size_of::()
+ mem::size_of::()
}
#[inline]
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
- unsafe {
- ptr::write(dst, self);
- TypedArenaPtr::new(dst as *mut Self)
- }
+ unsafe {
+ ptr::write(dst, self);
+ TypedArenaPtr::new(dst as *mut Self)
+ }
}
}
@@ -664,7 +682,7 @@ impl ArenaAllocated for IndexPtr {
#[derive(Clone, Copy, Debug)]
struct AllocSlab {
next: *mut AllocSlab,
- #[cfg(target_pointer_width="32")]
+ #[cfg(target_pointer_width = "32")]
_padding: u32,
header: ArenaHeader,
}
@@ -672,7 +690,7 @@ struct AllocSlab {
#[derive(Debug)]
pub struct Arena {
base: *mut AllocSlab,
- pub f64_tbl: F64Table,
+ pub f64_tbl: Arc,
}
unsafe impl Send for Arena {}
@@ -681,7 +699,10 @@ unsafe impl Sync for Arena {}
impl Arena {
#[inline]
pub fn new() -> Self {
- Arena { base: ptr::null_mut(), f64_tbl: F64Table::new() }
+ Arena {
+ base: ptr::null_mut(),
+ f64_tbl: F64Table::new(),
+ }
}
}
@@ -712,10 +733,10 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
#[cfg(feature = "http")]
ptr::drop_in_place(value.payload_offset::>>());
}
- ArenaHeaderTag::HttpWriteStream => {
+ ArenaHeaderTag::HttpWriteStream => {
#[cfg(feature = "http")]
- ptr::drop_in_place(value.payload_offset::>>());
- }
+ ptr::drop_in_place(value.payload_offset::>>());
+ }
ArenaHeaderTag::ReadlineStream => {
ptr::drop_in_place(value.payload_offset::>());
}
@@ -725,35 +746,32 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
ArenaHeaderTag::ByteStream => {
ptr::drop_in_place(value.payload_offset::>>());
}
- ArenaHeaderTag::OssifiedOpDir => {
- ptr::drop_in_place(value.payload_offset::());
- }
ArenaHeaderTag::LiveLoadState | ArenaHeaderTag::InactiveLoadState => {
ptr::drop_in_place(value.payload_offset::());
}
- ArenaHeaderTag::Dropped => {
- }
+ ArenaHeaderTag::Dropped => {}
ArenaHeaderTag::TcpListener => {
ptr::drop_in_place(value.payload_offset::());
}
- ArenaHeaderTag::HttpListener => {
+ ArenaHeaderTag::HttpListener => {
#[cfg(feature = "http")]
- ptr::drop_in_place(value.payload_offset::());
- }
- ArenaHeaderTag::HttpResponse => {
+ ptr::drop_in_place(value.payload_offset::());
+ }
+ ArenaHeaderTag::HttpResponse => {
#[cfg(feature = "http")]
- ptr::drop_in_place(value.payload_offset::());
- }
+ ptr::drop_in_place(value.payload_offset::());
+ }
ArenaHeaderTag::StandardOutputStream => {
ptr::drop_in_place(value.payload_offset::>());
}
ArenaHeaderTag::StandardErrorStream => {
ptr::drop_in_place(value.payload_offset::>());
}
- ArenaHeaderTag::NullStream | ArenaHeaderTag::IndexPtrUndefined |
- ArenaHeaderTag::IndexPtrDynamicUndefined | ArenaHeaderTag::IndexPtrDynamicIndex |
- ArenaHeaderTag::IndexPtrIndex => {
- }
+ ArenaHeaderTag::NullStream
+ | ArenaHeaderTag::IndexPtrUndefined
+ | ArenaHeaderTag::IndexPtrDynamicUndefined
+ | ArenaHeaderTag::IndexPtrDynamicIndex
+ | ArenaHeaderTag::IndexPtrIndex => {}
}
}
@@ -801,23 +819,25 @@ const_assert!(mem::size_of::>() == 8);
#[cfg(test)]
mod tests {
+ use std::ops::Deref;
+
use crate::machine::mock_wam::*;
use crate::machine::partial_string::*;
- use ordered_float::OrderedFloat;
use crate::parser::dashu::{Integer, Rational};
+ use ordered_float::OrderedFloat;
#[test]
fn float_ptr_cast() {
- let mut wam = MockWAM::new();
+ let wam = MockWAM::new();
let f = 0f64;
let fp = float_alloc!(f, wam.machine_st.arena);
- let mut cell = HeapCellValue::from(fp);
+ let mut cell = HeapCellValue::from(fp.clone());
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
assert_eq!(cell.get_mark_bit(), false);
- assert_eq!(*fp, OrderedFloat(f));
+ assert_eq!(fp.deref(), &OrderedFloat(f));
cell.set_mark_bit(true);
@@ -834,12 +854,12 @@ mod tests {
#[test]
fn heap_cell_value_const_cast() {
let mut wam = MockWAM::new();
- #[cfg(target_pointer_width="32")]
+ #[cfg(target_pointer_width = "32")]
let const_value = HeapCellValue::from(ConsPtr::build_with(
0x0000_0431 as *const _,
ConsPtrMaskTag::Cons,
));
- #[cfg(target_pointer_width="64")]
+ #[cfg(target_pointer_width = "64")]
let const_value = HeapCellValue::from(ConsPtr::build_with(
0x0000_5555_ff00_0431 as *const _,
ConsPtrMaskTag::Cons,
@@ -847,7 +867,10 @@ mod tests {
match const_value.to_untyped_arena_ptr() {
Some(arena_ptr) => {
- assert_eq!(arena_ptr.into_bytes(), const_value.to_untyped_arena_ptr_bytes());
+ assert_eq!(
+ arena_ptr.into_bytes(),
+ const_value.to_untyped_arena_ptr_bytes()
+ );
}
None => {
assert!(false);
@@ -860,7 +883,10 @@ mod tests {
match stream_cell.to_untyped_arena_ptr() {
Some(arena_ptr) => {
- assert_eq!(arena_ptr.into_bytes(), stream_cell.to_untyped_arena_ptr_bytes());
+ assert_eq!(
+ arena_ptr.into_bytes(),
+ stream_cell.to_untyped_arena_ptr_bytes()
+ );
}
None => {
assert!(false);
@@ -875,8 +901,7 @@ mod tests {
// integer
let big_int: Integer = 2 * Integer::from(1u64 << 63);
- let big_int_ptr: TypedArenaPtr =
- arena_alloc!(big_int, &mut wam.machine_st.arena);
+ let big_int_ptr: TypedArenaPtr = arena_alloc!(big_int, &mut wam.machine_st.arena);
assert!(!big_int_ptr.as_ptr().is_null());
@@ -951,8 +976,8 @@ mod tests {
let f_atom = atom!("f");
let g_atom = atom!("g");
- assert_eq!(f_atom.as_str(), "f");
- assert_eq!(g_atom.as_str(), "g");
+ assert_eq!(&*f_atom.as_str(), "f");
+ assert_eq!(&*g_atom.as_str(), "g");
let f_atom_cell = atom_as_cell!(f_atom);
let g_atom_cell = atom_as_cell!(g_atom);
@@ -962,7 +987,7 @@ mod tests {
match f_atom_cell.to_atom() {
Some(atom) => {
assert_eq!(f_atom, atom);
- assert_eq!(atom.as_str(), "f");
+ assert_eq!(&*atom.as_str(), "f");
}
None => {
assert!(false);
@@ -973,7 +998,7 @@ mod tests {
(HeapCellValueTag::Atom, (atom, arity)) => {
assert_eq!(f_atom, atom);
assert_eq!(arity, 0);
- assert_eq!(atom.as_str(), "f");
+ assert_eq!(&*atom.as_str(), "f");
}
_ => { unreachable!() }
);
@@ -982,21 +1007,22 @@ mod tests {
(HeapCellValueTag::Atom, (atom, arity)) => {
assert_eq!(g_atom, atom);
assert_eq!(arity, 0);
- assert_eq!(atom.as_str(), "g");
+ assert_eq!(&*atom.as_str(), "g");
}
_ => { unreachable!() }
);
// complete string
- let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "ronan", &mut wam.machine_st.atom_tbl);
+ let pstr_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "ronan", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
assert_eq!(pstr_cell.get_tag(), HeapCellValueTag::PStr);
match pstr_cell.to_pstr() {
Some(pstr) => {
- assert_eq!(pstr.as_str_from(0), "ronan");
+ assert_eq!(&*pstr.as_str_from(0), "ronan");
}
None => {
assert!(false);
@@ -1006,7 +1032,7 @@ mod tests {
read_heap_cell!(pstr_cell,
(HeapCellValueTag::PStr, pstr_atom) => {
let pstr = PartialString::from(pstr_atom);
- assert_eq!(pstr.as_str_from(0), "ronan");
+ assert_eq!(&*pstr.as_str_from(0), "ronan");
}
_ => { unreachable!() }
);
@@ -1115,7 +1141,7 @@ mod tests {
read_heap_cell!(cell,
(HeapCellValueTag::Atom, (el, _arity)) => {
assert_eq!(el.flat_index(), empty_list_as_cell!().get_value());
- assert_eq!(el.as_str(), "[]");
+ assert_eq!(&*el.as_str(), "[]");
}
_ => { unreachable!() }
);
diff --git a/src/arithmetic.rs b/src/arithmetic.rs
index ded84906..95b4fe2c 100644
--- a/src/arithmetic.rs
+++ b/src/arithmetic.rs
@@ -14,6 +14,8 @@ use crate::parser::dashu::{Integer, Rational};
use crate::machine::machine_errors::*;
use dashu::base::Abs;
+use dashu::base::BitTest;
+use num_order::NumOrd;
use ordered_float::*;
use std::cell::Cell;
@@ -158,13 +160,13 @@ fn push_literal(interm: &mut Vec, c: &Literal) -> Result<(), Ari
Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(*n.as_ptr()))),
Literal::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number(
- Number::Float(OrderedFloat(std::f64::consts::E))
+ Number::Float(OrderedFloat(std::f64::consts::E)),
)),
Literal::Atom(name) if name == &atom!("pi") => interm.push(ArithmeticTerm::Number(
- Number::Float(OrderedFloat(std::f64::consts::PI))
+ Number::Float(OrderedFloat(std::f64::consts::PI)),
)),
Literal::Atom(name) if name == &atom!("epsilon") => interm.push(ArithmeticTerm::Number(
- Number::Float(OrderedFloat(std::f64::EPSILON))
+ Number::Float(OrderedFloat(std::f64::EPSILON)),
)),
_ => return Err(ArithmeticError::NonEvaluableFunctor(*c, 0)),
}
@@ -326,23 +328,14 @@ impl<'a> ArithmeticEvaluator<'a> {
let var_num = name.to_var_num().unwrap();
let r = if lvl == Level::Shallow {
- self.marker.mark_non_callable(
- var_num,
- arg,
- term_loc,
- cell,
- &mut code,
- )
+ self.marker
+ .mark_non_callable(var_num, arg, term_loc, cell, &mut code)
} else if term_loc.is_last() || cell.get().norm().reg_num() == 0 {
let r = self.marker.get_binding(var_num);
if r.reg_num() == 0 {
self.marker.mark_var::(
- var_num,
- lvl,
- cell,
- term_loc,
- &mut code,
+ var_num, lvl, cell, term_loc, &mut code,
);
cell.get().norm()
} else {
@@ -370,8 +363,9 @@ impl<'a> ArithmeticEvaluator<'a> {
pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
match n {
&Number::Integer(i) => {
- if let Some(n) = i.to_i64() {
- fixnum!(Number, n, arena)
+ let result = (&*i).try_into();
+ if let Ok(value) = result{
+ fixnum!(Number, value, arena)
} else {
*n
}
@@ -392,8 +386,9 @@ pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
&Number::Rational(ref r) => {
let (_, floor) = (r.fract(), r.floor());
- if let Some(floor) = floor.to_i64() {
- fixnum!(Number, floor, arena)
+ let result = floor.clone().try_into();
+ if let Ok(value) = result{
+ fixnum!(Number, value, arena)
} else {
Number::Integer(arena_alloc!(floor, arena))
}
@@ -434,7 +429,7 @@ fn classify_float(f: f64) -> Result {
}
}
FpCategory::Nan => Err(EvalError::Undefined),
- _ => Ok(f)
+ _ => Ok(f),
}
}
@@ -542,15 +537,19 @@ impl PartialEq for Number {
fn eq(&self, rhs: &Self) -> bool {
match (self, rhs) {
(&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.eq(&n2),
- (&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().eq(&**n2),
- (&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).eq(&n2.get_num()),
- (&Number::Fixnum(n1), &Number::Rational(ref n2)) => n1.get_num().eq(&**n2),
- (&Number::Rational(ref n1), &Number::Fixnum(n2)) => (&**n1).eq(&n2.get_num()),
+ (&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().num_eq(&**n2),
+ (&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&n2.get_num()),
+ (&Number::Fixnum(n1), &Number::Rational(ref n2)) => Integer::from(n1.get_num()).num_eq(&**n2),
+ (&Number::Rational(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&Integer::from(n2.get_num())),
(&Number::Fixnum(n1), &Number::Float(n2)) => OrderedFloat(n1.get_num() as f64).eq(&n2),
(&Number::Float(n1), &Number::Fixnum(n2)) => n1.eq(&OrderedFloat(n2.get_num() as f64)),
(&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.eq(n2),
- (&Number::Integer(ref n1), Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).eq(n2),
- (&Number::Float(n1), &Number::Integer(ref n2)) => n1.eq(&OrderedFloat(n2.to_f64().value())),
+ (&Number::Integer(ref n1), Number::Float(n2)) => {
+ OrderedFloat(n1.to_f64().value()).eq(n2)
+ }
+ (&Number::Float(n1), &Number::Integer(ref n2)) => {
+ n1.eq(&OrderedFloat(n2.to_f64().value()))
+ }
(&Number::Integer(ref n1), &Number::Rational(ref n2)) => {
#[cfg(feature = "num")]
{
@@ -558,7 +557,7 @@ impl PartialEq for Number {
}
#[cfg(not(feature = "num"))]
{
- &**n1 == &**n2
+ (&**n1).num_eq(&**n2)
}
}
(&Number::Rational(ref n1), &Number::Integer(ref n2)) => {
@@ -568,11 +567,15 @@ impl PartialEq for Number {
}
#[cfg(not(feature = "num"))]
{
- &**n1 == &**n2
+ (&**n1).num_eq(&**n2)
}
}
- (&Number::Rational(ref n1), &Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).eq(&n2),
- (&Number::Float(n1), &Number::Rational(ref n2)) => n1.eq(&OrderedFloat(n2.to_f64().value())),
+ (&Number::Rational(ref n1), &Number::Float(n2)) => {
+ OrderedFloat(n1.to_f64().value()).eq(&n2)
+ }
+ (&Number::Float(n1), &Number::Rational(ref n2)) => {
+ n1.eq(&OrderedFloat(n2.to_f64().value()))
+ }
(&Number::Float(f1), &Number::Float(f2)) => f1.eq(&f2),
(&Number::Rational(ref r1), &Number::Rational(ref r2)) => r1.eq(&r2),
}
@@ -594,8 +597,8 @@ impl PartialOrd for Number {
(n as usize).partial_cmp(rhs)
}
}
- Number::Integer(n) => (&**n).partial_cmp(rhs),
- Number::Rational(r) => (&**r).partial_cmp(rhs),
+ Number::Integer(n) => Some((&**n).num_cmp(rhs)),
+ Number::Rational(r) => Some((&**r).num_cmp(&Integer::from(*rhs))),
Number::Float(f) => f.partial_cmp(&OrderedFloat(*rhs as f64)),
}
}
@@ -614,8 +617,8 @@ impl PartialEq for Number {
(n as usize).eq(rhs)
}
}
- Number::Integer(n) => (&**n).eq(rhs),
- Number::Rational(r) => (&**r).eq(rhs),
+ Number::Integer(n) => (&**n).num_eq(rhs),
+ Number::Rational(r) => (&**r).num_eq(&Integer::from(*rhs)),
Number::Float(f) => f.eq(&OrderedFloat(*rhs as f64)),
}
}
@@ -641,7 +644,9 @@ impl Ord for Number {
(&Number::Float(n1), &Number::Fixnum(n2)) => n1.cmp(&OrderedFloat(n2.get_num() as f64)),
(&Number::Integer(n1), &Number::Integer(n2)) => (*n1).cmp(&*n2),
(&Number::Integer(n1), Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).cmp(n2),
- (&Number::Float(n1), &Number::Integer(ref n2)) => n1.cmp(&OrderedFloat(n2.to_f64().value())),
+ (&Number::Float(n1), &Number::Integer(ref n2)) => {
+ n1.cmp(&OrderedFloat(n2.to_f64().value()))
+ }
(&Number::Integer(n1), &Number::Rational(n2)) => {
#[cfg(feature = "num")]
{
@@ -649,7 +654,7 @@ impl Ord for Number {
}
#[cfg(not(feature = "num"))]
{
- (&*n1).partial_cmp(&*n2).unwrap_or(Ordering::Less)
+ (&*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
}
}
(&Number::Rational(n1), &Number::Integer(n2)) => {
@@ -659,11 +664,15 @@ impl Ord for Number {
}
#[cfg(not(feature = "num"))]
{
- (&*n1).partial_cmp(&*n2).unwrap_or(Ordering::Less)
+ (&*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
}
}
- (&Number::Rational(n1), &Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).cmp(&n2),
- (&Number::Float(n1), &Number::Rational(n2)) => n1.cmp(&OrderedFloat(n2.to_f64().value())),
+ (&Number::Rational(n1), &Number::Float(n2)) => {
+ OrderedFloat(n1.to_f64().value()).cmp(&n2)
+ }
+ (&Number::Float(n1), &Number::Rational(n2)) => {
+ n1.cmp(&OrderedFloat(n2.to_f64().value()))
+ }
(&Number::Float(f1), &Number::Float(f2)) => f1.cmp(&f2),
(&Number::Rational(r1), &Number::Rational(r2)) => (*r1).cmp(&*r2),
}
@@ -706,14 +715,14 @@ impl TryFrom for Number {
pub(crate) fn binary_pow(mut n: Integer, power: &Integer) -> Integer {
let mut power = Integer::from(power.abs());
- if power == 0 {
+ if power.num_eq(&0) {
return Integer::from(1);
}
let mut oddand = Integer::from(1);
- while power > 1 {
- if power.is_odd() {
+ while power.num_gt(&1) {
+ if power.bit(0) {
oddand *= &n;
}
diff --git a/src/atom_table.rs b/src/atom_table.rs
index 087a9e20..80ba5411 100644
--- a/src/atom_table.rs
+++ b/src/atom_table.rs
@@ -1,18 +1,23 @@
use crate::parser::ast::MAX_ARITY;
use crate::raw_block::*;
+use crate::rcu::{Rcu, RcuRef};
use crate::types::*;
-use std::borrow::Borrow;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::mem;
+use std::ops::Deref;
use std::ptr;
use std::slice;
use std::str;
+use std::sync::Arc;
+use std::sync::Mutex;
+use std::sync::Weak;
use indexmap::IndexSet;
use modular_bitfield::prelude::*;
+use tokio::sync::RwLock;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Atom {
@@ -33,65 +38,43 @@ impl<'a> From<&'a Atom> for Atom {
impl From for Atom {
#[inline]
fn from(value: bool) -> Self {
- if value { atom!("true") } else { atom!("false") }
+ if value {
+ atom!("true")
+ } else {
+ atom!("false")
+ }
+ }
+}
+
+impl indexmap::Equivalent for str {
+ fn equivalent(&self, key: &Atom) -> bool {
+ &*key.as_str() == self
}
}
const ATOM_TABLE_INIT_SIZE: usize = 1 << 16;
const ATOM_TABLE_ALIGN: usize = 8;
-#[cfg(any(test, feature = "multi_thread"))]
-thread_local! {
- static ATOM_TABLE_BUF_BASE: std::cell::RefCell<*const u8> = std::cell::RefCell::new(ptr::null_mut());
-}
-
-#[cfg(all(not(test), not(feature = "multi_thread")))]
-static ATOM_TABLE_BUF_BASE: std::sync::atomic::AtomicPtr =
- std::sync::atomic::AtomicPtr::new(ptr::null_mut());
-
-fn set_atom_tbl_buf_base(old_ptr: *const u8, new_ptr: *const u8) -> Result<(), *const u8> {
- #[cfg(any(test, feature = "multi_thread"))]
+#[inline(always)]
+fn global_atom_table() -> &'static RwLock> {
+ #[cfg(feature = "rust_beta_channel")]
{
- ATOM_TABLE_BUF_BASE.with(|atom_table_buf_base| {
- let mut borrow = atom_table_buf_base.borrow_mut();
- if *borrow != old_ptr {
- Err(*borrow)
- } else {
- *borrow = new_ptr;
- Ok(())
- }
- })?;
- };
- #[cfg(all(not(test), not(feature = "multi_thread")))]
- {
- ATOM_TABLE_BUF_BASE
- .compare_exchange(
- old_ptr.cast_mut(),
- new_ptr.cast_mut(),
- std::sync::atomic::Ordering::Relaxed,
- std::sync::atomic::Ordering::Relaxed,
- )
- .map_err(|ptr| ptr.cast_const())
- }?;
- Ok(())
-}
-
-pub(crate) fn get_atom_tbl_buf_base() -> *const u8 {
- #[cfg(any(test, feature = "multi_thread"))]
- {
- ATOM_TABLE_BUF_BASE.with(|atom_table_buf_base| *atom_table_buf_base.borrow())
+ // const Weak::new will be stabilized in 1.73 which is currently in beta,
+ // till then we need a OnceLock for initialization
+ static GLOBAL_ATOM_TABLE: RwLock> = RwLock::const_new(Weak::new());
+ &GLOBAL_ATOM_TABLE
}
- #[cfg(not(any(test, feature = "multi_thread")))]
+ #[cfg(not(feature = "rust_beta_channel"))]
{
- ATOM_TABLE_BUF_BASE.load(std::sync::atomic::Ordering::Relaxed)
+ use std::sync::OnceLock;
+ static GLOBAL_ATOM_TABLE: OnceLock>> = OnceLock::new();
+ GLOBAL_ATOM_TABLE.get_or_init(|| RwLock::new(Weak::new()))
}
}
-#[test]
-#[should_panic(expected = "Overwriting atom table base pointer")]
-fn atomtable_is_not_concurrency_safe() {
- let _table_a = AtomTable::new();
- let _table_b = AtomTable::new();
+#[inline(always)]
+fn arc_atom_table() -> Option> {
+ global_atom_table().blocking_read().upgrade()
}
impl RawBlockTraits for AtomTable {
@@ -109,9 +92,11 @@ impl RawBlockTraits for AtomTable {
#[bitfield]
#[derive(Copy, Clone, Debug)]
struct AtomHeader {
- #[allow(unused)] m: bool,
+ #[allow(unused)]
+ m: bool,
len: B50,
- #[allow(unused)] padding: B13,
+ #[allow(unused)]
+ padding: B13,
}
impl AtomHeader {
@@ -120,13 +105,6 @@ impl AtomHeader {
}
}
-impl Borrow for Atom {
- #[inline]
- fn borrow(&self) -> &str {
- self.as_str()
- }
-}
-
impl Hash for Atom {
#[inline]
fn hash(&self, hasher: &mut H) {
@@ -142,29 +120,76 @@ macro_rules! is_char {
};
}
-impl Atom {
- #[inline]
- pub fn buf(self) -> *const u8 {
- let ptr = self.as_ptr();
+pub enum AtomString<'a> {
+ Static(&'a str),
+ Dynamic(AtomTableRef),
+}
- if ptr.is_null() {
- return ptr::null();
+impl AtomString<'_> {
+ pub fn map(self, f: F) -> Self
+ where
+ for<'a> F: FnOnce(&'a str) -> &'a str,
+ {
+ match self {
+ Self::Static(reference) => Self::Static(f(reference)),
+ Self::Dynamic(guard) => Self::Dynamic(AtomTableRef::map(guard, f)),
}
+ }
+}
- (ptr as usize + mem::size_of::()) as *const u8
+impl std::fmt::Debug for AtomString<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ std::fmt::Debug::fmt(self.deref(), f)
+ }
+}
+
+impl std::fmt::Display for AtomString<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.deref(), f)
+ }
+}
+
+impl std::ops::Deref for AtomString<'_> {
+ type Target = str;
+ fn deref(&self) -> &Self::Target {
+ match self {
+ Self::Static(reference) => reference,
+ Self::Dynamic(guard) => guard.deref(),
+ }
+ }
+}
+
+#[cfg(feature = "repl")]
+impl rustyline::completion::Candidate for AtomString<'_> {
+ fn display(&self) -> &str {
+ self.deref()
}
+ fn replacement(&self) -> &str {
+ self.deref()
+ }
+}
+
+impl Atom {
#[inline(always)]
pub fn is_static(self) -> bool {
(self.index as usize) < STRINGS.len() << 3
}
#[inline(always)]
- pub fn as_ptr(self) -> *const u8 {
+ pub fn as_ptr(self) -> Option> {
if self.is_static() {
- ptr::null()
+ None
} else {
- (get_atom_tbl_buf_base() as usize + (self.index as usize) - (STRINGS.len() << 3)) as *const u8
+ let atom_table =
+ arc_atom_table().expect("We should only have an Atom while there is an AtomTable");
+ unsafe {
+ AtomTableRef::try_map(atom_table.buf(), |buf| {
+ (buf as *const u8)
+ .offset(((self.index as usize) - (STRINGS.len() << 3)) as isize)
+ .as_ref()
+ })
+ }
}
}
@@ -178,7 +203,9 @@ impl Atom {
if self.is_static() {
STRINGS[(self.index >> 3) as usize].len()
} else {
- unsafe { ptr::read(self.as_ptr() as *const AtomHeader).len() as _ }
+ let ptr = self.as_ptr().unwrap();
+ let ptr = ptr.deref() as *const u8 as *const AtomHeader;
+ unsafe { ptr::read(ptr) }.len() as _
}
}
@@ -194,41 +221,44 @@ impl Atom {
let c1 = it.next();
let c2 = it.next();
- if c2.is_none() { c1 } else { None }
- }
-
- #[inline]
- pub fn chars(&self) -> str::Chars {
- self.as_str().chars()
- }
-
- #[inline]
- pub fn as_str(&self) -> &str {
- unsafe {
- let ptr = self.as_ptr();
-
- if ptr.is_null() {
- return STRINGS[(self.index >> 3) as usize];
- }
-
- let header = ptr::read::(ptr as *const _);
- let len = header.len() as usize;
- let buf = (ptr as usize + mem::size_of::()) as *mut u8;
-
- str::from_utf8_unchecked(slice::from_raw_parts(buf, len))
+ if c2.is_none() {
+ c1
+ } else {
+ None
}
}
- pub fn defrock_brackets(&self, atom_tbl: &mut AtomTable) -> Self {
+ #[inline]
+ pub fn as_str(&self) -> AtomString<'static> {
+ if self.is_static() {
+ AtomString::Static(STRINGS[(self.index >> 3) as usize])
+ } else {
+ if let Some(ptr) = self.as_ptr() {
+ AtomString::Dynamic(AtomTableRef::map(ptr, |ptr| {
+ let header =
+ unsafe { ptr::read::(ptr as *const u8 as *const AtomHeader) };
+ let len = header.len() as usize;
+ let buf =
+ unsafe { (ptr as *const u8).offset(mem::size_of::() as isize) };
+
+ unsafe { str::from_utf8_unchecked(slice::from_raw_parts(buf, len)) }
+ }))
+ } else {
+ AtomString::Static(&STRINGS[(self.index >> 3) as usize])
+ }
+ }
+ }
+
+ pub fn defrock_brackets(&self, atom_tbl: &AtomTable) -> Self {
let s = self.as_str();
- let s = if s.starts_with('(') && s.ends_with(')') {
+ let sub_str = if s.starts_with('(') && s.ends_with(')') {
&s['('.len_utf8()..s.len() - ')'.len_utf8()]
} else {
return *self;
};
- atom_tbl.build_with(s)
+ AtomTable::build_with(&atom_tbl, &sub_str)
}
}
@@ -248,116 +278,156 @@ impl PartialOrd for Atom {
impl Ord for Atom {
#[inline]
fn cmp(&self, other: &Atom) -> Ordering {
- self.as_str().cmp(other.as_str())
+ self.as_str().cmp(&*other.as_str())
}
}
#[derive(Debug)]
-pub struct AtomTable {
+pub struct InnerAtomTable {
block: RawBlock,
- pub table: IndexSet,
+ pub table: Rcu>,
}
-#[cold]
-fn atom_table_base_pointer_mismatch(expected: *const u8, got: *const u8) -> ! {
- assert_eq!(expected, got, "Overwriting atom table base pointer, expected old value to be {expected:p}, but found {got:p}");
- unreachable!("This should only be called in a case of a mismatch as such the assert_eq should have failed!")
+#[derive(Debug)]
+pub struct AtomTable {
+ inner: Rcu,
+ // this lock is taking during resizing
+ update: Mutex<()>,
}
-impl Drop for AtomTable {
- fn drop(&mut self) {
- if let Err(got) = set_atom_tbl_buf_base(self.block.base, ptr::null()) {
- atom_table_base_pointer_mismatch(self.block.base, got);
- }
- self.block.deallocate();
+pub type AtomTableRef = RcuRef;
+
+impl InnerAtomTable {
+ #[inline(always)]
+ fn lookup_str(self: &InnerAtomTable, string: &str) -> Option {
+ STATIC_ATOMS_MAP
+ .get(string)
+ .cloned()
+ .or_else(|| self.table.active_epoch().get(string).cloned())
}
}
impl AtomTable {
#[inline]
- pub fn new() -> Self {
- let mut block = RawBlock::new();
-
- if let Err(got) = set_atom_tbl_buf_base(ptr::null(), block.base) {
- block.deallocate();
- atom_table_base_pointer_mismatch(ptr::null(), got);
- }
-
- Self {
- block,
- table: IndexSet::new(),
+ pub fn new() -> Arc {
+ let upgraded = global_atom_table().blocking_read().upgrade();
+ // don't inline upgraded, otherwise temporary will be dropped too late in case of None
+ if let Some(atom_table) = upgraded {
+ atom_table
+ } else {
+ let mut guard = global_atom_table().blocking_write();
+ // try to upgrade again in case we lost the race on the write lock
+ if let Some(atom_table) = guard.upgrade() {
+ atom_table
+ } else {
+ let atom_table = Arc::new(Self {
+ inner: Rcu::new(InnerAtomTable {
+ block: RawBlock::new(),
+ table: Rcu::new(IndexSet::new()),
+ }),
+ update: Mutex::new(()),
+ });
+ *guard = Arc::downgrade(&atom_table);
+ atom_table
+ }
}
}
#[inline]
- pub fn buf(&self) -> *const u8 {
- self.block.base as *const u8
+ pub fn buf(&self) -> AtomTableRef {
+ AtomTableRef::::map(self.inner.active_epoch(), |inner| {
+ unsafe { inner.block.base.as_ref() }.unwrap()
+ })
}
- #[inline]
- pub fn top(&self) -> *const u8 {
- self.block.top
+ pub fn active_table(&self) -> RcuRef, IndexSet> {
+ self.inner.active_epoch().table.active_epoch()
}
- #[inline(always)]
- fn lookup_str(&self, string: &str) -> Option {
- STATIC_ATOMS_MAP.get(string).or_else(|| self.table.get(string)).cloned()
- }
+ pub fn build_with(atom_table: &AtomTable, string: &str) -> Atom {
+ loop {
+ let mut block_epoch = atom_table.inner.active_epoch();
+ let mut table_epoch = block_epoch.table.active_epoch();
- pub fn build_with(&mut self, string: &str) -> Atom {
- if let Some(atom) = self.lookup_str(string) {
- return atom;
- }
+ if let Some(atom) = block_epoch.lookup_str(string) {
+ return atom;
+ }
+
+ // take a lock to prevent concurrent updates
+ let update_guard = atom_table.update.lock().unwrap();
+
+ let is_same_allocation =
+ RcuRef::same_epoch(&block_epoch, &atom_table.inner.active_epoch());
+ let is_same_atom_list =
+ RcuRef::same_epoch(&table_epoch, &block_epoch.table.active_epoch());
+
+ if !(is_same_allocation && is_same_atom_list) {
+ // some other thread raced us between our lookup and
+ // us aquring the update lock,
+ // try again
+ continue;
+ }
- unsafe {
let size = mem::size_of::() + string.len();
let align_offset = 8 * mem::align_of::();
let size = (size & !(align_offset - 1)) + align_offset;
- let len_ptr = {
- let mut ptr;
-
- loop {
- ptr = self.block.alloc(size);
+ unsafe {
+ let len_ptr = loop {
+ let ptr = block_epoch.block.alloc(size);
if ptr.is_null() {
- let old_base = self.block.base;
- self.block.grow();
- if let Err(got) = set_atom_tbl_buf_base(old_base, self.block.base) {
- atom_table_base_pointer_mismatch(old_base, got);
- }
+ // garbage collection would go here
+ let new_block = block_epoch.block.grow_new().unwrap();
+ let new_table = Rcu::new(table_epoch.clone());
+ let new_alloc = InnerAtomTable {
+ block: new_block,
+ table: new_table,
+ };
+ atom_table.inner.replace(new_alloc);
+ block_epoch = atom_table.inner.active_epoch();
+ table_epoch = block_epoch.table.active_epoch();
} else {
- break;
+ break ptr;
}
- }
+ };
- ptr
- };
+ let ptr_base = block_epoch.block.base as usize;
- let ptr_base = self.block.base as usize;
+ write_to_ptr(string, len_ptr);
- write_to_ptr(string, len_ptr);
+ let atom = Atom {
+ index: ((STRINGS.len() << 3) + len_ptr as usize - ptr_base) as u64,
+ };
- let atom = Atom {
- index: ((STRINGS.len() << 3) + len_ptr as usize - ptr_base) as u64,
- };
+ let mut table = table_epoch.clone();
+ table.insert(atom);
+ block_epoch.table.replace(table);
- self.table.insert(atom);
+ // expicit drop to ensure we don't accidentally drop it early
+ drop(update_guard);
- atom
+ return atom;
+ }
}
}
}
+unsafe impl Send for AtomTable {}
+unsafe impl Sync for AtomTable {}
+
#[bitfield]
#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub struct AtomCell {
name: B46,
arity: B10,
- #[allow(unused)] f: bool,
- #[allow(unused)] m: bool,
- #[allow(unused)] tag: B6,
+ #[allow(unused)]
+ f: bool,
+ #[allow(unused)]
+ m: bool,
+ #[allow(unused)]
+ tag: B6,
}
impl AtomCell {
diff --git a/src/bin/scryer-prolog.rs b/src/bin/scryer-prolog.rs
index 01291652..f138024b 100644
--- a/src/bin/scryer-prolog.rs
+++ b/src/bin/scryer-prolog.rs
@@ -1,12 +1,13 @@
fn main() -> std::process::ExitCode {
- use std::sync::atomic::Ordering;
use scryer_prolog::*;
use scryer_prolog::atom_table::Atom;
+ use std::sync::atomic::Ordering;
#[cfg(feature = "repl")]
ctrlc::set_handler(move || {
scryer_prolog::machine::INTERRUPT.store(true, Ordering::Relaxed);
- }).unwrap();
+ })
+ .unwrap();
#[cfg(target_os = "wasi")]
let runtime = tokio::runtime::Builder::new_current_thread()
diff --git a/src/codegen.rs b/src/codegen.rs
index 4902a618..e4e75006 100644
--- a/src/codegen.rs
+++ b/src/codegen.rs
@@ -1,14 +1,14 @@
-use crate::atom_table::*;
-use crate::parser::ast::*;
-use crate::temp_v;
use crate::allocator::*;
use crate::arithmetic::*;
+use crate::atom_table::*;
use crate::debray_allocator::*;
use crate::forms::*;
use crate::indexing::*;
use crate::instructions::*;
use crate::iterators::*;
+use crate::parser::ast::*;
use crate::targets::*;
+use crate::temp_v;
use crate::types::*;
use crate::instr;
@@ -48,15 +48,20 @@ impl BranchCodeStack {
}
fn code<'a>(&'a mut self, default_code: &'a mut CodeDeque) -> &'a mut CodeDeque {
- self.stack.last_mut()
+ self.stack
+ .last_mut()
.and_then(|stack| stack.last_mut())
.unwrap_or(default_code)
}
- fn push_missing_vars(&mut self, depth: usize, marker: &mut DebrayAllocator) -> SubsumedBranchHits {
+ fn push_missing_vars(
+ &mut self,
+ depth: usize,
+ marker: &mut DebrayAllocator,
+ ) -> SubsumedBranchHits {
let mut subsumed_hits = SubsumedBranchHits::with_hasher(FxBuildHasher::default());
- for idx in (self.stack.len() - depth .. self.stack.len()).rev() {
+ for idx in (self.stack.len() - depth..self.stack.len()).rev() {
let branch = &mut marker.branch_stack[idx];
let branch_hits = &branch.hits;
@@ -91,14 +96,14 @@ impl BranchCodeStack {
fn push_jump_instrs(&mut self, depth: usize) {
// add 2 in each arm length to compensate for each jump
// instruction and each branch instruction not yet added.
- let mut jump_span: usize = self.stack[self.stack.len() - depth ..]
+ let mut jump_span: usize = self.stack[self.stack.len() - depth..]
.iter()
.map(|branch| branch.iter().map(|code| code.len() + 2).sum::())
.sum();
jump_span -= depth;
- for idx in self.stack.len() - depth .. self.stack.len() {
+ for idx in self.stack.len() - depth..self.stack.len() {
let inner_len = self.stack[idx].len();
for (inner_idx, code) in self.stack[idx].iter_mut().enumerate() {
@@ -117,9 +122,11 @@ impl BranchCodeStack {
fn pop_branch(&mut self, depth: usize, settings: CodeGenSettings) -> CodeDeque {
let mut combined_code = CodeDeque::new();
- for mut branch_arm in self.stack.drain(self.stack.len() - depth ..).rev() {
+ for mut branch_arm in self.stack.drain(self.stack.len() - depth..).rev() {
let num_branch_arms = branch_arm.len();
- branch_arm.last_mut().map(|code| code.extend(combined_code.drain(..)));
+ branch_arm
+ .last_mut()
+ .map(|code| code.extend(combined_code.drain(..)));
for (idx, code) in branch_arm.into_iter().enumerate() {
combined_code.push_back(if idx == 0 {
@@ -255,7 +262,7 @@ impl CodeGenSettings {
#[derive(Debug)]
pub(crate) struct CodeGenerator<'a> {
- pub(crate) atom_tbl: &'a mut AtomTable,
+ pub(crate) atom_tbl: &'a AtomTable,
marker: DebrayAllocator,
settings: CodeGenSettings,
pub(crate) skeleton: PredicateSkeleton,
@@ -269,13 +276,7 @@ impl DebrayAllocator {
vr: &Cell,
code: &mut CodeDeque,
) -> RegType {
- self.mark_var::(
- var_num,
- Level::Shallow,
- vr,
- term_loc,
- code,
- );
+ self.mark_var::(var_num, Level::Shallow, vr, term_loc, code);
vr.get().norm()
}
@@ -308,8 +309,8 @@ impl DebrayAllocator {
// decrement the arity of the PutStructure instruction by 1.
fn trim_structure_by_last_arg(instr: &mut Instruction, last_arg: &Term) {
match instr {
- Instruction::PutStructure(_, ref mut arity, _) |
- Instruction::GetStructure(.., ref mut arity, _) => {
+ Instruction::PutStructure(_, ref mut arity, _)
+ | Instruction::GetStructure(.., ref mut arity, _) => {
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
// it is acceptable if arity == 0 is the result of
// this decrement. call/N will have to read the index
@@ -352,16 +353,16 @@ impl<'a, 'b> AddToFreeList<'a, QueryInstruction> for CodeGenerator<'b> {
fn structure_cell(term: &Term) -> Option<&Cell> {
match term {
- &Term::Cons(ref cell, ..) |
- &Term::Clause(ref cell, ..) |
- Term::PartialString(ref cell, ..) |
- Term::CompleteString(ref cell, ..) => Some(cell),
+ &Term::Cons(ref cell, ..)
+ | &Term::Clause(ref cell, ..)
+ | Term::PartialString(ref cell, ..)
+ | Term::CompleteString(ref cell, ..) => Some(cell),
_ => None,
}
}
impl<'b> CodeGenerator<'b> {
- pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
+ pub(crate) fn new(atom_tbl: &'b AtomTable, settings: CodeGenSettings) -> Self {
CodeGenerator {
atom_tbl,
marker: DebrayAllocator::new(),
@@ -392,7 +393,8 @@ impl<'b> CodeGenerator<'b> {
target: &mut CodeDeque,
) {
if self.marker.var_data.records[var_num].num_occurrences > 1 {
- self.marker.mark_var::(var_num, Level::Deep, cell, term_loc, target);
+ self.marker
+ .mark_var::(var_num, Level::Deep, cell, term_loc, target);
} else {
Self::add_or_increment_void_instr::(target);
}
@@ -408,31 +410,33 @@ impl<'b> CodeGenerator<'b> {
&Term::AnonVar => {
Self::add_or_increment_void_instr::(target);
}
- &Term::Cons(ref cell, ..) |
- &Term::Clause(ref cell, ..) |
- Term::PartialString(ref cell, ..) |
- Term::CompleteString(ref cell, ..) => {
- self.marker.mark_non_var::(Level::Deep, term_loc, cell, target);
+ &Term::Cons(ref cell, ..)
+ | &Term::Clause(ref cell, ..)
+ | Term::PartialString(ref cell, ..)
+ | Term::CompleteString(ref cell, ..) => {
+ self.marker
+ .mark_non_var::(Level::Deep, term_loc, cell, target);
target.push_back(Target::clause_arg_to_instr(cell.get()));
}
&Term::Literal(_, ref constant) => {
target.push_back(Target::constant_subterm(constant.clone()));
}
&Term::Var(ref cell, ref var_ptr) => {
- self.deep_var_instr::(cell, var_ptr.to_var_num().unwrap(), term_loc, target);
+ self.deep_var_instr::(
+ cell,
+ var_ptr.to_var_num().unwrap(),
+ term_loc,
+ target,
+ );
}
};
}
- fn compile_target<'a, Target, Iter>(
- &mut self,
- iter: Iter,
- term_loc: GenContext,
- ) -> CodeDeque
+ fn compile_target<'a, Target, Iter>(&mut self, iter: Iter, term_loc: GenContext) -> CodeDeque
where
Target: crate::targets::CompilationTarget<'a>,
Iter: Iterator- >,
- CodeGenerator<'b>: AddToFreeList<'a, Target>
+ CodeGenerator<'b>: AddToFreeList<'a, Target>,
{
let mut target = CodeDeque::new();
@@ -442,14 +446,19 @@ impl<'b> CodeGenerator<'b> {
if let GenContext::Head = term_loc {
self.marker.advance_arg();
} else {
- self.marker.mark_anon_var::(lvl, term_loc, &mut target);
+ self.marker
+ .mark_anon_var::(lvl, term_loc, &mut target);
}
}
TermRef::Clause(lvl, cell, name, terms) => {
- self.marker.mark_non_var::(lvl, term_loc, cell, &mut target);
+ self.marker
+ .mark_non_var::(lvl, term_loc, cell, &mut target);
target.push_back(Target::to_structure(lvl, name, terms.len(), cell.get()));
- as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get());
+ as AddToFreeList<'a, Target>>::add_term_to_free_list(
+ self,
+ cell.get(),
+ );
if let Some(instr) = target.back_mut() {
if let Some(term) = terms.last() {
@@ -462,38 +471,52 @@ impl<'b> CodeGenerator<'b> {
}
for subterm in terms {
- as AddToFreeList<'a, Target>>::add_subterm_to_free_list(self, subterm);
+ as AddToFreeList<'a, Target>>::add_subterm_to_free_list(
+ self, subterm,
+ );
}
}
TermRef::Cons(lvl, cell, head, tail) => {
- self.marker.mark_non_var::(lvl, term_loc, cell, &mut target);
+ self.marker
+ .mark_non_var::(lvl, term_loc, cell, &mut target);
target.push_back(Target::to_list(lvl, cell.get()));
- as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get());
+ as AddToFreeList<'a, Target>>::add_term_to_free_list(
+ self,
+ cell.get(),
+ );
self.subterm_to_instr::(head, term_loc, &mut target);
self.subterm_to_instr::(tail, term_loc, &mut target);
- as AddToFreeList<'a, Target>>::add_subterm_to_free_list(self, head);
- as AddToFreeList<'a, Target>>::add_subterm_to_free_list(self, tail);
+ as AddToFreeList<'a, Target>>::add_subterm_to_free_list(
+ self, head,
+ );
+ as AddToFreeList<'a, Target>>::add_subterm_to_free_list(
+ self, tail,
+ );
}
TermRef::Literal(lvl @ Level::Shallow, cell, Literal::String(ref string)) => {
- self.marker.mark_non_var::(lvl, term_loc, cell, &mut target);
+ self.marker
+ .mark_non_var::(lvl, term_loc, cell, &mut target);
target.push_back(Target::to_pstr(lvl, *string, cell.get(), false));
}
TermRef::Literal(lvl @ Level::Shallow, cell, constant) => {
- self.marker.mark_non_var::(lvl, term_loc, cell, &mut target);
+ self.marker
+ .mark_non_var::(lvl, term_loc, cell, &mut target);
target.push_back(Target::to_constant(lvl, *constant, cell.get()));
}
TermRef::PartialString(lvl, cell, string, tail) => {
- self.marker.mark_non_var::(lvl, term_loc, cell, &mut target);
- let atom = self.atom_tbl.build_with(&string);
+ self.marker
+ .mark_non_var::(lvl, term_loc, cell, &mut target);
+ let atom = AtomTable::build_with(&self.atom_tbl, &string);
target.push_back(Target::to_pstr(lvl, atom, cell.get(), true));
self.subterm_to_instr::(tail, term_loc, &mut target);
}
TermRef::CompleteString(lvl, cell, atom) => {
- self.marker.mark_non_var::(lvl, term_loc, cell, &mut target);
+ self.marker
+ .mark_non_var::(lvl, term_loc, cell, &mut target);
target.push_back(Target::to_pstr(lvl, atom, cell.get(), false));
}
TermRef::Var(lvl @ Level::Shallow, cell, var) => {
@@ -563,9 +586,9 @@ impl<'b> CodeGenerator<'b> {
compare_number_instr!(cmp, at_1, at_2)
}
&InlinedClauseType::IsAtom(..) => match &terms[0] {
- &Term::Literal(_, Literal::Char(_)) |
- &Term::Literal(_, Literal::Atom(atom!("[]"))) |
- &Term::Literal(_, Literal::Atom(..)) => {
+ &Term::Literal(_, Literal::Char(_))
+ | &Term::Literal(_, Literal::Atom(atom!("[]")))
+ | &Term::Literal(_, Literal::Atom(..)) => {
instr!("$succeed")
}
&Term::Var(ref vr, ref name) => {
@@ -586,11 +609,11 @@ impl<'b> CodeGenerator<'b> {
}
},
&InlinedClauseType::IsAtomic(..) => match &terms[0] {
- &Term::AnonVar |
- &Term::Clause(..) |
- &Term::Cons(..) |
- &Term::PartialString(..) |
- &Term::CompleteString(..) => {
+ &Term::AnonVar
+ | &Term::Clause(..)
+ | &Term::Cons(..)
+ | &Term::PartialString(..)
+ | &Term::CompleteString(..) => {
instr!("$fail")
}
&Term::Literal(_, Literal::String(_)) => {
@@ -614,11 +637,11 @@ impl<'b> CodeGenerator<'b> {
}
},
&InlinedClauseType::IsCompound(..) => match &terms[0] {
- &Term::Clause(..) |
- &Term::Cons(..) |
- &Term::PartialString(..) |
- &Term::CompleteString(..) |
- &Term::Literal(_, Literal::String(..)) => {
+ &Term::Clause(..)
+ | &Term::Cons(..)
+ | &Term::PartialString(..)
+ | &Term::CompleteString(..)
+ | &Term::Literal(_, Literal::String(..)) => {
instr!("$succeed")
}
&Term::Var(ref vr, ref name) => {
@@ -644,7 +667,13 @@ impl<'b> CodeGenerator<'b> {
}
&Term::Var(ref vr, ref name) => {
self.marker.reset_arg(1);
- let r = self.marker.mark_non_callable(name.to_var_num().unwrap(), 1, term_loc, vr, code);
+ let r = self.marker.mark_non_callable(
+ name.to_var_num().unwrap(),
+ 1,
+ term_loc,
+ vr,
+ code,
+ );
instr!("rational", r)
}
_ => {
@@ -673,10 +702,10 @@ impl<'b> CodeGenerator<'b> {
}
},
&InlinedClauseType::IsNumber(..) => match &terms[0] {
- &Term::Literal(_, Literal::Float(_)) |
- &Term::Literal(_, Literal::Rational(_)) |
- &Term::Literal(_, Literal::Integer(_)) |
- &Term::Literal(_, Literal::Fixnum(_)) => {
+ &Term::Literal(_, Literal::Float(_))
+ | &Term::Literal(_, Literal::Rational(_))
+ | &Term::Literal(_, Literal::Integer(_))
+ | &Term::Literal(_, Literal::Fixnum(_)) => {
instr!("$succeed")
}
&Term::Var(ref vr, ref name) => {
@@ -718,8 +747,7 @@ impl<'b> CodeGenerator<'b> {
}
},
&InlinedClauseType::IsInteger(..) => match &terms[0] {
- &Term::Literal(_, Literal::Integer(_)) |
- &Term::Literal(_, Literal::Fixnum(_)) => {
+ &Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => {
instr!("$succeed")
}
&Term::Var(ref vr, ref name) => {
@@ -740,11 +768,11 @@ impl<'b> CodeGenerator<'b> {
}
},
&InlinedClauseType::IsVar(..) => match &terms[0] {
- &Term::Literal(..) |
- &Term::Clause(..) |
- &Term::Cons(..) |
- &Term::PartialString(..) |
- &Term::CompleteString(..) => {
+ &Term::Literal(..)
+ | &Term::Clause(..)
+ | &Term::Cons(..)
+ | &Term::PartialString(..)
+ | &Term::CompleteString(..) => {
instr!("$fail")
}
&Term::AnonVar => {
@@ -791,11 +819,11 @@ impl<'b> CodeGenerator<'b> {
call_policy: CallPolicy,
) -> Result<(), CompilationError> {
macro_rules! compile_expr {
- ($self:expr, $terms:expr, $term_loc:expr, $code:expr) => ({
+ ($self:expr, $terms:expr, $term_loc:expr, $code:expr) => {{
let (acode, at) = $self.compile_arith_expr($terms, 1, $term_loc, 2)?;
$code.extend(acode.into_iter());
at
- });
+ }};
}
self.marker.reset_arg(2);
@@ -843,10 +871,13 @@ impl<'b> CodeGenerator<'b> {
compile_expr!(self, &terms[1], term_loc, code)
}
}
- &Term::Literal(_, c @ Literal::Integer(_) |
- c @ Literal::Float(_) |
- c @ Literal::Rational(_) |
- c @ Literal::Fixnum(_)) => {
+ &Term::Literal(
+ _,
+ c @ Literal::Integer(_)
+ | c @ Literal::Float(_)
+ | c @ Literal::Rational(_)
+ | c @ Literal::Fixnum(_),
+ ) => {
let v = HeapCellValue::from(c);
code.push_back(instr!("put_constant", Level::Shallow, v, temp_v!(1)));
@@ -939,15 +970,29 @@ impl<'b> CodeGenerator<'b> {
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
ref terms,
call_policy,
- ) => self.compile_is_call(terms, branch_code_stack.code(code), term_loc, call_policy)?,
+ ) => self.compile_is_call(
+ terms,
+ branch_code_stack.code(code),
+ term_loc,
+ call_policy,
+ )?,
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
- self.compile_inlined(ct, terms, term_loc, branch_code_stack.code(code))?
+ self.compile_inlined(
+ ct,
+ terms,
+ term_loc,
+ branch_code_stack.code(code),
+ )?
}
&QueryTerm::Fail => {
branch_code_stack.code(code).push_back(instr!("$fail"));
}
term @ &QueryTerm::Clause(..) => {
- self.compile_query_line(term, term_loc, branch_code_stack.code(code));
+ self.compile_query_line(
+ term,
+ term_loc,
+ branch_code_stack.code(code),
+ );
if self.marker.max_reg_allocated() > MAX_ARITY {
return Err(CompilationError::ExceededMaxArity);
@@ -975,7 +1020,8 @@ impl<'b> CodeGenerator<'b> {
}
ClauseItem::BranchEnd(depth) => {
if !clause_iter.in_tail_position() {
- let subsumed_hits = branch_code_stack.push_missing_vars(depth, &mut self.marker);
+ let subsumed_hits =
+ branch_code_stack.push_missing_vars(depth, &mut self.marker);
self.marker.pop_branch(depth, subsumed_hits);
branch_code_stack.push_jump_instrs(depth);
} else {
@@ -1001,8 +1047,15 @@ impl<'b> CodeGenerator<'b> {
Ok(())
}
- pub(crate) fn compile_rule(&mut self, rule: &Rule, var_data: VarData) -> Result
{
- let Rule { head: (_, args), clauses } = rule;
+ pub(crate) fn compile_rule(
+ &mut self,
+ rule: &Rule,
+ var_data: VarData,
+ ) -> Result {
+ let Rule {
+ head: (_, args),
+ clauses,
+ } = rule;
self.marker.var_data = var_data;
let mut code = VecDeque::new();
@@ -1023,7 +1076,11 @@ impl<'b> CodeGenerator<'b> {
Ok(Vec::from(code))
}
- pub(crate) fn compile_fact(&mut self, fact: &Fact, var_data: VarData) -> Result {
+ pub(crate) fn compile_fact(
+ &mut self,
+ fact: &Fact,
+ var_data: VarData,
+ ) -> Result {
let mut code = Vec::new();
self.marker.var_data = var_data;
@@ -1031,10 +1088,7 @@ impl<'b> CodeGenerator<'b> {
self.marker.reset_at_head(args);
let iter = FactInstruction::iter(&fact.head);
- let compiled_fact = self.compile_target::(
- iter,
- GenContext::Head,
- );
+ let compiled_fact = self.compile_target::(iter, GenContext::Head);
if self.marker.max_reg_allocated() > MAX_ARITY {
return Err(CompilationError::ExceededMaxArity);
@@ -1059,7 +1113,7 @@ impl<'b> CodeGenerator<'b> {
&QueryTerm::Clause(_, ref ct, _, call_policy) => {
self.add_call(code, ct.to_instr(), call_policy);
}
- _ => unreachable!()
+ _ => unreachable!(),
};
}
@@ -1072,8 +1126,7 @@ impl<'b> CodeGenerator<'b> {
if let Some(args) = clause.args() {
for (instantiated_arg_index, arg) in args.iter().enumerate() {
match arg {
- Term::Var(..) | Term::AnonVar => {
- }
+ Term::Var(..) | Term::AnonVar => {}
_ => {
if optimal_index != instantiated_arg_index {
if left >= right {
@@ -1098,7 +1151,11 @@ impl<'b> CodeGenerator<'b> {
}
if left < right {
- subseqs.push(ClauseSpan { left, right, instantiated_arg_index: optimal_index });
+ subseqs.push(ClauseSpan {
+ left,
+ right,
+ instantiated_arg_index: optimal_index,
+ });
}
optimal_index = 0;
@@ -1129,7 +1186,8 @@ impl<'b> CodeGenerator<'b> {
optimal_index: usize,
) -> Result {
let mut code = VecDeque::new();
- let mut code_offsets = CodeOffsets::new(I::new(), optimal_index + 1);
+ let mut code_offsets =
+ CodeOffsets::new(I::new(), optimal_index + 1, self.settings.non_counted_bt);
let mut skip_stub_try_me_else = false;
let clauses_len = clauses.len();
@@ -1174,7 +1232,9 @@ impl<'b> CodeGenerator<'b> {
skip_stub_try_me_else = !self.settings.is_dynamic();
}
- let arg = clause.args().and_then(|args| args.iter().nth(optimal_index));
+ let arg = clause
+ .args()
+ .and_then(|args| args.iter().nth(optimal_index));
if let Some(arg) = arg {
let index = code.len();
@@ -1217,7 +1277,12 @@ impl<'b> CodeGenerator<'b> {
let split_pred = Self::split_predicate(&clauses);
let multi_seq = split_pred.len() > 1;
- for ClauseSpan { left, right, instantiated_arg_index } in split_pred {
+ for ClauseSpan {
+ left,
+ right,
+ instantiated_arg_index,
+ } in split_pred
+ {
let skel_lower_bound = self.skeleton.clauses.len();
let code_segment = if self.settings.is_dynamic() {
self.compile_pred_subseq::(
@@ -1248,9 +1313,8 @@ impl<'b> CodeGenerator<'b> {
if self.settings.is_extensible {
let segment_is_indexed = code_segment[0].to_indexing_line().is_some();
- for clause_index_info in self.skeleton.clauses
- .make_contiguous()[skel_lower_bound..]
- .iter_mut()
+ for clause_index_info in
+ self.skeleton.clauses.make_contiguous()[skel_lower_bound..].iter_mut()
{
clause_index_info.clause_start +=
clause_start_offset + 2 * (segment_is_indexed as usize);
diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs
index 0337ed4d..54f4283b 100644
--- a/src/debray_allocator.rs
+++ b/src/debray_allocator.rs
@@ -76,11 +76,16 @@ impl BranchStack {
}
}
- fn safety_unneeded_in_branch(&self, safety: &VarSafetyStatus, branch: &BranchDesignator) -> bool {
+ fn safety_unneeded_in_branch(
+ &self,
+ safety: &VarSafetyStatus,
+ branch: &BranchDesignator,
+ ) -> bool {
match safety {
VarSafetyStatus::Needed => false,
- VarSafetyStatus::LocallyUnneeded(planter_branch) =>
- self.branch_subsumes(planter_branch, branch),
+ VarSafetyStatus::LocallyUnneeded(planter_branch) => {
+ self.branch_subsumes(planter_branch, branch)
+ }
VarSafetyStatus::GloballyUnneeded => true,
}
}
@@ -91,7 +96,9 @@ impl BranchStack {
let num_branches = occurrences.num_branches;
- let entry = occurrences.hits.entry(var_num)
+ let entry = occurrences
+ .hits
+ .entry(var_num)
.or_insert_with(|| BitVec::repeat(false, num_branches));
entry.set(occurrences.current_branch, true);
@@ -105,11 +112,15 @@ impl BranchStack {
pub(crate) fn current_branch_designator(&self) -> BranchDesignator {
let branch_stack_num = self.len();
- let branch_num = self.last()
+ let branch_num = self
+ .last()
.map(|occurrences| occurrences.current_branch)
.unwrap_or(0);
- BranchDesignator { branch_stack_num, branch_num }
+ BranchDesignator {
+ branch_stack_num,
+ branch_num,
+ }
}
#[inline]
@@ -121,7 +132,7 @@ impl BranchStack {
#[inline]
pub(crate) fn drain_branches(&mut self, depth: usize) -> std::vec::Drain {
let start_idx = self.len() - depth;
- self.drain(start_idx ..)
+ self.drain(start_idx..)
}
}
@@ -156,13 +167,23 @@ impl DebrayAllocator {
match &mut self.var_data.records[var_num].allocation {
VarAlloc::Perm(_, ref mut allocation) => {
match allocation {
- PermVarAllocation::Done { shallow_safety, deep_safety, .. } => {
- if !self.branch_stack.safety_unneeded_in_branch(shallow_safety, &branch_designator) {
+ PermVarAllocation::Done {
+ shallow_safety,
+ deep_safety,
+ ..
+ } => {
+ if !self
+ .branch_stack
+ .safety_unneeded_in_branch(shallow_safety, &branch_designator)
+ {
let branch_occurrences = self.branch_stack.last_mut().unwrap();
branch_occurrences.shallow_safety.insert(var_num);
}
- if !self.branch_stack.safety_unneeded_in_branch(deep_safety, &branch_designator) {
+ if !self
+ .branch_stack
+ .safety_unneeded_in_branch(deep_safety, &branch_designator)
+ {
let branch_occurrences = self.branch_stack.last_mut().unwrap();
branch_occurrences.deep_safety.insert(var_num);
}
@@ -182,15 +203,15 @@ impl DebrayAllocator {
pub(crate) fn pop_branch(&mut self, depth: usize, subsumed_hits: SubsumedBranchHits) {
let removed_branches = self.branch_stack.drain_branches(depth);
- let (deep_safety, shallow_safety) = removed_branches
- .into_iter()
- .fold((BitSet::default(), BitSet::default()),
- |(mut deep_safety, mut shallow_safety), branch_occurrences| {
- deep_safety.union_with(&branch_occurrences.deep_safety);
- shallow_safety.union_with(&branch_occurrences.shallow_safety);
+ let (deep_safety, shallow_safety) = removed_branches.into_iter().fold(
+ (BitSet::default(), BitSet::default()),
+ |(mut deep_safety, mut shallow_safety), branch_occurrences| {
+ deep_safety.union_with(&branch_occurrences.deep_safety);
+ shallow_safety.union_with(&branch_occurrences.shallow_safety);
- (deep_safety, shallow_safety)
- });
+ (deep_safety, shallow_safety)
+ },
+ );
let branch_designator = self.branch_stack.current_branch_designator();
@@ -201,7 +222,7 @@ impl DebrayAllocator {
(&latest_branch.deep_safety, &latest_branch.shallow_safety)
}
- None => (&deep_safety, &shallow_safety)
+ None => (&deep_safety, &shallow_safety),
};
for var_num in subsumed_hits.iter().cloned() {
@@ -221,10 +242,13 @@ impl DebrayAllocator {
);
if running_count < num_occurrences {
- *allocation = PermVarAllocation::Done { shallow_safety, deep_safety };
+ *allocation = PermVarAllocation::Done {
+ shallow_safety,
+ deep_safety,
+ };
}
}
- _ => unreachable!()
+ _ => unreachable!(),
}
}
@@ -244,9 +268,11 @@ impl DebrayAllocator {
fn occurs_shallowly_in_head(&self, var_num: usize, r: usize) -> bool {
match &self.var_data.records[var_num].allocation {
- VarAlloc::Temp { temp_var_data, term_loc: GenContext::Head, .. } => {
- temp_var_data.use_set.contains(&(GenContext::Head, r))
- }
+ VarAlloc::Temp {
+ temp_var_data,
+ term_loc: GenContext::Head,
+ ..
+ } => temp_var_data.use_set.contains(&(GenContext::Head, r)),
_ => false,
}
}
@@ -325,12 +351,14 @@ impl DebrayAllocator {
match &self.var_data.records[t_var].allocation {
VarAlloc::Temp { temp_var_data, .. } => {
- if !temp_var_data.use_set.contains(&(GenContext::Last(chunk_num), k)) {
+ if !temp_var_data
+ .use_set
+ .contains(&(GenContext::Last(chunk_num), k))
+ {
return Some((t_var, self.alloc_with_ca(t_var)));
}
}
- _ => {
- }
+ _ => {}
}
None
@@ -356,7 +384,9 @@ impl DebrayAllocator {
self.shallow_temp_mappings.swap_remove(&k);
self.shallow_temp_mappings.insert(r.reg_num(), var_num);
- self.var_data.records[var_num].allocation.set_register(r.reg_num());
+ self.var_data.records[var_num]
+ .allocation
+ .set_register(r.reg_num());
self.in_use.insert(r.reg_num());
}
}
@@ -417,12 +447,9 @@ impl DebrayAllocator {
fn in_place(&self, var_num: usize, term_loc: GenContext, r: RegType, k: usize) -> bool {
match term_loc {
GenContext::Head if !r.is_perm() => r.reg_num() == k,
- _ => {
- match &self.var_data.records[var_num].allocation {
- &VarAlloc::Temp { temp_reg, .. } if r.reg_num() == k =>
- temp_reg == k,
- _ => false,
- }
+ _ => match &self.var_data.records[var_num].allocation {
+ &VarAlloc::Temp { temp_reg, .. } if r.reg_num() == k => temp_reg == k,
+ _ => false,
},
}
}
@@ -483,8 +510,7 @@ impl DebrayAllocator {
VarAlloc::Perm(p, PermVarAllocation::Pending) if *p > 0 => {
return Some(std::mem::replace(p, 0));
}
- _ => {
- }
+ _ => {}
}
} else {
return None;
@@ -500,8 +526,7 @@ impl DebrayAllocator {
*allocation = PermVarAllocation::Pending;
self.add_perm_to_free_list(chunk_num, var_num);
}
- _ => {
- }
+ _ => {}
}
}
@@ -509,7 +534,14 @@ impl DebrayAllocator {
let branch_designator = self.branch_stack.current_branch_designator();
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => {
+ VarAlloc::Perm(
+ _,
+ PermVarAllocation::Done {
+ deep_safety,
+ shallow_safety,
+ ..
+ },
+ ) => {
*deep_safety = VarSafetyStatus::unneeded(branch_designator);
*shallow_safety = VarSafetyStatus::unneeded(branch_designator);
}
@@ -524,7 +556,14 @@ impl DebrayAllocator {
let branch_designator = self.branch_stack.current_branch_designator();
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => {
+ VarAlloc::Perm(
+ _,
+ PermVarAllocation::Done {
+ deep_safety,
+ shallow_safety,
+ ..
+ },
+ ) => {
// GetVariable in head chunk is considered safe.
if lvl == Level::Deep {
*deep_safety = VarSafetyStatus::unneeded(branch_designator);
@@ -532,12 +571,16 @@ impl DebrayAllocator {
} else if term_loc == GenContext::Head {
*shallow_safety = VarSafetyStatus::GloballyUnneeded;
} else {
- if let Some(temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c).cloned() {
+ if let Some(temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c).cloned()
+ {
match &mut self.var_data.records[temp_var_num].allocation {
- VarAlloc::Temp { ref mut to_perm_var_num, .. } => {
+ VarAlloc::Temp {
+ ref mut to_perm_var_num,
+ ..
+ } => {
*to_perm_var_num = Some(var_num);
}
- _ => unreachable!()
+ _ => unreachable!(),
}
}
}
@@ -560,8 +603,18 @@ impl DebrayAllocator {
let branch_designator = self.branch_stack.current_branch_designator();
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm(_, PermVarAllocation::Done { ref mut shallow_safety, .. }) => {
- if !self.in_tail_position || self.branch_stack.safety_unneeded_in_branch(shallow_safety, &branch_designator) {
+ VarAlloc::Perm(
+ _,
+ PermVarAllocation::Done {
+ ref mut shallow_safety,
+ ..
+ },
+ ) => {
+ if !self.in_tail_position
+ || self
+ .branch_stack
+ .safety_unneeded_in_branch(shallow_safety, &branch_designator)
+ {
Target::argument_to_value(r, arg_c)
} else {
*shallow_safety = VarSafetyStatus::unneeded(branch_designator);
@@ -569,7 +622,10 @@ impl DebrayAllocator {
}
}
VarAlloc::Temp { ref mut safety, .. } => {
- if self.branch_stack.safety_unneeded_in_branch(safety, &branch_designator) {
+ if self
+ .branch_stack
+ .safety_unneeded_in_branch(safety, &branch_designator)
+ {
Target::argument_to_value(r, arg_c)
} else {
*safety = VarSafetyStatus::GloballyUnneeded;
@@ -590,8 +646,17 @@ impl DebrayAllocator {
let branch_designator = self.branch_stack.current_branch_designator();
match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm(_, PermVarAllocation::Done { ref mut deep_safety, .. }) => {
- if self.branch_stack.safety_unneeded_in_branch(deep_safety, &branch_designator) {
+ VarAlloc::Perm(
+ _,
+ PermVarAllocation::Done {
+ ref mut deep_safety,
+ ..
+ },
+ ) => {
+ if self
+ .branch_stack
+ .safety_unneeded_in_branch(deep_safety, &branch_designator)
+ {
Target::subterm_to_value(r)
} else {
*deep_safety = VarSafetyStatus::unneeded(branch_designator);
@@ -599,7 +664,10 @@ impl DebrayAllocator {
}
}
VarAlloc::Temp { ref mut safety, .. } => {
- if self.branch_stack.safety_unneeded_in_branch(safety, &branch_designator) {
+ if self
+ .branch_stack
+ .safety_unneeded_in_branch(safety, &branch_designator)
+ {
Target::subterm_to_value(r)
} else {
*safety = VarSafetyStatus::unneeded(branch_designator);
@@ -626,7 +694,7 @@ impl Allocator for DebrayAllocator {
in_use: BitSet::default(),
temp_free_list: vec![],
perm_free_list: VecDeque::new(),
- branch_stack: BranchStack { stack: vec![] }
+ branch_stack: BranchStack { stack: vec![] },
}
}
@@ -705,12 +773,14 @@ impl Allocator for DebrayAllocator {
}
r @ RegType::Perm(_) => {
let is_new_var = match &mut self.var_data.records[var_num].allocation {
- VarAlloc::Perm(_, allocation) => if allocation.pending() {
- *allocation = PermVarAllocation::done();
- true
- } else {
- false
- },
+ VarAlloc::Perm(_, allocation) => {
+ if allocation.pending() {
+ *allocation = PermVarAllocation::done();
+ true
+ } else {
+ false
+ }
+ }
_ => unreachable!(),
};
@@ -828,7 +898,9 @@ impl Allocator for DebrayAllocator {
if !r.is_perm() && r.reg_num() == 0 {
self.in_use.insert(idx + 1);
self.shallow_temp_mappings.insert(idx + 1, var_num);
- self.var_data.records[var_num].allocation.set_register(idx + 1);
+ self.var_data.records[var_num]
+ .allocation
+ .set_register(idx + 1);
}
}
}
diff --git a/src/ffi.rs b/src/ffi.rs
index a48ed62e..8fd55dbc 100644
--- a/src/ffi.rs
+++ b/src/ffi.rs
@@ -24,12 +24,12 @@ use crate::atom_table::Atom;
use std::alloc::{alloc, Layout};
use std::any::Any;
use std::collections::HashMap;
-use std::error::Error;
-use std::ffi::{CString, c_void};
use std::convert::TryFrom;
+use std::error::Error;
+use std::ffi::{c_void, CString};
-use libffi::low::{ffi_cif, types, CodePtr, ffi_abi_FFI_DEFAULT_ABI, prep_cif, ffi_type, type_tag};
-use libloading::{Symbol, Library};
+use libffi::low::{ffi_abi_FFI_DEFAULT_ABI, ffi_cif, ffi_type, prep_cif, type_tag, types, CodePtr};
+use libloading::{Library, Symbol};
pub struct FunctionDefinition {
pub name: String,
@@ -65,338 +65,393 @@ struct PointerArgs {
impl ForeignFunctionTable {
pub fn merge(&mut self, other: ForeignFunctionTable) {
- self.table.extend(other.table);
+ self.table.extend(other.table);
}
pub fn define_struct(&mut self, name: &str, atom_fields: Vec) {
- let mut fields: Vec<_> = atom_fields.iter().map(|x| self.map_type_ffi(&x)).collect();
- fields.push(std::ptr::null_mut::());
- let mut struct_type: ffi_type = Default::default();
- struct_type.type_ = type_tag::STRUCT;
- struct_type.elements = fields.as_mut_ptr();
- self.structs.insert(name.to_string(), StructImpl { ffi_type: struct_type, fields, atom_fields});
+ let mut fields: Vec<_> = atom_fields.iter().map(|x| self.map_type_ffi(&x)).collect();
+ fields.push(std::ptr::null_mut::());
+ let mut struct_type: ffi_type = Default::default();
+ struct_type.type_ = type_tag::STRUCT;
+ struct_type.elements = fields.as_mut_ptr();
+ self.structs.insert(
+ name.to_string(),
+ StructImpl {
+ ffi_type: struct_type,
+ fields,
+ atom_fields,
+ },
+ );
}
fn map_type_ffi(&mut self, source: &Atom) -> *mut ffi_type {
- unsafe {
- match source {
- atom!("sint64") => &mut types::sint64,
- atom!("sint32") => &mut types::sint32,
- atom!("sint16") => &mut types::sint16,
- atom!("sint8") => &mut types::sint8,
- atom!("uint64") => &mut types::uint64,
- atom!("uint32") => &mut types::uint32,
- atom!("uint16") => &mut types::uint16,
- atom!("uint8") => &mut types::uint8,
- atom!("bool") => &mut types::sint8,
- atom!("void") => &mut types::void,
- atom!("cstr") => &mut types::pointer,
- atom!("ptr") => &mut types::pointer,
- atom!("f32") => &mut types::float,
- atom!("f64") => &mut types::double,
- struct_name => {
- match self.structs.get_mut(struct_name.as_str()) {
- Some(ref mut struct_type) => {
- &mut struct_type.ffi_type
- },
- None => unreachable!()
- }
- }
- }
- }
+ unsafe {
+ match source {
+ atom!("sint64") => &mut types::sint64,
+ atom!("sint32") => &mut types::sint32,
+ atom!("sint16") => &mut types::sint16,
+ atom!("sint8") => &mut types::sint8,
+ atom!("uint64") => &mut types::uint64,
+ atom!("uint32") => &mut types::uint32,
+ atom!("uint16") => &mut types::uint16,
+ atom!("uint8") => &mut types::uint8,
+ atom!("bool") => &mut types::sint8,
+ atom!("void") => &mut types::void,
+ atom!("cstr") => &mut types::pointer,
+ atom!("ptr") => &mut types::pointer,
+ atom!("f32") => &mut types::float,
+ atom!("f64") => &mut types::double,
+ struct_name => match self.structs.get_mut(&*struct_name.as_str()) {
+ Some(ref mut struct_type) => &mut struct_type.ffi_type,
+ None => unreachable!(),
+ },
+ }
+ }
}
- pub(crate) fn load_library(&mut self, library_name: &str, functions: &Vec) -> Result<(), Box> {
- let mut ff_table: ForeignFunctionTable = Default::default();
- unsafe {
- let library = Library::new(library_name)?;
- for function in functions {
- let symbol_name: CString = CString::new(function.name.clone())?;
- let code_ptr: Symbol<*mut c_void> = library.get(&symbol_name.into_bytes_with_nul())?;
- let mut args: Vec<_> = function.args.iter().map(|x| self.map_type_ffi(&x)).collect();
- let mut cif: ffi_cif = Default::default();
- prep_cif(
- &mut cif,
- ffi_abi_FFI_DEFAULT_ABI,
- args.len(),
- self.map_type_ffi(&function.return_value),
- args.as_mut_ptr()
- ).unwrap();
+ pub(crate) fn load_library(
+ &mut self,
+ library_name: &str,
+ functions: &Vec,
+ ) -> Result<(), Box> {
+ let mut ff_table: ForeignFunctionTable = Default::default();
+ unsafe {
+ let library = Library::new(library_name)?;
+ for function in functions {
+ let symbol_name: CString = CString::new(function.name.clone())?;
+ let code_ptr: Symbol<*mut c_void> =
+ library.get(&symbol_name.into_bytes_with_nul())?;
+ let mut args: Vec<_> = function
+ .args
+ .iter()
+ .map(|x| self.map_type_ffi(&x))
+ .collect();
+ let mut cif: ffi_cif = Default::default();
+ prep_cif(
+ &mut cif,
+ ffi_abi_FFI_DEFAULT_ABI,
+ args.len(),
+ self.map_type_ffi(&function.return_value),
+ args.as_mut_ptr(),
+ )
+ .unwrap();
- let return_struct_name = if (*self.map_type_ffi(&function.return_value)).type_ as u32 == libffi::raw::FFI_TYPE_STRUCT {
- Some(function.return_value.as_str().to_string())
- } else {
- None
- };
+ let return_struct_name = if (*self.map_type_ffi(&function.return_value)).type_
+ as u32
+ == libffi::raw::FFI_TYPE_STRUCT
+ {
+ Some(function.return_value.as_str().to_string())
+ } else {
+ None
+ };
- ff_table.table.insert(function.name.clone(), FunctionImpl {
- cif,
- args,
- code_ptr: CodePtr(code_ptr.into_raw().into_raw() as *mut _),
- return_struct_name,
- });
- }
- std::mem::forget(library);
- }
- self.merge(ff_table);
- Ok(())
+ ff_table.table.insert(
+ function.name.clone(),
+ FunctionImpl {
+ cif,
+ args,
+ code_ptr: CodePtr(code_ptr.into_raw().into_raw() as *mut _),
+ return_struct_name,
+ },
+ );
+ }
+ std::mem::forget(library);
+ }
+ self.merge(ff_table);
+ Ok(())
}
- fn build_pointer_args(args: &mut Vec, type_args: &Vec<*mut ffi_type>, structs_table: &mut HashMap) -> Result {
- let mut pointers = Vec::with_capacity(args.len());
- let mut _memory = Vec::new();
- for i in 0..args.len() {
- let field_type = type_args[i];
- unsafe {
- macro_rules! push_int {
- ($type:ty) => {
- {
- let n: $type = <$type>::try_from(args[i].as_int()?).map_err(|_| FFIError::ValueDontFit)?;
- let mut box_value = Box::new(n) as Box;
- pointers.push(&mut *box_value as *mut _ as *mut c_void);
- _memory.push(box_value);
- }
- }
- }
-
- match (*field_type).type_ as u32 {
- libffi::raw::FFI_TYPE_UINT8 => push_int!(u8),
- libffi::raw::FFI_TYPE_SINT8 => push_int!(i8),
- libffi::raw::FFI_TYPE_UINT16 => push_int!(u16),
- libffi::raw::FFI_TYPE_SINT16 => push_int!(i16),
- libffi::raw::FFI_TYPE_UINT32 => push_int!(u32),
- libffi::raw::FFI_TYPE_SINT32 => push_int!(i32),
- libffi::raw::FFI_TYPE_UINT64 => push_int!(u64),
- libffi::raw::FFI_TYPE_SINT64 => push_int!(i64),
- libffi::raw::FFI_TYPE_FLOAT => {
- let n: f32 = args[i].as_float()? as f32;
- let mut box_value = Box::new(n) as Box;
- pointers.push(&mut *box_value as *mut _ as *mut c_void);
- _memory.push(box_value);
- },
- libffi::raw::FFI_TYPE_DOUBLE => {
- let n: f64 = args[i].as_float()?;
- let mut box_value = Box::new(n) as Box;
- pointers.push(&mut *box_value as *mut _ as *mut c_void);
- _memory.push(box_value);
- },
- libffi::raw::FFI_TYPE_POINTER => {
- let ptr: *mut c_void = args[i].as_ptr()?;
- pointers.push(ptr);
- },
- libffi::raw::FFI_TYPE_STRUCT => {
- let (mut ptr, _size, _align) = Self::build_struct(&mut args[i], structs_table)?;
- pointers.push(&mut *ptr as *mut _ as *mut c_void);
- _memory.push(ptr);
- },
- _ => return Err(FFIError::InvalidFFIType)
- }
- }
- }
- Ok(PointerArgs {
- pointers,
- _memory
- })
+ fn build_pointer_args(
+ args: &mut Vec,
+ type_args: &Vec<*mut ffi_type>,
+ structs_table: &mut HashMap,
+ ) -> Result {
+ let mut pointers = Vec::with_capacity(args.len());
+ let mut _memory = Vec::new();
+ for i in 0..args.len() {
+ let field_type = type_args[i];
+ unsafe {
+ macro_rules! push_int {
+ ($type:ty) => {{
+ let n: $type = <$type>::try_from(args[i].as_int()?)
+ .map_err(|_| FFIError::ValueDontFit)?;
+ let mut box_value = Box::new(n) as Box;
+ pointers.push(&mut *box_value as *mut _ as *mut c_void);
+ _memory.push(box_value);
+ }};
+ }
+
+ match (*field_type).type_ as u32 {
+ libffi::raw::FFI_TYPE_UINT8 => push_int!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => push_int!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => push_int!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => push_int!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => push_int!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => push_int!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => push_int!(u64),
+ libffi::raw::FFI_TYPE_SINT64 => push_int!(i64),
+ libffi::raw::FFI_TYPE_FLOAT => {
+ let n: f32 = args[i].as_float()? as f32;
+ let mut box_value = Box::new(n) as Box;
+ pointers.push(&mut *box_value as *mut _ as *mut c_void);
+ _memory.push(box_value);
+ }
+ libffi::raw::FFI_TYPE_DOUBLE => {
+ let n: f64 = args[i].as_float()?;
+ let mut box_value = Box::new(n) as Box;
+ pointers.push(&mut *box_value as *mut _ as *mut c_void);
+ _memory.push(box_value);
+ }
+ libffi::raw::FFI_TYPE_POINTER => {
+ let ptr: *mut c_void = args[i].as_ptr()?;
+ pointers.push(ptr);
+ }
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let (mut ptr, _size, _align) =
+ Self::build_struct(&mut args[i], structs_table)?;
+ pointers.push(&mut *ptr as *mut _ as *mut c_void);
+ _memory.push(ptr);
+ }
+ _ => return Err(FFIError::InvalidFFIType),
+ }
+ }
+ }
+ Ok(PointerArgs { pointers, _memory })
}
- fn build_struct(arg: &mut Value, structs_table: &mut HashMap) -> Result<(Box, usize, usize), FFIError> {
- unsafe {
- match arg {
- Value::Struct(ref name, ref mut struct_args) => {
- if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
- let layout = Layout::from_size_align(struct_type.ffi_type.size, struct_type.ffi_type.alignment.into()).unwrap();
- let align = struct_type.ffi_type.alignment as usize;
- let size = struct_type.ffi_type.size;
- let ptr = alloc(layout) as *mut c_void;
- let mut field_ptr = ptr;
+ fn build_struct(
+ arg: &mut Value,
+ structs_table: &mut HashMap,
+ ) -> Result<(Box, usize, usize), FFIError> {
+ unsafe {
+ match arg {
+ Value::Struct(ref name, ref mut struct_args) => {
+ if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
+ let layout = Layout::from_size_align(
+ struct_type.ffi_type.size,
+ struct_type.ffi_type.alignment.into(),
+ )
+ .unwrap();
+ let align = struct_type.ffi_type.alignment as usize;
+ let size = struct_type.ffi_type.size;
+ let ptr = alloc(layout) as *mut c_void;
+ let mut field_ptr = ptr;
- for i in 0..(struct_type.fields.len()-1) {
- macro_rules! try_write_int {
- ($type:ty) => {
- {
- field_ptr = field_ptr.add(field_ptr.align_offset(std::mem::align_of::<$type>()));
- let n: $type = <$type>::try_from(struct_args[i].as_int()?).map_err(|_| FFIError::ValueDontFit)?;
- std::ptr::write(field_ptr as *mut $type, n);
- field_ptr = field_ptr.add(std::mem::size_of::<$type>());
- }
- }
- }
+ for i in 0..(struct_type.fields.len() - 1) {
+ macro_rules! try_write_int {
+ ($type:ty) => {{
+ field_ptr = field_ptr
+ .add(field_ptr.align_offset(std::mem::align_of::<$type>()));
+ let n: $type = <$type>::try_from(struct_args[i].as_int()?)
+ .map_err(|_| FFIError::ValueDontFit)?;
+ std::ptr::write(field_ptr as *mut $type, n);
+ field_ptr = field_ptr.add(std::mem::size_of::<$type>());
+ }};
+ }
- macro_rules! write {
- ($type:ty, $value:expr) => {
- {
- let data: $type = $value;
- std::ptr::write(field_ptr as *mut $type, data);
- field_ptr = field_ptr.add(align);
- }
- }
- }
+ macro_rules! write {
+ ($type:ty, $value:expr) => {{
+ let data: $type = $value;
+ std::ptr::write(field_ptr as *mut $type, data);
+ field_ptr = field_ptr.add(align);
+ }};
+ }
- let field = struct_type.fields[i];
- match (*field).type_ as u32 {
- libffi::raw::FFI_TYPE_UINT8 => try_write_int!(u8),
- libffi::raw::FFI_TYPE_SINT8 => try_write_int!(i8),
- libffi::raw::FFI_TYPE_UINT16 => try_write_int!(u16),
- libffi::raw::FFI_TYPE_SINT16 => try_write_int!(i16),
- libffi::raw::FFI_TYPE_UINT32 => try_write_int!(u32),
- libffi::raw::FFI_TYPE_SINT32 => try_write_int!(i32),
- libffi::raw::FFI_TYPE_UINT64 => try_write_int!(u64),
- libffi::raw::FFI_TYPE_SINT64 => try_write_int!(i64),
- libffi::raw::FFI_TYPE_POINTER => write!(*mut c_void, struct_args[i].as_ptr()?),
- libffi::raw::FFI_TYPE_FLOAT => write!(f32, struct_args[i].as_float()? as f32),
- libffi::raw::FFI_TYPE_DOUBLE => write!(f64, struct_args[i].as_float()?),
- libffi::raw::FFI_TYPE_STRUCT => {
- let (struct_ptr, struct_size, struct_align) = Self::build_struct(&mut struct_args[i], structs_table)?;
- field_ptr = field_ptr.add(field_ptr.align_offset(struct_align));
-
- std::ptr::copy(& *struct_ptr as *const _ as *const c_void, field_ptr as *mut c_void, struct_size);
- field_ptr = field_ptr.add(struct_size);
- },
- _ => {
- unreachable!()
- }
- }
- }
- return Ok((Box::from_raw(ptr), size, align));
- } else {
- return Err(FFIError::InvalidStructName);
- }
- }
- _ => return Err(FFIError::ValueCast)
- }
- }
+ let field = struct_type.fields[i];
+ match (*field).type_ as u32 {
+ libffi::raw::FFI_TYPE_UINT8 => try_write_int!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => try_write_int!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => try_write_int!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => try_write_int!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => try_write_int!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => try_write_int!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => try_write_int!(u64),
+ libffi::raw::FFI_TYPE_SINT64 => try_write_int!(i64),
+ libffi::raw::FFI_TYPE_POINTER => {
+ write!(*mut c_void, struct_args[i].as_ptr()?)
+ }
+ libffi::raw::FFI_TYPE_FLOAT => {
+ write!(f32, struct_args[i].as_float()? as f32)
+ }
+ libffi::raw::FFI_TYPE_DOUBLE => {
+ write!(f64, struct_args[i].as_float()?)
+ }
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let (struct_ptr, struct_size, struct_align) =
+ Self::build_struct(&mut struct_args[i], structs_table)?;
+ field_ptr = field_ptr.add(field_ptr.align_offset(struct_align));
+
+ std::ptr::copy(
+ &*struct_ptr as *const _ as *const c_void,
+ field_ptr as *mut c_void,
+ struct_size,
+ );
+ field_ptr = field_ptr.add(struct_size);
+ }
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+ return Ok((Box::from_raw(ptr), size, align));
+ } else {
+ return Err(FFIError::InvalidStructName);
+ }
+ }
+ _ => return Err(FFIError::ValueCast),
+ }
+ }
}
pub fn exec(&mut self, name: &str, mut args: Vec) -> Result {
- let function_impl = self.table.get_mut(name).ok_or(FFIError::FunctionNotFound)?;
- let mut pointer_args = Self::build_pointer_args(&mut args, &function_impl.args, &mut self.structs)?;
-
- return unsafe {
- macro_rules! call_and_return {
- ($type:ty) => {
- {
- let mut n: Box = Box::new(0);
- libffi::raw::ffi_call(
- &mut function_impl.cif,
- Some(*function_impl.code_ptr.as_safe_fun()),
- &mut *n as *mut _ as *mut c_void,
- pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
- );
- Ok(Value::Int(i64::from(*n)))
- }
- }
- }
-
- match (*function_impl.cif.rtype).type_ as u32 {
- libffi::raw::FFI_TYPE_VOID => call_and_return!(i32),
- libffi::raw::FFI_TYPE_UINT8 => call_and_return!(u8),
- libffi::raw::FFI_TYPE_SINT8 => call_and_return!(i8),
- libffi::raw::FFI_TYPE_UINT16 => call_and_return!(u16),
- libffi::raw::FFI_TYPE_SINT16 => call_and_return!(i16),
- libffi::raw::FFI_TYPE_UINT32 => call_and_return!(u32),
- libffi::raw::FFI_TYPE_SINT32 => call_and_return!(i32),
- libffi::raw::FFI_TYPE_UINT64 => {
- let mut n: Box = Box::new(0);
- libffi::raw::ffi_call(
- &mut function_impl.cif,
- Some(*function_impl.code_ptr.as_safe_fun()),
- &mut *n as *mut _ as *mut c_void,
- pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
- );
- Ok(Value::Int(i64::try_from(*n).map_err(|_| FFIError::ValueDontFit)?))
- },
- libffi::raw::FFI_TYPE_SINT64 => call_and_return!(i64),
- libffi::raw::FFI_TYPE_POINTER => call_and_return!(*mut c_void),
- libffi::raw::FFI_TYPE_FLOAT => {
- let mut n: Box = Box::new(0.0);
- libffi::raw::ffi_call(
- &mut function_impl.cif,
- Some(*function_impl.code_ptr.as_safe_fun()),
- &mut *n as *mut _ as *mut c_void,
- pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
- );
- Ok(Value::Float((*n).into()))
- },
- libffi::raw::FFI_TYPE_DOUBLE => {
- let mut n: Box = Box::new(0.0);
- libffi::raw::ffi_call(
- &mut function_impl.cif,
- Some(*function_impl.code_ptr.as_safe_fun()),
- &mut *n as *mut _ as *mut c_void,
- pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
- );
- Ok(Value::Float(*n))
- },
- libffi::raw::FFI_TYPE_STRUCT => {
- let name = &function_impl.return_struct_name.clone().ok_or(FFIError::StructNotFound)?;
- let struct_type = self.structs.get(name).ok_or(FFIError::StructNotFound)?;
- let layout = Layout::from_size_align(struct_type.ffi_type.size, struct_type.ffi_type.alignment.into()).unwrap();
- let ptr = alloc(layout) as *mut c_void;
+ let function_impl = self.table.get_mut(name).ok_or(FFIError::FunctionNotFound)?;
+ let mut pointer_args =
+ Self::build_pointer_args(&mut args, &function_impl.args, &mut self.structs)?;
- libffi::raw::ffi_call(
- &mut function_impl.cif,
- Some(*function_impl.code_ptr.as_safe_fun()),
- &mut *ptr as *mut _ as *mut c_void,
- pointer_args.pointers.as_mut_ptr() as *mut *mut c_void
- );
- let struct_val = self.read_struct(ptr, name, struct_type);
- drop(Box::from_raw(ptr));
- struct_val
- }
- _ => unreachable!()
- }
- };
+ return unsafe {
+ macro_rules! call_and_return {
+ ($type:ty) => {{
+ let mut n: Box = Box::new(0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
+ );
+ Ok(Value::Int(i64::from(*n)))
+ }};
+ }
+
+ match (*function_impl.cif.rtype).type_ as u32 {
+ libffi::raw::FFI_TYPE_VOID => call_and_return!(i32),
+ libffi::raw::FFI_TYPE_UINT8 => call_and_return!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => call_and_return!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => call_and_return!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => call_and_return!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => call_and_return!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => call_and_return!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => {
+ let mut n: Box = Box::new(0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
+ );
+ Ok(Value::Int(
+ i64::try_from(*n).map_err(|_| FFIError::ValueDontFit)?,
+ ))
+ }
+ libffi::raw::FFI_TYPE_SINT64 => call_and_return!(i64),
+ libffi::raw::FFI_TYPE_POINTER => call_and_return!(*mut c_void),
+ libffi::raw::FFI_TYPE_FLOAT => {
+ let mut n: Box = Box::new(0.0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
+ );
+ Ok(Value::Float((*n).into()))
+ }
+ libffi::raw::FFI_TYPE_DOUBLE => {
+ let mut n: Box = Box::new(0.0);
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *n as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
+ );
+ Ok(Value::Float(*n))
+ }
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let name = &function_impl
+ .return_struct_name
+ .clone()
+ .ok_or(FFIError::StructNotFound)?;
+ let struct_type = self.structs.get(name).ok_or(FFIError::StructNotFound)?;
+ let layout = Layout::from_size_align(
+ struct_type.ffi_type.size,
+ struct_type.ffi_type.alignment.into(),
+ )
+ .unwrap();
+ let ptr = alloc(layout) as *mut c_void;
+
+ libffi::raw::ffi_call(
+ &mut function_impl.cif,
+ Some(*function_impl.code_ptr.as_safe_fun()),
+ &mut *ptr as *mut _ as *mut c_void,
+ pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
+ );
+ let struct_val = self.read_struct(ptr, name, struct_type);
+ drop(Box::from_raw(ptr));
+ struct_val
+ }
+ _ => unreachable!(),
+ }
+ };
}
- fn read_struct(&self, ptr: *mut c_void, name: &str, struct_type: &StructImpl) -> Result {
- unsafe {
- let mut returns = Vec::new();
- let mut field_ptr = ptr;
+ fn read_struct(
+ &self,
+ ptr: *mut c_void,
+ name: &str,
+ struct_type: &StructImpl,
+ ) -> Result {
+ unsafe {
+ let mut returns = Vec::new();
+ let mut field_ptr = ptr;
- for i in 0..(struct_type.fields.len()-1) {
- let field = struct_type.fields[i];
+ for i in 0..(struct_type.fields.len() - 1) {
+ let field = struct_type.fields[i];
- macro_rules! read_and_push_int {
- ($type:ty) => {
- {
- field_ptr = field_ptr.add(field_ptr.align_offset(std::mem::align_of::<$type>()));
- let n = std::ptr::read(field_ptr as *mut $type);
- returns.push(Value::Int(i64::from(n)));
- field_ptr = field_ptr.add(std::mem::size_of::<$type>());
- }
- }
- }
+ macro_rules! read_and_push_int {
+ ($type:ty) => {{
+ field_ptr =
+ field_ptr.add(field_ptr.align_offset(std::mem::align_of::<$type>()));
+ let n = std::ptr::read(field_ptr as *mut $type);
+ returns.push(Value::Int(i64::from(n)));
+ field_ptr = field_ptr.add(std::mem::size_of::<$type>());
+ }};
+ }
- match (*field).type_ as u32 {
- libffi::raw::FFI_TYPE_UINT8 => read_and_push_int!(u8),
- libffi::raw::FFI_TYPE_SINT8 => read_and_push_int!(i8),
- libffi::raw::FFI_TYPE_UINT16 => read_and_push_int!(u16),
- libffi::raw::FFI_TYPE_SINT16 => read_and_push_int!(i16),
- libffi::raw::FFI_TYPE_UINT32 => read_and_push_int!(u32),
- libffi::raw::FFI_TYPE_SINT32 => read_and_push_int!(i32),
- libffi::raw::FFI_TYPE_UINT64 => {
- field_ptr = field_ptr.add(field_ptr.align_offset(std::mem::align_of::()));
- let n = std::ptr::read(field_ptr as *mut u64);
- returns.push(Value::Int(i64::try_from(n).map_err(|_| FFIError::ValueDontFit)?));
- field_ptr = field_ptr.add(std::mem::size_of::());
- },
- libffi::raw::FFI_TYPE_SINT64 => read_and_push_int!(i64),
- libffi::raw::FFI_TYPE_POINTER => read_and_push_int!(i64),
- libffi::raw::FFI_TYPE_STRUCT => {
- let substruct = struct_type.atom_fields[i].as_str();
- let struct_type = self.structs.get(substruct).ok_or(FFIError::StructNotFound)?;
- field_ptr = field_ptr.add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
- let struct_val = self.read_struct(field_ptr, substruct, struct_type);
- returns.push(struct_val?);
- field_ptr = field_ptr.add(struct_type.ffi_type.size);
- },
- _ => {
- unreachable!()
- }
- }
- }
- Ok(Value::Struct(name.into(), returns))
- }
+ match (*field).type_ as u32 {
+ libffi::raw::FFI_TYPE_UINT8 => read_and_push_int!(u8),
+ libffi::raw::FFI_TYPE_SINT8 => read_and_push_int!(i8),
+ libffi::raw::FFI_TYPE_UINT16 => read_and_push_int!(u16),
+ libffi::raw::FFI_TYPE_SINT16 => read_and_push_int!(i16),
+ libffi::raw::FFI_TYPE_UINT32 => read_and_push_int!(u32),
+ libffi::raw::FFI_TYPE_SINT32 => read_and_push_int!(i32),
+ libffi::raw::FFI_TYPE_UINT64 => {
+ field_ptr =
+ field_ptr.add(field_ptr.align_offset(std::mem::align_of::()));
+ let n = std::ptr::read(field_ptr as *mut u64);
+ returns.push(Value::Int(
+ i64::try_from(n).map_err(|_| FFIError::ValueDontFit)?,
+ ));
+ field_ptr = field_ptr.add(std::mem::size_of::());
+ }
+ libffi::raw::FFI_TYPE_SINT64 => read_and_push_int!(i64),
+ libffi::raw::FFI_TYPE_POINTER => read_and_push_int!(i64),
+ libffi::raw::FFI_TYPE_STRUCT => {
+ let substruct = struct_type.atom_fields[i].as_str();
+ let struct_type = self
+ .structs
+ .get(&*substruct)
+ .ok_or(FFIError::StructNotFound)?;
+ field_ptr = field_ptr
+ .add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
+ let struct_val = self.read_struct(field_ptr, &*substruct, struct_type);
+ returns.push(struct_val?);
+ field_ptr = field_ptr.add(struct_type.ffi_type.size);
+ }
+ _ => {
+ unreachable!()
+ }
+ }
+ }
+ Ok(Value::Struct(name.into(), returns))
+ }
}
}
@@ -410,26 +465,26 @@ pub enum Value {
impl Value {
fn as_int(&self) -> Result {
- match self {
- Value::Int(n) => Ok(*n),
- _ => Err(FFIError::ValueCast),
- }
+ match self {
+ Value::Int(n) => Ok(*n),
+ _ => Err(FFIError::ValueCast),
+ }
}
fn as_float(&self) -> Result {
- match self {
- Value::Float(n) => Ok(*n),
- Value::Int(n) => Ok(*n as f64),
- _ => Err(FFIError::ValueCast),
- }
+ match self {
+ Value::Float(n) => Ok(*n),
+ Value::Int(n) => Ok(*n as f64),
+ _ => Err(FFIError::ValueCast),
+ }
}
fn as_ptr(&mut self) -> Result<*mut c_void, FFIError> {
- match self {
- Value::CString(ref mut cstr) => Ok(&mut *cstr as *mut _ as *mut c_void),
- Value::Int(n) => Ok(*n as *mut c_void),
- _ => Err(FFIError::ValueCast)
- }
+ match self {
+ Value::CString(ref mut cstr) => Ok(&mut *cstr as *mut _ as *mut c_void),
+ Value::Int(n) => Ok(*n as *mut c_void),
+ _ => Err(FFIError::ValueCast),
+ }
}
}
diff --git a/src/forms.rs b/src/forms.rs
index fd9c1e28..9280e535 100644
--- a/src/forms.rs
+++ b/src/forms.rs
@@ -7,8 +7,8 @@ use crate::machine::loader::PredicateQueue;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::parser::ast::*;
-use crate::parser::parser::CompositeOpDesc;
use crate::parser::dashu::{Integer, Rational};
+use crate::parser::parser::CompositeOpDesc;
use crate::types::*;
use fxhash::FxBuildHasher;
@@ -58,7 +58,7 @@ impl AppendOrPrepend {
#[derive(Debug, Clone, Copy)]
pub enum VarComparison {
Indistinct,
- Distinct
+ Distinct,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -153,11 +153,14 @@ impl DerefMut for ChunkedTermVec {
impl ChunkedTermVec {
#[inline]
pub fn new() -> Self {
- Self { chunk_vec: VecDeque::new() }
+ Self {
+ chunk_vec: VecDeque::new(),
+ }
}
pub fn reserve_branch(&mut self, capacity: usize) {
- self.chunk_vec.push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity)));
+ self.chunk_vec
+ .push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity)));
}
pub fn push_branch_arm(&mut self, branch: VecDeque) {
@@ -173,19 +176,22 @@ impl ChunkedTermVec {
#[inline]
pub fn add_chunk(&mut self) {
- self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![])));
+ self.chunk_vec
+ .push_back(ChunkedTerms::Chunk(VecDeque::from(vec![])));
}
pub fn push_chunk_term(&mut self, term: QueryTerm) {
match self.chunk_vec.back_mut() {
Some(ChunkedTerms::Branch(_)) => {
- self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term])));
+ self.chunk_vec
+ .push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term])));
}
Some(ChunkedTerms::Chunk(chunk)) => {
chunk.push_back(term);
}
None => {
- self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term])));
+ self.chunk_vec
+ .push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term])));
}
}
}
@@ -196,7 +202,7 @@ pub enum QueryTerm {
// register, clause type, subterms, clause call policy.
Clause(Cell, ClauseType, Vec, CallPolicy),
Fail,
- LocalCut(usize), // var_num
+ LocalCut(usize), // var_num
GlobalCut(usize), // var_num
GetCutPoint { var_num: usize, prev_b: bool },
GetLevel(usize), // var_num
@@ -266,11 +272,10 @@ impl ClauseInfo for Term {
fn name(&self) -> Option {
match self {
Term::Clause(_, name, terms) => {
-
match name {
atom!(":-") => {
match terms.len() {
- 1 => None, // a declaration.
+ 1 => None, // a declaration.
2 => terms[0].name(),
_ => Some(*name),
}
@@ -285,7 +290,7 @@ impl ClauseInfo for Term {
fn arity(&self) -> usize {
match self {
- Term::Clause(_, name, terms) => match name.as_str() {
+ Term::Clause(_, name, terms) => match &*name.as_str() {
":-" => match terms.len() {
1 => 0,
2 => terms[0].arity(),
@@ -410,7 +415,6 @@ pub(crate) fn fixity(spec: u32) -> Fixity {
}
}
-
impl OpDecl {
#[inline]
pub(crate) fn new(op_desc: OpDesc, name: Atom) -> Self {
@@ -477,35 +481,27 @@ pub enum AtomOrString {
impl AtomOrString {
#[inline]
- pub fn as_atom(&self, atom_tbl: &mut AtomTable) -> Atom {
+ pub fn as_atom(&self, atom_tbl: &AtomTable) -> Atom {
match self {
- &AtomOrString::Atom(atom) => {
- atom
- }
- AtomOrString::String(string) => {
- atom_tbl.build_with(&string)
- }
+ &AtomOrString::Atom(atom) => atom,
+ AtomOrString::String(string) => AtomTable::build_with(atom_tbl, &string),
}
}
#[inline]
- pub fn as_str(&self) -> &str {
+ pub fn as_str(&self) -> AtomString<'_> {
match self {
- AtomOrString::Atom(atom) if atom == &atom!("[]") => "",
+ AtomOrString::Atom(atom) if atom == &atom!("[]") => AtomString::Static(""),
AtomOrString::Atom(atom) => atom.as_str(),
- AtomOrString::String(string) => string.as_str(),
+ AtomOrString::String(string) => AtomString::Static(string.as_str()),
}
}
#[inline]
pub fn to_string(self) -> String {
match self {
- AtomOrString::Atom(atom) => {
- atom.as_str().to_owned()
- }
- AtomOrString::String(string) => {
- string
- }
+ AtomOrString::Atom(atom) => atom.as_str().to_owned(),
+ AtomOrString::String(string) => string,
}
}
}
@@ -561,9 +557,7 @@ pub(crate) fn fetch_op_spec(name: Atom, arity: usize, op_dir: &OpDir) -> Option<
}
})
}
- 0 => {
- fetch_atom_op_spec(name, None, op_dir)
- }
+ 0 => fetch_atom_op_spec(name, None, op_dir),
_ => None,
}
}
@@ -595,10 +589,7 @@ pub struct Module {
// Module's and related types are defined in forms.
impl Module {
- pub(crate) fn new(
- module_decl: ModuleDecl,
- listing_src: ListingSource,
- ) -> Self {
+ pub(crate) fn new(module_decl: ModuleDecl, listing_src: ListingSource) -> Self {
Module {
module_decl,
code_dir: CodeDir::with_hasher(FxBuildHasher::default()),
@@ -620,7 +611,7 @@ impl Module {
meta_predicates: MetaPredicateDir::with_hasher(FxBuildHasher::default()),
extensible_predicates: ExtensiblePredicates::with_hasher(FxBuildHasher::default()),
local_extensible_predicates: LocalExtensiblePredicates::with_hasher(
- FxBuildHasher::default()
+ FxBuildHasher::default(),
),
listing_src: ListingSource::DynamicallyGenerated,
}
@@ -923,8 +914,10 @@ impl PredicateInfo {
#[inline]
pub(crate) fn must_retract_local_clauses(&self, is_cross_module_clause: bool) -> bool {
- self.is_extensible && self.has_clauses && !self.is_discontiguous &&
- !(self.is_multifile && is_cross_module_clause)
+ self.is_extensible
+ && self.has_clauses
+ && !self.is_discontiguous
+ && !(self.is_multifile && is_cross_module_clause)
}
}
@@ -1013,19 +1006,17 @@ impl PredicateSkeleton {
&mut self,
clause_clause_loc: usize,
) -> Option {
- let search_result = self.core.clause_clause_locs
- .make_contiguous()[0..self.core.clause_assert_margin]
+ let search_result = self.core.clause_clause_locs.make_contiguous()
+ [0..self.core.clause_assert_margin]
.binary_search_by(|loc| clause_clause_loc.cmp(&loc));
match search_result {
Ok(loc) => Some(loc),
- Err(_) => {
- self.core.clause_clause_locs
- .make_contiguous()[self.core.clause_assert_margin..]
- .binary_search_by(|loc| loc.cmp(&clause_clause_loc))
- .map(|loc| loc + self.core.clause_assert_margin)
- .ok()
- }
+ Err(_) => self.core.clause_clause_locs.make_contiguous()
+ [self.core.clause_assert_margin..]
+ .binary_search_by(|loc| loc.cmp(&clause_clause_loc))
+ .map(|loc| loc + self.core.clause_assert_margin)
+ .ok(),
}
}
}
diff --git a/src/heap_iter.rs b/src/heap_iter.rs
index c20840b7..fc5d3416 100644
--- a/src/heap_iter.rs
+++ b/src/heap_iter.rs
@@ -73,12 +73,8 @@ impl IterStackLoc {
#[inline]
pub fn as_ref(self) -> Ref {
match self.heap_or_stack() {
- HeapOrStackTag::Heap => {
- Ref::heap_cell(self.value() as usize)
- }
- HeapOrStackTag::Stack => {
- Ref::stack_cell(self.value() as usize)
- }
+ HeapOrStackTag::Heap => Ref::heap_cell(self.value() as usize),
+ HeapOrStackTag::Stack => Ref::stack_cell(self.value() as usize),
}
}
}
@@ -158,24 +154,16 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
#[inline]
pub fn read_cell_mut(&mut self, loc: IterStackLoc) -> &mut HeapCellValue {
match loc.heap_or_stack() {
- HeapOrStackTag::Heap => {
- &mut self.heap[loc.value() as usize]
- }
- HeapOrStackTag::Stack => {
- &mut self.machine_stack[loc.value() as usize]
- }
+ HeapOrStackTag::Heap => &mut self.heap[loc.value() as usize],
+ HeapOrStackTag::Stack => &mut self.machine_stack[loc.value() as usize],
}
}
#[inline]
pub fn read_cell(&self, loc: IterStackLoc) -> HeapCellValue {
match loc.heap_or_stack() {
- HeapOrStackTag::Heap => {
- self.heap[loc.value() as usize]
- }
- HeapOrStackTag::Stack => {
- self.machine_stack[loc.value() as usize]
- }
+ HeapOrStackTag::Heap => self.heap[loc.value() as usize],
+ HeapOrStackTag::Stack => self.machine_stack[loc.value() as usize],
}
}
@@ -228,7 +216,10 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
if !cell.get_mark_bit() {
cell.set_mark_bit(true);
- self.stack.push(IterStackLoc::iterable_loc(loc.value() as usize, loc.heap_or_stack()));
+ self.stack.push(IterStackLoc::iterable_loc(
+ loc.value() as usize,
+ loc.heap_or_stack(),
+ ));
}
}
@@ -236,7 +227,10 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
while let Some(h) = self.stack.pop() {
if h.is_pending_mark() {
self.push_if_unmarked(h);
- self.stack.push(IterStackLoc::mark_loc(h.value() as usize, h.heap_or_stack()));
+ self.stack.push(IterStackLoc::mark_loc(
+ h.value() as usize,
+ h.heap_or_stack(),
+ ));
self.forward_if_referent_marked(h);
continue;
@@ -467,7 +461,7 @@ impl<'a> LeftistPostOrderHeapIter<'a> {
#[inline]
pub fn pop_stack(&mut self) {
if let Some((child_count, ..)) = self.parent_stack.last() {
- for _ in 0 .. *child_count {
+ for _ in 0..*child_count {
self.base_iter.pop_stack();
}
@@ -508,7 +502,6 @@ mod tests {
use super::*;
use crate::machine::mock_wam::*;
-
#[test]
fn heap_stackless_iter_tests() {
let mut wam = MockWAM::new();
@@ -518,8 +511,8 @@ mod tests {
let b_atom = atom!("b");
wam.machine_st
- .heap
- .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
+ .heap
+ .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
@@ -629,12 +622,12 @@ mod tests {
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(0),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), heap_loc_as_cell!(0));
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ heap_loc_as_cell!(0)
+ );
assert_eq!(iter.next(), None);
}
@@ -650,10 +643,7 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(0),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -688,10 +678,7 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(0));
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(0),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -721,7 +708,8 @@ mod tests {
// first a 'dangling' partial string, later modified to be a two-part complete string,
// then a three-part cyclic string involving an uncompacted list of chars.
- let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &mut wam.machine_st.atom_tbl);
+ let pstr_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
@@ -742,11 +730,8 @@ mod tests {
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
- let pstr_second_var_cell = put_partial_string(
- &mut wam.machine_st.heap,
- "def",
- &mut wam.machine_st.atom_tbl,
- );
+ let pstr_second_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "def", &wam.machine_st.atom_tbl);
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
@@ -771,13 +756,12 @@ mod tests {
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(4));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(2)));
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- pstr_loc_as_cell!(4),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(4));
let pstr_offset_cell = pstr_offset_as_cell!(0);
@@ -789,19 +773,35 @@ mod tests {
}
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ pstr_loc_as_cell!(2)
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ pstr_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ pstr_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
wam.machine_st.heap.truncate(4);
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
+ wam.machine_st
+ .heap
+ .push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
@@ -819,7 +819,9 @@ mod tests {
all_cells_unmarked(&wam.machine_st.heap);
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
@@ -827,8 +829,14 @@ mod tests {
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
assert_eq!(iter.next(), None);
@@ -1059,10 +1067,22 @@ mod tests {
all_cells_unmarked(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), heap_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), heap_loc_as_cell!(3));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ heap_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ heap_loc_as_cell!(2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ heap_loc_as_cell!(3)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ heap_loc_as_cell!(3)
+ );
wam.machine_st.heap.clear();
@@ -1089,9 +1109,18 @@ mod tests {
all_cells_unmarked(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), list_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(1));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ list_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ list_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ list_loc_as_cell!(1)
+ );
wam.machine_st.heap.clear();
@@ -1202,37 +1231,109 @@ mod tests {
assert_eq!(iter.next(), None);
}
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), list_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), str_loc_as_cell!(6));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), heap_loc_as_cell!(8));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(f_atom, 1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), heap_loc_as_cell!(11));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), list_loc_as_cell!(9));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), heap_loc_as_cell!(9));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[10]), empty_list_as_cell!());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[11]), attr_var_as_cell!(11));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[12]), heap_loc_as_cell!(13));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[13]), list_loc_as_cell!(14));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[14]), str_loc_as_cell!(16));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[15]), heap_loc_as_cell!(19));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[16]), atom_as_cell!(clpz_atom, 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[17]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[18]), atom_as_cell!(b_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[19]), list_loc_as_cell!(20));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[20]), str_loc_as_cell!(22));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[21]), empty_list_as_cell!());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[22]), atom_as_cell!(p_atom, 1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[23]), heap_loc_as_cell!(23));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ list_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ heap_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ heap_loc_as_cell!(3)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ list_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ str_loc_as_cell!(6)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ heap_loc_as_cell!(8)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ atom_as_cell!(f_atom, 1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ heap_loc_as_cell!(11)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ list_loc_as_cell!(9)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[9]),
+ heap_loc_as_cell!(9)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[10]),
+ empty_list_as_cell!()
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[11]),
+ attr_var_as_cell!(11)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[12]),
+ heap_loc_as_cell!(13)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[13]),
+ list_loc_as_cell!(14)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[14]),
+ str_loc_as_cell!(16)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[15]),
+ heap_loc_as_cell!(19)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[16]),
+ atom_as_cell!(clpz_atom, 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[17]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[18]),
+ atom_as_cell!(b_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[19]),
+ list_loc_as_cell!(20)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[20]),
+ str_loc_as_cell!(22)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[21]),
+ empty_list_as_cell!()
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[22]),
+ atom_as_cell!(p_atom, 1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[23]),
+ heap_loc_as_cell!(23)
+ );
wam.machine_st.heap.clear();
{
let mut iter = stackless_preorder_iter(
&mut wam.machine_st.heap,
- fixnum_as_cell!(Fixnum::build_with(0))
+ fixnum_as_cell!(Fixnum::build_with(0)),
);
assert_eq!(
@@ -1251,19 +1352,16 @@ mod tests {
wam.machine_st.heap.push(str_loc_as_cell!(1));
- wam.machine_st.heap.push(atom_as_cell!(atom!("g"),2));
+ wam.machine_st.heap.push(atom_as_cell!(atom!("g"), 2));
wam.machine_st.heap.push(heap_loc_as_cell!(0));
wam.machine_st.heap.push(atom_as_cell!(atom!("y")));
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- str_loc_as_cell!(1),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, str_loc_as_cell!(1));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
- atom_as_cell!(atom!("g"),2)
+ atom_as_cell!(atom!("g"), 2)
);
assert_eq!(
@@ -1271,10 +1369,7 @@ mod tests {
atom_as_cell!(atom!("y"))
);
- assert_eq!(
- unmark_cell_bits!(iter.next().unwrap()),
- str_loc_as_cell!(1)
- );
+ assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(1));
assert!(iter.next().is_none());
}
@@ -1283,19 +1378,16 @@ mod tests {
wam.machine_st.heap.clear();
- wam.machine_st.heap.push(atom_as_cell!(atom!("g"),2));
+ wam.machine_st.heap.push(atom_as_cell!(atom!("g"), 2));
wam.machine_st.heap.push(str_loc_as_cell!(0));
wam.machine_st.heap.push(atom_as_cell!(atom!("y")));
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- str_loc_as_cell!(0),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
- atom_as_cell!(atom!("g"),2)
+ atom_as_cell!(atom!("g"), 2)
);
assert_eq!(
@@ -1303,10 +1395,7 @@ mod tests {
atom_as_cell!(atom!("y"))
);
- assert_eq!(
- unmark_cell_bits!(iter.next().unwrap()),
- str_loc_as_cell!(0)
- );
+ assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
assert!(iter.next().is_none());
}
@@ -1327,10 +1416,7 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(7),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(7));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1390,10 +1476,7 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1));
{
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- str_loc_as_cell!(0),
- );
+ let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -1420,38 +1503,38 @@ mod tests {
wam.machine_st.heap.clear();
// representation of one of the heap terms as in issue #1384.
-/*
- wam.machine_st.heap.push(list_loc_as_cell!(7));
- wam.machine_st.heap.push(heap_loc_as_cell!(0));
- wam.machine_st.heap.push(list_loc_as_cell!(3));
- wam.machine_st.heap.push(list_loc_as_cell!(5));
- wam.machine_st.heap.push(empty_list_as_cell!());
- wam.machine_st.heap.push(heap_loc_as_cell!(2));
- wam.machine_st.heap.push(heap_loc_as_cell!(2));
- wam.machine_st.heap.push(empty_list_as_cell!());
- wam.machine_st.heap.push(heap_loc_as_cell!(3));
+ /*
+ wam.machine_st.heap.push(list_loc_as_cell!(7));
+ wam.machine_st.heap.push(heap_loc_as_cell!(0));
+ wam.machine_st.heap.push(list_loc_as_cell!(3));
+ wam.machine_st.heap.push(list_loc_as_cell!(5));
+ wam.machine_st.heap.push(empty_list_as_cell!());
+ wam.machine_st.heap.push(heap_loc_as_cell!(2));
+ wam.machine_st.heap.push(heap_loc_as_cell!(2));
+ wam.machine_st.heap.push(empty_list_as_cell!());
+ wam.machine_st.heap.push(heap_loc_as_cell!(3));
- {
- let mut iter = stackless_preorder_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(0),
- );
+ {
+ let mut iter = stackless_preorder_iter(
+ &mut wam.machine_st.heap,
+ heap_loc_as_cell!(0),
+ );
- while let Some(_) = iter.next() {
- print_heap_terms(iter.heap.iter(), 0);
- println!("");
- }
+ while let Some(_) = iter.next() {
+ print_heap_terms(iter.heap.iter(), 0);
+ println!("");
+ }
- /*
- assert_eq!(
- unmark_cell_bits!(iter.next().unwrap()),
- atom_as_cell!(atom!("f"), 2)
- );
+ /*
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ atom_as_cell!(atom!("f"), 2)
+ );
- assert!(iter.next().is_none());
- */
- }
-*/
+ assert!(iter.next().is_none());
+ */
+ }
+ */
}
#[test]
@@ -1462,7 +1545,8 @@ mod tests {
let a_atom = atom!("a");
let b_atom = atom!("b");
- wam.machine_st.heap
+ wam.machine_st
+ .heap
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
@@ -1686,7 +1770,8 @@ mod tests {
// two-part complete string, then a three-part cyclic string
// involving an uncompacted list of chars.
- let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &mut wam.machine_st.atom_tbl);
+ let pstr_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
@@ -1710,7 +1795,8 @@ mod tests {
wam.machine_st.heap.pop();
wam.machine_st.heap.push(heap_loc_as_cell!(2));
- let pstr_second_var_cell = put_partial_string(&mut wam.machine_st.heap, "def", &mut wam.machine_st.atom_tbl);
+ let pstr_second_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "def", &wam.machine_st.atom_tbl);
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
@@ -1731,10 +1817,14 @@ mod tests {
}
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
+ wam.machine_st
+ .heap
+ .push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
let mut iter = stackful_preorder_iter(
@@ -1750,7 +1840,10 @@ mod tests {
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
- assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64)));
+ assert_eq!(
+ iter.next().unwrap(),
+ fixnum_as_cell!(Fixnum::build_with(0i64))
+ );
assert_eq!(iter.next(), None);
}
@@ -1764,7 +1857,9 @@ mod tests {
*/
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
let mut iter = stackful_preorder_iter(
@@ -1781,13 +1876,19 @@ mod tests {
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
- assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1i64)));
+ assert_eq!(
+ iter.next().unwrap(),
+ fixnum_as_cell!(Fixnum::build_with(1i64))
+ );
let h = iter.focus();
assert_eq!(h.value(), 5);
assert_eq!(unmark_cell_bits!(iter.heap[4]), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(iter.heap[5]), fixnum_as_cell!(Fixnum::build_with(1i64)));
+ assert_eq!(
+ unmark_cell_bits!(iter.heap[5]),
+ fixnum_as_cell!(Fixnum::build_with(1i64))
+ );
assert_eq!(iter.next(), None);
}
@@ -1980,10 +2081,7 @@ mod tests {
pstr_as_cell!(atom!("a string"))
);
- assert_eq!(
- iter.next().unwrap(),
- empty_list_as_cell!()
- );
+ assert_eq!(iter.next().unwrap(), empty_list_as_cell!());
assert_eq!(iter.next(), None);
}
@@ -2037,7 +2135,8 @@ mod tests {
let a_atom = atom!("a");
let b_atom = atom!("b");
- wam.machine_st.heap
+ wam.machine_st
+ .heap
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
@@ -2075,7 +2174,8 @@ mod tests {
]
));
- for _ in 0..20 { // 0000 {
+ for _ in 0..20 {
+ // 0000 {
let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
@@ -2263,7 +2363,8 @@ mod tests {
// two-part complete string, then a three-part cyclic string
// involving an uncompacted list of chars.
- let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &mut wam.machine_st.atom_tbl);
+ let pstr_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
@@ -2286,7 +2387,8 @@ mod tests {
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
- let pstr_second_var_cell = put_partial_string(&mut wam.machine_st.heap, "def", &mut wam.machine_st.atom_tbl);
+ let pstr_second_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "def", &wam.machine_st.atom_tbl);
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
@@ -2307,10 +2409,14 @@ mod tests {
}
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
+ wam.machine_st
+ .heap
+ .push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
let mut iter = stackful_post_order_iter(
@@ -2319,8 +2425,14 @@ mod tests {
pstr_loc_as_cell!(0),
);
- assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64)));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
+ assert_eq!(
+ iter.next().unwrap(),
+ fixnum_as_cell!(Fixnum::build_with(0i64))
+ );
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
@@ -2329,7 +2441,9 @@ mod tests {
}
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{
let mut iter = stackful_post_order_iter(
@@ -2338,8 +2452,14 @@ mod tests {
pstr_loc_as_cell!(0),
);
- assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1i64)));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
+ assert_eq!(
+ iter.next().unwrap(),
+ fixnum_as_cell!(Fixnum::build_with(1i64))
+ );
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
@@ -2498,13 +2618,12 @@ mod tests {
let a_atom = atom!("a");
let b_atom = atom!("b");
- wam.machine_st.heap.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
+ wam.machine_st
+ .heap
+ .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
- let mut iter = stackless_post_order_iter(
- &mut wam.machine_st.heap,
- str_loc_as_cell!(0),
- );
+ let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2535,10 +2654,7 @@ mod tests {
));
for _ in 0..20 {
- let mut iter = stackless_post_order_iter(
- &mut wam.machine_st.heap,
- str_loc_as_cell!(0),
- );
+ let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0));
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
@@ -2568,10 +2684,8 @@ mod tests {
{
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackless_post_order_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(0),
- );
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2587,10 +2701,8 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0));
- let mut iter = stackless_post_order_iter(
- &mut wam.machine_st.heap,
- heap_loc_as_cell!(0),
- );
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2615,7 +2727,8 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!());
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2647,7 +2760,8 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(0));
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
// the cycle will be iterated twice before being detected.
assert_eq!(
@@ -2675,7 +2789,8 @@ mod tests {
}
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
// cut the iteration short to check that all cells are
// unmarked and unforwarded by the Drop instance of
@@ -2705,11 +2820,13 @@ mod tests {
// two-part complete string, then a three-part cyclic string
// involving an uncompacted list of chars.
- let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &mut wam.machine_st.atom_tbl);
+ let pstr_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2724,16 +2841,14 @@ mod tests {
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
- let pstr_second_var_cell = put_partial_string(
- &mut wam.machine_st.heap,
- "def",
- &mut wam.machine_st.atom_tbl,
- );
+ let pstr_second_var_cell =
+ put_partial_string(&mut wam.machine_st.heap, "def", &wam.machine_st.atom_tbl);
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2749,20 +2864,31 @@ mod tests {
all_cells_unmarked(&wam.machine_st.heap);
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
+ wam.machine_st
+ .heap
+ .push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(0)));
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
let mut pstr_loc_cell = pstr_loc_as_cell!(0);
pstr_loc_cell.set_forwarding_bit(true);
// assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64)));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
@@ -2773,14 +2899,23 @@ mod tests {
all_cells_unmarked(&wam.machine_st.heap);
wam.machine_st.heap.pop();
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(1)));
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
//assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1)));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(iter.next().unwrap()),
+ pstr_offset_as_cell!(0)
+ );
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
@@ -2801,7 +2936,8 @@ mod tests {
wam.machine_st.heap.extend(functor);
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
@@ -2861,7 +2997,8 @@ mod tests {
wam.machine_st.heap[4] = list_loc_as_cell!(1);
{
- let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
+ let mut iter =
+ stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
assert_eq!(
unmark_cell_bits!(iter.next().unwrap()),
diff --git a/src/heap_print.rs b/src/heap_print.rs
index 8be39076..01be59d6 100644
--- a/src/heap_print.rs
+++ b/src/heap_print.rs
@@ -29,6 +29,7 @@ use std::convert::TryFrom;
use std::iter::once;
use std::net::{IpAddr, TcpListener};
use std::rc::Rc;
+use std::sync::Arc;
/* contains the location, name, precision and Specifier of the parent op. */
#[derive(Debug, Copy, Clone)]
@@ -46,7 +47,7 @@ impl DirectedOp {
}
#[inline]
- fn is_prefix(&self )-> bool {
+ fn is_prefix(&self) -> bool {
match self {
&DirectedOp::Left(_name, cell) | &DirectedOp::Right(_name, cell) => {
is_prefix!(cell.get_spec() as u32)
@@ -74,7 +75,7 @@ fn needs_bracketing(child_desc: OpDesc, op: &DirectedOp) -> bool {
DirectedOp::Left(name, cell) => {
let (priority, spec) = cell.get();
- if name.as_str() == "-" {
+ if &*name.as_str() == "-" {
let child_assoc = child_desc.get_spec();
if is_prefix!(spec) && (is_postfix!(child_assoc) || is_infix!(child_assoc)) {
return true;
@@ -178,16 +179,16 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
'\u{08}' if is_quoted => "\\b".to_string(), // UTF-8 backspace
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
'\\' if is_quoted => "\\\\".to_string(),
- ' ' | '\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
- c.to_string()
- }
- _ =>
+ ' ' | '\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"'
+ | '\\' => c.to_string(),
+ _ => {
if c.is_whitespace() || c.is_control() {
// print all other control and whitespace characters in hex.
format!("\\x{:x}\\", c as u32)
} else {
c.to_string()
}
+ }
}
}
@@ -217,7 +218,8 @@ enum TokenOrRedirect {
CompositeRedirect(usize, DirectedOp),
CurlyBracketRedirect(usize),
FunctorRedirect(usize),
- #[allow(unused)] IpAddr(IpAddr),
+ #[allow(unused)]
+ IpAddr(IpAddr),
NumberFocus(usize, NumberFocus, Option),
Open,
Close,
@@ -467,8 +469,8 @@ pub fn fmt_float(mut fl: f64) -> String {
*/
if let Some(e_index) = fl_str.find('e') {
- if !fl_str[0 .. e_index].contains('.') {
- return fl_str[0 .. e_index].to_string() + ".0" + &fl_str[e_index ..];
+ if !fl_str[0..e_index].contains('.') {
+ return fl_str[0..e_index].to_string() + ".0" + &fl_str[e_index..];
}
}
@@ -479,7 +481,7 @@ pub fn fmt_float(mut fl: f64) -> String {
pub struct HCPrinter<'a, Outputter> {
outputter: Outputter,
iter: StackfulPreOrderHeapIter<'a>,
- atom_tbl: &'a mut AtomTable,
+ atom_tbl: Arc,
op_dir: &'a OpDir,
state_stack: Vec,
toplevel_spec: Option,
@@ -548,7 +550,7 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option
impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
pub fn new(
heap: &'a mut Heap,
- atom_tbl: &'a mut AtomTable,
+ atom_tbl: Arc,
stack: &'a mut Stack,
op_dir: &'a OpDir,
output: Outputter,
@@ -578,7 +580,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
fn ambiguity_check(&self, atom: &str) -> bool {
let tail = &self.outputter.as_str()[self.last_item_idx..];
- if !self.quoted || non_quoted_token(atom.chars()) {
+ if atom == "," || !self.quoted || non_quoted_token(atom.chars()) {
requires_space(tail, atom)
} else {
requires_space(tail, "'")
@@ -625,11 +627,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} else {
let op = DirectedOp::Left(name, spec);
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
+ self.state_stack
+ .push(TokenOrRedirect::CompositeRedirect(max_depth, op));
self.state_stack.push(TokenOrRedirect::Op(name, spec));
}
} else {
- match name.as_str() {
+ match &*name.as_str() {
"|" => {
self.format_bar_separator_op(max_depth, name, spec);
return;
@@ -653,9 +656,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(name, spec);
let right_directed_op = DirectedOp::Right(name, spec);
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(
+ max_depth,
+ left_directed_op,
+ ));
self.state_stack.push(TokenOrRedirect::Op(name, spec));
- self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
+ self.state_stack.push(TokenOrRedirect::CompositeRedirect(
+ max_depth,
+ right_directed_op,
+ ));
}
}
}
@@ -681,7 +690,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.state_stack.push(TokenOrRedirect::Close);
for _ in 0..arity {
- self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
+ self.state_stack
+ .push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::Comma);
}
@@ -738,9 +748,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
return false;
}
-
self.state_stack.push(TokenOrRedirect::RightCurly);
- self.state_stack.push(TokenOrRedirect::CurlyBracketRedirect(max_depth));
+ self.state_stack
+ .push(TokenOrRedirect::CurlyBracketRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::LeftCurly);
true
@@ -750,10 +760,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let h = self.iter.stack_last().unwrap();
let cell = self.iter.read_cell(h);
- let cell = heap_bound_store(
- &self.iter.heap,
- heap_bound_deref(&self.iter.heap, cell),
- );
+ let cell = heap_bound_store(&self.iter.heap, heap_bound_deref(&self.iter.heap, cell));
// 7.10.4
if let Some(var) = numbervar(&self.numbervars_offset, cell) {
@@ -835,10 +842,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
if let Some(cell) = self.iter.next() {
let is_cyclic = cell.get_forwarding_bit();
- let cell = heap_bound_store(
- self.iter.heap,
- heap_bound_deref(self.iter.heap, cell),
- );
+ let cell = heap_bound_store(self.iter.heap, heap_bound_deref(self.iter.heap, cell));
let cell = unmark_cell_bits!(cell);
match self.var_names.get(&cell).cloned() {
@@ -891,7 +895,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
}
fn print_impromptu_atom(&mut self, atom: Atom) {
- let result = self.print_op_addendum(atom.as_str());
+ let result = self.print_op_addendum(&*atom.as_str());
push_space_if_amb!(self, result.as_str(), {
append_str!(self, &result);
@@ -1020,7 +1024,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
match self.op_dir.get(&(atom!("rdiv"), Fixity::In)) {
Some(op_desc) => {
- if r.is_integer() {
+ if r.denominator().is_one() {
let output_str = format!("{}", r);
push_space_if_amb!(self, &output_str, {
@@ -1050,7 +1054,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
NumberFocus::Denominator(r),
left_directed_op,
));
- self.state_stack.push(TokenOrRedirect::Op(rdiv_ct, *op_desc));
+ self.state_stack
+ .push(TokenOrRedirect::Op(rdiv_ct, *op_desc));
self.state_stack.push(TokenOrRedirect::NumberFocus(
max_depth,
NumberFocus::Numerator(r),
@@ -1157,8 +1162,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset => {
self.iter.pop_stack();
}
- HeapCellValueTag::CStr => {
- }
+ HeapCellValueTag::CStr => {}
_ => {
unreachable!();
}
@@ -1203,8 +1207,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
append_str!(self, "[]");
}
} else {
- self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
- self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
+ self.state_stack
+ .push(TokenOrRedirect::FunctorRedirect(max_depth));
+ self.iter
+ .push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
}
}
} else {
@@ -1298,7 +1304,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
}
}
- self.state_stack.push(TokenOrRedirect::CloseList(switch.clone()));
+ self.state_stack
+ .push(TokenOrRedirect::CloseList(switch.clone()));
Some(switch)
}
@@ -1335,9 +1342,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let switch = self.close_list(cell);
- self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
+ self.state_stack
+ .push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
- self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth+1));
+ self.state_stack
+ .push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
self.open_list(switch);
}
@@ -1353,15 +1362,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth: usize,
) {
let add_brackets = if !self.ignore_ops {
- negated_operand ||
- if let Some(ref op) = op {
+ negated_operand
+ || if let Some(ref op) = op {
if self.numbervars && arity == 1 && name == atom!("$VAR") {
!self.iter.immediate_leaf_has_property(|addr| {
match Number::try_from(addr) {
Ok(Number::Integer(n)) => &*n >= &Integer::from(0),
Ok(Number::Fixnum(n)) => n.get_num() >= 0,
Ok(Number::Float(f)) => f >= OrderedFloat(0f64),
- Ok(Number::Rational(r)) => &*r >= &Integer::from(0),
+ Ok(Number::Rational(r)) => &*r >= &Rational::from(0),
_ => false,
}
}) && needs_bracketing(op_desc, op)
@@ -1381,7 +1390,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.state_stack.push(TokenOrRedirect::Open);
if !self.outputter.ends_with(" ") {
- let parent_op = self.parent_of_first_op
+ let parent_op = self
+ .parent_of_first_op
.and_then(|(parent_op, last_item_idx)| {
// if parent_op isn't printed to the output string
// already, then it doesn't border the present op
@@ -1395,7 +1405,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
for op in &[op, parent_op] {
if let Some(ref op) = &op {
- if op.is_left() && (op.is_prefix() || requires_space(op.as_atom().as_str(), "(")) {
+ if op.is_left()
+ && (op.is_prefix() || requires_space(&*op.as_atom().as_str(), "("))
+ {
self.state_stack.push(TokenOrRedirect::Space);
return;
}
@@ -1519,7 +1531,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth,
);
} else {
- push_space_if_amb!(printer, name.as_str(), {
+ push_space_if_amb!(printer, &*name.as_str(), {
printer.format_clause(max_depth, arity, name, None);
});
}
@@ -1529,14 +1541,18 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
if let Some(ref op) = op {
let op_is_prefix = op.is_prefix() && op.is_left();
- if op_is_prefix || printer.outputter.ends_with(&format!(" {}", op.as_atom().as_str())) {
+ if op_is_prefix
+ || printer
+ .outputter
+ .ends_with(&format!(" {}", op.as_atom().as_str()))
+ {
result.push(' ');
}
result.push('(');
}
- result += &printer.print_op_addendum(name.as_str());
+ result += &printer.print_op_addendum(&*name.as_str());
if op.is_some() {
result.push(')');
@@ -1546,7 +1562,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
append_str!(printer, &result);
});
} else {
- push_space_if_amb!(printer, name.as_str(), {
+ push_space_if_amb!(printer, &*name.as_str(), {
printer.print_impromptu_atom(name);
});
}
@@ -1557,7 +1573,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
None => return,
};
- if !addr.is_var() && !addr.is_compound(&self.iter.heap) && self.max_depth_exhausted(max_depth) {
+ if !addr.is_var()
+ && !addr.is_compound(&self.iter.heap)
+ && self.max_depth_exhausted(max_depth)
+ {
self.state_stack.push(TokenOrRedirect::Atom(atom!("...")));
return;
}
@@ -1567,7 +1586,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
print_struct(self, name, arity);
}
(HeapCellValueTag::Char, c) => {
- let name = self.atom_tbl.build_with(&String::from(c));
+ let name = AtomTable::build_with(&self.atom_tbl, &String::from(c));
print_struct(self, name, 0);
}
(HeapCellValueTag::Str, s) => {
@@ -1585,7 +1604,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth,
);
} else {
- push_space_if_amb!(self, name.as_str(), {
+ push_space_if_amb!(self, &*name.as_str(), {
self.format_clause(max_depth, arity, name, None);
});
}
@@ -1627,9 +1646,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
(ArenaHeaderTag::Stream, stream) => {
self.print_stream(stream, max_depth);
}
- (ArenaHeaderTag::OssifiedOpDir, _op_dir) => {
- self.print_impromptu_atom(atom!("$ossified_op_dir"));
- }
(ArenaHeaderTag::Dropped, _value) => {
self.print_impromptu_atom(atom!("$dropped_value"));
}
@@ -1668,7 +1684,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
TokenOrRedirect::Op(atom, op) => {
- self.print_op(atom.as_str());
+ self.print_op(&*atom.as_str());
if is_prefix!(op.get_spec()) {
self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
@@ -1737,16 +1753,18 @@ mod tests {
let b_atom = atom!("b");
let c_atom = atom!("c");
- wam.machine_st.heap.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
+ wam.machine_st
+ .heap
+ .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- heap_loc_as_cell!(0)
+ heap_loc_as_cell!(0),
);
let output = printer.print();
@@ -1771,11 +1789,11 @@ mod tests {
{
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- heap_loc_as_cell!(0)
+ heap_loc_as_cell!(0),
);
let output = printer.print();
@@ -1795,11 +1813,11 @@ mod tests {
{
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- heap_loc_as_cell!(0)
+ heap_loc_as_cell!(0),
);
let output = printer.print();
@@ -1808,14 +1826,16 @@ mod tests {
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- heap_loc_as_cell!(0)
+ heap_loc_as_cell!(0),
);
- printer.var_names.insert(list_loc_as_cell!(1), VarPtr::from("L"));
+ printer
+ .var_names
+ .insert(list_loc_as_cell!(1), VarPtr::from("L"));
let output = printer.print();
@@ -1839,7 +1859,7 @@ mod tests {
{
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
@@ -1858,7 +1878,7 @@ mod tests {
{
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
@@ -1875,14 +1895,16 @@ mod tests {
{
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- heap_loc_as_cell!(0)
+ heap_loc_as_cell!(0),
);
- printer.var_names.insert(list_loc_as_cell!(1), VarPtr::from("L"));
+ printer
+ .var_names
+ .insert(list_loc_as_cell!(1), VarPtr::from("L"));
let output = printer.print();
@@ -1905,11 +1927,11 @@ mod tests {
{
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- heap_loc_as_cell!(0)
+ heap_loc_as_cell!(0),
);
printer.max_depth = 5;
@@ -1923,16 +1945,16 @@ mod tests {
wam.machine_st.heap.clear();
- put_partial_string(&mut wam.machine_st.heap, "abc", &mut wam.machine_st.atom_tbl);
+ put_partial_string(&mut wam.machine_st.heap, "abc", &wam.machine_st.atom_tbl);
{
let printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
- pstr_loc_as_cell!(0)
+ pstr_loc_as_cell!(0),
);
let output = printer.print();
@@ -1956,7 +1978,7 @@ mod tests {
{
let mut printer = HCPrinter::new(
&mut wam.machine_st.heap,
- &mut wam.machine_st.atom_tbl,
+ Arc::clone(&wam.machine_st.atom_tbl),
&mut wam.machine_st.stack,
&wam.op_dir,
PrinterOutputter::new(),
@@ -2000,35 +2022,39 @@ mod tests {
all_cells_unmarked(&wam.machine_st.heap);
- wam.op_dir.insert(
- (atom!("+"), Fixity::In),
- OpDesc::build_with(500, YFX as u8),
- );
- wam.op_dir.insert(
- (atom!("*"), Fixity::In),
- OpDesc::build_with(400, YFX as u8),
- );
+ wam.op_dir
+ .insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8));
+ wam.op_dir
+ .insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8));
- assert_eq!(&wam.parse_and_print_term("[a|[] + b].").unwrap(), "[a|[]+b]");
+ assert_eq!(
+ &wam.parse_and_print_term("[a|[] + b].").unwrap(),
+ "[a|[]+b]"
+ );
all_cells_unmarked(&wam.machine_st.heap);
- assert_eq!(&wam.parse_and_print_term("[a|[b|c]*d].").unwrap(), "[a|[b|c]*d]");
+ assert_eq!(
+ &wam.parse_and_print_term("[a|[b|c]*d].").unwrap(),
+ "[a|[b|c]*d]"
+ );
all_cells_unmarked(&wam.machine_st.heap);
- wam.op_dir.insert(
- (atom!("fy"), Fixity::Pre),
- OpDesc::build_with(9, FY as u8),
+ wam.op_dir
+ .insert((atom!("fy"), Fixity::Pre), OpDesc::build_with(9, FY as u8));
+
+ wam.op_dir
+ .insert((atom!("yf"), Fixity::Post), OpDesc::build_with(9, YF as u8));
+
+ assert_eq!(
+ &wam.parse_and_print_term("(fy (fy 1)yf)yf.").unwrap(),
+ "(fy (fy 1)yf)yf"
);
- wam.op_dir.insert(
- (atom!("yf"), Fixity::Post),
- OpDesc::build_with(9, YF as u8),
+ assert_eq!(
+ &wam.parse_and_print_term("fy(fy(yf(fy(1)))).").unwrap(),
+ "fy fy (fy 1)yf"
);
-
- assert_eq!(&wam.parse_and_print_term("(fy (fy 1)yf)yf.").unwrap(), "(fy (fy 1)yf)yf");
-
- assert_eq!(&wam.parse_and_print_term("fy(fy(yf(fy(1)))).").unwrap(), "fy fy (fy 1)yf");
}
}
diff --git a/src/http.rs b/src/http.rs
index 8f548235..6c0d40c8 100644
--- a/src/http.rs
+++ b/src/http.rs
@@ -1,13 +1,13 @@
-use std::sync::{Arc, Mutex, Condvar};
-use std::future::Future;
-use std::pin::Pin;
-use http_body_util::Full;
use bytes::Bytes;
+use http_body_util::Full;
use hyper::service::Service;
use hyper::{body::Incoming as IncomingBody, Request, Response};
+use std::future::Future;
+use std::pin::Pin;
+use std::sync::{Arc, Condvar, Mutex};
pub struct HttpListener {
- pub incoming: std::sync::mpsc::Receiver
+ pub incoming: std::sync::mpsc::Receiver,
}
#[derive(Debug)]
@@ -31,7 +31,10 @@ impl Service> for HttpService {
// new connection!
// we send the Request info to Prolog
let response = Arc::new((Mutex::new(false), Mutex::new(None), Condvar::new()));
- let http_request = HttpRequest { request: req, response: Arc::clone(&response) };
+ let http_request = HttpRequest {
+ request: req,
+ response: Arc::clone(&response)
+ };
self.tx.send(http_request).unwrap();
// we wait for the Response info from Prolog
@@ -39,7 +42,7 @@ impl Service> for HttpService {
let (ready, _response, cvar) = &*response;
let mut ready = ready.lock().unwrap();
while !*ready {
- ready = cvar.wait(ready).unwrap();
+ ready = cvar.wait(ready).unwrap();
}
}
{
diff --git a/src/indexing.rs b/src/indexing.rs
index bad75be4..6a52fc97 100644
--- a/src/indexing.rs
+++ b/src/indexing.rs
@@ -150,17 +150,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let third_level_index = if self.append_or_prepend.is_append() {
vec![
IndexedChoiceInstruction::Try(external),
- IndexedChoiceInstruction::Trust(index)
- ].into()
+ IndexedChoiceInstruction::Trust(index),
+ ]
+ .into()
} else {
vec![
IndexedChoiceInstruction::Try(index),
- IndexedChoiceInstruction::Trust(external)
- ].into()
+ IndexedChoiceInstruction::Trust(external),
+ ]
+ .into()
};
let indexing_code_len = self.indexing_code.len();
- self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index));
+ self.indexing_code
+ .push(IndexingLine::IndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
@@ -188,7 +191,8 @@ impl<'a> IndexingCodeMergingPtr<'a> {
};
let indexing_code_len = self.indexing_code.len();
- self.indexing_code.push(IndexingLine::DynamicIndexedChoice(third_level_index));
+ self.indexing_code
+ .push(IndexingLine::DynamicIndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
@@ -275,10 +279,8 @@ impl<'a> IndexingCodeMergingPtr<'a> {
);
}
None | Some(IndexingCodePtr::Fail) => {
- constants.insert(
- overlapping_constant,
- IndexingCodePtr::External(index),
- );
+ constants
+ .insert(overlapping_constant, IndexingCodePtr::External(index));
}
Some(IndexingCodePtr::DynamicExternal(o)) => {
self.add_dynamic_indexed_choice_for_constant(
@@ -345,16 +347,10 @@ impl<'a> IndexingCodeMergingPtr<'a> {
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
match constants.get(&constant).cloned() {
None | Some(IndexingCodePtr::Fail) if self.is_dynamic => {
- constants.insert(
- constant,
- IndexingCodePtr::DynamicExternal(index),
- );
+ constants.insert(constant, IndexingCodePtr::DynamicExternal(index));
}
None | Some(IndexingCodePtr::Fail) => {
- constants.insert(
- constant,
- IndexingCodePtr::External(index),
- );
+ constants.insert(constant, IndexingCodePtr::External(index));
}
Some(IndexingCodePtr::DynamicExternal(o)) => {
self.add_dynamic_indexed_choice_for_constant(o, constant, index);
@@ -432,17 +428,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let third_level_index = if self.append_or_prepend.is_append() {
vec![
IndexedChoiceInstruction::Try(external),
- IndexedChoiceInstruction::Trust(index)
- ].into()
+ IndexedChoiceInstruction::Trust(index),
+ ]
+ .into()
} else {
vec![
IndexedChoiceInstruction::Try(index),
- IndexedChoiceInstruction::Trust(external)
- ].into()
+ IndexedChoiceInstruction::Trust(external),
+ ]
+ .into()
};
let indexing_code_len = self.indexing_code.len();
- self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index));
+ self.indexing_code
+ .push(IndexingLine::IndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
@@ -470,7 +469,8 @@ impl<'a> IndexingCodeMergingPtr<'a> {
};
let indexing_code_len = self.indexing_code.len();
- self.indexing_code.push(IndexingLine::DynamicIndexedChoice(third_level_index));
+ self.indexing_code
+ .push(IndexingLine::DynamicIndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
@@ -584,13 +584,15 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let third_level_index = if self.append_or_prepend.is_append() {
vec![
IndexedChoiceInstruction::Try(o),
- IndexedChoiceInstruction::Trust(index)
- ].into()
+ IndexedChoiceInstruction::Trust(index),
+ ]
+ .into()
} else {
vec![
IndexedChoiceInstruction::Try(index),
- IndexedChoiceInstruction::Trust(o)
- ].into()
+ IndexedChoiceInstruction::Trust(o),
+ ]
+ .into()
};
self.indexing_code
@@ -613,7 +615,7 @@ pub(crate) fn merge_clause_index(
target_indexing_code: &mut Vec,
skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton.
retracted_clauses: &Option>,
- new_clause_loc: usize, // the absolute location of the new clause in the code vector.
+ new_clause_loc: usize, // the absolute location of the new clause in the code vector.
append_or_prepend: AppendOrPrepend,
) {
let opt_arg_index_key = match append_or_prepend {
@@ -636,11 +638,7 @@ pub(crate) fn merge_clause_index(
for overlapping_constant in overlapping_constants {
merging_ptr.offset = 0;
- merging_ptr.index_overlapping_constant(
- *constant,
- *overlapping_constant,
- offset,
- );
+ merging_ptr.index_overlapping_constant(*constant, *overlapping_constant, offset);
}
}
OptArgIndexKey::Structure(_, index_loc, name, arity) => {
@@ -1060,19 +1058,27 @@ fn cap_choice_seq(prelude: &mut [IndexedChoiceInstruction]) {
#[inline]
fn cap_choice_seq_with_trust(prelude: &mut [IndexedChoiceInstruction]) {
- prelude.last_mut().map(|instr| {
- if let IndexedChoiceInstruction::Retry(i) = instr {
+ prelude.last_mut().map(|instr| match instr {
+ IndexedChoiceInstruction::Retry(i) => {
*instr = IndexedChoiceInstruction::Trust(*i);
}
+ IndexedChoiceInstruction::DefaultRetry(i) => {
+ *instr = IndexedChoiceInstruction::DefaultTrust(*i);
+ }
+ _ => {}
});
}
#[inline]
fn uncap_choice_seq_with_trust(prelude: &mut [IndexedChoiceInstruction]) {
- prelude.last_mut().map(|instr| {
- if let IndexedChoiceInstruction::Trust(i) = instr {
+ prelude.last_mut().map(|instr| match instr {
+ IndexedChoiceInstruction::Trust(i) => {
*instr = IndexedChoiceInstruction::Retry(*i);
}
+ IndexedChoiceInstruction::DefaultTrust(i) => {
+ *instr = IndexedChoiceInstruction::DefaultRetry(*i);
+ }
+ _ => {}
});
}
@@ -1087,7 +1093,7 @@ fn uncap_choice_seq_with_try(prelude: &mut [IndexedChoiceInstruction]) {
pub(crate) fn constant_key_alternatives(
constant: Literal,
- atom_tbl: &mut AtomTable,
+ atom_tbl: &AtomTable,
// arena: &mut Arena,
) -> Vec {
let mut constants = vec![];
@@ -1099,7 +1105,7 @@ pub(crate) fn constant_key_alternatives(
}
}
Literal::Char(c) => {
- let atom = atom_tbl.build_with(&c.to_string());
+ let atom = AtomTable::build_with(&atom_tbl, &c.to_string());
constants.push(Literal::Atom(atom));
}
/*
@@ -1116,8 +1122,9 @@ pub(crate) fn constant_key_alternatives(
}
*/
Literal::Integer(ref n) => {
- if let Some(n) = n.to_isize() {
- Fixnum::build_with_checked(n as i64).map(|n| {
+ let result = (&**n).try_into();
+ if let Ok(value) = result {
+ Fixnum::build_with_checked(value).map(|n| {
constants.push(Literal::Fixnum(n));
}).unwrap();
}
@@ -1147,11 +1154,19 @@ pub(crate) trait Indexer {
fn new() -> Self;
- fn constants(&mut self) -> &mut IndexMap, FxBuildHasher>;
+ fn constants(
+ &mut self,
+ ) -> &mut IndexMap, FxBuildHasher>;
fn lists(&mut self) -> &mut VecDeque;
- fn structures(&mut self) -> &mut IndexMap<(Atom, usize), VecDeque, FxBuildHasher>;
+ fn structures(
+ &mut self,
+ ) -> &mut IndexMap<(Atom, usize), VecDeque, FxBuildHasher>;
- fn compute_index(is_initial_index: bool, index: usize) -> Self::ThirdLevelIndex;
+ fn compute_index(
+ is_initial_index: bool,
+ index: usize,
+ non_counted_bt: bool,
+ ) -> Self::ThirdLevelIndex;
fn second_level_index(
indices: IndexMap, FxBuildHasher>,
@@ -1187,7 +1202,9 @@ impl Indexer for StaticCodeIndices {
}
#[inline]
- fn constants(&mut self) -> &mut IndexMap, FxBuildHasher> {
+ fn constants(
+ &mut self,
+ ) -> &mut IndexMap, FxBuildHasher> {
&mut self.constants
}
@@ -1197,13 +1214,21 @@ impl Indexer for StaticCodeIndices {
}
#[inline]
- fn structures(&mut self) -> &mut IndexMap<(Atom, usize), VecDeque, FxBuildHasher> {
+ fn structures(
+ &mut self,
+ ) -> &mut IndexMap<(Atom, usize), VecDeque, FxBuildHasher> {
&mut self.structures
}
- fn compute_index(is_initial_index: bool, index: usize) -> IndexedChoiceInstruction {
+ fn compute_index(
+ is_initial_index: bool,
+ index: usize,
+ non_counted_bt: bool,
+ ) -> IndexedChoiceInstruction {
if is_initial_index {
IndexedChoiceInstruction::Try(index + 1)
+ } else if non_counted_bt {
+ IndexedChoiceInstruction::DefaultRetry(index + 1)
} else {
IndexedChoiceInstruction::Retry(index + 1)
}
@@ -1231,7 +1256,9 @@ impl Indexer for StaticCodeIndices {
}
fn switch_on(
- mut instr_fn: impl FnMut(IndexMap) -> IndexingInstruction,
+ mut instr_fn: impl FnMut(
+ IndexMap,
+ ) -> IndexingInstruction,
index: &mut IndexMap, FxBuildHasher>,
prelude: &mut VecDeque,
) -> IndexingCodePtr {
@@ -1318,7 +1345,7 @@ impl Indexer for DynamicCodeIndices {
}
#[inline]
- fn compute_index(_: bool, index: usize) -> usize {
+ fn compute_index(_: bool, index: usize, _: bool) -> usize {
index + 1
}
@@ -1331,7 +1358,9 @@ impl Indexer for DynamicCodeIndices {
for (key, code) in indices.into_iter() {
if code.len() > 1 {
index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1));
- prelude.push_back(IndexingLine::DynamicIndexedChoice(code.into_iter().collect()));
+ prelude.push_back(IndexingLine::DynamicIndexedChoice(
+ code.into_iter().collect(),
+ ));
} else {
code.front().map(|i| {
index_locs.insert(key, IndexingCodePtr::DynamicExternal(*i));
@@ -1343,7 +1372,9 @@ impl Indexer for DynamicCodeIndices {
}
fn switch_on(
- mut instr_fn: impl FnMut(IndexMap) -> IndexingInstruction,
+ mut instr_fn: impl FnMut(
+ IndexMap,
+ ) -> IndexingInstruction,
index: &mut IndexMap, FxBuildHasher>,
prelude: &mut VecDeque,
) -> IndexingCodePtr {
@@ -1370,7 +1401,9 @@ impl Indexer for DynamicCodeIndices {
) -> IndexingCodePtr {
if lists.len() > 1 {
let lists = mem::replace(lists, VecDeque::new());
- prelude.push_back(IndexingLine::DynamicIndexedChoice(lists.into_iter().collect()));
+ prelude.push_back(IndexingLine::DynamicIndexedChoice(
+ lists.into_iter().collect(),
+ ));
IndexingCodePtr::Internal(1)
} else {
lists
@@ -1400,33 +1433,43 @@ impl Indexer for DynamicCodeIndices {
pub(crate) struct CodeOffsets {
indices: I,
optimal_index: usize,
+ non_counted_bt: bool,
}
impl CodeOffsets {
- pub(crate) fn new(indices: I, optimal_index: usize) -> Self {
+ pub(crate) fn new(indices: I, optimal_index: usize, non_counted_bt: bool) -> Self {
CodeOffsets {
indices,
optimal_index,
+ non_counted_bt,
}
}
fn index_list(&mut self, index: usize) {
let is_initial_index = self.indices.lists().is_empty();
- let index = I::compute_index(is_initial_index, index);
+ let index = I::compute_index(is_initial_index, index, self.non_counted_bt);
self.indices.lists().push_back(index);
}
fn index_constant(
&mut self,
- atom_tbl: &mut AtomTable,
+ atom_tbl: &AtomTable,
constant: Literal,
index: usize,
) -> Vec {
let overlapping_constants = constant_key_alternatives(constant, atom_tbl);
- let code = self.indices.constants().entry(constant).or_insert(VecDeque::new());
+ let code = self
+ .indices
+ .constants()
+ .entry(constant)
+ .or_insert(VecDeque::new());
let is_initial_index = code.is_empty();
- code.push_back(I::compute_index(is_initial_index, index));
+ code.push_back(I::compute_index(
+ is_initial_index,
+ index,
+ self.non_counted_bt,
+ ));
for constant in &overlapping_constants {
let code = self
@@ -1436,7 +1479,7 @@ impl CodeOffsets {
.or_insert(VecDeque::new());
let is_initial_index = code.is_empty();
- let index = I::compute_index(is_initial_index, index);
+ let index = I::compute_index(is_initial_index, index, self.non_counted_bt);
code.push_back(index);
}
@@ -1454,7 +1497,11 @@ impl CodeOffsets {
let code_len = code.len();
let is_initial_index = code.is_empty();
- code.push_back(I::compute_index(is_initial_index, index));
+ code.push_back(I::compute_index(
+ is_initial_index,
+ index,
+ self.non_counted_bt,
+ ));
code_len
}
@@ -1463,7 +1510,7 @@ impl CodeOffsets {
optimal_arg: &Term,
index: usize,
clause_index_info: &mut ClauseIndexInfo,
- atom_tbl: &mut AtomTable,
+ atom_tbl: &AtomTable,
) {
match optimal_arg {
&Term::Clause(_, atom!("."), ref terms) if terms.len() == 2 => {
diff --git a/src/iterators.rs b/src/iterators.rs
index adec2e4c..0961355d 100644
--- a/src/iterators.rs
+++ b/src/iterators.rs
@@ -62,9 +62,7 @@ impl<'a> TermIterState<'a> {
Term::PartialString(cell, string_buf, tail) => {
TermIterState::InitialPartialString(lvl, cell, string_buf, tail)
}
- Term::CompleteString(cell, atom) => {
- TermIterState::CompleteString(lvl, cell, *atom)
- }
+ Term::CompleteString(cell, atom) => TermIterState::CompleteString(lvl, cell, *atom),
Term::Var(cell, var_ptr) => TermIterState::Var(lvl, cell, var_ptr.clone()),
}
}
@@ -77,7 +75,8 @@ pub(crate) struct QueryIterator<'a> {
impl<'a> QueryIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
- self.state_stack.push(TermIterState::subterm_to_state(lvl, term));
+ self.state_stack
+ .push(TermIterState::subterm_to_state(lvl, term));
}
/*
@@ -94,19 +93,16 @@ impl<'a> QueryIterator<'a> {
fn from_term(term: &'a Term) -> Self {
let state = match term {
- Term::AnonVar | Term::Cons(..) | Term::Literal(..) |
- Term::PartialString(..) | Term::CompleteString(..) => {
+ Term::AnonVar
+ | Term::Cons(..)
+ | Term::Literal(..)
+ | Term::PartialString(..)
+ | Term::CompleteString(..) => {
return QueryIterator {
state_stack: vec![],
}
}
- Term::Clause(r, name, terms) => TermIterState::Clause(
- Level::Root,
- 0,
- r,
- *name,
- terms,
- ),
+ Term::Clause(r, name, terms) => TermIterState::Clause(Level::Root, 0, r, *name, terms),
Term::Var(cell, var_ptr) => TermIterState::Var(Level::Root, cell, var_ptr.clone()),
};
@@ -118,18 +114,21 @@ impl<'a> QueryIterator<'a> {
fn extend_state(&mut self, lvl: Level, term: &'a QueryTerm) {
match term {
&QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => {
- self.state_stack.push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms));
+ self.state_stack
+ .push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms));
}
&QueryTerm::Clause(ref cell, ref ct, ref terms, _) => {
- self.state_stack.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms));
- }
- _ => {
+ self.state_stack
+ .push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms));
}
+ _ => {}
}
}
pub fn new(term: &'a QueryTerm) -> Self {
- let mut iter = QueryIterator { state_stack: vec![] };
+ let mut iter = QueryIterator {
+ state_stack: vec![],
+ };
iter.extend_state(Level::Root, term);
iter
}
@@ -170,13 +169,15 @@ impl<'a> Iterator for QueryIterator<'a> {
}
}
TermIterState::InitialCons(lvl, cell, head, tail) => {
- self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail));
+ self.state_stack
+ .push(TermIterState::FinalCons(lvl, cell, head, tail));
self.push_subterm(lvl.child_level(), tail);
self.push_subterm(lvl.child_level(), head);
}
TermIterState::InitialPartialString(lvl, cell, string, tail) => {
- self.state_stack.push(TermIterState::FinalPartialString(lvl, cell, string, tail));
+ self.state_stack
+ .push(TermIterState::FinalPartialString(lvl, cell, string, tail));
self.push_subterm(lvl.child_level(), tail);
}
TermIterState::FinalPartialString(lvl, cell, atom, tail) => {
@@ -248,11 +249,7 @@ impl<'a> FactIterator<'a> {
)]
}
Term::CompleteString(cell, atom) => {
- vec![TermIterState::CompleteString(
- Level::Root,
- cell,
- *atom,
- )]
+ vec![TermIterState::CompleteString(Level::Root, cell, *atom)]
}
Term::Literal(cell, constant) => {
vec![TermIterState::Literal(Level::Root, cell, constant)]
@@ -319,7 +316,10 @@ pub(crate) fn post_order_iter<'a>(term: &'a Term) -> QueryIterator<'a> {
QueryIterator::from_term(term)
}
-pub(crate) fn breadth_first_iter<'a>(term: &'a Term, iterable_root: RootIterationPolicy) -> FactIterator<'a> {
+pub(crate) fn breadth_first_iter<'a>(
+ term: &'a Term,
+ iterable_root: RootIterationPolicy,
+) -> FactIterator<'a> {
FactIterator::new(term, iterable_root)
}
@@ -356,18 +356,14 @@ fn state_from_chunked_terms<'a>(chunk_vec: &'a VecDeque) -> Clause
impl<'a> ClauseIterator<'a> {
pub fn new(clauses: &'a ChunkedTermVec) -> Self {
match state_from_chunked_terms(&clauses.chunk_vec) {
- state @ ClauseIteratorState::RemainingBranches(..) => {
- Self {
- state_stack: vec![state],
- remaining_chunks_on_stack: 0,
- }
- }
- state @ ClauseIteratorState::RemainingChunks(..) => {
- Self {
- state_stack: vec![state],
- remaining_chunks_on_stack: 1,
- }
- }
+ state @ ClauseIteratorState::RemainingBranches(..) => Self {
+ state_stack: vec![state],
+ remaining_chunks_on_stack: 0,
+ },
+ state @ ClauseIteratorState::RemainingChunks(..) => Self {
+ state_stack: vec![state],
+ remaining_chunks_on_stack: 1,
+ },
}
}
@@ -403,14 +399,16 @@ impl<'a> Iterator for ClauseIterator<'a> {
match state {
ClauseIteratorState::RemainingChunks(chunks, focus) if focus < chunks.len() => {
if focus + 1 < chunks.len() {
- self.state_stack.push(ClauseIteratorState::RemainingChunks(chunks, focus + 1));
+ self.state_stack
+ .push(ClauseIteratorState::RemainingChunks(chunks, focus + 1));
} else {
self.remaining_chunks_on_stack -= 1;
}
match &chunks[focus] {
ChunkedTerms::Branch(branches) => {
- self.state_stack.push(ClauseIteratorState::RemainingBranches(branches, 0));
+ self.state_stack
+ .push(ClauseIteratorState::RemainingBranches(branches, 0));
}
ChunkedTerms::Chunk(chunk) => {
return Some(ClauseItem::Chunk(chunk));
@@ -420,8 +418,11 @@ impl<'a> Iterator for ClauseIterator<'a> {
ClauseIteratorState::RemainingChunks(chunks, focus) => {
debug_assert_eq!(chunks.len(), focus);
}
- ClauseIteratorState::RemainingBranches(branches, focus) if focus < branches.len() => {
- self.state_stack.push(ClauseIteratorState::RemainingBranches(&branches, focus + 1));
+ ClauseIteratorState::RemainingBranches(branches, focus)
+ if focus < branches.len() =>
+ {
+ self.state_stack
+ .push(ClauseIteratorState::RemainingBranches(&branches, focus + 1));
let state = state_from_chunked_terms(&branches[focus]);
if let ClauseIteratorState::RemainingChunks(..) = &state {
diff --git a/src/lib.rs b/src/lib.rs
index abd9d873..87a0f8ad 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,13 +19,13 @@ pub mod codegen;
mod debray_allocator;
#[cfg(feature = "ffi")]
mod ffi;
-mod variable_records;
mod forms;
mod heap_iter;
pub mod heap_print;
#[cfg(feature = "http")]
mod http;
mod indexing;
+mod variable_records;
#[macro_use]
pub mod instructions {
include!(concat!(env!("OUT_DIR"), "/instructions.rs"));
@@ -40,3 +40,19 @@ mod targets;
pub mod types;
use instructions::instr;
+
+mod rcu;
+
+#[cfg(target_arch = "wasm32")]
+use wasm_bindgen::prelude::*;
+
+#[cfg(target_arch = "wasm32")]
+#[wasm_bindgen]
+pub fn eval_code(s: &str) -> String {
+ use web_sys::console;
+ use machine::mock_wam::*;
+
+ let mut wam = Machine::with_test_streams();
+ let bytes = wam.test_load_string(s);
+ String::from_utf8_lossy(&bytes).to_string()
+}
diff --git a/src/lib/builtins.pl b/src/lib/builtins.pl
index 81f63ddd..a1c913bd 100644
--- a/src/lib/builtins.pl
+++ b/src/lib/builtins.pl
@@ -143,6 +143,7 @@ call(_, _, _, _, _, _, _, _, _).
% enabled) and `error` which throws an exception when a cylic term is created. Read and write.
% * `unknown`: How undefined predicates are handled when called. Possible values are `error` (the default, an error is thrown),
% `fail` (the call silently fails) and `warn` (the call fails and a warning about the undefined predicate is printed).
+% * `answer_write_options`: Additional write options used by the top level for writing answers.
%
current_prolog_flag(Flag, Value) :- Flag == max_arity, !, Value = 1023.
current_prolog_flag(max_arity, 1023).
@@ -160,6 +161,14 @@ current_prolog_flag(Flag, OccursCheckEnabled) :-
Flag == occurs_check,
!,
'$is_sto_enabled'(OccursCheckEnabled).
+current_prolog_flag(occurs_check, OccursCheckEnabled) :-
+ '$is_sto_enabled'(OccursCheckEnabled).
+current_prolog_flag(Flag, Value) :-
+ Flag == answer_write_options,
+ !,
+ answer_write_options(Value).
+current_prolog_flag(answer_write_options, Value) :-
+ answer_write_options(Value).
current_prolog_flag(Flag, _) :-
atom(Flag),
throw(error(domain_error(prolog_flag, Flag), current_prolog_flag/2)). % 8.17.2.3 b
@@ -167,6 +176,11 @@ current_prolog_flag(Flag, _) :-
nonvar(Flag),
throw(error(type_error(atom, Flag), current_prolog_flag/2)). % 8.17.2.3 a
+answer_write_options(Value) :-
+ ( iso_ext:bb_get('$answer_write_options', Value) -> true
+ ; Value = []
+ ).
+
%% set_prolog_flag(Flag, Value).
%
% Sets the internal value of the flag. To see the list of flags supported by Scryer Prolog,
@@ -207,14 +221,25 @@ set_prolog_flag(occurs_check, false) :-
set_prolog_flag(occurs_check, error) :-
!, '$set_sto_with_error_as_unify'.
set_prolog_flag(double_quotes, Value) :-
- throw(error(domain_error(flag_value, double_quotes + Value),
- set_prolog_flag/2)). % 8.17.1.3 e
+ flag_domain_error(double_quotes, Value).
+set_prolog_flag(answer_write_options, Options) :-
+ !,
+ catch(catch(builtins:parse_write_options(Options, _, set_prolog_flag/2),
+ error(domain_error(_,_), _),
+ throw(error(type_error(_,_), _))), % convert domain error to type error ....
+ error(type_error(_,_), _), % ... to catch type and domain errors.
+ flag_domain_error(answer_write_options, Options)),
+ iso_ext:bb_put('$answer_write_options', Options).
set_prolog_flag(Flag, _) :-
atom(Flag),
throw(error(domain_error(prolog_flag, Flag), set_prolog_flag/2)). % 8.17.1.3 d
set_prolog_flag(Flag, _) :-
throw(error(type_error(atom, Flag), set_prolog_flag/2)). % 8.17.1.3 c
+flag_domain_error(Flag, Value) :-
+ % domain error via 8.17.1.3 e: Value is inappropriate for Flag
+ throw(error(domain_error(flag_value, Flag + Value), set_prolog_flag/2)).
+
% control operators.
%% fail.
@@ -262,6 +287,9 @@ repeat :- repeat.
%% ->(G1, G2)
%
% If-then and if-then-else constructs
+
+:- non_counted_backtracking (->)/2.
+
G1 -> G2 :- control_entry_point((G1 -> G2)).
@@ -275,6 +303,9 @@ staggered_if_then(G1, G2) :-
%% ;(G1, G2)
%
% Disjunction (or)
+
+:- non_counted_backtracking (;)/2.
+
G1 ; G2 :- control_entry_point((G1 ; G2)).
@@ -304,6 +335,9 @@ set_cp(B) :- '$set_cp'(B).
%% ,(G1, G2)
%
% Conjuction (and)
+
+:- non_counted_backtracking (',')/2.
+
','(G1, G2) :- control_entry_point((G1, G2)).
@@ -788,7 +822,7 @@ catch(G,C,R) :-
catch(G,C,R,Bb) :-
'$install_new_block'(NBb),
- '$call_with_inference_counting'(call(G)),
+ call(G),
end_block(Bb, NBb).
catch(G,C,R,Bb) :-
'$reset_block'(Bb),
@@ -1342,11 +1376,6 @@ current_predicate(Pred) :-
; throw(error(type_error(predicate_indicator, Pred), current_predicate/1))
).
-'$iterate_op_db_refs'(RPriority, RSpec, ROp, _, RPriority, RSpec, ROp).
-'$iterate_op_db_refs'(RPriority, RSpec, ROp, OssifiedOpDir, Priority, Spec, Op) :-
- '$get_next_op_db_ref'(RPriority, RSpec, ROp, OssifiedOpDir, RRPriority, RRSpec, RROp),
- '$iterate_op_db_refs'(RRPriority, RRSpec, RROp, OssifiedOpDir, Priority, Spec, Op).
-
can_be_op_priority(Priority) :- var(Priority).
can_be_op_priority(Priority) :- op_priority(Priority).
@@ -1362,8 +1391,8 @@ current_op(Priority, Spec, Op) :-
( can_be_op_priority(Priority),
can_be_op_specifier(Spec),
error:can_be(atom, Op) ->
- '$get_next_op_db_ref'(RPriority, RSpec, ROp, OssifiedOpDir, _, _, Op),
- '$iterate_op_db_refs'(RPriority, RSpec, ROp, OssifiedOpDir, Priority, Spec, Op)
+ '$get_next_op_db_ref'(Priority, Spec, Op, ListOfOps),
+ lists:member(op(Priority, Spec, Op), ListOfOps)
).
list_of_op_atoms(Var) :-
@@ -2186,6 +2215,9 @@ set_stream_position(S_or_a, Position) :-
%% callable(X).
%
% True iff X is bound o an atom or a compund term.
+
+:- non_counted_backtracking callable/1.
+
callable(X) :-
( nonvar(X), functor(X, F, _), atom(F) ->
true
diff --git a/src/lib/clpb.pl b/src/lib/clpb.pl
index 3b7ac007..4dde600b 100644
--- a/src/lib/clpb.pl
+++ b/src/lib/clpb.pl
@@ -1,10 +1,29 @@
/* CLP(B): Constraint Logic Programming over Boolean Variables
- Copyright (C): 2019-2023 Markus Triska
- All rights reserved.
-
+ Author: Markus Triska
E-mail: triska@metalevel.at
- WWW: http://www.metalevel.at
+ WWW: https://www.metalevel.at
+ Copyright (C): 2019-2023 Markus Triska
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
*/
@@ -17,8 +36,8 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
:- module(clpb, [op(300, fy, ~),
- op(500, yfx, #),
- sat/1,
+ op(500, yfx, #),
+ sat/1,
taut/2,
labeling/1,
sat_count/2,
@@ -91,6 +110,46 @@ domain_error(Expectation, Term) :-
type_error(Expectation, Term) :-
type_error(Expectation, Term, unknown(Term)-1).
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Compatibility predicates.
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+:- meta_predicate(include(1, ?, ?)).
+
+include(_, [], []).
+include(Goal, [L|Ls0], Ls) :-
+ ( call(Goal, L) ->
+ Ls = [L|Rest]
+ ; Ls = Rest
+ ),
+ include(Goal, Ls0, Rest).
+
+:- meta_predicate(exclude(1, ?, ?)).
+
+exclude(_, [], []).
+exclude(Goal, [L|Ls0], Ls) :-
+ ( call(Goal, L) ->
+ Ls = Rest
+ ; Ls = [L|Rest]
+ ),
+ exclude(Goal, Ls0, Rest).
+
+:- meta_predicate(partition(2,?,?,?,?)).
+
+partition(_, [], [], [], []).
+partition(Pred, [H|T], L, E, G) :-
+ call(Pred, H, Diff),
+ partition_(Diff, H, Pred, T, L, E, G).
+
+partition_(<, H, Pred, T, [H|Rest], E, G) :-
+ partition(Pred, T, Rest, E, G).
+partition_(=, H, Pred, T, L, [H|Rest], G) :-
+ partition(Pred, T, L, Rest, G).
+partition_(>, H, Pred, T, L, E, [H|Rest]) :-
+ partition(Pred, T, L, E, Rest).
+
+:- meta_predicate(partition(1,?,?,?)).
+
partition(Pred, Ls0, As, Bs) :-
include(Pred, Ls0, As),
exclude(Pred, Ls0, Bs).
@@ -447,6 +506,10 @@ non_monotonic(X) :-
; true
).
+:- meta_predicate(bdd_nodes(1, ?, ?)).
+:- meta_predicate(bdd_nodes_(1, ?, ?, ?)).
+:- meta_predicate(with_aux(1, ?)).
+
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Rewriting to canonical expressions.
Atoms are converted to variables with a special attribute.
@@ -1513,8 +1576,7 @@ random_bindings(VNum, Node) -->
%
% ```
% ?- sat(A#B), weighted_maximum([1,2,1], [A,B,C], Maximum).
-% A = 0, B = 1, C = 1, Maximum = 3
-% ; false.
+% A = 0, B = 1, C = 1, Maximum = 3.
% ```
weighted_maximum(Ws, Vars, Max) :-
@@ -1635,8 +1697,7 @@ attribute_goals(Var) -->
{ bdd_nodes(BDD, Nodes),
phrase(nodes(Nodes), Ns) },
[clpb:'$clpb_bdd'(Ns)]
- ; { prepare_global_variables(BDD),
- phrase(sat_ands(Formula), Ands0),
+ ; { phrase(sat_ands(Formula), Ands0),
ands_fusion(Ands0, Ands),
maplist(formula_anf, Ands, ANFs0),
sort(ANFs0, ANFs1),
@@ -1656,6 +1717,10 @@ attribute_goals(Var) -->
booleans(RestVs)
; boolean(Var) % the variable may have occurred only in taut/2
).
+attribute_goals(Var) -->
+ { get_atts(Var, clpb_max(_)),
+ !,
+ put_atts(Var, -clpb_max(_)) }.
attribute_goals(Var) -->
{ get_atts(Var, clpb_bdd(BDD)),
ground(BDD),
@@ -1663,36 +1728,13 @@ attribute_goals(Var) -->
del_clpb(Var) :-
del_attr(Var, clpb),
- del_attr(Var, clpb_hash).
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- To make residual projection work with recorded constraints, the
- global counters must be adjusted so that new variables and nodes
- also get new IDs. Also, clpb_next_id/2 is used to actually create
- these counters, because creating them with b_setval/2 would make
- them [] on backtracking, which is quite unfortunate in itself.
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ del_attr(Var, clpb_hash),
+ del_attr(Var, clpb_atom).
b_setval(K, T) :- bb_b_put(K, T).
nb_setval(K, T) :- bb_put(K, T).
b_getval(K, T) :- bb_get(K, T).
-prepare_global_variables(BDD) :-
- clpb_next_id('$clpb_next_var', V0),
- clpb_next_id('$clpb_next_node', N0),
- bdd_nodes(BDD, Nodes),
- foldl(max_variable_node, Nodes, V0-N0, MaxV0-MaxN0),
- MaxV is MaxV0 + 1,
- MaxN is MaxN0 + 1,
- b_setval('$clpb_next_var', MaxV),
- b_setval('$clpb_next_node', MaxN).
-
-max_variable_node(Node, V0-N0, V-N) :-
- node_id(Node, N1),
- node_varindex(Node, V1),
- N is max(N0,N1),
- V is max(V0,V1).
-
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Fuse formulas that share the same variables into single conjunctions.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@@ -1817,7 +1859,8 @@ booleans([B|Bs]) --> boolean(B), booleans(Bs).
boolean(Var) -->
{ del_clpb(Var) },
- ( { get_attr(Var, clpb_omit_boolean, true) } -> []
+ ( { get_attr(Var, clpb_omit_boolean, true) } ->
+ { put_atts(Var, -clpb_omit_boolean(_)) }
; [clpb:sat(Var =:= Var)]
).
@@ -1919,49 +1962,3 @@ clpb_atom_var(Atom, Var) :-
put_assoc(Atom, A0, Var, A),
b_setval('$clpb_atoms', A)
).
-
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Compatibility predicates.
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
-include(Goal, List, Is) :-
- include_(List, Goal, Is).
-
-include_([], _, []).
-include_([X1|Xs1], P, Is) :-
- ( call(P, X1)
- -> Is = [X1|Is1]
- ; Is = Is1
- ),
- include_(Xs1, P, Is1).
-
-
-exclude(Goal, List, Is) :-
- exclude_(List, Goal, Is).
-
-exclude_([], _, []).
-exclude_([X1|Xs1], P, Is) :-
- ( call(P, X1)
- -> Is = Is1
- ; Is = [X1|Is1]
- ),
- exclude_(Xs1, P, Is1).
-
-
-partition(Pred, List, Less, Equal, Greater) :-
- partition_(List, Pred, Less, Equal, Greater).
-
-partition_([], _, [], [], []).
-partition_([H|T], Pred, L, E, G) :-
- call(Pred, H, Diff),
- partition_(Diff, H, Pred, T, L, E, G).
-
-partition_(<, H, Pred, T, [H|Rest], E, G) :-
- partition_(T, Pred, Rest, E, G).
-partition_(=, H, Pred, T, L, [H|Rest], G) :-
- partition_(T, Pred, L, Rest, G).
-partition_(>, H, Pred, T, L, E, [H|Rest]) :-
- partition_(T, Pred, L, E, Rest).
diff --git a/src/lib/clpz.pl b/src/lib/clpz.pl
index d560f675..f438043d 100644
--- a/src/lib/clpz.pl
+++ b/src/lib/clpz.pl
@@ -2142,16 +2142,17 @@ fds_sespsize([V|Vs], S0, S) :-
fds_sespsize(Vs, S2, S).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Optimisation uses destructive assignment to save the computed
- extremum over backtracking. Failure is used to get rid of copies of
- attributed variables that are created in intermediate steps. At
- least that's the intention - it currently doesn't work in SWI:
+ Optimisation uses the clause database to save the computed extremum
+ over backtracking. Failure is used to get rid of copies of
+ attributed variables that are created in intermediate steps.
- %?- X in 0..3, call_residue_vars(labeling([min(X)], [X]), Vs).
- %@ X = 0,
- %@ Vs = [_G6174, _G6177],
- %@ _G6174 in 0..3
+ Example:
+ ?- X in 1..3, call_residue_vars(labeling([min(X)], [X]), Vs).
+ %@ X = 1, Vs = []
+ %@ ; X = 2, Vs = []
+ %@ ; X = 3, Vs = []
+ %@ ; false.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
:- dynamic(extremum/1).
diff --git a/src/lib/iso_ext.pl b/src/lib/iso_ext.pl
index 0a5798ae..d53ff47b 100644
--- a/src/lib/iso_ext.pl
+++ b/src/lib/iso_ext.pl
@@ -226,8 +226,9 @@ end_block(B, _Bb, NBb, L) :-
:- non_counted_backtracking handle_ile/3.
-handle_ile(B, inference_limit_exceeded(B), inference_limit_exceeded) :-
+handle_ile(B, inference_limit_exceeded(B), R) :-
!,
+ R = inference_limit_exceeded,
'$pop_ball_stack'.
handle_ile(B, _, _) :-
'$remove_call_policy_check'(B),
@@ -358,10 +359,10 @@ call_nth_nesting(C, ID) :-
bb_put(ID, 0),
bb_put(i_call_nth_counter, C).
-%% countall(Goal, N).
+%% countall(G_0, N).
%
-% countall(Goal, N) counts all solutions of Goal and unifies N with
-% this number of solutions. This predicate always succeeds once.
+% countall(G_0, N) is true iff N unifies with the total number of
+% answers of call(G_0).
:- meta_predicate(countall(0, ?)).
@@ -370,7 +371,7 @@ countall(Goal, N) :-
( integer(N) ->
( N < 0 ->
domain_error(not_less_than_zero, N, countall/2)
- ; N > 0
+ ; true
)
; true
),
diff --git a/src/loader.pl b/src/loader.pl
index c7479d50..69897a0c 100644
--- a/src/loader.pl
+++ b/src/loader.pl
@@ -35,9 +35,9 @@ write_error(Error) :-
),
write('.').
-% '$print_message_and_fail'(inference_limit_exceeded(B)) :-
-% integer(B),
-% throw(inference_limit_exceeded(B)).
+
+:- non_counted_backtracking '$print_message_and_fail'/1.
+
'$print_message_and_fail'(Error) :-
write_error(Error),
nl,
@@ -70,6 +70,8 @@ term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
).
+:- non_counted_backtracking goal_expansion/3.
+
goal_expansion(Goal, Module, ExpandedGoal) :-
( atom(Module),
'$predicate_defined'(Module, goal_expansion, 2),
@@ -84,7 +86,6 @@ goal_expansion(Goal, Module, ExpandedGoal) :-
).
-
create_file_load_context(Stream, Path, Evacuable) :-
'$push_load_context'(Stream, Path),
'$push_load_state_payload'(Evacuable).
@@ -134,9 +135,15 @@ file_load_init(Stream, Evacuable) :-
run_initialization_goals.
file_load_cleanup(Evacuable, Error) :-
+ load_context(Module),
+ abolish(Module:'$initialization_goals'/1),
unload_evacuable(Evacuable),
- '$print_message_and_fail'(Error),
- throw(Error).
+ ( clause('$toplevel':argv(_), _) ->
+ % let the toplevel call loader:write_error/1
+ throw(Error)
+ ; '$print_message_and_fail'(Error)
+ ; throw(file_load_error)
+ ).
file_load(Stream, Path, Evacuable) :-
create_file_load_context(Stream, Path, Evacuable),
@@ -504,7 +511,9 @@ consult(Item) :-
use_module(Module) :-
'$push_load_state_payload'(Evacuable),
- use_module(Module, [], Evacuable).
+ catch('$call'(loader:use_module(Module, [], Evacuable)),
+ file_load_error,
+ '$call'(builtins:false)).
use_module(Module, Exports) :-
'$push_load_state_payload'(Evacuable),
@@ -591,6 +600,8 @@ consult_stream(Stream, PathFileName) :-
file_load(Stream, PathFileName, Subevacuable),
'$use_module'(Evacuable, Subevacuable, _).
+:- non_counted_backtracking check_predicate_property/5.
+
check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm) :-
'$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
check_predicate_property(built_in, _, Name, Arity, built_in) :-
@@ -603,6 +614,7 @@ check_predicate_property(discontiguous, Module, Name, Arity, discontiguous) :-
'$discontiguous_property'(Module, Name, Arity).
+:- non_counted_backtracking extract_predicate_property/2.
extract_predicate_property(Property, PropertyType) :-
( var(Property) ->
@@ -610,12 +622,16 @@ extract_predicate_property(Property, PropertyType) :-
; functor(Property, PropertyType, _)
).
+:- non_counted_backtracking load_context/1.
+
load_context(Module) :-
( prolog_load_context(module, Module) ->
true
; Module = user
).
+:- non_counted_backtracking predicate_property/2.
+
predicate_property(Callable, Property) :-
( var(Callable) ->
instantiation_error(predicate_property/2)
@@ -652,8 +668,6 @@ strip_subst_module(Goal, M1, M2, G) :-
; true
).
-:- non_counted_backtracking subgoal_expansion/3.
-
/*
* subgoal_expansion differs from goal_expansion only in that it fails
* unconditionally after catching an(y) exception, aborting the
@@ -661,10 +675,14 @@ strip_subst_module(Goal, M1, M2, G) :-
* when expand_goal is later invoked at runtime.
*/
+:- non_counted_backtracking subgoal_expansion_fail/1.
+
subgoal_expansion_fail(B) :-
builtins:set_cp(B),
fail.
+:- non_counted_backtracking subgoal_expansion/3.
+
subgoal_expansion(Goal, Module, ExpandedGoal) :-
'$get_cp'(B),
( atom(Module),
@@ -894,7 +912,6 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
% n_call_clause(N, Clauses) :-
% length(Args, N),
% Head =.. [call, G | Args],
-% CallNHead =.. [call, '$call'(G) | Args],
% N1 is N + 1,
% StripModule =.. ['$strip_module', G, M1, G1],
% FastCall =.. ['$fast_call', G | Args],
@@ -907,7 +924,7 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
% PrepareCallClause,
% expand_call_goal(G2, M1, G3),
% strip_subst_module(G3, M1, M2, G4),
-% '$call_with_inference_counting'(ModuleCall))].
+% ModuleCall)].
%
% generate_call_forms :-
% between(1, 64, N),
@@ -934,7 +951,7 @@ call(G0) :-
'$strip_module'(G0, M0, G1),
expand_call_goal(G1, M0, G2),
strip_subst_module(G2, M0, M1, G3),
- '$call_with_inference_counting'('$module_call'(M1, G3)).
+ '$module_call'(M1, G3).
:-non_counted_backtracking call/2.
call(A,B) :-
@@ -947,7 +964,7 @@ call(A,B) :-
'$prepare_call_clause'(E,D,B),
expand_call_goal(E,C,F),
strip_subst_module(F,C,G,H),
- '$call_with_inference_counting'('$module_call'(G,H)).
+ '$module_call'(G,H).
:-non_counted_backtracking call/3.
call(A,B,C) :-
@@ -960,7 +977,7 @@ call(A,B,C) :-
'$prepare_call_clause'(F,E,B,C),
expand_call_goal(F,D,G),
strip_subst_module(G,D,H,I),
- '$call_with_inference_counting'('$module_call'(H,I)).
+ '$module_call'(H,I).
:-non_counted_backtracking call/4.
call(A,B,C,D) :-
@@ -973,7 +990,7 @@ call(A,B,C,D) :-
'$prepare_call_clause'(G,F,B,C,D),
expand_call_goal(G,E,H),
strip_subst_module(H,E,I,J),
- '$call_with_inference_counting'('$module_call'(I,J)).
+ '$module_call'(I,J).
:-non_counted_backtracking call/5.
call(A,B,C,D,E) :-
@@ -986,7 +1003,7 @@ call(A,B,C,D,E) :-
'$prepare_call_clause'(H,G,B,C,D,E),
expand_call_goal(H,F,I),
strip_subst_module(I,F,J,K),
- '$call_with_inference_counting'('$module_call'(J,K)).
+ '$module_call'(J,K).
:-non_counted_backtracking call/6.
call(A,B,C,D,E,F) :-
@@ -999,7 +1016,7 @@ call(A,B,C,D,E,F) :-
'$prepare_call_clause'(I,H,B,C,D,E,F),
expand_call_goal(I,G,J),
strip_subst_module(J,G,K,L),
- '$call_with_inference_counting'('$module_call'(K,L)).
+ '$module_call'(K,L).
:-non_counted_backtracking call/7.
call(A,B,C,D,E,F,G) :-
@@ -1012,7 +1029,7 @@ call(A,B,C,D,E,F,G) :-
'$prepare_call_clause'(J,I,B,C,D,E,F,G),
expand_call_goal(J,H,K),
strip_subst_module(K,H,L,M),
- '$call_with_inference_counting'('$module_call'(L,M)).
+ '$module_call'(L,M).
:-non_counted_backtracking call/8.
call(A,B,C,D,E,F,G,H) :-
@@ -1025,7 +1042,7 @@ call(A,B,C,D,E,F,G,H) :-
'$prepare_call_clause'(K,J,B,C,D,E,F,G,H),
expand_call_goal(K,I,L),
strip_subst_module(L,I,M,N),
- '$call_with_inference_counting'('$module_call'(M,N)).
+ '$module_call'(M,N).
:-non_counted_backtracking call/9.
call(A,B,C,D,E,F,G,H,I) :-
@@ -1038,7 +1055,7 @@ call(A,B,C,D,E,F,G,H,I) :-
'$prepare_call_clause'(L,K,B,C,D,E,F,G,H,I),
expand_call_goal(L,J,M),
strip_subst_module(M,J,N,O),
- '$call_with_inference_counting'('$module_call'(N,O)).
+ '$module_call'(N,O).
:-non_counted_backtracking call/10.
call(A,B,C,D,E,F,G,H,I,J) :-
@@ -1051,7 +1068,7 @@ call(A,B,C,D,E,F,G,H,I,J) :-
'$prepare_call_clause'(M,L,B,C,D,E,F,G,H,I,J),
expand_call_goal(M,K,N),
strip_subst_module(N,K,O,P),
- '$call_with_inference_counting'('$module_call'(O,P)).
+ '$module_call'(O,P).
:-non_counted_backtracking call/11.
call(A,B,C,D,E,F,G,H,I,J,K) :-
@@ -1064,7 +1081,7 @@ call(A,B,C,D,E,F,G,H,I,J,K) :-
'$prepare_call_clause'(N,M,B,C,D,E,F,G,H,I,J,K),
expand_call_goal(N,L,O),
strip_subst_module(O,L,P,Q),
- '$call_with_inference_counting'('$module_call'(P,Q)).
+ '$module_call'(P,Q).
:-non_counted_backtracking call/12.
call(A,B,C,D,E,F,G,H,I,J,K,L) :-
@@ -1077,7 +1094,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L) :-
'$prepare_call_clause'(O,N,B,C,D,E,F,G,H,I,J,K,L),
expand_call_goal(O,M,P),
strip_subst_module(P,M,Q,R),
- '$call_with_inference_counting'('$module_call'(Q,R)).
+ '$module_call'(Q,R).
:-non_counted_backtracking call/13.
call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
@@ -1090,7 +1107,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
'$prepare_call_clause'(P,O,B,C,D,E,F,G,H,I,J,K,L,M),
expand_call_goal(P,N,Q),
strip_subst_module(Q,N,R,S),
- '$call_with_inference_counting'('$module_call'(R,S)).
+ '$module_call'(R,S).
:-non_counted_backtracking call/14.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
@@ -1103,7 +1120,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
'$prepare_call_clause'(Q,P,B,C,D,E,F,G,H,I,J,K,L,M,N),
expand_call_goal(Q,O,R),
strip_subst_module(R,O,S,T),
- '$call_with_inference_counting'('$module_call'(S,T)).
+ '$module_call'(S,T).
:-non_counted_backtracking call/15.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
@@ -1116,7 +1133,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
'$prepare_call_clause'(R,Q,B,C,D,E,F,G,H,I,J,K,L,M,N,O),
expand_call_goal(R,P,S),
strip_subst_module(S,P,T,U),
- '$call_with_inference_counting'('$module_call'(T,U)).
+ '$module_call'(T,U).
:-non_counted_backtracking call/16.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
@@ -1129,7 +1146,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
'$prepare_call_clause'(S,R,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P),
expand_call_goal(S,Q,T),
strip_subst_module(T,Q,U,V),
- '$call_with_inference_counting'('$module_call'(U,V)).
+ '$module_call'(U,V).
:-non_counted_backtracking call/17.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
@@ -1142,7 +1159,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
'$prepare_call_clause'(T,S,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),
expand_call_goal(T,R,U),
strip_subst_module(U,R,V,W),
- '$call_with_inference_counting'('$module_call'(V,W)).
+ '$module_call'(V,W).
:-non_counted_backtracking call/18.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
@@ -1155,7 +1172,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
'$prepare_call_clause'(U,T,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R),
expand_call_goal(U,S,V),
strip_subst_module(V,S,W,X),
- '$call_with_inference_counting'('$module_call'(W,X)).
+ '$module_call'(W,X).
:-non_counted_backtracking call/19.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
@@ -1168,7 +1185,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
'$prepare_call_clause'(V,U,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S),
expand_call_goal(V,T,W),
strip_subst_module(W,T,X,Y),
- '$call_with_inference_counting'('$module_call'(X,Y)).
+ '$module_call'(X,Y).
:-non_counted_backtracking call/20.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
@@ -1181,7 +1198,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
'$prepare_call_clause'(W,V,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),
expand_call_goal(W,U,X),
strip_subst_module(X,U,Y,Z),
- '$call_with_inference_counting'('$module_call'(Y,Z)).
+ '$module_call'(Y,Z).
:-non_counted_backtracking call/21.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
@@ -1194,7 +1211,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
'$prepare_call_clause'(X,W,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U),
expand_call_goal(X,V,Y),
strip_subst_module(Y,V,Z,A1),
- '$call_with_inference_counting'('$module_call'(Z,A1)).
+ '$module_call'(Z,A1).
:-non_counted_backtracking call/22.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
@@ -1207,7 +1224,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
'$prepare_call_clause'(Y,X,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V),
expand_call_goal(Y,W,Z),
strip_subst_module(Z,W,A1,B1),
- '$call_with_inference_counting'('$module_call'(A1,B1)).
+ '$module_call'(A1,B1).
:-non_counted_backtracking call/23.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
@@ -1220,7 +1237,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
'$prepare_call_clause'(Z,Y,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W),
expand_call_goal(Z,X,A1),
strip_subst_module(A1,X,B1,C1),
- '$call_with_inference_counting'('$module_call'(B1,C1)).
+ '$module_call'(B1,C1).
:-non_counted_backtracking call/24.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
@@ -1233,7 +1250,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
'$prepare_call_clause'(A1,Z,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X),
expand_call_goal(A1,Y,B1),
strip_subst_module(B1,Y,C1,D1),
- '$call_with_inference_counting'('$module_call'(C1,D1)).
+ '$module_call'(C1,D1).
:-non_counted_backtracking call/25.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :-
@@ -1246,7 +1263,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :-
'$prepare_call_clause'(B1,A1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y),
expand_call_goal(B1,Z,C1),
strip_subst_module(C1,Z,D1,E1),
- '$call_with_inference_counting'('$module_call'(D1,E1)).
+ '$module_call'(D1,E1).
:-non_counted_backtracking call/26.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :-
@@ -1259,7 +1276,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :-
'$prepare_call_clause'(C1,B1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z),
expand_call_goal(C1,A1,D1),
strip_subst_module(D1,A1,E1,F1),
- '$call_with_inference_counting'('$module_call'(E1,F1)).
+ '$module_call'(E1,F1).
:-non_counted_backtracking call/27.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :-
@@ -1272,7 +1289,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :-
'$prepare_call_clause'(D1,C1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1),
expand_call_goal(D1,B1,E1),
strip_subst_module(E1,B1,F1,G1),
- '$call_with_inference_counting'('$module_call'(F1,G1)).
+ '$module_call'(F1,G1).
:-non_counted_backtracking call/28.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :-
@@ -1285,7 +1302,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :-
'$prepare_call_clause'(E1,D1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1),
expand_call_goal(E1,C1,F1),
strip_subst_module(F1,C1,G1,H1),
- '$call_with_inference_counting'('$module_call'(G1,H1)).
+ '$module_call'(G1,H1).
:-non_counted_backtracking call/29.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :-
@@ -1298,7 +1315,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :-
'$prepare_call_clause'(F1,E1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1),
expand_call_goal(F1,D1,G1),
strip_subst_module(G1,D1,H1,I1),
- '$call_with_inference_counting'('$module_call'(H1,I1)).
+ '$module_call'(H1,I1).
:-non_counted_backtracking call/30.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :-
@@ -1311,7 +1328,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :-
'$prepare_call_clause'(G1,F1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1),
expand_call_goal(G1,E1,H1),
strip_subst_module(H1,E1,I1,J1),
- '$call_with_inference_counting'('$module_call'(I1,J1)).
+ '$module_call'(I1,J1).
:-non_counted_backtracking call/31.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :-
@@ -1324,7 +1341,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :-
'$prepare_call_clause'(H1,G1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1),
expand_call_goal(H1,F1,I1),
strip_subst_module(I1,F1,J1,K1),
- '$call_with_inference_counting'('$module_call'(J1,K1)).
+ '$module_call'(J1,K1).
:-non_counted_backtracking call/32.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :-
@@ -1337,7 +1354,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :-
'$prepare_call_clause'(I1,H1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1),
expand_call_goal(I1,G1,J1),
strip_subst_module(J1,G1,K1,L1),
- '$call_with_inference_counting'('$module_call'(K1,L1)).
+ '$module_call'(K1,L1).
:-non_counted_backtracking call/33.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :-
@@ -1350,7 +1367,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :
'$prepare_call_clause'(J1,I1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1),
expand_call_goal(J1,H1,K1),
strip_subst_module(K1,H1,L1,M1),
- '$call_with_inference_counting'('$module_call'(L1,M1)).
+ '$module_call'(L1,M1).
:-non_counted_backtracking call/34.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :-
@@ -1363,7 +1380,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(K1,J1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1),
expand_call_goal(K1,I1,L1),
strip_subst_module(L1,I1,M1,N1),
- '$call_with_inference_counting'('$module_call'(M1,N1)).
+ '$module_call'(M1,N1).
:-non_counted_backtracking call/35.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
@@ -1376,7 +1393,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(L1,K1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1),
expand_call_goal(L1,J1,M1),
strip_subst_module(M1,J1,N1,O1),
- '$call_with_inference_counting'('$module_call'(N1,O1)).
+ '$module_call'(N1,O1).
:-non_counted_backtracking call/36.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
@@ -1389,7 +1406,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(M1,L1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1),
expand_call_goal(M1,K1,N1),
strip_subst_module(N1,K1,O1,P1),
- '$call_with_inference_counting'('$module_call'(O1,P1)).
+ '$module_call'(O1,P1).
:-non_counted_backtracking call/37.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
@@ -1402,7 +1419,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(N1,M1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1),
expand_call_goal(N1,L1,O1),
strip_subst_module(O1,L1,P1,Q1),
- '$call_with_inference_counting'('$module_call'(P1,Q1)).
+ '$module_call'(P1,Q1).
:-non_counted_backtracking call/38.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
@@ -1415,7 +1432,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(O1,N1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1),
expand_call_goal(O1,M1,P1),
strip_subst_module(P1,M1,Q1,R1),
- '$call_with_inference_counting'('$module_call'(Q1,R1)).
+ '$module_call'(Q1,R1).
:-non_counted_backtracking call/39.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
@@ -1428,7 +1445,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(P1,O1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1),
expand_call_goal(P1,N1,Q1),
strip_subst_module(Q1,N1,R1,S1),
- '$call_with_inference_counting'('$module_call'(R1,S1)).
+ '$module_call'(R1,S1).
:-non_counted_backtracking call/40.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
@@ -1441,7 +1458,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(Q1,P1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1),
expand_call_goal(Q1,O1,R1),
strip_subst_module(R1,O1,S1,T1),
- '$call_with_inference_counting'('$module_call'(S1,T1)).
+ '$module_call'(S1,T1).
:-non_counted_backtracking call/41.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
@@ -1454,7 +1471,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(R1,Q1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1),
expand_call_goal(R1,P1,S1),
strip_subst_module(S1,P1,T1,U1),
- '$call_with_inference_counting'('$module_call'(T1,U1)).
+ '$module_call'(T1,U1).
:-non_counted_backtracking call/42.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
@@ -1467,7 +1484,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(S1,R1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1),
expand_call_goal(S1,Q1,T1),
strip_subst_module(T1,Q1,U1,V1),
- '$call_with_inference_counting'('$module_call'(U1,V1)).
+ '$module_call'(U1,V1).
:-non_counted_backtracking call/43.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
@@ -1480,7 +1497,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(T1,S1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1),
expand_call_goal(T1,R1,U1),
strip_subst_module(U1,R1,V1,W1),
- '$call_with_inference_counting'('$module_call'(V1,W1)).
+ '$module_call'(V1,W1).
:-non_counted_backtracking call/44.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
@@ -1493,7 +1510,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(U1,T1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1),
expand_call_goal(U1,S1,V1),
strip_subst_module(V1,S1,W1,X1),
- '$call_with_inference_counting'('$module_call'(W1,X1)).
+ '$module_call'(W1,X1).
:-non_counted_backtracking call/45.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
@@ -1506,7 +1523,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(V1,U1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1),
expand_call_goal(V1,T1,W1),
strip_subst_module(W1,T1,X1,Y1),
- '$call_with_inference_counting'('$module_call'(X1,Y1)).
+ '$module_call'(X1,Y1).
:-non_counted_backtracking call/46.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
@@ -1519,7 +1536,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(W1,V1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1),
expand_call_goal(W1,U1,X1),
strip_subst_module(X1,U1,Y1,Z1),
- '$call_with_inference_counting'('$module_call'(Y1,Z1)).
+ '$module_call'(Y1,Z1).
:-non_counted_backtracking call/47.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
@@ -1532,7 +1549,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(X1,W1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1),
expand_call_goal(X1,V1,Y1),
strip_subst_module(Y1,V1,Z1,A2),
- '$call_with_inference_counting'('$module_call'(Z1,A2)).
+ '$module_call'(Z1,A2).
:-non_counted_backtracking call/48.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
@@ -1545,7 +1562,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(Y1,X1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1),
expand_call_goal(Y1,W1,Z1),
strip_subst_module(Z1,W1,A2,B2),
- '$call_with_inference_counting'('$module_call'(A2,B2)).
+ '$module_call'(A2,B2).
:-non_counted_backtracking call/49.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
@@ -1558,7 +1575,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(Z1,Y1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1),
expand_call_goal(Z1,X1,A2),
strip_subst_module(A2,X1,B2,C2),
- '$call_with_inference_counting'('$module_call'(B2,C2)).
+ '$module_call'(B2,C2).
:-non_counted_backtracking call/50.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
@@ -1571,7 +1588,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(A2,Z1,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1),
expand_call_goal(A2,Y1,B2),
strip_subst_module(B2,Y1,C2,D2),
- '$call_with_inference_counting'('$module_call'(C2,D2)).
+ '$module_call'(C2,D2).
:-non_counted_backtracking call/51.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
@@ -1584,7 +1601,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(B2,A2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1),
expand_call_goal(B2,Z1,C2),
strip_subst_module(C2,Z1,D2,E2),
- '$call_with_inference_counting'('$module_call'(D2,E2)).
+ '$module_call'(D2,E2).
:-non_counted_backtracking call/52.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
@@ -1597,7 +1614,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(C2,B2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1),
expand_call_goal(C2,A2,D2),
strip_subst_module(D2,A2,E2,F2),
- '$call_with_inference_counting'('$module_call'(E2,F2)).
+ '$module_call'(E2,F2).
:-non_counted_backtracking call/53.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
@@ -1610,7 +1627,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(D2,C2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2),
expand_call_goal(D2,B2,E2),
strip_subst_module(E2,B2,F2,G2),
- '$call_with_inference_counting'('$module_call'(F2,G2)).
+ '$module_call'(F2,G2).
:-non_counted_backtracking call/54.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
@@ -1623,7 +1640,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(E2,D2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2),
expand_call_goal(E2,C2,F2),
strip_subst_module(F2,C2,G2,H2),
- '$call_with_inference_counting'('$module_call'(G2,H2)).
+ '$module_call'(G2,H2).
:-non_counted_backtracking call/55.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
@@ -1636,7 +1653,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(F2,E2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2),
expand_call_goal(F2,D2,G2),
strip_subst_module(G2,D2,H2,I2),
- '$call_with_inference_counting'('$module_call'(H2,I2)).
+ '$module_call'(H2,I2).
:-non_counted_backtracking call/56.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
@@ -1649,7 +1666,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(G2,F2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2),
expand_call_goal(G2,E2,H2),
strip_subst_module(H2,E2,I2,J2),
- '$call_with_inference_counting'('$module_call'(I2,J2)).
+ '$module_call'(I2,J2).
:-non_counted_backtracking call/57.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
@@ -1662,7 +1679,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(H2,G2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2),
expand_call_goal(H2,F2,I2),
strip_subst_module(I2,F2,J2,K2),
- '$call_with_inference_counting'('$module_call'(J2,K2)).
+ '$module_call'(J2,K2).
:-non_counted_backtracking call/58.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
@@ -1675,7 +1692,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(I2,H2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2),
expand_call_goal(I2,G2,J2),
strip_subst_module(J2,G2,K2,L2),
- '$call_with_inference_counting'('$module_call'(K2,L2)).
+ '$module_call'(K2,L2).
:-non_counted_backtracking call/59.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
@@ -1688,7 +1705,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(J2,I2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2),
expand_call_goal(J2,H2,K2),
strip_subst_module(K2,H2,L2,M2),
- '$call_with_inference_counting'('$module_call'(L2,M2)).
+ '$module_call'(L2,M2).
:-non_counted_backtracking call/60.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
@@ -1701,7 +1718,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(K2,J2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2),
expand_call_goal(K2,I2,L2),
strip_subst_module(L2,I2,M2,N2),
- '$call_with_inference_counting'('$module_call'(M2,N2)).
+ '$module_call'(M2,N2).
:-non_counted_backtracking call/61.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
@@ -1714,7 +1731,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(L2,K2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2),
expand_call_goal(L2,J2,M2),
strip_subst_module(M2,J2,N2,O2),
- '$call_with_inference_counting'('$module_call'(N2,O2)).
+ '$module_call'(N2,O2).
:-non_counted_backtracking call/62.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
@@ -1727,7 +1744,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(M2,L2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2),
expand_call_goal(M2,K2,N2),
strip_subst_module(N2,K2,O2,P2),
- '$call_with_inference_counting'('$module_call'(O2,P2)).
+ '$module_call'(O2,P2).
:-non_counted_backtracking call/63.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
@@ -1740,7 +1757,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(N2,M2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2),
expand_call_goal(N2,L2,O2),
strip_subst_module(O2,L2,P2,Q2),
- '$call_with_inference_counting'('$module_call'(P2,Q2)).
+ '$module_call'(P2,Q2).
:-non_counted_backtracking call/64.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
@@ -1753,7 +1770,7 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(O2,N2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2),
expand_call_goal(O2,M2,P2),
strip_subst_module(P2,M2,Q2,R2),
- '$call_with_inference_counting'('$module_call'(Q2,R2)).
+ '$module_call'(Q2,R2).
:-non_counted_backtracking call/65.
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
@@ -1766,4 +1783,4 @@ call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1
'$prepare_call_clause'(P2,O2,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2),
expand_call_goal(P2,N2,Q2),
strip_subst_module(Q2,N2,R2,S2),
- '$call_with_inference_counting'('$module_call'(R2,S2)).
+ '$module_call'(R2,S2).
diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs
index 02087865..21d46a85 100644
--- a/src/machine/arithmetic_ops.rs
+++ b/src/machine/arithmetic_ops.rs
@@ -1,7 +1,9 @@
use dashu::base::Abs;
+use dashu::base::DivRem;
use dashu::base::Gcd;
use dashu::integer::IBig;
use divrem::*;
+use num_order::NumOrd;
use crate::arena::*;
use crate::arithmetic::*;
@@ -50,9 +52,7 @@ macro_rules! drop_iter_on_err {
};
}
-fn zero_divisor_eval_error(
- stub_gen: impl Fn() -> FunctorStub + 'static,
-) -> MachineStubGen {
+fn zero_divisor_eval_error(stub_gen: impl Fn() -> FunctorStub + 'static) -> MachineStubGen {
Box::new(move |machine_st| {
let eval_error = machine_st.evaluation_error(EvalError::ZeroDivisor);
let stub = stub_gen();
@@ -61,9 +61,7 @@ fn zero_divisor_eval_error(
})
}
-fn undefined_eval_error(
- stub_gen: impl Fn() -> FunctorStub + 'static,
-) -> MachineStubGen {
+fn undefined_eval_error(stub_gen: impl Fn() -> FunctorStub + 'static) -> MachineStubGen {
Box::new(move |machine_st| {
let eval_error = machine_st.evaluation_error(EvalError::Undefined);
let stub = stub_gen();
@@ -169,9 +167,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result {
- Ok(Number::arena_from(&*n1 + &*n2, arena))
- }
+ | (Number::Rational(n2), Number::Integer(n1)) => Ok(Number::arena_from(&*n1 + &*n2, arena)),
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
@@ -179,9 +175,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result {
Ok(Number::Float(add_f(f1, f2)?))
}
- (Number::Rational(r1), Number::Rational(r2)) => {
- Ok(Number::arena_from(&*r1 + &*r2, arena))
- }
+ (Number::Rational(r1), Number::Rational(r2)) => Ok(Number::arena_from(&*r1 + &*r2, arena)),
}
}
@@ -197,12 +191,12 @@ pub(crate) fn neg(n: Number, arena: &mut Arena) -> Number {
Number::Integer(n) => {
let n_clone: Integer = (*n).clone();
Number::arena_from(-Integer::from(n_clone), arena)
- },
+ }
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
Number::Rational(r) => {
let r_clone: Rational = (*r).clone();
Number::arena_from(-Rational::from(r_clone), arena)
- },
+ }
}
}
@@ -219,12 +213,12 @@ pub(crate) fn abs(n: Number, arena: &mut Arena) -> Number {
Number::Integer(n) => {
let n_clone: Integer = (*n).clone();
Number::arena_from(Integer::from(n_clone.abs()), arena)
- },
+ }
Number::Float(f) => Number::Float(f.abs()),
Number::Rational(r) => {
let r_clone: Rational = (*r).clone();
Number::arena_from(Rational::from(r_clone.abs()), arena)
- },
+ }
}
}
@@ -368,7 +362,11 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result {
let n2_i = n2.get_num();
- if !(&*n1 == &Integer::from(1) || &*n1 == &Integer::from(0) || &*n1 == &Integer::from(-1)) && n2_i < 0 {
+ if !(&*n1 == &Integer::from(1)
+ || &*n1 == &Integer::from(0)
+ || &*n1 == &Integer::from(-1))
+ && n2_i < 0
+ {
let n = Number::Integer(n1);
Err(numerical_type_error(ValidType::Float, n, stub_gen))
} else {
@@ -377,7 +375,11 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result {
- if !(&*n1 == &Integer::from(1) || &*n1 == &Integer::from(0) || &*n1 == &Integer::from(-1)) && &*n2 < &Integer::from(0) {
+ if !(&*n1 == &Integer::from(1)
+ || &*n1 == &Integer::from(0)
+ || &*n1 == &Integer::from(-1))
+ && &*n2 < &Integer::from(0)
+ {
let n = Number::Integer(n1);
Err(numerical_type_error(ValidType::Float, n, stub_gen))
} else {
@@ -454,14 +456,14 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result {
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
- if &*n2 > &n1.get_num() {
+ if (&*n2).num_gt(&n1.get_num()) {
Ok(Number::Integer(n2))
} else {
Ok(Number::Fixnum(n1))
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
- if &*n1 > &n2.get_num() {
+ if (&*n1).num_gt(&n2.get_num()) {
Ok(Number::Integer(n1))
} else {
Ok(Number::Fixnum(n2))
@@ -498,14 +500,14 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result {
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
- if &*n2 < &n1.get_num() {
+ if (&*n2).num_lt(&n1.get_num()) {
Ok(Number::Integer(n2))
} else {
Ok(Number::Fixnum(n1))
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
- if &*n1 < &n2.get_num() {
+ if (&*n1).num_lt(&n2.get_num()) {
Ok(Number::Integer(n1))
} else {
Ok(Number::Fixnum(n2))
@@ -552,7 +554,7 @@ pub fn rational_from_number(
Number::Integer(n) => {
let n_clone: Integer = (*n).clone();
Ok(arena_alloc!(Rational::from(n_clone), arena))
- },
+ }
}
}
@@ -560,7 +562,7 @@ pub(crate) fn rdiv(
r1: TypedArenaPtr,
r2: TypedArenaPtr,
) -> Result {
- if &*r2 == &0 {
+ if &*r2 == &Rational::from(0) {
let stub_gen = || {
let rdiv_atom = atom!("rdiv");
functor_stub(rdiv_atom, 2)
@@ -594,7 +596,7 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result {
- if &*n2 == &0 {
+ if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(Integer::from(n1) / &*n2, arena))
@@ -608,11 +610,11 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result {
- if &*n2 == &0 {
+ if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(
- <(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).0,
+ <(Integer, Integer)>::from((&*n1).div_rem(&*n2)).0,
arena,
))
}
@@ -659,31 +661,42 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result> n2, arena));
- } else {
+ } else {
return Ok(Number::arena_from(n1 >> usize::max_value(), arena));
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1.get_num());
- match n2.to_usize() {
- Some(n2) => Ok(Number::arena_from(n1 >> n2, arena)),
- _ => {
- Ok(Number::arena_from(n1 >> usize::max_value(), arena))
- },
+ let result: Result = (&*n2).try_into();
+
+ match result {
+ Ok(n2) => {
+ Ok(Number::arena_from(n1 >> n2, arena))
+ }
+ Err(_) => {
+ Ok(Number::arena_from(n1 >> usize::max_value(), arena))
+ }
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
Ok(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)),
- _ => {
- Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()),arena))
- },
+ _ => Ok(Number::arena_from(
+ Integer::from(&*n1 >> usize::max_value()),
+ arena,
+ )),
},
- (Number::Integer(n1), Number::Integer(n2)) => match n2.to_usize() {
- Some(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)),
- _ => {
- Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
- },
+ (Number::Integer(n1), Number::Integer(n2)) => {
+ let result: Result = (&*n2).try_into();
+
+ match result {
+ Ok(n2) => {
+ Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena))
+ }
+ Err(_) => {
+ Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
+ }
+ }
},
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
@@ -710,15 +723,18 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result {
let n1 = Integer::from(n1.get_num());
- match n2.to_u32() {
- Some(n2) => Ok(Number::arena_from(n1.to_u64().unwrap() << n2, arena)),
+ match (&*n2).try_into() as Result