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.toml b/Cargo.toml
index 8c214b4a..2b8f803f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,15 +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]
-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"
@@ -80,7 +85,19 @@ tokio = { version = "1.28.2", features = ["full"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2.10", features = ["js"] }
-tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt", "time"] }
+tokio = { version = "1.28.2", features = ["sync", "macros", "io-util", "rt"] }
+
+[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/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..4dc9c893 100644
--- a/build/instructions_template.rs
+++ b/build/instructions_template.rs
@@ -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..0631decc 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
}
}
@@ -141,7 +176,7 @@ pub enum ArenaHeaderTag {
OutputFileStream = 0b10100,
NamedTcpStream = 0b011100,
NamedTlsStream = 0b100000,
- HttpReadStream = 0b100001,
+ HttpReadStream = 0b100001,
HttpWriteStream = 0b100010,
ReadlineStream = 0b110000,
StaticStringStream = 0b110100,
@@ -276,7 +311,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 +350,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 +371,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 +418,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 +457,7 @@ impl F64Offset {
#[inline(always)]
pub fn as_ptr(self) -> F64Ptr {
- F64Ptr::from_offset(self.0)
+ F64Ptr::from_offset(self)
}
#[inline(always)]
@@ -577,20 +618,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 +641,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 +705,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 +713,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 +722,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 +756,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::>());
}
@@ -731,29 +775,29 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
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 +845,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 +880,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 +893,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 +909,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 +927,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 +1002,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 +1013,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 +1024,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 +1033,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 +1058,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 +1167,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 a13510b7..95b4fe2c 100644
--- a/src/arithmetic.rs
+++ b/src/arithmetic.rs
@@ -160,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)),
}
@@ -328,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 {
@@ -438,7 +429,7 @@ fn classify_float(f: f64) -> Result {
}
}
FpCategory::Nan => Err(EvalError::Undefined),
- _ => Ok(f)
+ _ => Ok(f),
}
}
@@ -553,8 +544,12 @@ impl PartialEq for Number {
(&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")]
{
@@ -575,8 +570,12 @@ impl PartialEq for Number {
(&**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),
}
@@ -645,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")]
{
@@ -666,8 +667,12 @@ impl Ord for Number {
(&*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),
}
diff --git a/src/atom_table.rs b/src/atom_table.rs
index 79c83805..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(test)]
-thread_local! {
- static ATOM_TABLE_BUF_BASE: std::cell::RefCell<*const u8> = std::cell::RefCell::new(ptr::null_mut());
-}
-
-#[cfg(not(test))]
-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(test)]
+#[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(not(test))]
+ // 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"))]
{
- 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(test)]
- {
- ATOM_TABLE_BUF_BASE.with(|atom_table_buf_base| *atom_table_buf_base.borrow())
-}
-#[cfg(not(test))]
- {
- 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 eb0fd5ff..09465006 100644
--- a/src/bin/scryer-prolog.rs
+++ b/src/bin/scryer-prolog.rs
@@ -1,11 +1,12 @@
fn main() -> std::process::ExitCode {
- use std::sync::atomic::Ordering;
use scryer_prolog::*;
+ use std::sync::atomic::Ordering;
#[cfg(feature = "repl")]
ctrlc::set_handler(move || {
scryer_prolog::machine::INTERRUPT.store(true, Ordering::Relaxed);
- }).unwrap();
+ })
+ .unwrap();
let mut wam = machine::Machine::new();
wam.run_top_level()
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 d22ca6c9..361ed989 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);
@@ -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,8 +1362,8 @@ 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) {
@@ -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);
});
}
@@ -1668,7 +1687,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 +1756,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 +1792,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 +1816,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 +1829,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 +1862,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 +1881,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 +1898,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 +1930,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 +1948,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 +1981,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 +2025,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 71d1682c..13d6ff31 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)]
@@ -28,27 +28,28 @@ impl Service> for HttpService {
type Future = Pin> + Send>>;
fn call(&mut self, req: Request) -> Self::Future {
- // 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) };
- self.tx.send(http_request).unwrap();
+ // 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),
+ };
+ self.tx.send(http_request).unwrap();
- // we wait for the Response info from Prolog
- {
- let (ready, _response, cvar) = &*response;
- let mut ready = ready.lock().unwrap();
- while !*ready {
- ready = cvar.wait(ready).unwrap();
- }
- }
- {
- let (_, response, _) = &*response;
- let response = response.lock().unwrap().take();
- let res = response.expect("Data race error in HTTP Server");
- Box::pin(async move {
- Ok(res)
- })
- }
+ // we wait for the Response info from Prolog
+ {
+ let (ready, _response, cvar) = &*response;
+ let mut ready = ready.lock().unwrap();
+ while !*ready {
+ ready = cvar.wait(ready).unwrap();
+ }
+ }
+ {
+ let (_, response, _) = &*response;
+ let response = response.lock().unwrap().take();
+ let res = response.expect("Data race error in HTTP Server");
+ Box::pin(async move { Ok(res) })
+ }
}
}
diff --git a/src/indexing.rs b/src/indexing.rs
index 54beced1..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));
}
/*
@@ -1148,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>,
@@ -1188,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
}
@@ -1198,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)
}
@@ -1232,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 {
@@ -1319,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
}
@@ -1332,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));
@@ -1344,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 {
@@ -1371,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
@@ -1401,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
@@ -1437,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);
}
@@ -1455,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
}
@@ -1464,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 acae77eb..8817fa5f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -17,13 +17,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"));
@@ -38,3 +38,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..8e88e626 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),
@@ -2186,6 +2220,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 441852ee..0ba61117 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),
@@ -587,6 +596,8 @@ use_module(Module, Exports, Evacuable) :-
).
+:- 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) :-
@@ -599,6 +610,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) ->
@@ -606,12 +618,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)
@@ -648,8 +664,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
@@ -657,10 +671,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),
@@ -890,7 +908,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],
@@ -903,7 +920,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),
@@ -930,7 +947,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) :-
@@ -943,7 +960,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) :-
@@ -956,7 +973,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) :-
@@ -969,7 +986,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) :-
@@ -982,7 +999,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) :-
@@ -995,7 +1012,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) :-
@@ -1008,7 +1025,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) :-
@@ -1021,7 +1038,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) :-
@@ -1034,7 +1051,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) :-
@@ -1047,7 +1064,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) :-
@@ -1060,7 +1077,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) :-
@@ -1073,7 +1090,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) :-
@@ -1086,7 +1103,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) :-
@@ -1099,7 +1116,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) :-
@@ -1112,7 +1129,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) :-
@@ -1125,7 +1142,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) :-
@@ -1138,7 +1155,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) :-
@@ -1151,7 +1168,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) :-
@@ -1164,7 +1181,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) :-
@@ -1177,7 +1194,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) :-
@@ -1190,7 +1207,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) :-
@@ -1203,7 +1220,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) :-
@@ -1216,7 +1233,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) :-
@@ -1229,7 +1246,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) :-
@@ -1242,7 +1259,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) :-
@@ -1255,7 +1272,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) :-
@@ -1268,7 +1285,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) :-
@@ -1281,7 +1298,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) :-
@@ -1294,7 +1311,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) :-
@@ -1307,7 +1324,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) :-
@@ -1320,7 +1337,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) :-
@@ -1333,7 +1350,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) :-
@@ -1346,7 +1363,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) :-
@@ -1359,7 +1376,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) :-
@@ -1372,7 +1389,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) :-
@@ -1385,7 +1402,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) :-
@@ -1398,7 +1415,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) :-
@@ -1411,7 +1428,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) :-
@@ -1424,7 +1441,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) :-
@@ -1437,7 +1454,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) :-
@@ -1450,7 +1467,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) :-
@@ -1463,7 +1480,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) :-
@@ -1476,7 +1493,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) :-
@@ -1489,7 +1506,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) :-
@@ -1502,7 +1519,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) :-
@@ -1515,7 +1532,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) :-
@@ -1528,7 +1545,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) :-
@@ -1541,7 +1558,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) :-
@@ -1554,7 +1571,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) :-
@@ -1567,7 +1584,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) :-
@@ -1580,7 +1597,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) :-
@@ -1593,7 +1610,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) :-
@@ -1606,7 +1623,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) :-
@@ -1619,7 +1636,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) :-
@@ -1632,7 +1649,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) :-
@@ -1645,7 +1662,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) :-
@@ -1658,7 +1675,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) :-
@@ -1671,7 +1688,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) :-
@@ -1684,7 +1701,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) :-
@@ -1697,7 +1714,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) :-
@@ -1710,7 +1727,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) :-
@@ -1723,7 +1740,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) :-
@@ -1736,7 +1753,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) :-
@@ -1749,7 +1766,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) :-
@@ -1762,4 +1779,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 da2f28d6..21d46a85 100644
--- a/src/machine/arithmetic_ops.rs
+++ b/src/machine/arithmetic_ops.rs
@@ -52,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();
@@ -63,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();
@@ -171,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)?))
@@ -181,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)),
}
}
@@ -199,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)
- },
+ }
}
}
@@ -221,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)
- },
+ }
}
}
@@ -370,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 {
@@ -379,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 {
@@ -554,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))
- },
+ }
}
}
@@ -661,7 +661,7 @@ 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));
}
}
@@ -681,9 +681,10 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result 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)) => {
let result: Result = (&*n2).try_into();
@@ -722,7 +723,7 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result Result 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).try_into() as Result {
Ok(n2) => {
@@ -967,10 +969,7 @@ pub(crate) fn gcd(n1: Number, n2: Number, arena: &mut Arena) -> Result {
@@ -1069,12 +1068,14 @@ pub(crate) fn atanh(n1: Number) -> Result {
let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
- try_numeric_result!(if f1 == 1.0 || f1 == -1.0 {
- Err(EvalError::Undefined)
- } else {
- result_f(&Number::Float(OrderedFloat(f1.atanh())))
- },
- stub_gen)
+ try_numeric_result!(
+ if f1 == 1.0 || f1 == -1.0 {
+ Err(EvalError::Undefined)
+ } else {
+ result_f(&Number::Float(OrderedFloat(f1.atanh())))
+ },
+ stub_gen
+ )
}
#[inline]
@@ -1126,7 +1127,6 @@ pub(crate) fn floor(n1: Number, arena: &mut Arena) -> Number {
rnd_i(&n1, arena)
}
-
#[inline]
pub(crate) fn ceiling(n1: Number, arena: &mut Arena) -> Number {
let n1 = neg(n1, arena);
@@ -1179,16 +1179,17 @@ impl MachineState {
pub fn get_number(&mut self, at: &ArithmeticTerm) -> Result {
match at {
&ArithmeticTerm::Reg(r) => {
- let value = self.store(self.deref(self[r]));
+ let value = self.store(self.deref(self[r]));
match Number::try_from(value) {
Ok(n) => Ok(n),
Err(_) => self.arith_eval_by_metacall(value),
}
}
- &ArithmeticTerm::Interm(i) => {
- Ok(mem::replace(&mut self.interms[i - 1], Number::Fixnum(Fixnum::build_with(0))))
- }
+ &ArithmeticTerm::Interm(i) => Ok(mem::replace(
+ &mut self.interms[i - 1],
+ Number::Fixnum(Fixnum::build_with(0)),
+ )),
&ArithmeticTerm::Number(n) => Ok(n),
}
}
@@ -1202,11 +1203,14 @@ impl MachineState {
match rational_from_number(n, caller, &mut self.arena) {
Ok(r) => Ok(r),
- Err(e_gen) => Err(e_gen(self))
+ Err(e_gen) => Err(e_gen(self)),
}
}
- pub(crate) fn arith_eval_by_metacall(&mut self, value: HeapCellValue) -> Result {
+ pub(crate) fn arith_eval_by_metacall(
+ &mut self,
+ value: HeapCellValue,
+ ) -> Result {
let stub_gen = || functor_stub(atom!("is"), 2);
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, value);
@@ -1512,26 +1516,11 @@ mod tests {
let mut wam = MachineState::new();
let mut op_dir = default_op_dir();
- op_dir.insert(
- (atom!("+"), Fixity::In),
- OpDesc::build_with(500, YFX as u8),
- );
- op_dir.insert(
- (atom!("-"), Fixity::In),
- OpDesc::build_with(500, YFX as u8),
- );
- op_dir.insert(
- (atom!("-"), Fixity::Pre),
- OpDesc::build_with(200, FY as u8),
- );
- op_dir.insert(
- (atom!("*"), Fixity::In),
- OpDesc::build_with(400, YFX as u8),
- );
- op_dir.insert(
- (atom!("/"), Fixity::In),
- OpDesc::build_with(400, YFX as u8),
- );
+ op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8));
+ op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8));
+ op_dir.insert((atom!("-"), Fixity::Pre), OpDesc::build_with(200, FY as u8));
+ op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8));
+ op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8));
let term_write_result =
parse_and_write_parsed_term_to_heap(&mut wam, "3 + 4 - 1 + 2.", &op_dir).unwrap();
diff --git a/src/machine/attributed_variables.rs b/src/machine/attributed_variables.rs
index 633378a0..0b08e8bb 100644
--- a/src/machine/attributed_variables.rs
+++ b/src/machine/attributed_variables.rs
@@ -118,12 +118,9 @@ impl MachineState {
and_frame[i] = self.registers[i];
}
- and_frame[arity + 1] =
- fixnum_as_cell!(Fixnum::build_with(self.b0 as i64));
- and_frame[arity + 2] =
- fixnum_as_cell!(Fixnum::build_with(self.num_of_args as i64));
- and_frame[arity + 3] =
- fixnum_as_cell!(Fixnum::build_with(self.attr_var_init.cp as i64));
+ and_frame[arity + 1] = fixnum_as_cell!(Fixnum::build_with(self.b0 as i64));
+ and_frame[arity + 2] = fixnum_as_cell!(Fixnum::build_with(self.num_of_args as i64));
+ and_frame[arity + 3] = fixnum_as_cell!(Fixnum::build_with(self.attr_var_init.cp as i64));
self.verify_attributes();
diff --git a/src/machine/code_walker.rs b/src/machine/code_walker.rs
index c2032727..84f4cc93 100644
--- a/src/machine/code_walker.rs
+++ b/src/machine/code_walker.rs
@@ -8,7 +8,9 @@ fn capture_offset(line: &Instruction, index: usize, stack: &mut Vec) -> b
&Instruction::TryMeElse(offset) if offset > 0 => {
stack.push(index + offset);
}
- &Instruction::DefaultRetryMeElse(offset) | &Instruction::RetryMeElse(offset) if offset > 0 => {
+ &Instruction::DefaultRetryMeElse(offset) | &Instruction::RetryMeElse(offset)
+ if offset > 0 =>
+ {
stack.push(index + offset);
}
&Instruction::DynamicElse(_, _, NextOrFail::Next(offset)) if offset > 0 => {
diff --git a/src/machine/compile.rs b/src/machine/compile.rs
index a3575c7f..170bffaf 100644
--- a/src/machine/compile.rs
+++ b/src/machine/compile.rs
@@ -28,17 +28,15 @@ pub(super) fn bootstrapping_compile(
) -> Result<(), SessionError> {
let (wam_prelude, machine_st) = wam.prelude_view_and_machine_st();
- let term_stream = BootstrappingTermStream::from_char_reader(
- stream,
- machine_st,
- listing_src,
- );
+ let term_stream = BootstrappingTermStream::from_char_reader(stream, machine_st, listing_src);
- let payload = BootstrappingLoadState(
- LoadStatePayload::new(wam_prelude.code.len(), term_stream)
- );
+ let payload =
+ BootstrappingLoadState(LoadStatePayload::new(wam_prelude.code.len(), term_stream));
- let loader: Loader<'_, BootstrappingLoadState> = Loader { payload, wam_prelude };
+ let loader: Loader<'_, BootstrappingLoadState> = Loader {
+ payload,
+ wam_prelude,
+ };
loader.load()?;
Ok(())
@@ -98,8 +96,8 @@ fn derelictize_try_me_else(
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(index, *o));
Some(mem::replace(o, 0))
}
- Instruction::DynamicElse(_, _, NextOrFail::Fail(_)) |
- Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => None,
+ Instruction::DynamicElse(_, _, NextOrFail::Fail(_))
+ | Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => None,
Instruction::TryMeElse(0) => None,
Instruction::TryMeElse(ref mut o) => {
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(index, *o));
@@ -154,8 +152,8 @@ fn merge_indices(
fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
loop {
match &code[index] {
- Instruction::DynamicElse(_, _, NextOrFail::Next(i)) |
- Instruction::DynamicInternalElse(_, _, NextOrFail::Next(i))
+ Instruction::DynamicElse(_, _, NextOrFail::Next(i))
+ | Instruction::DynamicInternalElse(_, _, NextOrFail::Next(i))
if *i > 0 =>
{
index += i;
@@ -170,42 +168,37 @@ fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> usize {
loop {
match &code[index] {
- Instruction::TryMeElse(o) |
- Instruction::RetryMeElse(o) => {
+ Instruction::TryMeElse(o) | Instruction::RetryMeElse(o) => {
if *o > 0 {
return index;
} else {
index = index_loc;
}
}
- &Instruction::DynamicElse(_, _, next_or_fail) => {
- match next_or_fail {
- NextOrFail::Next(i) => {
- if i == 0 {
- index = index_loc;
- } else {
- return index;
- }
- }
- NextOrFail::Fail(_) => {
+ &Instruction::DynamicElse(_, _, next_or_fail) => match next_or_fail {
+ NextOrFail::Next(i) => {
+ if i == 0 {
index = index_loc;
- }
- }
- }
- &Instruction::DynamicInternalElse(_, _, next_or_fail) => {
- match next_or_fail {
- NextOrFail::Next(i) => {
- if i == 0 {
- index = index_loc;
- } else {
- return index;
- }
- }
- NextOrFail::Fail(_) => {
+ } else {
return index;
}
}
- }
+ NextOrFail::Fail(_) => {
+ index = index_loc;
+ }
+ },
+ &Instruction::DynamicInternalElse(_, _, next_or_fail) => match next_or_fail {
+ NextOrFail::Next(i) => {
+ if i == 0 {
+ index = index_loc;
+ } else {
+ return index;
+ }
+ }
+ NextOrFail::Fail(_) => {
+ return index;
+ }
+ },
Instruction::TrustMe(_) => {
return index;
}
@@ -215,11 +208,7 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
index += v;
}
IndexingCodePtr::DynamicExternal(v) => match &code[index + v] {
- &Instruction::DynamicInternalElse(
- _,
- _,
- NextOrFail::Next(0),
- ) => {
+ &Instruction::DynamicInternalElse(_, _, NextOrFail::Next(0)) => {
return index + v;
}
_ => {
@@ -309,8 +298,7 @@ fn merge_indexed_subsequences(
code[inner_try_me_else_loc] = Instruction::TrustMe(o);
}
_ => {
- code[inner_try_me_else_loc] =
- Instruction::RetryMeElse(o);
+ code[inner_try_me_else_loc] = Instruction::RetryMeElse(o);
}
},
}
@@ -376,7 +364,9 @@ fn delete_from_skeleton(
}
if skeleton.core.is_dynamic {
- skeleton.core.add_retracted_dynamic_clause_info(clause_index_info);
+ skeleton
+ .core
+ .add_retracted_dynamic_clause_info(clause_index_info);
retraction_info.push_record(RetractionRecord::RemovedDynamicSkeletonClause(
compilation_target,
@@ -409,8 +399,8 @@ fn blunt_leading_choice_instr(
code[instr_loc] = Instruction::TryMeElse(*o);
return instr_loc;
}
- Instruction::DynamicElse(_, _, NextOrFail::Next(_)) |
- Instruction::DynamicInternalElse(_, _, NextOrFail::Next(_)) => {
+ Instruction::DynamicElse(_, _, NextOrFail::Next(_))
+ | Instruction::DynamicInternalElse(_, _, NextOrFail::Next(_)) => {
return instr_loc;
}
&mut Instruction::DynamicElse(b, d, NextOrFail::Fail(o)) => {
@@ -422,26 +412,19 @@ fn blunt_leading_choice_instr(
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Next(0));
return instr_loc;
}
- &mut Instruction::DynamicInternalElse(
- b,
- d,
- NextOrFail::Fail(o),
- ) => {
+ &mut Instruction::DynamicInternalElse(b, d, NextOrFail::Fail(o)) => {
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
instr_loc,
NextOrFail::Fail(o),
));
- code[instr_loc] = Instruction::DynamicInternalElse(
- b,
- d,
- NextOrFail::Next(0),
- );
+ code[instr_loc] = Instruction::DynamicInternalElse(b, d, NextOrFail::Next(0));
return instr_loc;
}
Instruction::TrustMe(o) => {
- retraction_info.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
+ retraction_info
+ .push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
code[instr_loc] = Instruction::TryMeElse(0);
return instr_loc + 1;
@@ -481,9 +464,9 @@ fn set_switch_var_offset_to_choice_instr(
};
match &code[index_loc + v] {
- Instruction::TryMeElse(_) |
- Instruction::DynamicElse(..) |
- Instruction::DynamicInternalElse(..) => {}
+ Instruction::TryMeElse(_)
+ | Instruction::DynamicElse(..)
+ | Instruction::DynamicInternalElse(..) => {}
_ => {
set_switch_var_offset(code, index_loc, offset, retraction_info);
}
@@ -523,9 +506,8 @@ fn internalize_choice_instr_at(
retraction_info: &mut RetractionInfo,
) {
match &mut code[instr_loc] {
- Instruction::DynamicElse(_, _, NextOrFail::Fail(_)) |
- Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => {
- }
+ Instruction::DynamicElse(_, _, NextOrFail::Fail(_))
+ | Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => {}
Instruction::DynamicElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, 0));
*o = NextOrFail::Fail(0);
@@ -554,18 +536,10 @@ fn internalize_choice_instr_at(
match &mut code[instr_loc + o] {
Instruction::RevJmpBy(p) if *p == 0 => {
- code[instr_loc] = Instruction::DynamicInternalElse(
- b,
- d,
- NextOrFail::Fail(o),
- );
+ code[instr_loc] = Instruction::DynamicInternalElse(b, d, NextOrFail::Fail(o));
}
_ => {
- code[instr_loc] = Instruction::DynamicInternalElse(
- b,
- d,
- NextOrFail::Next(o),
- );
+ code[instr_loc] = Instruction::DynamicInternalElse(b, d, NextOrFail::Next(o));
}
}
}
@@ -609,23 +583,20 @@ fn thread_choice_instr_at_to(
*o = target_loc - instr_loc;
return;
}
- Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)) |
- Instruction::DynamicInternalElse(
- _,
- _,
- NextOrFail::Next(ref mut o),
- ) if target_loc >= instr_loc => {
+ Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o))
+ | Instruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o))
+ if target_loc >= instr_loc =>
+ {
retraction_info
.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, *o));
*o = target_loc - instr_loc;
return;
}
- Instruction::DynamicElse(_, _, NextOrFail::Next(o)) |
- Instruction::DynamicInternalElse(_, _, NextOrFail::Next(o)) => {
+ Instruction::DynamicElse(_, _, NextOrFail::Next(o))
+ | Instruction::DynamicInternalElse(_, _, NextOrFail::Next(o)) => {
instr_loc += *o;
}
- Instruction::TryMeElse(o)
- | Instruction::RetryMeElse(o) => {
+ Instruction::TryMeElse(o) | Instruction::RetryMeElse(o) => {
instr_loc += *o;
}
Instruction::RevJmpBy(ref mut o) if instr_loc >= target_loc => {
@@ -642,7 +613,8 @@ fn thread_choice_instr_at_to(
{
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
- code[instr_loc] = instr!("dynamic_else",
+ code[instr_loc] = instr!(
+ "dynamic_else",
birth,
death,
NextOrFail::Next(target_loc - instr_loc)
@@ -653,14 +625,13 @@ fn thread_choice_instr_at_to(
Instruction::DynamicElse(_, _, NextOrFail::Fail(o)) if *o > 0 => {
instr_loc += *o;
}
- &mut Instruction::DynamicInternalElse(
- birth,
- death,
- ref mut fail,
- ) if target_loc >= instr_loc => {
+ &mut Instruction::DynamicInternalElse(birth, death, ref mut fail)
+ if target_loc >= instr_loc =>
+ {
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
- code[instr_loc] = instr!("dynamic_internal_else",
+ code[instr_loc] = instr!(
+ "dynamic_internal_else",
birth,
death,
NextOrFail::Next(target_loc - instr_loc)
@@ -668,9 +639,7 @@ fn thread_choice_instr_at_to(
return;
}
- Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(o))
- if *o > 0 =>
- {
+ Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(o)) if *o > 0 => {
instr_loc += *o;
}
Instruction::TrustMe(ref mut o) if target_loc >= instr_loc => {
@@ -711,33 +680,31 @@ fn remove_non_leading_clause(
None
}
- Instruction::TrustMe(_) => {
- match &mut code[preceding_choice_instr_loc] {
- Instruction::RetryMeElse(o) => {
- retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(
- preceding_choice_instr_loc,
- *o,
- ));
+ Instruction::TrustMe(_) => match &mut code[preceding_choice_instr_loc] {
+ Instruction::RetryMeElse(o) => {
+ retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(
+ preceding_choice_instr_loc,
+ *o,
+ ));
- code[preceding_choice_instr_loc] = Instruction::TrustMe(0);
+ code[preceding_choice_instr_loc] = Instruction::TrustMe(0);
- None
- }
- Instruction::TryMeElse(ref mut o) => {
- retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
- preceding_choice_instr_loc,
- *o,
- ));
-
- *o = 0;
-
- Some(IndexPtr::index(preceding_choice_instr_loc + 1))
- }
- _ => {
- unreachable!();
- }
+ None
}
- }
+ Instruction::TryMeElse(ref mut o) => {
+ retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
+ preceding_choice_instr_loc,
+ *o,
+ ));
+
+ *o = 0;
+
+ Some(IndexPtr::index(preceding_choice_instr_loc + 1))
+ }
+ _ => {
+ unreachable!();
+ }
+ },
_ => {
unreachable!();
}
@@ -988,11 +955,7 @@ fn prepend_compiled_clause(
Instruction::TryMeElse(ref mut o) if *o == 0 => {
*o = prepend_queue_len - 2;
}
- Instruction::DynamicInternalElse(
- _,
- _,
- ref mut o @ NextOrFail::Next(0),
- ) => {
+ Instruction::DynamicInternalElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
*o = NextOrFail::Fail(prepend_queue_len - 2);
}
_ => {
@@ -1258,7 +1221,11 @@ fn print_overwrite_warning(
_ => {}
}
- println!("Warning: overwriting {}/{} because the clauses are discontiguous", key.0.as_str(), key.1);
+ println!(
+ "Warning: overwriting {}/{} because the clauses are discontiguous",
+ key.0.as_str(),
+ key.1
+ );
}
impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
@@ -1270,8 +1237,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
if let Some(path_str) = load_context.path.to_str() {
if !path_str.is_empty() {
- return Some(LS::machine_st(&mut self.payload).atom_tbl.build_with(
- path_str
+ return Some(AtomTable::build_with(
+ &LS::machine_st(&mut self.payload).atom_tbl,
+ path_str,
));
}
}
@@ -1290,10 +1258,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let clause = self.try_term_to_tl(term, &mut preprocessor)?;
// let queue = preprocessor.parse_queue(self)?;
- let mut cg = CodeGenerator::new(
- &mut LS::machine_st(&mut self.payload).atom_tbl,
- settings,
- );
+ let mut cg = CodeGenerator::new(&LS::machine_st(&mut self.payload).atom_tbl, settings);
let clause_code = cg.compile_predicate(vec![clause])?;
@@ -1323,10 +1288,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
clauses.push(self.try_term_to_tl(term, &mut preprocessor)?);
}
- let mut cg = CodeGenerator::new(
- &mut LS::machine_st(&mut self.payload).atom_tbl,
- settings,
- );
+ let mut cg = CodeGenerator::new(&LS::machine_st(&mut self.payload).atom_tbl, settings);
let mut code = cg.compile_predicate(clauses)?;
@@ -1361,26 +1323,23 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.clause_clause_locs
.extend(&clause_clause_locs.make_contiguous()[0..]);
- self.payload.retraction_info
- .push_record(RetractionRecord::SkeletonClauseTruncateBack(
+ self.payload.retraction_info.push_record(
+ RetractionRecord::SkeletonClauseTruncateBack(
predicates.compilation_target,
key,
skeleton_clause_len,
- ));
+ ),
+ );
}
None => {
cg.skeleton
- .core
- .clause_clause_locs
- .extend(&clause_clause_locs.make_contiguous()[0..]);
+ .core
+ .clause_clause_locs
+ .extend(&clause_clause_locs.make_contiguous()[0..]);
let skeleton = cg.skeleton;
- self.add_extensible_predicate(
- key,
- skeleton,
- predicates.compilation_target,
- );
+ self.add_extensible_predicate(key, skeleton, predicates.compilation_target);
}
};
@@ -1450,11 +1409,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
skeleton.clause_clause_locs = clause_clause_locs;
- self.add_local_extensible_predicate(
- *compilation_target,
- *key,
- skeleton,
- );
+ self.add_local_extensible_predicate(*compilation_target, *key, skeleton);
}
}
}
@@ -1490,11 +1445,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
skeleton.clause_clause_locs.push_front(code_len);
- self.add_local_extensible_predicate(
- *compilation_target,
- *key,
- skeleton,
- );
+ self.add_local_extensible_predicate(*compilation_target, *key, skeleton);
}
}
}
@@ -1530,11 +1481,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
skeleton.clause_clause_locs.push_back(code_len);
- self.add_local_extensible_predicate(
- *compilation_target,
- *key,
- skeleton,
- );
+ self.add_local_extensible_predicate(*compilation_target, *key, skeleton);
}
}
}
@@ -1606,7 +1553,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
skeleton.core.clause_clause_locs.push_back(code_len);
- self.payload.retraction_info
+ self.payload
+ .retraction_info
.push_record(RetractionRecord::SkeletonClausePopBack(
compilation_target,
key,
@@ -1624,8 +1572,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.push_back_to_local_predicate_skeleton(&compilation_target, &key, code_len);
- let code_index =
- self.get_or_insert_code_index(key, compilation_target);
+ let code_index = self.get_or_insert_code_index(key, compilation_target);
if let Some(new_code_ptr) = result {
set_code_index(
@@ -1646,7 +1593,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
skeleton.core.clause_clause_locs.push_front(code_len);
skeleton.core.clause_assert_margin += 1;
- self.payload.retraction_info
+ self.payload
+ .retraction_info
.push_record(RetractionRecord::SkeletonClausePopFront(
compilation_target,
key,
@@ -1666,8 +1614,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.push_front_to_local_predicate_skeleton(&compilation_target, &key, code_len);
- let code_index =
- self.get_or_insert_code_index(key, compilation_target);
+ let code_index = self.get_or_insert_code_index(key, compilation_target);
set_code_index(
&mut self.payload.retraction_info,
@@ -1698,19 +1645,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.opt_arg_index_key
.switch_on_term_loc()
{
- Some(index_loc) => {
- find_inner_choice_instr(
- &self.wam_prelude.code,
- skeleton.clauses[target_pos].clause_start,
- index_loc,
- )
- }
+ Some(index_loc) => find_inner_choice_instr(
+ &self.wam_prelude.code,
+ skeleton.clauses[target_pos].clause_start,
+ index_loc,
+ ),
None => skeleton.clauses[target_pos].clause_start,
};
match &mut self.wam_prelude.code[clause_loc] {
- Instruction::DynamicElse(_, ref mut d, _) |
- Instruction::DynamicInternalElse(_, ref mut d, _) => {
+ Instruction::DynamicElse(_, ref mut d, _)
+ | Instruction::DynamicInternalElse(_, ref mut d, _) => {
*d = Death::Finite(LS::machine_st(&mut self.payload).global_clock);
}
_ => unreachable!(),
@@ -1797,11 +1742,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
skeleton.clauses[target_pos + 1].clause_start =
skeleton.clauses[target_pos].clause_start;
- let update_code_index = target_pos == 0 &&
- skeleton.clauses[target_pos + 1]
- .opt_arg_index_key
- .switch_on_term_loc()
- .is_none();
+ let update_code_index = target_pos == 0
+ && skeleton.clauses[target_pos + 1]
+ .opt_arg_index_key
+ .switch_on_term_loc()
+ .is_none();
let index_ptr_opt = if update_code_index {
Some(IndexPtr::index(clause_loc))
@@ -1964,7 +1909,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
index_loc,
);
- let lower_bound_clause_start = skeleton.clauses[lower_bound].clause_start;
+ let lower_bound_clause_start =
+ skeleton.clauses[lower_bound].clause_start;
let preceding_choice_instr_loc;
match &mut code[clause_start] {
@@ -2093,13 +2039,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
clause_clauses: ClauseIter,
append_or_prepend: AppendOrPrepend,
) -> Result<(), SessionError> {
- let clause_predicates = clause_clauses.map(|(head, body)| {
- Term::Clause(
- Cell::default(),
- atom!("$clause"),
- vec![head, body],
- )
- });
+ let clause_predicates = clause_clauses
+ .map(|(head, body)| Term::Clause(Cell::default(), atom!("$clause"), vec![head, body]));
let clause_clause_compilation_target = match compilation_target {
CompilationTarget::User => CompilationTarget::Module(atom!("builtins")),
@@ -2132,21 +2073,21 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.cloned()
.collect()
}
- Some(skeleton) => {
- skeleton.core.clause_clause_locs.make_contiguous()[0..num_clause_predicates]
- .iter()
- .cloned()
- .collect()
- }
+ Some(skeleton) => skeleton.core.clause_clause_locs.make_contiguous()
+ [0..num_clause_predicates]
+ .iter()
+ .cloned()
+ .collect(),
None => {
unreachable!()
}
};
- match self.wam_prelude.indices.get_predicate_skeleton_mut(
- &clause_clause_compilation_target,
- &(atom!("$clause"), 2),
- ) {
+ match self
+ .wam_prelude
+ .indices
+ .get_predicate_skeleton_mut(&clause_clause_compilation_target, &(atom!("$clause"), 2))
+ {
Some(skeleton) if append_or_prepend.is_append() => {
for _ in 0..num_clause_predicates {
skeleton.core.clause_clause_locs.pop_back();
@@ -2270,25 +2211,25 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
println!(
"Warning: overwriting multifile predicate {}:{}/{} because \
it was not locally declared multifile.",
- self.payload.predicates.compilation_target, key.0.as_str(), key.1
+ self.payload.predicates.compilation_target,
+ key.0.as_str(),
+ key.1
);
}
- if let Some(skeleton) = self
- .wam_prelude
- .indices
- .remove_predicate_skeleton(&self.payload.predicates.compilation_target, &key)
- {
+ if let Some(skeleton) = self.wam_prelude.indices.remove_predicate_skeleton(
+ &self.payload.predicates.compilation_target,
+ &key,
+ ) {
let compilation_target = self.payload.predicates.compilation_target;
if predicate_info.is_dynamic {
- let clause_clause_compilation_target =
- match compilation_target {
- CompilationTarget::User => {
- CompilationTarget::Module(atom!("builtins"))
- }
- module => module,
- };
+ let clause_clause_compilation_target = match compilation_target {
+ CompilationTarget::User => {
+ CompilationTarget::Module(atom!("builtins"))
+ }
+ module => module,
+ };
self.retract_local_clauses_by_locs(
clause_clause_compilation_target,
@@ -2301,11 +2242,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
self.payload.retraction_info.push_record(
- RetractionRecord::RemovedSkeleton(
- compilation_target,
- key,
- skeleton,
- ),
+ RetractionRecord::RemovedSkeleton(compilation_target, key, skeleton),
);
}
}
@@ -2328,9 +2265,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
match self.wam_prelude.indices.modules.get_mut(&filename) {
Some(ref mut module) => {
let index_ptr = code_index.get();
- let code_index = module.code_dir.entry(key)
- .or_insert(code_index)
- .clone();
+ let code_index = module.code_dir.entry(key).or_insert(code_index).clone();
set_code_index(
&mut self.payload.retraction_info,
@@ -2349,8 +2284,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
LS::machine_st(&mut self.payload).global_clock += 1;
let clause_clauses_len = self.payload.clause_clauses.len();
- let clauses_vec: Vec<_> = self.payload
- .clause_clauses.drain(0..std::cmp::min(predicates_len, clause_clauses_len))
+ let clauses_vec: Vec<_> = self
+ .payload
+ .clause_clauses
+ .drain(0..std::cmp::min(predicates_len, clause_clauses_len))
.collect();
let compilation_target = self.payload.predicates.compilation_target;
@@ -2374,10 +2311,7 @@ impl Machine {
module_name: HeapCellValue,
key: PredicateKey,
) -> CodeIndex {
- let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(
- self,
- InlineTermStream {},
- );
+ let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(self, InlineTermStream {});
let module_name = if module_name.get_tag() == HeapCellValueTag::Atom {
cell_as_atom!(module_name)
@@ -2394,10 +2328,8 @@ impl Machine {
vars: &[Term],
) -> Result<(), SessionError> {
let mut compile = || {
- let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(
- self,
- InlineTermStream {},
- );
+ let mut loader: Loader<'_, InlineLoadState<'_>> =
+ Loader::new(self, InlineTermStream {});
let term = loader.read_term_from_heap(term_loc)?;
let clause = build_rule_body(vars, term);
diff --git a/src/machine/copier.rs b/src/machine/copier.rs
index 23330fd5..01f7e8bd 100644
--- a/src/machine/copier.rs
+++ b/src/machine/copier.rs
@@ -91,12 +91,16 @@ impl CopyTermState {
self.target.push(hcv);
}
- let cdr = self.target.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
+ let cdr = self
+ .target
+ .store(self.target.deref(heap_loc_as_cell!(addr + 1)));
if !cdr.is_var() {
self.trail_list_cell(addr + 1, threshold);
} else {
- let car = self.target.store(self.target.deref(heap_loc_as_cell!(addr)));
+ let car = self
+ .target
+ .store(self.target.deref(heap_loc_as_cell!(addr)));
if !car.is_var() {
self.trail_list_cell(addr, threshold);
@@ -188,10 +192,10 @@ impl CopyTermState {
while let HeapCellValueTag::Lis = list_addr.get_tag() {
let threshold = self.target.threshold();
let heap_loc = list_addr.get_value() as usize;
- let str_loc = self.target[heap_loc].get_value() as usize;
+ let str_loc = self.target[heap_loc].get_value() as usize;
- self.target.push(heap_loc_as_cell!(threshold+2));
- self.target.push(heap_loc_as_cell!(threshold+1));
+ self.target.push(heap_loc_as_cell!(threshold + 2));
+ self.target.push(heap_loc_as_cell!(threshold + 1));
read_heap_cell!(self.target[str_loc],
(HeapCellValueTag::Atom) => {
@@ -377,8 +381,9 @@ 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)]));
assert_eq!(wam.machine_st.heap[0], atom_as_cell!(f_atom, 2));
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
@@ -401,20 +406,26 @@ mod tests {
wam.machine_st.heap.clear();
- 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];
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];
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 wam = TermCopyingMockWAM { wam: &mut wam };
@@ -428,14 +439,20 @@ mod tests {
assert_eq!(wam.machine_st.heap[2], pstr_second_cell);
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(4));
assert_eq!(wam.machine_st.heap[4], pstr_offset_as_cell!(0));
- assert_eq!(wam.machine_st.heap[5], fixnum_as_cell!(Fixnum::build_with(0i64)));
+ assert_eq!(
+ wam.machine_st.heap[5],
+ fixnum_as_cell!(Fixnum::build_with(0i64))
+ );
assert_eq!(wam.machine_st.heap[7], pstr_cell);
assert_eq!(wam.machine_st.heap[8], pstr_loc_as_cell!(9));
assert_eq!(wam.machine_st.heap[9], pstr_second_cell);
assert_eq!(wam.machine_st.heap[10], pstr_loc_as_cell!(11));
assert_eq!(wam.machine_st.heap[11], pstr_offset_as_cell!(7));
- assert_eq!(wam.machine_st.heap[12], fixnum_as_cell!(Fixnum::build_with(0i64)));
+ assert_eq!(
+ wam.machine_st.heap[12],
+ fixnum_as_cell!(Fixnum::build_with(0i64))
+ );
wam.machine_st.heap.clear();
diff --git a/src/machine/disjuncts.rs b/src/machine/disjuncts.rs
index 96da0a8d..a8a01d36 100644
--- a/src/machine/disjuncts.rs
+++ b/src/machine/disjuncts.rs
@@ -74,7 +74,7 @@ impl BranchNumber {
fn halve_delta(&self) -> BranchNumber {
BranchNumber {
branch_num: self.branch_num.clone(),
- delta : &self.delta / Rational::from(2),
+ delta: &self.delta / Rational::from(2),
}
}
}
@@ -108,7 +108,10 @@ pub struct BranchInfo {
impl BranchInfo {
fn new(branch_num: BranchNumber) -> Self {
- Self { branch_num, chunks: vec![] }
+ Self {
+ branch_num,
+ chunks: vec![],
+ }
}
}
@@ -149,11 +152,11 @@ enum TraversalState {
// where it leaves off.
BuildFinalDisjunct(usize),
Fail,
- GetCutPoint{ var_num: usize, prev_b: bool },
+ GetCutPoint { var_num: usize, prev_b: bool },
Cut { var_num: usize, is_global: bool },
ResetCallPolicy(CallPolicy),
Term(Term),
- RemoveBranchNum, // pop the current_branch_num and from the root set.
+ RemoveBranchNum, // pop the current_branch_num and from the root set.
AddBranchNum(BranchNumber), // set current_branch_num, add it to the root set
RepBranchNum(BranchNumber), // replace current_branch_num and the latest in the root set
}
@@ -179,22 +182,22 @@ pub struct VarData {
impl VarData {
fn emit_initial_get_level(&mut self, build_stack: &mut ChunkedTermVec) {
- let global_cut_var_num =
- if let &Some(global_cut_var_num) = &self.global_cut_var_num {
- match &self.records[global_cut_var_num].allocation {
- VarAlloc::Perm(..) => Some(global_cut_var_num),
- VarAlloc::Temp { term_loc, .. } if term_loc.chunk_num() > 0 => {
- Some(global_cut_var_num)
- }
- _ => None
+ let global_cut_var_num = if let &Some(global_cut_var_num) = &self.global_cut_var_num {
+ match &self.records[global_cut_var_num].allocation {
+ VarAlloc::Perm(..) => Some(global_cut_var_num),
+ VarAlloc::Temp { term_loc, .. } if term_loc.chunk_num() > 0 => {
+ Some(global_cut_var_num)
}
- } else {
- None
- };
+ _ => None,
+ }
+ } else {
+ None
+ };
if let Some(global_cut_var_num) = global_cut_var_num {
let term = QueryTerm::GetLevel(global_cut_var_num);
- self.records[global_cut_var_num].allocation = VarAlloc::Perm(0, PermVarAllocation::Pending);
+ self.records[global_cut_var_num].allocation =
+ VarAlloc::Perm(0, PermVarAllocation::Pending);
match build_stack.front_mut() {
Some(ChunkedTerms::Branch(_)) => {
@@ -229,7 +232,7 @@ fn merge_branch_seq(branches: impl Iterator- ) -> BranchInfo {
}
fn flatten_into_disjunct(build_stack: &mut ChunkedTermVec, preceding_len: usize) {
- let branch_vec = build_stack.drain(preceding_len + 1 ..).collect();
+ let branch_vec = build_stack.drain(preceding_len + 1..).collect();
if let ChunkedTerms::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] {
disjuncts.push(branch_vec);
@@ -254,11 +257,14 @@ impl VariableClassifier {
pub fn classify_fact(mut self, term: Term) -> Result {
self.classify_head_variables(&term)?;
- Ok((term, self.branch_map.separate_and_classify_variables(
- self.var_num,
- self.global_cut_var_num,
- self.current_chunk_num,
- )))
+ Ok((
+ term,
+ self.branch_map.separate_and_classify_variables(
+ self.var_num,
+ self.global_cut_var_num,
+ self.current_chunk_num,
+ ),
+ ))
}
pub fn classify_rule<'a, LS: LoadState<'a>>(
@@ -298,7 +304,7 @@ impl VariableClassifier {
}
}
- let iter = old_branches.drain(old_branches_len - 1 ..);
+ let iter = old_branches.drain(old_branches_len - 1..);
branches.push(merge_branch_seq(iter));
}
@@ -346,9 +352,13 @@ impl VariableClassifier {
}
fn probe_body_var(&mut self, var_info: VarInfo) {
- let term_loc = self.current_chunk_type.to_gen_context(self.current_chunk_num);
+ let term_loc = self
+ .current_chunk_type
+ .to_gen_context(self.current_chunk_num);
- let branch_info_v = self.branch_map.entry(var_info.var_ptr.clone())
+ let branch_info_v = self
+ .branch_map
+ .entry(var_info.var_ptr.clone())
.or_insert_with(|| vec![]);
let needs_new_branch = if let Some(last_bi) = branch_info_v.last() {
@@ -396,12 +406,14 @@ impl VariableClassifier {
fn classify_head_variables(&mut self, term: &Term) -> Result<(), CompilationError> {
match term {
- Term::Clause(..) | Term::Literal(_, Literal::Atom(_)) => {
- }
+ Term::Clause(..) | Term::Literal(_, Literal::Atom(_)) => {}
_ => return Err(CompilationError::InvalidRuleHead),
}
- let mut classify_info = ClassifyInfo { arg_c: 1, arity: term.arity() };
+ let mut classify_info = ClassifyInfo {
+ arg_c: 1,
+ arity: term.arity(),
+ };
match term {
Term::Clause(_, _, terms) => {
@@ -414,13 +426,16 @@ impl VariableClassifier {
// the body of the if let here is an inlined
// "probe_head_var". note the difference between it
// and "probe_body_var".
- let branch_info_v = self.branch_map.entry(var_ptr.clone())
+ let branch_info_v = self
+ .branch_map
+ .entry(var_ptr.clone())
.or_insert_with(|| vec![]);
let needs_new_branch = branch_info_v.is_empty();
if needs_new_branch {
- branch_info_v.push(BranchInfo::new(self.current_branch_num.clone()));
+ branch_info_v
+ .push(BranchInfo::new(self.current_branch_num.clone()));
}
let branch_info = branch_info_v.last_mut().unwrap();
@@ -509,13 +524,11 @@ impl VariableClassifier {
self.probe_in_situ_var(var_num);
- build_stack.push_chunk_term(
- if is_global {
- QueryTerm::GlobalCut(var_num)
- } else {
- QueryTerm::LocalCut(var_num)
- }
- );
+ build_stack.push_chunk_term(if is_global {
+ QueryTerm::GlobalCut(var_num)
+ } else {
+ QueryTerm::LocalCut(var_num)
+ });
}
TraversalState::Fail => {
build_stack.push_chunk_term(QueryTerm::Fail);
@@ -539,22 +552,28 @@ impl VariableClassifier {
classifier.probe_body_term(arg_c + 1, terms.len(), term);
}
- build_stack.push_chunk_term(
- clause_to_query_term(
- loader,
- name,
- terms,
- classifier.call_policy,
- ),
- );
+ build_stack.push_chunk_term(clause_to_query_term(
+ loader,
+ name,
+ terms,
+ classifier.call_policy,
+ ));
};
match term {
- Term::Clause(_, name @ (atom!("->") | atom!(";") | atom!(",")), mut terms) if terms.len() == 3 => {
+ Term::Clause(
+ _,
+ name @ (atom!("->") | atom!(";") | atom!(",")),
+ mut terms,
+ ) if terms.len() == 3 => {
if let Some(last_arg) = terms.last() {
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
terms.pop();
- state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), name, terms)));
+ state_stack.push(TraversalState::Term(Term::Clause(
+ Cell::default(),
+ name,
+ terms,
+ )));
} else {
add_chunk(self, name, terms);
}
@@ -583,7 +602,7 @@ impl VariableClassifier {
let mut branch_numbers = vec![first_branch_num];
- for idx in 1 .. branches.len() {
+ for idx in 1..branches.len() {
let succ_branch_number = branch_numbers[idx - 1].incr_by_delta();
branch_numbers.push(if idx + 1 < branches.len() {
@@ -610,8 +629,11 @@ impl VariableClassifier {
state_stack.push(TraversalState::AddBranchNum(branch_num));
}
- if let TraversalState::BuildDisjunct(build_stack_len) = state_stack[final_disjunct_loc] {
- state_stack[final_disjunct_loc] = TraversalState::BuildFinalDisjunct(build_stack_len);
+ if let TraversalState::BuildDisjunct(build_stack_len) =
+ state_stack[final_disjunct_loc]
+ {
+ state_stack[final_disjunct_loc] =
+ TraversalState::BuildFinalDisjunct(build_stack_len);
}
self.current_chunk_type = ChunkType::Mid;
@@ -621,18 +643,30 @@ impl VariableClassifier {
let then_term = terms.pop().unwrap();
let if_term = terms.pop().unwrap();
- let prev_b = if matches!(state_stack.last(), Some(TraversalState::RemoveBranchNum)) {
+ let prev_b = if matches!(
+ state_stack.last(),
+ Some(TraversalState::RemoveBranchNum)
+ ) {
// check if the second-to-last element is a regular BuildDisjunct, as we don't
// want to add GetPrevLevel in case of a TrustMe.
- matches!(state_stack.iter().rev().nth(1), Some(TraversalState::BuildDisjunct(..)))
+ matches!(
+ state_stack.iter().rev().nth(1),
+ Some(TraversalState::BuildDisjunct(..))
+ )
} else {
false
};
state_stack.push(TraversalState::Term(then_term));
- state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false });
+ state_stack.push(TraversalState::Cut {
+ var_num: self.var_num,
+ is_global: false,
+ });
state_stack.push(TraversalState::Term(if_term));
- state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b });
+ state_stack.push(TraversalState::GetCutPoint {
+ var_num: self.var_num,
+ prev_b,
+ });
self.var_num += 1;
}
@@ -643,12 +677,22 @@ impl VariableClassifier {
build_stack.reserve_branch(2);
state_stack.push(TraversalState::BuildFinalDisjunct(build_stack_len));
- state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), atom!("$succeed"), vec![])));
+ state_stack.push(TraversalState::Term(Term::Clause(
+ Cell::default(),
+ atom!("$succeed"),
+ vec![],
+ )));
state_stack.push(TraversalState::BuildDisjunct(build_stack_len));
state_stack.push(TraversalState::Fail);
- state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false });
+ state_stack.push(TraversalState::Cut {
+ var_num: self.var_num,
+ is_global: false,
+ });
state_stack.push(TraversalState::Term(not_term));
- state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b: true });
+ state_stack.push(TraversalState::GetCutPoint {
+ var_num: self.var_num,
+ prev_b: true,
+ });
self.current_chunk_type = ChunkType::Mid;
self.current_chunk_num += 1;
@@ -668,15 +712,13 @@ impl VariableClassifier {
build_stack.add_chunk();
}
- build_stack.push_chunk_term(
- qualified_clause_to_query_term(
- loader,
- module_name,
- predicate_name,
- vec![],
- self.call_policy,
- ),
- );
+ build_stack.push_chunk_term(qualified_clause_to_query_term(
+ loader,
+ module_name,
+ predicate_name,
+ vec![],
+ self.call_policy,
+ ));
}
(
Term::Literal(_, Literal::Atom(module_name)),
@@ -690,15 +732,13 @@ impl VariableClassifier {
self.probe_body_term(arg_c + 1, terms.len(), term);
}
- build_stack.push_chunk_term(
- qualified_clause_to_query_term(
- loader,
- module_name,
- name,
- terms,
- self.call_policy,
- ),
- );
+ build_stack.push_chunk_term(qualified_clause_to_query_term(
+ loader,
+ module_name,
+ name,
+ terms,
+ self.call_policy,
+ ));
}
(module_name, predicate_name) => {
if update_chunk_data(self, atom!("call"), 2) {
@@ -711,18 +751,18 @@ impl VariableClassifier {
terms.push(module_name);
terms.push(predicate_name);
- build_stack.push_chunk_term(
- clause_to_query_term(
- loader,
- atom!("call"),
- vec![Term::Clause(Cell::default(), atom!(":"), terms)],
- self.call_policy,
- ),
- );
+ build_stack.push_chunk_term(clause_to_query_term(
+ loader,
+ atom!("call"),
+ vec![Term::Clause(Cell::default(), atom!(":"), terms)],
+ self.call_policy,
+ ));
}
}
}
- Term::Clause(_, atom!("$call_with_inference_counting"), mut terms) if terms.len() == 1 => {
+ Term::Clause(_, atom!("$call_with_inference_counting"), mut terms)
+ if terms.len() == 1 =>
+ {
state_stack.push(TraversalState::ResetCallPolicy(self.call_policy));
state_stack.push(TraversalState::Term(terms.pop().unwrap()));
@@ -738,14 +778,12 @@ impl VariableClassifier {
self.probe_body_term(1, 1, &var);
- build_stack.push_chunk_term(
- clause_to_query_term(
- loader,
- atom!("call"),
- vec![var],
- self.call_policy,
- ),
- );
+ build_stack.push_chunk_term(clause_to_query_term(
+ loader,
+ atom!("call"),
+ vec![var],
+ self.call_policy,
+ ));
}
Term::Literal(_, Literal::Atom(atom!("!")) | Literal::Char('!')) => {
if self.global_cut_var_num.is_none() {
@@ -765,14 +803,12 @@ impl VariableClassifier {
build_stack.add_chunk();
}
- build_stack.push_chunk_term(
- clause_to_query_term(
- loader,
- name,
- vec![],
- self.call_policy,
- ),
- );
+ build_stack.push_chunk_term(clause_to_query_term(
+ loader,
+ name,
+ vec![],
+ self.call_policy,
+ ));
}
_ => {
return Err(CompilationError::InadmissibleQueryTerm);
@@ -800,12 +836,11 @@ impl BranchMap {
};
for (var, branches) in self.iter_mut() {
- let (mut var_num, var_num_incr) =
- if let Var::InSitu(var_num) = *var.borrow() {
- (var_num, false)
- } else {
- (var_data.records.len(), true)
- };
+ let (mut var_num, var_num_incr) = if let Var::InSitu(var_num) = *var.borrow() {
+ (var_num, false)
+ } else {
+ (var_data.records.len(), true)
+ };
for branch in branches.iter_mut() {
if var_num_incr {
@@ -813,7 +848,8 @@ impl BranchMap {
var_data.records.push(VariableRecord::default());
}
- if branch.chunks.len() <= 1 { // true iff var is a temporary variable.
+ if branch.chunks.len() <= 1 {
+ // true iff var is a temporary variable.
debug_assert_eq!(branch.chunks.len(), 1);
let chunk = &mut branch.chunks[0];
@@ -822,7 +858,9 @@ impl BranchMap {
for var_info in chunk.vars.iter_mut() {
if var_info.lvl == Level::Shallow {
let term_loc = var_info.chunk_type.to_gen_context(chunk.chunk_num);
- temp_var_data.use_set.insert((term_loc, var_info.classify_info.arg_c));
+ temp_var_data
+ .use_set
+ .insert((term_loc, var_info.classify_info.arg_c));
}
}
diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs
index dc55ed86..89174091 100644
--- a/src/machine/dispatch.rs
+++ b/src/machine/dispatch.rs
@@ -1,10 +1,10 @@
use crate::arena::*;
use crate::atom_table::*;
use crate::instructions::*;
-use crate::machine::*;
use crate::machine::arithmetic_ops::*;
use crate::machine::machine_errors::*;
use crate::machine::machine_state::*;
+use crate::machine::*;
use crate::types::*;
use crate::try_numeric_result;
@@ -59,17 +59,16 @@ impl MachineState {
let a2 = self.registers[2];
let a3 = self.registers[3];
- let check_atom = |machine_st: &mut MachineState, name: Atom, arity: usize| -> Result<(), MachineStub> {
- match name {
- atom!(">") | atom!("<") | atom!("=") if arity == 0 => {
- Ok(())
+ let check_atom =
+ |machine_st: &mut MachineState, name: Atom, arity: usize| -> Result<(), MachineStub> {
+ match name {
+ atom!(">") | atom!("<") | atom!("=") if arity == 0 => Ok(()),
+ _ => {
+ let err = machine_st.domain_error(DomainErrorType::Order, a1);
+ Err(machine_st.error_form(err, stub_gen()))
+ }
}
- _ => {
- let err = machine_st.domain_error(DomainErrorType::Order, a1);
- Err(machine_st.error_form(err, stub_gen()))
- }
- }
- };
+ };
read_heap_cell!(a1,
(HeapCellValueTag::Atom, (name, arity)) => {
@@ -127,13 +126,9 @@ impl MachineState {
compare_term_test!(self, *v1, *v2).unwrap_or(Ordering::Less)
});
- list.dedup_by(|v1, v2| {
- compare_term_test!(self, *v1, *v2) == Some(Ordering::Equal)
- });
+ list.dedup_by(|v1, v2| compare_term_test!(self, *v1, *v2) == Some(Ordering::Equal));
- let heap_addr = heap_loc_as_cell!(
- iter_to_heap_list(&mut self.heap, list.into_iter())
- );
+ let heap_addr = heap_loc_as_cell!(iter_to_heap_list(&mut self.heap, list.into_iter()));
let target_addr = self.registers[2];
@@ -159,9 +154,7 @@ impl MachineState {
});
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
- let heap_addr = heap_loc_as_cell!(
- iter_to_heap_list(&mut self.heap, key_pairs)
- );
+ let heap_addr = heap_loc_as_cell!(iter_to_heap_list(&mut self.heap, key_pairs));
let target_addr = self.registers[2];
@@ -312,11 +305,7 @@ impl Machine {
pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> {
loop {
match &self.code[p] {
- &Instruction::DynamicElse(
- birth,
- death,
- NextOrFail::Next(i),
- ) => {
+ &Instruction::DynamicElse(birth, death, NextOrFail::Next(i)) => {
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
return Some((p, i));
} else if i > 0 {
@@ -325,22 +314,14 @@ impl Machine {
return None;
}
}
- &Instruction::DynamicElse(
- birth,
- death,
- NextOrFail::Fail(_),
- ) => {
+ &Instruction::DynamicElse(birth, death, NextOrFail::Fail(_)) => {
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
return Some((p, 0));
} else {
return None;
}
}
- &Instruction::DynamicInternalElse(
- birth,
- death,
- NextOrFail::Next(i),
- ) => {
+ &Instruction::DynamicInternalElse(birth, death, NextOrFail::Next(i)) => {
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
return Some((p, i));
} else if i > 0 {
@@ -349,11 +330,7 @@ impl Machine {
return None;
}
}
- &Instruction::DynamicInternalElse(
- birth,
- death,
- NextOrFail::Fail(_),
- ) => {
+ &Instruction::DynamicInternalElse(birth, death, NextOrFail::Fail(_)) => {
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
return Some((p, 0));
} else {
@@ -370,7 +347,11 @@ impl Machine {
}
}
- pub(super) fn find_living_dynamic(&self, oi: u32, mut ii: u32) -> Option<(usize, u32, u32, bool)> {
+ pub(super) fn find_living_dynamic(
+ &self,
+ oi: u32,
+ mut ii: u32,
+ ) -> Option<(usize, u32, u32, bool)> {
let p = self.machine_st.p;
let indexed_choice_instrs = match &self.code[p] {
@@ -386,12 +367,9 @@ impl Machine {
loop {
match &indexed_choice_instrs.get(ii as usize) {
Some(&offset) => match &self.code[p + offset - 1] {
- &Instruction::DynamicInternalElse(
- birth,
- death,
- next_or_fail,
- ) => {
- if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
+ &Instruction::DynamicInternalElse(birth, death, next_or_fail) => {
+ if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death
+ {
return Some((offset, oi, ii, next_or_fail.is_next()));
} else {
ii += 1;
@@ -418,7 +396,9 @@ impl Machine {
match &machine.code[p - 1] {
&Instruction::DynamicInternalElse(birth, death, _) => {
- if birth < machine.machine_st.cc && Death::Finite(machine.machine_st.cc) <= death {
+ if birth < machine.machine_st.cc
+ && Death::Finite(machine.machine_st.cc) <= death
+ {
return true;
} else {
return false;
@@ -434,9 +414,9 @@ impl Machine {
let mut index = 0;
let addr = match &indexing_lines[0] {
- &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(arg, ..)) => {
- self.machine_st.store(self.machine_st.deref(self.machine_st.registers[arg]))
- }
+ &IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(arg, ..)) => self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st.registers[arg])),
_ => {
unreachable!()
}
@@ -445,7 +425,9 @@ impl Machine {
loop {
match &indexing_lines[index] {
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, c, l, s)) => {
- let offset = self.machine_st.select_switch_on_term_index(addr, v, c, l, s);
+ let offset = self
+ .machine_st
+ .select_switch_on_term_index(addr, v, c, l, s);
match offset {
IndexingCodePtr::Fail => {
@@ -560,4850 +542,4967 @@ impl Machine {
#[inline(always)]
pub(super) fn dispatch_loop(&mut self) -> std::process::ExitCode {
'outer: loop {
- for _ in 0 .. INSTRUCTIONS_PER_INTERRUPT_POLL {
- match &self.code[self.machine_st.p] {
- &Instruction::BreakFromDispatchLoop => {
- break 'outer;
- }
- &Instruction::InstallVerifyAttr => {
- self.machine_st.p = self.machine_st.attr_var_init.p;
+ for _ in 0..INSTRUCTIONS_PER_INTERRUPT_POLL {
+ match &self.code[self.machine_st.p] {
+ &Instruction::BreakFromDispatchLoop => {
+ break 'outer;
+ }
+ &Instruction::InstallVerifyAttr => {
+ self.machine_st.p = self.machine_st.attr_var_init.p;
+
+ if self.code[self.machine_st.p].is_execute() {
+ self.machine_st.p = self.machine_st.attr_var_init.cp;
+ } else {
+ self.machine_st.p += 1;
+ self.machine_st.cp = self.machine_st.attr_var_init.cp;
+ }
+
+ let mut p = self.machine_st.p;
+
+ while self.code[p].is_head_instr() {
+ p += 1;
+ }
+
+ let instr =
+ std::mem::replace(&mut self.code[p], Instruction::VerifyAttrInterrupt);
+
+ self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr;
+ self.machine_st.attr_var_init.cp = p;
+ }
+ &Instruction::VerifyAttrInterrupt => {
+ let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
+ let arity = std::cmp::max(arity, self.machine_st.num_of_args);
+ self.run_verify_attr_interrupt(arity);
+ }
+ &Instruction::Add(ref a1, ref a2, t) => {
+ let stub_gen = || functor_stub(atom!("is"), 2);
+
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ try_numeric_result!(add(n1, n2, &mut self.machine_st.arena), stub_gen)
+ );
- if self.code[self.machine_st.p].is_execute() {
- self.machine_st.p = self.machine_st.attr_var_init.cp;
- } else {
self.machine_st.p += 1;
- self.machine_st.cp = self.machine_st.attr_var_init.cp;
}
+ &Instruction::Sub(ref a1, ref a2, t) => {
+ let stub_gen = || functor_stub(atom!("is"), 2);
- let mut p = self.machine_st.p;
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- while self.code[p].is_head_instr() {
- p += 1;
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen)
+ );
+
+ self.machine_st.p += 1;
}
+ &Instruction::Mul(ref a1, ref a2, t) => {
+ let stub_gen = || functor_stub(atom!("is"), 2);
- let instr = std::mem::replace(
- &mut self.code[p],
- Instruction::VerifyAttrInterrupt,
- );
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr;
- self.machine_st.attr_var_init.cp = p;
- }
- &Instruction::VerifyAttrInterrupt => {
- let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
- let arity = std::cmp::max(arity, self.machine_st.num_of_args);
- self.run_verify_attr_interrupt(arity);
- }
- &Instruction::Add(ref a1, ref a2, t) => {
- let stub_gen = || functor_stub(atom!("is"), 2);
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ try_numeric_result!(mul(n1, n2, &mut self.machine_st.arena), stub_gen)
+ );
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- try_numeric_result!(add(n1, n2, &mut self.machine_st.arena), stub_gen)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Sub(ref a1, ref a2, t) => {
- let stub_gen = || functor_stub(atom!("is"), 2);
-
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Mul(ref a1, ref a2, t) => {
- let stub_gen = || functor_stub(atom!("is"), 2);
-
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- try_numeric_result!(mul(n1, n2, &mut self.machine_st.arena), stub_gen)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Max(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- max(n1, n2)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Min(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- min(n1, n2)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::IntPow(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- int_pow(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Gcd(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- gcd(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Pow(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- pow(n1, n2, atom!("**"))
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::RDiv(ref a1, ref a2, t) => {
- let stub_gen = || functor_stub(atom!("(rdiv)"), 2);
-
- let r1 = try_or_throw!(self.machine_st, self.machine_st.get_rational(a1, stub_gen));
- let r2 = try_or_throw!(self.machine_st, self.machine_st.get_rational(a2, stub_gen));
-
- self.machine_st.interms[t - 1] = Number::Rational(arena_alloc!(
- try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)),
- &mut self.machine_st.arena
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::IntFloorDiv(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- int_floor_div(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::IDiv(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- idiv(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Abs(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = abs(n1, &mut self.machine_st.arena);
- self.machine_st.p += 1;
- }
- &Instruction::Sign(ref a1, t) => {
- let n = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = n.sign();
- self.machine_st.p += 1;
- }
- &Instruction::Neg(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = neg(n1, &mut self.machine_st.arena);
- self.machine_st.p += 1;
- }
- &Instruction::BitwiseComplement(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- bitwise_complement(n1, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Div(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- div(n1, n2)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Shr(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- shr(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Shl(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- shl(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Xor(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- xor(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::And(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- and(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Or(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- or(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Mod(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- modulus(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Rem(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
- &mut self.machine_st,
- remainder(n1, n2, &mut self.machine_st.arena)
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::Cos(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, cos(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Sin(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, sin(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Tan(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, tan(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Sqrt(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, sqrt(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Log(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, log(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Exp(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, exp(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ACos(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, acos(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ASin(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, asin(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ATan(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, atan(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ATan2(ref a1, ref a2, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, atan2(n1, n2))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ACosh(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, acosh(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ASinh(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, asinh(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::ATanh(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, atanh(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Cosh(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, cosh(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Sinh(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, sinh(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Tanh(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, tanh(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Log10(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, log10(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Float(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, float(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Truncate(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = truncate(n1, &mut self.machine_st.arena);
- self.machine_st.p += 1;
- }
- &Instruction::Round(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] =
- try_or_throw_gen!(&mut self.machine_st, round(n1, &mut self.machine_st.arena));
-
- self.machine_st.p += 1;
- }
- &Instruction::Ceiling(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = ceiling(n1, &mut self.machine_st.arena);
- self.machine_st.p += 1;
- }
- &Instruction::Floor(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = floor(n1, &mut self.machine_st.arena);
- self.machine_st.p += 1;
- }
- &Instruction::FloatFractionalPart(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, float_fractional_part(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::FloatIntegerPart(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, float_integer_part(n1))
- ));
-
- self.machine_st.p += 1;
- }
- &Instruction::Plus(ref a1, t) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
-
- self.machine_st.interms[t - 1] = n1;
- self.machine_st.p += 1;
- }
- &Instruction::DynamicElse(..) => {
- if let FirstOrNext::First = self.machine_st.dynamic_mode {
- self.machine_st.cc = self.machine_st.global_clock;
+ self.machine_st.p += 1;
}
+ &Instruction::Max(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- let p = self.machine_st.p;
+ self.machine_st.interms[t - 1] =
+ try_or_throw_gen!(&mut self.machine_st, max(n1, n2));
- match self.find_living_dynamic_else(p) {
- Some((p, next_i)) => {
- self.machine_st.p = p;
- self.machine_st.oip = 0;
- self.machine_st.iip = 0;
+ self.machine_st.p += 1;
+ }
+ &Instruction::Min(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- match self.machine_st.dynamic_mode {
- FirstOrNext::First if next_i == 0 => {
- self.machine_st.p += 1;
- }
- FirstOrNext::First => {
- self.machine_st.cc = self.machine_st.global_clock;
+ self.machine_st.interms[t - 1] =
+ try_or_throw_gen!(&mut self.machine_st, min(n1, n2));
- match self.find_living_dynamic_else(p + next_i) {
- Some(_) => {
- self.machine_st.registers[self.machine_st.num_of_args + 1] =
- fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
+ self.machine_st.p += 1;
+ }
+ &Instruction::IntPow(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.num_of_args += 1;
- self.try_me_else(next_i);
- self.machine_st.num_of_args -= 1;
- }
- None => {
- self.machine_st.p += 1;
- }
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ int_pow(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Gcd(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ gcd(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Pow(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] =
+ try_or_throw_gen!(&mut self.machine_st, pow(n1, n2, atom!("**")));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::RDiv(ref a1, ref a2, t) => {
+ let stub_gen = || functor_stub(atom!("(rdiv)"), 2);
+
+ let r1 = try_or_throw!(
+ self.machine_st,
+ self.machine_st.get_rational(a1, stub_gen)
+ );
+ let r2 = try_or_throw!(
+ self.machine_st,
+ self.machine_st.get_rational(a2, stub_gen)
+ );
+
+ self.machine_st.interms[t - 1] = Number::Rational(arena_alloc!(
+ try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)),
+ &mut self.machine_st.arena
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::IntFloorDiv(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ int_floor_div(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::IDiv(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ idiv(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Abs(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = abs(n1, &mut self.machine_st.arena);
+ self.machine_st.p += 1;
+ }
+ &Instruction::Sign(ref a1, t) => {
+ let n = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = n.sign();
+ self.machine_st.p += 1;
+ }
+ &Instruction::Neg(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = neg(n1, &mut self.machine_st.arena);
+ self.machine_st.p += 1;
+ }
+ &Instruction::BitwiseComplement(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ bitwise_complement(n1, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Div(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] =
+ try_or_throw_gen!(&mut self.machine_st, div(n1, n2));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Shr(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ shr(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Shl(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ shl(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Xor(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ xor(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::And(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ and(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Or(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ or(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Mod(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ modulus(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Rem(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ remainder(n1, n2, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Cos(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, cos(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Sin(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, sin(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Tan(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, tan(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Sqrt(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, sqrt(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Log(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, log(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Exp(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, exp(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ACos(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, acos(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ASin(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, asin(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ATan(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, atan(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ATan2(ref a1, ref a2, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, atan2(n1, n2)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ACosh(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, acosh(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ASinh(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, asinh(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::ATanh(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, atanh(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Cosh(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, cosh(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Sinh(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, sinh(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Tanh(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, tanh(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Log10(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, log10(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Float(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, float(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Truncate(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = truncate(n1, &mut self.machine_st.arena);
+ self.machine_st.p += 1;
+ }
+ &Instruction::Round(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ &mut self.machine_st,
+ round(n1, &mut self.machine_st.arena)
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Ceiling(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = ceiling(n1, &mut self.machine_st.arena);
+ self.machine_st.p += 1;
+ }
+ &Instruction::Floor(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = floor(n1, &mut self.machine_st.arena);
+ self.machine_st.p += 1;
+ }
+ &Instruction::FloatFractionalPart(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, float_fractional_part(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::FloatIntegerPart(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
+ try_or_throw_gen!(&mut self.machine_st, float_integer_part(n1)),
+ ));
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Plus(ref a1, t) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+
+ self.machine_st.interms[t - 1] = n1;
+ self.machine_st.p += 1;
+ }
+ &Instruction::DynamicElse(..) => {
+ if let FirstOrNext::First = self.machine_st.dynamic_mode {
+ self.machine_st.cc = self.machine_st.global_clock;
+ }
+
+ let p = self.machine_st.p;
+
+ match self.find_living_dynamic_else(p) {
+ Some((p, next_i)) => {
+ self.machine_st.p = p;
+ self.machine_st.oip = 0;
+ self.machine_st.iip = 0;
+
+ match self.machine_st.dynamic_mode {
+ FirstOrNext::First if next_i == 0 => {
+ self.machine_st.p += 1;
}
- }
- FirstOrNext::Next => {
- let n = self.machine_st
- .stack
- .index_or_frame(self.machine_st.b)
- .prelude
- .num_cells;
+ FirstOrNext::First => {
+ self.machine_st.cc = self.machine_st.global_clock;
- self.machine_st.cc = cell_as_fixnum!(
- self.machine_st.stack[stack_loc!(OrFrame, self.machine_st.b, n-1)]
- ).get_num() as usize;
-
- if next_i > 0 {
match self.find_living_dynamic_else(p + next_i) {
Some(_) => {
- self.retry_me_else(next_i);
+ self.machine_st.registers
+ [self.machine_st.num_of_args + 1] = fixnum_as_cell!(
+ Fixnum::build_with(self.machine_st.cc as i64)
+ );
+
+ self.machine_st.num_of_args += 1;
+ self.try_me_else(next_i);
+ self.machine_st.num_of_args -= 1;
}
None => {
- self.trust_me();
+ self.machine_st.p += 1;
}
}
- } else {
- self.trust_me();
}
-
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- }
- None => {
- self.machine_st.fail = true;
- }
- }
-
- self.machine_st.dynamic_mode = FirstOrNext::Next;
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DynamicInternalElse(..) => {
- let p = self.machine_st.p;
-
- match self.find_living_dynamic_else(p) {
- Some((p, next_i)) => {
- self.machine_st.p = p;
- self.machine_st.oip = 0;
- self.machine_st.iip = 0;
-
- match self.machine_st.dynamic_mode {
- FirstOrNext::First if next_i == 0 => {
- self.machine_st.p += 1;
- }
- FirstOrNext::First => {
- match self.find_living_dynamic_else(p + next_i) {
- Some(_) => {
- self.machine_st.registers[self.machine_st.num_of_args + 1] =
- fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
-
- self.machine_st.num_of_args += 1;
- self.try_me_else(next_i);
- self.machine_st.num_of_args -= 1;
- }
- None => {
- self.machine_st.p += 1;
- }
- }
- }
- FirstOrNext::Next => {
- let n = self.machine_st
- .stack
- .index_or_frame(self.machine_st.b)
- .prelude
- .num_cells;
-
- self.machine_st.cc = cell_as_fixnum!(
- self.machine_st.stack[stack_loc!(OrFrame, self.machine_st.b, n-1)]
- ).get_num() as usize;
-
- if next_i > 0 {
- match self.find_living_dynamic_else(p + next_i) {
- Some(_) => {
- self.retry_me_else(next_i);
- }
- None => {
- self.trust_me();
- }
- }
- } else {
- self.trust_me();
- }
-
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- }
- None => {
- self.machine_st.fail = true;
- }
- }
-
- self.machine_st.dynamic_mode = FirstOrNext::Next;
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::TryMeElse(offset) => {
- self.try_me_else(offset);
- }
- &Instruction::DefaultRetryMeElse(offset) => {
- self.retry_me_else(offset);
- }
- &Instruction::DefaultTrustMe(_) => {
- self.trust_me();
- }
- &Instruction::RetryMeElse(offset) => {
- self.retry_me_else(offset);
-
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- &Instruction::TrustMe(_) => {
- self.trust_me();
-
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- &Instruction::NeckCut => {
- self.machine_st.neck_cut();
- self.machine_st.p += 1;
- }
- &Instruction::GetLevel(r) => {
- let b0 = self.machine_st.b0;
-
- self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(b0 as i64));
- self.machine_st.p += 1;
- }
- &Instruction::GetPrevLevel(r) => {
- let prev_b = self.machine_st.stack.index_or_frame(self.machine_st.b).prelude.b;
-
- self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(prev_b as i64));
- self.machine_st.p += 1;
- }
- &Instruction::GetCutPoint(r) => {
- self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(self.machine_st.b as i64));
- self.machine_st.p += 1;
- }
- &Instruction::Cut(r) => {
- let value = self.machine_st[r];
- self.machine_st.cut_body(value);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- continue;
- }
-
- if (self.machine_st.run_cleaners_fn)(self) {
- continue;
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::Allocate(num_cells) => {
- self.machine_st.allocate(num_cells);
- }
- &Instruction::DefaultCallAcyclicTerm => {
- let addr = self.machine_st.registers[1];
-
- if self.machine_st.is_cyclic_term(addr) {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p += 1;
- }
- }
- &Instruction::DefaultExecuteAcyclicTerm => {
- let addr = self.machine_st.registers[1];
-
- if self.machine_st.is_cyclic_term(addr) {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallArg => {
- try_or_throw!(self.machine_st, self.machine_st.try_arg());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteArg => {
- try_or_throw!(self.machine_st, self.machine_st.try_arg());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::DefaultCallCompare => {
- try_or_throw!(self.machine_st, self.machine_st.compare());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteCompare => {
- try_or_throw!(self.machine_st, self.machine_st.compare());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::DefaultCallTermGreaterThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DefaultExecuteTermGreaterThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DefaultCallTermLessThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DefaultExecuteTermLessThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DefaultCallTermGreaterThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Greater | Ordering::Equal) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteTermGreaterThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Greater | Ordering::Equal) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallTermLessThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Less | Ordering::Equal) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteTermLessThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Less | Ordering::Equal) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallCopyTerm => {
- self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteCopyTerm => {
- self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallTermEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if self.machine_st.eq_test(a1, a2) {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p += 1;
- }
- }
- &Instruction::DefaultExecuteTermEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if self.machine_st.eq_test(a1, a2) {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallGround => {
- if self.machine_st.ground_test() {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p += 1;
- }
- }
- &Instruction::DefaultExecuteGround => {
- if self.machine_st.ground_test() {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallFunctor => {
- try_or_throw!(self.machine_st, self.machine_st.try_functor());
-
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteFunctor => {
- try_or_throw!(self.machine_st, self.machine_st.try_functor());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallTermNotEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p += 1;
- }
- }
- &Instruction::DefaultExecuteTermNotEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallSort => {
- try_or_throw!(self.machine_st, self.machine_st.sort());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteSort => {
- try_or_throw!(self.machine_st, self.machine_st.sort());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::DefaultCallKeySort => {
- try_or_throw!(self.machine_st, self.machine_st.keysort(VarComparison::Distinct));
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteKeySort => {
- try_or_throw!(self.machine_st, self.machine_st.keysort(VarComparison::Distinct));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::DefaultCallIs(r, at) => {
- try_or_throw!(self.machine_st, self.machine_st.is(r, at));
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::DefaultExecuteIs(r, at) => {
- try_or_throw!(self.machine_st, self.machine_st.is(r, at));
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- Instruction::DefaultCallGetNumber(at) => {
- try_or_throw!(self.machine_st, self.machine_st.get_number(at));
- step_or_fail!(self, self.machine_st.p += 1);
- }
- Instruction::DefaultExecuteGetNumber(at) => {
- try_or_throw!(self.machine_st, self.machine_st.get_number(at));
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallAcyclicTerm => {
- let addr = self.machine_st.registers[1];
-
- if self.machine_st.is_cyclic_term(addr) {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteAcyclicTerm => {
- let addr = self.machine_st.registers[1];
-
- if self.machine_st.is_cyclic_term(addr) {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallArg => {
- try_or_throw!(self.machine_st, self.machine_st.try_arg());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteArg => {
- try_or_throw!(self.machine_st, self.machine_st.try_arg());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallCompare => {
- try_or_throw!(self.machine_st, self.machine_st.compare());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteCompare => {
- try_or_throw!(self.machine_st, self.machine_st.compare());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallTermGreaterThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2) {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::ExecuteTermGreaterThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2) {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::CallTermLessThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::ExecuteTermLessThan => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- &Instruction::CallTermGreaterThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Greater | Ordering::Equal) => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteTermGreaterThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Greater | Ordering::Equal) => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallTermLessThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Less | Ordering::Equal) => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteTermLessThanOrEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- match compare_term_test!(self.machine_st, a1, a2) {
- Some(Ordering::Less | Ordering::Equal) => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallCopyTerm => {
- self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteCopyTerm => {
- self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallTermEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if self.machine_st.eq_test(a1, a2) {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteTermEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if self.machine_st.eq_test(a1, a2) {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallGround => {
- if self.machine_st.ground_test() {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteGround => {
- if self.machine_st.ground_test() {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallFunctor => {
- try_or_throw!(self.machine_st, self.machine_st.try_functor());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteFunctor => {
- try_or_throw!(self.machine_st, self.machine_st.try_functor());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallTermNotEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteTermNotEqual => {
- let a1 = self.machine_st.registers[1];
- let a2 = self.machine_st.registers[2];
-
- if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallSort => {
- try_or_throw!(self.machine_st, self.machine_st.sort());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteSort => {
- try_or_throw!(self.machine_st, self.machine_st.sort());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallKeySort => {
- try_or_throw!(self.machine_st, self.machine_st.keysort(VarComparison::Distinct));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteKeySort => {
- try_or_throw!(self.machine_st, self.machine_st.keysort(VarComparison::Distinct));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallKeySortWithConstantVarOrdering => {
- try_or_throw!(self.machine_st, self.machine_st.keysort(VarComparison::Indistinct));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteKeySortWithConstantVarOrdering => {
- try_or_throw!(self.machine_st, self.machine_st.keysort(VarComparison::Indistinct));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallIs(r, at) => {
- try_or_throw!(self.machine_st, self.machine_st.is(r, at));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteIs(r, at) => {
- try_or_throw!(self.machine_st, self.machine_st.is(r, at));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- Instruction::CallGetNumber(at) => {
- try_or_throw!(self.machine_st, self.machine_st.get_number(at));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- Instruction::ExecuteGetNumber(at) => {
- try_or_throw!(self.machine_st, self.machine_st.get_number(at));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallN(arity) => {
- let pred = self.machine_st.registers[1];
-
- for i in 2..arity + 1 {
- self.machine_st.registers[i - 1] = self.machine_st.registers[i];
- }
-
- self.machine_st.registers[arity] = pred;
-
- try_or_throw!(
- self.machine_st,
- self.call_n(atom!("user"), arity)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- &Instruction::ExecuteN(arity) => {
- let pred = self.machine_st.registers[1];
-
- for i in 2..arity + 1 {
- self.machine_st.registers[i - 1] = self.machine_st.registers[i];
- }
-
- self.machine_st.registers[arity] = pred;
-
- try_or_throw!(
- self.machine_st,
- self.execute_n(atom!("user"), arity)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- &Instruction::DefaultCallN(arity) => {
- let pred = self.machine_st.registers[1];
-
- for i in 2..arity + 1 {
- self.machine_st.registers[i - 1] = self.machine_st.registers[i];
- }
-
- self.machine_st.registers[arity] = pred;
-
- try_or_throw!(
- self.machine_st,
- self.call_n(atom!("user"), arity)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DefaultExecuteN(arity) => {
- let pred = self.machine_st.registers[1];
-
- for i in 2..arity + 1 {
- self.machine_st.registers[i - 1] = self.machine_st.registers[i];
- }
-
- self.machine_st.registers[arity] = pred;
-
- try_or_throw!(
- self.machine_st,
- self.execute_n(atom!("user"), arity)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less | Ordering::Equal => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less | Ordering::Equal => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallNumberEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteNumberEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallNumberNotEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- self.machine_st.backtrack();
- }
- _ => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- }
- }
- &Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- self.machine_st.backtrack();
- }
- _ => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- }
- }
- &Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater | Ordering::Equal => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater | Ordering::Equal => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallNumberGreaterThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallNumberLessThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteNumberLessThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less => {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
-
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less | Ordering::Equal => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less | Ordering::Equal => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- self.machine_st.backtrack();
- }
- _ => {
- self.machine_st.p += 1;
- }
- }
- }
- &Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- self.machine_st.backtrack();
- }
- _ => {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- }
- &Instruction::DefaultCallNumberEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Equal => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater | Ordering::Equal => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater | Ordering::Equal => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Greater => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2) => {
- let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
- let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
-
- match n1.cmp(&n2) {
- Ordering::Less => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- //
- &Instruction::CallIsAtom(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity == 0 {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Str, s) => {
- let arity = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_arity();
-
- if arity == 0 {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Char) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::ExecuteIsAtom(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity == 0 {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Str, s) => {
- let arity = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_arity();
-
- if arity == 0 {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Char) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::CallIsAtomic(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Char | HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
- HeapCellValueTag::Cons) => {
- self.machine_st.p += 1;
- }
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity == 0 {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Str, s) => {
- let arity = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_arity();
-
- if arity == 0 {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::ExecuteIsAtomic(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Char | HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
- HeapCellValueTag::Cons) => {
- self.machine_st.p = self.machine_st.cp;
- }
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity == 0 {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Str, s) => {
- let arity = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_arity();
-
- if arity == 0 {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::CallIsCompound(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Lis |
- HeapCellValueTag::PStrLoc |
- HeapCellValueTag::CStr) => {
- self.machine_st.p += 1;
- }
- (HeapCellValueTag::Str, s) => {
- let arity = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_arity();
-
- if arity > 0 {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity > 0 {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::ExecuteIsCompound(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Lis |
- HeapCellValueTag::PStrLoc |
- HeapCellValueTag::CStr) => {
- self.machine_st.p = self.machine_st.cp;
- }
- (HeapCellValueTag::Str, s) => {
- let arity = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_arity();
-
- if arity > 0 {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- (HeapCellValueTag::Atom, (_name, arity)) => {
- if arity > 0 {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::CallIsInteger(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match Number::try_from(d) {
- Ok(Number::Fixnum(_) | Number::Integer(_)) => {
- self.machine_st.p += 1;
- }
- Ok(Number::Rational(n)) => {
- if n.denominator().is_one() {
- self.machine_st.p += 1;
- } else {
- self.machine_st.backtrack();
- }
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteIsInteger(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match Number::try_from(d) {
- Ok(Number::Fixnum(_) | Number::Integer(_)) => {
- self.machine_st.p = self.machine_st.cp;
- }
- Ok(Number::Rational(n)) => {
- if n.denominator().is_one() {
- self.machine_st.p = self.machine_st.cp;
- } else {
- self.machine_st.backtrack();
- }
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallIsNumber(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match Number::try_from(d) {
- Ok(_) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteIsNumber(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match Number::try_from(d) {
- Ok(_) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallIsRational(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Cons, ptr) => {
- match_untyped_arena_ptr!(ptr,
- (ArenaHeaderTag::Rational | ArenaHeaderTag::Integer, _r) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- (HeapCellValueTag::Fixnum) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::ExecuteIsRational(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- read_heap_cell!(d,
- (HeapCellValueTag::Cons, ptr) => {
- match_untyped_arena_ptr!(ptr,
- (ArenaHeaderTag::Rational | ArenaHeaderTag::Integer, _r) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- (HeapCellValueTag::Fixnum) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- );
- }
- &Instruction::CallIsFloat(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match Number::try_from(d) {
- Ok(Number::Float(_)) => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteIsFloat(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match Number::try_from(d) {
- Ok(Number::Float(_)) => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallIsNonVar(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match d.get_tag() {
- HeapCellValueTag::AttrVar |
- HeapCellValueTag::Var |
- HeapCellValueTag::StackVar => {
- self.machine_st.backtrack();
- }
- _ => {
- self.machine_st.p += 1;
- }
- }
- }
- &Instruction::ExecuteIsNonVar(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match d.get_tag() {
- HeapCellValueTag::AttrVar |
- HeapCellValueTag::Var |
- HeapCellValueTag::StackVar => {
- self.machine_st.backtrack();
- }
- _ => {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- }
- &Instruction::CallIsVar(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match d.get_tag() {
- HeapCellValueTag::AttrVar |
- HeapCellValueTag::Var |
- HeapCellValueTag::StackVar => {
- self.machine_st.p += 1;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::ExecuteIsVar(r) => {
- let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r]));
-
- match d.get_tag() {
- HeapCellValueTag::AttrVar |
- HeapCellValueTag::Var |
- HeapCellValueTag::StackVar => {
- self.machine_st.p = self.machine_st.cp;
- }
- _ => {
- self.machine_st.backtrack();
- }
- }
- }
- &Instruction::CallNamed(arity, name, ref idx) => {
- let idx = idx.get();
-
- try_or_throw!(
- self.machine_st,
- self.try_call(name, arity, idx)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- &Instruction::ExecuteNamed(arity, name, ref idx) => {
- let idx = idx.get();
-
- try_or_throw!(
- self.machine_st,
- self.try_execute(name, arity, idx)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- &Instruction::DefaultCallNamed(arity, name, ref idx) => {
- let idx = idx.get();
-
- try_or_throw!(
- self.machine_st,
- self.try_call(name, arity, idx)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::DefaultExecuteNamed(arity, name, ref idx) => {
- let idx = idx.get();
-
- try_or_throw!(
- self.machine_st,
- self.try_execute(name, arity, idx)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::Deallocate => {
- self.machine_st.deallocate()
- }
- &Instruction::JmpByCall(offset) => {
- self.machine_st.p += offset;
- }
- &Instruction::RevJmpBy(offset) => {
- self.machine_st.p -= offset;
- }
- &Instruction::Proceed => {
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::GetConstant(_, c, reg) => {
- let value = self.machine_st.deref(self.machine_st[reg]);
- self.machine_st.write_literal_to_var(value, c);
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::GetList(_, reg) => {
- let deref_v = self.machine_st.deref(self.machine_st[reg]);
- let store_v = self.machine_st.store(deref_v);
-
- read_heap_cell!(store_v,
- (HeapCellValueTag::PStrLoc, h) => {
- let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h);
-
- self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize);
- self.machine_st.s_offset = 0;
- self.machine_st.mode = MachineMode::Read;
- }
- (HeapCellValueTag::CStr) => {
- let h = self.machine_st.heap.len();
- self.machine_st.heap.push(store_v);
-
- self.machine_st.s = HeapPtr::PStrChar(h, 0);
- self.machine_st.s_offset = 0;
- self.machine_st.mode = MachineMode::Read;
- }
- (HeapCellValueTag::Str, s) => {
- let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
- .get_name_and_arity();
-
- if name == atom!(".") && arity == 2 {
- self.machine_st.s = HeapPtr::HeapCell(s+1);
- self.machine_st.s_offset = 0;
- self.machine_st.mode = MachineMode::Read;
- } else {
- self.machine_st.backtrack();
- continue;
- }
- }
- (HeapCellValueTag::Lis, l) => {
- self.machine_st.s = HeapPtr::HeapCell(l);
- self.machine_st.s_offset = 0;
- self.machine_st.mode = MachineMode::Read;
- }
- (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
- let h = self.machine_st.heap.len();
-
- self.machine_st.heap.push(list_loc_as_cell!(h+1));
- self.machine_st.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h));
-
- self.machine_st.mode = MachineMode::Write;
- }
- _ => {
- self.machine_st.backtrack();
- continue;
- }
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::GetPartialString(_, string, reg, has_tail) => {
- let deref_v = self.machine_st.deref(self.machine_st[reg]);
- let store_v = self.machine_st.store(deref_v);
-
- read_heap_cell!(store_v,
- (HeapCellValueTag::Str |
- HeapCellValueTag::Lis |
- HeapCellValueTag::PStrLoc |
- HeapCellValueTag::CStr) => {
- self.machine_st.match_partial_string(store_v, string, has_tail);
- }
- (HeapCellValueTag::AttrVar |
- HeapCellValueTag::StackVar |
- HeapCellValueTag::Var) => {
- let target_cell = self.machine_st.push_str_to_heap(
- string.as_str(),
- has_tail,
- );
-
- self.machine_st.bind(
- store_v.as_var().unwrap(),
- target_cell,
- );
- }
- _ => {
- self.machine_st.backtrack();
- continue;
- }
- );
-
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::GetStructure(_lvl, name, arity, reg) => {
- let deref_v = self.machine_st.deref(self.machine_st[reg]);
- let store_v = self.machine_st.store(deref_v);
-
- read_heap_cell!(store_v,
- (HeapCellValueTag::Str, a) => {
- read_heap_cell!(self.machine_st.heap[a],
- (HeapCellValueTag::Atom, (result_name, result_arity)) => {
- if arity == result_arity && name == result_name {
- self.machine_st.s = HeapPtr::HeapCell(a + 1);
- self.machine_st.s_offset = 0;
- self.machine_st.mode = MachineMode::Read;
- } else {
- self.machine_st.backtrack();
- continue;
- }
- }
- _ => {
- unreachable!();
- }
- );
- }
- (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
- let h = self.machine_st.heap.len();
-
- self.machine_st.heap.push(str_loc_as_cell!(h+1));
- self.machine_st.heap.push(atom_as_cell!(name, arity));
-
- self.machine_st.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h));
- self.machine_st.mode = MachineMode::Write;
- }
- _ => {
- self.machine_st.backtrack();
- continue;
- }
- );
-
- self.machine_st.p += 1;
- }
- &Instruction::GetVariable(norm, arg) => {
- self.machine_st[norm] = self.machine_st.registers[arg];
- self.machine_st.p += 1;
- }
- &Instruction::GetValue(norm, arg) => {
- let norm_addr = self.machine_st[norm];
- let reg_addr = self.machine_st.registers[arg];
-
- unify_fn!(&mut self.machine_st, norm_addr, reg_addr);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- continue;
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::UnifyConstant(v) => {
- match self.machine_st.mode {
- MachineMode::Read => {
- let addr = self.machine_st.read_s();
-
- self.machine_st.write_literal_to_var(addr, v);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- continue;
- } else {
- self.machine_st.s_offset += 1;
- }
- }
- MachineMode::Write => {
- self.machine_st.heap.push(v);
- }
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::UnifyLocalValue(reg) => {
- match self.machine_st.mode {
- MachineMode::Read => {
- let reg_addr = self.machine_st[reg];
- let value = self.machine_st.read_s();
-
- unify_fn!(&mut self.machine_st, reg_addr, value);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- continue;
- } else {
- self.machine_st.s_offset += 1;
- }
- }
- MachineMode::Write => {
- let value = self.machine_st.store(self.machine_st.deref(self.machine_st[reg]));
- let h = self.machine_st.heap.len();
-
- read_heap_cell!(value,
- (HeapCellValueTag::Var | HeapCellValueTag::AttrVar, hc) => {
- let value = self.machine_st.heap[hc];
-
- self.machine_st.heap.push(value);
- self.machine_st.s_offset += 1;
- }
- _ => {
- self.machine_st.heap.push(heap_loc_as_cell!(h));
- (self.machine_st.bind_fn)(
- &mut self.machine_st,
- Ref::heap_cell(h),
- value,
- );
- }
- );
- }
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::UnifyVariable(reg) => {
- match self.machine_st.mode {
- MachineMode::Read => {
- self.machine_st[reg] = self.machine_st.read_s();
- self.machine_st.s_offset += 1;
- }
- MachineMode::Write => {
- let h = self.machine_st.heap.len();
-
- self.machine_st.heap.push(heap_loc_as_cell!(h));
- self.machine_st[reg] = heap_loc_as_cell!(h);
- }
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::UnifyValue(reg) => {
- match self.machine_st.mode {
- MachineMode::Read => {
- let reg_addr = self.machine_st[reg];
- let value = self.machine_st.read_s();
-
- unify_fn!(&mut self.machine_st, reg_addr, value);
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- continue;
- } else {
- self.machine_st.s_offset += 1;
- }
- }
- MachineMode::Write => {
- let h = self.machine_st.heap.len();
- self.machine_st.heap.push(heap_loc_as_cell!(h));
-
- let addr = self.machine_st.store(self.machine_st[reg]);
- (self.machine_st.bind_fn)(&mut self.machine_st, Ref::heap_cell(h), addr);
-
- // the former code of this match arm was:
-
- // let addr = self.machine_st.store(self.machine_st[reg]);
- // self.machine_st.heap.push(HeapCellValue::Addr(addr));
-
- // the old code didn't perform the occurs
- // check when enabled and so it was changed to
- // the above, which is only slightly less
- // efficient when the occurs_check is disabled.
- }
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::UnifyVoid(n) => {
- match self.machine_st.mode {
- MachineMode::Read => {
- self.machine_st.s_offset += n;
- }
- MachineMode::Write => {
- let h = self.machine_st.heap.len();
-
- for i in h..h + n {
- self.machine_st.heap.push(heap_loc_as_cell!(i));
- }
- }
- }
-
- self.machine_st.p += 1;
- }
- &Instruction::IndexingCode(ref indexing_lines) => {
- match &indexing_lines[self.machine_st.oip as usize] {
- IndexingLine::Indexing(_) => {
- self.execute_switch_on_term();
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- IndexingLine::IndexedChoice(ref indexed_choice) => {
- match &indexed_choice[self.machine_st.iip as usize] {
- &IndexedChoiceInstruction::Try(offset) => {
- self.indexed_try(offset);
- }
- &IndexedChoiceInstruction::Retry(l) => {
- self.retry(l);
-
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- &IndexedChoiceInstruction::Trust(l) => {
- self.trust(l);
-
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- }
- IndexingLine::DynamicIndexedChoice(_) => {
- let p = self.machine_st.p;
-
- match self.find_living_dynamic(self.machine_st.oip, self.machine_st.iip) {
- Some((offset, oi, ii, is_next_clause)) => {
- self.machine_st.p = p;
- self.machine_st.oip = oi;
- self.machine_st.iip = ii;
-
- match self.machine_st.dynamic_mode {
- FirstOrNext::First if !is_next_clause => {
- self.machine_st.p = p + offset;
- }
- FirstOrNext::First => {
- // there's a leading DynamicElse that sets self.machine_st.cc.
- // self.machine_st.cc = self.machine_st.global_clock;
-
- // see that there is a following dynamic_else
- // clause so we avoid generating a choice
- // point in case there isn't.
- match self.find_living_dynamic(oi, ii + 1) {
+ FirstOrNext::Next => {
+ let n = self
+ .machine_st
+ .stack
+ .index_or_frame(self.machine_st.b)
+ .prelude
+ .num_cells;
+
+ self.machine_st.cc = cell_as_fixnum!(
+ self.machine_st.stack
+ [stack_loc!(OrFrame, self.machine_st.b, n - 1)]
+ )
+ .get_num()
+ as usize;
+
+ if next_i > 0 {
+ match self.find_living_dynamic_else(p + next_i) {
Some(_) => {
- self.machine_st.registers[self.machine_st.num_of_args + 1] =
- fixnum_as_cell!(Fixnum::build_with(self.machine_st.cc as i64));
-
- self.machine_st.num_of_args += 1;
- self.indexed_try(offset);
- self.machine_st.num_of_args -= 1;
+ self.retry_me_else(next_i);
}
None => {
- self.machine_st.p = p + offset;
- self.machine_st.oip = 0;
- self.machine_st.iip = 0;
+ self.trust_me();
}
}
+ } else {
+ self.trust_me();
}
- FirstOrNext::Next => {
- let b = self.machine_st.b;
- let n = self.machine_st
- .stack
- .index_or_frame(b)
- .prelude
- .num_cells;
- self.machine_st.cc = cell_as_fixnum!(
- self.machine_st.stack[stack_loc!(OrFrame, b, n-1)]
- ).get_num() as usize;
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
+ }
+ }
+ None => {
+ self.machine_st.fail = true;
+ }
+ }
- if is_next_clause {
- match self.find_living_dynamic(self.machine_st.oip, self.machine_st.iip + 1) {
- // if we're executing the last instruction
- // of the internal block pointed to by
- // self.machine_st.iip, we want trust, not retry.
- // this is true iff ii + 1 < len.
- Some(_) => {
- self.retry(offset);
+ self.machine_st.dynamic_mode = FirstOrNext::Next;
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- _ => {
- self.trust(offset);
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DynamicInternalElse(..) => {
+ let p = self.machine_st.p;
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
- );
- }
- }
- } else {
- self.trust(offset);
+ match self.find_living_dynamic_else(p) {
+ Some((p, next_i)) => {
+ self.machine_st.p = p;
+ self.machine_st.oip = 0;
+ self.machine_st.iip = 0;
- try_or_throw!(
- self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ match self.machine_st.dynamic_mode {
+ FirstOrNext::First if next_i == 0 => {
+ self.machine_st.p += 1;
+ }
+ FirstOrNext::First => {
+ match self.find_living_dynamic_else(p + next_i) {
+ Some(_) => {
+ self.machine_st.registers
+ [self.machine_st.num_of_args + 1] = fixnum_as_cell!(
+ Fixnum::build_with(self.machine_st.cc as i64)
);
+
+ self.machine_st.num_of_args += 1;
+ self.try_me_else(next_i);
+ self.machine_st.num_of_args -= 1;
+ }
+ None => {
+ self.machine_st.p += 1;
}
}
}
- }
- None => {
- self.machine_st.fail = true;
+ FirstOrNext::Next => {
+ let n = self
+ .machine_st
+ .stack
+ .index_or_frame(self.machine_st.b)
+ .prelude
+ .num_cells;
+
+ self.machine_st.cc = cell_as_fixnum!(
+ self.machine_st.stack
+ [stack_loc!(OrFrame, self.machine_st.b, n - 1)]
+ )
+ .get_num()
+ as usize;
+
+ if next_i > 0 {
+ match self.find_living_dynamic_else(p + next_i) {
+ Some(_) => {
+ self.retry_me_else(next_i);
+ }
+ None => {
+ self.trust_me();
+ }
+ }
+ } else {
+ self.trust_me();
+ }
+
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
}
}
+ None => {
+ self.machine_st.fail = true;
+ }
+ }
- self.machine_st.dynamic_mode = FirstOrNext::Next;
+ self.machine_st.dynamic_mode = FirstOrNext::Next;
- if self.machine_st.fail {
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::TryMeElse(offset) => {
+ self.try_me_else(offset);
+ }
+ &Instruction::DefaultRetryMeElse(offset) => {
+ self.retry_me_else(offset);
+ }
+ &Instruction::DefaultTrustMe(_) => {
+ self.trust_me();
+ }
+ &Instruction::RetryMeElse(offset) => {
+ self.retry_me_else(offset);
+
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+ }
+ &Instruction::TrustMe(_) => {
+ self.trust_me();
+
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+ }
+ &Instruction::NeckCut => {
+ self.machine_st.neck_cut();
+ self.machine_st.p += 1;
+ }
+ &Instruction::GetLevel(r) => {
+ let b0 = self.machine_st.b0;
+
+ self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(b0 as i64));
+ self.machine_st.p += 1;
+ }
+ &Instruction::GetPrevLevel(r) => {
+ let prev_b = self
+ .machine_st
+ .stack
+ .index_or_frame(self.machine_st.b)
+ .prelude
+ .b;
+
+ self.machine_st[r] = fixnum_as_cell!(Fixnum::as_cutpoint(prev_b as i64));
+ self.machine_st.p += 1;
+ }
+ &Instruction::GetCutPoint(r) => {
+ self.machine_st[r] =
+ fixnum_as_cell!(Fixnum::as_cutpoint(self.machine_st.b as i64));
+ self.machine_st.p += 1;
+ }
+ &Instruction::Cut(r) => {
+ let value = self.machine_st[r];
+ self.machine_st.cut_body(value);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ continue;
+ }
+
+ if (self.machine_st.run_cleaners_fn)(self) {
+ continue;
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::Allocate(num_cells) => {
+ self.machine_st.allocate(num_cells);
+ }
+ &Instruction::DefaultCallAcyclicTerm => {
+ let addr = self.machine_st.registers[1];
+
+ if self.machine_st.is_cyclic_term(addr) {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::DefaultExecuteAcyclicTerm => {
+ let addr = self.machine_st.registers[1];
+
+ if self.machine_st.is_cyclic_term(addr) {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::DefaultCallArg => {
+ try_or_throw!(self.machine_st, self.machine_st.try_arg());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::DefaultExecuteArg => {
+ try_or_throw!(self.machine_st, self.machine_st.try_arg());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::DefaultCallCompare => {
+ try_or_throw!(self.machine_st, self.machine_st.compare());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::DefaultExecuteCompare => {
+ try_or_throw!(self.machine_st, self.machine_st.compare());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::DefaultCallTermGreaterThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2)
+ {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DefaultExecuteTermGreaterThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2)
+ {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DefaultCallTermLessThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DefaultExecuteTermLessThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DefaultCallTermGreaterThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Greater | Ordering::Equal) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
self.machine_st.backtrack();
}
}
}
- }
- &Instruction::PutConstant(_, c, reg) => {
- self.machine_st[reg] = c;
- self.machine_st.p += 1;
- }
- &Instruction::PutList(_, reg) => {
- self.machine_st[reg] = list_loc_as_cell!(self.machine_st.heap.len());
- self.machine_st.p += 1;
- }
- &Instruction::PutPartialString(_, string, reg, has_tail) => {
- let pstr_addr = if has_tail {
- if string != atom!("") {
- let h = self.machine_st.heap.len();
- self.machine_st.heap.push(string_as_pstr_cell!(string));
+ &Instruction::DefaultExecuteTermGreaterThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
- // the tail will be pushed by the next
- // instruction, so don't push one here.
-
- pstr_loc_as_cell!(h)
- } else {
- empty_list_as_cell!()
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Greater | Ordering::Equal) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
}
- } else {
- string_as_cstr_cell!(string)
- };
-
- self.machine_st[reg] = pstr_addr;
- self.machine_st.p += 1;
- }
- &Instruction::PutStructure(name, arity, reg) => {
- let h = self.machine_st.heap.len();
-
- self.machine_st.heap.push(atom_as_cell!(name, arity));
- self.machine_st[reg] = str_loc_as_cell!(h);
-
- self.machine_st.p += 1;
- }
- &Instruction::PutUnsafeValue(perm_slot, arg) => {
- let s = stack_loc!(AndFrame, self.machine_st.e, perm_slot);
- let addr = self.machine_st.store(self.machine_st.deref(stack_loc_as_cell!(s)));
-
- if addr.is_protected(self.machine_st.e) {
- self.machine_st.registers[arg] = addr;
- } else {
- let h = self.machine_st.heap.len();
-
- self.machine_st.heap.push(heap_loc_as_cell!(h));
- (self.machine_st.bind_fn)(&mut self.machine_st, Ref::heap_cell(h), addr);
-
- self.machine_st.registers[arg] = heap_loc_as_cell!(h);
}
+ &Instruction::DefaultCallTermLessThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
- self.machine_st.p += 1;
- }
- &Instruction::PutValue(norm, arg) => {
- self.machine_st.registers[arg] = self.machine_st[norm];
- self.machine_st.p += 1;
- }
- &Instruction::PutVariable(norm, arg) => {
- match norm {
- RegType::Perm(n) => {
- self.machine_st[norm] = stack_loc_as_cell!(AndFrame, self.machine_st.e, n);
- self.machine_st.registers[arg] = self.machine_st[norm];
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Less | Ordering::Equal) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
}
- RegType::Temp(_) => {
- let h = self.machine_st.heap.len();
- self.machine_st.heap.push(heap_loc_as_cell!(h));
+ }
+ &Instruction::DefaultExecuteTermLessThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
- self.machine_st[norm] = heap_loc_as_cell!(h);
- self.machine_st.registers[arg] = heap_loc_as_cell!(h);
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Less | Ordering::Equal) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
}
- };
-
- self.machine_st.p += 1;
- }
- &Instruction::SetConstant(c) => {
- self.machine_st.heap.push(c);
- self.machine_st.p += 1;
- }
- &Instruction::SetLocalValue(reg) => {
- let addr = self.machine_st.deref(self.machine_st[reg]);
- let stored_v = self.machine_st.store(addr);
-
- if stored_v.is_stack_var() {
- let h = self.machine_st.heap.len();
- self.machine_st.heap.push(heap_loc_as_cell!(h));
- (self.machine_st.bind_fn)(&mut self.machine_st, Ref::heap_cell(h), stored_v);
- } else {
- self.machine_st.heap.push(stored_v);
}
-
- self.machine_st.p += 1;
- }
- &Instruction::SetVariable(reg) => {
- let h = self.machine_st.heap.len();
-
- self.machine_st.heap.push(heap_loc_as_cell!(h));
- self.machine_st[reg] = heap_loc_as_cell!(h);
-
- self.machine_st.p += 1;
- }
- &Instruction::SetValue(reg) => {
- let heap_val = self.machine_st.store(self.machine_st[reg]);
- self.machine_st.heap.push(heap_val);
- self.machine_st.p += 1;
- }
- &Instruction::SetVoid(n) => {
- let h = self.machine_st.heap.len();
-
- for i in h..h + n {
- self.machine_st.heap.push(heap_loc_as_cell!(i));
- }
-
- self.machine_st.p += 1;
- }
- //
- &Instruction::CallAtomChars => {
- self.atom_chars();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteAtomChars => {
- self.atom_chars();
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallAtomCodes => {
- try_or_throw!(self.machine_st, self.atom_codes());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p += 1;
- }
- }
- &Instruction::ExecuteAtomCodes => {
- try_or_throw!(self.machine_st, self.atom_codes());
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
- self.machine_st.p = self.machine_st.cp;
- }
- }
- &Instruction::CallAtomLength => {
- self.atom_length();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteAtomLength => {
- self.atom_length();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallBindFromRegister => {
- self.bind_from_register();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteBindFromRegister => {
- self.bind_from_register();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallContinuation => {
- try_or_throw!(self.machine_st, self.call_continuation(false));
- }
- &Instruction::ExecuteContinuation => {
- try_or_throw!(self.machine_st, self.call_continuation(true));
- }
- &Instruction::CallCharCode => {
- try_or_throw!(self.machine_st, self.char_code());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCharCode => {
- try_or_throw!(self.machine_st, self.char_code());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCharType => {
- self.char_type();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCharType => {
- self.char_type();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCharsToNumber => {
- try_or_throw!(self.machine_st, self.chars_to_number());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCharsToNumber => {
- try_or_throw!(self.machine_st, self.chars_to_number());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCodesToNumber => {
- try_or_throw!(self.machine_st, self.codes_to_number());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCodesToNumber => {
- try_or_throw!(self.machine_st, self.codes_to_number());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCopyTermWithoutAttrVars => {
- self.copy_term_without_attr_vars();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCopyTermWithoutAttrVars => {
- self.copy_term_without_attr_vars();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCheckCutPoint => {
- self.check_cut_point();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCheckCutPoint => {
- self.check_cut_point();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallClose => {
- try_or_throw!(self.machine_st, self.close());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteClose => {
- try_or_throw!(self.machine_st, self.close());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallCopyToLiftedHeap => {
- self.copy_to_lifted_heap();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteCopyToLiftedHeap => {
- self.copy_to_lifted_heap();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallCreatePartialString => {
- self.create_partial_string();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCreatePartialString => {
- self.create_partial_string();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCurrentHostname => {
- self.current_hostname();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCurrentHostname => {
- self.current_hostname();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCurrentInput => {
- try_or_throw!(self.machine_st, self.current_input());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCurrentInput => {
- try_or_throw!(self.machine_st, self.current_input());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCurrentOutput => {
- try_or_throw!(self.machine_st, self.current_output());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCurrentOutput => {
- try_or_throw!(self.machine_st, self.current_output());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDirectoryFiles => {
- try_or_throw!(self.machine_st, self.directory_files());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDirectoryFiles => {
- try_or_throw!(self.machine_st, self.directory_files());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFileSize => {
- self.file_size();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFileSize => {
- self.file_size();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFileExists => {
- self.file_exists();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFileExists => {
- self.file_exists();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDirectoryExists => {
- self.directory_exists();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDirectoryExists => {
- self.directory_exists();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDirectorySeparator => {
- self.directory_separator();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDirectorySeparator => {
- self.directory_separator();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallMakeDirectory => {
- self.make_directory();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteMakeDirectory => {
- self.make_directory();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallMakeDirectoryPath => {
- self.make_directory_path();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteMakeDirectoryPath => {
- self.make_directory_path();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDeleteFile => {
- self.delete_file();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDeleteFile => {
- self.delete_file();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallRenameFile => {
- self.rename_file();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteRenameFile => {
- self.rename_file();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFileCopy => {
- self.file_copy();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFileCopy => {
- self.file_copy();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallWorkingDirectory => {
- try_or_throw!(self.machine_st, self.working_directory());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteWorkingDirectory => {
- try_or_throw!(self.machine_st, self.working_directory());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDeleteDirectory => {
- self.delete_directory();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDeleteDirectory => {
- self.delete_directory();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPathCanonical => {
- try_or_throw!(self.machine_st, self.path_canonical());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePathCanonical => {
- try_or_throw!(self.machine_st, self.path_canonical());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFileTime => {
- self.file_time();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFileTime => {
- self.file_time();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDynamicModuleResolution(arity) => {
- let (module_name, key) = try_or_throw!(
- self.machine_st,
- self.dynamic_module_resolution(arity - 2)
- );
-
- try_or_throw!(
- self.machine_st,
- self.call_clause(module_name, key)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::ExecuteDynamicModuleResolution(arity) => {
- let (module_name, key) = try_or_throw!(
- self.machine_st,
- self.dynamic_module_resolution(arity - 2)
- );
-
- try_or_throw!(
- self.machine_st,
- self.execute_clause(module_name, key)
- );
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- }
- }
- &Instruction::CallFetchGlobalVar => {
- self.fetch_global_var();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFetchGlobalVar => {
- self.fetch_global_var();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFirstStream => {
- self.first_stream();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFirstStream => {
- self.first_stream();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFlushOutput => {
- try_or_throw!(self.machine_st, self.flush_output());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteFlushOutput => {
- try_or_throw!(self.machine_st, self.flush_output());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallGetByte => {
- try_or_throw!(self.machine_st, self.get_byte());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetByte => {
- try_or_throw!(self.machine_st, self.get_byte());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetChar => {
- try_or_throw!(self.machine_st, self.get_char());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetChar => {
- try_or_throw!(self.machine_st, self.get_char());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetNChars => {
- try_or_throw!(self.machine_st, self.get_n_chars());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetNChars => {
- try_or_throw!(self.machine_st, self.get_n_chars());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetCode => {
- try_or_throw!(self.machine_st, self.get_code());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetCode => {
- try_or_throw!(self.machine_st, self.get_code());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetSingleChar => {
- try_or_throw!(self.machine_st, self.get_single_char());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetSingleChar => {
- try_or_throw!(self.machine_st, self.get_single_char());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff => {
- self.truncate_if_no_lifted_heap_growth_diff();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff => {
- self.truncate_if_no_lifted_heap_growth_diff();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallTruncateIfNoLiftedHeapGrowth => {
- self.truncate_if_no_lifted_heap_growth();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth => {
- self.truncate_if_no_lifted_heap_growth();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetAttributedVariableList => {
- self.get_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetAttributedVariableList => {
- self.get_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetAttrVarQueueDelimiter => {
- self.get_attr_var_queue_delimiter();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetAttrVarQueueDelimiter => {
- self.get_attr_var_queue_delimiter();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetAttrVarQueueBeyond => {
- self.get_attr_var_queue_beyond();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetAttrVarQueueBeyond => {
- self.get_attr_var_queue_beyond();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetBValue => {
- self.get_b_value();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetBValue => {
- self.get_b_value();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetContinuationChunk => {
- self.get_continuation_chunk();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetContinuationChunk => {
- self.get_continuation_chunk();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLookupDBRef => {
- self.lookup_db_ref();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLookupDBRef => {
- self.lookup_db_ref();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetNextOpDBRef => {
- self.get_next_op_db_ref();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetNextOpDBRef => {
- self.get_next_op_db_ref();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallIsPartialString => {
- self.is_partial_string();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteIsPartialString => {
- self.is_partial_string();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallHalt | &Instruction::ExecuteHalt => {
- return self.halt();
- }
- &Instruction::CallGetLiftedHeapFromOffset => {
- self.get_lifted_heap_from_offset();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetLiftedHeapFromOffset => {
- self.get_lifted_heap_from_offset();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetLiftedHeapFromOffsetDiff => {
- self.get_lifted_heap_from_offset_diff();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetLiftedHeapFromOffsetDiff => {
- self.get_lifted_heap_from_offset_diff();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetSCCCleaner => {
- self.get_scc_cleaner();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetSCCCleaner => {
- self.get_scc_cleaner();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallHeadIsDynamic => {
- self.head_is_dynamic();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteHeadIsDynamic => {
- self.head_is_dynamic();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallInstallSCCCleaner => {
- self.install_scc_cleaner();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteInstallSCCCleaner => {
- self.install_scc_cleaner();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallInstallInferenceCounter => {
- try_or_throw!(self.machine_st, self.install_inference_counter());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteInstallInferenceCounter => {
- try_or_throw!(self.machine_st, self.install_inference_counter());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLiftedHeapLength => {
- self.lifted_heap_length();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLiftedHeapLength => {
- self.lifted_heap_length();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadLibraryAsStream => {
- try_or_throw!(self.machine_st, self.load_library_as_stream());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadLibraryAsStream => {
- try_or_throw!(self.machine_st, self.load_library_as_stream());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallModuleExists => {
- self.module_exists();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteModuleExists => {
- self.module_exists();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallNextEP => {
- self.next_ep();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteNextEP => {
- self.next_ep();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallNoSuchPredicate => {
- try_or_throw!(self.machine_st, self.no_such_predicate());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteNoSuchPredicate => {
- try_or_throw!(self.machine_st, self.no_such_predicate());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallNumberToChars => {
- self.number_to_chars();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteNumberToChars => {
- self.number_to_chars();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallNumberToCodes => {
- self.number_to_codes();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteNumberToCodes => {
- self.number_to_codes();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallOpDeclaration => {
- try_or_throw!(self.machine_st, self.op_declaration());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteOpDeclaration => {
- try_or_throw!(self.machine_st, self.op_declaration());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallOpen => {
- try_or_throw!(self.machine_st, self.open());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteOpen => {
- try_or_throw!(self.machine_st, self.open());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetStreamOptions => {
- try_or_throw!(self.machine_st, self.set_stream_options());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetStreamOptions => {
- try_or_throw!(self.machine_st, self.set_stream_options());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallNextStream => {
- self.next_stream();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteNextStream => {
- self.next_stream();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPartialStringTail => {
- self.partial_string_tail();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePartialStringTail => {
- self.partial_string_tail();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPeekByte => {
- try_or_throw!(self.machine_st, self.peek_byte());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePeekByte => {
- try_or_throw!(self.machine_st, self.peek_byte());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPeekChar => {
- try_or_throw!(self.machine_st, self.peek_char());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePeekChar => {
- try_or_throw!(self.machine_st, self.peek_char());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPeekCode => {
- try_or_throw!(self.machine_st, self.peek_code());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePeekCode => {
- try_or_throw!(self.machine_st, self.peek_code());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPointsToContinuationResetMarker => {
- self.points_to_continuation_reset_marker();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePointsToContinuationResetMarker => {
- self.points_to_continuation_reset_marker();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPutByte => {
- try_or_throw!(self.machine_st, self.put_byte());
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePutByte => {
- try_or_throw!(self.machine_st, self.put_byte());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPutChar => {
- try_or_throw!(self.machine_st, self.put_char());
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePutChar => {
- try_or_throw!(self.machine_st, self.put_char());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPutChars => {
- try_or_throw!(self.machine_st, self.put_chars());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePutChars => {
- try_or_throw!(self.machine_st, self.put_chars());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPutCode => {
- try_or_throw!(self.machine_st, self.put_code());
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePutCode => {
- try_or_throw!(self.machine_st, self.put_code());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallReadQueryTerm => {
- try_or_throw!(self.machine_st, self.read_query_term());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteReadQueryTerm => {
- try_or_throw!(self.machine_st, self.read_query_term());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallReadTerm => {
- try_or_throw!(self.machine_st, self.read_term());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteReadTerm => {
- try_or_throw!(self.machine_st, self.read_term());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallRedoAttrVarBinding => {
- self.redo_attr_var_binding();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteRedoAttrVarBinding => {
- self.redo_attr_var_binding();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallRemoveCallPolicyCheck => {
- self.remove_call_policy_check();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteRemoveCallPolicyCheck => {
- self.remove_call_policy_check();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallRemoveInferenceCounter => {
- self.remove_inference_counter();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteRemoveInferenceCounter => {
- self.remove_inference_counter();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallResetContinuationMarker => {
- self.reset_continuation_marker();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteResetContinuationMarker => {
- self.reset_continuation_marker();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallRestoreCutPolicy => {
- self.restore_cut_policy();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteRestoreCutPolicy => {
- self.restore_cut_policy();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallSetCutPoint(r) => {
- if !self.set_cut_point(r) {
+ &Instruction::DefaultCallCopyTerm => {
+ self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
step_or_fail!(self, self.machine_st.p += 1);
}
- }
- &Instruction::ExecuteSetCutPoint(r) => {
- let cp = self.machine_st.cp;
+ &Instruction::DefaultExecuteCopyTerm => {
+ self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
- if !self.set_cut_point(r) {
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::DefaultCallTermEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if self.machine_st.eq_test(a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::DefaultExecuteTermEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if self.machine_st.eq_test(a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::DefaultCallGround => {
+ if self.machine_st.ground_test() {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::DefaultExecuteGround => {
+ if self.machine_st.ground_test() {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::DefaultCallFunctor => {
+ try_or_throw!(self.machine_st, self.machine_st.try_functor());
+
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::DefaultExecuteFunctor => {
+ try_or_throw!(self.machine_st, self.machine_st.try_functor());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::DefaultCallTermNotEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::DefaultExecuteTermNotEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::DefaultCallSort => {
+ try_or_throw!(self.machine_st, self.machine_st.sort());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::DefaultExecuteSort => {
+ try_or_throw!(self.machine_st, self.machine_st.sort());
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- } else {
- // run_cleaners in set_cut_point calls call_by_index.
- // replace the effect of call_by_index with that
- // of execute_by_index here.
+ }
+ &Instruction::DefaultCallKeySort => {
+ try_or_throw!(
+ self.machine_st,
+ self.machine_st.keysort(VarComparison::Distinct)
+ );
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::DefaultExecuteKeySort => {
+ try_or_throw!(
+ self.machine_st,
+ self.machine_st.keysort(VarComparison::Distinct)
+ );
- self.machine_st.cp = cp;
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
}
- }
- &Instruction::CallSetInput => {
- try_or_throw!(self.machine_st, self.set_input());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetInput => {
- try_or_throw!(self.machine_st, self.set_input());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallSetOutput => {
- try_or_throw!(self.machine_st, self.set_output());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetOutput => {
- try_or_throw!(self.machine_st, self.set_output());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallStoreBacktrackableGlobalVar => {
- self.store_backtrackable_global_var();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteStoreBacktrackableGlobalVar => {
- self.store_backtrackable_global_var();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallStoreGlobalVar => {
- self.store_global_var();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteStoreGlobalVar => {
- self.store_global_var();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallStreamProperty => {
- try_or_throw!(self.machine_st, self.stream_property());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteStreamProperty => {
- try_or_throw!(self.machine_st, self.stream_property());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetStreamPosition => {
- try_or_throw!(self.machine_st, self.set_stream_position());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSetStreamPosition => {
- try_or_throw!(self.machine_st, self.set_stream_position());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallInferenceLevel => {
- self.inference_level();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteInferenceLevel => {
- self.inference_level();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCleanUpBlock => {
- self.clean_up_block();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteCleanUpBlock => {
- self.clean_up_block();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallFail | &Instruction::ExecuteFail => {
- self.machine_st.backtrack();
- }
- &Instruction::CallGetBall => {
- self.get_ball();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetBall => {
- self.get_ball();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetCurrentBlock => {
- self.get_current_block();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetCurrentBlock => {
- self.get_current_block();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetCurrentSCCBlock => {
- self.get_current_scc_block();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetCurrentSCCBlock => {
- self.get_current_scc_block();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetCutPoint => {
- self.get_cut_point();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetCutPoint => {
- self.get_cut_point();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetDoubleQuotes => {
- self.get_double_quotes();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetDoubleQuotes => {
- self.get_double_quotes();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetUnknown => {
- self.get_unknown();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetUnknown => {
- self.get_unknown();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallInstallNewBlock => {
- self.machine_st.install_new_block(self.machine_st.registers[1]);
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteInstallNewBlock => {
- self.machine_st.install_new_block(self.machine_st.registers[1]);
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallMaybe => {
- self.maybe();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteMaybe => {
- self.maybe();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCpuNow => {
- self.cpu_now();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCpuNow => {
- self.cpu_now();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDeterministicLengthRundown => {
- try_or_throw!(self.machine_st, self.det_length_rundown());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDeterministicLengthRundown => {
- try_or_throw!(self.machine_st, self.det_length_rundown());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallHttpOpen => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_open());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteHttpOpen => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_open());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallHttpListen => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_listen());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteHttpListen => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_listen());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallHttpAccept => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_accept());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteHttpAccept => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_accept());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallHttpAnswer => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_answer());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteHttpAnswer => {
- #[cfg(feature = "http")]
- try_or_throw!(self.machine_st, self.http_answer());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadForeignLib => {
- #[cfg(feature = "ffi")]
- try_or_throw!(self.machine_st, self.load_foreign_lib());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadForeignLib => {
- #[cfg(feature = "ffi")]
- try_or_throw!(self.machine_st, self.load_foreign_lib());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallForeignCall => {
- #[cfg(feature = "ffi")]
- try_or_throw!(self.machine_st, self.foreign_call());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteForeignCall => {
- #[cfg(feature = "ffi")]
- try_or_throw!(self.machine_st, self.foreign_call());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDefineForeignStruct => {
- #[cfg(feature = "ffi")]
- try_or_throw!(self.machine_st, self.define_foreign_struct());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDefineForeignStruct => {
- #[cfg(feature = "ffi")]
- try_or_throw!(self.machine_st, self.define_foreign_struct());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCurrentTime => {
- self.current_time();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCurrentTime => {
- self.current_time();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallQuotedToken => {
- self.quoted_token();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteQuotedToken => {
- self.quoted_token();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallReadFromChars => {
- try_or_throw!(self.machine_st, self.read_from_chars());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteReadFromChars => {
- try_or_throw!(self.machine_st, self.read_from_chars());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallReadTermFromChars => {
- try_or_throw!(self.machine_st, self.read_term_from_chars());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteReadTermFromChars => {
- try_or_throw!(self.machine_st, self.read_term_from_chars());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallResetBlock => {
- self.reset_block();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteResetBlock => {
- self.reset_block();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallResetSCCBlock => {
- self.reset_scc_block();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteResetSCCBlock => {
- self.reset_scc_block();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallReturnFromVerifyAttr |
- &Instruction::ExecuteReturnFromVerifyAttr => {
- self.return_from_verify_attr();
- }
- &Instruction::CallSetBall => {
- self.set_ball();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetBall => {
- self.set_ball();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPushBallStack => {
- self.push_ball_stack();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePushBallStack => {
- self.push_ball_stack();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPopBallStack => {
- self.pop_ball_stack();
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePopBallStack => {
- self.pop_ball_stack();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPopFromBallStack => {
- self.pop_from_ball_stack();
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePopFromBallStack => {
- self.pop_from_ball_stack();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallSetCutPointByDefault(r) => {
- self.set_cut_point_by_default(r);
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSetCutPointByDefault(r) => {
- self.set_cut_point_by_default(r);
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetDoubleQuotes => {
- self.set_double_quotes();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSetDoubleQuotes => {
- self.set_double_quotes();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetUnknown => {
- self.set_unknown();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSetUnknown => {
- self.set_unknown();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetSeed => {
- self.set_seed();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSetSeed => {
- self.set_seed();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSkipMaxList => {
- try_or_throw!(self.machine_st, self.machine_st.skip_max_list());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSkipMaxList => {
- try_or_throw!(self.machine_st, self.machine_st.skip_max_list());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSleep => {
- self.sleep();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSleep => {
- self.sleep();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallSocketClientOpen => {
- try_or_throw!(self.machine_st, self.socket_client_open());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSocketClientOpen => {
- try_or_throw!(self.machine_st, self.socket_client_open());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSocketServerOpen => {
- try_or_throw!(self.machine_st, self.socket_server_open());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSocketServerOpen => {
- try_or_throw!(self.machine_st, self.socket_server_open());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSocketServerAccept => {
- try_or_throw!(self.machine_st, self.socket_server_accept());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteSocketServerAccept => {
- try_or_throw!(self.machine_st, self.socket_server_accept());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSocketServerClose => {
- try_or_throw!(self.machine_st, self.socket_server_close());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSocketServerClose => {
- try_or_throw!(self.machine_st, self.socket_server_close());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallTLSAcceptClient => {
- #[cfg(feature = "tls")]
- try_or_throw!(self.machine_st, self.tls_accept_client());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTLSAcceptClient => {
- #[cfg(feature = "tls")]
- try_or_throw!(self.machine_st, self.tls_accept_client());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallTLSClientConnect => {
- #[cfg(feature = "tls")]
- try_or_throw!(self.machine_st, self.tls_client_connect());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTLSClientConnect => {
- #[cfg(feature = "tls")]
- try_or_throw!(self.machine_st, self.tls_client_connect());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSucceed => {
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSucceed => {
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallTermAttributedVariables => {
- self.term_attributed_variables();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTermAttributedVariables => {
- self.term_attributed_variables();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallTermVariables => {
- self.term_variables();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTermVariables => {
- self.term_variables();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallTermVariablesUnderMaxDepth => {
- self.term_variables_under_max_depth();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteTermVariablesUnderMaxDepth => {
- self.term_variables_under_max_depth();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallTruncateLiftedHeapTo => {
- self.truncate_lifted_heap_to();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteTruncateLiftedHeapTo => {
- self.truncate_lifted_heap_to();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallUnifyWithOccursCheck => {
- self.unify_with_occurs_check();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteUnifyWithOccursCheck => {
- self.unify_with_occurs_check();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallUnwindEnvironments => {
- if !self.unwind_environments() {
- self.machine_st.p += 1;
+ &Instruction::DefaultCallIs(r, at) => {
+ try_or_throw!(self.machine_st, self.machine_st.is(r, at));
+ step_or_fail!(self, self.machine_st.p += 1);
}
- }
- &Instruction::ExecuteUnwindEnvironments => {
- if !self.unwind_environments() {
+ &Instruction::DefaultExecuteIs(r, at) => {
+ try_or_throw!(self.machine_st, self.machine_st.is(r, at));
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ Instruction::DefaultCallGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ Instruction::DefaultExecuteGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallAcyclicTerm => {
+ let addr = self.machine_st.registers[1];
+
+ if self.machine_st.is_cyclic_term(addr) {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteAcyclicTerm => {
+ let addr = self.machine_st.registers[1];
+
+ if self.machine_st.is_cyclic_term(addr) {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallArg => {
+ try_or_throw!(self.machine_st, self.machine_st.try_arg());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteArg => {
+ try_or_throw!(self.machine_st, self.machine_st.try_arg());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallCompare => {
+ try_or_throw!(self.machine_st, self.machine_st.compare());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteCompare => {
+ try_or_throw!(self.machine_st, self.machine_st.compare());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallTermGreaterThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2)
+ {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::ExecuteTermGreaterThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Greater) = compare_term_test!(self.machine_st, a1, a2)
+ {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::CallTermLessThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::ExecuteTermLessThan => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Less) = compare_term_test!(self.machine_st, a1, a2) {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::CallTermGreaterThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Greater | Ordering::Equal) => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteTermGreaterThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Greater | Ordering::Equal) => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallTermLessThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Less | Ordering::Equal) => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteTermLessThanOrEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ match compare_term_test!(self.machine_st, a1, a2) {
+ Some(Ordering::Less | Ordering::Equal) => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallCopyTerm => {
+ self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteCopyTerm => {
+ self.machine_st.copy_term(AttrVarPolicy::DeepCopy);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallTermEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if self.machine_st.eq_test(a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteTermEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if self.machine_st.eq_test(a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallGround => {
+ if self.machine_st.ground_test() {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteGround => {
+ if self.machine_st.ground_test() {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallFunctor => {
+ try_or_throw!(self.machine_st, self.machine_st.try_functor());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteFunctor => {
+ try_or_throw!(self.machine_st, self.machine_st.try_functor());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallTermNotEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteTermNotEqual => {
+ let a1 = self.machine_st.registers[1];
+ let a2 = self.machine_st.registers[2];
+
+ if let Some(Ordering::Equal) = compare_term_test!(self.machine_st, a1, a2) {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallSort => {
+ try_or_throw!(self.machine_st, self.machine_st.sort());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteSort => {
+ try_or_throw!(self.machine_st, self.machine_st.sort());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallKeySort => {
+ try_or_throw!(
+ self.machine_st,
+ self.machine_st.keysort(VarComparison::Distinct)
+ );
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteKeySort => {
+ try_or_throw!(
+ self.machine_st,
+ self.machine_st.keysort(VarComparison::Distinct)
+ );
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallKeySortWithConstantVarOrdering => {
+ try_or_throw!(
+ self.machine_st,
+ self.machine_st.keysort(VarComparison::Indistinct)
+ );
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteKeySortWithConstantVarOrdering => {
+ try_or_throw!(
+ self.machine_st,
+ self.machine_st.keysort(VarComparison::Indistinct)
+ );
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallIs(r, at) => {
+ try_or_throw!(self.machine_st, self.machine_st.is(r, at));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteIs(r, at) => {
+ try_or_throw!(self.machine_st, self.machine_st.is(r, at));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ Instruction::CallGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ Instruction::ExecuteGetNumber(at) => {
+ try_or_throw!(self.machine_st, self.machine_st.get_number(at));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallN(arity) => {
+ let pred = self.machine_st.registers[1];
+
+ for i in 2..arity + 1 {
+ self.machine_st.registers[i - 1] = self.machine_st.registers[i];
+ }
+
+ self.machine_st.registers[arity] = pred;
+
+ try_or_throw!(self.machine_st, self.call_n(atom!("user"), arity));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+ }
+ }
+ &Instruction::ExecuteN(arity) => {
+ let pred = self.machine_st.registers[1];
+
+ for i in 2..arity + 1 {
+ self.machine_st.registers[i - 1] = self.machine_st.registers[i];
+ }
+
+ self.machine_st.registers[arity] = pred;
+
+ try_or_throw!(self.machine_st, self.execute_n(atom!("user"), arity));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+ }
+ }
+ &Instruction::DefaultCallN(arity) => {
+ let pred = self.machine_st.registers[1];
+
+ for i in 2..arity + 1 {
+ self.machine_st.registers[i - 1] = self.machine_st.registers[i];
+ }
+
+ self.machine_st.registers[arity] = pred;
+
+ try_or_throw!(self.machine_st, self.call_n(atom!("user"), arity));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DefaultExecuteN(arity) => {
+ let pred = self.machine_st.registers[1];
+
+ for i in 2..arity + 1 {
+ self.machine_st.registers[i - 1] = self.machine_st.registers[i];
+ }
+
+ self.machine_st.registers[arity] = pred;
+
+ try_or_throw!(self.machine_st, self.execute_n(atom!("user"), arity));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less | Ordering::Equal => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less | Ordering::Equal => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallNumberEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteNumberEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallNumberNotEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ self.machine_st.backtrack();
+ }
+ _ => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ }
+ }
+ &Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ self.machine_st.backtrack();
+ }
+ _ => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ }
+ &Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater | Ordering::Equal => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater | Ordering::Equal => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallNumberGreaterThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallNumberLessThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteNumberLessThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less => {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less | Ordering::Equal => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less | Ordering::Equal => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ self.machine_st.backtrack();
+ }
+ _ => {
+ self.machine_st.p += 1;
+ }
+ }
+ }
+ &Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ self.machine_st.backtrack();
+ }
+ _ => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ }
+ &Instruction::DefaultCallNumberEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Equal => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater | Ordering::Equal => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater | Ordering::Equal => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Greater => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2) => {
+ let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
+ let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
+
+ match n1.cmp(&n2) {
+ Ordering::Less => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ //
+ &Instruction::CallIsAtom(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity == 0 {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Str, s) => {
+ let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_arity();
+
+ if arity == 0 {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Char) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::ExecuteIsAtom(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity == 0 {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Str, s) => {
+ let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_arity();
+
+ if arity == 0 {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Char) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::CallIsAtomic(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Char | HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
+ HeapCellValueTag::Cons) => {
+ self.machine_st.p += 1;
+ }
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity == 0 {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Str, s) => {
+ let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_arity();
+
+ if arity == 0 {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::ExecuteIsAtomic(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Char | HeapCellValueTag::Fixnum | HeapCellValueTag::F64 |
+ HeapCellValueTag::Cons) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity == 0 {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Str, s) => {
+ let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_arity();
+
+ if arity == 0 {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::CallIsCompound(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Lis |
+ HeapCellValueTag::PStrLoc |
+ HeapCellValueTag::CStr) => {
+ self.machine_st.p += 1;
+ }
+ (HeapCellValueTag::Str, s) => {
+ let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_arity();
+
+ if arity > 0 {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity > 0 {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::ExecuteIsCompound(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Lis |
+ HeapCellValueTag::PStrLoc |
+ HeapCellValueTag::CStr) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ (HeapCellValueTag::Str, s) => {
+ let arity = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_arity();
+
+ if arity > 0 {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ if arity > 0 {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::CallIsInteger(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match Number::try_from(d) {
+ Ok(Number::Fixnum(_) | Number::Integer(_)) => {
+ self.machine_st.p += 1;
+ }
+ Ok(Number::Rational(n)) => {
+ if n.denominator().is_one() {
+ self.machine_st.p += 1;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteIsInteger(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match Number::try_from(d) {
+ Ok(Number::Fixnum(_) | Number::Integer(_)) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ Ok(Number::Rational(n)) => {
+ if n.denominator().is_one() {
+ self.machine_st.p = self.machine_st.cp;
+ } else {
+ self.machine_st.backtrack();
+ }
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallIsNumber(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match Number::try_from(d) {
+ Ok(_) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteIsNumber(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match Number::try_from(d) {
+ Ok(_) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallIsRational(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Cons, ptr) => {
+ match_untyped_arena_ptr!(ptr,
+ (ArenaHeaderTag::Rational | ArenaHeaderTag::Integer, _r) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ (HeapCellValueTag::Fixnum) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::ExecuteIsRational(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ read_heap_cell!(d,
+ (HeapCellValueTag::Cons, ptr) => {
+ match_untyped_arena_ptr!(ptr,
+ (ArenaHeaderTag::Rational | ArenaHeaderTag::Integer, _r) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ (HeapCellValueTag::Fixnum) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ );
+ }
+ &Instruction::CallIsFloat(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match Number::try_from(d) {
+ Ok(Number::Float(_)) => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteIsFloat(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match Number::try_from(d) {
+ Ok(Number::Float(_)) => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallIsNonVar(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match d.get_tag() {
+ HeapCellValueTag::AttrVar
+ | HeapCellValueTag::Var
+ | HeapCellValueTag::StackVar => {
+ self.machine_st.backtrack();
+ }
+ _ => {
+ self.machine_st.p += 1;
+ }
+ }
+ }
+ &Instruction::ExecuteIsNonVar(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match d.get_tag() {
+ HeapCellValueTag::AttrVar
+ | HeapCellValueTag::Var
+ | HeapCellValueTag::StackVar => {
+ self.machine_st.backtrack();
+ }
+ _ => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ }
+ &Instruction::CallIsVar(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match d.get_tag() {
+ HeapCellValueTag::AttrVar
+ | HeapCellValueTag::Var
+ | HeapCellValueTag::StackVar => {
+ self.machine_st.p += 1;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::ExecuteIsVar(r) => {
+ let d = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[r]));
+
+ match d.get_tag() {
+ HeapCellValueTag::AttrVar
+ | HeapCellValueTag::Var
+ | HeapCellValueTag::StackVar => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ &Instruction::CallNamed(arity, name, ref idx) => {
+ let idx = idx.get();
+
+ try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+ }
+ }
+ &Instruction::ExecuteNamed(arity, name, ref idx) => {
+ let idx = idx.get();
+
+ try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ );
+ }
+ }
+ &Instruction::DefaultCallNamed(arity, name, ref idx) => {
+ let idx = idx.get();
+
+ try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::DefaultExecuteNamed(arity, name, ref idx) => {
+ let idx = idx.get();
+
+ try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::Deallocate => self.machine_st.deallocate(),
+ &Instruction::JmpByCall(offset) => {
+ self.machine_st.p += offset;
+ }
+ &Instruction::RevJmpBy(offset) => {
+ self.machine_st.p -= offset;
+ }
+ &Instruction::Proceed => {
self.machine_st.p = self.machine_st.cp;
}
- }
- &Instruction::CallUnwindStack | &Instruction::ExecuteUnwindStack => {
- self.machine_st.unwind_stack();
- self.machine_st.backtrack();
- }
- &Instruction::CallWAMInstructions => {
- try_or_throw!(self.machine_st, self.wam_instructions());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteWAMInstructions => {
- try_or_throw!(self.machine_st, self.wam_instructions());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallInlinedInstructions => {
- self.inlined_instructions();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteInlinedInstructions => {
- self.inlined_instructions();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallWriteTerm => {
- try_or_throw!(self.machine_st, self.write_term());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteWriteTerm => {
- try_or_throw!(self.machine_st, self.write_term());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallWriteTermToChars => {
- try_or_throw!(self.machine_st, self.write_term_to_chars());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteWriteTermToChars => {
- try_or_throw!(self.machine_st, self.write_term_to_chars());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallScryerPrologVersion => {
- self.scryer_prolog_version();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteScryerPrologVersion => {
- self.scryer_prolog_version();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoRandomByte => {
- self.crypto_random_byte();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoRandomByte => {
- self.crypto_random_byte();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoDataHash => {
- self.crypto_data_hash();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoDataHash => {
- self.crypto_data_hash();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoDataHKDF => {
- self.crypto_data_hkdf();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoDataHKDF => {
- self.crypto_data_hkdf();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoPasswordHash => {
- self.crypto_password_hash();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoPasswordHash => {
- self.crypto_password_hash();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoDataEncrypt => {
- self.crypto_data_encrypt();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoDataEncrypt => {
- self.crypto_data_encrypt();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoDataDecrypt => {
- self.crypto_data_decrypt();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoDataDecrypt => {
- self.crypto_data_decrypt();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCryptoCurveScalarMult => {
- self.crypto_curve_scalar_mult();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCryptoCurveScalarMult => {
- self.crypto_curve_scalar_mult();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallEd25519Sign => {
- self.ed25519_sign();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteEd25519Sign => {
- self.ed25519_sign();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallEd25519Verify => {
- self.ed25519_verify();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteEd25519Verify => {
- self.ed25519_verify();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallEd25519NewKeyPair => {
- self.ed25519_new_key_pair();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteEd25519NewKeyPair => {
- self.ed25519_new_key_pair();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallEd25519KeyPairPublicKey => {
- self.ed25519_key_pair_public_key();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteEd25519KeyPairPublicKey => {
- self.ed25519_key_pair_public_key();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCurve25519ScalarMult => {
- self.curve25519_scalar_mult();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCurve25519ScalarMult => {
- self.curve25519_scalar_mult();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFirstNonOctet => {
- self.first_non_octet();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteFirstNonOctet => {
- self.first_non_octet();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadHTML => {
- self.load_html();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadHTML => {
- self.load_html();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadXML => {
- self.load_xml();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadXML => {
- self.load_xml();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallGetEnv => {
- self.get_env();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetEnv => {
- self.get_env();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetEnv => {
- self.set_env();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetEnv => {
- self.set_env();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallUnsetEnv => {
- self.unset_env();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteUnsetEnv => {
- self.unset_env();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallShell => {
- self.shell();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteShell => {
- self.shell();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPID => {
- self.pid();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePID => {
- self.pid();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCharsBase64 => {
- try_or_throw!(self.machine_st, self.chars_base64());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCharsBase64 => {
- try_or_throw!(self.machine_st, self.chars_base64());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDevourWhitespace => {
- try_or_throw!(self.machine_st, self.devour_whitespace());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDevourWhitespace => {
- try_or_throw!(self.machine_st, self.devour_whitespace());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallIsSTOEnabled => {
- self.is_sto_enabled();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteIsSTOEnabled => {
- self.is_sto_enabled();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallSetSTOAsUnify => {
- self.set_sto_as_unify();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetSTOAsUnify => {
- self.set_sto_as_unify();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallSetNSTOAsUnify => {
- self.set_nsto_as_unify();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetNSTOAsUnify => {
- self.set_nsto_as_unify();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallSetSTOWithErrorAsUnify => {
- self.set_sto_with_error_as_unify();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteSetSTOWithErrorAsUnify => {
- self.set_sto_with_error_as_unify();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallHomeDirectory => {
- self.home_directory();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteHomeDirectory => {
- self.home_directory();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDebugHook => {
- self.debug_hook();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteDebugHook => {
- self.debug_hook();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPopCount => {
- self.pop_count();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePopCount => {
- self.pop_count();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallAddDiscontiguousPredicate => {
- try_or_throw!(self.machine_st, self.add_discontiguous_predicate());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddDiscontiguousPredicate => {
- try_or_throw!(self.machine_st, self.add_discontiguous_predicate());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAddDynamicPredicate => {
- try_or_throw!(self.machine_st, self.add_dynamic_predicate());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddDynamicPredicate => {
- try_or_throw!(self.machine_st, self.add_dynamic_predicate());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAddMultifilePredicate => {
- try_or_throw!(self.machine_st, self.add_multifile_predicate());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddMultifilePredicate => {
- try_or_throw!(self.machine_st, self.add_multifile_predicate());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAddGoalExpansionClause => {
- try_or_throw!(self.machine_st, self.add_goal_expansion_clause());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddGoalExpansionClause => {
- try_or_throw!(self.machine_st, self.add_goal_expansion_clause());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAddTermExpansionClause => {
- try_or_throw!(self.machine_st, self.add_term_expansion_clause());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddTermExpansionClause => {
- try_or_throw!(self.machine_st, self.add_term_expansion_clause());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAddInSituFilenameModule => {
- try_or_throw!(self.machine_st, self.add_in_situ_filename_module());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddInSituFilenameModule => {
- try_or_throw!(self.machine_st, self.add_in_situ_filename_module());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallClauseToEvacuable => {
- try_or_throw!(self.machine_st, self.clause_to_evacuable());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteClauseToEvacuable => {
- try_or_throw!(self.machine_st, self.clause_to_evacuable());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallScopedClauseToEvacuable => {
- try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteScopedClauseToEvacuable => {
- try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallConcludeLoad => {
- try_or_throw!(self.machine_st, self.conclude_load());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteConcludeLoad => {
- try_or_throw!(self.machine_st, self.conclude_load());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallDeclareModule => {
- try_or_throw!(self.machine_st, self.declare_module());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteDeclareModule => {
- try_or_throw!(self.machine_st, self.declare_module());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallLoadCompiledLibrary => {
- try_or_throw!(self.machine_st, self.load_compiled_library());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadCompiledLibrary => {
- try_or_throw!(self.machine_st, self.load_compiled_library());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadContextSource => {
- self.load_context_source();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadContextSource => {
- self.load_context_source();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadContextFile => {
- self.load_context_file();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadContextFile => {
- self.load_context_file();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadContextDirectory => {
- self.load_context_directory();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadContextDirectory => {
- self.load_context_directory();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadContextModule => {
- self.load_context_module(self.machine_st.registers[1]);
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadContextModule => {
- self.load_context_module(self.machine_st.registers[1]);
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallLoadContextStream => {
- self.load_context_stream();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteLoadContextStream => {
- self.load_context_stream();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPopLoadContext => {
- self.pop_load_context();
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePopLoadContext => {
- self.pop_load_context();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPopLoadStatePayload => {
- self.pop_load_state_payload();
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePopLoadStatePayload => {
- self.pop_load_state_payload();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPushLoadContext => {
- try_or_throw!(self.machine_st, self.push_load_context());
- self.machine_st.p += 1;
- }
- &Instruction::ExecutePushLoadContext => {
- try_or_throw!(self.machine_st, self.push_load_context());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPushLoadStatePayload => {
- self.push_load_state_payload();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePushLoadStatePayload => {
- self.push_load_state_payload();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallUseModule => {
- try_or_throw!(self.machine_st, self.use_module());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteUseModule => {
- try_or_throw!(self.machine_st, self.use_module());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallBuiltInProperty => {
- let key = self
- .machine_st
- .read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
+ &Instruction::GetConstant(_, c, reg) => {
+ let value = self.machine_st.deref(self.machine_st[reg]);
+ self.machine_st.write_literal_to_var(value, c);
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::GetList(_, reg) => {
+ let deref_v = self.machine_st.deref(self.machine_st[reg]);
+ let store_v = self.machine_st.store(deref_v);
- self.machine_st.fail = !self.indices.builtin_property(key);
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteBuiltInProperty => {
- let key = self
- .machine_st
- .read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
+ read_heap_cell!(store_v,
+ (HeapCellValueTag::PStrLoc, h) => {
+ let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h);
- self.machine_st.fail = !self.indices.builtin_property(key);
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallMetaPredicateProperty => {
- self.meta_predicate_property();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteMetaPredicateProperty => {
- self.meta_predicate_property();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallMultifileProperty => {
- self.multifile_property();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteMultifileProperty => {
- self.multifile_property();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDiscontiguousProperty => {
- self.discontiguous_property();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDiscontiguousProperty => {
- self.discontiguous_property();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDynamicProperty => {
- self.dynamic_property();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDynamicProperty => {
- self.dynamic_property();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallAbolishClause => {
- try_or_throw!(self.machine_st, self.abolish_clause());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAbolishClause => {
- try_or_throw!(self.machine_st, self.abolish_clause());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAsserta => {
- try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Prepend));
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAsserta => {
- try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Prepend));
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAssertz => {
- try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Append));
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAssertz => {
- try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Append));
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallRetract => {
- try_or_throw!(self.machine_st, self.retract_clause());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteRetract => {
- try_or_throw!(self.machine_st, self.retract_clause());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallIsConsistentWithTermQueue => {
- try_or_throw!(self.machine_st, self.is_consistent_with_term_queue());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteIsConsistentWithTermQueue => {
- try_or_throw!(self.machine_st, self.is_consistent_with_term_queue());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::CallFlushTermQueue => {
- try_or_throw!(self.machine_st, self.flush_term_queue());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteFlushTermQueue => {
- try_or_throw!(self.machine_st, self.flush_term_queue());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallRemoveModuleExports => {
- try_or_throw!(self.machine_st, self.remove_module_exports());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteRemoveModuleExports => {
- try_or_throw!(self.machine_st, self.remove_module_exports());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallAddNonCountedBacktracking => {
- try_or_throw!(self.machine_st, self.add_non_counted_backtracking());
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteAddNonCountedBacktracking => {
- try_or_throw!(self.machine_st, self.add_non_counted_backtracking());
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallPredicateDefined => {
- self.machine_st.fail = !self.predicate_defined();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePredicateDefined => {
- self.machine_st.fail = !self.predicate_defined();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallStripModule => {
- self.strip_module();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteStripModule => {
- self.strip_module();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPrepareCallClause(arity) => {
- try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePrepareCallClause(arity) => {
- try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallCompileInlineOrExpandedGoal => {
- try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal());
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteCompileInlineOrExpandedGoal => {
- try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal());
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallIsExpandedOrInlined => {
- self.machine_st.fail = !self.is_expanded_or_inlined();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteIsExpandedOrInlined => {
- self.machine_st.fail = !self.is_expanded_or_inlined();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallFastCallN(arity) => {
- let call_at_index = |wam: &mut Machine, name, arity, ptr| {
- wam.try_call(name, arity, ptr)
- };
+ self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize);
+ self.machine_st.s_offset = 0;
+ self.machine_st.mode = MachineMode::Read;
+ }
+ (HeapCellValueTag::CStr) => {
+ let h = self.machine_st.heap.len();
+ self.machine_st.heap.push(store_v);
- try_or_throw!(self.machine_st, self.fast_call(arity, call_at_index));
+ self.machine_st.s = HeapPtr::PStrChar(h, 0);
+ self.machine_st.s_offset = 0;
+ self.machine_st.mode = MachineMode::Read;
+ }
+ (HeapCellValueTag::Str, s) => {
+ let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+ .get_name_and_arity();
- if self.machine_st.fail {
+ if name == atom!(".") && arity == 2 {
+ self.machine_st.s = HeapPtr::HeapCell(s+1);
+ self.machine_st.s_offset = 0;
+ self.machine_st.mode = MachineMode::Read;
+ } else {
+ self.machine_st.backtrack();
+ continue;
+ }
+ }
+ (HeapCellValueTag::Lis, l) => {
+ self.machine_st.s = HeapPtr::HeapCell(l);
+ self.machine_st.s_offset = 0;
+ self.machine_st.mode = MachineMode::Read;
+ }
+ (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
+ let h = self.machine_st.heap.len();
+
+ self.machine_st.heap.push(list_loc_as_cell!(h+1));
+ self.machine_st.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h));
+
+ self.machine_st.mode = MachineMode::Write;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ continue;
+ }
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::GetPartialString(_, string, reg, has_tail) => {
+ let deref_v = self.machine_st.deref(self.machine_st[reg]);
+ let store_v = self.machine_st.store(deref_v);
+
+ read_heap_cell!(store_v,
+ (HeapCellValueTag::Str |
+ HeapCellValueTag::Lis |
+ HeapCellValueTag::PStrLoc |
+ HeapCellValueTag::CStr) => {
+ self.machine_st.match_partial_string(store_v, string, has_tail);
+ }
+ (HeapCellValueTag::AttrVar |
+ HeapCellValueTag::StackVar |
+ HeapCellValueTag::Var) => {
+ let target_cell = self.machine_st.push_str_to_heap(
+ &string.as_str(),
+ has_tail,
+ );
+
+ self.machine_st.bind(
+ store_v.as_var().unwrap(),
+ target_cell,
+ );
+ }
+ _ => {
+ self.machine_st.backtrack();
+ continue;
+ }
+ );
+
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::GetStructure(_lvl, name, arity, reg) => {
+ let deref_v = self.machine_st.deref(self.machine_st[reg]);
+ let store_v = self.machine_st.store(deref_v);
+
+ read_heap_cell!(store_v,
+ (HeapCellValueTag::Str, a) => {
+ read_heap_cell!(self.machine_st.heap[a],
+ (HeapCellValueTag::Atom, (result_name, result_arity)) => {
+ if arity == result_arity && name == result_name {
+ self.machine_st.s = HeapPtr::HeapCell(a + 1);
+ self.machine_st.s_offset = 0;
+ self.machine_st.mode = MachineMode::Read;
+ } else {
+ self.machine_st.backtrack();
+ continue;
+ }
+ }
+ _ => {
+ unreachable!();
+ }
+ );
+ }
+ (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
+ let h = self.machine_st.heap.len();
+
+ self.machine_st.heap.push(str_loc_as_cell!(h+1));
+ self.machine_st.heap.push(atom_as_cell!(name, arity));
+
+ self.machine_st.bind(store_v.as_var().unwrap(), heap_loc_as_cell!(h));
+ self.machine_st.mode = MachineMode::Write;
+ }
+ _ => {
+ self.machine_st.backtrack();
+ continue;
+ }
+ );
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::GetVariable(norm, arg) => {
+ self.machine_st[norm] = self.machine_st.registers[arg];
+ self.machine_st.p += 1;
+ }
+ &Instruction::GetValue(norm, arg) => {
+ let norm_addr = self.machine_st[norm];
+ let reg_addr = self.machine_st.registers[arg];
+
+ unify_fn!(&mut self.machine_st, norm_addr, reg_addr);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ continue;
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::UnifyConstant(v) => {
+ match self.machine_st.mode {
+ MachineMode::Read => {
+ let addr = self.machine_st.read_s();
+
+ self.machine_st.write_literal_to_var(addr, v);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ continue;
+ } else {
+ self.machine_st.s_offset += 1;
+ }
+ }
+ MachineMode::Write => {
+ self.machine_st.heap.push(v);
+ }
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::UnifyLocalValue(reg) => {
+ match self.machine_st.mode {
+ MachineMode::Read => {
+ let reg_addr = self.machine_st[reg];
+ let value = self.machine_st.read_s();
+
+ unify_fn!(&mut self.machine_st, reg_addr, value);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ continue;
+ } else {
+ self.machine_st.s_offset += 1;
+ }
+ }
+ MachineMode::Write => {
+ let value = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st[reg]));
+ let h = self.machine_st.heap.len();
+
+ read_heap_cell!(value,
+ (HeapCellValueTag::Var | HeapCellValueTag::AttrVar, hc) => {
+ let value = self.machine_st.heap[hc];
+
+ self.machine_st.heap.push(value);
+ self.machine_st.s_offset += 1;
+ }
+ _ => {
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+ (self.machine_st.bind_fn)(
+ &mut self.machine_st,
+ Ref::heap_cell(h),
+ value,
+ );
+ }
+ );
+ }
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::UnifyVariable(reg) => {
+ match self.machine_st.mode {
+ MachineMode::Read => {
+ self.machine_st[reg] = self.machine_st.read_s();
+ self.machine_st.s_offset += 1;
+ }
+ MachineMode::Write => {
+ let h = self.machine_st.heap.len();
+
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+ self.machine_st[reg] = heap_loc_as_cell!(h);
+ }
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::UnifyValue(reg) => {
+ match self.machine_st.mode {
+ MachineMode::Read => {
+ let reg_addr = self.machine_st[reg];
+ let value = self.machine_st.read_s();
+
+ unify_fn!(&mut self.machine_st, reg_addr, value);
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ continue;
+ } else {
+ self.machine_st.s_offset += 1;
+ }
+ }
+ MachineMode::Write => {
+ let h = self.machine_st.heap.len();
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+
+ let addr = self.machine_st.store(self.machine_st[reg]);
+ (self.machine_st.bind_fn)(
+ &mut self.machine_st,
+ Ref::heap_cell(h),
+ addr,
+ );
+
+ // the former code of this match arm was:
+
+ // let addr = self.machine_st.store(self.machine_st[reg]);
+ // self.machine_st.heap.push(HeapCellValue::Addr(addr));
+
+ // the old code didn't perform the occurs
+ // check when enabled and so it was changed to
+ // the above, which is only slightly less
+ // efficient when the occurs_check is disabled.
+ }
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::UnifyVoid(n) => {
+ match self.machine_st.mode {
+ MachineMode::Read => {
+ self.machine_st.s_offset += n;
+ }
+ MachineMode::Write => {
+ let h = self.machine_st.heap.len();
+
+ for i in h..h + n {
+ self.machine_st.heap.push(heap_loc_as_cell!(i));
+ }
+ }
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::IndexingCode(ref indexing_lines) => {
+ match &indexing_lines[self.machine_st.oip as usize] {
+ IndexingLine::Indexing(_) => {
+ self.execute_switch_on_term();
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ IndexingLine::IndexedChoice(ref indexed_choice) => {
+ match &indexed_choice[self.machine_st.iip as usize] {
+ &IndexedChoiceInstruction::Try(offset) => {
+ self.indexed_try(offset);
+ }
+ &IndexedChoiceInstruction::Retry(l) => {
+ self.retry(l);
+
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
+ &IndexedChoiceInstruction::DefaultRetry(l) => {
+ self.retry(l);
+ }
+ &IndexedChoiceInstruction::Trust(l) => {
+ self.trust(l);
+
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
+ &IndexedChoiceInstruction::DefaultTrust(l) => {
+ self.trust(l);
+ }
+ }
+ }
+ IndexingLine::DynamicIndexedChoice(_) => {
+ let p = self.machine_st.p;
+
+ match self
+ .find_living_dynamic(self.machine_st.oip, self.machine_st.iip)
+ {
+ Some((offset, oi, ii, is_next_clause)) => {
+ self.machine_st.p = p;
+ self.machine_st.oip = oi;
+ self.machine_st.iip = ii;
+
+ match self.machine_st.dynamic_mode {
+ FirstOrNext::First if !is_next_clause => {
+ self.machine_st.p = p + offset;
+ }
+ FirstOrNext::First => {
+ // there's a leading DynamicElse that sets self.machine_st.cc.
+ // self.machine_st.cc = self.machine_st.global_clock;
+
+ // see that there is a following dynamic_else
+ // clause so we avoid generating a choice
+ // point in case there isn't.
+ match self.find_living_dynamic(oi, ii + 1) {
+ Some(_) => {
+ self.machine_st.registers
+ [self.machine_st.num_of_args + 1] =
+ fixnum_as_cell!(Fixnum::build_with(
+ self.machine_st.cc as i64
+ ));
+
+ self.machine_st.num_of_args += 1;
+ self.indexed_try(offset);
+ self.machine_st.num_of_args -= 1;
+ }
+ None => {
+ self.machine_st.p = p + offset;
+ self.machine_st.oip = 0;
+ self.machine_st.iip = 0;
+ }
+ }
+ }
+ FirstOrNext::Next => {
+ let b = self.machine_st.b;
+ let n = self
+ .machine_st
+ .stack
+ .index_or_frame(b)
+ .prelude
+ .num_cells;
+
+ self.machine_st.cc = cell_as_fixnum!(
+ self.machine_st.stack
+ [stack_loc!(OrFrame, b, n - 1)]
+ )
+ .get_num()
+ as usize;
+
+ if is_next_clause {
+ match self.find_living_dynamic(
+ self.machine_st.oip,
+ self.machine_st.iip + 1,
+ ) {
+ // if we're executing the last instruction
+ // of the internal block pointed to by
+ // self.machine_st.iip, we want trust, not retry.
+ // this is true iff ii + 1 < len.
+ Some(_) => {
+ self.retry(offset);
+
+ try_or_throw!(
+ self.machine_st,
+ (self
+ .machine_st
+ .increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
+ _ => {
+ self.trust(offset);
+
+ try_or_throw!(
+ self.machine_st,
+ (self
+ .machine_st
+ .increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
+ }
+ } else {
+ self.trust(offset);
+
+ try_or_throw!(
+ self.machine_st,
+ (self.machine_st.increment_call_count_fn)(
+ &mut self.machine_st
+ )
+ );
+ }
+ }
+ }
+ }
+ None => {
+ self.machine_st.fail = true;
+ }
+ }
+
+ self.machine_st.dynamic_mode = FirstOrNext::Next;
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ }
+ }
+ &Instruction::PutConstant(_, c, reg) => {
+ self.machine_st[reg] = c;
+ self.machine_st.p += 1;
+ }
+ &Instruction::PutList(_, reg) => {
+ self.machine_st[reg] = list_loc_as_cell!(self.machine_st.heap.len());
+ self.machine_st.p += 1;
+ }
+ &Instruction::PutPartialString(_, string, reg, has_tail) => {
+ let pstr_addr = if has_tail {
+ if string != atom!("") {
+ let h = self.machine_st.heap.len();
+ self.machine_st.heap.push(string_as_pstr_cell!(string));
+
+ // the tail will be pushed by the next
+ // instruction, so don't push one here.
+
+ pstr_loc_as_cell!(h)
+ } else {
+ empty_list_as_cell!()
+ }
+ } else {
+ string_as_cstr_cell!(string)
+ };
+
+ self.machine_st[reg] = pstr_addr;
+ self.machine_st.p += 1;
+ }
+ &Instruction::PutStructure(name, arity, reg) => {
+ let h = self.machine_st.heap.len();
+
+ self.machine_st.heap.push(atom_as_cell!(name, arity));
+ self.machine_st[reg] = str_loc_as_cell!(h);
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::PutUnsafeValue(perm_slot, arg) => {
+ let s = stack_loc!(AndFrame, self.machine_st.e, perm_slot);
+ let addr = self
+ .machine_st
+ .store(self.machine_st.deref(stack_loc_as_cell!(s)));
+
+ if addr.is_protected(self.machine_st.e) {
+ self.machine_st.registers[arg] = addr;
+ } else {
+ let h = self.machine_st.heap.len();
+
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+ (self.machine_st.bind_fn)(
+ &mut self.machine_st,
+ Ref::heap_cell(h),
+ addr,
+ );
+
+ self.machine_st.registers[arg] = heap_loc_as_cell!(h);
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::PutValue(norm, arg) => {
+ self.machine_st.registers[arg] = self.machine_st[norm];
+ self.machine_st.p += 1;
+ }
+ &Instruction::PutVariable(norm, arg) => {
+ match norm {
+ RegType::Perm(n) => {
+ self.machine_st[norm] =
+ stack_loc_as_cell!(AndFrame, self.machine_st.e, n);
+ self.machine_st.registers[arg] = self.machine_st[norm];
+ }
+ RegType::Temp(_) => {
+ let h = self.machine_st.heap.len();
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+
+ self.machine_st[norm] = heap_loc_as_cell!(h);
+ self.machine_st.registers[arg] = heap_loc_as_cell!(h);
+ }
+ };
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::SetConstant(c) => {
+ self.machine_st.heap.push(c);
+ self.machine_st.p += 1;
+ }
+ &Instruction::SetLocalValue(reg) => {
+ let addr = self.machine_st.deref(self.machine_st[reg]);
+ let stored_v = self.machine_st.store(addr);
+
+ if stored_v.is_stack_var() {
+ let h = self.machine_st.heap.len();
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+ (self.machine_st.bind_fn)(
+ &mut self.machine_st,
+ Ref::heap_cell(h),
+ stored_v,
+ );
+ } else {
+ self.machine_st.heap.push(stored_v);
+ }
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::SetVariable(reg) => {
+ let h = self.machine_st.heap.len();
+
+ self.machine_st.heap.push(heap_loc_as_cell!(h));
+ self.machine_st[reg] = heap_loc_as_cell!(h);
+
+ self.machine_st.p += 1;
+ }
+ &Instruction::SetValue(reg) => {
+ let heap_val = self.machine_st.store(self.machine_st[reg]);
+ self.machine_st.heap.push(heap_val);
+ self.machine_st.p += 1;
+ }
+ &Instruction::SetVoid(n) => {
+ let h = self.machine_st.heap.len();
+
+ for i in h..h + n {
+ self.machine_st.heap.push(heap_loc_as_cell!(i));
+ }
+
+ self.machine_st.p += 1;
+ }
+ //
+ &Instruction::CallAtomChars => {
+ self.atom_chars();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteAtomChars => {
+ self.atom_chars();
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallAtomCodes => {
+ try_or_throw!(self.machine_st, self.atom_codes());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteAtomCodes => {
+ try_or_throw!(self.machine_st, self.atom_codes());
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ } else {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallAtomLength => {
+ self.atom_length();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteAtomLength => {
+ self.atom_length();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallBindFromRegister => {
+ self.bind_from_register();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteBindFromRegister => {
+ self.bind_from_register();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallContinuation => {
+ try_or_throw!(self.machine_st, self.call_continuation(false));
+ }
+ &Instruction::ExecuteContinuation => {
+ try_or_throw!(self.machine_st, self.call_continuation(true));
+ }
+ &Instruction::CallCharCode => {
+ try_or_throw!(self.machine_st, self.char_code());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCharCode => {
+ try_or_throw!(self.machine_st, self.char_code());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCharType => {
+ self.char_type();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCharType => {
+ self.char_type();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCharsToNumber => {
+ try_or_throw!(self.machine_st, self.chars_to_number());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCharsToNumber => {
+ try_or_throw!(self.machine_st, self.chars_to_number());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCodesToNumber => {
+ try_or_throw!(self.machine_st, self.codes_to_number());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCodesToNumber => {
+ try_or_throw!(self.machine_st, self.codes_to_number());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCopyTermWithoutAttrVars => {
+ self.copy_term_without_attr_vars();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCopyTermWithoutAttrVars => {
+ self.copy_term_without_attr_vars();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCheckCutPoint => {
+ self.check_cut_point();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCheckCutPoint => {
+ self.check_cut_point();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallClose => {
+ try_or_throw!(self.machine_st, self.close());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteClose => {
+ try_or_throw!(self.machine_st, self.close());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallCopyToLiftedHeap => {
+ self.copy_to_lifted_heap();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteCopyToLiftedHeap => {
+ self.copy_to_lifted_heap();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallCreatePartialString => {
+ self.create_partial_string();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCreatePartialString => {
+ self.create_partial_string();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCurrentHostname => {
+ self.current_hostname();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCurrentHostname => {
+ self.current_hostname();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCurrentInput => {
+ try_or_throw!(self.machine_st, self.current_input());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCurrentInput => {
+ try_or_throw!(self.machine_st, self.current_input());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCurrentOutput => {
+ try_or_throw!(self.machine_st, self.current_output());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCurrentOutput => {
+ try_or_throw!(self.machine_st, self.current_output());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDirectoryFiles => {
+ try_or_throw!(self.machine_st, self.directory_files());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDirectoryFiles => {
+ try_or_throw!(self.machine_st, self.directory_files());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFileSize => {
+ self.file_size();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFileSize => {
+ self.file_size();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFileExists => {
+ self.file_exists();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFileExists => {
+ self.file_exists();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDirectoryExists => {
+ self.directory_exists();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDirectoryExists => {
+ self.directory_exists();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDirectorySeparator => {
+ self.directory_separator();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDirectorySeparator => {
+ self.directory_separator();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallMakeDirectory => {
+ self.make_directory();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteMakeDirectory => {
+ self.make_directory();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallMakeDirectoryPath => {
+ self.make_directory_path();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteMakeDirectoryPath => {
+ self.make_directory_path();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDeleteFile => {
+ self.delete_file();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDeleteFile => {
+ self.delete_file();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallRenameFile => {
+ self.rename_file();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteRenameFile => {
+ self.rename_file();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFileCopy => {
+ self.file_copy();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFileCopy => {
+ self.file_copy();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallWorkingDirectory => {
+ try_or_throw!(self.machine_st, self.working_directory());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteWorkingDirectory => {
+ try_or_throw!(self.machine_st, self.working_directory());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDeleteDirectory => {
+ self.delete_directory();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDeleteDirectory => {
+ self.delete_directory();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPathCanonical => {
+ try_or_throw!(self.machine_st, self.path_canonical());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePathCanonical => {
+ try_or_throw!(self.machine_st, self.path_canonical());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFileTime => {
+ self.file_time();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFileTime => {
+ self.file_time();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDynamicModuleResolution(arity) => {
+ let (module_name, key) = try_or_throw!(
+ self.machine_st,
+ self.dynamic_module_resolution(arity - 2)
+ );
+
+ try_or_throw!(self.machine_st, self.call_clause(module_name, key));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::ExecuteDynamicModuleResolution(arity) => {
+ let (module_name, key) = try_or_throw!(
+ self.machine_st,
+ self.dynamic_module_resolution(arity - 2)
+ );
+
+ try_or_throw!(self.machine_st, self.execute_clause(module_name, key));
+
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
+ }
+ }
+ &Instruction::CallFetchGlobalVar => {
+ self.fetch_global_var();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFetchGlobalVar => {
+ self.fetch_global_var();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFirstStream => {
+ self.first_stream();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFirstStream => {
+ self.first_stream();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFlushOutput => {
+ try_or_throw!(self.machine_st, self.flush_output());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteFlushOutput => {
+ try_or_throw!(self.machine_st, self.flush_output());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallGetByte => {
+ try_or_throw!(self.machine_st, self.get_byte());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetByte => {
+ try_or_throw!(self.machine_st, self.get_byte());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetChar => {
+ try_or_throw!(self.machine_st, self.get_char());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetChar => {
+ try_or_throw!(self.machine_st, self.get_char());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetNChars => {
+ try_or_throw!(self.machine_st, self.get_n_chars());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetNChars => {
+ try_or_throw!(self.machine_st, self.get_n_chars());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetCode => {
+ try_or_throw!(self.machine_st, self.get_code());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetCode => {
+ try_or_throw!(self.machine_st, self.get_code());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetSingleChar => {
+ try_or_throw!(self.machine_st, self.get_single_char());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetSingleChar => {
+ try_or_throw!(self.machine_st, self.get_single_char());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff => {
+ self.truncate_if_no_lifted_heap_growth_diff();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff => {
+ self.truncate_if_no_lifted_heap_growth_diff();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallTruncateIfNoLiftedHeapGrowth => {
+ self.truncate_if_no_lifted_heap_growth();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth => {
+ self.truncate_if_no_lifted_heap_growth();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetAttributedVariableList => {
+ self.get_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetAttributedVariableList => {
+ self.get_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetAttrVarQueueDelimiter => {
+ self.get_attr_var_queue_delimiter();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetAttrVarQueueDelimiter => {
+ self.get_attr_var_queue_delimiter();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetAttrVarQueueBeyond => {
+ self.get_attr_var_queue_beyond();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetAttrVarQueueBeyond => {
+ self.get_attr_var_queue_beyond();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetBValue => {
+ self.get_b_value();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetBValue => {
+ self.get_b_value();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetContinuationChunk => {
+ self.get_continuation_chunk();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetContinuationChunk => {
+ self.get_continuation_chunk();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLookupDBRef => {
+ self.lookup_db_ref();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLookupDBRef => {
+ self.lookup_db_ref();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetNextOpDBRef => {
+ self.get_next_op_db_ref();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetNextOpDBRef => {
+ self.get_next_op_db_ref();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallIsPartialString => {
+ self.is_partial_string();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteIsPartialString => {
+ self.is_partial_string();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallHalt | &Instruction::ExecuteHalt => {
+ return self.halt();
+ }
+ &Instruction::CallGetLiftedHeapFromOffset => {
+ self.get_lifted_heap_from_offset();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetLiftedHeapFromOffset => {
+ self.get_lifted_heap_from_offset();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetLiftedHeapFromOffsetDiff => {
+ self.get_lifted_heap_from_offset_diff();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetLiftedHeapFromOffsetDiff => {
+ self.get_lifted_heap_from_offset_diff();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetSCCCleaner => {
+ self.get_scc_cleaner();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetSCCCleaner => {
+ self.get_scc_cleaner();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallHeadIsDynamic => {
+ self.head_is_dynamic();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteHeadIsDynamic => {
+ self.head_is_dynamic();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallInstallSCCCleaner => {
+ self.install_scc_cleaner();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteInstallSCCCleaner => {
+ self.install_scc_cleaner();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallInstallInferenceCounter => {
+ try_or_throw!(self.machine_st, self.install_inference_counter());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteInstallInferenceCounter => {
+ try_or_throw!(self.machine_st, self.install_inference_counter());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLiftedHeapLength => {
+ self.lifted_heap_length();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLiftedHeapLength => {
+ self.lifted_heap_length();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadLibraryAsStream => {
+ try_or_throw!(self.machine_st, self.load_library_as_stream());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadLibraryAsStream => {
+ try_or_throw!(self.machine_st, self.load_library_as_stream());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallModuleExists => {
+ self.module_exists();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteModuleExists => {
+ self.module_exists();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallNextEP => {
+ self.next_ep();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteNextEP => {
+ self.next_ep();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallNoSuchPredicate => {
+ try_or_throw!(self.machine_st, self.no_such_predicate());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteNoSuchPredicate => {
+ try_or_throw!(self.machine_st, self.no_such_predicate());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallNumberToChars => {
+ self.number_to_chars();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteNumberToChars => {
+ self.number_to_chars();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallNumberToCodes => {
+ self.number_to_codes();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteNumberToCodes => {
+ self.number_to_codes();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallOpDeclaration => {
+ try_or_throw!(self.machine_st, self.op_declaration());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteOpDeclaration => {
+ try_or_throw!(self.machine_st, self.op_declaration());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallOpen => {
+ try_or_throw!(self.machine_st, self.open());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteOpen => {
+ try_or_throw!(self.machine_st, self.open());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetStreamOptions => {
+ try_or_throw!(self.machine_st, self.set_stream_options());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetStreamOptions => {
+ try_or_throw!(self.machine_st, self.set_stream_options());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallNextStream => {
+ self.next_stream();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteNextStream => {
+ self.next_stream();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPartialStringTail => {
+ self.partial_string_tail();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePartialStringTail => {
+ self.partial_string_tail();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPeekByte => {
+ try_or_throw!(self.machine_st, self.peek_byte());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePeekByte => {
+ try_or_throw!(self.machine_st, self.peek_byte());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPeekChar => {
+ try_or_throw!(self.machine_st, self.peek_char());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePeekChar => {
+ try_or_throw!(self.machine_st, self.peek_char());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPeekCode => {
+ try_or_throw!(self.machine_st, self.peek_code());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePeekCode => {
+ try_or_throw!(self.machine_st, self.peek_code());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPointsToContinuationResetMarker => {
+ self.points_to_continuation_reset_marker();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePointsToContinuationResetMarker => {
+ self.points_to_continuation_reset_marker();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPutByte => {
+ try_or_throw!(self.machine_st, self.put_byte());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePutByte => {
+ try_or_throw!(self.machine_st, self.put_byte());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPutChar => {
+ try_or_throw!(self.machine_st, self.put_char());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePutChar => {
+ try_or_throw!(self.machine_st, self.put_char());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPutChars => {
+ try_or_throw!(self.machine_st, self.put_chars());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePutChars => {
+ try_or_throw!(self.machine_st, self.put_chars());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPutCode => {
+ try_or_throw!(self.machine_st, self.put_code());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePutCode => {
+ try_or_throw!(self.machine_st, self.put_code());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallReadQueryTerm => {
+ try_or_throw!(self.machine_st, self.read_query_term());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteReadQueryTerm => {
+ try_or_throw!(self.machine_st, self.read_query_term());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallReadTerm => {
+ try_or_throw!(self.machine_st, self.read_term());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteReadTerm => {
+ try_or_throw!(self.machine_st, self.read_term());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallRedoAttrVarBinding => {
+ self.redo_attr_var_binding();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteRedoAttrVarBinding => {
+ self.redo_attr_var_binding();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallRemoveCallPolicyCheck => {
+ self.remove_call_policy_check();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteRemoveCallPolicyCheck => {
+ self.remove_call_policy_check();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallRemoveInferenceCounter => {
+ self.remove_inference_counter();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteRemoveInferenceCounter => {
+ self.remove_inference_counter();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallResetContinuationMarker => {
+ self.reset_continuation_marker();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteResetContinuationMarker => {
+ self.reset_continuation_marker();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallRestoreCutPolicy => {
+ self.restore_cut_policy();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteRestoreCutPolicy => {
+ self.restore_cut_policy();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallSetCutPoint(r) => {
+ if !self.set_cut_point(r) {
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ }
+ &Instruction::ExecuteSetCutPoint(r) => {
+ let cp = self.machine_st.cp;
+
+ if !self.set_cut_point(r) {
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ } else {
+ // run_cleaners in set_cut_point calls call_by_index.
+ // replace the effect of call_by_index with that
+ // of execute_by_index here.
+
+ self.machine_st.cp = cp;
+ }
+ }
+ &Instruction::CallSetInput => {
+ try_or_throw!(self.machine_st, self.set_input());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetInput => {
+ try_or_throw!(self.machine_st, self.set_input());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallSetOutput => {
+ try_or_throw!(self.machine_st, self.set_output());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetOutput => {
+ try_or_throw!(self.machine_st, self.set_output());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallStoreBacktrackableGlobalVar => {
+ self.store_backtrackable_global_var();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteStoreBacktrackableGlobalVar => {
+ self.store_backtrackable_global_var();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallStoreGlobalVar => {
+ self.store_global_var();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteStoreGlobalVar => {
+ self.store_global_var();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallStreamProperty => {
+ try_or_throw!(self.machine_st, self.stream_property());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteStreamProperty => {
+ try_or_throw!(self.machine_st, self.stream_property());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetStreamPosition => {
+ try_or_throw!(self.machine_st, self.set_stream_position());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSetStreamPosition => {
+ try_or_throw!(self.machine_st, self.set_stream_position());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallInferenceLevel => {
+ self.inference_level();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteInferenceLevel => {
+ self.inference_level();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCleanUpBlock => {
+ self.clean_up_block();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteCleanUpBlock => {
+ self.clean_up_block();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallFail | &Instruction::ExecuteFail => {
self.machine_st.backtrack();
- } else {
+ }
+ &Instruction::CallGetBall => {
+ self.get_ball();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetBall => {
+ self.get_ball();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetCurrentBlock => {
+ self.get_current_block();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetCurrentBlock => {
+ self.get_current_block();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetCurrentSCCBlock => {
+ self.get_current_scc_block();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetCurrentSCCBlock => {
+ self.get_current_scc_block();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetCutPoint => {
+ self.get_cut_point();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetCutPoint => {
+ self.get_cut_point();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetDoubleQuotes => {
+ self.get_double_quotes();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetDoubleQuotes => {
+ self.get_double_quotes();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetUnknown => {
+ self.get_unknown();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetUnknown => {
+ self.get_unknown();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallInstallNewBlock => {
+ self.machine_st
+ .install_new_block(self.machine_st.registers[1]);
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteInstallNewBlock => {
+ self.machine_st
+ .install_new_block(self.machine_st.registers[1]);
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallMaybe => {
+ self.maybe();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteMaybe => {
+ self.maybe();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCpuNow => {
+ self.cpu_now();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCpuNow => {
+ self.cpu_now();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDeterministicLengthRundown => {
+ try_or_throw!(self.machine_st, self.det_length_rundown());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDeterministicLengthRundown => {
+ try_or_throw!(self.machine_st, self.det_length_rundown());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallHttpOpen => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_open());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteHttpOpen => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_open());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallHttpListen => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_listen());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteHttpListen => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_listen());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallHttpAccept => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_accept());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteHttpAccept => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_accept());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallHttpAnswer => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_answer());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteHttpAnswer => {
+ #[cfg(feature = "http")]
+ try_or_throw!(self.machine_st, self.http_answer());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadForeignLib => {
+ #[cfg(feature = "ffi")]
+ try_or_throw!(self.machine_st, self.load_foreign_lib());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadForeignLib => {
+ #[cfg(feature = "ffi")]
+ try_or_throw!(self.machine_st, self.load_foreign_lib());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallForeignCall => {
+ #[cfg(feature = "ffi")]
+ try_or_throw!(self.machine_st, self.foreign_call());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteForeignCall => {
+ #[cfg(feature = "ffi")]
+ try_or_throw!(self.machine_st, self.foreign_call());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDefineForeignStruct => {
+ #[cfg(feature = "ffi")]
+ try_or_throw!(self.machine_st, self.define_foreign_struct());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDefineForeignStruct => {
+ #[cfg(feature = "ffi")]
+ try_or_throw!(self.machine_st, self.define_foreign_struct());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCurrentTime => {
+ self.current_time();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCurrentTime => {
+ self.current_time();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallQuotedToken => {
+ self.quoted_token();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteQuotedToken => {
+ self.quoted_token();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallReadFromChars => {
+ try_or_throw!(self.machine_st, self.read_from_chars());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteReadFromChars => {
+ try_or_throw!(self.machine_st, self.read_from_chars());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallReadTermFromChars => {
+ try_or_throw!(self.machine_st, self.read_term_from_chars());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteReadTermFromChars => {
+ try_or_throw!(self.machine_st, self.read_term_from_chars());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallResetBlock => {
+ self.reset_block();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteResetBlock => {
+ self.reset_block();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallResetSCCBlock => {
+ self.reset_scc_block();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteResetSCCBlock => {
+ self.reset_scc_block();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallReturnFromVerifyAttr
+ | &Instruction::ExecuteReturnFromVerifyAttr => {
+ self.return_from_verify_attr();
+ }
+ &Instruction::CallSetBall => {
+ self.set_ball();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetBall => {
+ self.set_ball();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPushBallStack => {
+ self.push_ball_stack();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePushBallStack => {
+ self.push_ball_stack();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPopBallStack => {
+ self.pop_ball_stack();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePopBallStack => {
+ self.pop_ball_stack();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPopFromBallStack => {
+ self.pop_from_ball_stack();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePopFromBallStack => {
+ self.pop_from_ball_stack();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallSetCutPointByDefault(r) => {
+ self.set_cut_point_by_default(r);
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSetCutPointByDefault(r) => {
+ self.set_cut_point_by_default(r);
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetDoubleQuotes => {
+ self.set_double_quotes();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSetDoubleQuotes => {
+ self.set_double_quotes();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetUnknown => {
+ self.set_unknown();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSetUnknown => {
+ self.set_unknown();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetSeed => {
+ self.set_seed();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSetSeed => {
+ self.set_seed();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSkipMaxList => {
+ try_or_throw!(self.machine_st, self.machine_st.skip_max_list());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSkipMaxList => {
+ try_or_throw!(self.machine_st, self.machine_st.skip_max_list());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSleep => {
+ self.sleep();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSleep => {
+ self.sleep();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallSocketClientOpen => {
+ try_or_throw!(self.machine_st, self.socket_client_open());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSocketClientOpen => {
+ try_or_throw!(self.machine_st, self.socket_client_open());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSocketServerOpen => {
+ try_or_throw!(self.machine_st, self.socket_server_open());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSocketServerOpen => {
+ try_or_throw!(self.machine_st, self.socket_server_open());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSocketServerAccept => {
+ try_or_throw!(self.machine_st, self.socket_server_accept());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteSocketServerAccept => {
+ try_or_throw!(self.machine_st, self.socket_server_accept());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSocketServerClose => {
+ try_or_throw!(self.machine_st, self.socket_server_close());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSocketServerClose => {
+ try_or_throw!(self.machine_st, self.socket_server_close());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallTLSAcceptClient => {
+ #[cfg(feature = "tls")]
+ try_or_throw!(self.machine_st, self.tls_accept_client());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTLSAcceptClient => {
+ #[cfg(feature = "tls")]
+ try_or_throw!(self.machine_st, self.tls_accept_client());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallTLSClientConnect => {
+ #[cfg(feature = "tls")]
+ try_or_throw!(self.machine_st, self.tls_client_connect());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTLSClientConnect => {
+ #[cfg(feature = "tls")]
+ try_or_throw!(self.machine_st, self.tls_client_connect());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSucceed => {
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSucceed => {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallTermAttributedVariables => {
+ self.term_attributed_variables();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTermAttributedVariables => {
+ self.term_attributed_variables();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallTermVariables => {
+ self.term_variables();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTermVariables => {
+ self.term_variables();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallTermVariablesUnderMaxDepth => {
+ self.term_variables_under_max_depth();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteTermVariablesUnderMaxDepth => {
+ self.term_variables_under_max_depth();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallTruncateLiftedHeapTo => {
+ self.truncate_lifted_heap_to();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteTruncateLiftedHeapTo => {
+ self.truncate_lifted_heap_to();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallUnifyWithOccursCheck => {
+ self.unify_with_occurs_check();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteUnifyWithOccursCheck => {
+ self.unify_with_occurs_check();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallUnwindEnvironments => {
+ if !self.unwind_environments() {
+ self.machine_st.p += 1;
+ }
+ }
+ &Instruction::ExecuteUnwindEnvironments => {
+ if !self.unwind_environments() {
+ self.machine_st.p = self.machine_st.cp;
+ }
+ }
+ &Instruction::CallUnwindStack | &Instruction::ExecuteUnwindStack => {
+ self.machine_st.unwind_stack();
+ self.machine_st.backtrack();
+ }
+ &Instruction::CallWAMInstructions => {
+ try_or_throw!(self.machine_st, self.wam_instructions());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteWAMInstructions => {
+ try_or_throw!(self.machine_st, self.wam_instructions());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallInlinedInstructions => {
+ self.inlined_instructions();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteInlinedInstructions => {
+ self.inlined_instructions();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallWriteTerm => {
+ try_or_throw!(self.machine_st, self.write_term());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteWriteTerm => {
+ try_or_throw!(self.machine_st, self.write_term());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallWriteTermToChars => {
+ try_or_throw!(self.machine_st, self.write_term_to_chars());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteWriteTermToChars => {
+ try_or_throw!(self.machine_st, self.write_term_to_chars());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallScryerPrologVersion => {
+ self.scryer_prolog_version();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteScryerPrologVersion => {
+ self.scryer_prolog_version();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCryptoRandomByte => {
+ self.crypto_random_byte();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCryptoRandomByte => {
+ self.crypto_random_byte();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCryptoDataHash => {
+ self.crypto_data_hash();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCryptoDataHash => {
+ self.crypto_data_hash();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCryptoDataHKDF => {
+ self.crypto_data_hkdf();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCryptoDataHKDF => {
+ self.crypto_data_hkdf();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCryptoPasswordHash => {
+ self.crypto_password_hash();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCryptoPasswordHash => {
+ self.crypto_password_hash();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallCryptoDataEncrypt => {
+ self.crypto_data_encrypt();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteCryptoDataEncrypt => {
+ self.crypto_data_encrypt();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallCryptoDataDecrypt => {
+ self.crypto_data_decrypt();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteCryptoDataDecrypt => {
+ self.crypto_data_decrypt();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCryptoCurveScalarMult => {
+ self.crypto_curve_scalar_mult();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCryptoCurveScalarMult => {
+ self.crypto_curve_scalar_mult();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallEd25519Sign => {
+ self.ed25519_sign();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteEd25519Sign => {
+ self.ed25519_sign();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallEd25519Verify => {
+ self.ed25519_verify();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteEd25519Verify => {
+ self.ed25519_verify();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallEd25519NewKeyPair => {
+ self.ed25519_new_key_pair();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteEd25519NewKeyPair => {
+ self.ed25519_new_key_pair();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::CallEd25519KeyPairPublicKey => {
+ self.ed25519_key_pair_public_key();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ #[cfg(feature = "crypto-full")]
+ &Instruction::ExecuteEd25519KeyPairPublicKey => {
+ self.ed25519_key_pair_public_key();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCurve25519ScalarMult => {
+ self.curve25519_scalar_mult();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCurve25519ScalarMult => {
+ self.curve25519_scalar_mult();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFirstNonOctet => {
+ self.first_non_octet();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteFirstNonOctet => {
+ self.first_non_octet();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadHTML => {
+ self.load_html();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadHTML => {
+ self.load_html();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadXML => {
+ self.load_xml();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadXML => {
+ self.load_xml();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallGetEnv => {
+ self.get_env();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetEnv => {
+ self.get_env();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetEnv => {
+ self.set_env();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetEnv => {
+ self.set_env();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallUnsetEnv => {
+ self.unset_env();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteUnsetEnv => {
+ self.unset_env();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallShell => {
+ self.shell();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteShell => {
+ self.shell();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPID => {
+ self.pid();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePID => {
+ self.pid();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCharsBase64 => {
+ try_or_throw!(self.machine_st, self.chars_base64());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCharsBase64 => {
+ try_or_throw!(self.machine_st, self.chars_base64());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDevourWhitespace => {
+ try_or_throw!(self.machine_st, self.devour_whitespace());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDevourWhitespace => {
+ try_or_throw!(self.machine_st, self.devour_whitespace());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallIsSTOEnabled => {
+ self.is_sto_enabled();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteIsSTOEnabled => {
+ self.is_sto_enabled();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallSetSTOAsUnify => {
+ self.set_sto_as_unify();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetSTOAsUnify => {
+ self.set_sto_as_unify();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallSetNSTOAsUnify => {
+ self.set_nsto_as_unify();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetNSTOAsUnify => {
+ self.set_nsto_as_unify();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallSetSTOWithErrorAsUnify => {
+ self.set_sto_with_error_as_unify();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteSetSTOWithErrorAsUnify => {
+ self.set_sto_with_error_as_unify();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallHomeDirectory => {
+ self.home_directory();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteHomeDirectory => {
+ self.home_directory();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDebugHook => {
+ self.debug_hook();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteDebugHook => {
+ self.debug_hook();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPopCount => {
+ self.pop_count();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePopCount => {
+ self.pop_count();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallAddDiscontiguousPredicate => {
+ try_or_throw!(self.machine_st, self.add_discontiguous_predicate());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddDiscontiguousPredicate => {
+ try_or_throw!(self.machine_st, self.add_discontiguous_predicate());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAddDynamicPredicate => {
+ try_or_throw!(self.machine_st, self.add_dynamic_predicate());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddDynamicPredicate => {
+ try_or_throw!(self.machine_st, self.add_dynamic_predicate());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAddMultifilePredicate => {
+ try_or_throw!(self.machine_st, self.add_multifile_predicate());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddMultifilePredicate => {
+ try_or_throw!(self.machine_st, self.add_multifile_predicate());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAddGoalExpansionClause => {
+ try_or_throw!(self.machine_st, self.add_goal_expansion_clause());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddGoalExpansionClause => {
+ try_or_throw!(self.machine_st, self.add_goal_expansion_clause());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAddTermExpansionClause => {
+ try_or_throw!(self.machine_st, self.add_term_expansion_clause());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddTermExpansionClause => {
+ try_or_throw!(self.machine_st, self.add_term_expansion_clause());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAddInSituFilenameModule => {
+ try_or_throw!(self.machine_st, self.add_in_situ_filename_module());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddInSituFilenameModule => {
+ try_or_throw!(self.machine_st, self.add_in_situ_filename_module());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallClauseToEvacuable => {
+ try_or_throw!(self.machine_st, self.clause_to_evacuable());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteClauseToEvacuable => {
+ try_or_throw!(self.machine_st, self.clause_to_evacuable());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallScopedClauseToEvacuable => {
+ try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteScopedClauseToEvacuable => {
+ try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallConcludeLoad => {
+ try_or_throw!(self.machine_st, self.conclude_load());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteConcludeLoad => {
+ try_or_throw!(self.machine_st, self.conclude_load());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallDeclareModule => {
+ try_or_throw!(self.machine_st, self.declare_module());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteDeclareModule => {
+ try_or_throw!(self.machine_st, self.declare_module());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallLoadCompiledLibrary => {
+ try_or_throw!(self.machine_st, self.load_compiled_library());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadCompiledLibrary => {
+ try_or_throw!(self.machine_st, self.load_compiled_library());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadContextSource => {
+ self.load_context_source();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadContextSource => {
+ self.load_context_source();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadContextFile => {
+ self.load_context_file();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadContextFile => {
+ self.load_context_file();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadContextDirectory => {
+ self.load_context_directory();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadContextDirectory => {
+ self.load_context_directory();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadContextModule => {
+ self.load_context_module(self.machine_st.registers[1]);
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadContextModule => {
+ self.load_context_module(self.machine_st.registers[1]);
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallLoadContextStream => {
+ self.load_context_stream();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteLoadContextStream => {
+ self.load_context_stream();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPopLoadContext => {
+ self.pop_load_context();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePopLoadContext => {
+ self.pop_load_context();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPopLoadStatePayload => {
+ self.pop_load_state_payload();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePopLoadStatePayload => {
+ self.pop_load_state_payload();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPushLoadContext => {
+ try_or_throw!(self.machine_st, self.push_load_context());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecutePushLoadContext => {
+ try_or_throw!(self.machine_st, self.push_load_context());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPushLoadStatePayload => {
+ self.push_load_state_payload();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePushLoadStatePayload => {
+ self.push_load_state_payload();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallUseModule => {
+ try_or_throw!(self.machine_st, self.use_module());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteUseModule => {
+ try_or_throw!(self.machine_st, self.use_module());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallBuiltInProperty => {
+ let key = self.machine_st.read_predicate_key(
+ self.machine_st.registers[1],
+ self.machine_st.registers[2],
+ );
+
+ self.machine_st.fail = !self.indices.builtin_property(key);
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteBuiltInProperty => {
+ let key = self.machine_st.read_predicate_key(
+ self.machine_st.registers[1],
+ self.machine_st.registers[2],
+ );
+
+ self.machine_st.fail = !self.indices.builtin_property(key);
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallMetaPredicateProperty => {
+ self.meta_predicate_property();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteMetaPredicateProperty => {
+ self.meta_predicate_property();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallMultifileProperty => {
+ self.multifile_property();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteMultifileProperty => {
+ self.multifile_property();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDiscontiguousProperty => {
+ self.discontiguous_property();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDiscontiguousProperty => {
+ self.discontiguous_property();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDynamicProperty => {
+ self.dynamic_property();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDynamicProperty => {
+ self.dynamic_property();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallAbolishClause => {
+ try_or_throw!(self.machine_st, self.abolish_clause());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAbolishClause => {
+ try_or_throw!(self.machine_st, self.abolish_clause());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAsserta => {
try_or_throw!(
self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ self.compile_assert(AppendOrPrepend::Prepend)
);
+ self.machine_st.p += 1;
}
- }
- &Instruction::ExecuteFastCallN(arity) => {
- let call_at_index = |wam: &mut Machine, name, arity, ptr| {
- wam.try_execute(name, arity, ptr)
- };
-
- try_or_throw!(self.machine_st, self.fast_call(arity, call_at_index));
-
- if self.machine_st.fail {
- self.machine_st.backtrack();
- } else {
+ &Instruction::ExecuteAsserta => {
try_or_throw!(
self.machine_st,
- (self.machine_st.increment_call_count_fn)(&mut self.machine_st)
+ self.compile_assert(AppendOrPrepend::Prepend)
);
+ self.machine_st.p = self.machine_st.cp;
}
- }
- &Instruction::CallGetClauseP => {
- let module_name = cell_as_atom!(self.deref_register(3));
+ &Instruction::CallAssertz => {
+ try_or_throw!(
+ self.machine_st,
+ self.compile_assert(AppendOrPrepend::Append)
+ );
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAssertz => {
+ try_or_throw!(
+ self.machine_st,
+ self.compile_assert(AppendOrPrepend::Append)
+ );
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallRetract => {
+ try_or_throw!(self.machine_st, self.retract_clause());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteRetract => {
+ try_or_throw!(self.machine_st, self.retract_clause());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallIsConsistentWithTermQueue => {
+ try_or_throw!(self.machine_st, self.is_consistent_with_term_queue());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteIsConsistentWithTermQueue => {
+ try_or_throw!(self.machine_st, self.is_consistent_with_term_queue());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::CallFlushTermQueue => {
+ try_or_throw!(self.machine_st, self.flush_term_queue());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteFlushTermQueue => {
+ try_or_throw!(self.machine_st, self.flush_term_queue());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallRemoveModuleExports => {
+ try_or_throw!(self.machine_st, self.remove_module_exports());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteRemoveModuleExports => {
+ try_or_throw!(self.machine_st, self.remove_module_exports());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallAddNonCountedBacktracking => {
+ try_or_throw!(self.machine_st, self.add_non_counted_backtracking());
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteAddNonCountedBacktracking => {
+ try_or_throw!(self.machine_st, self.add_non_counted_backtracking());
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallPredicateDefined => {
+ self.machine_st.fail = !self.predicate_defined();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePredicateDefined => {
+ self.machine_st.fail = !self.predicate_defined();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallStripModule => {
+ self.strip_module();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteStripModule => {
+ self.strip_module();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPrepareCallClause(arity) => {
+ try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePrepareCallClause(arity) => {
+ try_or_throw!(self.machine_st, self.prepare_call_clause(arity));
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallCompileInlineOrExpandedGoal => {
+ try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal());
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteCompileInlineOrExpandedGoal => {
+ try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal());
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallIsExpandedOrInlined => {
+ self.machine_st.fail = !self.is_expanded_or_inlined();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteIsExpandedOrInlined => {
+ self.machine_st.fail = !self.is_expanded_or_inlined();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallFastCallN(arity) => {
+ let call_at_index =
+ |wam: &mut Machine, name, arity, ptr| wam.try_call(name, arity, ptr);
- let (n, p) = self.get_clause_p(module_name);
+ try_or_throw!(self.machine_st, self.fast_call(arity, call_at_index));
- let r = self.machine_st.registers[2];
- let r = self.machine_st.store(self.machine_st.deref(r));
-
- let h = self.machine_st.heap.len();
- self.machine_st.heap.extend(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
-
- let r = r.as_var().unwrap();
- self.machine_st.bind(r, str_loc_as_cell!(h));
-
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetClauseP => {
- let module_name = cell_as_atom!(self.deref_register(3));
-
- let (n, p) = self.get_clause_p(module_name);
-
- let r = self.machine_st.registers[2];
- let r = self.machine_st.store(self.machine_st.deref(r));
-
- let h = self.machine_st.heap.len();
- self.machine_st.heap.extend(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
-
- let r = r.as_var().unwrap();
- self.machine_st.bind(r, str_loc_as_cell!(h));
-
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallInvokeClauseAtP => {
- let key_cell = self.machine_st.registers[1];
- let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap();
-
- let l = self.machine_st.registers[3];
- let l = self.machine_st.store(self.machine_st.deref(l));
-
- let l = match Number::try_from(l) {
- Ok(Number::Fixnum(l)) => l.get_num() as usize,
- _ => unreachable!(),
- };
-
- let p = self.machine_st.registers[4];
- let p = self.machine_st.store(self.machine_st.deref(p));
-
- let p = match Number::try_from(p) {
- Ok(Number::Fixnum(p)) => p.get_num() as usize,
- _ => unreachable!(),
- };
-
- let module_name = cell_as_atom!(self.deref_register(6));
-
- let compilation_target = match module_name {
- atom!("user") => CompilationTarget::User,
- _ => CompilationTarget::Module(module_name),
- };
-
- let skeleton = self.indices.get_predicate_skeleton_mut(
- &compilation_target,
- &key,
- ).unwrap();
-
- match skeleton.target_pos_of_clause_clause_loc(l) {
- Some(n) => {
- let r = self.machine_st.store(self.machine_st.deref(
- self.machine_st.registers[5],
- ));
-
- self.machine_st.unify_fixnum(Fixnum::build_with(n as i64), r);
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
}
- None => {}
}
+ &Instruction::ExecuteFastCallN(arity) => {
+ let call_at_index =
+ |wam: &mut Machine, name, arity, ptr| wam.try_execute(name, arity, ptr);
- self.machine_st.call_at_index(2, p);
- }
- &Instruction::ExecuteInvokeClauseAtP => {
- let key_cell = self.machine_st.registers[1];
- let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap();
+ try_or_throw!(self.machine_st, self.fast_call(arity, call_at_index));
- let l = self.machine_st.registers[3];
- let l = self.machine_st.store(self.machine_st.deref(l));
-
- let l = match Number::try_from(l) {
- Ok(Number::Fixnum(l)) => l.get_num() as usize,
- _ => unreachable!(),
- };
-
- let p = self.machine_st.registers[4];
- let p = self.machine_st.store(self.machine_st.deref(p));
-
- let p = match Number::try_from(p) {
- Ok(Number::Fixnum(p)) => p.get_num() as usize,
- _ => unreachable!(),
- };
-
- let module_name = cell_as_atom!(self.deref_register(6));
-
- let compilation_target = match module_name {
- atom!("user") => CompilationTarget::User,
- _ => CompilationTarget::Module(module_name),
- };
-
- let skeleton = self.indices.get_predicate_skeleton_mut(
- &compilation_target,
- &key,
- ).unwrap();
-
- match skeleton.target_pos_of_clause_clause_loc(l) {
- Some(n) => {
- let r = self.machine_st.store(self.machine_st.deref(
- self.machine_st.registers[5],
- ));
-
- self.machine_st.unify_fixnum(Fixnum::build_with(n as i64), r);
+ if self.machine_st.fail {
+ self.machine_st.backtrack();
}
- None => {}
}
+ &Instruction::CallGetClauseP => {
+ let module_name = cell_as_atom!(self.deref_register(3));
- self.machine_st.execute_at_index(2, p);
- }
- &Instruction::CallGetFromAttributedVarList => {
- self.get_from_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetFromAttributedVarList => {
- self.get_from_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallPutToAttributedVarList => {
- self.put_to_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecutePutToAttributedVarList => {
- self.put_to_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDeleteFromAttributedVarList => {
- self.delete_from_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteDeleteFromAttributedVarList => {
- self.delete_from_attributed_variable_list();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
- }
- &Instruction::CallDeleteAllAttributesFromVar => {
- self.delete_all_attributes_from_var();
- self.machine_st.p += 1;
- }
- &Instruction::ExecuteDeleteAllAttributesFromVar => {
- self.delete_all_attributes_from_var();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallUnattributedVar => {
- self.machine_st.unattributed_var();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteUnattributedVar => {
- self.machine_st.unattributed_var();
- self.machine_st.p = self.machine_st.cp;
- }
- &Instruction::CallGetDBRefs => {
- self.get_db_refs();
- step_or_fail!(self, self.machine_st.p += 1);
- }
- &Instruction::ExecuteGetDBRefs => {
- self.get_db_refs();
- step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ let (n, p) = self.get_clause_p(module_name);
+
+ let r = self.machine_st.registers[2];
+ let r = self.machine_st.store(self.machine_st.deref(r));
+
+ let h = self.machine_st.heap.len();
+ self.machine_st
+ .heap
+ .extend(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
+
+ let r = r.as_var().unwrap();
+ self.machine_st.bind(r, str_loc_as_cell!(h));
+
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetClauseP => {
+ let module_name = cell_as_atom!(self.deref_register(3));
+
+ let (n, p) = self.get_clause_p(module_name);
+
+ let r = self.machine_st.registers[2];
+ let r = self.machine_st.store(self.machine_st.deref(r));
+
+ let h = self.machine_st.heap.len();
+ self.machine_st
+ .heap
+ .extend(functor!(atom!("-"), [fixnum(n), fixnum(p)]));
+
+ let r = r.as_var().unwrap();
+ self.machine_st.bind(r, str_loc_as_cell!(h));
+
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallInvokeClauseAtP => {
+ let key_cell = self.machine_st.registers[1];
+ let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap();
+
+ let l = self.machine_st.registers[3];
+ let l = self.machine_st.store(self.machine_st.deref(l));
+
+ let l = match Number::try_from(l) {
+ Ok(Number::Fixnum(l)) => l.get_num() as usize,
+ _ => unreachable!(),
+ };
+
+ let p = self.machine_st.registers[4];
+ let p = self.machine_st.store(self.machine_st.deref(p));
+
+ let p = match Number::try_from(p) {
+ Ok(Number::Fixnum(p)) => p.get_num() as usize,
+ _ => unreachable!(),
+ };
+
+ let module_name = cell_as_atom!(self.deref_register(6));
+
+ let compilation_target = match module_name {
+ atom!("user") => CompilationTarget::User,
+ _ => CompilationTarget::Module(module_name),
+ };
+
+ let skeleton = self
+ .indices
+ .get_predicate_skeleton_mut(&compilation_target, &key)
+ .unwrap();
+
+ match skeleton.target_pos_of_clause_clause_loc(l) {
+ Some(n) => {
+ let r = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st.registers[5]));
+
+ self.machine_st
+ .unify_fixnum(Fixnum::build_with(n as i64), r);
+ }
+ None => {}
+ }
+
+ self.machine_st.call_at_index(2, p);
+ }
+ &Instruction::ExecuteInvokeClauseAtP => {
+ let key_cell = self.machine_st.registers[1];
+ let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap();
+
+ let l = self.machine_st.registers[3];
+ let l = self.machine_st.store(self.machine_st.deref(l));
+
+ let l = match Number::try_from(l) {
+ Ok(Number::Fixnum(l)) => l.get_num() as usize,
+ _ => unreachable!(),
+ };
+
+ let p = self.machine_st.registers[4];
+ let p = self.machine_st.store(self.machine_st.deref(p));
+
+ let p = match Number::try_from(p) {
+ Ok(Number::Fixnum(p)) => p.get_num() as usize,
+ _ => unreachable!(),
+ };
+
+ let module_name = cell_as_atom!(self.deref_register(6));
+
+ let compilation_target = match module_name {
+ atom!("user") => CompilationTarget::User,
+ _ => CompilationTarget::Module(module_name),
+ };
+
+ let skeleton = self
+ .indices
+ .get_predicate_skeleton_mut(&compilation_target, &key)
+ .unwrap();
+
+ match skeleton.target_pos_of_clause_clause_loc(l) {
+ Some(n) => {
+ let r = self
+ .machine_st
+ .store(self.machine_st.deref(self.machine_st.registers[5]));
+
+ self.machine_st
+ .unify_fixnum(Fixnum::build_with(n as i64), r);
+ }
+ None => {}
+ }
+
+ self.machine_st.execute_at_index(2, p);
+ }
+ &Instruction::CallGetFromAttributedVarList => {
+ self.get_from_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetFromAttributedVarList => {
+ self.get_from_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallPutToAttributedVarList => {
+ self.put_to_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecutePutToAttributedVarList => {
+ self.put_to_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDeleteFromAttributedVarList => {
+ self.delete_from_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteDeleteFromAttributedVarList => {
+ self.delete_from_attributed_variable_list();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
+ &Instruction::CallDeleteAllAttributesFromVar => {
+ self.delete_all_attributes_from_var();
+ self.machine_st.p += 1;
+ }
+ &Instruction::ExecuteDeleteAllAttributesFromVar => {
+ self.delete_all_attributes_from_var();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallUnattributedVar => {
+ self.machine_st.unattributed_var();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteUnattributedVar => {
+ self.machine_st.unattributed_var();
+ self.machine_st.p = self.machine_st.cp;
+ }
+ &Instruction::CallGetDBRefs => {
+ self.get_db_refs();
+ step_or_fail!(self, self.machine_st.p += 1);
+ }
+ &Instruction::ExecuteGetDBRefs => {
+ self.get_db_refs();
+ step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
+ }
}
}
- }
- let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed);
+ let interrupted = INTERRUPT.load(std::sync::atomic::Ordering::Relaxed);
- match INTERRUPT.compare_exchange(
- interrupted,
- false,
- std::sync::atomic::Ordering::Relaxed,
- std::sync::atomic::Ordering::Relaxed,
- ) {
- Ok(interruption) => {
- if interruption {
- self.machine_st.throw_interrupt_exception();
- self.machine_st.backtrack();
+ match INTERRUPT.compare_exchange(
+ interrupted,
+ false,
+ std::sync::atomic::Ordering::Relaxed,
+ std::sync::atomic::Ordering::Relaxed,
+ ) {
+ Ok(interruption) => {
+ if interruption {
+ self.machine_st.throw_interrupt_exception();
+ self.machine_st.backtrack();
+ }
}
+ Err(_) => unreachable!(),
}
- Err(_) => unreachable!(),
- }
}
std::process::ExitCode::SUCCESS
diff --git a/src/machine/gc.rs b/src/machine/gc.rs
index ad42b1d5..5b4895bd 100644
--- a/src/machine/gc.rs
+++ b/src/machine/gc.rs
@@ -3,7 +3,7 @@ use crate::machine::heap::*;
use crate::types::*;
#[cfg(test)]
-use crate::heap_iter::{IterStackLoc, FocusedHeapIter, HeapOrStackTag};
+use crate::heap_iter::{FocusedHeapIter, HeapOrStackTag, IterStackLoc};
use core::marker::PhantomData;
@@ -173,14 +173,18 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
match self.heap[self.current].get_tag() {
HeapCellValueTag::AttrVar => {
- if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); }
+ if let Some(cell) = UMP::forward_attr_var(self) {
+ return Some(cell);
+ }
if self.heap[self.next as usize].get_mark_bit() {
return Some(attr_var_as_cell!(self.current));
}
}
HeapCellValueTag::Var => {
- if let Some(cell) = self.forward_var() { return Some(cell); }
+ if let Some(cell) = self.forward_var() {
+ return Some(cell);
+ }
if self.heap[self.next as usize].get_mark_bit() {
return Some(heap_loc_as_cell!(self.current));
@@ -196,7 +200,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
let arity = cell_as_atom_cell!(self.heap[h]).get_arity();
- for cell in &mut self.heap[h + 1 .. h + arity + 1] {
+ for cell in &mut self.heap[h + 1..h + arity + 1] {
cell.set_forwarding_bit(true);
}
@@ -227,12 +231,12 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
let h = self.next as usize;
let cell = self.heap[h];
- if self.heap[h+1].get_forwarding_bit() {
+ if self.heap[h + 1].get_forwarding_bit() {
return self.backward_and_return();
}
if self.heap[h].get_tag() == HeapCellValueTag::PStr {
- let last_cell_loc = h+1;
+ let last_cell_loc = h + 1;
self.heap[last_cell_loc].set_forwarding_bit(true);
self.next = self.heap[last_cell_loc].get_value();
@@ -257,9 +261,9 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
let cell = self.heap[h];
// mark the Fixnum offset.
- UMP::mark(self.heap, self.current+1);
+ UMP::mark(self.heap, self.current + 1);
- let last_cell_loc = h+1;
+ let last_cell_loc = h + 1;
if self.heap[last_cell_loc].get_forwarding_bit() {
return self.backward_and_return();
@@ -328,9 +332,9 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
self.current -= 1;
- let temp = self.heap[self.current+1].get_value();
+ let temp = self.heap[self.current + 1].get_value();
- self.heap[self.current+1].set_value(self.next);
+ self.heap[self.current + 1].set_value(self.next);
self.next = self.heap[self.current].get_value();
self.heap[self.current].set_value(temp);
@@ -366,16 +370,25 @@ 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)]));
mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(0));
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(f_atom, 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), atom_as_cell!(b_atom));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(f_atom, 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ atom_as_cell!(b_atom)
+ );
wam.machine_st.heap.clear();
@@ -393,11 +406,26 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(f_atom, 4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), atom_as_cell!(b_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), str_loc_as_cell!(0));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(f_atom, 4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ atom_as_cell!(b_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ str_loc_as_cell!(0)
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -428,12 +456,30 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), str_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(f_atom, 4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(b_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), str_loc_as_cell!(1));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ str_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ atom_as_cell!(f_atom, 4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(b_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ str_loc_as_cell!(1)
+ );
wam.machine_st.heap.clear();
@@ -443,7 +489,10 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), heap_loc_as_cell!(0));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ heap_loc_as_cell!(0)
+ );
wam.machine_st.heap.clear();
@@ -458,11 +507,26 @@ mod tests {
all_cells_marked_and_unforwarded(&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]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(b_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), empty_list_as_cell!());
+ 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]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ list_loc_as_cell!(3)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(b_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ empty_list_as_cell!()
+ );
wam.machine_st.heap.pop();
@@ -477,11 +541,26 @@ mod tests {
all_cells_marked_and_unforwarded(&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]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(b_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), heap_loc_as_cell!(0));
+ 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]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ list_loc_as_cell!(3)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(b_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ heap_loc_as_cell!(0)
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -511,11 +590,23 @@ mod tests {
all_cells_marked_and_unforwarded(&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]), atom_as_cell!(a_atom));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
+ 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]),
+ atom_as_cell!(a_atom)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ list_loc_as_cell!(3)
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), stream_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), empty_list_as_cell!());
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ empty_list_as_cell!()
+ );
wam.machine_st.heap.clear();
@@ -530,10 +621,22 @@ mod tests {
all_cells_marked_and_unforwarded(&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!(0));
+ 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!(0)
+ );
wam.machine_st.heap.clear();
@@ -541,7 +644,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];
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
@@ -549,7 +653,10 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ heap_loc_as_cell!(1)
+ );
wam.machine_st.heap.pop();
@@ -559,7 +666,8 @@ mod tests {
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];
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
@@ -567,9 +675,15 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
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]), heap_loc_as_cell!(3));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ heap_loc_as_cell!(3)
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -578,18 +692,32 @@ 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)));
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(4));
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
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))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -600,11 +728,23 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
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))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -615,11 +755,23 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
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))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -630,11 +782,23 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
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))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -645,11 +809,23 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
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);
@@ -657,9 +833,13 @@ mod tests {
cell.set_mark_bit(false);
}
- wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
+ wam.machine_st
+ .heap
+ .push(atom_as_cell!(atom!("irrelevant stuff")));
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)));
wam.machine_st.heap[3] = pstr_loc_as_cell!(5);
@@ -674,24 +854,47 @@ mod tests {
assert!(wam.machine_st.heap[6].get_mark_bit());
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!(5));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(atom!("irrelevant stuff")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ pstr_loc_as_cell!(5)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
wam.machine_st.heap.clear();
- wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
+ wam.machine_st
+ .heap
+ .push(atom_as_cell!(atom!("irrelevant stuff")));
wam.machine_st.heap.push(pstr_cell);
wam.machine_st.heap.push(pstr_loc_as_cell!(4));
- wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
+ wam.machine_st
+ .heap
+ .push(atom_as_cell!(atom!("irrelevant stuff")));
wam.machine_st.heap.push(pstr_second_cell);
wam.machine_st.heap.push(pstr_loc_as_cell!(7));
- wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
+ wam.machine_st
+ .heap
+ .push(atom_as_cell!(atom!("irrelevant stuff")));
wam.machine_st.heap.push(pstr_offset_as_cell!(1));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(2)));
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(7));
@@ -705,15 +908,36 @@ mod tests {
assert!(wam.machine_st.heap[7].get_mark_bit());
assert!(wam.machine_st.heap[8].get_mark_bit());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ pstr_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ pstr_offset_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -735,15 +959,36 @@ mod tests {
assert!(!cell.get_forwarding_bit());
}
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ pstr_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ pstr_offset_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -765,15 +1010,36 @@ mod tests {
assert!(!cell.get_forwarding_bit());
}
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ pstr_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ pstr_offset_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -795,15 +1061,36 @@ mod tests {
assert!(!cell.get_forwarding_bit());
}
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ pstr_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ pstr_offset_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -825,15 +1112,36 @@ mod tests {
assert!(!cell.get_forwarding_bit());
}
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ pstr_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ atom_as_cell!(atom!("irrelevant stuff"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ pstr_offset_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -846,7 +1154,9 @@ mod tests {
wam.machine_st.heap.push(pstr_cell);
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(3)));
wam.machine_st.heap.push(list_loc_as_cell!(5));
wam.machine_st.heap.push(pstr_loc_as_cell!(0));
wam.machine_st.heap.push(empty_list_as_cell!());
@@ -860,19 +1170,39 @@ 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[2]), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), fixnum_as_cell!(Fixnum::build_with(3)));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), list_loc_as_cell!(5));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), empty_list_as_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[2]),
+ pstr_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ fixnum_as_cell!(Fixnum::build_with(3))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ list_loc_as_cell!(5)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ empty_list_as_cell!()
+ );
wam.machine_st.heap.clear();
wam.machine_st.heap.push(pstr_cell);
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(3)));
wam.machine_st.heap.push(list_loc_as_cell!(5));
wam.machine_st.heap.push(pstr_loc_as_cell!(0));
wam.machine_st.heap.push(heap_loc_as_cell!(4));
@@ -886,12 +1216,30 @@ 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[2]), pstr_offset_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), fixnum_as_cell!(Fixnum::build_with(3)));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), list_loc_as_cell!(5));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(4));
+ 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_offset_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ fixnum_as_cell!(Fixnum::build_with(3))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ list_loc_as_cell!(5)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ pstr_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ heap_loc_as_cell!(4)
+ );
wam.machine_st.heap.clear();
@@ -906,10 +1254,22 @@ mod tests {
all_cells_marked_and_unforwarded(&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();
@@ -922,9 +1282,18 @@ mod tests {
all_cells_marked_and_unforwarded(&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();
@@ -948,19 +1317,58 @@ mod tests {
all_cells_marked_and_unforwarded(&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]), 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!(12));
+ 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!(12)
+ );
// now populate the attributes list.
let clpz_atom = atom!("clpz");
@@ -990,30 +1398,102 @@ mod tests {
all_cells_marked_and_unforwarded(&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]), 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)
+ );
for cell in &mut wam.machine_st.heap {
cell.set_mark_bit(false);
@@ -1034,36 +1514,119 @@ mod tests {
assert_eq!(cell.get_mark_bit(), false);
}
- 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[24]), heap_loc_as_cell!(5));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[25]), heap_loc_as_cell!(5));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[26]), list_loc_as_cell!(5));
+ 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[24]),
+ heap_loc_as_cell!(5)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[25]),
+ heap_loc_as_cell!(5)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[26]),
+ list_loc_as_cell!(5)
+ );
wam.machine_st.heap.clear();
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(0)));
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
@@ -1090,16 +1653,46 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), str_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(atom!("g"), 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("y")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(atom!("="), 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), atom_as_cell!(atom!("X")));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), list_loc_as_cell!(8));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), str_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), empty_list_as_cell!());
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ str_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ atom_as_cell!(atom!("g"), 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ heap_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ atom_as_cell!(atom!("y"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ atom_as_cell!(atom!("="), 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ atom_as_cell!(atom!("X"))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ heap_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ list_loc_as_cell!(8)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ str_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[9]),
+ empty_list_as_cell!()
+ );
wam.machine_st.heap.clear();
@@ -1111,9 +1704,18 @@ mod tests {
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("f"), 2));
- 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!(1));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ atom_as_cell!(atom!("f"), 2)
+ );
+ 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!(1)
+ );
wam.machine_st.heap.clear();
@@ -1131,13 +1733,34 @@ mod tests {
all_cells_marked_and_unforwarded(&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]), empty_list_as_cell!());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), heap_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), heap_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), empty_list_as_cell!());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(2));
+ 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]),
+ empty_list_as_cell!()
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ list_loc_as_cell!(3)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ heap_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ heap_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ empty_list_as_cell!()
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ heap_loc_as_cell!(2)
+ );
wam.machine_st.heap.clear();
@@ -1145,8 +1768,8 @@ mod tests {
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)); // A = [B|[]].
- wam.machine_st.heap.push(list_loc_as_cell!(5)); // B = [A|A].
+ wam.machine_st.heap.push(list_loc_as_cell!(3)); // A = [B|[]].
+ wam.machine_st.heap.push(list_loc_as_cell!(5)); // B = [A|A].
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));
@@ -1158,44 +1781,109 @@ mod tests {
assert!(wam.machine_st.heap[0].get_mark_bit());
assert!(!wam.machine_st.heap[1].get_mark_bit());
- all_cells_marked_and_unforwarded(&wam.machine_st.heap[2 ..]);
+ all_cells_marked_and_unforwarded(&wam.machine_st.heap[2..]);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(0));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), list_loc_as_cell!(5));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), empty_list_as_cell!());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), heap_loc_as_cell!(2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), empty_list_as_cell!());
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), heap_loc_as_cell!(3));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ list_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ heap_loc_as_cell!(0)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ list_loc_as_cell!(3)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ list_loc_as_cell!(5)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ empty_list_as_cell!()
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ heap_loc_as_cell!(2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ heap_loc_as_cell!(2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ empty_list_as_cell!()
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ heap_loc_as_cell!(3)
+ );
wam.machine_st.heap.clear();
wam.machine_st.heap.push(str_loc_as_cell!(1));
wam.machine_st.heap.push(atom_as_cell!(atom!("+"), 2));
wam.machine_st.heap.push(str_loc_as_cell!(4));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(2)));
wam.machine_st.heap.push(atom_as_cell!(atom!("-"), 2));
wam.machine_st.heap.push(str_loc_as_cell!(7));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(1)));
wam.machine_st.heap.push(atom_as_cell!(atom!("+"), 2));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3)));
- wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(4)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(3)));
+ wam.machine_st
+ .heap
+ .push(fixnum_as_cell!(Fixnum::build_with(4)));
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), str_loc_as_cell!(1));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(atom!("+"), 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), str_loc_as_cell!(4));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), fixnum_as_cell!(Fixnum::build_with(2)));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(atom!("-"), 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), str_loc_as_cell!(7));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), fixnum_as_cell!(Fixnum::build_with(1)));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), atom_as_cell!(atom!("+"), 2));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(3)));
- assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), fixnum_as_cell!(Fixnum::build_with(4)));
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[0]),
+ str_loc_as_cell!(1)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[1]),
+ atom_as_cell!(atom!("+"), 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[2]),
+ str_loc_as_cell!(4)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[3]),
+ fixnum_as_cell!(Fixnum::build_with(2))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[4]),
+ atom_as_cell!(atom!("-"), 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[5]),
+ str_loc_as_cell!(7)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[6]),
+ fixnum_as_cell!(Fixnum::build_with(1))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[7]),
+ atom_as_cell!(atom!("+"), 2)
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[8]),
+ fixnum_as_cell!(Fixnum::build_with(3))
+ );
+ assert_eq!(
+ unmark_cell_bits!(wam.machine_st.heap[9]),
+ fixnum_as_cell!(Fixnum::build_with(4))
+ );
}
}
diff --git a/src/machine/heap.rs b/src/machine/heap.rs
index c479162e..858e4487 100644
--- a/src/machine/heap.rs
+++ b/src/machine/heap.rs
@@ -130,11 +130,7 @@ pub fn print_heap_terms<'a, I: Iterator