flatten the instruction dispatch loop
This commit is contained in:
76
Cargo.lock
generated
76
Cargo.lock
generated
@@ -378,6 +378,15 @@ dependencies = [
|
||||
"new_debug_unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
@@ -436,6 +445,15 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.3.1"
|
||||
@@ -471,6 +489,20 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instructions-template"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"syn 1.0.81",
|
||||
"to-syn-value",
|
||||
"to-syn-value_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
@@ -1325,6 +1357,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
||||
|
||||
[[package]]
|
||||
name = "rustyline"
|
||||
version = "9.0.0"
|
||||
@@ -1392,9 +1430,11 @@ dependencies = [
|
||||
"crossterm",
|
||||
"dirs-next",
|
||||
"divrem",
|
||||
"fxhash",
|
||||
"git-version",
|
||||
"hostname",
|
||||
"indexmap",
|
||||
"instructions-template",
|
||||
"lazy_static",
|
||||
"lexical",
|
||||
"libc",
|
||||
@@ -1655,6 +1695,25 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"rustversion",
|
||||
"syn 1.0.81",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
@@ -1724,6 +1783,23 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "to-syn-value"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"syn 1.0.81",
|
||||
"to-syn-value_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "to-syn-value_derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.81",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
|
||||
@@ -12,7 +12,11 @@ categories = ["command-line-utilities"]
|
||||
build = "build.rs"
|
||||
|
||||
[workspace]
|
||||
members = ["crates/num-rug-adapter", "crates/static-string-indexing"]
|
||||
members = ["crates/num-rug-adapter",
|
||||
"crates/static-string-indexing",
|
||||
"crates/instructions-template",
|
||||
"crates/to-syn-value",
|
||||
"crates/to-syn-value_derive"]
|
||||
|
||||
[features]
|
||||
num = ["num-rug-adapter"]
|
||||
@@ -24,6 +28,7 @@ default = ["rug"]
|
||||
[build-dependencies]
|
||||
indexmap = "1.0.2"
|
||||
static-string-indexing = { path = "./crates/static-string-indexing" }
|
||||
instructions-template = { path = "./crates/instructions-template" }
|
||||
proc-macro2 = "*"
|
||||
|
||||
[dependencies]
|
||||
@@ -31,13 +36,13 @@ cpu-time = "1.0.0"
|
||||
crossterm = "0.16.0"
|
||||
dirs-next = "2.0.0"
|
||||
divrem = "0.1.0"
|
||||
fxhash = "0.2.1"
|
||||
git-version = "0.3.4"
|
||||
hostname = "0.3.1"
|
||||
indexmap = "1.0.2"
|
||||
lazy_static = "1.4.0"
|
||||
lexical = "5.2.2"
|
||||
libc = "0.2.62"
|
||||
# temporary to remove unnecessary braces warnings.
|
||||
modular-bitfield = { git = "https://github.com/mthom/modular-bitfield" } # modular-bitfield = "0.11.2"
|
||||
nix = "0.15.0"
|
||||
num-rug-adapter = { optional = true, path = "./crates/num-rug-adapter" }
|
||||
|
||||
15
build.rs
15
build.rs
@@ -1,4 +1,5 @@
|
||||
use static_string_indexing::index_static_strings;
|
||||
use instructions_template::generate_instructions_rs;
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
@@ -55,6 +56,20 @@ fn main() {
|
||||
find_prolog_files(&mut libraries, "", &lib_path);
|
||||
libraries.write_all(b"\n m\n };\n}\n").unwrap();
|
||||
|
||||
let instructions_path = Path::new("src/instructions.rs");
|
||||
let mut instructions_file = File::create(&instructions_path).unwrap();
|
||||
|
||||
let quoted_output = generate_instructions_rs();
|
||||
|
||||
instructions_file
|
||||
.write_all(quoted_output.to_string().as_bytes())
|
||||
.unwrap();
|
||||
|
||||
Command::new("rustfmt")
|
||||
.arg(instructions_path.as_os_str())
|
||||
.spawn().unwrap()
|
||||
.wait().unwrap();
|
||||
|
||||
let static_atoms_path = Path::new("src/static_atoms.rs");
|
||||
let mut static_atoms_file = File::create(&static_atoms_path).unwrap();
|
||||
|
||||
|
||||
129
crates/instructions-template/Cargo.lock
generated
Normal file
129
crates/instructions-template/Cargo.lock
generated
Normal file
@@ -0,0 +1,129 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instructions-template"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "392a54546fda6b7cc663379d0e6ce8b324cf88aecc5a499838e1be9781bdce2e"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "to-syn-value"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"syn",
|
||||
"to-syn-value_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "to-syn-value_derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
14
crates/instructions-template/Cargo.toml
Normal file
14
crates/instructions-template/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "instructions-template"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
indexmap = "*"
|
||||
proc-macro2 = "*"
|
||||
quote = "*"
|
||||
strum = "0.23"
|
||||
strum_macros = "0.23"
|
||||
syn = { version = "*", features = ['full', 'visit', 'extra-traits'] }
|
||||
to-syn-value = { path = "../to-syn-value" }
|
||||
to-syn-value_derive = { path = "../to-syn-value_derive" }
|
||||
3286
crates/instructions-template/src/lib.rs
Normal file
3286
crates/instructions-template/src/lib.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "prolog_parser"
|
||||
version = "0.8.68"
|
||||
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/mthom/scryer-prolog"
|
||||
description = " An operator precedence parser for the Rebis development version of Scryer Prolog, an up and coming ISO Prolog implementation."
|
||||
license = "BSD-3-Clause"
|
||||
|
||||
[dependencies]
|
||||
indexmap = "1.0.2"
|
||||
lexical = "5.2.1"
|
||||
ordered-float = "0.5.0"
|
||||
rug = { optional = true, version = "1.4.0" }
|
||||
num-rug-adapter = { optional = true, path = "../num-rug-adapter" }
|
||||
unicode_reader = "1.0.0"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
num = ["num-rug-adapter"]
|
||||
# no default features to make num tests work
|
||||
# workaround for --no-default-features and --features not working intuitively for workspaces with a root package
|
||||
# see rust-lang/cargo#7160
|
||||
# default = ["rug"]
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "static-string-indexing"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "*"
|
||||
|
||||
10
crates/to-syn-value/Cargo.toml
Normal file
10
crates/to-syn-value/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "to-syn-value"
|
||||
version = "0.1.0"
|
||||
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "*", features = ['full', 'visit', 'extra-traits'] }
|
||||
to-syn-value_derive = { path = "../to-syn-value_derive" }
|
||||
3
crates/to-syn-value/src/lib.rs
Normal file
3
crates/to-syn-value/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub trait ToDeriveInput {
|
||||
fn to_derive_input() -> syn::DeriveInput;
|
||||
}
|
||||
14
crates/to-syn-value_derive/Cargo.toml
Normal file
14
crates/to-syn-value_derive/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "to-syn-value_derive"
|
||||
version = "0.1.0"
|
||||
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "*"
|
||||
syn = { version = "*", features = ['full', 'visit', 'extra-traits'] }
|
||||
quote = "*"
|
||||
20
crates/to-syn-value_derive/src/lib.rs
Normal file
20
crates/to-syn-value_derive/src/lib.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use syn::*;
|
||||
use quote::*;
|
||||
|
||||
#[proc_macro_derive(ToDeriveInput)]
|
||||
pub fn derive_to_derive_input(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let derive_input = parse_macro_input!(input as DeriveInput);
|
||||
let ty_name = derive_input.ident.clone();
|
||||
|
||||
quote! {
|
||||
use to_syn_value::*;
|
||||
|
||||
impl ToDeriveInput for #ty_name {
|
||||
fn to_derive_input() -> syn::DeriveInput {
|
||||
syn::parse_quote! {
|
||||
#derive_input
|
||||
}
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
@@ -3,6 +3,7 @@ use crate::temp_v;
|
||||
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
@@ -11,7 +12,7 @@ use std::rc::Rc;
|
||||
pub(crate) trait Allocator<'a> {
|
||||
fn new() -> Self;
|
||||
|
||||
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
||||
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Code)
|
||||
where
|
||||
Target: crate::targets::CompilationTarget<'a>;
|
||||
fn mark_non_var<Target>(
|
||||
@@ -19,7 +20,7 @@ pub(crate) trait Allocator<'a> {
|
||||
_: Level,
|
||||
_: GenContext,
|
||||
_: &'a Cell<RegType>,
|
||||
_: &mut Vec<Target>,
|
||||
_: &mut Code,
|
||||
) where
|
||||
Target: crate::targets::CompilationTarget<'a>;
|
||||
fn mark_reserved_var<Target>(
|
||||
@@ -28,7 +29,7 @@ pub(crate) trait Allocator<'a> {
|
||||
_: Level,
|
||||
_: &'a Cell<VarReg>,
|
||||
_: GenContext,
|
||||
_: &mut Vec<Target>,
|
||||
_: &mut Code,
|
||||
_: RegType,
|
||||
_: bool,
|
||||
) where
|
||||
@@ -39,7 +40,7 @@ pub(crate) trait Allocator<'a> {
|
||||
_: Level,
|
||||
_: &'a Cell<VarReg>,
|
||||
_: GenContext,
|
||||
_: &mut Vec<Target>,
|
||||
_: &mut Code,
|
||||
) where
|
||||
Target: crate::targets::CompilationTarget<'a>;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
@@ -25,6 +24,29 @@ use std::ops::Div;
|
||||
use std::rc::Rc;
|
||||
use std::vec::Vec;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ArithmeticTerm {
|
||||
Reg(RegType),
|
||||
Interm(usize),
|
||||
Number(Number),
|
||||
}
|
||||
|
||||
impl ArithmeticTerm {
|
||||
pub(crate) fn interm_or(&self, interm: usize) -> usize {
|
||||
if let &ArithmeticTerm::Interm(interm) = self {
|
||||
interm
|
||||
} else {
|
||||
interm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ArithmeticTerm {
|
||||
fn default() -> Self {
|
||||
ArithmeticTerm::Number(Number::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ArithInstructionIterator<'a> {
|
||||
state_stack: Vec<TermIterState<'a>>,
|
||||
@@ -46,7 +68,7 @@ impl<'a> ArithInstructionIterator<'a> {
|
||||
Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
|
||||
}
|
||||
ClauseType::Inlined(InlinedClauseType::IsFloat(_)) => {
|
||||
let ct = ClauseType::Named(atom!("float"), 1, CodeIndex::default());
|
||||
let ct = ClauseType::Named(1, atom!("float"), CodeIndex::default());
|
||||
Ok(TermIterState::Clause(Level::Shallow, 0, cell, ct, terms))
|
||||
}
|
||||
_ => Err(ArithmeticError::NonEvaluableFunctor(
|
||||
@@ -174,27 +196,27 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
name: Atom,
|
||||
a1: ArithmeticTerm,
|
||||
t: usize,
|
||||
) -> Result<ArithmeticInstruction, ArithmeticError> {
|
||||
) -> Result<Instruction, ArithmeticError> {
|
||||
match name {
|
||||
atom!("abs") => Ok(ArithmeticInstruction::Abs(a1, t)),
|
||||
atom!("-") => Ok(ArithmeticInstruction::Neg(a1, t)),
|
||||
atom!("+") => Ok(ArithmeticInstruction::Plus(a1, t)),
|
||||
atom!("cos") => Ok(ArithmeticInstruction::Cos(a1, t)),
|
||||
atom!("sin") => Ok(ArithmeticInstruction::Sin(a1, t)),
|
||||
atom!("tan") => Ok(ArithmeticInstruction::Tan(a1, t)),
|
||||
atom!("log") => Ok(ArithmeticInstruction::Log(a1, t)),
|
||||
atom!("exp") => Ok(ArithmeticInstruction::Exp(a1, t)),
|
||||
atom!("sqrt") => Ok(ArithmeticInstruction::Sqrt(a1, t)),
|
||||
atom!("acos") => Ok(ArithmeticInstruction::ACos(a1, t)),
|
||||
atom!("asin") => Ok(ArithmeticInstruction::ASin(a1, t)),
|
||||
atom!("atan") => Ok(ArithmeticInstruction::ATan(a1, t)),
|
||||
atom!("float") => Ok(ArithmeticInstruction::Float(a1, t)),
|
||||
atom!("truncate") => Ok(ArithmeticInstruction::Truncate(a1, t)),
|
||||
atom!("round") => Ok(ArithmeticInstruction::Round(a1, t)),
|
||||
atom!("ceiling") => Ok(ArithmeticInstruction::Ceiling(a1, t)),
|
||||
atom!("floor") => Ok(ArithmeticInstruction::Floor(a1, t)),
|
||||
atom!("sign") => Ok(ArithmeticInstruction::Sign(a1, t)),
|
||||
atom!("\\") => Ok(ArithmeticInstruction::BitwiseComplement(a1, t)),
|
||||
atom!("abs") => Ok(Instruction::Abs(a1, t)),
|
||||
atom!("-") => Ok(Instruction::Neg(a1, t)),
|
||||
atom!("+") => Ok(Instruction::Plus(a1, t)),
|
||||
atom!("cos") => Ok(Instruction::Cos(a1, t)),
|
||||
atom!("sin") => Ok(Instruction::Sin(a1, t)),
|
||||
atom!("tan") => Ok(Instruction::Tan(a1, t)),
|
||||
atom!("log") => Ok(Instruction::Log(a1, t)),
|
||||
atom!("exp") => Ok(Instruction::Exp(a1, t)),
|
||||
atom!("sqrt") => Ok(Instruction::Sqrt(a1, t)),
|
||||
atom!("acos") => Ok(Instruction::ACos(a1, t)),
|
||||
atom!("asin") => Ok(Instruction::ASin(a1, t)),
|
||||
atom!("atan") => Ok(Instruction::ATan(a1, t)),
|
||||
atom!("float") => Ok(Instruction::Float(a1, t)),
|
||||
atom!("truncate") => Ok(Instruction::Truncate(a1, t)),
|
||||
atom!("round") => Ok(Instruction::Round(a1, t)),
|
||||
atom!("ceiling") => Ok(Instruction::Ceiling(a1, t)),
|
||||
atom!("floor") => Ok(Instruction::Floor(a1, t)),
|
||||
atom!("sign") => Ok(Instruction::Sign(a1, t)),
|
||||
atom!("\\") => Ok(Instruction::BitwiseComplement(a1, t)),
|
||||
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 1)),
|
||||
}
|
||||
}
|
||||
@@ -205,28 +227,28 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
a1: ArithmeticTerm,
|
||||
a2: ArithmeticTerm,
|
||||
t: usize,
|
||||
) -> Result<ArithmeticInstruction, ArithmeticError> {
|
||||
) -> Result<Instruction, ArithmeticError> {
|
||||
match name {
|
||||
atom!("+") => Ok(ArithmeticInstruction::Add(a1, a2, t)),
|
||||
atom!("-") => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
|
||||
atom!("/") => Ok(ArithmeticInstruction::Div(a1, a2, t)),
|
||||
atom!("//") => Ok(ArithmeticInstruction::IDiv(a1, a2, t)),
|
||||
atom!("max") => Ok(ArithmeticInstruction::Max(a1, a2, t)),
|
||||
atom!("min") => Ok(ArithmeticInstruction::Min(a1, a2, t)),
|
||||
atom!("div") => Ok(ArithmeticInstruction::IntFloorDiv(a1, a2, t)),
|
||||
atom!("rdiv") => Ok(ArithmeticInstruction::RDiv(a1, a2, t)),
|
||||
atom!("*") => Ok(ArithmeticInstruction::Mul(a1, a2, t)),
|
||||
atom!("**") => Ok(ArithmeticInstruction::Pow(a1, a2, t)),
|
||||
atom!("^") => Ok(ArithmeticInstruction::IntPow(a1, a2, t)),
|
||||
atom!(">>") => Ok(ArithmeticInstruction::Shr(a1, a2, t)),
|
||||
atom!("<<") => Ok(ArithmeticInstruction::Shl(a1, a2, t)),
|
||||
atom!("/\\") => Ok(ArithmeticInstruction::And(a1, a2, t)),
|
||||
atom!("\\/") => Ok(ArithmeticInstruction::Or(a1, a2, t)),
|
||||
atom!("xor") => Ok(ArithmeticInstruction::Xor(a1, a2, t)),
|
||||
atom!("mod") => Ok(ArithmeticInstruction::Mod(a1, a2, t)),
|
||||
atom!("rem") => Ok(ArithmeticInstruction::Rem(a1, a2, t)),
|
||||
atom!("gcd") => Ok(ArithmeticInstruction::Gcd(a1, a2, t)),
|
||||
atom!("atan2") => Ok(ArithmeticInstruction::ATan2(a1, a2, t)),
|
||||
atom!("+") => Ok(Instruction::Add(a1, a2, t)),
|
||||
atom!("-") => Ok(Instruction::Sub(a1, a2, t)),
|
||||
atom!("/") => Ok(Instruction::Div(a1, a2, t)),
|
||||
atom!("//") => Ok(Instruction::IDiv(a1, a2, t)),
|
||||
atom!("max") => Ok(Instruction::Max(a1, a2, t)),
|
||||
atom!("min") => Ok(Instruction::Min(a1, a2, t)),
|
||||
atom!("div") => Ok(Instruction::IntFloorDiv(a1, a2, t)),
|
||||
atom!("rdiv") => Ok(Instruction::RDiv(a1, a2, t)),
|
||||
atom!("*") => Ok(Instruction::Mul(a1, a2, t)),
|
||||
atom!("**") => Ok(Instruction::Pow(a1, a2, t)),
|
||||
atom!("^") => Ok(Instruction::IntPow(a1, a2, t)),
|
||||
atom!(">>") => Ok(Instruction::Shr(a1, a2, t)),
|
||||
atom!("<<") => Ok(Instruction::Shl(a1, a2, t)),
|
||||
atom!("/\\") => Ok(Instruction::And(a1, a2, t)),
|
||||
atom!("\\/") => Ok(Instruction::Or(a1, a2, t)),
|
||||
atom!("xor") => Ok(Instruction::Xor(a1, a2, t)),
|
||||
atom!("mod") => Ok(Instruction::Mod(a1, a2, t)),
|
||||
atom!("rem") => Ok(Instruction::Rem(a1, a2, t)),
|
||||
atom!("gcd") => Ok(Instruction::Gcd(a1, a2, t)),
|
||||
atom!("atan2") => Ok(Instruction::ATan2(a1, a2, t)),
|
||||
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 2)),
|
||||
}
|
||||
}
|
||||
@@ -244,7 +266,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
&mut self,
|
||||
name: Atom,
|
||||
arity: usize,
|
||||
) -> Result<ArithmeticInstruction, ArithmeticError> {
|
||||
) -> Result<Instruction, ArithmeticError> {
|
||||
match arity {
|
||||
1 => {
|
||||
let a1 = self.interm.pop().unwrap();
|
||||
@@ -310,7 +332,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
self.interm.push(ArithmeticTerm::Reg(r));
|
||||
}
|
||||
ArithTermRef::Op(name, arity) => {
|
||||
code.push(Line::Arithmetic(self.instr_from_clause(name, arity)?));
|
||||
code.push(self.instr_from_clause(name, arity)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,952 +0,0 @@
|
||||
use crate::atom_table::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::rug::rand::RandState;
|
||||
|
||||
use crate::forms::Number;
|
||||
use crate::temp_v;
|
||||
|
||||
use ref_thread_local::{ref_thread_local};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum CompareNumberQT {
|
||||
GreaterThan,
|
||||
LessThan,
|
||||
GreaterThanOrEqual,
|
||||
LessThanOrEqual,
|
||||
NotEqual,
|
||||
Equal,
|
||||
}
|
||||
|
||||
impl CompareNumberQT {
|
||||
fn name(self) -> Atom {
|
||||
match self {
|
||||
CompareNumberQT::GreaterThan => atom!(">"),
|
||||
CompareNumberQT::LessThan => atom!("<"),
|
||||
CompareNumberQT::GreaterThanOrEqual => atom!(">="),
|
||||
CompareNumberQT::LessThanOrEqual => atom!("=<"),
|
||||
CompareNumberQT::NotEqual => atom!("=\\="),
|
||||
CompareNumberQT::Equal => atom!("=:="),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CompareTermQT {
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThanOrEqual,
|
||||
GreaterThan,
|
||||
}
|
||||
|
||||
impl CompareTermQT {
|
||||
fn name(self) -> Atom {
|
||||
match self {
|
||||
CompareTermQT::GreaterThan => atom!("@>"),
|
||||
CompareTermQT::LessThan => atom!("@<"),
|
||||
CompareTermQT::GreaterThanOrEqual => atom!("@>="),
|
||||
CompareTermQT::LessThanOrEqual => atom!("@=<"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ArithmeticTerm {
|
||||
Reg(RegType),
|
||||
Interm(usize),
|
||||
Number(Number),
|
||||
}
|
||||
|
||||
impl ArithmeticTerm {
|
||||
pub(crate) fn interm_or(&self, interm: usize) -> usize {
|
||||
if let &ArithmeticTerm::Interm(interm) = self {
|
||||
interm
|
||||
} else {
|
||||
interm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum InlinedClauseType {
|
||||
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
|
||||
IsAtom(RegType),
|
||||
IsAtomic(RegType),
|
||||
IsCompound(RegType),
|
||||
IsInteger(RegType),
|
||||
IsNumber(RegType),
|
||||
IsRational(RegType),
|
||||
IsFloat(RegType),
|
||||
IsNonVar(RegType),
|
||||
IsVar(RegType),
|
||||
}
|
||||
|
||||
ref_thread_local! {
|
||||
pub(crate) static managed RANDOM_STATE: RandState<'static> = RandState::new();
|
||||
}
|
||||
|
||||
pub fn clause_type_form(name: Atom, arity: usize) -> Option<ClauseType> {
|
||||
match (name, arity) {
|
||||
(atom!(">"), 2) => Some(ClauseType::Inlined(InlinedClauseType::CompareNumber(
|
||||
CompareNumberQT::GreaterThan,
|
||||
ar_reg!(temp_v!(1)),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!("<"), 2) => Some(ClauseType::Inlined(InlinedClauseType::CompareNumber(
|
||||
CompareNumberQT::LessThan,
|
||||
ar_reg!(temp_v!(1)),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!(">="), 2) => Some(ClauseType::Inlined(InlinedClauseType::CompareNumber(
|
||||
CompareNumberQT::GreaterThanOrEqual,
|
||||
ar_reg!(temp_v!(1)),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!("=<"), 2) => Some(ClauseType::Inlined(InlinedClauseType::CompareNumber(
|
||||
CompareNumberQT::LessThanOrEqual,
|
||||
ar_reg!(temp_v!(1)),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!("=:="), 2) => Some(ClauseType::Inlined(InlinedClauseType::CompareNumber(
|
||||
CompareNumberQT::Equal,
|
||||
ar_reg!(temp_v!(1)),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!("=\\="), 2) => Some(ClauseType::Inlined(InlinedClauseType::CompareNumber(
|
||||
CompareNumberQT::NotEqual,
|
||||
ar_reg!(temp_v!(1)),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!("atom"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsAtom(temp_v!(1)))),
|
||||
(atom!("atomic"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsAtomic(temp_v!(1)))),
|
||||
(atom!("compound"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsCompound(temp_v!(
|
||||
1
|
||||
)))),
|
||||
(atom!("integer"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsInteger(temp_v!(
|
||||
1
|
||||
)))),
|
||||
(atom!("number"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsNumber(temp_v!(1)))),
|
||||
(atom!("rational"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsRational(temp_v!(
|
||||
1
|
||||
)))),
|
||||
(atom!("float"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsFloat(temp_v!(1)))),
|
||||
(atom!("nonvar"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsNonVar(temp_v!(1)))),
|
||||
(atom!("var"), 1) => Some(ClauseType::Inlined(InlinedClauseType::IsVar(temp_v!(1)))),
|
||||
(atom!("acyclic_term"), 1) => Some(ClauseType::BuiltIn(BuiltInClauseType::AcyclicTerm)),
|
||||
(atom!("arg"), 3) => Some(ClauseType::BuiltIn(BuiltInClauseType::Arg)),
|
||||
(atom!("compare"), 3) => Some(ClauseType::BuiltIn(BuiltInClauseType::Compare)),
|
||||
(atom!("@>"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(
|
||||
CompareTermQT::GreaterThan,
|
||||
))),
|
||||
(atom!("@<"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(
|
||||
CompareTermQT::LessThan,
|
||||
))),
|
||||
(atom!("@>="), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(
|
||||
CompareTermQT::GreaterThanOrEqual,
|
||||
))),
|
||||
(atom!("@=<"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(
|
||||
CompareTermQT::LessThanOrEqual,
|
||||
))),
|
||||
(atom!("copy_term"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::CopyTerm)),
|
||||
(atom!("=="), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::Eq)),
|
||||
(atom!("functor"), 3) => Some(ClauseType::BuiltIn(BuiltInClauseType::Functor)),
|
||||
(atom!("ground"), 1) => Some(ClauseType::BuiltIn(BuiltInClauseType::Ground)),
|
||||
(atom!("is"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::Is(
|
||||
temp_v!(1),
|
||||
ar_reg!(temp_v!(2)),
|
||||
))),
|
||||
(atom!("keysort"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::KeySort)),
|
||||
(atom!("\\=="), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::NotEq)),
|
||||
(atom!("read"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::Read)),
|
||||
(atom!("sort"), 2) => Some(ClauseType::BuiltIn(BuiltInClauseType::Sort)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
impl InlinedClauseType {
|
||||
pub(crate) fn name(&self) -> Atom {
|
||||
match self {
|
||||
&InlinedClauseType::CompareNumber(qt, ..) => qt.name(),
|
||||
&InlinedClauseType::IsAtom(..) => atom!("atom"),
|
||||
&InlinedClauseType::IsAtomic(..) => atom!("atomic"),
|
||||
&InlinedClauseType::IsCompound(..) => atom!("compound"),
|
||||
&InlinedClauseType::IsNumber(..) => atom!("number"),
|
||||
&InlinedClauseType::IsInteger(..) => atom!("integer"),
|
||||
&InlinedClauseType::IsRational(..) => atom!("rational"),
|
||||
&InlinedClauseType::IsFloat(..) => atom!("float"),
|
||||
&InlinedClauseType::IsNonVar(..) => atom!("nonvar"),
|
||||
&InlinedClauseType::IsVar(..) => atom!("var"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum SystemClauseType {
|
||||
AtomChars,
|
||||
AtomCodes,
|
||||
AtomLength,
|
||||
BindFromRegister,
|
||||
CallContinuation,
|
||||
CharCode,
|
||||
CharType,
|
||||
CharsToNumber,
|
||||
CodesToNumber,
|
||||
CopyTermWithoutAttrVars,
|
||||
CheckCutPoint,
|
||||
Close,
|
||||
CopyToLiftedHeap,
|
||||
CreatePartialString,
|
||||
CurrentHostname,
|
||||
CurrentInput,
|
||||
CurrentOutput,
|
||||
DirectoryFiles,
|
||||
FileSize,
|
||||
FileExists,
|
||||
DirectoryExists,
|
||||
DirectorySeparator,
|
||||
MakeDirectory,
|
||||
MakeDirectoryPath,
|
||||
DeleteFile,
|
||||
RenameFile,
|
||||
WorkingDirectory,
|
||||
DeleteDirectory,
|
||||
PathCanonical,
|
||||
FileTime,
|
||||
DeleteAttribute,
|
||||
DeleteHeadAttribute,
|
||||
DynamicModuleResolution(usize),
|
||||
EnqueueAttributedVar,
|
||||
FetchGlobalVar,
|
||||
FirstStream,
|
||||
FlushOutput,
|
||||
GetByte,
|
||||
GetChar,
|
||||
GetNChars,
|
||||
GetCode,
|
||||
GetSingleChar,
|
||||
ResetAttrVarState,
|
||||
TruncateIfNoLiftedHeapGrowthDiff,
|
||||
TruncateIfNoLiftedHeapGrowth,
|
||||
GetAttributedVariableList,
|
||||
GetAttrVarQueueDelimiter,
|
||||
GetAttrVarQueueBeyond,
|
||||
GetBValue,
|
||||
GetContinuationChunk,
|
||||
GetNextDBRef,
|
||||
GetNextOpDBRef,
|
||||
IsPartialString,
|
||||
Halt,
|
||||
GetLiftedHeapFromOffset,
|
||||
GetLiftedHeapFromOffsetDiff,
|
||||
GetSCCCleaner,
|
||||
HeadIsDynamic,
|
||||
InstallSCCCleaner,
|
||||
InstallInferenceCounter,
|
||||
LiftedHeapLength,
|
||||
LoadLibraryAsStream,
|
||||
ModuleExists,
|
||||
NextEP,
|
||||
NoSuchPredicate,
|
||||
NumberToChars,
|
||||
NumberToCodes,
|
||||
OpDeclaration,
|
||||
Open,
|
||||
SetStreamOptions,
|
||||
NextStream,
|
||||
PartialStringTail,
|
||||
PeekByte,
|
||||
PeekChar,
|
||||
PeekCode,
|
||||
PointsToContinuationResetMarker,
|
||||
PutByte,
|
||||
PutChar,
|
||||
PutChars,
|
||||
PutCode,
|
||||
REPL(REPLCodePtr),
|
||||
ReadQueryTerm,
|
||||
ReadTerm,
|
||||
RedoAttrVarBinding,
|
||||
RemoveCallPolicyCheck,
|
||||
RemoveInferenceCounter,
|
||||
ResetContinuationMarker,
|
||||
RestoreCutPolicy,
|
||||
SetCutPoint(RegType),
|
||||
SetInput,
|
||||
SetOutput,
|
||||
StoreBacktrackableGlobalVar,
|
||||
StoreGlobalVar,
|
||||
StreamProperty,
|
||||
SetStreamPosition,
|
||||
InferenceLevel,
|
||||
CleanUpBlock,
|
||||
EraseBall,
|
||||
Fail,
|
||||
GetBall,
|
||||
GetCurrentBlock,
|
||||
GetCutPoint,
|
||||
GetStaggeredCutPoint,
|
||||
GetDoubleQuotes,
|
||||
InstallNewBlock,
|
||||
Maybe,
|
||||
CpuNow,
|
||||
CurrentTime,
|
||||
QuotedToken,
|
||||
ReadTermFromChars,
|
||||
ResetBlock,
|
||||
ReturnFromVerifyAttr,
|
||||
SetBall,
|
||||
SetCutPointByDefault(RegType),
|
||||
SetDoubleQuotes,
|
||||
SetSeed,
|
||||
SkipMaxList,
|
||||
Sleep,
|
||||
SocketClientOpen,
|
||||
SocketServerOpen,
|
||||
SocketServerAccept,
|
||||
SocketServerClose,
|
||||
TLSAcceptClient,
|
||||
TLSClientConnect,
|
||||
Succeed,
|
||||
TermAttributedVariables,
|
||||
TermVariables,
|
||||
TermVariablesUnderMaxDepth,
|
||||
TruncateLiftedHeapTo,
|
||||
UnifyWithOccursCheck,
|
||||
UnwindEnvironments,
|
||||
UnwindStack,
|
||||
WAMInstructions,
|
||||
WriteTerm,
|
||||
WriteTermToChars,
|
||||
ScryerPrologVersion,
|
||||
CryptoRandomByte,
|
||||
CryptoDataHash,
|
||||
CryptoDataHKDF,
|
||||
CryptoPasswordHash,
|
||||
CryptoDataEncrypt,
|
||||
CryptoDataDecrypt,
|
||||
CryptoCurveScalarMult,
|
||||
Ed25519Sign,
|
||||
Ed25519Verify,
|
||||
Ed25519NewKeyPair,
|
||||
Ed25519KeyPairPublicKey,
|
||||
Curve25519ScalarMult,
|
||||
FirstNonOctet,
|
||||
LoadHTML,
|
||||
LoadXML,
|
||||
GetEnv,
|
||||
SetEnv,
|
||||
UnsetEnv,
|
||||
Shell,
|
||||
PID,
|
||||
CharsBase64,
|
||||
DevourWhitespace,
|
||||
IsSTOEnabled,
|
||||
SetSTOAsUnify,
|
||||
SetNSTOAsUnify,
|
||||
SetSTOWithErrorAsUnify,
|
||||
HomeDirectory,
|
||||
DebugHook,
|
||||
PopCount
|
||||
}
|
||||
|
||||
impl SystemClauseType {
|
||||
pub(crate) fn name(&self) -> Atom {
|
||||
match self {
|
||||
&SystemClauseType::AtomChars => atom!("$atom_chars"),
|
||||
&SystemClauseType::AtomCodes => atom!("$atom_codes"),
|
||||
&SystemClauseType::AtomLength => atom!("$atom_length"),
|
||||
&SystemClauseType::BindFromRegister => atom!("$bind_from_register"),
|
||||
&SystemClauseType::CallContinuation => atom!("$call_continuation"),
|
||||
&SystemClauseType::CharCode => atom!("$char_code"),
|
||||
&SystemClauseType::CharType => atom!("$char_type"),
|
||||
&SystemClauseType::CharsToNumber => atom!("$chars_to_number"),
|
||||
&SystemClauseType::CheckCutPoint => atom!("$check_cp"),
|
||||
&SystemClauseType::CodesToNumber => atom!("$codes_to_number"),
|
||||
&SystemClauseType::CopyTermWithoutAttrVars => {
|
||||
atom!("$copy_term_without_attr_vars")
|
||||
}
|
||||
&SystemClauseType::CreatePartialString => atom!("$create_partial_string"),
|
||||
&SystemClauseType::CurrentInput => atom!("$current_input"),
|
||||
&SystemClauseType::CurrentHostname => atom!("$current_hostname"),
|
||||
&SystemClauseType::CurrentOutput => atom!("$current_output"),
|
||||
&SystemClauseType::DirectoryFiles => atom!("$directory_files"),
|
||||
&SystemClauseType::FileSize => atom!("$file_size"),
|
||||
&SystemClauseType::FileExists => atom!("$file_exists"),
|
||||
&SystemClauseType::DirectoryExists => atom!("$directory_exists"),
|
||||
&SystemClauseType::DirectorySeparator => atom!("$directory_separator"),
|
||||
&SystemClauseType::MakeDirectory => atom!("$make_directory"),
|
||||
&SystemClauseType::MakeDirectoryPath => atom!("$make_directory_path"),
|
||||
&SystemClauseType::DeleteFile => atom!("$delete_file"),
|
||||
&SystemClauseType::RenameFile => atom!("$rename_file"),
|
||||
&SystemClauseType::DeleteDirectory => atom!("$delete_directory"),
|
||||
&SystemClauseType::WorkingDirectory => atom!("$working_directory"),
|
||||
&SystemClauseType::PathCanonical => atom!("$path_canonical"),
|
||||
&SystemClauseType::FileTime => atom!("$file_time"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddDiscontiguousPredicate) => {
|
||||
atom!("$add_discontiguous_predicate")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => atom!("$add_dynamic_predicate"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddMultifilePredicate) => {
|
||||
atom!("$add_multifile_predicate")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
|
||||
atom!("$add_goal_expansion_clause")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
|
||||
atom!("$add_term_expansion_clause")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => atom!("$clause_to_evacuable"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::ScopedClauseToEvacuable) => {
|
||||
atom!("$scoped_clause_to_evacuable")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => atom!("$conclude_load"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => atom!("$declare_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => atom!("$load_compiled_library"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
|
||||
atom!("$push_load_state_payload")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule) => {
|
||||
atom!("$add_in_situ_filename_module")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::Asserta) => atom!("$asserta"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Assertz) => atom!("$assertz"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Retract) => atom!("$retract_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) => atom!("$use_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => atom!("$push_load_context"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => atom!("$pop_load_context"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => atom!("$pop_load_state_payload"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => atom!("$prolog_lc_source"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => atom!("$prolog_lc_file"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => atom!("$prolog_lc_dir"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => atom!("$prolog_lc_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => atom!("$prolog_lc_stream"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
|
||||
atom!("$cpp_meta_predicate_property")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => atom!("$cpp_built_in_property"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => atom!("$cpp_dynamic_property"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => atom!("$cpp_multifile_property"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => {
|
||||
atom!("$cpp_discontiguous_property")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => atom!("$abolish_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::IsConsistentWithTermQueue) => {
|
||||
atom!("$is_consistent_with_term_queue")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::FlushTermQueue) => atom!("$flush_term_queue"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::RemoveModuleExports) => atom!("$remove_module_exports"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddNonCountedBacktracking) => {
|
||||
atom!("$add_non_counted_backtracking")
|
||||
}
|
||||
&SystemClauseType::Close => atom!("$close"),
|
||||
&SystemClauseType::CopyToLiftedHeap => atom!("$copy_to_lh"),
|
||||
&SystemClauseType::DeleteAttribute => atom!("$del_attr_non_head"),
|
||||
&SystemClauseType::DeleteHeadAttribute => atom!("$del_attr_head"),
|
||||
&SystemClauseType::DynamicModuleResolution(_) => atom!("$module_call"),
|
||||
&SystemClauseType::EnqueueAttributedVar => atom!("$enqueue_attr_var"),
|
||||
&SystemClauseType::FetchGlobalVar => atom!("$fetch_global_var"),
|
||||
&SystemClauseType::FirstStream => atom!("$first_stream"),
|
||||
&SystemClauseType::FlushOutput => atom!("$flush_output"),
|
||||
&SystemClauseType::GetByte => atom!("$get_byte"),
|
||||
&SystemClauseType::GetChar => atom!("$get_char"),
|
||||
&SystemClauseType::GetNChars => atom!("$get_n_chars"),
|
||||
&SystemClauseType::GetCode => atom!("$get_code"),
|
||||
&SystemClauseType::GetSingleChar => atom!("$get_single_char"),
|
||||
&SystemClauseType::ResetAttrVarState => atom!("$reset_attr_var_state"),
|
||||
&SystemClauseType::TruncateIfNoLiftedHeapGrowth => atom!("$truncate_if_no_lh_growth"),
|
||||
&SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff => atom!("$truncate_if_no_lh_growth_diff"),
|
||||
&SystemClauseType::GetAttributedVariableList => atom!("$get_attr_list"),
|
||||
&SystemClauseType::GetAttrVarQueueDelimiter => atom!("$get_attr_var_queue_delim"),
|
||||
&SystemClauseType::GetAttrVarQueueBeyond => atom!("$get_attr_var_queue_beyond"),
|
||||
&SystemClauseType::GetContinuationChunk => atom!("$get_cont_chunk"),
|
||||
&SystemClauseType::GetLiftedHeapFromOffset => atom!("$get_lh_from_offset"),
|
||||
&SystemClauseType::GetLiftedHeapFromOffsetDiff => atom!("$get_lh_from_offset_diff"),
|
||||
&SystemClauseType::GetBValue => atom!("$get_b_value"),
|
||||
&SystemClauseType::GetNextDBRef => atom!("$get_next_db_ref"),
|
||||
&SystemClauseType::GetNextOpDBRef => atom!("$get_next_op_db_ref"),
|
||||
&SystemClauseType::GetDoubleQuotes => atom!("$get_double_quotes"),
|
||||
&SystemClauseType::GetSCCCleaner => atom!("$get_scc_cleaner"),
|
||||
&SystemClauseType::Halt => atom!("$halt"),
|
||||
&SystemClauseType::HeadIsDynamic => atom!("$head_is_dynamic"),
|
||||
&SystemClauseType::Open => atom!("$open"),
|
||||
&SystemClauseType::OpDeclaration => atom!("$op"),
|
||||
&SystemClauseType::InstallSCCCleaner => atom!("$install_scc_cleaner"),
|
||||
&SystemClauseType::InstallInferenceCounter => atom!("$install_inference_counter"),
|
||||
&SystemClauseType::IsPartialString => atom!("$is_partial_string"),
|
||||
&SystemClauseType::PartialStringTail => atom!("$partial_string_tail"),
|
||||
&SystemClauseType::PeekByte => atom!("$peek_byte"),
|
||||
&SystemClauseType::PeekChar => atom!("$peek_char"),
|
||||
&SystemClauseType::PeekCode => atom!("$peek_code"),
|
||||
&SystemClauseType::LiftedHeapLength => atom!("$lh_length"),
|
||||
&SystemClauseType::Maybe => atom!("maybe"),
|
||||
&SystemClauseType::CpuNow => atom!("$cpu_now"),
|
||||
&SystemClauseType::CurrentTime => atom!("$current_time"),
|
||||
&SystemClauseType::ModuleExists => atom!("$module_exists"),
|
||||
&SystemClauseType::NextStream => atom!("$next_stream"),
|
||||
&SystemClauseType::NoSuchPredicate => atom!("$no_such_predicate"),
|
||||
&SystemClauseType::NumberToChars => atom!("$number_to_chars"),
|
||||
&SystemClauseType::NumberToCodes => atom!("$number_to_codes"),
|
||||
&SystemClauseType::PointsToContinuationResetMarker => {
|
||||
atom!("$points_to_cont_reset_marker")
|
||||
}
|
||||
&SystemClauseType::PutByte => {
|
||||
atom!("$put_byte")
|
||||
}
|
||||
&SystemClauseType::PutChar => {
|
||||
atom!("$put_char")
|
||||
}
|
||||
&SystemClauseType::PutChars => {
|
||||
atom!("$put_chars")
|
||||
}
|
||||
&SystemClauseType::PutCode => {
|
||||
atom!("$put_code")
|
||||
}
|
||||
&SystemClauseType::QuotedToken => {
|
||||
atom!("$quoted_token")
|
||||
}
|
||||
&SystemClauseType::RedoAttrVarBinding => atom!("$redo_attr_var_binding"),
|
||||
&SystemClauseType::RemoveCallPolicyCheck => atom!("$remove_call_policy_check"),
|
||||
&SystemClauseType::RemoveInferenceCounter => atom!("$remove_inference_counter"),
|
||||
&SystemClauseType::RestoreCutPolicy => atom!("$restore_cut_policy"),
|
||||
&SystemClauseType::SetCutPoint(_) => atom!("$set_cp"),
|
||||
&SystemClauseType::SetInput => atom!("$set_input"),
|
||||
&SystemClauseType::SetOutput => atom!("$set_output"),
|
||||
&SystemClauseType::SetSeed => atom!("$set_seed"),
|
||||
&SystemClauseType::StreamProperty => atom!("$stream_property"),
|
||||
&SystemClauseType::SetStreamPosition => atom!("$set_stream_position"),
|
||||
&SystemClauseType::SetStreamOptions => atom!("$set_stream_options"),
|
||||
&SystemClauseType::StoreBacktrackableGlobalVar => {
|
||||
atom!("$store_back_trackable_global_var")
|
||||
}
|
||||
&SystemClauseType::StoreGlobalVar => atom!("$store_global_var"),
|
||||
&SystemClauseType::InferenceLevel => atom!("$inference_level"),
|
||||
&SystemClauseType::CleanUpBlock => atom!("$clean_up_block"),
|
||||
&SystemClauseType::EraseBall => atom!("$erase_ball"),
|
||||
&SystemClauseType::Fail => atom!("$fail"),
|
||||
&SystemClauseType::GetBall => atom!("$get_ball"),
|
||||
&SystemClauseType::GetCutPoint => atom!("$get_cp"),
|
||||
&SystemClauseType::GetStaggeredCutPoint => atom!("$get_staggered_cp"),
|
||||
&SystemClauseType::GetCurrentBlock => atom!("$get_current_block"),
|
||||
&SystemClauseType::InstallNewBlock => atom!("$install_new_block"),
|
||||
&SystemClauseType::NextEP => atom!("$nextEP"),
|
||||
&SystemClauseType::ReadQueryTerm => atom!("$read_query_term"),
|
||||
&SystemClauseType::ReadTerm => atom!("$read_term"),
|
||||
&SystemClauseType::ReadTermFromChars => atom!("$read_term_from_chars"),
|
||||
&SystemClauseType::ResetBlock => atom!("$reset_block"),
|
||||
&SystemClauseType::ResetContinuationMarker => atom!("$reset_cont_marker"),
|
||||
&SystemClauseType::ReturnFromVerifyAttr => atom!("$return_from_verify_attr"),
|
||||
&SystemClauseType::SetBall => atom!("$set_ball"),
|
||||
&SystemClauseType::SetCutPointByDefault(_) => atom!("$set_cp_by_default"),
|
||||
&SystemClauseType::SetDoubleQuotes => atom!("$set_double_quotes"),
|
||||
&SystemClauseType::SkipMaxList => atom!("$skip_max_list"),
|
||||
&SystemClauseType::Sleep => atom!("$sleep"),
|
||||
&SystemClauseType::SocketClientOpen => atom!("$socket_client_open"),
|
||||
&SystemClauseType::SocketServerOpen => atom!("$socket_server_open"),
|
||||
&SystemClauseType::SocketServerAccept => atom!("$socket_server_accept"),
|
||||
&SystemClauseType::SocketServerClose => atom!("$socket_server_close"),
|
||||
&SystemClauseType::TLSAcceptClient => atom!("$tls_accept_client"),
|
||||
&SystemClauseType::TLSClientConnect => atom!("$tls_client_connect"),
|
||||
&SystemClauseType::Succeed => atom!("$succeed"),
|
||||
&SystemClauseType::TermAttributedVariables => {
|
||||
atom!("$term_attributed_variables")
|
||||
}
|
||||
&SystemClauseType::TermVariables => atom!("$term_variables"),
|
||||
&SystemClauseType::TermVariablesUnderMaxDepth => atom!("$term_variables_under_max_depth"),
|
||||
&SystemClauseType::TruncateLiftedHeapTo => atom!("$truncate_lh_to"),
|
||||
&SystemClauseType::UnifyWithOccursCheck => atom!("$unify_with_occurs_check"),
|
||||
&SystemClauseType::UnwindEnvironments => atom!("$unwind_environments"),
|
||||
&SystemClauseType::UnwindStack => atom!("$unwind_stack"),
|
||||
&SystemClauseType::WAMInstructions => atom!("$wam_instructions"),
|
||||
&SystemClauseType::WriteTerm => atom!("$write_term"),
|
||||
&SystemClauseType::WriteTermToChars => atom!("$write_term_to_chars"),
|
||||
&SystemClauseType::ScryerPrologVersion => atom!("$scryer_prolog_version"),
|
||||
&SystemClauseType::CryptoRandomByte => atom!("$crypto_random_byte"),
|
||||
&SystemClauseType::CryptoDataHash => atom!("$crypto_data_hash"),
|
||||
&SystemClauseType::CryptoDataHKDF => atom!("$crypto_data_hkdf"),
|
||||
&SystemClauseType::CryptoPasswordHash => atom!("$crypto_password_hash"),
|
||||
&SystemClauseType::CryptoDataEncrypt => atom!("$crypto_data_encrypt"),
|
||||
&SystemClauseType::CryptoDataDecrypt => atom!("$crypto_data_decrypt"),
|
||||
&SystemClauseType::CryptoCurveScalarMult => atom!("$crypto_curve_scalar_mult"),
|
||||
&SystemClauseType::Ed25519Sign => atom!("$ed25519_sign"),
|
||||
&SystemClauseType::Ed25519Verify => atom!("$ed25519_verify"),
|
||||
&SystemClauseType::Ed25519NewKeyPair => atom!("$ed25519_new_keypair"),
|
||||
&SystemClauseType::Ed25519KeyPairPublicKey => {
|
||||
atom!("$ed25519_keypair_public_key")
|
||||
}
|
||||
&SystemClauseType::Curve25519ScalarMult => atom!("$curve25519_scalar_mult"),
|
||||
&SystemClauseType::FirstNonOctet => atom!("$first_non_octet"),
|
||||
&SystemClauseType::LoadHTML => atom!("$load_html"),
|
||||
&SystemClauseType::LoadXML => atom!("$load_xml"),
|
||||
&SystemClauseType::GetEnv => atom!("$getenv"),
|
||||
&SystemClauseType::SetEnv => atom!("$setenv"),
|
||||
&SystemClauseType::UnsetEnv => atom!("$unsetenv"),
|
||||
&SystemClauseType::Shell => atom!("$shell"),
|
||||
&SystemClauseType::PID => atom!("$pid"),
|
||||
&SystemClauseType::CharsBase64 => atom!("$chars_base64"),
|
||||
&SystemClauseType::LoadLibraryAsStream => atom!("$load_library_as_stream"),
|
||||
&SystemClauseType::DevourWhitespace => atom!("$devour_whitespace"),
|
||||
&SystemClauseType::IsSTOEnabled => atom!("$is_sto_enabled"),
|
||||
&SystemClauseType::SetSTOAsUnify => atom!("$set_sto_as_unify"),
|
||||
&SystemClauseType::SetNSTOAsUnify => atom!("$set_nsto_as_unify"),
|
||||
&SystemClauseType::HomeDirectory => atom!("$home_directory"),
|
||||
&SystemClauseType::SetSTOWithErrorAsUnify => {
|
||||
atom!("$set_sto_with_error_as_unify")
|
||||
}
|
||||
&SystemClauseType::DebugHook => atom!("$debug_hook"),
|
||||
&SystemClauseType::PopCount => atom!("$popcount"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from(name: Atom, arity: usize) -> Option<SystemClauseType> {
|
||||
match (name, arity) {
|
||||
(atom!("$abolish_clause"), 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
||||
(atom!("$add_dynamic_predicate"), 4) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
|
||||
}
|
||||
(atom!("$add_multifile_predicate"), 4) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddMultifilePredicate))
|
||||
}
|
||||
(atom!("$add_discontiguous_predicate"), 4) => Some(SystemClauseType::REPL(
|
||||
REPLCodePtr::AddDiscontiguousPredicate,
|
||||
)),
|
||||
(atom!("$add_goal_expansion_clause"), 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
|
||||
}
|
||||
(atom!("$add_term_expansion_clause"), 2) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
|
||||
}
|
||||
(atom!("$atom_chars"), 2) => Some(SystemClauseType::AtomChars),
|
||||
(atom!("$atom_codes"), 2) => Some(SystemClauseType::AtomCodes),
|
||||
(atom!("$atom_length"), 2) => Some(SystemClauseType::AtomLength),
|
||||
(atom!("$bind_from_register"), 2) => Some(SystemClauseType::BindFromRegister),
|
||||
(atom!("$call_continuation"), 1) => Some(SystemClauseType::CallContinuation),
|
||||
(atom!("$char_code"), 2) => Some(SystemClauseType::CharCode),
|
||||
(atom!("$char_type"), 2) => Some(SystemClauseType::CharType),
|
||||
(atom!("$chars_to_number"), 2) => Some(SystemClauseType::CharsToNumber),
|
||||
(atom!("$codes_to_number"), 2) => Some(SystemClauseType::CodesToNumber),
|
||||
(atom!("$copy_term_without_attr_vars"), 2) => Some(SystemClauseType::CopyTermWithoutAttrVars),
|
||||
(atom!("$create_partial_string"), 3) => Some(SystemClauseType::CreatePartialString),
|
||||
(atom!("$check_cp"), 1) => Some(SystemClauseType::CheckCutPoint),
|
||||
(atom!("$copy_to_lh"), 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
||||
(atom!("$close"), 2) => Some(SystemClauseType::Close),
|
||||
(atom!("$current_hostname"), 1) => Some(SystemClauseType::CurrentHostname),
|
||||
(atom!("$current_input"), 1) => Some(SystemClauseType::CurrentInput),
|
||||
(atom!("$current_output"), 1) => Some(SystemClauseType::CurrentOutput),
|
||||
(atom!("$first_stream"), 1) => Some(SystemClauseType::FirstStream),
|
||||
(atom!("$next_stream"), 2) => Some(SystemClauseType::NextStream),
|
||||
(atom!("$flush_output"), 1) => Some(SystemClauseType::FlushOutput),
|
||||
(atom!("$del_attr_non_head"), 1) => Some(SystemClauseType::DeleteAttribute),
|
||||
(atom!("$del_attr_head"), 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
||||
(atom!("$get_next_db_ref"), 4) => Some(SystemClauseType::GetNextDBRef),
|
||||
(atom!("$get_next_op_db_ref"), 7) => Some(SystemClauseType::GetNextOpDBRef),
|
||||
(atom!("$module_call"), _) => Some(SystemClauseType::DynamicModuleResolution(arity - 2)),
|
||||
(atom!("$enqueue_attr_var"), 1) => Some(SystemClauseType::EnqueueAttributedVar),
|
||||
(atom!("$partial_string_tail"), 2) => Some(SystemClauseType::PartialStringTail),
|
||||
(atom!("$peek_byte"), 2) => Some(SystemClauseType::PeekByte),
|
||||
(atom!("$peek_char"), 2) => Some(SystemClauseType::PeekChar),
|
||||
(atom!("$peek_code"), 2) => Some(SystemClauseType::PeekCode),
|
||||
(atom!("$is_partial_string"), 1) => Some(SystemClauseType::IsPartialString),
|
||||
(atom!("$fetch_global_var"), 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||
(atom!("$get_byte"), 2) => Some(SystemClauseType::GetByte),
|
||||
(atom!("$get_char"), 2) => Some(SystemClauseType::GetChar),
|
||||
(atom!("$get_n_chars"), 3) => Some(SystemClauseType::GetNChars),
|
||||
(atom!("$get_code"), 2) => Some(SystemClauseType::GetCode),
|
||||
(atom!("$get_single_char"), 1) => Some(SystemClauseType::GetSingleChar),
|
||||
(atom!("$points_to_cont_reset_marker"), 1) => {
|
||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||
}
|
||||
(atom!("$put_byte"), 2) => Some(SystemClauseType::PutByte),
|
||||
(atom!("$put_char"), 2) => Some(SystemClauseType::PutChar),
|
||||
(atom!("$put_chars"), 2) => Some(SystemClauseType::PutChars),
|
||||
(atom!("$put_code"), 2) => Some(SystemClauseType::PutCode),
|
||||
(atom!("$reset_attr_var_state"), 0) => Some(SystemClauseType::ResetAttrVarState),
|
||||
(atom!("$truncate_if_no_lh_growth"), 1) => {
|
||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
||||
}
|
||||
(atom!("$truncate_if_no_lh_growth_diff"), 2) => {
|
||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowthDiff)
|
||||
}
|
||||
(atom!("$get_attr_list"), 2) => Some(SystemClauseType::GetAttributedVariableList),
|
||||
(atom!("$get_b_value"), 1) => Some(SystemClauseType::GetBValue),
|
||||
(atom!("$get_lh_from_offset"), 2) => Some(SystemClauseType::GetLiftedHeapFromOffset),
|
||||
(atom!("$get_lh_from_offset_diff"), 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
||||
(atom!("$get_double_quotes"), 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||
(atom!("$get_scc_cleaner"), 1) => Some(SystemClauseType::GetSCCCleaner),
|
||||
(atom!("$halt"), 1) => Some(SystemClauseType::Halt),
|
||||
(atom!("$head_is_dynamic"), 2) => Some(SystemClauseType::HeadIsDynamic),
|
||||
(atom!("$install_scc_cleaner"), 2) => Some(SystemClauseType::InstallSCCCleaner),
|
||||
(atom!("$install_inference_counter"), 3) => Some(SystemClauseType::InstallInferenceCounter),
|
||||
(atom!("$lh_length"), 1) => Some(SystemClauseType::LiftedHeapLength),
|
||||
(atom!("$maybe"), 0) => Some(SystemClauseType::Maybe),
|
||||
(atom!("$cpu_now"), 1) => Some(SystemClauseType::CpuNow),
|
||||
(atom!("$current_time"), 1) => Some(SystemClauseType::CurrentTime),
|
||||
(atom!("$module_exists"), 1) => Some(SystemClauseType::ModuleExists),
|
||||
(atom!("$no_such_predicate"), 2) => Some(SystemClauseType::NoSuchPredicate),
|
||||
(atom!("$number_to_chars"), 2) => Some(SystemClauseType::NumberToChars),
|
||||
(atom!("$number_to_codes"), 2) => Some(SystemClauseType::NumberToCodes),
|
||||
(atom!("$op"), 3) => Some(SystemClauseType::OpDeclaration),
|
||||
(atom!("$open"), 7) => Some(SystemClauseType::Open),
|
||||
(atom!("$set_stream_options"), 5) => Some(SystemClauseType::SetStreamOptions),
|
||||
(atom!("$redo_attr_var_binding"), 2) => Some(SystemClauseType::RedoAttrVarBinding),
|
||||
(atom!("$remove_call_policy_check"), 1) => Some(SystemClauseType::RemoveCallPolicyCheck),
|
||||
(atom!("$remove_inference_counter"), 2) => Some(SystemClauseType::RemoveInferenceCounter),
|
||||
(atom!("$restore_cut_policy"), 0) => Some(SystemClauseType::RestoreCutPolicy),
|
||||
(atom!("$set_cp"), 1) => Some(SystemClauseType::SetCutPoint(temp_v!(1))),
|
||||
(atom!("$set_input"), 1) => Some(SystemClauseType::SetInput),
|
||||
(atom!("$set_output"), 1) => Some(SystemClauseType::SetOutput),
|
||||
(atom!("$stream_property"), 3) => Some(SystemClauseType::StreamProperty),
|
||||
(atom!("$set_stream_position"), 2) => Some(SystemClauseType::SetStreamPosition),
|
||||
(atom!("$inference_level"), 2) => Some(SystemClauseType::InferenceLevel),
|
||||
(atom!("$clean_up_block"), 1) => Some(SystemClauseType::CleanUpBlock),
|
||||
(atom!("$erase_ball"), 0) => Some(SystemClauseType::EraseBall),
|
||||
(atom!("$fail"), 0) => Some(SystemClauseType::Fail),
|
||||
(atom!("$get_attr_var_queue_beyond"), 2) => Some(SystemClauseType::GetAttrVarQueueBeyond),
|
||||
(atom!("$get_attr_var_queue_delim"), 1) => Some(SystemClauseType::GetAttrVarQueueDelimiter),
|
||||
(atom!("$get_ball"), 1) => Some(SystemClauseType::GetBall),
|
||||
(atom!("$get_cont_chunk"), 3) => Some(SystemClauseType::GetContinuationChunk),
|
||||
(atom!("$get_current_block"), 1) => Some(SystemClauseType::GetCurrentBlock),
|
||||
(atom!("$get_cp"), 1) => Some(SystemClauseType::GetCutPoint),
|
||||
(atom!("$get_staggered_cp"), 1) => Some(SystemClauseType::GetStaggeredCutPoint),
|
||||
(atom!("$install_new_block"), 1) => Some(SystemClauseType::InstallNewBlock),
|
||||
(atom!("$quoted_token"), 1) => Some(SystemClauseType::QuotedToken),
|
||||
(atom!("$nextEP"), 3) => Some(SystemClauseType::NextEP),
|
||||
(atom!("$read_query_term"), 5) => Some(SystemClauseType::ReadQueryTerm),
|
||||
(atom!("$read_term"), 5) => Some(SystemClauseType::ReadTerm),
|
||||
(atom!("$read_term_from_chars"), 2) => Some(SystemClauseType::ReadTermFromChars),
|
||||
(atom!("$reset_block"), 1) => Some(SystemClauseType::ResetBlock),
|
||||
(atom!("$reset_cont_marker"), 0) => Some(SystemClauseType::ResetContinuationMarker),
|
||||
(atom!("$return_from_verify_attr"), 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
|
||||
(atom!("$set_ball"), 1) => Some(SystemClauseType::SetBall),
|
||||
(atom!("$set_cp_by_default"), 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
|
||||
(atom!("$set_double_quotes"), 1) => Some(SystemClauseType::SetDoubleQuotes),
|
||||
(atom!("$set_seed"), 1) => Some(SystemClauseType::SetSeed),
|
||||
(atom!("$skip_max_list"), 4) => Some(SystemClauseType::SkipMaxList),
|
||||
(atom!("$sleep"), 1) => Some(SystemClauseType::Sleep),
|
||||
(atom!("$tls_accept_client"), 4) => Some(SystemClauseType::TLSAcceptClient),
|
||||
(atom!("$tls_client_connect"), 3) => Some(SystemClauseType::TLSClientConnect),
|
||||
(atom!("$socket_client_open"), 8) => Some(SystemClauseType::SocketClientOpen),
|
||||
(atom!("$socket_server_open"), 3) => Some(SystemClauseType::SocketServerOpen),
|
||||
(atom!("$socket_server_accept"), 7) => Some(SystemClauseType::SocketServerAccept),
|
||||
(atom!("$socket_server_close"), 1) => Some(SystemClauseType::SocketServerClose),
|
||||
(atom!("$store_global_var"), 2) => Some(SystemClauseType::StoreGlobalVar),
|
||||
(atom!("$store_backtrackable_global_var"), 2) => {
|
||||
Some(SystemClauseType::StoreBacktrackableGlobalVar)
|
||||
}
|
||||
(atom!("$term_attributed_variables"), 2) => Some(SystemClauseType::TermAttributedVariables),
|
||||
(atom!("$term_variables"), 2) => Some(SystemClauseType::TermVariables),
|
||||
(atom!("$term_variables_under_max_depth"), 3) => Some(SystemClauseType::TermVariablesUnderMaxDepth),
|
||||
(atom!("$truncate_lh_to"), 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||
(atom!("$unwind_environments"), 0) => Some(SystemClauseType::UnwindEnvironments),
|
||||
(atom!("$unwind_stack"), 0) => Some(SystemClauseType::UnwindStack),
|
||||
(atom!("$unify_with_occurs_check"), 2) => Some(SystemClauseType::UnifyWithOccursCheck),
|
||||
(atom!("$directory_files"), 2) => Some(SystemClauseType::DirectoryFiles),
|
||||
(atom!("$file_size"), 2) => Some(SystemClauseType::FileSize),
|
||||
(atom!("$file_exists"), 1) => Some(SystemClauseType::FileExists),
|
||||
(atom!("$directory_exists"), 1) => Some(SystemClauseType::DirectoryExists),
|
||||
(atom!("$directory_separator"), 1) => Some(SystemClauseType::DirectorySeparator),
|
||||
(atom!("$make_directory"), 1) => Some(SystemClauseType::MakeDirectory),
|
||||
(atom!("$make_directory_path"), 1) => Some(SystemClauseType::MakeDirectoryPath),
|
||||
(atom!("$delete_file"), 1) => Some(SystemClauseType::DeleteFile),
|
||||
(atom!("$rename_file"), 2) => Some(SystemClauseType::RenameFile),
|
||||
(atom!("$delete_directory"), 1) => Some(SystemClauseType::DeleteDirectory),
|
||||
(atom!("$working_directory"), 2) => Some(SystemClauseType::WorkingDirectory),
|
||||
(atom!("$path_canonical"), 2) => Some(SystemClauseType::PathCanonical),
|
||||
(atom!("$file_time"), 3) => Some(SystemClauseType::FileTime),
|
||||
(atom!("$clause_to_evacuable"), 2) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
|
||||
}
|
||||
(atom!("$scoped_clause_to_evacuable"), 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::ScopedClauseToEvacuable))
|
||||
}
|
||||
(atom!("$conclude_load"), 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
|
||||
(atom!("$use_module"), 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||
(atom!("$declare_module"), 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
||||
(atom!("$load_compiled_library"), 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
|
||||
}
|
||||
(atom!("$push_load_state_payload"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
|
||||
}
|
||||
(atom!("$add_in_situ_filename_module"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddInSituFilenameModule))
|
||||
}
|
||||
(atom!("$asserta"), 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
|
||||
(atom!("$assertz"), 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
|
||||
(atom!("$retract_clause"), 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
|
||||
(atom!("$is_consistent_with_term_queue"), 4) => Some(SystemClauseType::REPL(
|
||||
REPLCodePtr::IsConsistentWithTermQueue,
|
||||
)),
|
||||
(atom!("$flush_term_queue"), 1) => Some(SystemClauseType::REPL(REPLCodePtr::FlushTermQueue)),
|
||||
(atom!("$remove_module_exports"), 2) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::RemoveModuleExports))
|
||||
}
|
||||
(atom!("$add_non_counted_backtracking"), 3) => Some(SystemClauseType::REPL(
|
||||
REPLCodePtr::AddNonCountedBacktracking,
|
||||
)),
|
||||
(atom!("$wam_instructions"), 4) => Some(SystemClauseType::WAMInstructions),
|
||||
(atom!("$write_term"), 7) => Some(SystemClauseType::WriteTerm),
|
||||
(atom!("$write_term_to_chars"), 7) => Some(SystemClauseType::WriteTermToChars),
|
||||
(atom!("$scryer_prolog_version"), 1) => Some(SystemClauseType::ScryerPrologVersion),
|
||||
(atom!("$crypto_random_byte"), 1) => Some(SystemClauseType::CryptoRandomByte),
|
||||
(atom!("$crypto_data_hash"), 4) => Some(SystemClauseType::CryptoDataHash),
|
||||
(atom!("$crypto_data_hkdf"), 7) => Some(SystemClauseType::CryptoDataHKDF),
|
||||
(atom!("$crypto_password_hash"), 4) => Some(SystemClauseType::CryptoPasswordHash),
|
||||
(atom!("$crypto_data_encrypt"), 7) => Some(SystemClauseType::CryptoDataEncrypt),
|
||||
(atom!("$crypto_data_decrypt"), 6) => Some(SystemClauseType::CryptoDataDecrypt),
|
||||
(atom!("$crypto_curve_scalar_mult"), 5) => Some(SystemClauseType::CryptoCurveScalarMult),
|
||||
(atom!("$ed25519_sign"), 4) => Some(SystemClauseType::Ed25519Sign),
|
||||
(atom!("$ed25519_verify"), 4) => Some(SystemClauseType::Ed25519Verify),
|
||||
(atom!("$ed25519_new_keypair"), 1) => Some(SystemClauseType::Ed25519NewKeyPair),
|
||||
(atom!("$ed25519_keypair_public_key"), 2) => Some(SystemClauseType::Ed25519KeyPairPublicKey),
|
||||
(atom!("$curve25519_scalar_mult"), 3) => Some(SystemClauseType::Curve25519ScalarMult),
|
||||
(atom!("$first_non_octet"), 2) => Some(SystemClauseType::FirstNonOctet),
|
||||
(atom!("$load_html"), 3) => Some(SystemClauseType::LoadHTML),
|
||||
(atom!("$load_xml"), 3) => Some(SystemClauseType::LoadXML),
|
||||
(atom!("$getenv"), 2) => Some(SystemClauseType::GetEnv),
|
||||
(atom!("$setenv"), 2) => Some(SystemClauseType::SetEnv),
|
||||
(atom!("$unsetenv"), 1) => Some(SystemClauseType::UnsetEnv),
|
||||
(atom!("$shell"), 2) => Some(SystemClauseType::Shell),
|
||||
(atom!("$pid"), 1) => Some(SystemClauseType::PID),
|
||||
(atom!("$chars_base64"), 4) => Some(SystemClauseType::CharsBase64),
|
||||
(atom!("$load_library_as_stream"), 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
||||
(atom!("$push_load_context"), 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
|
||||
(atom!("$pop_load_state_payload"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload))
|
||||
}
|
||||
(atom!("$pop_load_context"), 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
|
||||
(atom!("$prolog_lc_source"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource))
|
||||
}
|
||||
(atom!("$prolog_lc_file"), 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
|
||||
(atom!("$prolog_lc_dir"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
|
||||
}
|
||||
(atom!("$prolog_lc_module"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
|
||||
}
|
||||
(atom!("$prolog_lc_stream"), 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream))
|
||||
}
|
||||
(atom!("$cpp_meta_predicate_property"), 4) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty))
|
||||
}
|
||||
(atom!("$cpp_built_in_property"), 2) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty))
|
||||
}
|
||||
(atom!("$cpp_dynamic_property"), 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty))
|
||||
}
|
||||
(atom!("$cpp_multifile_property"), 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty))
|
||||
}
|
||||
(atom!("$cpp_discontiguous_property"), 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty))
|
||||
}
|
||||
(atom!("$devour_whitespace"), 1) => Some(SystemClauseType::DevourWhitespace),
|
||||
(atom!("$is_sto_enabled"), 1) => Some(SystemClauseType::IsSTOEnabled),
|
||||
(atom!("$set_sto_as_unify"), 0) => Some(SystemClauseType::SetSTOAsUnify),
|
||||
(atom!("$set_nsto_as_unify"), 0) => Some(SystemClauseType::SetNSTOAsUnify),
|
||||
(atom!("$set_sto_with_error_as_unify"), 0) => Some(SystemClauseType::SetSTOWithErrorAsUnify),
|
||||
(atom!("$home_directory"), 1) => Some(SystemClauseType::HomeDirectory),
|
||||
(atom!("$debug_hook"), 0) => Some(SystemClauseType::DebugHook),
|
||||
(atom!("$popcount"), 2) => Some(SystemClauseType::PopCount),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum BuiltInClauseType {
|
||||
AcyclicTerm,
|
||||
Arg,
|
||||
Compare,
|
||||
CompareTerm(CompareTermQT),
|
||||
CopyTerm,
|
||||
Eq,
|
||||
Functor,
|
||||
Ground,
|
||||
Is(RegType, ArithmeticTerm),
|
||||
KeySort,
|
||||
NotEq,
|
||||
Read,
|
||||
Sort,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ClauseType {
|
||||
BuiltIn(BuiltInClauseType),
|
||||
CallN,
|
||||
Inlined(InlinedClauseType),
|
||||
Named(Atom, usize, CodeIndex), // name, arity, index.
|
||||
System(SystemClauseType),
|
||||
}
|
||||
|
||||
impl BuiltInClauseType {
|
||||
pub(crate) fn name(&self) -> Atom {
|
||||
match self {
|
||||
&BuiltInClauseType::AcyclicTerm => atom!("acyclic_term"),
|
||||
&BuiltInClauseType::Arg => atom!("arg"),
|
||||
&BuiltInClauseType::Compare => atom!("compare"),
|
||||
&BuiltInClauseType::CompareTerm(qt) => qt.name(),
|
||||
&BuiltInClauseType::CopyTerm => atom!("copy_term"),
|
||||
&BuiltInClauseType::Eq => atom!("=="),
|
||||
&BuiltInClauseType::Functor => atom!("functor"),
|
||||
&BuiltInClauseType::Ground => atom!("ground"),
|
||||
&BuiltInClauseType::Is(..) => atom!("is"),
|
||||
&BuiltInClauseType::KeySort => atom!("keysort"),
|
||||
&BuiltInClauseType::NotEq => atom!("\\=="),
|
||||
&BuiltInClauseType::Read => atom!("read"),
|
||||
&BuiltInClauseType::Sort => atom!("sort"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn arity(&self) -> usize {
|
||||
match self {
|
||||
&BuiltInClauseType::AcyclicTerm => 1,
|
||||
&BuiltInClauseType::Arg => 3,
|
||||
&BuiltInClauseType::Compare => 2,
|
||||
&BuiltInClauseType::CompareTerm(_) => 2,
|
||||
&BuiltInClauseType::CopyTerm => 2,
|
||||
&BuiltInClauseType::Eq => 2,
|
||||
&BuiltInClauseType::Functor => 3,
|
||||
&BuiltInClauseType::Ground => 1,
|
||||
&BuiltInClauseType::Is(..) => 2,
|
||||
&BuiltInClauseType::KeySort => 2,
|
||||
&BuiltInClauseType::NotEq => 2,
|
||||
&BuiltInClauseType::Read => 1,
|
||||
&BuiltInClauseType::Sort => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClauseType {
|
||||
pub(crate) fn name(&self) -> Atom {
|
||||
match self {
|
||||
&ClauseType::BuiltIn(ref built_in) => built_in.name(),
|
||||
&ClauseType::CallN => atom!("$call"),
|
||||
&ClauseType::Inlined(ref inlined) => inlined.name(),
|
||||
&ClauseType::Named(name, ..) => name,
|
||||
&ClauseType::System(ref system) => system.name(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from(name: Atom, arity: usize) -> Self {
|
||||
clause_type_form(name, arity).unwrap_or_else(|| {
|
||||
SystemClauseType::from(name, arity)
|
||||
.map(ClauseType::System)
|
||||
.unwrap_or_else(|| {
|
||||
if name == atom!("$call") {
|
||||
ClauseType::CallN
|
||||
} else {
|
||||
ClauseType::Named(name, arity, CodeIndex::default())
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InlinedClauseType> for ClauseType {
|
||||
fn from(inlined_ct: InlinedClauseType) -> Self {
|
||||
ClauseType::Inlined(inlined_ct)
|
||||
}
|
||||
}
|
||||
313
src/codegen.rs
313
src/codegen.rs
@@ -4,7 +4,6 @@ use crate::{perm_v, temp_v};
|
||||
|
||||
use crate::allocator::*;
|
||||
use crate::arithmetic::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::indexing::*;
|
||||
@@ -13,6 +12,7 @@ use crate::iterators::*;
|
||||
use crate::targets::*;
|
||||
use crate::types::*;
|
||||
|
||||
use crate::instr;
|
||||
use crate::machine::machine_errors::*;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
@@ -57,7 +57,9 @@ impl<'a> ConjunctInfo<'a> {
|
||||
let mut code_index = 0;
|
||||
|
||||
for phase in 0.. {
|
||||
while let Line::Query(ref query_instr) = &code[code_index] {
|
||||
while code[code_index].is_query_instr() {
|
||||
let query_instr = &mut code[code_index];
|
||||
|
||||
if !unsafe_var_marker.mark_safe_vars(query_instr) {
|
||||
unsafe_var_marker.mark_phase(query_instr, phase);
|
||||
}
|
||||
@@ -75,7 +77,8 @@ impl<'a> ConjunctInfo<'a> {
|
||||
code_index = 0;
|
||||
|
||||
for phase in 0.. {
|
||||
while let Line::Query(ref mut query_instr) = &mut code[code_index] {
|
||||
while code[code_index].is_query_instr() {
|
||||
let query_instr = &mut code[code_index];
|
||||
unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
|
||||
code_index += 1;
|
||||
}
|
||||
@@ -103,9 +106,9 @@ impl CodeGenSettings {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn internal_try_me_else(&self, offset: usize) -> ChoiceInstruction {
|
||||
pub(crate) fn internal_try_me_else(&self, offset: usize) -> Instruction {
|
||||
if let Some(global_clock_time) = self.global_clock_tick {
|
||||
ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicInternalElse(
|
||||
global_clock_time,
|
||||
Death::Infinity,
|
||||
if offset == 0 {
|
||||
@@ -115,13 +118,13 @@ impl CodeGenSettings {
|
||||
},
|
||||
)
|
||||
} else {
|
||||
ChoiceInstruction::TryMeElse(offset)
|
||||
Instruction::TryMeElse(offset)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn try_me_else(&self, offset: usize) -> ChoiceInstruction {
|
||||
pub(crate) fn try_me_else(&self, offset: usize) -> Instruction {
|
||||
if let Some(global_clock_tick) = self.global_clock_tick {
|
||||
ChoiceInstruction::DynamicElse(
|
||||
Instruction::DynamicElse(
|
||||
global_clock_tick,
|
||||
Death::Infinity,
|
||||
if offset == 0 {
|
||||
@@ -131,13 +134,13 @@ impl CodeGenSettings {
|
||||
},
|
||||
)
|
||||
} else {
|
||||
ChoiceInstruction::TryMeElse(offset)
|
||||
Instruction::TryMeElse(offset)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn internal_retry_me_else(&self, offset: usize) -> ChoiceInstruction {
|
||||
pub(crate) fn internal_retry_me_else(&self, offset: usize) -> Instruction {
|
||||
if let Some(global_clock_tick) = self.global_clock_tick {
|
||||
ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicInternalElse(
|
||||
global_clock_tick,
|
||||
Death::Infinity,
|
||||
if offset == 0 {
|
||||
@@ -147,13 +150,13 @@ impl CodeGenSettings {
|
||||
},
|
||||
)
|
||||
} else {
|
||||
ChoiceInstruction::RetryMeElse(offset)
|
||||
Instruction::RetryMeElse(offset)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn retry_me_else(&self, offset: usize) -> ChoiceInstruction {
|
||||
pub(crate) fn retry_me_else(&self, offset: usize) -> Instruction {
|
||||
if let Some(global_clock_tick) = self.global_clock_tick {
|
||||
ChoiceInstruction::DynamicElse(
|
||||
Instruction::DynamicElse(
|
||||
global_clock_tick,
|
||||
Death::Infinity,
|
||||
if offset == 0 {
|
||||
@@ -163,33 +166,33 @@ impl CodeGenSettings {
|
||||
},
|
||||
)
|
||||
} else if self.non_counted_bt {
|
||||
ChoiceInstruction::DefaultRetryMeElse(offset)
|
||||
Instruction::DefaultRetryMeElse(offset)
|
||||
} else {
|
||||
ChoiceInstruction::RetryMeElse(offset)
|
||||
Instruction::RetryMeElse(offset)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn internal_trust_me(&self) -> ChoiceInstruction {
|
||||
pub(crate) fn internal_trust_me(&self) -> Instruction {
|
||||
if let Some(global_clock_tick) = self.global_clock_tick {
|
||||
ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicInternalElse(
|
||||
global_clock_tick,
|
||||
Death::Infinity,
|
||||
NextOrFail::Fail(0),
|
||||
)
|
||||
} else if self.non_counted_bt {
|
||||
ChoiceInstruction::DefaultTrustMe(0)
|
||||
Instruction::DefaultTrustMe(0)
|
||||
} else {
|
||||
ChoiceInstruction::TrustMe(0)
|
||||
Instruction::TrustMe(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn trust_me(&self) -> ChoiceInstruction {
|
||||
pub(crate) fn trust_me(&self) -> Instruction {
|
||||
if let Some(global_clock_tick) = self.global_clock_tick {
|
||||
ChoiceInstruction::DynamicElse(global_clock_tick, Death::Infinity, NextOrFail::Fail(0))
|
||||
Instruction::DynamicElse(global_clock_tick, Death::Infinity, NextOrFail::Fail(0))
|
||||
} else if self.non_counted_bt {
|
||||
ChoiceInstruction::DefaultTrustMe(0)
|
||||
Instruction::DefaultTrustMe(0)
|
||||
} else {
|
||||
ChoiceInstruction::TrustMe(0)
|
||||
Instruction::TrustMe(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,12 +241,11 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
vr: &'a Cell<VarReg>,
|
||||
code: &mut Code,
|
||||
) -> RegType {
|
||||
let mut target = Vec::new();
|
||||
self.marker
|
||||
.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
|
||||
let mut target = Code::new();
|
||||
self.marker.mark_var::<QueryInstruction>(name, Level::Shallow, vr, term_loc, &mut target);
|
||||
|
||||
if !target.is_empty() {
|
||||
code.extend(target.into_iter().map(Line::Query));
|
||||
code.extend(target.into_iter());
|
||||
}
|
||||
|
||||
vr.get().norm()
|
||||
@@ -271,7 +273,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_or_increment_void_instr<Target>(target: &mut Vec<Target>)
|
||||
fn add_or_increment_void_instr<Target>(target: &mut Code)
|
||||
where
|
||||
Target: crate::targets::CompilationTarget<'a>,
|
||||
{
|
||||
@@ -291,13 +293,12 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
var: &'a Rc<String>,
|
||||
term_loc: GenContext,
|
||||
is_exposed: bool,
|
||||
target: &mut Vec<Target>,
|
||||
target: &mut Code,
|
||||
) {
|
||||
if is_exposed || self.get_var_count(var.as_ref()) > 1 {
|
||||
self.marker
|
||||
.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
|
||||
self.marker.mark_var::<Target>(var.clone(), Level::Deep, cell, term_loc, target);
|
||||
} else {
|
||||
Self::add_or_increment_void_instr(target);
|
||||
Self::add_or_increment_void_instr::<Target>(target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,27 +307,26 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
subterm: &'a Term,
|
||||
term_loc: GenContext,
|
||||
is_exposed: bool,
|
||||
target: &mut Vec<Target>,
|
||||
target: &mut Code,
|
||||
) {
|
||||
match subterm {
|
||||
&Term::AnonVar if is_exposed => {
|
||||
self.marker.mark_anon_var(Level::Deep, term_loc, target);
|
||||
self.marker.mark_anon_var::<Target>(Level::Deep, term_loc, target);
|
||||
}
|
||||
&Term::AnonVar => {
|
||||
Self::add_or_increment_void_instr(target);
|
||||
Self::add_or_increment_void_instr::<Target>(target);
|
||||
}
|
||||
&Term::Cons(ref cell, ..)
|
||||
| &Term::Clause(ref cell, ..)
|
||||
| Term::PartialString(ref cell, ..) => {
|
||||
self.marker
|
||||
.mark_non_var(Level::Deep, term_loc, cell, target);
|
||||
self.marker.mark_non_var::<Target>(Level::Deep, term_loc, cell, target);
|
||||
target.push(Target::clause_arg_to_instr(cell.get()));
|
||||
}
|
||||
&Term::Literal(_, ref constant) => {
|
||||
target.push(Target::constant_subterm(constant.clone()));
|
||||
}
|
||||
&Term::Var(ref cell, ref var) => {
|
||||
self.deep_var_instr(cell, var, term_loc, is_exposed, target);
|
||||
self.deep_var_instr::<Target>(cell, var, term_loc, is_exposed, target);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -336,12 +336,12 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
iter: Iter,
|
||||
term_loc: GenContext,
|
||||
is_exposed: bool,
|
||||
) -> Vec<Target>
|
||||
) -> Code
|
||||
where
|
||||
Target: crate::targets::CompilationTarget<'a>,
|
||||
Iter: Iterator<Item = TermRef<'a>>,
|
||||
{
|
||||
let mut target = Vec::new();
|
||||
let mut target: Code = Vec::new();
|
||||
|
||||
for term in iter {
|
||||
match term {
|
||||
@@ -349,38 +349,38 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
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::<Target>(lvl, term_loc, &mut target);
|
||||
}
|
||||
}
|
||||
TermRef::Clause(lvl, cell, ct, terms) => {
|
||||
self.marker.mark_non_var(lvl, term_loc, cell, &mut target);
|
||||
target.push(Target::to_structure(ct, terms.len(), cell.get()));
|
||||
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
||||
target.push(Target::to_structure(ct.name(), terms.len(), cell.get()));
|
||||
|
||||
for subterm in terms {
|
||||
self.subterm_to_instr(subterm, term_loc, is_exposed, &mut target);
|
||||
self.subterm_to_instr::<Target>(subterm, term_loc, is_exposed, &mut target);
|
||||
}
|
||||
}
|
||||
TermRef::Cons(lvl, cell, head, tail) => {
|
||||
self.marker.mark_non_var(lvl, term_loc, cell, &mut target);
|
||||
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
||||
target.push(Target::to_list(lvl, cell.get()));
|
||||
|
||||
self.subterm_to_instr(head, term_loc, is_exposed, &mut target);
|
||||
self.subterm_to_instr(tail, term_loc, is_exposed, &mut target);
|
||||
self.subterm_to_instr::<Target>(head, term_loc, is_exposed, &mut target);
|
||||
self.subterm_to_instr::<Target>(tail, term_loc, is_exposed, &mut target);
|
||||
}
|
||||
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::<Target>(lvl, term_loc, cell, &mut target);
|
||||
target.push(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::<Target>(lvl, term_loc, cell, &mut target);
|
||||
target.push(Target::to_constant(lvl, *constant, cell.get()));
|
||||
}
|
||||
TermRef::PartialString(lvl, cell, string, tail) => {
|
||||
self.marker.mark_non_var(lvl, term_loc, cell, &mut target);
|
||||
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
||||
|
||||
if let Some(tail) = tail {
|
||||
target.push(Target::to_pstr(lvl, string, cell.get(), true));
|
||||
self.subterm_to_instr(tail, term_loc, is_exposed, &mut target);
|
||||
self.subterm_to_instr::<Target>(tail, term_loc, is_exposed, &mut target);
|
||||
} else {
|
||||
target.push(Target::to_pstr(lvl, string, cell.get(), false));
|
||||
}
|
||||
@@ -388,7 +388,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
|
||||
if self.marker.is_unbound(var.clone()) {
|
||||
if term_loc != GenContext::Head {
|
||||
self.marker.mark_reserved_var(
|
||||
self.marker.mark_reserved_var::<Target>(
|
||||
var.clone(),
|
||||
lvl,
|
||||
cell,
|
||||
@@ -401,12 +401,10 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
}
|
||||
}
|
||||
|
||||
self.marker
|
||||
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||
self.marker.mark_var::<Target>(var.clone(), lvl, cell, term_loc, &mut target);
|
||||
}
|
||||
TermRef::Var(lvl @ Level::Shallow, cell, var) => {
|
||||
self.marker
|
||||
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||
self.marker.mark_var::<Target>(var.clone(), lvl, cell, term_loc, &mut target);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
@@ -451,13 +449,13 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
match qt {
|
||||
&QueryTerm::Jump(ref vars) => {
|
||||
self.jmp_by_locs.push(code.len());
|
||||
code.push(jmp_call!(vars.len(), 0, pvs));
|
||||
code.push(instr!("jmp_by_call", vars.len(), 0, pvs));
|
||||
}
|
||||
&QueryTerm::Clause(_, ref ct, ref terms, true) => {
|
||||
code.push(call_clause_by_default!(ct.clone(), terms.len(), pvs));
|
||||
&QueryTerm::Clause(_, ref ct, _, true) => {
|
||||
code.push(call_clause_by_default!(ct.clone(), pvs));
|
||||
}
|
||||
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
||||
code.push(call_clause!(ct.clone(), terms.len(), pvs));
|
||||
&QueryTerm::Clause(_, ref ct, _, false) => {
|
||||
code.push(call_clause!(ct.clone(), pvs));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -465,25 +463,29 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
|
||||
fn lco(code: &mut Code) -> usize {
|
||||
let mut dealloc_index = code.len() - 1;
|
||||
let last_instr = code.pop();
|
||||
|
||||
match code.last_mut() {
|
||||
Some(&mut Line::Control(ref mut ctrl)) => match ctrl {
|
||||
&mut ControlInstruction::CallClause(_, _, _, ref mut last_call, _) => {
|
||||
*last_call = true;
|
||||
match last_instr {
|
||||
Some(instr @ Instruction::Proceed) => {
|
||||
code.push(instr);
|
||||
}
|
||||
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
|
||||
*last_call = true;
|
||||
}
|
||||
&mut ControlInstruction::Proceed => {}
|
||||
_ => {
|
||||
Some(instr @ Instruction::Cut(_)) => {
|
||||
dealloc_index += 1;
|
||||
code.push(instr);
|
||||
}
|
||||
},
|
||||
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
||||
Some(mut instr) if instr.is_ctrl_instr() => {
|
||||
code.push(if instr.perm_vars_mut().is_some() {
|
||||
instr.to_execute()
|
||||
} else {
|
||||
dealloc_index += 1;
|
||||
instr
|
||||
});
|
||||
}
|
||||
Some(instr) => {
|
||||
code.push(instr);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
dealloc_index
|
||||
}
|
||||
@@ -496,7 +498,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
code: &mut Code,
|
||||
) -> Result<(), CompilationError> {
|
||||
match ct {
|
||||
&InlinedClauseType::CompareNumber(cmp, ..) => {
|
||||
&InlinedClauseType::CompareNumber(mut cmp) => {
|
||||
self.marker.reset_arg(2);
|
||||
|
||||
let (mut lcode, at_1) = self.call_arith_eval(&terms[0], 1)?;
|
||||
@@ -523,71 +525,71 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
&Term::Literal(_, Literal::Char(_))
|
||||
| &Term::Literal(_, Literal::Atom(atom!("[]")))
|
||||
| &Term::Literal(_, Literal::Atom(..)) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_atom!(r));
|
||||
code.push(instr!("atom", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsAtomic(..) => match &terms[0] {
|
||||
&Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) | &Term::PartialString(..) => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
&Term::Literal(_, Literal::String(_)) => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
&Term::Literal(..) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_atomic!(r));
|
||||
code.push(instr!("atomic", r, 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsCompound(..) => match &terms[0] {
|
||||
&Term::Clause(..) | &Term::Cons(..) | &Term::PartialString(..) |
|
||||
&Term::Literal(_, Literal::String(..)) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_compound!(r));
|
||||
code.push(instr!("compound", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsRational(..) => match &terms[0] {
|
||||
&Term::Literal(_, Literal::Rational(_)) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_rational!(r));
|
||||
code.push(instr!("rational", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsFloat(..) => match &terms[0] {
|
||||
&Term::Literal(_, Literal::Float(_)) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_float!(r));
|
||||
code.push(instr!("float", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsNumber(..) => match &terms[0] {
|
||||
@@ -595,41 +597,41 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
| &Term::Literal(_, Literal::Rational(_))
|
||||
| &Term::Literal(_, Literal::Integer(_))
|
||||
| &Term::Literal(_, Literal::Fixnum(_)) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_number!(r));
|
||||
code.push(instr!("number", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsNonVar(..) => match &terms[0] {
|
||||
&Term::AnonVar => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_nonvar!(r));
|
||||
code.push(instr!("nonvar", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsInteger(..) => match &terms[0] {
|
||||
&Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_integer!(r));
|
||||
code.push(instr!("integer", r, 0));
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsVar(..) => match &terms[0] {
|
||||
@@ -637,15 +639,15 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
| &Term::Clause(..)
|
||||
| &Term::Cons(..)
|
||||
| &Term::PartialString(..) => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
}
|
||||
&Term::AnonVar => {
|
||||
code.push(succeed!());
|
||||
code.push(instr!("$succeed", 0));
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
self.marker.reset_arg(1);
|
||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||
code.push(is_var!(r));
|
||||
code.push(instr!("var", r, 0));
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -678,34 +680,39 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
let mut target = vec![];
|
||||
|
||||
self.marker
|
||||
.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
|
||||
self.marker.mark_var::<QueryInstruction>(
|
||||
name.clone(),
|
||||
Level::Shallow,
|
||||
vr,
|
||||
term_loc,
|
||||
&mut target,
|
||||
);
|
||||
|
||||
if !target.is_empty() {
|
||||
code.extend(target.into_iter().map(Line::Query));
|
||||
code.extend(target.into_iter());
|
||||
}
|
||||
}
|
||||
&Term::Literal(_, c @ Literal::Integer(_))
|
||||
| &Term::Literal(_, c @ Literal::Fixnum(_)) => {
|
||||
let v = HeapCellValue::from(c);
|
||||
code.push(Line::Query(put_constant!(Level::Shallow, v, temp_v!(1))));
|
||||
code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1)));
|
||||
|
||||
self.marker.advance_arg();
|
||||
}
|
||||
&Term::Literal(_, c @ Literal::Float(_)) => {
|
||||
let v = HeapCellValue::from(c);
|
||||
code.push(Line::Query(put_constant!(Level::Shallow, v, temp_v!(1))));
|
||||
code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1)));
|
||||
|
||||
self.marker.advance_arg();
|
||||
}
|
||||
&Term::Literal(_, c @ Literal::Rational(_)) => {
|
||||
let v = HeapCellValue::from(c);
|
||||
code.push(Line::Query(put_constant!(Level::Shallow, v, temp_v!(1))));
|
||||
code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1)));
|
||||
|
||||
self.marker.advance_arg();
|
||||
}
|
||||
_ => {
|
||||
code.push(fail!());
|
||||
code.push(instr!("$fail", 0));
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
@@ -717,9 +724,9 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
};
|
||||
|
||||
Ok(if use_default_call_policy {
|
||||
code.push(is_call_by_default!(temp_v!(1), at));
|
||||
code.push(instr!("is", default, temp_v!(1), at, 0));
|
||||
} else {
|
||||
code.push(is_call!(temp_v!(1), at));
|
||||
code.push(instr!("is", temp_v!(1), at, 0));
|
||||
})
|
||||
}
|
||||
|
||||
@@ -727,7 +734,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &'a Cell<VarReg>) {
|
||||
let r = self.marker.get(Rc::new(String::from("!")));
|
||||
cell.set(VarReg::Norm(r));
|
||||
code.push(set_cp!(cell.get().norm()));
|
||||
code.push(instr!("$set_cp", cell.get().norm(), 0));
|
||||
}
|
||||
|
||||
fn compile_get_level_and_unify(
|
||||
@@ -737,21 +744,16 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
var: Rc<String>,
|
||||
term_loc: GenContext,
|
||||
) {
|
||||
let mut target = Vec::new();
|
||||
let mut target = Code::new();
|
||||
|
||||
self.marker.reset_arg(1);
|
||||
self.marker
|
||||
.mark_var(var, Level::Shallow, cell, term_loc, &mut target);
|
||||
self.marker.mark_var::<QueryInstruction>(var, Level::Shallow, cell, term_loc, &mut target);
|
||||
|
||||
if !target.is_empty() {
|
||||
code.extend(
|
||||
target
|
||||
.into_iter()
|
||||
.map(|query_instr| Line::Query(query_instr)),
|
||||
);
|
||||
code.extend(target.into_iter());
|
||||
}
|
||||
|
||||
code.push(get_level_and_unify!(cell.get().norm()));
|
||||
code.push(instr!("get_level_and_unify", cell.get().norm()));
|
||||
}
|
||||
|
||||
fn compile_seq(
|
||||
@@ -775,9 +777,9 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
}
|
||||
&QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
|
||||
&QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut)
|
||||
Instruction::NeckCut
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||
Instruction::Cut(perm_v!(1))
|
||||
}),
|
||||
&QueryTerm::Clause(
|
||||
_,
|
||||
@@ -810,10 +812,10 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
if conjunct_info.allocates() {
|
||||
let perm_vars = conjunct_info.perm_vars();
|
||||
|
||||
body.push(Line::Control(ControlInstruction::Allocate(perm_vars)));
|
||||
body.push(Instruction::Allocate(perm_vars));
|
||||
|
||||
if conjunct_info.has_deep_cut {
|
||||
body.push(Line::Cut(CutInstruction::GetLevel(perm_v!(1))));
|
||||
body.push(Instruction::GetLevel(perm_v!(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -826,8 +828,9 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
) {
|
||||
// add a proceed to bookend any trailing cuts.
|
||||
match toc {
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
||||
&QueryTerm::Clause(_, ClauseType::Inlined(..), ..) => code.push(proceed!()),
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => {
|
||||
code.push(instr!("proceed"));
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
@@ -843,7 +846,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
}
|
||||
}
|
||||
|
||||
code.insert(dealloc_index, Line::Control(ControlInstruction::Deallocate));
|
||||
code.insert(dealloc_index, instr!("deallocate"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,16 +868,13 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||
|
||||
let iter = FactIterator::from_rule_head_clause(args);
|
||||
let mut fact = self.compile_target(iter, GenContext::Head, false);
|
||||
let mut fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head, false);
|
||||
|
||||
let mut unsafe_var_marker = UnsafeVarMarker::new();
|
||||
|
||||
if !fact.is_empty() {
|
||||
unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact);
|
||||
|
||||
for fact_instr in fact {
|
||||
code.push(Line::Fact(fact_instr));
|
||||
}
|
||||
code.extend(fact.into_iter());
|
||||
}
|
||||
|
||||
let iter = ChunkedIterator::from_rule_body(p1, clauses);
|
||||
@@ -886,18 +886,18 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
fn mark_unsafe_fact_vars(&self, fact: &mut CompiledFact) -> UnsafeVarMarker {
|
||||
fn mark_unsafe_fact_vars(&self, fact: &mut Code) -> UnsafeVarMarker {
|
||||
let mut safe_vars = IndexSet::new();
|
||||
|
||||
for fact_instr in fact.iter_mut() {
|
||||
match fact_instr {
|
||||
&mut FactInstruction::UnifyValue(r) => {
|
||||
&mut Instruction::UnifyValue(r) => {
|
||||
if !safe_vars.contains(&r) {
|
||||
*fact_instr = FactInstruction::UnifyLocalValue(r);
|
||||
*fact_instr = Instruction::UnifyLocalValue(r);
|
||||
safe_vars.insert(r);
|
||||
}
|
||||
}
|
||||
&mut FactInstruction::UnifyVariable(r) => {
|
||||
&mut Instruction::UnifyVariable(r) => {
|
||||
safe_vars.insert(r);
|
||||
}
|
||||
_ => {}
|
||||
@@ -923,18 +923,20 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
self.marker.reset_at_head(args);
|
||||
|
||||
let iter = FactInstruction::iter(term);
|
||||
let mut compiled_fact = self.compile_target(iter, GenContext::Head, false);
|
||||
let mut compiled_fact = self.compile_target::<FactInstruction, _>(
|
||||
iter,
|
||||
GenContext::Head,
|
||||
false,
|
||||
);
|
||||
|
||||
self.mark_unsafe_fact_vars(&mut compiled_fact);
|
||||
|
||||
if !compiled_fact.is_empty() {
|
||||
for fact_instr in compiled_fact {
|
||||
code.push(Line::Fact(fact_instr));
|
||||
}
|
||||
code.extend(compiled_fact.into_iter());
|
||||
}
|
||||
}
|
||||
|
||||
code.push(proceed!());
|
||||
code.push(instr!("proceed"));
|
||||
code
|
||||
}
|
||||
|
||||
@@ -949,12 +951,10 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
self.marker.reset_arg(term.arity());
|
||||
|
||||
let iter = query_term_post_order_iter(term);
|
||||
let query = self.compile_target(iter, term_loc, is_exposed);
|
||||
let query = self.compile_target::<QueryInstruction, _>(iter, term_loc, is_exposed);
|
||||
|
||||
if !query.is_empty() {
|
||||
for query_instr in query {
|
||||
code.push(Line::Query(query_instr));
|
||||
}
|
||||
code.extend(query.into_iter());
|
||||
}
|
||||
|
||||
self.add_conditional_call(code, term, num_perm_vars_left);
|
||||
@@ -1061,12 +1061,12 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
if clauses.len() > 1 {
|
||||
let choice = match i {
|
||||
0 => self.settings.internal_try_me_else(clause_code.len() + 1),
|
||||
//ChoiceInstruction::TryMeElse(clause_code.len() + 1),
|
||||
//Instruction::TryMeElse(clause_code.len() + 1),
|
||||
_ if i == clauses.len() - 1 => self.settings.internal_trust_me(),
|
||||
_ => self.settings.internal_retry_me_else(clause_code.len() + 1),
|
||||
};
|
||||
|
||||
code.push_back(Line::Choice(choice));
|
||||
code.push_back(choice);
|
||||
} else if self.settings.is_extensible {
|
||||
/*
|
||||
generate stub choice instructions for extensible
|
||||
@@ -1079,9 +1079,8 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
over them.
|
||||
*/
|
||||
|
||||
code.push_front(Line::Choice(self.settings.internal_try_me_else(0)));
|
||||
//Line::Choice(ChoiceInstruction::TryMeElse(0)));
|
||||
skip_stub_try_me_else = !self.settings.is_dynamic(); //true;
|
||||
code.push_front(self.settings.internal_try_me_else(0));
|
||||
skip_stub_try_me_else = !self.settings.is_dynamic();
|
||||
}
|
||||
|
||||
let arg = match clause.args() {
|
||||
@@ -1109,7 +1108,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
self.global_jmp_by_locs_offset = jmp_by_locs_len;
|
||||
|
||||
if !index_code.is_empty() {
|
||||
code.push_front(Line::IndexingCode(index_code));
|
||||
code.push_front(Instruction::IndexingCode(index_code));
|
||||
|
||||
if skip_stub_try_me_else {
|
||||
// skip the TryMeElse(0) also.
|
||||
@@ -1160,13 +1159,13 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
||||
_ => self.settings.retry_me_else(code_segment.len() + 1),
|
||||
};
|
||||
|
||||
code.push(Line::Choice(choice));
|
||||
code.push(choice);
|
||||
} else if self.settings.is_extensible {
|
||||
code.push(Line::Choice(self.settings.try_me_else(0)));
|
||||
code.push(self.settings.try_me_else(0));
|
||||
}
|
||||
|
||||
if self.settings.is_extensible {
|
||||
let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some();
|
||||
let segment_is_indexed = code_segment[0].to_indexing_line().is_some();
|
||||
|
||||
for clause_index_info in self.skeleton.clauses[skel_lower_bound..].iter_mut() {
|
||||
clause_index_info.clause_start +=
|
||||
|
||||
@@ -3,23 +3,26 @@ use indexmap::IndexMap;
|
||||
use crate::allocator::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::Level;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::targets::CompilationTarget;
|
||||
|
||||
use crate::temp_v;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::BTreeSet;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DebrayAllocator {
|
||||
bindings: IndexMap<Rc<String>, VarData>,
|
||||
bindings: IndexMap<Rc<String>, VarData, FxBuildHasher>,
|
||||
arg_c: usize,
|
||||
temp_lb: usize,
|
||||
arity: usize, // 0 if not at head.
|
||||
contents: IndexMap<usize, Rc<String>>,
|
||||
contents: IndexMap<usize, Rc<String>, FxBuildHasher>,
|
||||
in_use: BTreeSet<usize>,
|
||||
}
|
||||
|
||||
@@ -123,7 +126,7 @@ impl DebrayAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec<Target>)
|
||||
fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec<Instruction>)
|
||||
where
|
||||
Target: CompilationTarget<'a>,
|
||||
{
|
||||
@@ -152,7 +155,7 @@ impl DebrayAllocator {
|
||||
var: &String,
|
||||
lvl: Level,
|
||||
term_loc: GenContext,
|
||||
target: &mut Vec<Target>,
|
||||
target: &mut Vec<Instruction>,
|
||||
) -> usize
|
||||
where
|
||||
Target: CompilationTarget<'a>,
|
||||
@@ -160,7 +163,7 @@ impl DebrayAllocator {
|
||||
match term_loc {
|
||||
GenContext::Head => {
|
||||
if let Level::Shallow = lvl {
|
||||
self.evacuate_arg(0, target);
|
||||
self.evacuate_arg::<Target>(0, target);
|
||||
self.alloc_with_cr(var)
|
||||
} else {
|
||||
self.alloc_with_ca(var)
|
||||
@@ -169,7 +172,7 @@ impl DebrayAllocator {
|
||||
GenContext::Mid(_) => self.alloc_with_ca(var),
|
||||
GenContext::Last(chunk_num) => {
|
||||
if let Level::Shallow = lvl {
|
||||
self.evacuate_arg(chunk_num, target);
|
||||
self.evacuate_arg::<Target>(chunk_num, target);
|
||||
self.alloc_with_cr(var)
|
||||
} else {
|
||||
self.alloc_with_ca(var)
|
||||
@@ -210,13 +213,18 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
arity: 0,
|
||||
arg_c: 1,
|
||||
temp_lb: 1,
|
||||
bindings: IndexMap::new(),
|
||||
contents: IndexMap::new(),
|
||||
bindings: IndexMap::with_hasher(FxBuildHasher::default()),
|
||||
contents: IndexMap::with_hasher(FxBuildHasher::default()),
|
||||
in_use: BTreeSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn mark_anon_var<Target>(&mut self, lvl: Level, term_loc: GenContext, target: &mut Vec<Target>)
|
||||
fn mark_anon_var<Target>(
|
||||
&mut self,
|
||||
lvl: Level,
|
||||
term_loc: GenContext,
|
||||
target: &mut Vec<Instruction>,
|
||||
)
|
||||
where
|
||||
Target: CompilationTarget<'a>,
|
||||
{
|
||||
@@ -228,7 +236,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
let k = self.arg_c;
|
||||
|
||||
if let GenContext::Last(chunk_num) = term_loc {
|
||||
self.evacuate_arg(chunk_num, target);
|
||||
self.evacuate_arg::<Target>(chunk_num, target);
|
||||
}
|
||||
|
||||
self.arg_c += 1;
|
||||
@@ -243,7 +251,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
lvl: Level,
|
||||
term_loc: GenContext,
|
||||
cell: &Cell<RegType>,
|
||||
target: &mut Vec<Target>,
|
||||
target: &mut Vec<Instruction>,
|
||||
) where
|
||||
Target: CompilationTarget<'a>,
|
||||
{
|
||||
@@ -254,7 +262,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
let k = self.arg_c;
|
||||
|
||||
if let GenContext::Last(chunk_num) = term_loc {
|
||||
self.evacuate_arg(chunk_num, target);
|
||||
self.evacuate_arg::<Target>(chunk_num, target);
|
||||
}
|
||||
|
||||
self.arg_c += 1;
|
||||
@@ -270,20 +278,18 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
cell.set(r);
|
||||
}
|
||||
|
||||
fn mark_var<Target>(
|
||||
fn mark_var<Target: CompilationTarget<'a>>(
|
||||
&mut self,
|
||||
var: Rc<String>,
|
||||
lvl: Level,
|
||||
cell: &'a Cell<VarReg>,
|
||||
term_loc: GenContext,
|
||||
target: &mut Vec<Target>,
|
||||
) where
|
||||
Target: CompilationTarget<'a>,
|
||||
{
|
||||
target: &mut Vec<Instruction>,
|
||||
) {
|
||||
let (r, is_new_var) = match self.get(var.clone()) {
|
||||
RegType::Temp(0) => {
|
||||
// here, r is temporary *and* unassigned.
|
||||
let o = self.alloc_reg_to_var(&var, lvl, term_loc, target);
|
||||
let o = self.alloc_reg_to_var::<Target>(&var, lvl, term_loc, target);
|
||||
cell.set(VarReg::Norm(RegType::Temp(o)));
|
||||
|
||||
(RegType::Temp(o), true)
|
||||
@@ -297,27 +303,25 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
r => (r, false),
|
||||
};
|
||||
|
||||
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||
self.mark_reserved_var::<Target>(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||
}
|
||||
|
||||
fn mark_reserved_var<Target>(
|
||||
fn mark_reserved_var<Target: CompilationTarget<'a>>(
|
||||
&mut self,
|
||||
var: Rc<String>,
|
||||
lvl: Level,
|
||||
cell: &'a Cell<VarReg>,
|
||||
term_loc: GenContext,
|
||||
target: &mut Vec<Target>,
|
||||
target: &mut Vec<Instruction>,
|
||||
r: RegType,
|
||||
is_new_var: bool,
|
||||
) where
|
||||
Target: CompilationTarget<'a>,
|
||||
{
|
||||
) {
|
||||
match lvl {
|
||||
Level::Root | Level::Shallow => {
|
||||
let k = self.arg_c;
|
||||
|
||||
if self.is_curr_arg_distinct_from(&var) {
|
||||
self.evacuate_arg(term_loc.chunk_num(), target);
|
||||
self.evacuate_arg::<Target>(term_loc.chunk_num(), target);
|
||||
}
|
||||
|
||||
self.arg_c += 1;
|
||||
|
||||
@@ -272,10 +272,10 @@ impl UnsafeVarMarker {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) -> bool {
|
||||
pub(crate) fn mark_safe_vars(&mut self, query_instr: &Instruction) -> bool {
|
||||
match query_instr {
|
||||
&QueryInstruction::PutVariable(r @ RegType::Temp(_), _)
|
||||
| &QueryInstruction::SetVariable(r) => {
|
||||
&Instruction::PutVariable(r @ RegType::Temp(_), _) |
|
||||
&Instruction::SetVariable(r) => {
|
||||
self.safe_vars.insert(r);
|
||||
true
|
||||
}
|
||||
@@ -283,10 +283,10 @@ impl UnsafeVarMarker {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn mark_phase(&mut self, query_instr: &QueryInstruction, phase: usize) {
|
||||
pub(crate) fn mark_phase(&mut self, query_instr: &Instruction, phase: usize) {
|
||||
match query_instr {
|
||||
&QueryInstruction::PutValue(r @ RegType::Perm(_), _)
|
||||
| &QueryInstruction::SetValue(r) => {
|
||||
&Instruction::PutValue(r @ RegType::Perm(_), _) |
|
||||
&Instruction::SetValue(r) => {
|
||||
let p = self.unsafe_vars.entry(r).or_insert(0);
|
||||
*p = phase;
|
||||
}
|
||||
@@ -294,21 +294,21 @@ impl UnsafeVarMarker {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn mark_unsafe_vars(&mut self, query_instr: &mut QueryInstruction, phase: usize) {
|
||||
pub(crate) fn mark_unsafe_vars(&mut self, query_instr: &mut Instruction, phase: usize) {
|
||||
match query_instr {
|
||||
&mut QueryInstruction::PutValue(RegType::Perm(i), arg) => {
|
||||
&mut Instruction::PutValue(RegType::Perm(i), arg) => {
|
||||
if let Some(p) = self.unsafe_vars.swap_remove(&RegType::Perm(i)) {
|
||||
if p == phase {
|
||||
*query_instr = QueryInstruction::PutUnsafeValue(i, arg);
|
||||
*query_instr = Instruction::PutUnsafeValue(i, arg);
|
||||
self.safe_vars.insert(RegType::Perm(i));
|
||||
} else {
|
||||
self.unsafe_vars.insert(RegType::Perm(i), p);
|
||||
}
|
||||
}
|
||||
}
|
||||
&mut QueryInstruction::SetValue(r) => {
|
||||
&mut Instruction::SetValue(r) => {
|
||||
if !self.safe_vars.contains(&r) {
|
||||
*query_instr = QueryInstruction::SetLocalValue(r);
|
||||
*query_instr = Instruction::SetLocalValue(r);
|
||||
|
||||
self.safe_vars.insert(r);
|
||||
self.unsafe_vars.remove(&r);
|
||||
|
||||
61
src/forms.rs
61
src/forms.rs
@@ -1,17 +1,17 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::parser::CompositeOpDesc;
|
||||
use crate::parser::rug::{Integer, Rational};
|
||||
use crate::{is_infix, is_postfix};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::heap::*;
|
||||
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::rug::{Integer, Rational};
|
||||
use crate::types::*;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
@@ -19,10 +19,13 @@ use slice_deque::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::ops::AddAssign;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{is_infix, is_postfix};
|
||||
|
||||
pub type PredicateKey = (Atom, usize); // name, arity.
|
||||
|
||||
pub type Predicate = Vec<PredicateClause>;
|
||||
@@ -375,7 +378,6 @@ impl AtomOrString {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: try to rid yourself and the earth of the next two functions.
|
||||
pub(crate) fn fetch_atom_op_spec(
|
||||
name: Atom,
|
||||
spec: Option<OpDesc>,
|
||||
@@ -431,7 +433,7 @@ pub(crate) fn fetch_op_spec(name: Atom, arity: usize, op_dir: &OpDir) -> Option<
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type ModuleDir = IndexMap<Atom, Module>;
|
||||
pub(crate) type ModuleDir = IndexMap<Atom, Module, FxBuildHasher>;
|
||||
|
||||
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||
pub enum ModuleExport {
|
||||
@@ -464,11 +466,13 @@ impl Module {
|
||||
) -> Self {
|
||||
Module {
|
||||
module_decl,
|
||||
code_dir: CodeDir::new(),
|
||||
code_dir: CodeDir::with_hasher(FxBuildHasher::default()),
|
||||
op_dir: default_op_dir(),
|
||||
meta_predicates: MetaPredicateDir::new(),
|
||||
extensible_predicates: ExtensiblePredicates::new(),
|
||||
local_extensible_predicates: LocalExtensiblePredicates::new(),
|
||||
meta_predicates: MetaPredicateDir::with_hasher(FxBuildHasher::default()),
|
||||
extensible_predicates: ExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||
local_extensible_predicates: LocalExtensiblePredicates::with_hasher(
|
||||
FxBuildHasher::default(),
|
||||
),
|
||||
listing_src,
|
||||
}
|
||||
}
|
||||
@@ -476,11 +480,13 @@ impl Module {
|
||||
pub(crate) fn new_in_situ(module_decl: ModuleDecl) -> Self {
|
||||
Module {
|
||||
module_decl,
|
||||
code_dir: CodeDir::new(),
|
||||
op_dir: OpDir::new(),
|
||||
meta_predicates: MetaPredicateDir::new(),
|
||||
extensible_predicates: ExtensiblePredicates::new(),
|
||||
local_extensible_predicates: LocalExtensiblePredicates::new(),
|
||||
code_dir: CodeDir::with_hasher(FxBuildHasher::default()),
|
||||
op_dir: OpDir::with_hasher(FxBuildHasher::default()),
|
||||
meta_predicates: MetaPredicateDir::with_hasher(FxBuildHasher::default()),
|
||||
extensible_predicates: ExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||
local_extensible_predicates: LocalExtensiblePredicates::with_hasher(
|
||||
FxBuildHasher::default()
|
||||
),
|
||||
listing_src: ListingSource::DynamicallyGenerated,
|
||||
}
|
||||
}
|
||||
@@ -495,12 +501,22 @@ pub enum Number {
|
||||
}
|
||||
|
||||
impl Default for Number {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Number::Fixnum(Fixnum::build_with(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Number {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Number::Float(fl) => write!(f, "{}", fl),
|
||||
Number::Integer(n) => write!(f, "{}", n),
|
||||
Number::Rational(r) => write!(f, "{}", r),
|
||||
Number::Fixnum(n) => write!(f, "{}", n.get_num()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ArenaFrom<T> {
|
||||
fn arena_from(value: T, arena: &mut Arena) -> Self;
|
||||
}
|
||||
@@ -849,12 +865,3 @@ impl PredicateSkeleton {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) enum IndexingCodePtr {
|
||||
External(usize), // the index points past the indexing instruction prelude.
|
||||
DynamicExternal(usize), // an External index of a dynamic predicate, potentially invalidated by retraction.
|
||||
Fail,
|
||||
Internal(usize), // the index points into the indexing instruction prelude.
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::instructions::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::parser::rug::{Integer, Rational};
|
||||
use crate::{
|
||||
@@ -8,7 +9,6 @@ use crate::{
|
||||
sign_char, single_quote_char, small_letter_char, solo_char, variable_indicator_char,
|
||||
};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::heap::*;
|
||||
|
||||
@@ -1,919 +0,0 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::types::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_errors::MachineStub;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use slice_deque::SliceDeque;
|
||||
|
||||
fn reg_type_into_functor(r: RegType) -> MachineStub {
|
||||
match r {
|
||||
RegType::Temp(r) => functor!(atom!("x"), [fixnum(r)]),
|
||||
RegType::Perm(r) => functor!(atom!("y"), [fixnum(r)]),
|
||||
}
|
||||
}
|
||||
|
||||
impl Level {
|
||||
fn into_functor(self) -> MachineStub {
|
||||
match self {
|
||||
Level::Root => functor!(atom!("level"), [atom(atom!("root"))]),
|
||||
Level::Shallow => functor!(atom!("level"), [atom(atom!("shallow"))]),
|
||||
Level::Deep => functor!(atom!("level"), [atom(atom!("deep"))]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ArithmeticTerm {
|
||||
fn into_functor(&self, arena: &mut Arena) -> MachineStub {
|
||||
match self {
|
||||
&ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
||||
&ArithmeticTerm::Interm(i) => {
|
||||
functor!(atom!("intermediate"), [fixnum(i)])
|
||||
}
|
||||
&ArithmeticTerm::Number(n) => {
|
||||
vec![HeapCellValue::from((n, arena))]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) enum NextOrFail {
|
||||
Next(usize),
|
||||
Fail(usize),
|
||||
}
|
||||
|
||||
impl NextOrFail {
|
||||
#[inline]
|
||||
pub fn is_next(&self) -> bool {
|
||||
if let NextOrFail::Next(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub(crate) enum Death {
|
||||
Finite(usize),
|
||||
Infinity,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ChoiceInstruction {
|
||||
DynamicElse(usize, Death, NextOrFail),
|
||||
DynamicInternalElse(usize, Death, NextOrFail),
|
||||
DefaultRetryMeElse(usize),
|
||||
DefaultTrustMe(usize),
|
||||
RetryMeElse(usize),
|
||||
TrustMe(usize),
|
||||
TryMeElse(usize),
|
||||
}
|
||||
|
||||
impl ChoiceInstruction {
|
||||
pub(crate) fn to_functor(&self, h: usize) -> MachineStub {
|
||||
match self {
|
||||
&ChoiceInstruction::DynamicElse(birth, death, next_or_fail) => {
|
||||
match (death, next_or_fail) {
|
||||
(Death::Infinity, NextOrFail::Next(i)) => {
|
||||
functor!(
|
||||
atom!("dynamic_else"),
|
||||
[fixnum(birth), atom(atom!("inf")), fixnum(i)]
|
||||
)
|
||||
}
|
||||
(Death::Infinity, NextOrFail::Fail(i)) => {
|
||||
let next_functor = functor!(atom!("fail"), [fixnum(i)]);
|
||||
|
||||
functor!(
|
||||
atom!("dynamic_else"),
|
||||
[fixnum(birth), atom(atom!("inf")), str(h, 0)],
|
||||
[next_functor]
|
||||
)
|
||||
}
|
||||
(Death::Finite(d), NextOrFail::Fail(i)) => {
|
||||
let next_functor = functor!(atom!("fail"), [fixnum(i)]);
|
||||
|
||||
functor!(
|
||||
atom!("dynamic_else"),
|
||||
[fixnum(birth), fixnum(d), str(h, 0)],
|
||||
[next_functor]
|
||||
)
|
||||
}
|
||||
(Death::Finite(d), NextOrFail::Next(i)) => {
|
||||
functor!(atom!("dynamic_else"), [fixnum(birth), fixnum(d), fixnum(i)])
|
||||
}
|
||||
}
|
||||
}
|
||||
&ChoiceInstruction::DynamicInternalElse(birth, death, next_or_fail) => {
|
||||
match (death, next_or_fail) {
|
||||
(Death::Infinity, NextOrFail::Next(i)) => {
|
||||
functor!(
|
||||
atom!("dynamic_internal_else"),
|
||||
[fixnum(birth), atom(atom!("inf")), fixnum(i)]
|
||||
)
|
||||
}
|
||||
(Death::Infinity, NextOrFail::Fail(i)) => {
|
||||
let next_functor = functor!(atom!("fail"), [fixnum(i)]);
|
||||
|
||||
functor!(
|
||||
atom!("dynamic_internal_else"),
|
||||
[fixnum(birth), atom(atom!("inf")), str(h, 0)],
|
||||
[next_functor]
|
||||
)
|
||||
}
|
||||
(Death::Finite(d), NextOrFail::Fail(i)) => {
|
||||
let next_functor = functor!(atom!("fail"), [fixnum(i)]);
|
||||
|
||||
functor!(
|
||||
atom!("dynamic_internal_else"),
|
||||
[fixnum(birth), fixnum(d), str(h, 0)],
|
||||
[next_functor]
|
||||
)
|
||||
}
|
||||
(Death::Finite(d), NextOrFail::Next(i)) => {
|
||||
functor!(
|
||||
atom!("dynamic_internal_else"),
|
||||
[fixnum(birth), fixnum(d), fixnum(i)]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
&ChoiceInstruction::TryMeElse(offset) => {
|
||||
functor!(atom!("try_me_else"), [fixnum(offset)])
|
||||
}
|
||||
&ChoiceInstruction::RetryMeElse(offset) => {
|
||||
functor!(atom!("retry_me_else"), [fixnum(offset)])
|
||||
}
|
||||
&ChoiceInstruction::TrustMe(offset) => {
|
||||
functor!(atom!("trust_me"), [fixnum(offset)])
|
||||
}
|
||||
&ChoiceInstruction::DefaultRetryMeElse(offset) => {
|
||||
functor!(atom!("default_retry_me_else"), [fixnum(offset)])
|
||||
}
|
||||
&ChoiceInstruction::DefaultTrustMe(offset) => {
|
||||
functor!(atom!("default_trust_me"), [fixnum(offset)])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum CutInstruction {
|
||||
Cut(RegType),
|
||||
GetLevel(RegType),
|
||||
GetLevelAndUnify(RegType),
|
||||
NeckCut,
|
||||
}
|
||||
|
||||
impl CutInstruction {
|
||||
pub(crate) fn to_functor(&self, h: usize) -> MachineStub {
|
||||
match self {
|
||||
&CutInstruction::Cut(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
functor!(atom!("cut"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&CutInstruction::GetLevel(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
functor!(atom!("get_level"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&CutInstruction::GetLevelAndUnify(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
functor!(atom!("get_level_and_unify"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&CutInstruction::NeckCut => {
|
||||
functor!(atom!("neck_cut"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) enum IndexedChoiceInstruction {
|
||||
Retry(usize),
|
||||
Trust(usize),
|
||||
Try(usize),
|
||||
}
|
||||
|
||||
impl IndexedChoiceInstruction {
|
||||
pub(crate) fn offset(&self) -> usize {
|
||||
match self {
|
||||
&IndexedChoiceInstruction::Retry(offset) => offset,
|
||||
&IndexedChoiceInstruction::Trust(offset) => offset,
|
||||
&IndexedChoiceInstruction::Try(offset) => offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_functor(&self) -> MachineStub {
|
||||
match self {
|
||||
&IndexedChoiceInstruction::Try(offset) => {
|
||||
functor!(atom!("try"), [fixnum(offset)])
|
||||
}
|
||||
&IndexedChoiceInstruction::Trust(offset) => {
|
||||
functor!(atom!("trust"), [fixnum(offset)])
|
||||
}
|
||||
&IndexedChoiceInstruction::Retry(offset) => {
|
||||
functor!(atom!("retry"), [fixnum(offset)])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A `Line` is an instruction (cf. page 98 of wambook).
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum IndexingLine {
|
||||
Indexing(IndexingInstruction),
|
||||
IndexedChoice(SliceDeque<IndexedChoiceInstruction>),
|
||||
DynamicIndexedChoice(SliceDeque<usize>),
|
||||
}
|
||||
|
||||
impl From<IndexingInstruction> for IndexingLine {
|
||||
#[inline]
|
||||
fn from(instr: IndexingInstruction) -> Self {
|
||||
IndexingLine::Indexing(instr)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SliceDeque<IndexedChoiceInstruction>> for IndexingLine {
|
||||
#[inline]
|
||||
fn from(instrs: SliceDeque<IndexedChoiceInstruction>) -> Self {
|
||||
IndexingLine::IndexedChoice(instrs)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Line {
|
||||
Arithmetic(ArithmeticInstruction),
|
||||
Choice(ChoiceInstruction),
|
||||
Control(ControlInstruction),
|
||||
Cut(CutInstruction),
|
||||
Fact(FactInstruction),
|
||||
IndexingCode(Vec<IndexingLine>),
|
||||
IndexedChoice(IndexedChoiceInstruction),
|
||||
DynamicIndexedChoice(usize),
|
||||
Query(QueryInstruction),
|
||||
}
|
||||
|
||||
impl Line {
|
||||
#[inline]
|
||||
pub(crate) fn is_head_instr(&self) -> bool {
|
||||
match self {
|
||||
&Line::Fact(_) => true,
|
||||
&Line::Query(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enqueue_functors(
|
||||
&self,
|
||||
mut h: usize,
|
||||
arena: &mut Arena,
|
||||
functors: &mut Vec<MachineStub>,
|
||||
) {
|
||||
match self {
|
||||
&Line::Arithmetic(ref arith_instr) => {
|
||||
functors.push(arith_instr.to_functor(h, arena))
|
||||
}
|
||||
&Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor(h)),
|
||||
&Line::Control(ref control_instr) => functors.push(control_instr.to_functor()),
|
||||
&Line::Cut(ref cut_instr) => functors.push(cut_instr.to_functor(h)),
|
||||
&Line::Fact(ref fact_instr) => functors.push(fact_instr.to_functor(h)),
|
||||
&Line::IndexingCode(ref indexing_instrs) => {
|
||||
for indexing_instr in indexing_instrs {
|
||||
match indexing_instr {
|
||||
IndexingLine::Indexing(indexing_instr) => {
|
||||
let section = indexing_instr.to_functor(h);
|
||||
h += section.len();
|
||||
functors.push(section);
|
||||
}
|
||||
IndexingLine::IndexedChoice(indexed_choice_instrs) => {
|
||||
for indexed_choice_instr in indexed_choice_instrs {
|
||||
let section = indexed_choice_instr.to_functor();
|
||||
h += section.len();
|
||||
functors.push(section);
|
||||
}
|
||||
}
|
||||
IndexingLine::DynamicIndexedChoice(indexed_choice_instrs) => {
|
||||
for indexed_choice_instr in indexed_choice_instrs {
|
||||
let section = functor!(
|
||||
atom!("dynamic"),
|
||||
[fixnum(*indexed_choice_instr)]
|
||||
);
|
||||
|
||||
h += section.len();
|
||||
functors.push(section);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&Line::IndexedChoice(ref indexed_choice_instr) => {
|
||||
functors.push(indexed_choice_instr.to_functor())
|
||||
}
|
||||
&Line::DynamicIndexedChoice(ref indexed_choice_instr) => {
|
||||
functors.push(functor!(atom!("dynamic"), [fixnum(*indexed_choice_instr)]));
|
||||
}
|
||||
&Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
||||
match line {
|
||||
Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
||||
match line {
|
||||
Line::IndexingCode(ref indexing_code) => Some(indexing_code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ArithmeticInstruction {
|
||||
Add(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Sub(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Mul(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Pow(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
IntPow(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
IDiv(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Max(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Min(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
IntFloorDiv(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
RDiv(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Div(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Shl(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Shr(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Xor(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
And(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Or(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Mod(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Rem(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Gcd(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Sign(ArithmeticTerm, usize),
|
||||
Cos(ArithmeticTerm, usize),
|
||||
Sin(ArithmeticTerm, usize),
|
||||
Tan(ArithmeticTerm, usize),
|
||||
Log(ArithmeticTerm, usize),
|
||||
Exp(ArithmeticTerm, usize),
|
||||
ACos(ArithmeticTerm, usize),
|
||||
ASin(ArithmeticTerm, usize),
|
||||
ATan(ArithmeticTerm, usize),
|
||||
ATan2(ArithmeticTerm, ArithmeticTerm, usize),
|
||||
Sqrt(ArithmeticTerm, usize),
|
||||
Abs(ArithmeticTerm, usize),
|
||||
Float(ArithmeticTerm, usize),
|
||||
Truncate(ArithmeticTerm, usize),
|
||||
Round(ArithmeticTerm, usize),
|
||||
Ceiling(ArithmeticTerm, usize),
|
||||
Floor(ArithmeticTerm, usize),
|
||||
Neg(ArithmeticTerm, usize),
|
||||
Plus(ArithmeticTerm, usize),
|
||||
BitwiseComplement(ArithmeticTerm, usize),
|
||||
}
|
||||
|
||||
fn arith_instr_unary_functor(
|
||||
h: usize,
|
||||
name: Atom,
|
||||
arena: &mut Arena,
|
||||
at: &ArithmeticTerm,
|
||||
t: usize,
|
||||
) -> MachineStub {
|
||||
let at_stub = at.into_functor(arena);
|
||||
functor!(name, [str(h, 0), fixnum(t)], [at_stub])
|
||||
}
|
||||
|
||||
fn arith_instr_bin_functor(
|
||||
h: usize,
|
||||
name: Atom,
|
||||
arena: &mut Arena,
|
||||
at_1: &ArithmeticTerm,
|
||||
at_2: &ArithmeticTerm,
|
||||
t: usize,
|
||||
) -> MachineStub {
|
||||
let at_1_stub = at_1.into_functor(arena);
|
||||
let at_2_stub = at_2.into_functor(arena);
|
||||
|
||||
functor!(
|
||||
name,
|
||||
[str(h, 0), str(h, 1), fixnum(t)],
|
||||
[at_1_stub, at_2_stub]
|
||||
)
|
||||
}
|
||||
|
||||
impl ArithmeticInstruction {
|
||||
pub(crate) fn to_functor(
|
||||
&self,
|
||||
h: usize,
|
||||
arena: &mut Arena,
|
||||
) -> MachineStub {
|
||||
match self {
|
||||
&ArithmeticInstruction::Add(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("add"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sub(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("sub"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Mul(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("mul"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::IntPow(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("int_pow"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Pow(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("pow"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::IDiv(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("idiv"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Max(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("max"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Min(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("min"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::IntFloorDiv(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("int_floor_div"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::RDiv(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("rdiv"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Div(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("div"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Shl(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("shl"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Shr(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("shr"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Xor(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("xor"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::And(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("and"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Or(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("or"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Mod(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("mod"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Rem(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("rem"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::ATan2(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("rem"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, atom!("gcd"), arena, at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sign(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("sign"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Cos(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("cos"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sin(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("sin"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Tan(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("tan"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Log(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("log"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Exp(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("exp"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::ACos(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("acos"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::ASin(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("asin"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::ATan(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("atan"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sqrt(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("sqrt"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Abs(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("abs"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Float(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("float"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Truncate(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("truncate"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Round(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("round"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Ceiling(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("ceiling"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Floor(ref at, t) => {
|
||||
arith_instr_unary_functor(h, atom!("floor"), arena, at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(
|
||||
h,
|
||||
atom!("-"),
|
||||
arena,
|
||||
at,
|
||||
t,
|
||||
),
|
||||
&ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(
|
||||
h,
|
||||
atom!("+"),
|
||||
arena,
|
||||
at,
|
||||
t,
|
||||
),
|
||||
&ArithmeticInstruction::BitwiseComplement(ref at, t) => arith_instr_unary_functor(
|
||||
h,
|
||||
atom!("\\"),
|
||||
arena,
|
||||
at,
|
||||
t,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ControlInstruction {
|
||||
Allocate(usize), // num_frames.
|
||||
// name, arity, perm_vars after threshold, last call, use default call policy.
|
||||
CallClause(ClauseType, usize, usize, bool, bool),
|
||||
Deallocate,
|
||||
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
||||
RevJmpBy(usize), // notice the lack of context change as in
|
||||
// JmpBy. RevJmpBy is used only to patch extensible
|
||||
// predicates together.
|
||||
Proceed,
|
||||
}
|
||||
|
||||
impl ControlInstruction {
|
||||
pub(crate) fn perm_vars(&self) -> Option<usize> {
|
||||
match self {
|
||||
ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
|
||||
ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_functor(&self) -> MachineStub {
|
||||
match self {
|
||||
&ControlInstruction::Allocate(num_frames) => {
|
||||
functor!(atom!("allocate"), [fixnum(num_frames)])
|
||||
}
|
||||
&ControlInstruction::CallClause(ref ct, arity, _, false, _) => {
|
||||
functor!(atom!("call"), [atom(ct.name()), fixnum(arity)])
|
||||
}
|
||||
&ControlInstruction::CallClause(ref ct, arity, _, true, _) => {
|
||||
functor!(atom!("execute"), [atom(ct.name()), fixnum(arity)])
|
||||
}
|
||||
&ControlInstruction::Deallocate => {
|
||||
functor!(atom!("deallocate"))
|
||||
}
|
||||
&ControlInstruction::JmpBy(_, offset, ..) => {
|
||||
functor!(atom!("jmp_by"), [fixnum(offset)])
|
||||
}
|
||||
&ControlInstruction::RevJmpBy(offset) => {
|
||||
functor!(atom!("rev_jmp_by"), [fixnum(offset)])
|
||||
}
|
||||
&ControlInstruction::Proceed => {
|
||||
functor!(atom!("proceed"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `IndexingInstruction` cf. page 110 of wambook.
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum IndexingInstruction {
|
||||
// The first index is the optimal argument being indexed.
|
||||
SwitchOnTerm(
|
||||
usize,
|
||||
IndexingCodePtr,
|
||||
IndexingCodePtr,
|
||||
IndexingCodePtr,
|
||||
IndexingCodePtr,
|
||||
),
|
||||
SwitchOnConstant(IndexMap<Literal, IndexingCodePtr>),
|
||||
SwitchOnStructure(IndexMap<(Atom, usize), IndexingCodePtr>),
|
||||
}
|
||||
|
||||
impl IndexingCodePtr {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn to_functor(self) -> MachineStub {
|
||||
match self {
|
||||
IndexingCodePtr::DynamicExternal(o) => functor!(atom!("dynamic_external"), [fixnum(o)]),
|
||||
IndexingCodePtr::External(o) => functor!(atom!("external"), [fixnum(o)]),
|
||||
IndexingCodePtr::Internal(o) => functor!(atom!("internal"), [fixnum(o)]),
|
||||
IndexingCodePtr::Fail => {
|
||||
vec![atom_as_cell!(atom!("fail"))]
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexingInstruction {
|
||||
pub(crate) fn to_functor(&self, mut h: usize) -> MachineStub {
|
||||
match self {
|
||||
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
||||
functor!(
|
||||
atom!("switch_on_term"),
|
||||
[
|
||||
fixnum(arg),
|
||||
indexing_code_ptr(h, vars),
|
||||
indexing_code_ptr(h, constants),
|
||||
indexing_code_ptr(h, lists),
|
||||
indexing_code_ptr(h, structures)
|
||||
]
|
||||
)
|
||||
}
|
||||
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
||||
let mut key_value_list_stub = vec![];
|
||||
let orig_h = h;
|
||||
|
||||
h += 2; // skip the 2-cell "switch_on_constant" functor.
|
||||
|
||||
for (c, ptr) in constants.iter() {
|
||||
let key_value_pair = functor!(
|
||||
atom!(":"),
|
||||
[literal(*c), indexing_code_ptr(h + 3, *ptr)]
|
||||
);
|
||||
|
||||
key_value_list_stub.push(list_loc_as_cell!(h + 1));
|
||||
key_value_list_stub.push(str_loc_as_cell!(h + 3));
|
||||
key_value_list_stub.push(heap_loc_as_cell!(h + 3 + key_value_pair.len()));
|
||||
|
||||
h += key_value_pair.len() + 3;
|
||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||
}
|
||||
|
||||
key_value_list_stub.push(empty_list_as_cell!());
|
||||
|
||||
functor!(
|
||||
atom!("switch_on_constant"),
|
||||
[str(orig_h, 0)],
|
||||
[key_value_list_stub]
|
||||
)
|
||||
}
|
||||
&IndexingInstruction::SwitchOnStructure(ref structures) => {
|
||||
let mut key_value_list_stub = vec![];
|
||||
let orig_h = h;
|
||||
|
||||
h += 2; // skip the 2-cell "switch_on_constant" functor.
|
||||
|
||||
for ((name, arity), ptr) in structures.iter() {
|
||||
let predicate_indicator_stub = functor!(
|
||||
atom!("/"),
|
||||
[atom(name), fixnum(*arity)]
|
||||
);
|
||||
|
||||
let key_value_pair = functor!(
|
||||
atom!(":"),
|
||||
[str(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
|
||||
[predicate_indicator_stub]
|
||||
);
|
||||
|
||||
key_value_list_stub.push(list_loc_as_cell!(h + 1));
|
||||
key_value_list_stub.push(str_loc_as_cell!(h + 3));
|
||||
key_value_list_stub.push(heap_loc_as_cell!(h + 3 + key_value_pair.len()));
|
||||
|
||||
h += key_value_pair.len() + 3;
|
||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||
}
|
||||
|
||||
key_value_list_stub.push(empty_list_as_cell!());
|
||||
|
||||
functor!(
|
||||
atom!("switch_on_structure"),
|
||||
[str(orig_h, 0)],
|
||||
[key_value_list_stub]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FactInstruction {
|
||||
GetConstant(Level, HeapCellValue, RegType),
|
||||
GetList(Level, RegType),
|
||||
GetPartialString(Level, Atom, RegType, bool),
|
||||
GetStructure(ClauseType, usize, RegType),
|
||||
GetValue(RegType, usize),
|
||||
GetVariable(RegType, usize),
|
||||
UnifyConstant(HeapCellValue),
|
||||
UnifyLocalValue(RegType),
|
||||
UnifyVariable(RegType),
|
||||
UnifyValue(RegType),
|
||||
UnifyVoid(usize),
|
||||
}
|
||||
|
||||
impl FactInstruction {
|
||||
pub(crate) fn to_functor(&self, h: usize) -> MachineStub {
|
||||
match self {
|
||||
&FactInstruction::GetConstant(lvl, c, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("get_constant"),
|
||||
[str(h, 0), cell(c), str(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
&FactInstruction::GetList(lvl, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("get_list"),
|
||||
[str(h, 0), str(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
&FactInstruction::GetPartialString(lvl, s, r, has_tail) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("get_partial_string"),
|
||||
[
|
||||
str(h, 0),
|
||||
string(h, s),
|
||||
str(h, 1),
|
||||
boolean(has_tail)
|
||||
],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
&FactInstruction::GetStructure(ref ct, arity, r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("get_structure"),
|
||||
[atom(ct.name()), fixnum(arity), str(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
}
|
||||
&FactInstruction::GetValue(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("get_value"), [str(h, 0), fixnum(arg)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::GetVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("get_variable"), [str(h, 0), fixnum(arg)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyConstant(c) => {
|
||||
functor!(atom!("unify_constant"), [cell(c)])
|
||||
}
|
||||
&FactInstruction::UnifyLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("unify_local_value"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyVariable(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("unify_variable"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("unify_value"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyVoid(vars) => {
|
||||
functor!(atom!("unify_void"), [fixnum(vars)])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum QueryInstruction {
|
||||
GetVariable(RegType, usize),
|
||||
PutConstant(Level, HeapCellValue, RegType),
|
||||
PutList(Level, RegType),
|
||||
PutPartialString(Level, Atom, RegType, bool),
|
||||
PutStructure(ClauseType, usize, RegType),
|
||||
PutUnsafeValue(usize, usize),
|
||||
PutValue(RegType, usize),
|
||||
PutVariable(RegType, usize),
|
||||
SetConstant(HeapCellValue),
|
||||
SetLocalValue(RegType),
|
||||
SetVariable(RegType),
|
||||
SetValue(RegType),
|
||||
SetVoid(usize),
|
||||
}
|
||||
|
||||
impl QueryInstruction {
|
||||
pub(crate) fn to_functor(&self, h: usize) -> MachineStub {
|
||||
match self {
|
||||
&QueryInstruction::PutUnsafeValue(norm, arg) => {
|
||||
functor!(atom!("put_unsafe_value"), [fixnum(norm), fixnum(arg)])
|
||||
}
|
||||
&QueryInstruction::PutConstant(lvl, c, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("put_constant"),
|
||||
[str(h, 0), cell(c), str(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
&QueryInstruction::PutList(lvl, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("put_list"),
|
||||
[str(h, 0), str(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
&QueryInstruction::PutPartialString(lvl, s, r, has_tail) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("put_partial_string"),
|
||||
[
|
||||
str(h, 0),
|
||||
string(h, s),
|
||||
str(h, 1),
|
||||
boolean(has_tail)
|
||||
],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
}
|
||||
&QueryInstruction::PutStructure(ref ct, arity, r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
atom!("put_structure"),
|
||||
[atom(ct.name()), fixnum(arity), str(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
}
|
||||
&QueryInstruction::PutValue(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("put_value"), [str(h, 0), fixnum(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::GetVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("get_variable"), [str(h, 0), fixnum(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::PutVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("put_variable"), [str(h, 0), fixnum(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetConstant(c) => {
|
||||
functor!(atom!("set_constant"), [cell(c)], [])
|
||||
}
|
||||
&QueryInstruction::SetLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("set_local_value"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetVariable(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("set_variable"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(atom!("set_value"), [str(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetVoid(vars) => {
|
||||
functor!(atom!("set_void"), [fixnum(vars)])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type CompiledFact = Vec<FactInstruction>;
|
||||
|
||||
pub(crate) type Code = Vec<Line>;
|
||||
@@ -1,9 +1,8 @@
|
||||
use crate::atom_table::*;
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -52,7 +51,7 @@ impl<'a> TermIterState<'a> {
|
||||
match term {
|
||||
Term::AnonVar => TermIterState::AnonVar(lvl),
|
||||
Term::Clause(cell, name, subterms) => {
|
||||
let ct = ClauseType::Named(name.clone(), subterms.len(), CodeIndex::default());
|
||||
let ct = ClauseType::Named(subterms.len(), *name, CodeIndex::default());
|
||||
TermIterState::Clause(lvl, 0, cell, ct, subterms)
|
||||
}
|
||||
Term::Cons(cell, head, tail) => {
|
||||
@@ -112,8 +111,8 @@ impl<'a> QueryIterator<'a> {
|
||||
|
||||
fn new(term: &'a QueryTerm) -> Self {
|
||||
match term {
|
||||
&QueryTerm::Clause(ref cell, ClauseType::CallN, ref terms, _) => {
|
||||
let state = TermIterState::Clause(Level::Root, 1, cell, ClauseType::CallN, terms);
|
||||
&QueryTerm::Clause(ref cell, ClauseType::CallN(arity), ref terms, _) => {
|
||||
let state = TermIterState::Clause(Level::Root, 1, cell, ClauseType::CallN(arity), terms);
|
||||
QueryIterator {
|
||||
state_stack: vec![state],
|
||||
}
|
||||
@@ -164,7 +163,7 @@ impl<'a> Iterator for QueryIterator<'a> {
|
||||
TermIterState::Clause(lvl, child_num, cell, ct, child_terms) => {
|
||||
if child_num == child_terms.len() {
|
||||
match ct {
|
||||
ClauseType::CallN => {
|
||||
ClauseType::CallN(_) => {
|
||||
self.push_subterm(Level::Shallow, &child_terms[0]);
|
||||
}
|
||||
ClauseType::Named(..) => {
|
||||
@@ -499,7 +498,7 @@ impl<'a> ChunkedIterator<'a> {
|
||||
}
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::Clause(
|
||||
_,
|
||||
ClauseType::CallN,
|
||||
ClauseType::CallN(_),
|
||||
ref subterms,
|
||||
_,
|
||||
)) => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![recursion_limit = "4112"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate static_assertions;
|
||||
|
||||
@@ -11,7 +13,6 @@ pub mod arena;
|
||||
pub mod parser;
|
||||
mod allocator;
|
||||
mod arithmetic;
|
||||
mod clause_types;
|
||||
pub mod codegen;
|
||||
mod debray_allocator;
|
||||
mod fixtures;
|
||||
@@ -19,7 +20,8 @@ mod forms;
|
||||
mod heap_iter;
|
||||
pub mod heap_print;
|
||||
mod indexing;
|
||||
mod instructions;
|
||||
#[macro_use]
|
||||
pub mod instructions;
|
||||
mod iterators;
|
||||
pub mod machine;
|
||||
mod raw_block;
|
||||
|
||||
@@ -12,9 +12,7 @@ between(Lower, Upper, X) :-
|
||||
( nonvar(X) ->
|
||||
Lower =< X,
|
||||
X =< Upper
|
||||
; % compare(Ord, Lower, Upper),
|
||||
% between_(Ord, Lower, Upper, X)
|
||||
Lower =< Upper,
|
||||
; Lower =< Upper,
|
||||
between_(Lower, Upper, X)
|
||||
).
|
||||
|
||||
@@ -27,16 +25,6 @@ between_(Lower, Upper, Lower1) :-
|
||||
)
|
||||
).
|
||||
|
||||
/*
|
||||
between_(<, Lower0, Upper, X) :-
|
||||
( X = Lower0
|
||||
; Lower1 is Lower0 + 1,
|
||||
compare(Ord, Lower1, Upper),
|
||||
between_(Ord, Lower1, Upper, X)
|
||||
).
|
||||
between_(=, Upper, Upper, Upper).
|
||||
*/
|
||||
|
||||
enumerate_nats(I, I).
|
||||
enumerate_nats(I0, N) :-
|
||||
I1 is I0 + 1,
|
||||
|
||||
@@ -59,15 +59,13 @@ call(G, A, B, C, D, E, F, G) :- '$call'(G, A, B, C, D, E, F, G).
|
||||
|
||||
call(G, A, B, C, D, E, F, G, H) :- '$call'(G, A, B, C, D, E, F, G, H).
|
||||
|
||||
% dynamic module resolution.
|
||||
|
||||
Module : Predicate :-
|
||||
( atom(Module) -> '$module_call'(Module, Predicate)
|
||||
; throw(error(type_error(atom, Module), (:)/2))
|
||||
).
|
||||
|
||||
|
||||
% dynamic module resolution.
|
||||
|
||||
:(Module, Predicate, A1) :-
|
||||
( atom(Module) ->
|
||||
'$module_call'(A1, Module, Predicate)
|
||||
|
||||
@@ -56,13 +56,16 @@ length(Xs, N) :-
|
||||
!,
|
||||
'$skip_max_list'(M, -1, Xs, Xs0),
|
||||
( Xs0 == [] -> N = M
|
||||
; var(Xs0) -> length_addendum(Xs0, N, M)).
|
||||
; var(Xs0) -> length_addendum(Xs0, N, M)
|
||||
).
|
||||
length(Xs, N) :-
|
||||
integer(N),
|
||||
N >= 0, !,
|
||||
N >= 0,
|
||||
!,
|
||||
'$skip_max_list'(M, N, Xs, Xs0),
|
||||
( Xs0 == [] -> N = M
|
||||
; var(Xs0) -> R is N-M, length_rundown(Xs0, R)).
|
||||
; var(Xs0) -> R is N-M, length_rundown(Xs0, R)
|
||||
).
|
||||
length(_, N) :-
|
||||
integer(N), !,
|
||||
domain_error(not_less_than_zero, N, length/2).
|
||||
|
||||
@@ -90,7 +90,6 @@ unload_evacuable(Evacuable) :-
|
||||
run_initialization_goals(Module) :-
|
||||
( predicate_property(Module:'$initialization_goals'(_), dynamic) ->
|
||||
% FIXME: failing here. also, see add_module.
|
||||
'$debug_hook',
|
||||
findall(Module:Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals),
|
||||
abolish(Module:'$initialization_goals'/1),
|
||||
( maplist(Module:call, Goals) ->
|
||||
@@ -543,15 +542,15 @@ use_module(Module, Exports, Evacuable) :-
|
||||
|
||||
|
||||
check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm) :-
|
||||
'$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
||||
'$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
||||
check_predicate_property(built_in, _, Name, Arity, built_in) :-
|
||||
'$cpp_built_in_property'(Name, Arity).
|
||||
'$built_in_property'(Name, Arity).
|
||||
check_predicate_property(dynamic, Module, Name, Arity, dynamic) :-
|
||||
'$cpp_dynamic_property'(Module, Name, Arity).
|
||||
'$dynamic_property'(Module, Name, Arity).
|
||||
check_predicate_property(multifile, Module, Name, Arity, multifile) :-
|
||||
'$cpp_multifile_property'(Module, Name, Arity).
|
||||
'$multifile_property'(Module, Name, Arity).
|
||||
check_predicate_property(discontiguous, Module, Name, Arity, discontiguous) :-
|
||||
'$cpp_discontiguous_property'(Module, Name, Arity).
|
||||
'$discontiguous_property'(Module, Name, Arity).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ use divrem::*;
|
||||
use crate::arena::*;
|
||||
use crate::arithmetic::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
|
||||
@@ -15,8 +15,9 @@ pub(super) type Bindings = Vec<(usize, HeapCellValue)>;
|
||||
pub(super) struct AttrVarInitializer {
|
||||
pub(super) attr_var_queue: Vec<usize>,
|
||||
pub(super) bindings: Bindings,
|
||||
pub(super) cp: LocalCodePtr,
|
||||
pub(super) instigating_p: LocalCodePtr,
|
||||
pub(super) p: usize,
|
||||
pub(super) cp: usize,
|
||||
// pub(super) instigating_p: usize,
|
||||
pub(super) verify_attrs_loc: usize,
|
||||
}
|
||||
|
||||
@@ -25,8 +26,8 @@ impl AttrVarInitializer {
|
||||
AttrVarInitializer {
|
||||
attr_var_queue: vec![],
|
||||
bindings: vec![],
|
||||
instigating_p: LocalCodePtr::default(),
|
||||
cp: LocalCodePtr::default(),
|
||||
p: 0,
|
||||
cp: 0,
|
||||
verify_attrs_loc,
|
||||
}
|
||||
}
|
||||
@@ -41,15 +42,14 @@ impl AttrVarInitializer {
|
||||
impl MachineState {
|
||||
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: HeapCellValue) {
|
||||
if self.attr_var_init.bindings.is_empty() {
|
||||
self.attr_var_init.instigating_p = self.p.local();
|
||||
// save self.p and self.cp and ensure that the next
|
||||
// instruction is InstallVerifyAttrInterrupt.
|
||||
|
||||
if self.last_call {
|
||||
self.attr_var_init.p = self.p;
|
||||
self.attr_var_init.cp = self.cp;
|
||||
} else {
|
||||
self.attr_var_init.cp = self.p.local() + 1;
|
||||
}
|
||||
|
||||
self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc);
|
||||
self.p = INSTALL_VERIFY_ATTR_INTERRUPT - 1;
|
||||
self.cp = INSTALL_VERIFY_ATTR_INTERRUPT;
|
||||
}
|
||||
|
||||
self.attr_var_init.bindings.push((h, addr));
|
||||
@@ -109,25 +109,27 @@ impl MachineState {
|
||||
}
|
||||
|
||||
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
||||
self.allocate(self.num_of_args + 2);
|
||||
self.allocate(self.num_of_args + 3);
|
||||
|
||||
let e = self.e;
|
||||
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
|
||||
let and_frame = self.stack.index_and_frame_mut(e);
|
||||
|
||||
for i in 1..self.num_of_args + 1 {
|
||||
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
||||
and_frame[i] = self.registers[i];
|
||||
}
|
||||
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] =
|
||||
and_frame[self.num_of_args + 1] =
|
||||
fixnum_as_cell!(Fixnum::build_with(self.b0 as i64));
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] =
|
||||
and_frame[self.num_of_args + 2] =
|
||||
fixnum_as_cell!(Fixnum::build_with(self.num_of_args as i64));
|
||||
and_frame[self.num_of_args + 3] =
|
||||
fixnum_as_cell!(Fixnum::build_with(self.attr_var_init.cp as i64));
|
||||
|
||||
self.verify_attributes();
|
||||
|
||||
self.num_of_args = 2;
|
||||
self.num_of_args = 3;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
||||
self.p = p;
|
||||
}
|
||||
|
||||
pub(super) fn attr_vars_of_term(&mut self, cell: HeapCellValue) -> Vec<HeapCellValue> {
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
use crate::clause_types::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::{Machine, MachineState};
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub(crate) enum OwnedOrIndexed {
|
||||
Indexed(usize),
|
||||
Owned(Line),
|
||||
}
|
||||
|
||||
impl fmt::Debug for OwnedOrIndexed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&OwnedOrIndexed::Indexed(ref index) => write!(f, "Indexed({:?})", index),
|
||||
&OwnedOrIndexed::Owned(ref owned) => write!(f, "Owned({:?})", owned),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OwnedOrIndexed {
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_ref<'a>(&'a self, code: &'a Code) -> &'a Line {
|
||||
match self {
|
||||
&OwnedOrIndexed::Indexed(p) => &code[p],
|
||||
&OwnedOrIndexed::Owned(ref r) => r,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: remove this, replace with just 'Code'.
|
||||
#[derive(Debug)]
|
||||
pub struct CodeRepo {
|
||||
pub(super) code: Code,
|
||||
}
|
||||
|
||||
impl CodeRepo {
|
||||
pub(super) fn lookup_instr(&self, machine_st: &MachineState, p: &CodePtr) -> Option<OwnedOrIndexed> {
|
||||
match p {
|
||||
&CodePtr::Local(local) => {
|
||||
return Some(self.lookup_local_instr(machine_st, local));
|
||||
}
|
||||
&CodePtr::REPL(..) => None,
|
||||
&CodePtr::BuiltInClause(ref built_in, _) => {
|
||||
let call_clause = call_clause!(
|
||||
ClauseType::BuiltIn(built_in.clone()),
|
||||
built_in.arity(),
|
||||
0,
|
||||
machine_st.last_call
|
||||
);
|
||||
|
||||
Some(OwnedOrIndexed::Owned(call_clause))
|
||||
}
|
||||
&CodePtr::CallN(arity, _, last_call) => {
|
||||
let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call);
|
||||
Some(OwnedOrIndexed::Owned(call_clause))
|
||||
}
|
||||
&CodePtr::VerifyAttrInterrupt(p) => Some(OwnedOrIndexed::Indexed(p)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn lookup_local_instr(&self, machine_st: &MachineState, p: LocalCodePtr) -> OwnedOrIndexed {
|
||||
match p {
|
||||
LocalCodePtr::Halt => {
|
||||
// exit with the interrupt exit code.
|
||||
std::process::exit(1);
|
||||
}
|
||||
LocalCodePtr::DirEntry(p) => match &self.code[p] {
|
||||
&Line::IndexingCode(ref indexing_lines) => {
|
||||
match &indexing_lines[machine_st.oip as usize] {
|
||||
&IndexingLine::IndexedChoice(ref indexed_choice_instrs) => {
|
||||
OwnedOrIndexed::Owned(
|
||||
Line::IndexedChoice(indexed_choice_instrs[machine_st.iip as usize])
|
||||
)
|
||||
}
|
||||
&IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
|
||||
OwnedOrIndexed::Owned(
|
||||
Line::DynamicIndexedChoice(indexed_choice_instrs[machine_st.iip as usize])
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
OwnedOrIndexed::Indexed(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => OwnedOrIndexed::Indexed(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> {
|
||||
loop {
|
||||
match &self.code_repo.code[p] {
|
||||
&Line::Choice(ChoiceInstruction::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 {
|
||||
p += i;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::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;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::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 {
|
||||
p += i;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Fail(_),
|
||||
)) => {
|
||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||
return Some((p, 0));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
&Line::Control(ControlInstruction::RevJmpBy(i)) => {
|
||||
p -= i;
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn find_living_dynamic(&self, oi: u32, mut ii: u32) -> Option<(usize, u32, u32, bool)> {
|
||||
let p = self.machine_st.p.local().abs_loc();
|
||||
|
||||
let indexed_choice_instrs = match &self.code_repo.code[p] {
|
||||
Line::IndexingCode(ref indexing_code) => match &indexing_code[oi as usize] {
|
||||
IndexingLine::DynamicIndexedChoice(ref indexed_choice_instrs) => {
|
||||
indexed_choice_instrs
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
loop {
|
||||
match &indexed_choice_instrs.get(ii as usize) {
|
||||
Some(&offset) => match &self.code_repo.code[p + offset - 1] {
|
||||
&Line::Choice(ChoiceInstruction::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;
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CodeRepo {
|
||||
#[inline]
|
||||
pub(super) fn new() -> Self {
|
||||
CodeRepo { code: Code::new() }
|
||||
}
|
||||
}
|
||||
@@ -2,45 +2,47 @@ use crate::instructions::*;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
fn capture_offset(line: &Line, index: usize, stack: &mut Vec<usize>) -> bool {
|
||||
fn capture_offset(line: &Instruction, index: usize, stack: &mut Vec<usize>) -> bool {
|
||||
match line {
|
||||
&Line::Choice(ChoiceInstruction::TryMeElse(offset)) if offset > 0 => {
|
||||
&Instruction::TryMeElse(offset) if offset > 0 => {
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DefaultRetryMeElse(offset))
|
||||
| &Line::Choice(ChoiceInstruction::RetryMeElse(offset))
|
||||
&Instruction::DefaultRetryMeElse(offset) |
|
||||
&Instruction::RetryMeElse(offset)
|
||||
if offset > 0 =>
|
||||
{
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(offset)))
|
||||
&Instruction::DynamicElse(_, _, NextOrFail::Next(offset))
|
||||
if offset > 0 =>
|
||||
{
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(offset)))
|
||||
&Instruction::DynamicInternalElse(_, _, NextOrFail::Next(offset))
|
||||
if offset > 0 =>
|
||||
{
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => {
|
||||
&Instruction::JmpByCall(_, offset, _) => {
|
||||
stack.push(index + offset);
|
||||
}
|
||||
&Line::Control(ControlInstruction::JmpBy(_, offset, _, true)) => {
|
||||
&Instruction::JmpByExecute(_, offset, _) => {
|
||||
stack.push(index + offset);
|
||||
return true;
|
||||
}
|
||||
&Line::Control(ControlInstruction::Proceed)
|
||||
| &Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) => {
|
||||
&Instruction::Proceed => {
|
||||
return true;
|
||||
}
|
||||
&Line::Control(ControlInstruction::RevJmpBy(offset)) => {
|
||||
&Instruction::RevJmpBy(offset) => {
|
||||
if offset > 0 {
|
||||
stack.push(index - offset);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
instr if instr.is_execute() => {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
@@ -51,7 +53,7 @@ fn capture_offset(line: &Line, index: usize, stack: &mut Vec<usize>) -> bool {
|
||||
* begin in code at the offset p. Each instruction is passed to the
|
||||
* walker function.
|
||||
*/
|
||||
pub(crate) fn walk_code(code: &Code, p: usize, mut walker: impl FnMut(&Line)) {
|
||||
pub(crate) fn walk_code(code: &Code, p: usize, mut walker: impl FnMut(&Instruction)) {
|
||||
let mut stack = vec![p];
|
||||
let mut visited_indices = IndexSet::new();
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ pub(super) fn bootstrapping_compile(
|
||||
);
|
||||
|
||||
let payload = BootstrappingLoadState(
|
||||
LoadStatePayload::new(wam_prelude.code_repo.code.len(), term_stream)
|
||||
LoadStatePayload::new(wam_prelude.code.len(), term_stream)
|
||||
);
|
||||
|
||||
let loader: Loader<'_, BootstrappingLoadState> = Loader { payload, wam_prelude };
|
||||
@@ -73,7 +73,8 @@ pub(super) fn compile_appendix(
|
||||
let code_len = code.len();
|
||||
|
||||
match &mut code[jmp_by_offset] {
|
||||
&mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..)) => {
|
||||
&mut Instruction::JmpByCall(_, ref mut offset, ..) |
|
||||
&mut Instruction::JmpByExecute(_, ref mut offset, ..) => {
|
||||
*offset = code_len - jmp_by_offset;
|
||||
}
|
||||
_ => {
|
||||
@@ -144,20 +145,20 @@ fn derelictize_try_me_else(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> Option<usize> {
|
||||
match &mut code[index] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(0))) => None,
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(ref mut o))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(0)) => None,
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(index, *o));
|
||||
Some(mem::replace(o, 0))
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(0))) => None,
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o))) => {
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(0)) => None,
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(index, *o));
|
||||
Some(mem::replace(o, 0))
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Fail(_)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Fail(_))) => None,
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => None,
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
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));
|
||||
Some(mem::replace(o, 0))
|
||||
}
|
||||
@@ -183,7 +184,7 @@ fn merge_indices(
|
||||
let clause_loc =
|
||||
find_inner_choice_instr(code, skeleton[clause_index].clause_start, index_loc);
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[target_index_loc]).unwrap();
|
||||
let target_indexing_line = code[target_index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
skeleton[clause_index]
|
||||
.opt_arg_index_key
|
||||
@@ -210,8 +211,8 @@ fn merge_indices(
|
||||
fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
|
||||
loop {
|
||||
match &code[index] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(i)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(i)))
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(i)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(i))
|
||||
if *i > 0 =>
|
||||
{
|
||||
index += i;
|
||||
@@ -226,15 +227,15 @@ 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] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o) |
|
||||
Instruction::RetryMeElse(o) => {
|
||||
if *o > 0 {
|
||||
return index;
|
||||
} else {
|
||||
index = index_loc;
|
||||
}
|
||||
}
|
||||
&Line::Choice(ChoiceInstruction::DynamicElse(_, _, next_or_fail)) => match next_or_fail
|
||||
&Instruction::DynamicElse(_, _, next_or_fail) => match next_or_fail
|
||||
{
|
||||
NextOrFail::Next(i) => {
|
||||
if i == 0 {
|
||||
@@ -247,7 +248,7 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
||||
index = index_loc;
|
||||
}
|
||||
},
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, next_or_fail)) => {
|
||||
&Instruction::DynamicInternalElse(_, _, next_or_fail) => {
|
||||
match next_or_fail {
|
||||
NextOrFail::Next(i) => {
|
||||
if i == 0 {
|
||||
@@ -261,20 +262,20 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(_)) => {
|
||||
Instruction::TrustMe(_) => {
|
||||
return index;
|
||||
}
|
||||
Line::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
Instruction::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, ..)) => match v {
|
||||
IndexingCodePtr::External(v) => {
|
||||
index += v;
|
||||
}
|
||||
IndexingCodePtr::DynamicExternal(v) => match &code[index + v] {
|
||||
&Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
&Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(0),
|
||||
)) => {
|
||||
) => {
|
||||
return index + v;
|
||||
}
|
||||
_ => {
|
||||
@@ -287,7 +288,7 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
||||
unreachable!();
|
||||
}
|
||||
},
|
||||
Line::Control(ControlInstruction::RevJmpBy(offset)) => {
|
||||
Instruction::RevJmpBy(offset) => {
|
||||
index -= offset;
|
||||
}
|
||||
_ => {
|
||||
@@ -310,9 +311,7 @@ fn remove_index_from_subsequence(
|
||||
) {
|
||||
if let Some(index_loc) = opt_arg_index_key.switch_on_term_loc() {
|
||||
let clause_start = find_inner_choice_instr(code, clause_start, index_loc);
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
let offset = clause_start - index_loc + 1;
|
||||
|
||||
remove_index(opt_arg_index_key, target_indexing_line, offset);
|
||||
@@ -351,7 +350,7 @@ fn merge_indexed_subsequences(
|
||||
);
|
||||
|
||||
match &mut code[inner_try_me_else_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||
inner_try_me_else_loc,
|
||||
*o,
|
||||
@@ -359,15 +358,15 @@ fn merge_indexed_subsequences(
|
||||
|
||||
match *o {
|
||||
0 => {
|
||||
code[inner_try_me_else_loc] = Line::Choice(ChoiceInstruction::TrustMe(0));
|
||||
code[inner_try_me_else_loc] = Instruction::TrustMe(0);
|
||||
}
|
||||
o => match &code[inner_try_me_else_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(0)) => {
|
||||
code[inner_try_me_else_loc] = Line::Choice(ChoiceInstruction::TrustMe(o));
|
||||
Instruction::RevJmpBy(0) => {
|
||||
code[inner_try_me_else_loc] = Instruction::TrustMe(o);
|
||||
}
|
||||
_ => {
|
||||
code[inner_try_me_else_loc] =
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o));
|
||||
Instruction::RetryMeElse(o);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -403,7 +402,7 @@ fn merge_indexed_subsequences(
|
||||
);
|
||||
}
|
||||
None => match &mut code[outer_threaded_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info
|
||||
.push_record(RetractionRecord::ModifiedTryMeElse(inner_trust_me_loc, *o));
|
||||
|
||||
@@ -461,60 +460,55 @@ fn blunt_leading_choice_instr(
|
||||
) -> usize {
|
||||
loop {
|
||||
match &mut code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::RetryMeElse(o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(instr_loc, *o));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TryMeElse(*o));
|
||||
|
||||
code[instr_loc] = Instruction::TryMeElse(*o);
|
||||
return instr_loc;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(_)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(_))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(_)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(_)) => {
|
||||
return instr_loc;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Fail(o))) => {
|
||||
&mut Instruction::DynamicElse(b, d, NextOrFail::Fail(o)) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
|
||||
instr_loc,
|
||||
NextOrFail::Fail(o),
|
||||
));
|
||||
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Next(0)));
|
||||
|
||||
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Next(0));
|
||||
return instr_loc;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
&mut Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Fail(o),
|
||||
)) => {
|
||||
) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
|
||||
instr_loc,
|
||||
NextOrFail::Fail(o),
|
||||
));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
code[instr_loc] = Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Next(0),
|
||||
));
|
||||
);
|
||||
|
||||
return instr_loc;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(o)) => {
|
||||
retraction_info
|
||||
.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
|
||||
Instruction::TrustMe(o) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TryMeElse(0));
|
||||
code[instr_loc] = Instruction::TryMeElse(0);
|
||||
return instr_loc + 1;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
return instr_loc + 1;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o) => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Control(ControlInstruction::RevJmpBy(o)) => {
|
||||
Instruction::RevJmpBy(o) => {
|
||||
instr_loc -= *o;
|
||||
}
|
||||
_ => {
|
||||
@@ -530,7 +524,7 @@ fn set_switch_var_offset_to_choice_instr(
|
||||
offset: usize,
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) {
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
let v = match &target_indexing_line[0] {
|
||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, v, ..)) => match v {
|
||||
@@ -543,9 +537,9 @@ fn set_switch_var_offset_to_choice_instr(
|
||||
};
|
||||
|
||||
match &code[index_loc + v] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(_))
|
||||
| Line::Choice(ChoiceInstruction::DynamicElse(..))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(..)) => {}
|
||||
Instruction::TryMeElse(_) |
|
||||
Instruction::DynamicElse(..) |
|
||||
Instruction::DynamicInternalElse(..) => {}
|
||||
_ => {
|
||||
set_switch_var_offset(code, index_loc, offset, retraction_info);
|
||||
}
|
||||
@@ -559,7 +553,7 @@ fn set_switch_var_offset(
|
||||
offset: usize,
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) {
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
let old_v = match &mut target_indexing_line[0] {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, ref mut v, ..)) => match *v {
|
||||
@@ -585,72 +579,67 @@ fn internalize_choice_instr_at(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) {
|
||||
match &mut code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Fail(_)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Fail(_))) => {}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, ref mut o @ NextOrFail::Next(0))) => {
|
||||
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);
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Next(o))) => {
|
||||
&mut Instruction::DynamicElse(b, d, NextOrFail::Next(o)) => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
|
||||
instr_loc,
|
||||
NextOrFail::Next(o),
|
||||
));
|
||||
|
||||
match &mut code[instr_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(p)) if *p == 0 => {
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Fail(o)));
|
||||
Instruction::RevJmpBy(p) if *p == 0 => {
|
||||
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Fail(o));
|
||||
}
|
||||
_ => {
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(b, d, NextOrFail::Next(o)));
|
||||
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Next(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
ref mut o @ NextOrFail::Next(0),
|
||||
)) => {
|
||||
Instruction::DynamicInternalElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, 0));
|
||||
*o = NextOrFail::Fail(0);
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicInternalElse(b, d, NextOrFail::Next(o))) => {
|
||||
&mut Instruction::DynamicInternalElse(b, d, NextOrFail::Next(o)) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, o));
|
||||
|
||||
match &mut code[instr_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(p)) if *p == 0 => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::RevJmpBy(p) if *p == 0 => {
|
||||
code[instr_loc] = Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Fail(o),
|
||||
));
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
code[instr_loc] = Instruction::DynamicInternalElse(
|
||||
b,
|
||||
d,
|
||||
NextOrFail::Next(o),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(instr_loc, 0));
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TrustMe(0));
|
||||
code[instr_loc] = Instruction::TrustMe(0);
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o) => {
|
||||
let o = *o;
|
||||
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(instr_loc, o));
|
||||
|
||||
match &mut code[instr_loc + o] {
|
||||
Line::Control(ControlInstruction::RevJmpBy(p)) if *p == 0 => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::TrustMe(o));
|
||||
Instruction::RevJmpBy(p) if *p == 0 => {
|
||||
code[instr_loc] = Instruction::TrustMe(o);
|
||||
}
|
||||
_ => {
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::RetryMeElse(o));
|
||||
code[instr_loc] = Instruction::RetryMeElse(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -668,8 +657,7 @@ fn thread_choice_instr_at_to(
|
||||
) {
|
||||
loop {
|
||||
match &mut code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o))
|
||||
Instruction::TryMeElse(ref mut o) | Instruction::RetryMeElse(ref mut o)
|
||||
if target_loc >= instr_loc =>
|
||||
{
|
||||
retraction_info.push_record(RetractionRecord::ReplacedChoiceOffset(instr_loc, *o));
|
||||
@@ -677,82 +665,80 @@ fn thread_choice_instr_at_to(
|
||||
*o = target_loc - instr_loc;
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)) |
|
||||
Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(ref mut o),
|
||||
)) if target_loc >= instr_loc => {
|
||||
) if target_loc >= instr_loc => {
|
||||
retraction_info
|
||||
.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, *o));
|
||||
*o = target_loc - instr_loc;
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(o)))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(o))) => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Next(o)) |
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(o)) => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::TryMeElse(o)
|
||||
| Instruction::RetryMeElse(o) => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Control(ControlInstruction::RevJmpBy(ref mut o)) if instr_loc >= target_loc => {
|
||||
Instruction::RevJmpBy(ref mut o) if instr_loc >= target_loc => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedRevJmpBy(instr_loc, *o));
|
||||
|
||||
*o = instr_loc - target_loc;
|
||||
return;
|
||||
}
|
||||
&mut Line::Control(ControlInstruction::RevJmpBy(o)) => {
|
||||
&mut Instruction::RevJmpBy(o) => {
|
||||
instr_loc -= o;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicElse(birth, death, ref mut fail))
|
||||
&mut Instruction::DynamicElse(birth, death, ref mut fail)
|
||||
if target_loc >= instr_loc =>
|
||||
{
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
code[instr_loc] = instr!("dynamic_else",
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Next(target_loc - instr_loc),
|
||||
));
|
||||
NextOrFail::Next(target_loc - instr_loc)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Fail(o))) if *o > 0 => {
|
||||
Instruction::DynamicElse(_, _, NextOrFail::Fail(o)) if *o > 0 => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
&mut Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
&mut Instruction::DynamicInternalElse(
|
||||
birth,
|
||||
death,
|
||||
ref mut fail,
|
||||
)) if target_loc >= instr_loc => {
|
||||
) if target_loc >= instr_loc => {
|
||||
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
|
||||
|
||||
code[instr_loc] = Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
code[instr_loc] = instr!("dynamic_internal_else",
|
||||
birth,
|
||||
death,
|
||||
NextOrFail::Next(target_loc - instr_loc),
|
||||
));
|
||||
NextOrFail::Next(target_loc - instr_loc)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Fail(o)))
|
||||
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(o))
|
||||
if *o > 0 =>
|
||||
{
|
||||
instr_loc += *o;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(ref mut o)) if target_loc >= instr_loc => {
|
||||
Instruction::TrustMe(ref mut o) if target_loc >= instr_loc => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::AppendedTrustMe(instr_loc, *o, false),
|
||||
//choice_instr.is_default()),
|
||||
);
|
||||
|
||||
code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(target_loc - instr_loc));
|
||||
|
||||
code[instr_loc] = instr!("retry_me_else", target_loc - instr_loc);
|
||||
return;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(o)) if *o > 0 => {
|
||||
Instruction::TrustMe(o) if *o > 0 => {
|
||||
instr_loc += *o;
|
||||
}
|
||||
_ => {
|
||||
@@ -769,7 +755,7 @@ fn remove_non_leading_clause(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> Option<IndexPtr> {
|
||||
match &mut code[non_indexed_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o)) => {
|
||||
Instruction::RetryMeElse(ref mut o) => {
|
||||
let o = *o;
|
||||
|
||||
thread_choice_instr_at_to(
|
||||
@@ -781,19 +767,19 @@ fn remove_non_leading_clause(
|
||||
|
||||
None
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TrustMe(_)) => {
|
||||
Instruction::TrustMe(_) => {
|
||||
match &mut code[preceding_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
|
||||
Instruction::RetryMeElse(o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(
|
||||
preceding_choice_instr_loc,
|
||||
*o,
|
||||
));
|
||||
|
||||
code[preceding_choice_instr_loc] = Line::Choice(ChoiceInstruction::TrustMe(0));
|
||||
code[preceding_choice_instr_loc] = Instruction::TrustMe(0);
|
||||
|
||||
None
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||
preceding_choice_instr_loc,
|
||||
*o,
|
||||
@@ -850,7 +836,7 @@ fn remove_leading_unindexed_clause(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
) -> Option<IndexPtr> {
|
||||
match &mut code[non_indexed_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) => {
|
||||
Instruction::TryMeElse(ref mut o) => {
|
||||
if *o > 0 {
|
||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||
non_indexed_choice_instr_loc,
|
||||
@@ -878,7 +864,7 @@ fn remove_leading_unindexed_clause(
|
||||
|
||||
fn find_dynamic_outer_choice_instr(code: &Code, index_loc: usize) -> usize {
|
||||
match &code[index_loc] {
|
||||
Line::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
Instruction::IndexingCode(indexing_code) => match &indexing_code[0] {
|
||||
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
IndexingCodePtr::DynamicExternal(v),
|
||||
@@ -951,22 +937,16 @@ fn prepend_compiled_clause(
|
||||
let inner_thread_rev_offset =
|
||||
3 + prepend_queue.len() + clause_loc - skeleton.clauses[1].clause_start;
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(
|
||||
settings.internal_try_me_else(prepend_queue.len()),
|
||||
));
|
||||
prepend_queue.push_front(settings.internal_try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse N_2
|
||||
// | (clause_code)
|
||||
// +N_2 | RevJmpBy (RetryMeElse(M_1) or TryMeElse(0) at index_loc + 1)
|
||||
|
||||
prepend_queue.push_front(Line::Control(ControlInstruction::RevJmpBy(
|
||||
1 + clause_loc - index_loc,
|
||||
)));
|
||||
prepend_queue.push_front(Instruction::RevJmpBy(1 + clause_loc - index_loc));
|
||||
|
||||
let outer_thread_choice_offset = // outer_thread_choice_loc WAS index_loc - 1..
|
||||
match derelictize_try_me_else(code, outer_thread_choice_loc, retraction_info) {
|
||||
@@ -978,7 +958,7 @@ fn prepend_compiled_clause(
|
||||
next_subseq_offset;
|
||||
|
||||
prepend_queue.push_back(
|
||||
Line::Control(ControlInstruction::RevJmpBy(outer_thread_rev_offset))
|
||||
Instruction::RevJmpBy(outer_thread_rev_offset)
|
||||
);
|
||||
|
||||
prepend_queue.len()
|
||||
@@ -994,17 +974,13 @@ fn prepend_compiled_clause(
|
||||
// awaiting the addition of unindexed
|
||||
// clauses.
|
||||
|
||||
prepend_queue.push_back(
|
||||
Line::Control(ControlInstruction::RevJmpBy(0)),
|
||||
);
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(0));
|
||||
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
prepend_queue.push_front(Line::Choice(
|
||||
settings.try_me_else(outer_thread_choice_offset),
|
||||
));
|
||||
prepend_queue.push_front(settings.try_me_else(outer_thread_choice_offset));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse N_3
|
||||
@@ -1014,7 +990,7 @@ fn prepend_compiled_clause(
|
||||
// N_2 | RevJmpBy (RetryMeElse(M_1) or TryMeElse(0) at index_loc + 1)
|
||||
// N_3 | RevJmpBy (TryMeElse(N_1) at index_loc - 1 or TrustMe if N_1 == 0)
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
merge_clause_index(
|
||||
target_indexing_line,
|
||||
@@ -1060,19 +1036,19 @@ fn prepend_compiled_clause(
|
||||
|
||||
// this is a stub for chaining inner-threaded choice
|
||||
// instructions.
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(0)));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(0));
|
||||
|
||||
let prepend_queue_len = prepend_queue.len();
|
||||
|
||||
match &mut prepend_queue[1] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o)) if *o == 0 => {
|
||||
Instruction::TryMeElse(ref mut o) if *o == 0 => {
|
||||
*o = prepend_queue_len - 2;
|
||||
}
|
||||
Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
ref mut o @ NextOrFail::Next(0),
|
||||
)) => {
|
||||
) => {
|
||||
*o = NextOrFail::Fail(prepend_queue_len - 2);
|
||||
}
|
||||
_ => {
|
||||
@@ -1080,11 +1056,8 @@ fn prepend_compiled_clause(
|
||||
}
|
||||
}
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(settings.try_me_else(prepend_queue.len())));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
prepend_queue.push_front(settings.try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse(N_2)
|
||||
@@ -1114,11 +1087,8 @@ fn prepend_compiled_clause(
|
||||
let inner_thread_rev_offset =
|
||||
1 + prepend_queue.len() + clause_loc - old_clause_start;
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(settings.try_me_else(prepend_queue.len())));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
prepend_queue.push_front(settings.try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse(N_2)
|
||||
@@ -1142,11 +1112,8 @@ fn prepend_compiled_clause(
|
||||
let inner_thread_rev_offset =
|
||||
1 + prepend_queue.len() + clause_loc - old_clause_start;
|
||||
|
||||
prepend_queue.push_back(Line::Control(ControlInstruction::RevJmpBy(
|
||||
inner_thread_rev_offset,
|
||||
)));
|
||||
|
||||
prepend_queue.push_front(Line::Choice(settings.try_me_else(prepend_queue.len())));
|
||||
prepend_queue.push_back(Instruction::RevJmpBy(inner_thread_rev_offset));
|
||||
prepend_queue.push_front(settings.try_me_else(prepend_queue.len()));
|
||||
|
||||
// prepend_queue is now:
|
||||
// | TryMeElse(N_2)
|
||||
@@ -1205,7 +1172,7 @@ fn append_compiled_clause(
|
||||
.switch_on_term_loc()
|
||||
{
|
||||
Some(index_loc) if lower_bound_arg_num == target_arg_num => {
|
||||
code.push(Line::Choice(settings.internal_trust_me()));
|
||||
code.push(settings.internal_trust_me());
|
||||
|
||||
code.extend(clause_code.drain(3..)); // skip the indexing code
|
||||
|
||||
@@ -1218,7 +1185,7 @@ fn append_compiled_clause(
|
||||
skeleton.clauses[target_pos].clause_start,
|
||||
));
|
||||
|
||||
let target_indexing_line = to_indexing_line_mut(&mut code[index_loc]).unwrap();
|
||||
let target_indexing_line = code[index_loc].to_indexing_line_mut().unwrap();
|
||||
|
||||
merge_clause_index(
|
||||
target_indexing_line,
|
||||
@@ -1252,7 +1219,7 @@ fn append_compiled_clause(
|
||||
target_pos_clause_start // skeleton.clauses[target_pos - 1].clause_start
|
||||
}
|
||||
_ => {
|
||||
code.push(Line::Choice(settings.trust_me()));
|
||||
code.push(settings.trust_me());
|
||||
|
||||
skeleton.clauses[target_pos].opt_arg_index_key += clause_loc;
|
||||
code.extend(clause_code.drain(1..));
|
||||
@@ -1331,9 +1298,9 @@ fn print_overwrite_warning(
|
||||
key: &PredicateKey,
|
||||
is_dynamic: bool,
|
||||
) {
|
||||
if let CompilationTarget::Module(ref module_name) = compilation_target {
|
||||
match module_name.as_str() {
|
||||
"builtins" | "loader" => return,
|
||||
if let CompilationTarget::Module(module_name) = compilation_target {
|
||||
match module_name {
|
||||
atom!("builtins") | atom!("loader") => return,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -1405,7 +1372,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
) -> Result<CodeIndex, SessionError> {
|
||||
let code_index = self.get_or_insert_code_index(key, predicates.compilation_target);
|
||||
|
||||
let code_len = self.wam_prelude.code_repo.code.len();
|
||||
let code_len = self.wam_prelude.code.len();
|
||||
let mut code_ptr = code_len;
|
||||
|
||||
let mut clauses = vec![];
|
||||
@@ -1443,7 +1410,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
|
||||
match &mut code[0] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
code_ptr += 1;
|
||||
}
|
||||
_ => {}
|
||||
@@ -1514,7 +1481,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
index_ptr,
|
||||
);
|
||||
|
||||
self.wam_prelude.code_repo.code.extend(code.into_iter());
|
||||
self.wam_prelude.code.extend(code.into_iter());
|
||||
Ok(code_index)
|
||||
}
|
||||
|
||||
@@ -1690,7 +1657,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
mut standalone_skeleton,
|
||||
} = self.compile_standalone_clause(clause, settings)?;
|
||||
|
||||
let code_len = self.wam_prelude.code_repo.code.len();
|
||||
let code_len = self.wam_prelude.code.len();
|
||||
|
||||
let skeleton = match self
|
||||
.wam_prelude
|
||||
@@ -1717,7 +1684,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
||||
|
||||
let result = append_compiled_clause(
|
||||
&mut self.wam_prelude.code_repo.code,
|
||||
&mut self.wam_prelude.code,
|
||||
clause_code,
|
||||
skeleton,
|
||||
&mut self.payload.retraction_info,
|
||||
@@ -1757,7 +1724,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
||||
|
||||
let new_code_ptr = prepend_compiled_clause(
|
||||
&mut self.wam_prelude.code_repo.code,
|
||||
&mut self.wam_prelude.code,
|
||||
compilation_target,
|
||||
key,
|
||||
clause_code,
|
||||
@@ -1801,16 +1768,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
.switch_on_term_loc()
|
||||
{
|
||||
Some(index_loc) => find_inner_choice_instr(
|
||||
&self.wam_prelude.code_repo.code,
|
||||
&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_repo.code[clause_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(_, ref mut d, _))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(_, ref mut d, _)) => {
|
||||
match &mut self.wam_prelude.code[clause_loc] {
|
||||
Instruction::DynamicElse(_, ref mut d, _) |
|
||||
Instruction::DynamicInternalElse(_, ref mut d, _) => {
|
||||
*d = Death::Finite(LS::machine_st(&mut self.payload).global_clock);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@@ -1840,7 +1807,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
};
|
||||
|
||||
let code = &mut self.wam_prelude.code_repo.code;
|
||||
let code = &mut self.wam_prelude.code;
|
||||
let lower_bound = lower_bound_of_target_clause(skeleton, target_pos);
|
||||
let lower_bound_is_unindexed = !skeleton.clauses[lower_bound].opt_arg_index_key.is_some();
|
||||
|
||||
@@ -1975,13 +1942,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
Some(later_indexing_loc) if later_indexing_loc < target_indexing_loc => {
|
||||
let target_indexing_line = mem::replace(
|
||||
&mut code[target_indexing_loc],
|
||||
Line::Control(ControlInstruction::RevJmpBy(
|
||||
target_indexing_loc - later_indexing_loc,
|
||||
)),
|
||||
Instruction::RevJmpBy(target_indexing_loc - later_indexing_loc),
|
||||
);
|
||||
|
||||
match target_indexing_line {
|
||||
Line::IndexingCode(indexing_code) => {
|
||||
Instruction::IndexingCode(indexing_code) => {
|
||||
self.payload.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedIndexingLine(
|
||||
target_indexing_loc,
|
||||
@@ -2073,7 +2038,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
);
|
||||
|
||||
match &mut code[preceding_choice_instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(0)) => {
|
||||
Instruction::TryMeElse(0) => {
|
||||
set_switch_var_offset(
|
||||
code,
|
||||
index_loc,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@ use crate::types::*;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
// TODO: rename to 'unmark_if_iter', 'mark_if_gc'
|
||||
pub(crate) trait UnmarkPolicy {
|
||||
fn unmark(heap: &mut [HeapCellValue], current: usize) -> bool;
|
||||
fn mark(heap: &mut [HeapCellValue], current: usize);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::parser::ast::*;
|
||||
use crate::types::*;
|
||||
@@ -251,7 +250,7 @@ where
|
||||
filtered_iter_to_heap_list(heap, values, |_, _| true)
|
||||
}
|
||||
|
||||
pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<LocalCodePtr> {
|
||||
pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usize> {
|
||||
let extract_integer = |s: usize| -> Option<usize> {
|
||||
match Number::try_from(heap[s]) {
|
||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
|
||||
@@ -265,7 +264,7 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<Loca
|
||||
let (name, arity) = cell_as_atom_cell!(heap[s]).get_name_and_arity();
|
||||
|
||||
if name == atom!("dir_entry") && arity == 1 {
|
||||
extract_integer(s+1).map(LocalCodePtr::DirEntry)
|
||||
extract_integer(s+1)
|
||||
} else {
|
||||
panic!(
|
||||
"to_local_code_ptr crashed with p.i. {}/{}",
|
||||
@@ -279,182 +278,3 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<Loca
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
#[inline]
|
||||
pub(crate) fn new() -> Self {
|
||||
HeapTemplate {
|
||||
buf: RawBlock::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: move this to the WAM, then remove the temporary (and by
|
||||
// then, unnecessary and impossible) "arena" argument. OR, remove
|
||||
// this thing totally! if we can. by that I mean, just convert a
|
||||
// little to a HeapCellValue. don't bother writing to the
|
||||
// heap at all. Each of these data is either already inlinable in a
|
||||
// HeapCellValue or a pointer to an GC'ed location in memory.
|
||||
#[inline]
|
||||
pub(crate) fn put_literal(&mut self, literal: Literal) -> HeapCellValue {
|
||||
match literal {
|
||||
Literal::Atom(name) => atom_as_cell!(name),
|
||||
Literal::Char(c) => char_as_cell!(c),
|
||||
Literal::EmptyList => empty_list_as_cell!(),
|
||||
Literal::Fixnum(n) => fixnum_as_cell!(n),
|
||||
Literal::Integer(bigint_ptr) => {
|
||||
let h = self.push(typed_arena_ptr_as_cell!(bigint_ptr));
|
||||
self[h]
|
||||
}
|
||||
Literal::Rational(bigint_ptr) => {
|
||||
let h = self.push(typed_arena_ptr_as_cell!(bigint_ptr));
|
||||
self[h]
|
||||
}
|
||||
Literal::Float(f) => typed_arena_ptr_as_cell!(f),
|
||||
Literal::String(s) => {
|
||||
if s.as_str().is_empty() {
|
||||
empty_list_as_cell!()
|
||||
} else {
|
||||
// TODO: how do we know where the tail is located?? well, there is no tail. separate tag?
|
||||
untyped_arena_ptr_as_cell!(s) // self.put_complete_string(arena, &s)
|
||||
}
|
||||
} // Literal::Usize(n) => Addr::Usize(n),
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.h() == 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn pop(&mut self) {
|
||||
let h = self.h();
|
||||
|
||||
if h > 0 {
|
||||
self.truncate(h - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn push(&mut self, val: HeapCellValue) -> usize {
|
||||
let h = self.h();
|
||||
|
||||
unsafe {
|
||||
let new_ptr = self.buf.alloc(mem::size_of::<HeapCellValue>());
|
||||
ptr::write(new_ptr as *mut _, val);
|
||||
}
|
||||
|
||||
h
|
||||
}
|
||||
|
||||
/*
|
||||
#[inline]
|
||||
pub(crate) fn atom_at(&self, h: usize) -> bool {
|
||||
if let HeapCellValue::Atom(..) = &self[h] {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
|
||||
match non_heap_value {
|
||||
HeapCellValue::Addr(addr) => addr,
|
||||
val @ HeapCellValue::Atom(..)
|
||||
| val @ HeapCellValue::Integer(_)
|
||||
| val @ HeapCellValue::DBRef(_)
|
||||
| val @ HeapCellValue::Rational(_) => Addr::Con(self.push(val)),
|
||||
val @ HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(self.push(val)),
|
||||
val @ HeapCellValue::NamedStr(..) => Addr::Str(self.push(val)),
|
||||
HeapCellValue::PartialString(pstr, has_tail) => {
|
||||
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
if has_tail {
|
||||
self.push(HeapCellValue::Addr(Addr::EmptyList));
|
||||
}
|
||||
|
||||
Addr::Con(h)
|
||||
}
|
||||
val @ HeapCellValue::Stream(..) => Addr::Stream(self.push(val)),
|
||||
val @ HeapCellValue::TcpListener(..) => Addr::TcpListener(self.push(val)),
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn truncate(&mut self, h: usize) {
|
||||
let new_ptr = self.buf.top as usize - h * mem::size_of::<HeapCellValue>();
|
||||
self.buf.ptr = new_ptr as *mut _;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn h(&self) -> usize {
|
||||
(self.buf.top as usize - self.buf.ptr as usize) / mem::size_of::<HeapCellValue>()
|
||||
}
|
||||
|
||||
pub(crate) fn append(&mut self, vals: Vec<HeapCellValue>) {
|
||||
for val in vals {
|
||||
self.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clear(&mut self) {
|
||||
if !self.buf.base.is_null() {
|
||||
self.truncate(0);
|
||||
self.buf.top = self.buf.base;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: get rid of this!!
|
||||
#[inline]
|
||||
pub(crate) fn index_addr<'a>(&'a self, addr: &Addr) -> RefOrOwned<'a, HeapCellValue> {
|
||||
match addr {
|
||||
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => {
|
||||
RefOrOwned::Borrowed(&self[h])
|
||||
}
|
||||
addr => RefOrOwned::Owned(HeapCellValue::Addr(*addr)),
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Index<u64> for HeapTemplate<T> {
|
||||
type Output = HeapCellValue;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: u64) -> &Self::Output {
|
||||
unsafe {
|
||||
let ptr =
|
||||
self.buf.top as usize - (index as usize + 1) * mem::size_of::<HeapCellValue>();
|
||||
&*(ptr as *const HeapCellValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Index<usize> for HeapTemplate<T> {
|
||||
type Output = HeapCellValue;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
unsafe {
|
||||
let ptr = self.buf.top as usize - (index + 1) * mem::size_of::<HeapCellValue>();
|
||||
&*(ptr as *const HeapCellValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> IndexMut<usize> for HeapTemplate<T> {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
unsafe {
|
||||
let ptr = self.buf.top as usize - (index + 1) * mem::size_of::<HeapCellValue>();
|
||||
&mut *(ptr as *mut HeapCellValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
@@ -8,6 +7,7 @@ use crate::machine::term_stream::*;
|
||||
use crate::machine::*;
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexSet;
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
use slice_deque::{sdeq, SliceDeque};
|
||||
@@ -753,7 +753,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
pub(super) fn get_clause_type(&mut self, name: Atom, arity: usize) -> ClauseType {
|
||||
match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
let payload_compilation_target = self.payload.compilation_target;
|
||||
|
||||
let idx = self.get_or_insert_code_index(
|
||||
@@ -761,7 +761,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
payload_compilation_target,
|
||||
);
|
||||
|
||||
ClauseType::Named(name, arity, idx)
|
||||
ClauseType::Named(arity, name, idx)
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
@@ -774,11 +774,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
arity: usize,
|
||||
) -> ClauseType {
|
||||
match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
let key = (name, arity);
|
||||
let idx = self.get_or_insert_qualified_code_index(module_name, key);
|
||||
|
||||
ClauseType::Named(name, arity, idx)
|
||||
ClauseType::Named(arity, name, idx)
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
@@ -922,7 +922,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
let local_extensible_predicates = mem::replace(
|
||||
&mut module.local_extensible_predicates,
|
||||
LocalExtensiblePredicates::new(),
|
||||
LocalExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||
);
|
||||
|
||||
for ((compilation_target, key), skeleton) in local_extensible_predicates.iter() {
|
||||
@@ -1162,11 +1162,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
let subloader: Loader<'_, BootstrappingLoadState> = Loader {
|
||||
payload: BootstrappingLoadState(
|
||||
LoadStatePayload::new(self.wam_prelude.code_repo.code.len(), term_stream)
|
||||
LoadStatePayload::new(self.wam_prelude.code.len(), term_stream)
|
||||
),
|
||||
wam_prelude: MachinePreludeView {
|
||||
indices: self.wam_prelude.indices,
|
||||
code_repo: self.wam_prelude.code_repo,
|
||||
code: self.wam_prelude.code,
|
||||
load_contexts: self.wam_prelude.load_contexts,
|
||||
}
|
||||
};
|
||||
@@ -1225,11 +1225,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
|
||||
let subloader: Loader<'_, BootstrappingLoadState> = Loader {
|
||||
payload: BootstrappingLoadState(
|
||||
LoadStatePayload::new(self.wam_prelude.code_repo.code.len(), term_stream),
|
||||
LoadStatePayload::new(self.wam_prelude.code.len(), term_stream),
|
||||
),
|
||||
wam_prelude: MachinePreludeView {
|
||||
indices: self.wam_prelude.indices,
|
||||
code_repo: self.wam_prelude.code_repo,
|
||||
code: self.wam_prelude.code,
|
||||
load_contexts: self.wam_prelude.load_contexts,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::indexing::*;
|
||||
@@ -327,7 +326,7 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
|
||||
loader.compile_and_submit()?;
|
||||
}
|
||||
|
||||
let repo_len = loader.wam_prelude.code_repo.code.len();
|
||||
let repo_len = loader.wam_prelude.code.len();
|
||||
|
||||
loader
|
||||
.payload
|
||||
@@ -363,7 +362,7 @@ pub struct Loader<'a, LS: LoadState<'a>> {
|
||||
impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
#[inline]
|
||||
pub(super) fn new(wam: &'a mut Machine, term_stream: <LS as LoadState<'a>>::TS) -> Self {
|
||||
let payload = LoadStatePayload::new(wam.code_repo.code.len(), term_stream);
|
||||
let payload = LoadStatePayload::new(wam.code.len(), term_stream);
|
||||
let (wam_prelude, machine_st) = wam.prelude_view_and_machine_st();
|
||||
|
||||
Self {
|
||||
@@ -696,8 +695,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
RetractionRecord::AddedIndex(index_key, clause_loc) => {
|
||||
// WAS: inner_index_locs) => {
|
||||
if let Some(index_loc) = index_key.switch_on_term_loc() {
|
||||
let indexing_code = match &mut self.wam_prelude.code_repo.code[index_loc] {
|
||||
Line::IndexingCode(indexing_code) => indexing_code,
|
||||
let indexing_code = match &mut self.wam_prelude.code[index_loc] {
|
||||
Instruction::IndexingCode(indexing_code) => indexing_code,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
@@ -743,10 +742,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
// write the retraction logic of this arm.
|
||||
}
|
||||
RetractionRecord::ReplacedChoiceOffset(instr_loc, offset) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(ref mut o))
|
||||
| Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o))
|
||||
| Line::Choice(ChoiceInstruction::DefaultRetryMeElse(ref mut o)) => {
|
||||
match self.wam_prelude.code[instr_loc] {
|
||||
Instruction::TryMeElse(ref mut o) |
|
||||
Instruction::RetryMeElse(ref mut o) |
|
||||
Instruction::DefaultRetryMeElse(ref mut o) => {
|
||||
*o = offset;
|
||||
}
|
||||
_ => {
|
||||
@@ -755,22 +754,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::AppendedTrustMe(instr_loc, offset, is_default) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ref mut choice_instr) => {
|
||||
*choice_instr = if is_default {
|
||||
ChoiceInstruction::DefaultTrustMe(offset)
|
||||
self.wam_prelude.code[instr_loc] = if is_default {
|
||||
Instruction::DefaultTrustMe(offset)
|
||||
} else {
|
||||
ChoiceInstruction::TrustMe(offset)
|
||||
Instruction::TrustMe(offset)
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
RetractionRecord::ReplacedSwitchOnTermVarIndex(index_loc, old_v) => {
|
||||
match self.wam_prelude.code_repo.code[index_loc] {
|
||||
Line::IndexingCode(ref mut indexing_code) => match &mut indexing_code[0] {
|
||||
match self.wam_prelude.code[index_loc] {
|
||||
Instruction::IndexingCode(ref mut indexing_code) => match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
ref mut v,
|
||||
@@ -784,16 +776,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::ModifiedTryMeElse(instr_loc, o) => {
|
||||
self.wam_prelude.code_repo.code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::TryMeElse(o));
|
||||
self.wam_prelude.code[instr_loc] = Instruction::TryMeElse(o);
|
||||
}
|
||||
RetractionRecord::ModifiedRetryMeElse(instr_loc, o) => {
|
||||
self.wam_prelude.code_repo.code[instr_loc] =
|
||||
Line::Choice(ChoiceInstruction::RetryMeElse(o));
|
||||
self.wam_prelude.code[instr_loc] = Instruction::RetryMeElse(o);
|
||||
}
|
||||
RetractionRecord::ModifiedRevJmpBy(instr_loc, o) => {
|
||||
self.wam_prelude.code_repo.code[instr_loc] =
|
||||
Line::Control(ControlInstruction::RevJmpBy(o));
|
||||
self.wam_prelude.code[instr_loc] = Instruction::RevJmpBy(o);
|
||||
}
|
||||
RetractionRecord::SkeletonClausePopBack(compilation_target, key) => {
|
||||
match self
|
||||
@@ -959,7 +948,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::ReplacedIndexingLine(index_loc, indexing_code) => {
|
||||
self.wam_prelude.code_repo.code[index_loc] = Line::IndexingCode(indexing_code);
|
||||
self.wam_prelude.code[index_loc] = Instruction::IndexingCode(indexing_code);
|
||||
}
|
||||
RetractionRecord::RemovedLocalSkeletonClauseLocations(
|
||||
compilation_target,
|
||||
@@ -992,34 +981,34 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||
}
|
||||
}
|
||||
RetractionRecord::ReplacedDynamicElseOffset(instr_loc, next) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
match self.wam_prelude.code[instr_loc] {
|
||||
Instruction::DynamicElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(ref mut o),
|
||||
))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
)
|
||||
| Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
NextOrFail::Next(ref mut o),
|
||||
)) => {
|
||||
) => {
|
||||
*o = next;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
RetractionRecord::AppendedNextOrFail(instr_loc, fail) => {
|
||||
match self.wam_prelude.code_repo.code[instr_loc] {
|
||||
Line::Choice(ChoiceInstruction::DynamicElse(
|
||||
match self.wam_prelude.code[instr_loc] {
|
||||
Instruction::DynamicElse(
|
||||
_,
|
||||
_,
|
||||
ref mut next_or_fail,
|
||||
))
|
||||
| Line::Choice(ChoiceInstruction::DynamicInternalElse(
|
||||
)
|
||||
| Instruction::DynamicInternalElse(
|
||||
_,
|
||||
_,
|
||||
ref mut next_or_fail,
|
||||
)) => {
|
||||
) => {
|
||||
*next_or_fail = fail;
|
||||
}
|
||||
_ => {}
|
||||
@@ -1384,7 +1373,7 @@ impl<'a> MachinePreludeView<'a> {
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub(crate) fn use_module(&mut self) {
|
||||
pub(crate) fn use_module(&mut self) -> CallResult {
|
||||
let subevacuable_addr = self
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(self.machine_st.registers[2]));
|
||||
@@ -1395,7 +1384,7 @@ impl Machine {
|
||||
match payload.compilation_target {
|
||||
CompilationTarget::Module(module_name) => module_name,
|
||||
CompilationTarget::User => {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1415,10 +1404,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = use_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn load_compiled_library(&mut self) {
|
||||
pub(crate) fn load_compiled_library(&mut self) -> CallResult {
|
||||
let library = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1426,7 +1415,7 @@ impl Machine {
|
||||
if let Some(module) = self.indices.modules.get(&library) {
|
||||
if let ListingSource::DynamicallyGenerated = module.listing_src {
|
||||
self.machine_st.fail = true;
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
|
||||
@@ -1444,13 +1433,14 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = import_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
} else {
|
||||
self.machine_st.fail = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn declare_module(&mut self) {
|
||||
pub(crate) fn declare_module(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1471,34 +1461,34 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = declare_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn add_discontiguous_predicate(&mut self) {
|
||||
pub(crate) fn add_discontiguous_predicate(&mut self) -> CallResult {
|
||||
self.add_extensible_predicate_declaration(
|
||||
|loader, compilation_target, clause_name, arity| {
|
||||
loader.add_discontiguous_predicate(compilation_target, clause_name, arity)
|
||||
},
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn add_dynamic_predicate(&mut self) {
|
||||
pub(crate) fn add_dynamic_predicate(&mut self) -> CallResult {
|
||||
self.add_extensible_predicate_declaration(
|
||||
|loader, compilation_target, clause_name, arity| {
|
||||
loader.add_dynamic_predicate(compilation_target, clause_name, arity)
|
||||
},
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn add_multifile_predicate(&mut self) {
|
||||
pub(crate) fn add_multifile_predicate(&mut self) -> CallResult {
|
||||
self.add_extensible_predicate_declaration(
|
||||
|loader, compilation_target, clause_name, arity| {
|
||||
loader.add_multifile_predicate(compilation_target, clause_name, arity)
|
||||
},
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
fn add_extensible_predicate_declaration(
|
||||
@@ -1509,7 +1499,7 @@ impl Machine {
|
||||
Atom,
|
||||
usize,
|
||||
) -> Result<(), SessionError>,
|
||||
) {
|
||||
) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1543,10 +1533,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_predicate_decl();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_term_expansion_clause(&mut self) {
|
||||
pub(crate) fn add_term_expansion_clause(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(2));
|
||||
|
||||
let add_clause = || {
|
||||
@@ -1564,10 +1554,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_clause();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_goal_expansion_clause(&mut self) {
|
||||
pub(crate) fn add_goal_expansion_clause(&mut self) -> CallResult {
|
||||
let target_module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1594,10 +1584,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_clause();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_in_situ_filename_module(&mut self) {
|
||||
pub(crate) fn add_in_situ_filename_module(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(1));
|
||||
|
||||
let add_in_situ_filename_module = || {
|
||||
@@ -1643,7 +1633,7 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = add_in_situ_filename_module();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn loader_from_heap_evacuable<'a>(
|
||||
@@ -1668,15 +1658,13 @@ impl Machine {
|
||||
pub(crate) fn push_load_state_payload(&mut self) {
|
||||
let payload = arena_alloc!(
|
||||
LoadStatePayload::new(
|
||||
self.code_repo.code.len(),
|
||||
self.code.len(),
|
||||
LiveTermStream::new(ListingSource::User),
|
||||
),
|
||||
&mut self.machine_st.arena
|
||||
);
|
||||
|
||||
let var = self.machine_st.deref(
|
||||
self.machine_st.registers[1]
|
||||
);
|
||||
let var = self.machine_st.deref(self.machine_st.registers[1]);
|
||||
|
||||
self.machine_st.bind(
|
||||
var.as_var().unwrap(),
|
||||
@@ -1718,38 +1706,40 @@ impl Machine {
|
||||
self.load_contexts.pop();
|
||||
}
|
||||
|
||||
pub(crate) fn push_load_context(&mut self) {
|
||||
let stream = try_or_fail!(
|
||||
self.machine_st,
|
||||
self.machine_st.get_stream_or_alias(
|
||||
pub(crate) fn push_load_context(&mut self) -> CallResult {
|
||||
let stream = self.machine_st.get_stream_or_alias(
|
||||
self.machine_st.registers[1],
|
||||
&self.indices.stream_aliases,
|
||||
atom!("$push_load_context"),
|
||||
2,
|
||||
)
|
||||
);
|
||||
)?;
|
||||
|
||||
let path = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2]))
|
||||
);
|
||||
|
||||
self.load_contexts.push(LoadContext::new(path.as_str(), stream));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn restore_load_state_payload(
|
||||
&mut self,
|
||||
result: Result<TypedArenaPtr<LiveLoadState>, SessionError>,
|
||||
) {
|
||||
) -> CallResult {
|
||||
match result {
|
||||
Ok(_payload) => {
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
self.throw_session_error(e, (atom!("load"), 1));
|
||||
let err = self.machine_st.session_error(e);
|
||||
let stub = functor_stub(atom!("load"), 1);
|
||||
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn scoped_clause_to_evacuable(&mut self) {
|
||||
pub(crate) fn scoped_clause_to_evacuable(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -1762,18 +1752,18 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = loader.read_and_enqueue_term(temp_v!(2), compilation_target);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn clause_to_evacuable(&mut self) {
|
||||
pub(crate) fn clause_to_evacuable(&mut self) -> CallResult {
|
||||
let loader = self.loader_from_heap_evacuable(temp_v!(2));
|
||||
let compilation_target = loader.payload.compilation_target;
|
||||
|
||||
let result = loader.read_and_enqueue_term(temp_v!(1), compilation_target);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn conclude_load(&mut self) {
|
||||
pub(crate) fn conclude_load(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(1));
|
||||
|
||||
let compile_final_terms = || {
|
||||
@@ -1786,7 +1776,7 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = compile_final_terms();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn load_context_source(&mut self) {
|
||||
@@ -1852,7 +1842,7 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compile_assert<'a>(&'a mut self, append_or_prepend: AppendOrPrepend) {
|
||||
pub(crate) fn compile_assert<'a>(&'a mut self, append_or_prepend: AppendOrPrepend) -> CallResult {
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(3)], self.machine_st[temp_v!(4)]);
|
||||
@@ -1906,26 +1896,27 @@ impl Machine {
|
||||
};
|
||||
|
||||
match compile_assert() {
|
||||
Ok(_) => {}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
let error_pi = match append_or_prepend {
|
||||
AppendOrPrepend::Append => (atom!("assertz"), 1),
|
||||
AppendOrPrepend::Prepend => (atom!("asserta"), 1),
|
||||
let stub = match append_or_prepend {
|
||||
AppendOrPrepend::Append => functor_stub(atom!("assertz"), 1),
|
||||
AppendOrPrepend::Prepend => functor_stub(atom!("asserta"), 1),
|
||||
};
|
||||
let err = self.machine_st.session_error(e);
|
||||
|
||||
self.throw_session_error(e, error_pi);
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn abolish_clause(&mut self) {
|
||||
pub(crate) fn abolish_clause(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(2)], self.machine_st[temp_v!(3)]);
|
||||
.read_predicate_key(self.machine_st.registers[2], self.machine_st.registers[3]);
|
||||
|
||||
let compilation_target = match module_name {
|
||||
atom!("user") => CompilationTarget::User,
|
||||
@@ -2000,14 +1991,16 @@ impl Machine {
|
||||
};
|
||||
|
||||
match abolish_clause() {
|
||||
Ok(_) => {}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
self.throw_session_error(e, (atom!("abolish"), 1));
|
||||
let stub = functor_stub(atom!("abolish"), 1);
|
||||
let err = self.machine_st.session_error(e);
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn retract_clause(&mut self) {
|
||||
pub(crate) fn retract_clause(&mut self) -> CallResult {
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(1)], self.machine_st[temp_v!(2)]);
|
||||
@@ -2066,14 +2059,17 @@ impl Machine {
|
||||
};
|
||||
|
||||
match retract_clause() {
|
||||
Ok(_) => {}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
self.throw_session_error(e, (atom!("retract"), 1));
|
||||
let stub = functor_stub(atom!("retract"), 1);
|
||||
let err = self.machine_st.session_error(e);
|
||||
|
||||
Err(self.machine_st.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_consistent_with_term_queue(&mut self) {
|
||||
pub(crate) fn is_consistent_with_term_queue(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -2095,10 +2091,10 @@ impl Machine {
|
||||
|| !key.is_consistent(&loader.payload.predicates);
|
||||
|
||||
let result = LiveLoadAndMachineState::evacuate(loader);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn flush_term_queue(&mut self) {
|
||||
pub(crate) fn flush_term_queue(&mut self) -> CallResult {
|
||||
let mut loader = self.loader_from_heap_evacuable(temp_v!(1));
|
||||
|
||||
let flush_term_queue = || {
|
||||
@@ -2110,10 +2106,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = flush_term_queue();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn remove_module_exports(&mut self) {
|
||||
pub(crate) fn remove_module_exports(&mut self) -> CallResult {
|
||||
let module_name = cell_as_atom!(
|
||||
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
|
||||
);
|
||||
@@ -2126,10 +2122,10 @@ impl Machine {
|
||||
};
|
||||
|
||||
let result = remove_module_exports();
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn add_non_counted_backtracking(&mut self) {
|
||||
pub(crate) fn add_non_counted_backtracking(&mut self) -> CallResult {
|
||||
let key = self
|
||||
.machine_st
|
||||
.read_predicate_key(self.machine_st[temp_v!(1)], self.machine_st[temp_v!(2)]);
|
||||
@@ -2138,7 +2134,7 @@ impl Machine {
|
||||
loader.payload.non_counted_bt_preds.insert(key);
|
||||
|
||||
let result = LiveLoadAndMachineState::evacuate(loader);
|
||||
self.restore_load_state_payload(result);
|
||||
self.restore_load_state_payload(result)
|
||||
}
|
||||
|
||||
pub(crate) fn meta_predicate_property(&mut self) {
|
||||
@@ -2271,10 +2267,10 @@ impl Machine {
|
||||
.read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
|
||||
|
||||
match ClauseType::from(key.0, key.1) {
|
||||
ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN => {
|
||||
ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN(_) => {
|
||||
return;
|
||||
}
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) {
|
||||
self.machine_st.fail = !module.code_dir.contains_key(&(name, arity));
|
||||
return;
|
||||
|
||||
@@ -538,13 +538,18 @@ impl MachineState {
|
||||
|
||||
pub(super) fn throw_exception(&mut self, err: MachineStub) {
|
||||
let h = self.heap.len();
|
||||
let err_len = err.len();
|
||||
|
||||
self.ball.boundary = 0;
|
||||
self.ball.stub.truncate(0);
|
||||
|
||||
self.heap.extend(err.into_iter());
|
||||
|
||||
self.registers[1] = str_loc_as_cell!(h);
|
||||
self.registers[1] = if err_len == 1 {
|
||||
heap_loc_as_cell!(h)
|
||||
} else {
|
||||
str_loc_as_cell!(h)
|
||||
};
|
||||
|
||||
self.set_ball();
|
||||
self.unwind_stack();
|
||||
|
||||
@@ -2,30 +2,22 @@ use crate::parser::ast::*;
|
||||
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::MachineStub;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::streams::Stream;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeSet;
|
||||
use std::ops::{Add, AddAssign, Deref, Sub, SubAssign};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
// these statics store the locations of one-off control instructions
|
||||
// in the code vector.
|
||||
|
||||
pub static HALT_CODE: usize = 0;
|
||||
|
||||
use crate::types::*;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub(crate) struct OrderedOpDirKey(pub(crate) Atom, pub(crate) Fixity);
|
||||
@@ -134,6 +126,7 @@ impl Default for CodeIndex {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
|
||||
pub enum REPLCodePtr {
|
||||
AddDiscontiguousPredicate,
|
||||
@@ -174,156 +167,28 @@ pub enum REPLCodePtr {
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum CodePtr {
|
||||
BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
|
||||
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
|
||||
Local(LocalCodePtr),
|
||||
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
|
||||
BuiltInClause(BuiltInClauseType, usize), // local is the successor call.
|
||||
CallN(usize, usize, bool), // arity, local, last call.
|
||||
Local(usize),
|
||||
REPL(REPLCodePtr, usize), // the REPL code, the return pointer.
|
||||
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
|
||||
}
|
||||
|
||||
impl CodePtr {
|
||||
pub(crate) fn local(&self) -> LocalCodePtr {
|
||||
pub(crate) fn local(&self) -> usize {
|
||||
match self {
|
||||
&CodePtr::BuiltInClause(_, ref local)
|
||||
| &CodePtr::CallN(_, ref local, _)
|
||||
| &CodePtr::Local(ref local) => local.clone(),
|
||||
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
||||
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
|
||||
&CodePtr::BuiltInClause(_, ref local) |
|
||||
&CodePtr::CallN(_, ref local, _) |
|
||||
&CodePtr::Local(ref local) => *local,
|
||||
&CodePtr::VerifyAttrInterrupt(p) => p,
|
||||
&CodePtr::REPL(_, p) => p,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_halt(&self) -> bool {
|
||||
if let CodePtr::Local(LocalCodePtr::Halt) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum LocalCodePtr {
|
||||
DirEntry(usize), // offset
|
||||
Halt,
|
||||
// IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
|
||||
// TopLevel(usize, usize), // chunk_num, offset
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub(crate) fn is_reset_cont_marker(&self, p: LocalCodePtr) -> bool {
|
||||
match self.code_repo.lookup_instr(&self.machine_st, &CodePtr::Local(p)) {
|
||||
Some(line) => match line.as_ref(&self.code_repo.code) {
|
||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pub fn assign_if_local(&self, cp: &mut usize) {
|
||||
match self {
|
||||
CodePtr::Local(local) => *cp = *local,
|
||||
_ => {}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalCodePtr {
|
||||
pub fn assign_if_local(&mut self, cp: CodePtr) {
|
||||
match cp {
|
||||
CodePtr::Local(local) => *self = local,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn abs_loc(&self) -> usize {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref p) => *p,
|
||||
// LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_functor(&self) -> MachineStub {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => {
|
||||
functor!(atom!("dir_entry"), [fixnum(*p)])
|
||||
}
|
||||
LocalCodePtr::Halt => {
|
||||
functor!(atom!("halt"))
|
||||
}
|
||||
/*
|
||||
LocalCodePtr::IndexingBuf(p, o, i) => {
|
||||
functor!(
|
||||
atom!("indexed_buf"),
|
||||
[fixnum(*p), fixnum(*o), fixnum(*i)]
|
||||
)
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CodePtr {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
CodePtr::Local(LocalCodePtr::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LocalCodePtr {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
LocalCodePtr::DirEntry(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for LocalCodePtr {
|
||||
type Output = LocalCodePtr;
|
||||
|
||||
#[inline]
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
// LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<usize> for LocalCodePtr {
|
||||
type Output = Option<LocalCodePtr>;
|
||||
|
||||
#[inline]
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
// LocalCodePtr::IndexingBuf(p, o, i) => i
|
||||
// .checked_sub(rhs)
|
||||
// .map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, rhs: usize) {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
|
||||
LocalCodePtr::Halt => unreachable!() // | LocalCodePtr::IndexingBuf(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
match self {
|
||||
&mut LocalCodePtr::DirEntry(ref mut i) => *i += rhs,
|
||||
// | &mut LocalCodePtr::IndexingBuf(_, _, ref mut i) => *i += rhs,
|
||||
&mut LocalCodePtr::Halt => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,7 +198,9 @@ impl Add<usize> for CodePtr {
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => p,
|
||||
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
|
||||
p
|
||||
}
|
||||
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
||||
CodePtr::Local(local + rhs)
|
||||
@@ -362,20 +229,30 @@ impl SubAssign<usize> for CodePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue>;
|
||||
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData>;
|
||||
impl Default for CodePtr {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
CodePtr::Local(0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>)>;
|
||||
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue, FxBuildHasher>;
|
||||
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData, FxBuildHasher>;
|
||||
|
||||
pub(crate) type StreamAliasDir = IndexMap<Atom, Stream>;
|
||||
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>;
|
||||
|
||||
pub(crate) type StreamAliasDir = IndexMap<Atom, Stream, FxBuildHasher>;
|
||||
pub(crate) type StreamDir = BTreeSet<Stream>;
|
||||
|
||||
pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>>;
|
||||
pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>, FxBuildHasher>;
|
||||
|
||||
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>;
|
||||
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton, FxBuildHasher>;
|
||||
|
||||
pub(crate) type LocalExtensiblePredicates =
|
||||
IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton>;
|
||||
IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton, FxBuildHasher>;
|
||||
|
||||
pub(crate) type CodeDir = IndexMap<PredicateKey, CodeIndex, FxBuildHasher>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexStore {
|
||||
@@ -504,14 +381,14 @@ impl IndexStore {
|
||||
) -> Option<CodeIndex> {
|
||||
if module == atom!("user") {
|
||||
match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||
ClauseType::Named(arity, name, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
self.modules
|
||||
.get(&module)
|
||||
.and_then(|module| match ClauseType::from(name, arity) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
ClauseType::Named(arity, name, _) => {
|
||||
module.code_dir.get(&(name, arity)).cloned()
|
||||
}
|
||||
_ => None,
|
||||
@@ -561,8 +438,10 @@ impl IndexStore {
|
||||
|
||||
#[inline]
|
||||
pub(super) fn new() -> Self {
|
||||
index_store!(CodeDir::new(), default_op_dir(), ModuleDir::new())
|
||||
index_store!(
|
||||
CodeDir::with_hasher(FxBuildHasher::default()),
|
||||
default_op_dir(),
|
||||
ModuleDir::with_hasher(FxBuildHasher::default())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type CodeDir = IndexMap<PredicateKey, CodeIndex>;
|
||||
|
||||
@@ -55,14 +55,14 @@ pub struct MachineState {
|
||||
pub arena: Arena,
|
||||
pub(super) pdl: Vec<HeapCellValue>,
|
||||
pub(super) s: HeapPtr,
|
||||
pub(super) p: CodePtr,
|
||||
pub(super) p: usize,
|
||||
pub(super) oip: u32, // first internal code ptr
|
||||
pub(super) iip : u32, // second internal code ptr
|
||||
pub(super) b: usize,
|
||||
pub(super) b0: usize,
|
||||
pub(super) e: usize,
|
||||
pub(super) num_of_args: usize,
|
||||
pub(super) cp: LocalCodePtr,
|
||||
pub(super) cp: usize,
|
||||
pub(super) attr_var_init: AttrVarInitializer,
|
||||
pub(super) fail: bool,
|
||||
pub heap: Heap,
|
||||
@@ -79,7 +79,6 @@ pub struct MachineState {
|
||||
// locations of cleaners, cut points, the previous block. for setup_call_cleanup.
|
||||
pub(super) cont_pts: Vec<(HeapCellValue, usize, usize)>,
|
||||
pub(super) cwil: CWIL,
|
||||
pub(super) last_call: bool, // TODO: REMOVE THIS.
|
||||
pub(crate) flags: MachineFlags,
|
||||
pub(crate) cc: usize,
|
||||
pub(crate) global_clock: usize,
|
||||
@@ -115,7 +114,6 @@ impl fmt::Debug for MachineState {
|
||||
.field("ball", &self.ball)
|
||||
.field("lifted_heap", &self.lifted_heap)
|
||||
.field("interms", &self.interms)
|
||||
.field("last_call", &self.last_call)
|
||||
.field("flags", &self.flags)
|
||||
.field("cc", &self.cc)
|
||||
.field("global_clock", &self.global_clock)
|
||||
@@ -365,6 +363,20 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate) fn backtrack(&mut self) {
|
||||
let b = self.b;
|
||||
let or_frame = self.stack.index_or_frame(b);
|
||||
|
||||
self.b0 = or_frame.prelude.b0;
|
||||
self.p = or_frame.prelude.bp;
|
||||
|
||||
self.oip = or_frame.prelude.boip;
|
||||
self.iip = or_frame.prelude.biip;
|
||||
|
||||
self.pdl.clear();
|
||||
self.fail = false;
|
||||
}
|
||||
|
||||
pub(crate) fn increment_call_count(&mut self) -> CallResult {
|
||||
if self.cwil.inference_limit_exceeded || self.ball.stub.len() > 0 {
|
||||
return Ok(());
|
||||
@@ -422,17 +434,19 @@ impl MachineState {
|
||||
self.error_form(err, stub)
|
||||
}
|
||||
|
||||
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
self.cp.assign_if_local(self.p + 1);
|
||||
#[inline(always)]
|
||||
pub(super) fn call_at_index(&mut self, arity: usize, p: usize) {
|
||||
self.cp = self.p + 1;
|
||||
self.p = p;
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
#[inline(always)]
|
||||
pub(super) fn execute_at_index(&mut self, arity: usize, p: usize) {
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
self.p = p;
|
||||
}
|
||||
|
||||
pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
|
||||
@@ -467,7 +481,7 @@ impl MachineState {
|
||||
|
||||
if stream.past_end_of_stream() {
|
||||
if EOFAction::Reset != stream.options().eof_action() {
|
||||
return return_from_clause!(self.last_call, self);
|
||||
return Ok(());
|
||||
} else if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -710,7 +724,7 @@ impl MachineState {
|
||||
or_frame.prelude.e = self.e;
|
||||
or_frame.prelude.cp = self.cp;
|
||||
or_frame.prelude.b = self.b;
|
||||
or_frame.prelude.bp = self.p.local() + offset;
|
||||
or_frame.prelude.bp = self.p + offset;
|
||||
or_frame.prelude.boip = 0;
|
||||
or_frame.prelude.biip = 0;
|
||||
or_frame.prelude.tr = self.tr;
|
||||
@@ -720,7 +734,7 @@ impl MachineState {
|
||||
self.b = b;
|
||||
|
||||
for i in 0..n {
|
||||
self.stack[stack_loc!(OrFrame, b, i)] = self.registers[i+1];
|
||||
or_frame[i] = self.registers[i+1];
|
||||
}
|
||||
|
||||
self.hb = self.heap.len();
|
||||
@@ -737,7 +751,7 @@ impl MachineState {
|
||||
or_frame.prelude.e = self.e;
|
||||
or_frame.prelude.cp = self.cp;
|
||||
or_frame.prelude.b = self.b;
|
||||
or_frame.prelude.bp = self.p.local(); // + 1; in self.iip now!
|
||||
or_frame.prelude.bp = self.p; // + 1; in self.iip now!
|
||||
or_frame.prelude.boip = self.oip;
|
||||
or_frame.prelude.biip = self.iip + 1;
|
||||
or_frame.prelude.tr = self.tr;
|
||||
@@ -751,7 +765,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
self.hb = self.heap.len();
|
||||
self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset));
|
||||
self.p = self.p + offset;
|
||||
|
||||
self.oip = 0;
|
||||
self.iip = 0;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::types::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::attributed_variables::*;
|
||||
use crate::machine::copier::*;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::Machine;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
@@ -23,11 +21,6 @@ use indexmap::IndexSet;
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
// TODO: move this block to.. a place.
|
||||
impl Machine {
|
||||
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate) fn new() -> Self {
|
||||
MachineState {
|
||||
@@ -35,14 +28,14 @@ impl MachineState {
|
||||
atom_tbl: AtomTable::new(),
|
||||
pdl: Vec::with_capacity(1024),
|
||||
s: HeapPtr::default(),
|
||||
p: CodePtr::default(),
|
||||
p: 0,
|
||||
oip: 0,
|
||||
iip: 0,
|
||||
b: 0,
|
||||
b0: 0,
|
||||
e: 0,
|
||||
num_of_args: 0,
|
||||
cp: LocalCodePtr::default(),
|
||||
cp: 0,
|
||||
attr_var_init: AttrVarInitializer::new(0),
|
||||
fail: false,
|
||||
heap: Heap::with_capacity(256 * 256),
|
||||
@@ -58,7 +51,6 @@ impl MachineState {
|
||||
interms: vec![Number::default();256],
|
||||
cont_pts: Vec::with_capacity(256),
|
||||
cwil: CWIL::new(),
|
||||
last_call: false,
|
||||
flags: MachineFlags::default(),
|
||||
cc: 0,
|
||||
global_clock: 0,
|
||||
@@ -202,16 +194,16 @@ impl MachineState {
|
||||
match r1.get_tag() {
|
||||
RefTag::StackCell => {
|
||||
self.stack[r1.get_value() as usize] = t2;
|
||||
self.trail(TrailRef::Ref(r1));
|
||||
}
|
||||
RefTag::HeapCell => {
|
||||
self.heap[r1.get_value() as usize] = t2;
|
||||
self.trail(TrailRef::Ref(r1));
|
||||
}
|
||||
RefTag::AttrVar => {
|
||||
self.bind_attr_var(r1.get_value() as usize, t2);
|
||||
}
|
||||
};
|
||||
|
||||
self.trail(TrailRef::Ref(r1));
|
||||
} else {
|
||||
read_heap_cell!(a2,
|
||||
(HeapCellValueTag::StackVar, s) => {
|
||||
@@ -864,17 +856,6 @@ impl MachineState {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn copy_term(&mut self, attr_var_policy: AttrVarPolicy) {
|
||||
let old_h = self.heap.len();
|
||||
|
||||
let a1 = self.registers[1];
|
||||
let a2 = self.registers[2];
|
||||
|
||||
copy_term(CopyTerm::new(self), a1, attr_var_policy);
|
||||
|
||||
unify_fn!(*self, heap_loc_as_cell!(old_h), a2);
|
||||
}
|
||||
|
||||
pub(super) fn unwind_stack(&mut self) {
|
||||
self.b = self.block;
|
||||
self.fail = true;
|
||||
@@ -1912,9 +1893,6 @@ impl MachineState {
|
||||
);
|
||||
}
|
||||
Some(PStrPrefixCmpResult { prefix_len, .. }) => {
|
||||
// TODO: this is woefully insufficient! you need to
|
||||
// match the remaining portion of string if offset <
|
||||
// pstr.len().
|
||||
let focus = heap_pstr_iter.focus();
|
||||
let tail_addr = self.heap[focus];
|
||||
|
||||
@@ -1996,23 +1974,7 @@ impl MachineState {
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn handle_internal_call_n(&mut self, arity: usize) {
|
||||
let arity = arity + 1;
|
||||
let pred = self.registers[1];
|
||||
|
||||
for i in 2..arity {
|
||||
self.registers[i - 1] = self.registers[i];
|
||||
}
|
||||
|
||||
if arity > 1 {
|
||||
self.registers[arity - 1] = pred;
|
||||
return;
|
||||
}
|
||||
|
||||
self.fail = true;
|
||||
}
|
||||
|
||||
pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey> {
|
||||
pub(super) fn setup_call_n(&mut self, arity: usize) -> Result<PredicateKey, MachineStub> {
|
||||
let addr = self.store(self.deref(self.registers[arity]));
|
||||
|
||||
let (name, narity) = read_heap_cell!(addr,
|
||||
@@ -2022,10 +1984,7 @@ impl MachineState {
|
||||
if narity + arity > MAX_ARITY {
|
||||
let stub = functor_stub(atom!("call"), arity + 1);
|
||||
let err = self.representation_error(RepFlag::MaxArity);
|
||||
let representation_error = self.error_form(err, stub);
|
||||
|
||||
self.throw_exception(representation_error);
|
||||
return None;
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
|
||||
for i in (1..arity).rev() {
|
||||
@@ -2039,12 +1998,8 @@ impl MachineState {
|
||||
(name, narity)
|
||||
}
|
||||
(HeapCellValueTag::Atom, (name, arity)) => {
|
||||
if arity == 0 {
|
||||
debug_assert_eq!(arity, 0);
|
||||
(name, 0)
|
||||
} else {
|
||||
self.fail = true;
|
||||
return None;
|
||||
}
|
||||
}
|
||||
(HeapCellValueTag::Char, c) => {
|
||||
(self.atom_tbl.build_with(&c.to_string()), 0)
|
||||
@@ -2052,22 +2007,16 @@ impl MachineState {
|
||||
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, _h) => {
|
||||
let stub = functor_stub(atom!("call"), arity + 1);
|
||||
let err = self.instantiation_error();
|
||||
let instantiation_error = self.error_form(err, stub);
|
||||
|
||||
self.throw_exception(instantiation_error);
|
||||
return None;
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
_ => {
|
||||
let stub = functor_stub(atom!("call"), arity + 1);
|
||||
let err = self.type_error(ValidType::Callable, addr);
|
||||
let type_error = self.error_form(err, stub);
|
||||
|
||||
self.throw_exception(type_error);
|
||||
return None;
|
||||
return Err(self.error_form(err, stub));
|
||||
}
|
||||
);
|
||||
|
||||
Some((name, arity + narity - 1))
|
||||
Ok((name, arity + narity - 1))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -2233,45 +2182,6 @@ impl MachineState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compare_numbers(&mut self, cmp: CompareNumberQT, n1: Number, n2: Number) {
|
||||
let ordering = n1.cmp(&n2);
|
||||
|
||||
self.fail = match cmp {
|
||||
CompareNumberQT::GreaterThan if ordering == Ordering::Greater => false,
|
||||
CompareNumberQT::GreaterThanOrEqual if ordering != Ordering::Less => false,
|
||||
CompareNumberQT::LessThan if ordering == Ordering::Less => false,
|
||||
CompareNumberQT::LessThanOrEqual if ordering != Ordering::Greater => false,
|
||||
CompareNumberQT::NotEqual if ordering != Ordering::Equal => false,
|
||||
CompareNumberQT::Equal if ordering == Ordering::Equal => false,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
self.p += 1;
|
||||
}
|
||||
|
||||
pub fn compare_term(&mut self, qt: CompareTermQT) {
|
||||
let a1 = self.registers[1];
|
||||
let a2 = self.registers[2];
|
||||
|
||||
match compare_term_test!(self, a1, a2) {
|
||||
Some(Ordering::Greater) => match qt {
|
||||
CompareTermQT::GreaterThan | CompareTermQT::GreaterThanOrEqual => {}
|
||||
_ => self.fail = true,
|
||||
},
|
||||
Some(Ordering::Equal) => match qt {
|
||||
CompareTermQT::GreaterThanOrEqual | CompareTermQT::LessThanOrEqual => {}
|
||||
_ => self.fail = true,
|
||||
},
|
||||
Some(Ordering::Less) => match qt {
|
||||
CompareTermQT::LessThan | CompareTermQT::LessThanOrEqual => {}
|
||||
_ => self.fail = true,
|
||||
},
|
||||
None => {
|
||||
self.fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true on failure, false on success.
|
||||
pub fn eq_test(&mut self, h1: HeapCellValue, h2: HeapCellValue) -> bool {
|
||||
if h1 == h2 {
|
||||
@@ -2652,12 +2562,14 @@ impl MachineState {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn setup_built_in_call(&mut self, ct: BuiltInClauseType) {
|
||||
self.num_of_args = ct.arity();
|
||||
self.b0 = self.b;
|
||||
|
||||
self.p = CodePtr::BuiltInClause(ct, self.p.local());
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn deallocate(&mut self) {
|
||||
let e = self.e;
|
||||
|
||||
@@ -227,7 +227,7 @@ impl Machine {
|
||||
let mut wam = Machine {
|
||||
machine_st,
|
||||
indices: IndexStore::new(),
|
||||
code_repo: CodeRepo::new(),
|
||||
code: Code::new(),
|
||||
user_input,
|
||||
user_output,
|
||||
user_error,
|
||||
@@ -239,6 +239,8 @@ impl Machine {
|
||||
lib_path.pop();
|
||||
lib_path.push("lib");
|
||||
|
||||
wam.add_impls_to_indices();
|
||||
|
||||
bootstrapping_compile(
|
||||
Stream::from_static_string(
|
||||
LIBRARIES.borrow()["ops_and_meta_predicates"],
|
||||
@@ -262,7 +264,7 @@ impl Machine {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(builtins) = wam.indices.modules.get(&atom!("builtins")) {
|
||||
if let Some(ref mut builtins) = wam.indices.modules.get_mut(&atom!("builtins")) {
|
||||
load_module(
|
||||
&mut wam.indices.code_dir,
|
||||
&mut wam.indices.op_dir,
|
||||
@@ -270,6 +272,8 @@ impl Machine {
|
||||
&CompilationTarget::User,
|
||||
builtins,
|
||||
);
|
||||
|
||||
import_builtin_impls(&wam.indices.code_dir, builtins);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
@@ -207,34 +207,6 @@ fn setup_use_module_decl(mut terms: Vec<Term>) -> Result<ModuleSource, Compilati
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn setup_double_quotes(mut terms: Vec<Box<Term>>) -> Result<DoubleQuotes, CompilationError> {
|
||||
let dbl_quotes = *terms.pop().unwrap();
|
||||
|
||||
match terms[0].as_ref() {
|
||||
Term::Literal(_, Literal::Atom(ref name, _))
|
||||
if name.as_str() == "double_quotes" => {
|
||||
match dbl_quotes {
|
||||
Term::Literal(_, Literal::Atom(name, _)) => {
|
||||
match name.as_str() {
|
||||
"atom" => Ok(DoubleQuotes::Atom),
|
||||
"chars" => Ok(DoubleQuotes::Chars),
|
||||
"codes" => Ok(DoubleQuotes::Codes),
|
||||
_ => Err(CompilationError::InvalidDoubleQuotesDecl),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidDoubleQuotesDecl)
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Err(CompilationError::InvalidDoubleQuotesDecl)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
type UseModuleExport = (ModuleSource, IndexSet<ModuleExport>);
|
||||
|
||||
fn setup_qualified_import(
|
||||
@@ -735,7 +707,7 @@ impl Preprocessor {
|
||||
},
|
||||
Term::Var(..) => Ok(QueryTerm::Clause(
|
||||
Cell::default(),
|
||||
ClauseType::CallN,
|
||||
ClauseType::CallN(1),
|
||||
vec![term],
|
||||
false,
|
||||
)),
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::types::*;
|
||||
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::raw_block::*;
|
||||
use crate::types::*;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::{Index, IndexMut};
|
||||
@@ -47,8 +45,7 @@ pub(crate) struct FramePrelude {
|
||||
pub(crate) struct AndFramePrelude {
|
||||
pub(crate) univ_prelude: FramePrelude,
|
||||
pub(crate) e: usize,
|
||||
pub(crate) cp: LocalCodePtr,
|
||||
pub(crate) interrupt_cp: LocalCodePtr, // TODO: get rid of it!
|
||||
pub(crate) cp: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -118,9 +115,9 @@ impl IndexMut<usize> for Stack {
|
||||
pub(crate) struct OrFramePrelude {
|
||||
pub(crate) univ_prelude: FramePrelude,
|
||||
pub(crate) e: usize,
|
||||
pub(crate) cp: LocalCodePtr,
|
||||
pub(crate) cp: usize,
|
||||
pub(crate) b: usize,
|
||||
pub(crate) bp: LocalCodePtr,
|
||||
pub(crate) bp: usize,
|
||||
pub(crate) boip: u32,
|
||||
pub(crate) biip: u32,
|
||||
pub(crate) tr: usize,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
256
src/macros.rs
256
src/macros.rs
@@ -1,9 +1,3 @@
|
||||
macro_rules! interm {
|
||||
($n: expr) => {
|
||||
ArithmeticTerm::Interm($n)
|
||||
};
|
||||
}
|
||||
|
||||
/* A simple macro to count the arguments in a variadic list
|
||||
* of token trees.
|
||||
*/
|
||||
@@ -524,6 +518,35 @@ macro_rules! functor_term {
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! compare_number_instr {
|
||||
($cmp: expr, $at_1: expr, $at_2: expr) => {{
|
||||
$cmp.set_terms($at_1, $at_2);
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp)), 0)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! call_clause {
|
||||
($clause_type:expr, $pvs:expr) => {{
|
||||
let mut instr = $clause_type.to_instr();
|
||||
instr.perm_vars_mut().map(|pvs| *pvs = $pvs);
|
||||
instr
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! call_clause_by_default {
|
||||
($clause_type:expr, $pvs:expr) => {{
|
||||
let mut instr = $clause_type.to_instr().to_default();
|
||||
instr.perm_vars_mut().map(|pvs| *pvs = $pvs);
|
||||
instr
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! interm {
|
||||
($n: expr) => {
|
||||
ArithmeticTerm::Interm($n)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! ar_reg {
|
||||
($r: expr) => {
|
||||
ArithmeticTerm::Reg($r)
|
||||
@@ -545,229 +568,18 @@ macro_rules! index_store {
|
||||
($code_dir:expr, $op_dir:expr, $modules:expr) => {
|
||||
IndexStore {
|
||||
code_dir: $code_dir,
|
||||
extensible_predicates: ExtensiblePredicates::new(),
|
||||
local_extensible_predicates: LocalExtensiblePredicates::new(),
|
||||
global_variables: GlobalVarDir::new(),
|
||||
meta_predicates: MetaPredicateDir::new(),
|
||||
extensible_predicates: ExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||
local_extensible_predicates: LocalExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||
global_variables: GlobalVarDir::with_hasher(FxBuildHasher::default()),
|
||||
meta_predicates: MetaPredicateDir::with_hasher(FxBuildHasher::default()),
|
||||
modules: $modules,
|
||||
op_dir: $op_dir,
|
||||
streams: StreamDir::new(),
|
||||
stream_aliases: StreamAliasDir::new(),
|
||||
stream_aliases: StreamAliasDir::with_hasher(FxBuildHasher::default()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_atom {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_atomic {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtomic($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_integer {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsInteger($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_compound {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsCompound($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_float {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsFloat($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_rational {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsRational($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_number {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsNumber($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_nonvar {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_var {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::Inlined(InlinedClauseType::IsVar($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! call_clause {
|
||||
($ct:expr, $arity:expr, $pvs:expr) => {
|
||||
Line::Control(ControlInstruction::CallClause(
|
||||
$ct, $arity, $pvs, false, false,
|
||||
))
|
||||
};
|
||||
($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => {
|
||||
Line::Control(ControlInstruction::CallClause(
|
||||
$ct, $arity, $pvs, $lco, false,
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! call_clause_by_default {
|
||||
($ct:expr, $arity:expr, $pvs:expr) => {
|
||||
Line::Control(ControlInstruction::CallClause(
|
||||
$ct, $arity, $pvs, false, true,
|
||||
))
|
||||
};
|
||||
($ct:expr, $arity:expr, $pvs:expr, $lco:expr) => {
|
||||
Line::Control(ControlInstruction::CallClause(
|
||||
$ct, $arity, $pvs, $lco, true,
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! proceed {
|
||||
() => {
|
||||
Line::Control(ControlInstruction::Proceed)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_call {
|
||||
($r:expr, $at:expr) => {
|
||||
call_clause!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_call_by_default {
|
||||
($r:expr, $at:expr) => {
|
||||
call_clause_by_default!(ClauseType::BuiltIn(BuiltInClauseType::Is($r, $at)), 2, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! set_cp {
|
||||
($r:expr) => {
|
||||
call_clause!(ClauseType::System(SystemClauseType::SetCutPoint($r)), 1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! succeed {
|
||||
() => {
|
||||
call_clause!(ClauseType::System(SystemClauseType::Succeed), 0, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! fail {
|
||||
() => {
|
||||
call_clause!(ClauseType::System(SystemClauseType::Fail), 0, 0)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! compare_number_instr {
|
||||
($cmp: expr, $at_1: expr, $at_2: expr) => {{
|
||||
let ct = ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp, $at_1, $at_2));
|
||||
call_clause!(ct, 2, 0)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! jmp_call {
|
||||
($arity:expr, $offset:expr, $pvs:expr) => {
|
||||
Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! return_from_clause {
|
||||
($lco:expr, $machine_st:expr) => {{
|
||||
if let CodePtr::VerifyAttrInterrupt(_) = $machine_st.p {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if $lco {
|
||||
$machine_st.p = CodePtr::Local($machine_st.cp);
|
||||
} else {
|
||||
$machine_st.p += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! dir_entry {
|
||||
($idx:expr) => {
|
||||
LocalCodePtr::DirEntry($idx)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! put_constant {
|
||||
($lvl:expr, $cons:expr, $r:expr) => {
|
||||
QueryInstruction::PutConstant($lvl, $cons, $r)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! get_level_and_unify {
|
||||
($r: expr) => {
|
||||
Line::Cut(CutInstruction::GetLevelAndUnify($r))
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
macro_rules! unwind_protect {
|
||||
($e: expr, $protected: expr) => {
|
||||
match $e {
|
||||
Err(e) => {
|
||||
$protected;
|
||||
return Err(e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
/*
|
||||
macro_rules! discard_result {
|
||||
($f: expr) => {
|
||||
match $f {
|
||||
_ => (),
|
||||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
macro_rules! try_or_fail {
|
||||
($s:expr, $e:expr) => {{
|
||||
match $e {
|
||||
Ok(val) => val,
|
||||
Err(msg) => {
|
||||
$s.throw_exception(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! try_or_fail_gen {
|
||||
($s:expr, $e:expr) => {{
|
||||
match $e {
|
||||
Ok(val) => val,
|
||||
Err(msg_fn) => {
|
||||
let e = msg_fn($s);
|
||||
$s.throw_exception(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! unify {
|
||||
($machine_st:expr, $($value:expr),*) => {{
|
||||
$($machine_st.pdl.push($value);)*
|
||||
|
||||
@@ -13,6 +13,7 @@ use std::vec::Vec;
|
||||
|
||||
use rug::{Integer, Rational};
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
use indexmap::IndexMap;
|
||||
use modular_bitfield::error::OutOfBounds;
|
||||
use modular_bitfield::prelude::*;
|
||||
@@ -286,7 +287,7 @@ impl OpDesc {
|
||||
}
|
||||
|
||||
// name and fixity -> operator type and precedence.
|
||||
pub type OpDir = IndexMap<(Atom, Fixity), OpDesc>;
|
||||
pub type OpDir = IndexMap<(Atom, Fixity), OpDesc, FxBuildHasher>;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct MachineFlags {
|
||||
@@ -329,7 +330,7 @@ impl Default for DoubleQuotes {
|
||||
}
|
||||
|
||||
pub fn default_op_dir() -> OpDir {
|
||||
let mut op_dir = OpDir::new();
|
||||
let mut op_dir = OpDir::with_hasher(FxBuildHasher::default());
|
||||
|
||||
op_dir.insert(
|
||||
(atom!(":-"), Fixity::In),
|
||||
|
||||
@@ -12,6 +12,8 @@ use crate::machine::streams::*;
|
||||
use crate::parser::char_reader::*;
|
||||
use crate::types::*;
|
||||
|
||||
use fxhash::FxBuildHasher;
|
||||
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::{Cmd, Config, Editor, KeyEvent};
|
||||
|
||||
@@ -257,7 +259,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
||||
heap,
|
||||
atom_tbl,
|
||||
queue: SubtermDeque::new(),
|
||||
var_dict: HeapVarDict::new(),
|
||||
var_dict: HeapVarDict::with_hasher(FxBuildHasher::default()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
152
src/targets.rs
152
src/targets.rs
@@ -1,39 +1,41 @@
|
||||
use crate::parser::ast::*;
|
||||
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
use crate::types::*;
|
||||
|
||||
pub(crate) struct FactInstruction;
|
||||
pub(crate) struct QueryInstruction;
|
||||
|
||||
pub(crate) trait CompilationTarget<'a> {
|
||||
type Iterator: Iterator<Item = TermRef<'a>>;
|
||||
|
||||
fn iter(term: &'a Term) -> Self::Iterator;
|
||||
|
||||
fn to_constant(lvl: Level, literal: Literal, r: RegType) -> Self;
|
||||
fn to_list(lvl: Level, r: RegType) -> Self;
|
||||
fn to_structure(ct: ClauseType, arity: usize, r: RegType) -> Self;
|
||||
fn to_constant(lvl: Level, literal: Literal, r: RegType) -> Instruction;
|
||||
fn to_list(lvl: Level, r: RegType) -> Instruction;
|
||||
fn to_structure(name: Atom, arity: usize, r: RegType) -> Instruction;
|
||||
|
||||
fn to_void(num_subterms: usize) -> Self;
|
||||
fn is_void_instr(&self) -> bool;
|
||||
fn to_void(num_subterms: usize) -> Instruction;
|
||||
fn is_void_instr(instr: &Instruction) -> bool;
|
||||
|
||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Self;
|
||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction;
|
||||
|
||||
fn incr_void_instr(&mut self);
|
||||
fn incr_void_instr(instr: &mut Instruction);
|
||||
|
||||
fn constant_subterm(literal: Literal) -> Self;
|
||||
fn constant_subterm(literal: Literal) -> Instruction;
|
||||
|
||||
fn argument_to_variable(r: RegType, r: usize) -> Self;
|
||||
fn argument_to_value(r: RegType, val: usize) -> Self;
|
||||
fn argument_to_variable(r: RegType, r: usize) -> Instruction;
|
||||
fn argument_to_value(r: RegType, val: usize) -> Instruction;
|
||||
|
||||
fn move_to_register(r: RegType, val: usize) -> Self;
|
||||
fn move_to_register(r: RegType, val: usize) -> Instruction;
|
||||
|
||||
fn subterm_to_variable(r: RegType) -> Self;
|
||||
fn subterm_to_value(r: RegType) -> Self;
|
||||
fn subterm_to_variable(r: RegType) -> Instruction;
|
||||
fn subterm_to_value(r: RegType) -> Instruction;
|
||||
|
||||
fn clause_arg_to_instr(r: RegType) -> Self;
|
||||
fn clause_arg_to_instr(r: RegType) -> Instruction;
|
||||
}
|
||||
|
||||
impl<'a> CompilationTarget<'a> for FactInstruction {
|
||||
@@ -43,66 +45,66 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
|
||||
breadth_first_iter(term, false) // do not iterate over the root clause if one exists.
|
||||
}
|
||||
|
||||
fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Self {
|
||||
FactInstruction::GetConstant(lvl, HeapCellValue::from(constant), reg)
|
||||
fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Instruction {
|
||||
Instruction::GetConstant(lvl, HeapCellValue::from(constant), reg)
|
||||
}
|
||||
|
||||
fn to_structure(ct: ClauseType, arity: usize, reg: RegType) -> Self {
|
||||
FactInstruction::GetStructure(ct, arity, reg)
|
||||
fn to_structure(name: Atom, arity: usize, reg: RegType) -> Instruction {
|
||||
Instruction::GetStructure(name, arity, reg)
|
||||
}
|
||||
|
||||
fn to_list(lvl: Level, reg: RegType) -> Self {
|
||||
FactInstruction::GetList(lvl, reg)
|
||||
fn to_list(lvl: Level, reg: RegType) -> Instruction {
|
||||
Instruction::GetList(lvl, reg)
|
||||
}
|
||||
|
||||
fn to_void(num_subterms: usize) -> Self {
|
||||
FactInstruction::UnifyVoid(num_subterms)
|
||||
fn to_void(num_subterms: usize) -> Instruction {
|
||||
Instruction::UnifyVoid(num_subterms)
|
||||
}
|
||||
|
||||
fn is_void_instr(&self) -> bool {
|
||||
match self {
|
||||
&FactInstruction::UnifyVoid(_) => true,
|
||||
fn is_void_instr(instr: &Instruction) -> bool {
|
||||
match instr {
|
||||
&Instruction::UnifyVoid(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Self {
|
||||
FactInstruction::GetPartialString(lvl, string, r, has_tail)
|
||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction {
|
||||
Instruction::GetPartialString(lvl, string, r, has_tail)
|
||||
}
|
||||
|
||||
fn incr_void_instr(&mut self) {
|
||||
match self {
|
||||
&mut FactInstruction::UnifyVoid(ref mut incr) => *incr += 1,
|
||||
fn incr_void_instr(instr: &mut Instruction) {
|
||||
match instr {
|
||||
&mut Instruction::UnifyVoid(ref mut incr) => *incr += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn constant_subterm(constant: Literal) -> Self {
|
||||
FactInstruction::UnifyConstant(HeapCellValue::from(constant))
|
||||
fn constant_subterm(constant: Literal) -> Instruction {
|
||||
Instruction::UnifyConstant(HeapCellValue::from(constant))
|
||||
}
|
||||
|
||||
fn argument_to_variable(arg: RegType, val: usize) -> Self {
|
||||
FactInstruction::GetVariable(arg, val)
|
||||
fn argument_to_variable(arg: RegType, val: usize) -> Instruction {
|
||||
Instruction::GetVariable(arg, val)
|
||||
}
|
||||
|
||||
fn move_to_register(arg: RegType, val: usize) -> Self {
|
||||
FactInstruction::GetVariable(arg, val)
|
||||
fn move_to_register(arg: RegType, val: usize) -> Instruction {
|
||||
Instruction::GetVariable(arg, val)
|
||||
}
|
||||
|
||||
fn argument_to_value(arg: RegType, val: usize) -> Self {
|
||||
FactInstruction::GetValue(arg, val)
|
||||
fn argument_to_value(arg: RegType, val: usize) -> Instruction {
|
||||
Instruction::GetValue(arg, val)
|
||||
}
|
||||
|
||||
fn subterm_to_variable(val: RegType) -> Self {
|
||||
FactInstruction::UnifyVariable(val)
|
||||
fn subterm_to_variable(val: RegType) -> Instruction {
|
||||
Instruction::UnifyVariable(val)
|
||||
}
|
||||
|
||||
fn subterm_to_value(val: RegType) -> Self {
|
||||
FactInstruction::UnifyValue(val)
|
||||
fn subterm_to_value(val: RegType) -> Instruction {
|
||||
Instruction::UnifyValue(val)
|
||||
}
|
||||
|
||||
fn clause_arg_to_instr(val: RegType) -> Self {
|
||||
FactInstruction::UnifyVariable(val)
|
||||
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
||||
Instruction::UnifyVariable(val)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,65 +115,65 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
|
||||
post_order_iter(term)
|
||||
}
|
||||
|
||||
fn to_structure(ct: ClauseType, arity: usize, r: RegType) -> Self {
|
||||
QueryInstruction::PutStructure(ct, arity, r)
|
||||
fn to_structure(name: Atom, arity: usize, r: RegType) -> Instruction {
|
||||
Instruction::PutStructure(name, arity, r)
|
||||
}
|
||||
|
||||
fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Self {
|
||||
QueryInstruction::PutConstant(lvl, HeapCellValue::from(constant), reg)
|
||||
fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Instruction {
|
||||
Instruction::PutConstant(lvl, HeapCellValue::from(constant), reg)
|
||||
}
|
||||
|
||||
fn to_list(lvl: Level, reg: RegType) -> Self {
|
||||
QueryInstruction::PutList(lvl, reg)
|
||||
fn to_list(lvl: Level, reg: RegType) -> Instruction {
|
||||
Instruction::PutList(lvl, reg)
|
||||
}
|
||||
|
||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Self {
|
||||
QueryInstruction::PutPartialString(lvl, string, r, has_tail)
|
||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction {
|
||||
Instruction::PutPartialString(lvl, string, r, has_tail)
|
||||
}
|
||||
|
||||
fn to_void(subterms: usize) -> Self {
|
||||
QueryInstruction::SetVoid(subterms)
|
||||
fn to_void(subterms: usize) -> Instruction {
|
||||
Instruction::SetVoid(subterms)
|
||||
}
|
||||
|
||||
fn is_void_instr(&self) -> bool {
|
||||
match self {
|
||||
&QueryInstruction::SetVoid(_) => true,
|
||||
fn is_void_instr(instr: &Instruction) -> bool {
|
||||
match instr {
|
||||
&Instruction::SetVoid(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn incr_void_instr(&mut self) {
|
||||
match self {
|
||||
&mut QueryInstruction::SetVoid(ref mut incr) => *incr += 1,
|
||||
fn incr_void_instr(instr: &mut Instruction) {
|
||||
match instr {
|
||||
&mut Instruction::SetVoid(ref mut incr) => *incr += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn constant_subterm(constant: Literal) -> Self {
|
||||
QueryInstruction::SetConstant(HeapCellValue::from(constant))
|
||||
fn constant_subterm(constant: Literal) -> Instruction {
|
||||
Instruction::SetConstant(HeapCellValue::from(constant))
|
||||
}
|
||||
|
||||
fn argument_to_variable(arg: RegType, val: usize) -> Self {
|
||||
QueryInstruction::PutVariable(arg, val)
|
||||
fn argument_to_variable(arg: RegType, val: usize) -> Instruction {
|
||||
Instruction::PutVariable(arg, val)
|
||||
}
|
||||
|
||||
fn move_to_register(arg: RegType, val: usize) -> Self {
|
||||
QueryInstruction::GetVariable(arg, val)
|
||||
fn move_to_register(arg: RegType, val: usize) -> Instruction {
|
||||
Instruction::GetVariable(arg, val)
|
||||
}
|
||||
|
||||
fn argument_to_value(arg: RegType, val: usize) -> Self {
|
||||
QueryInstruction::PutValue(arg, val)
|
||||
fn argument_to_value(arg: RegType, val: usize) -> Instruction {
|
||||
Instruction::PutValue(arg, val)
|
||||
}
|
||||
|
||||
fn subterm_to_variable(val: RegType) -> Self {
|
||||
QueryInstruction::SetVariable(val)
|
||||
fn subterm_to_variable(val: RegType) -> Instruction {
|
||||
Instruction::SetVariable(val)
|
||||
}
|
||||
|
||||
fn subterm_to_value(val: RegType) -> Self {
|
||||
QueryInstruction::SetValue(val)
|
||||
fn subterm_to_value(val: RegType) -> Instruction {
|
||||
Instruction::SetValue(val)
|
||||
}
|
||||
|
||||
fn clause_arg_to_instr(val: RegType) -> Self {
|
||||
QueryInstruction::SetValue(val)
|
||||
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
||||
Instruction::SetValue(val)
|
||||
}
|
||||
}
|
||||
|
||||
110
src/write.rs
110
src/write.rs
@@ -1,6 +1,5 @@
|
||||
use crate::arena::*;
|
||||
use crate::atom_table::*;
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::loader::CompilationTarget;
|
||||
@@ -15,18 +14,7 @@ use ordered_float::OrderedFloat;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
impl fmt::Display for LocalCodePtr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => write!(f, "LocalCodePtr::DirEntry({})", p),
|
||||
LocalCodePtr::Halt => write!(f, "LocalCodePtr::Halt"),
|
||||
// LocalCodePtr::IndexingBuf(p, o, i) => {
|
||||
// write!(f, "LocalCodePtr::IndexingBuf({}, {}, {})", p, o, i)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Display for REPLCodePtr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -77,6 +65,7 @@ impl fmt::Display for REPLCodePtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl fmt::Display for IndexPtr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -97,6 +86,7 @@ impl fmt::Display for CompilationTarget {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Display for FactInstruction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -221,6 +211,7 @@ impl fmt::Display for ClauseType {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl fmt::Display for HeapCellValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -269,82 +260,10 @@ impl fmt::Display for HeapCellValue {
|
||||
unreachable!()
|
||||
}
|
||||
)
|
||||
/*
|
||||
match self {
|
||||
&HeapCellValue::Addr(ref addr) => write!(f, "{}", addr),
|
||||
&HeapCellValue::Atom(ref atom, _) => write!(f, "{}", atom.as_str()),
|
||||
&HeapCellValue::DBRef(ref db_ref) => write!(f, "{}", db_ref),
|
||||
&HeapCellValue::Integer(ref n) => write!(f, "{}", n),
|
||||
&HeapCellValue::LoadStatePayload(_) => write!(f, "LoadStatePayload"),
|
||||
&HeapCellValue::Rational(ref n) => write!(f, "{}", n),
|
||||
&HeapCellValue::NamedStr(arity, ref name, Some(ref cell)) => write!(
|
||||
f,
|
||||
"{}/{} (op, priority: {}, spec: {})",
|
||||
name.as_str(),
|
||||
arity,
|
||||
cell.prec(),
|
||||
cell.assoc()
|
||||
),
|
||||
&HeapCellValue::NamedStr(arity, ref name, None) => {
|
||||
write!(f, "{}/{}", name.as_str(), arity)
|
||||
}
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
write!(
|
||||
f,
|
||||
"pstr ( buf: \"{}\", has_tail({}) )",
|
||||
pstr.as_str_from(0),
|
||||
has_tail,
|
||||
)
|
||||
}
|
||||
&HeapCellValue::Stream(ref stream) => {
|
||||
write!(f, "$stream({})", stream.as_ptr() as usize)
|
||||
}
|
||||
&HeapCellValue::TcpListener(ref tcp_listener) => {
|
||||
write!(f, "$tcp_listener({})", tcp_listener.local_addr().unwrap())
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Display for DBRef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&DBRef::NamedPred(ref name, arity, _) => write!(f, "db_ref:named:{}/{}", name, arity),
|
||||
&DBRef::Op(priority, spec, ref name, ..) => {
|
||||
write!(f, "db_ref:op({}, {}, {})", priority, spec, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
impl fmt::Display for Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&Addr::Char(c) => write!(f, "Addr::Char({})", c),
|
||||
&Addr::EmptyList => write!(f, "Addr::EmptyList"),
|
||||
&Addr::Fixnum(n) => write!(f, "Addr::Fixnum({})", n),
|
||||
&Addr::Float(fl) => write!(f, "Addr::Float({})", fl),
|
||||
&Addr::CutPoint(cp) => write!(f, "Addr::CutPoint({})", cp),
|
||||
&Addr::Con(ref c) => write!(f, "Addr::Con({})", c),
|
||||
&Addr::Lis(l) => write!(f, "Addr::Lis({})", l),
|
||||
&Addr::LoadStatePayload(s) => write!(f, "Addr::LoadStatePayload({})", s),
|
||||
&Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h),
|
||||
&Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h),
|
||||
&Addr::StackCell(fr, sc) => write!(f, "Addr::StackCell({}, {})", fr, sc),
|
||||
&Addr::Str(s) => write!(f, "Addr::Str({})", s),
|
||||
&Addr::PStrLocation(h, n) => write!(f, "Addr::PStrLocation({}, {})", h, n),
|
||||
&Addr::Stream(stream) => write!(f, "Addr::Stream({})", stream),
|
||||
&Addr::TcpListener(tcp_listener) => write!(f, "Addr::TcpListener({})", tcp_listener),
|
||||
&Addr::Usize(cp) => write!(f, "Addr::Usize({})", cp),
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl fmt::Display for ControlInstruction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -375,6 +294,7 @@ impl fmt::Display for ControlInstruction {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl fmt::Display for IndexedChoiceInstruction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -386,6 +306,7 @@ impl fmt::Display for IndexedChoiceInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Display for ChoiceInstruction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -443,6 +364,7 @@ impl fmt::Display for ChoiceInstruction {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl fmt::Display for IndexingCodePtr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -602,6 +524,7 @@ impl fmt::Display for IndexingLine {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl fmt::Display for Line {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -625,17 +548,8 @@ impl fmt::Display for Line {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Number {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Number::Float(fl) => write!(f, "{}", fl),
|
||||
Number::Integer(n) => write!(f, "{}", n),
|
||||
Number::Rational(r) => write!(f, "{}", r),
|
||||
Number::Fixnum(n) => write!(f, "{}", n.get_num()),
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
|
||||
impl fmt::Display for ArithmeticTerm {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -745,7 +659,8 @@ impl fmt::Display for CutInstruction {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
impl fmt::Display for Level {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@@ -754,3 +669,4 @@ impl fmt::Display for Level {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user