push of preliminary delimited continuations library cont.pl (#136)
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -311,8 +311,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.8.36"
|
version = "0.8.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -447,7 +446,7 @@ dependencies = [
|
|||||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.8.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prolog_parser 0.8.37",
|
||||||
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -590,7 +589,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
||||||
"checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d"
|
"checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
"checksum prolog_parser 0.8.36 (registry+https://github.com/rust-lang/crates.io-index)" = "fea0ae985b51f28cb3582469fbe9318e238d504a7358d90eb671f0d772fb5061"
|
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ libc = "0.2.62"
|
|||||||
nix = "0.15.0"
|
nix = "0.15.0"
|
||||||
num-rug-adapter = { optional = true, version = "0.1.1" }
|
num-rug-adapter = { optional = true, version = "0.1.1" }
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = { version = "0.8.36", default-features = false }
|
prolog_parser = { version = "0.8.37", default-features = false }
|
||||||
ref_thread_local = "0.0.0"
|
ref_thread_local = "0.0.0"
|
||||||
rug = { version = "1.4.0", optional = true }
|
rug = { version = "1.4.0", optional = true }
|
||||||
rustyline = "5.0.3"
|
rustyline = "5.0.3"
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -50,6 +50,8 @@ Extend Scryer Prolog to include the following, among other features:
|
|||||||
- [x] Backtrackable and non-backtrackable global variables via `bb_get/2`
|
- [x] Backtrackable and non-backtrackable global variables via `bb_get/2`
|
||||||
`bb_put/2` (non-backtrackable) and `bb_b_put/2`
|
`bb_put/2` (non-backtrackable) and `bb_b_put/2`
|
||||||
(backtrackable).
|
(backtrackable).
|
||||||
|
- [ ] Delimited continuations based on reset/3, shift/1 (documented in
|
||||||
|
"Delimited Continuations for Prolog") (_in progress_).
|
||||||
- [ ] clp(B) and clp(ℤ) as builtin libraries (_in progress_).
|
- [ ] clp(B) and clp(ℤ) as builtin libraries (_in progress_).
|
||||||
- [ ] Streams and predicates for stream control (_in progress_).
|
- [ ] Streams and predicates for stream control (_in progress_).
|
||||||
- [ ] An incremental compacting garbage collector satisfying the five
|
- [ ] An incremental compacting garbage collector satisfying the five
|
||||||
@@ -79,15 +81,12 @@ Programming?"
|
|||||||
unum implementation or an ad hoc one. Unums are described in
|
unum implementation or an ad hoc one. Unums are described in
|
||||||
Gustafson's book "The End of Error."
|
Gustafson's book "The End of Error."
|
||||||
|
|
||||||
3. Add support for shift/reset delimited continuations, see "Delimited
|
3. Add concurrent tables to manage shared references to atoms and
|
||||||
Continuations for Prolog."
|
|
||||||
|
|
||||||
4. Add concurrent tables to manage shared references to atoms and
|
|
||||||
strings.
|
strings.
|
||||||
|
|
||||||
5. Add optional SLG resolution for fast memoization of predicates.
|
4. Add optional SLG resolution for fast memoization of predicates.
|
||||||
|
|
||||||
6. Add some form of JIT predicate indexing.
|
5. Add some form of JIT predicate indexing.
|
||||||
|
|
||||||
## Installing Scryer Prolog
|
## Installing Scryer Prolog
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ pub enum SystemClauseType {
|
|||||||
AtomLength,
|
AtomLength,
|
||||||
BindFromRegister,
|
BindFromRegister,
|
||||||
CallAttributeGoals,
|
CallAttributeGoals,
|
||||||
|
CallContinuation,
|
||||||
CharCode,
|
CharCode,
|
||||||
CharsToNumber,
|
CharsToNumber,
|
||||||
ClearAttrVarBindings,
|
ClearAttrVarBindings,
|
||||||
@@ -193,6 +194,7 @@ pub enum SystemClauseType {
|
|||||||
GetAttrVarQueueBeyond,
|
GetAttrVarQueueBeyond,
|
||||||
GetBValue,
|
GetBValue,
|
||||||
GetClause,
|
GetClause,
|
||||||
|
GetContinuationChunk,
|
||||||
GetModuleClause,
|
GetModuleClause,
|
||||||
GetNextDBRef,
|
GetNextDBRef,
|
||||||
GetNextOpDBRef,
|
GetNextOpDBRef,
|
||||||
@@ -212,10 +214,12 @@ pub enum SystemClauseType {
|
|||||||
ModuleExists,
|
ModuleExists,
|
||||||
ModuleOf,
|
ModuleOf,
|
||||||
ModuleRetractClause,
|
ModuleRetractClause,
|
||||||
|
NextEP,
|
||||||
NoSuchPredicate,
|
NoSuchPredicate,
|
||||||
NumberToChars,
|
NumberToChars,
|
||||||
NumberToCodes,
|
NumberToCodes,
|
||||||
OpDeclaration,
|
OpDeclaration,
|
||||||
|
PointsToContinuationResetMarker,
|
||||||
REPL(REPLCodePtr),
|
REPL(REPLCodePtr),
|
||||||
ReadQueryTerm,
|
ReadQueryTerm,
|
||||||
ReadTerm,
|
ReadTerm,
|
||||||
@@ -252,6 +256,7 @@ pub enum SystemClauseType {
|
|||||||
TermVariables,
|
TermVariables,
|
||||||
TruncateLiftedHeapTo,
|
TruncateLiftedHeapTo,
|
||||||
UnifyWithOccursCheck,
|
UnifyWithOccursCheck,
|
||||||
|
UnwindEnvironments,
|
||||||
UnwindStack,
|
UnwindStack,
|
||||||
Variant,
|
Variant,
|
||||||
WAMInstructions,
|
WAMInstructions,
|
||||||
@@ -271,6 +276,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
|
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
|
||||||
&SystemClauseType::BindFromRegister => clause_name!("$bind_from_register"),
|
&SystemClauseType::BindFromRegister => clause_name!("$bind_from_register"),
|
||||||
&SystemClauseType::CallAttributeGoals => clause_name!("$call_attribute_goals"),
|
&SystemClauseType::CallAttributeGoals => clause_name!("$call_attribute_goals"),
|
||||||
|
&SystemClauseType::CallContinuation => clause_name!("$call_continuation"),
|
||||||
&SystemClauseType::CharCode => clause_name!("$char_code"),
|
&SystemClauseType::CharCode => clause_name!("$char_code"),
|
||||||
&SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"),
|
&SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"),
|
||||||
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
||||||
@@ -316,6 +322,7 @@ impl SystemClauseType {
|
|||||||
clause_name!("$get_attr_var_queue_delim")
|
clause_name!("$get_attr_var_queue_delim")
|
||||||
}
|
}
|
||||||
&SystemClauseType::GetAttrVarQueueBeyond => clause_name!("$get_attr_var_queue_beyond"),
|
&SystemClauseType::GetAttrVarQueueBeyond => clause_name!("$get_attr_var_queue_beyond"),
|
||||||
|
&SystemClauseType::GetContinuationChunk => clause_name!("$get_cont_chunk"),
|
||||||
&SystemClauseType::GetLiftedHeapFromOffset => clause_name!("$get_lh_from_offset"),
|
&SystemClauseType::GetLiftedHeapFromOffset => clause_name!("$get_lh_from_offset"),
|
||||||
&SystemClauseType::GetLiftedHeapFromOffsetDiff => {
|
&SystemClauseType::GetLiftedHeapFromOffsetDiff => {
|
||||||
clause_name!("$get_lh_from_offset_diff")
|
clause_name!("$get_lh_from_offset_diff")
|
||||||
@@ -350,6 +357,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
|
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
|
||||||
&SystemClauseType::NumberToChars => clause_name!("$number_to_chars"),
|
&SystemClauseType::NumberToChars => clause_name!("$number_to_chars"),
|
||||||
&SystemClauseType::NumberToCodes => clause_name!("$number_to_codes"),
|
&SystemClauseType::NumberToCodes => clause_name!("$number_to_codes"),
|
||||||
|
&SystemClauseType::PointsToContinuationResetMarker => {
|
||||||
|
clause_name!("$points_to_cont_reset_marker")
|
||||||
|
}
|
||||||
&SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"),
|
&SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"),
|
||||||
&SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"),
|
&SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"),
|
||||||
&SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
|
&SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
|
||||||
@@ -370,6 +380,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
|
&SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
|
||||||
&SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
|
&SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
|
||||||
&SystemClauseType::ModuleRetractClause => clause_name!("$module_retract_clause"),
|
&SystemClauseType::ModuleRetractClause => clause_name!("$module_retract_clause"),
|
||||||
|
&SystemClauseType::NextEP => clause_name!("$nextEP"),
|
||||||
&SystemClauseType::ReadQueryTerm => clause_name!("$read_query_term"),
|
&SystemClauseType::ReadQueryTerm => clause_name!("$read_query_term"),
|
||||||
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
||||||
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
||||||
@@ -386,6 +397,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
||||||
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
||||||
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
||||||
|
&SystemClauseType::UnwindEnvironments => clause_name!("$unwind_environments"),
|
||||||
&SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
|
&SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
|
||||||
&SystemClauseType::Variant => clause_name!("$variant"),
|
&SystemClauseType::Variant => clause_name!("$variant"),
|
||||||
&SystemClauseType::WAMInstructions => clause_name!("$wam_instructions"),
|
&SystemClauseType::WAMInstructions => clause_name!("$wam_instructions"),
|
||||||
@@ -407,6 +419,7 @@ impl SystemClauseType {
|
|||||||
("$asserta", 4) => Some(SystemClauseType::AssertDynamicPredicateToFront),
|
("$asserta", 4) => Some(SystemClauseType::AssertDynamicPredicateToFront),
|
||||||
("$assertz", 4) => Some(SystemClauseType::AssertDynamicPredicateToBack),
|
("$assertz", 4) => Some(SystemClauseType::AssertDynamicPredicateToBack),
|
||||||
("$call_attribute_goals", 2) => Some(SystemClauseType::CallAttributeGoals),
|
("$call_attribute_goals", 2) => Some(SystemClauseType::CallAttributeGoals),
|
||||||
|
("$call_continuation", 1) => Some(SystemClauseType::CallContinuation),
|
||||||
("$char_code", 2) => Some(SystemClauseType::CharCode),
|
("$char_code", 2) => Some(SystemClauseType::CharCode),
|
||||||
("$chars_to_number", 2) => Some(SystemClauseType::CharsToNumber),
|
("$chars_to_number", 2) => Some(SystemClauseType::CharsToNumber),
|
||||||
("$clear_attr_var_bindings", 0) => Some(SystemClauseType::ClearAttrVarBindings),
|
("$clear_attr_var_bindings", 0) => Some(SystemClauseType::ClearAttrVarBindings),
|
||||||
@@ -432,6 +445,9 @@ impl SystemClauseType {
|
|||||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||||
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
||||||
("$get_char", 1) => Some(SystemClauseType::GetChar),
|
("$get_char", 1) => Some(SystemClauseType::GetChar),
|
||||||
|
("$points_to_cont_reset_marker", 1) => {
|
||||||
|
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||||
|
}
|
||||||
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
||||||
("$truncate_if_no_lh_growth", 1) => {
|
("$truncate_if_no_lh_growth", 1) => {
|
||||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
||||||
@@ -473,10 +489,12 @@ impl SystemClauseType {
|
|||||||
("$get_attr_var_queue_beyond", 2) => Some(SystemClauseType::GetAttrVarQueueBeyond),
|
("$get_attr_var_queue_beyond", 2) => Some(SystemClauseType::GetAttrVarQueueBeyond),
|
||||||
("$get_attr_var_queue_delim", 1) => Some(SystemClauseType::GetAttrVarQueueDelimiter),
|
("$get_attr_var_queue_delim", 1) => Some(SystemClauseType::GetAttrVarQueueDelimiter),
|
||||||
("$get_ball", 1) => Some(SystemClauseType::GetBall),
|
("$get_ball", 1) => Some(SystemClauseType::GetBall),
|
||||||
|
("$get_cont_chunk", 3) => Some(SystemClauseType::GetContinuationChunk),
|
||||||
("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
|
("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
|
||||||
("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
|
("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
|
||||||
("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
|
("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
|
||||||
("$raw_input_read_char", 1) => Some(SystemClauseType::RawInputReadChar),
|
("$raw_input_read_char", 1) => Some(SystemClauseType::RawInputReadChar),
|
||||||
|
("$nextEP", 3) => Some(SystemClauseType::NextEP),
|
||||||
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
|
("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
|
||||||
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
|
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
|
||||||
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
|
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
|
||||||
@@ -494,6 +512,7 @@ impl SystemClauseType {
|
|||||||
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
|
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
|
||||||
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||||
|
("$unwind_environments", 0) => Some(SystemClauseType::UnwindEnvironments),
|
||||||
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
|
||||||
("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck),
|
("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck),
|
||||||
("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||||
|
|||||||
@@ -809,6 +809,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
Constant::CharCode(c) => self.append_str(&format!("{}", c)),
|
Constant::CharCode(c) => self.append_str(&format!("{}", c)),
|
||||||
|
Constant::CutPoint(b) => self.append_str(&format!("{}", b)),
|
||||||
Constant::EmptyList => self.append_str("[]"),
|
Constant::EmptyList => self.append_str("[]"),
|
||||||
Constant::Integer(n) => self.print_number(Number::Integer(n), op),
|
Constant::Integer(n) => self.print_number(Number::Integer(n), op),
|
||||||
Constant::Float(n) => self.print_number(Number::Float(n), op),
|
Constant::Float(n) => self.print_number(Number::Float(n), op),
|
||||||
|
|||||||
@@ -364,6 +364,17 @@ pub enum ControlInstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ControlInstruction {
|
impl ControlInstruction {
|
||||||
|
pub fn perm_vars(&self) -> Option<usize> {
|
||||||
|
match self {
|
||||||
|
ControlInstruction::CallClause(_, _, num_cells, ..) =>
|
||||||
|
Some(*num_cells),
|
||||||
|
ControlInstruction::JmpBy(_, _, num_cells, ..) =>
|
||||||
|
Some(*num_cells),
|
||||||
|
_ =>
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_functor(&self) -> MachineStub {
|
pub fn to_functor(&self) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&ControlInstruction::Allocate(num_frames) => {
|
&ControlInstruction::Allocate(num_frames) => {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ shift(Term) :-
|
|||||||
get_chunks(E, P, L) :-
|
get_chunks(E, P, L) :-
|
||||||
( '$points_to_cont_reset_marker'(P) ->
|
( '$points_to_cont_reset_marker'(P) ->
|
||||||
L = []
|
L = []
|
||||||
; '$get_chunk'(E,P,TB),
|
; '$get_cont_chunk'(E,P,TB),
|
||||||
L = [TB|Rest],
|
L = [TB|Rest],
|
||||||
'$nextEP'(E, NextE, NextP),
|
'$nextEP'(E, NextE, NextP),
|
||||||
get_chunks(NextE, NextP, Rest)
|
get_chunks(NextE, NextP, Rest)
|
||||||
@@ -26,4 +26,3 @@ get_chunks(E, P, L) :-
|
|||||||
call_continuation(L) :- '$call_continuation'(L).
|
call_continuation(L) :- '$call_continuation'(L).
|
||||||
|
|
||||||
'$write_cont_and_term'(_, _, _, _).
|
'$write_cont_and_term'(_, _, _, _).
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl MachineState {
|
|||||||
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)].clone();
|
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::Con(Constant::Usize(self.b0));
|
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::Con(Constant::CutPoint(self.b0));
|
||||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Con(Constant::Usize(self.num_of_args));
|
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Con(Constant::Usize(self.num_of_args));
|
||||||
|
|
||||||
self.verify_attributes();
|
self.verify_attributes();
|
||||||
|
|||||||
@@ -82,6 +82,50 @@ impl Heap {
|
|||||||
self.push(hcv);
|
self.push(hcv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
|
||||||
|
let extract_integer = |s: usize| -> Option<usize> {
|
||||||
|
match self.heap[s].as_addr(s) {
|
||||||
|
Addr::Con(Constant::Integer(n)) => n.to_usize(),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
Addr::Str(s) => {
|
||||||
|
match &self.heap[*s] {
|
||||||
|
HeapCellValue::NamedStr(arity, ref name, _) => {
|
||||||
|
match (name.as_str(), *arity) {
|
||||||
|
("dir_entry", 1) => {
|
||||||
|
extract_integer(s+1).map(LocalCodePtr::DirEntry)
|
||||||
|
}
|
||||||
|
("in_situ_dir_entry", 1) => {
|
||||||
|
extract_integer(s+1).map(LocalCodePtr::InSituDirEntry)
|
||||||
|
}
|
||||||
|
("top_level", 2) => {
|
||||||
|
if let Some(chunk_num) = extract_integer(s+1) {
|
||||||
|
if let Some(p) = extract_integer(s+2) {
|
||||||
|
return Some(LocalCodePtr::TopLevel(chunk_num, p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
("user_goal_expansion", 1) => {
|
||||||
|
extract_integer(s+1).map(LocalCodePtr::UserGoalExpansion)
|
||||||
|
}
|
||||||
|
("user_term_expansion", 1) => {
|
||||||
|
extract_integer(s+1).map(LocalCodePtr::UserTermExpansion)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<usize> for Heap {
|
impl Index<usize> for Heap {
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ use prolog_parser::tabled_rc::*;
|
|||||||
use crate::prolog::clause_types::*;
|
use crate::prolog::clause_types::*;
|
||||||
use crate::prolog::fixtures::*;
|
use crate::prolog::fixtures::*;
|
||||||
use crate::prolog::forms::*;
|
use crate::prolog::forms::*;
|
||||||
|
use crate::prolog::machine::code_repo::CodeRepo;
|
||||||
use crate::prolog::machine::Ball;
|
use crate::prolog::machine::Ball;
|
||||||
|
use crate::prolog::machine::heap::Heap;
|
||||||
|
use crate::prolog::instructions::*;
|
||||||
|
use crate::prolog::rug::Integer;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
@@ -346,6 +350,69 @@ impl LocalCodePtr {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||||
|
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
||||||
|
Some(line) => {
|
||||||
|
match line.as_ref() {
|
||||||
|
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||||
|
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_functor(&self, heap: &mut Heap) -> Addr {
|
||||||
|
let addr = Addr::HeapCell(heap.h);
|
||||||
|
|
||||||
|
match self {
|
||||||
|
LocalCodePtr::DirEntry(p) => {
|
||||||
|
heap.append(functor!(
|
||||||
|
"dir_entry",
|
||||||
|
1,
|
||||||
|
[heap_integer!(Integer::from(*p))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
LocalCodePtr::InSituDirEntry(p) => {
|
||||||
|
heap.append(functor!(
|
||||||
|
"in_situ_dir_entry",
|
||||||
|
1,
|
||||||
|
[heap_integer!(Integer::from(*p))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
LocalCodePtr::TopLevel(chunk_num, offset) => {
|
||||||
|
heap.append(functor!(
|
||||||
|
"top_level",
|
||||||
|
2,
|
||||||
|
[heap_integer!(Integer::from(*chunk_num)),
|
||||||
|
heap_integer!(Integer::from(*offset))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
LocalCodePtr::UserGoalExpansion(p) => {
|
||||||
|
heap.append(functor!(
|
||||||
|
"user_goal_expansion",
|
||||||
|
1,
|
||||||
|
[heap_integer!(Integer::from(*p))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
LocalCodePtr::UserTermExpansion(p) => {
|
||||||
|
heap.append(functor!(
|
||||||
|
"user_term_expansion",
|
||||||
|
1,
|
||||||
|
[heap_integer!(Integer::from(*p))]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd<CodePtr> for CodePtr {
|
impl PartialOrd<CodePtr> for CodePtr {
|
||||||
@@ -399,6 +466,25 @@ impl Add<usize> for LocalCodePtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sub<usize> for LocalCodePtr {
|
||||||
|
type Output = Option<LocalCodePtr>;
|
||||||
|
|
||||||
|
fn sub(self, rhs: usize) -> Self::Output {
|
||||||
|
match self {
|
||||||
|
LocalCodePtr::InSituDirEntry(p) =>
|
||||||
|
p.checked_sub(rhs).map(LocalCodePtr::InSituDirEntry),
|
||||||
|
LocalCodePtr::DirEntry(p) =>
|
||||||
|
p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||||
|
LocalCodePtr::TopLevel(cn, p) =>
|
||||||
|
p.checked_sub(rhs).map(|r| LocalCodePtr::TopLevel(cn, r)),
|
||||||
|
LocalCodePtr::UserTermExpansion(p) =>
|
||||||
|
p.checked_sub(rhs).map(LocalCodePtr::UserTermExpansion),
|
||||||
|
LocalCodePtr::UserGoalExpansion(p) =>
|
||||||
|
p.checked_sub(rhs).map(LocalCodePtr::UserGoalExpansion),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AddAssign<usize> for LocalCodePtr {
|
impl AddAssign<usize> for LocalCodePtr {
|
||||||
fn add_assign(&mut self, rhs: usize) {
|
fn add_assign(&mut self, rhs: usize) {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@@ -1063,17 +1063,20 @@ downcast!(dyn CutPolicy);
|
|||||||
fn cut_body(machine_st: &mut MachineState, addr: Addr) -> bool {
|
fn cut_body(machine_st: &mut MachineState, addr: Addr) -> bool {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
|
|
||||||
if let Addr::Con(Constant::Usize(b0)) = addr {
|
match addr {
|
||||||
if b > b0 {
|
Addr::Con(Constant::CutPoint(b0)) | Addr::Con(Constant::Usize(b0)) => {
|
||||||
machine_st.b = b0;
|
if b > b0 {
|
||||||
machine_st.tidy_trail();
|
machine_st.b = b0;
|
||||||
machine_st.tidy_pstr_trail();
|
machine_st.tidy_trail();
|
||||||
machine_st.truncate_stack();
|
machine_st.tidy_pstr_trail();
|
||||||
|
machine_st.truncate_stack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
_ => {
|
||||||
machine_st.fail = true;
|
machine_st.fail = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -1148,15 +1151,19 @@ impl CutPolicy for SCCCutPolicy {
|
|||||||
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
fn cut(&mut self, machine_st: &mut MachineState, r: RegType) -> bool {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
|
|
||||||
if let Addr::Con(Constant::Usize(b0)) = machine_st[r].clone() {
|
match machine_st[r].clone() {
|
||||||
if b > b0 {
|
Addr::Con(Constant::Usize(b0)) | Addr::Con(Constant::CutPoint(b0)) => {
|
||||||
machine_st.b = b0;
|
if b > b0 {
|
||||||
machine_st.tidy_trail();
|
machine_st.b = b0;
|
||||||
machine_st.tidy_pstr_trail();
|
machine_st.tidy_trail();
|
||||||
|
machine_st.tidy_pstr_trail();
|
||||||
|
machine_st.truncate_stack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
machine_st.fail = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
machine_st.fail = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.run_cleaners(machine_st)
|
self.run_cleaners(machine_st)
|
||||||
|
|||||||
@@ -3337,7 +3337,7 @@ impl MachineState {
|
|||||||
&CutInstruction::GetLevel(r) => {
|
&CutInstruction::GetLevel(r) => {
|
||||||
let b0 = self.b0;
|
let b0 = self.b0;
|
||||||
|
|
||||||
self[r] = Addr::Con(Constant::Usize(b0));
|
self[r] = Addr::Con(Constant::CutPoint(b0));
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
}
|
}
|
||||||
&CutInstruction::GetLevelAndUnify(r) => {
|
&CutInstruction::GetLevelAndUnify(r) => {
|
||||||
|
|||||||
@@ -580,6 +580,51 @@ impl MachineState {
|
|||||||
functors
|
functors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_continuation_chunk(&mut self, chunk: Addr, return_p: LocalCodePtr) -> LocalCodePtr {
|
||||||
|
let chunk = self.store(self.deref(chunk));
|
||||||
|
|
||||||
|
match chunk {
|
||||||
|
Addr::Str(s) => {
|
||||||
|
match &self.heap[s] {
|
||||||
|
HeapCellValue::NamedStr(arity, ..) => {
|
||||||
|
let num_cells = arity - 1;
|
||||||
|
let p_functor = self.heap[s+1].as_addr(s+1);
|
||||||
|
|
||||||
|
let cp = self.heap.to_local_code_ptr(&p_functor).unwrap();
|
||||||
|
let prev_e = self.e;
|
||||||
|
|
||||||
|
let e = self.stack.allocate_and_frame(num_cells);
|
||||||
|
let and_frame = self.stack.index_and_frame_mut(e);
|
||||||
|
|
||||||
|
and_frame.prelude.e = prev_e;
|
||||||
|
and_frame.prelude.cp = return_p;
|
||||||
|
|
||||||
|
self.p = CodePtr::Local(cp + 1);
|
||||||
|
|
||||||
|
// adjust cut point to occur after call_continuation.
|
||||||
|
if num_cells > 0 {
|
||||||
|
if let Addr::Con(Constant::CutPoint(_)) = self.heap[s+2].as_addr(s+2) {
|
||||||
|
and_frame[1] = Addr::Con(Constant::CutPoint(self.b));
|
||||||
|
} else {
|
||||||
|
and_frame[1] = self.heap[s+2].as_addr(s+2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for index in s+3 .. s+2+num_cells {
|
||||||
|
and_frame[index - (s+1)] = self.heap[index].as_addr(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.e = e;
|
||||||
|
|
||||||
|
self.p.local()
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn system_call(
|
pub(super) fn system_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
ct: &SystemClauseType,
|
ct: &SystemClauseType,
|
||||||
@@ -784,6 +829,28 @@ impl MachineState {
|
|||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::CallContinuation => {
|
||||||
|
let stub = MachineError::functor_stub(clause_name!("call_continuation"), 1);
|
||||||
|
|
||||||
|
match self.try_from_list(temp_v!(1), stub) {
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
Ok(cont_chunks) => {
|
||||||
|
let mut return_p = if self.last_call {
|
||||||
|
self.cp
|
||||||
|
} else {
|
||||||
|
self.p.local() + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
self.p = CodePtr::Local(return_p);
|
||||||
|
|
||||||
|
for chunk in cont_chunks.into_iter().rev() {
|
||||||
|
return_p = self.call_continuation_chunk(chunk, return_p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
&SystemClauseType::CharsToNumber => {
|
&SystemClauseType::CharsToNumber => {
|
||||||
let stub = MachineError::functor_stub(clause_name!("number_chars"), 2);
|
let stub = MachineError::functor_stub(clause_name!("number_chars"), 2);
|
||||||
|
|
||||||
@@ -897,7 +964,7 @@ impl MachineState {
|
|||||||
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Con(Constant::Usize(old_b)) => {
|
Addr::Con(Constant::Usize(old_b)) | Addr::Con(Constant::CutPoint(old_b)) => {
|
||||||
let prev_b = self.stack.index_or_frame(self.b).prelude.b;
|
let prev_b = self.stack.index_or_frame(self.b).prelude.b;
|
||||||
let prev_b = self.stack.index_or_frame(prev_b).prelude.b;
|
let prev_b = self.stack.index_or_frame(prev_b).prelude.b;
|
||||||
|
|
||||||
@@ -1477,6 +1544,50 @@ impl MachineState {
|
|||||||
_ => self.fail = true,
|
_ => self.fail = true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::GetContinuationChunk => {
|
||||||
|
let e = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
|
let e = if let Addr::Con(Constant::Usize(e)) = e {
|
||||||
|
e
|
||||||
|
} else {
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
let p_functor = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
|
let p = self.heap.to_local_code_ptr(&p_functor).unwrap();
|
||||||
|
|
||||||
|
let num_cells = match code_repo.lookup_instr(self.last_call, &CodePtr::Local(p)) {
|
||||||
|
Some(line) => {
|
||||||
|
let perm_vars = match line.as_ref() {
|
||||||
|
Line::Control(ref ctrl_instr) => ctrl_instr.perm_vars(),
|
||||||
|
_ => None
|
||||||
|
};
|
||||||
|
|
||||||
|
perm_vars.unwrap()
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut addrs = vec![];
|
||||||
|
|
||||||
|
for index in 1 .. num_cells + 1 {
|
||||||
|
addrs.push(self.stack.index_and_frame(e)[index].clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let chunk = Addr::HeapCell(self.heap.h);
|
||||||
|
|
||||||
|
self.heap.push(HeapCellValue::NamedStr(
|
||||||
|
1 + num_cells,
|
||||||
|
clause_name!("cont_chunk"),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
|
||||||
|
self.heap.push(HeapCellValue::Addr(p_functor));
|
||||||
|
self.heap.extend(addrs.into_iter().map(HeapCellValue::Addr));
|
||||||
|
|
||||||
|
self.unify(self[temp_v!(3)].clone(), chunk);
|
||||||
|
}
|
||||||
&SystemClauseType::GetLiftedHeapFromOffsetDiff => {
|
&SystemClauseType::GetLiftedHeapFromOffsetDiff => {
|
||||||
let lh_offset = self[temp_v!(1)].clone();
|
let lh_offset = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
@@ -1609,7 +1720,8 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match (a1, a2.clone()) {
|
match (a1, a2.clone()) {
|
||||||
(Addr::Con(Constant::Usize(bp)), Addr::Con(Constant::Integer(n))) => {
|
(Addr::Con(Constant::Usize(bp)), Addr::Con(Constant::Integer(n)))
|
||||||
|
| (Addr::Con(Constant::CutPoint(bp)), Addr::Con(Constant::Integer(n))) => {
|
||||||
match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
|
||||||
Some(call_policy) => {
|
Some(call_policy) => {
|
||||||
let count = call_policy.add_limit(n, bp);
|
let count = call_policy.add_limit(n, bp);
|
||||||
@@ -1771,14 +1883,17 @@ impl MachineState {
|
|||||||
Some(call_policy) => {
|
Some(call_policy) => {
|
||||||
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
if let Addr::Con(Constant::Usize(bp)) = a1 {
|
match a1 {
|
||||||
if call_policy.is_empty() && bp == self.b {
|
Addr::Con(Constant::Usize(bp)) | Addr::Con(Constant::CutPoint(bp)) => {
|
||||||
Some(call_policy.into_inner())
|
if call_policy.is_empty() && bp == self.b {
|
||||||
} else {
|
Some(call_policy.into_inner())
|
||||||
None
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("remove_call_policy_check: expected Usize in A1.");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
panic!("remove_call_policy_check: expected Usize in A1.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => panic!(
|
None => panic!(
|
||||||
@@ -1796,15 +1911,18 @@ impl MachineState {
|
|||||||
Some(call_policy) => {
|
Some(call_policy) => {
|
||||||
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
if let Addr::Con(Constant::Usize(bp)) = a1 {
|
match a1 {
|
||||||
let count = call_policy.remove_limit(bp);
|
Addr::Con(Constant::Usize(bp)) | Addr::Con(Constant::CutPoint(bp)) => {
|
||||||
let count = Addr::Con(Constant::Integer(count.clone()));
|
let count = call_policy.remove_limit(bp);
|
||||||
|
let count = Addr::Con(Constant::Integer(count.clone()));
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
self.unify(a2, count);
|
self.unify(a2, count);
|
||||||
} else {
|
}
|
||||||
panic!("remove_inference_counter: expected Usize in A1.");
|
_ => {
|
||||||
|
panic!("remove_inference_counter: expected Usize in A1.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => panic!(
|
None => panic!(
|
||||||
@@ -1836,7 +1954,7 @@ impl MachineState {
|
|||||||
self[RegType::Temp(i)] = self.stack.index_and_frame(e)[i].clone();
|
self[RegType::Temp(i)] = self.stack.index_and_frame(e)[i].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let &Addr::Con(Constant::Usize(b0)) = &self.stack.index_and_frame(e)[frame_len - 1] {
|
if let &Addr::Con(Constant::CutPoint(b0)) = &self.stack.index_and_frame(e)[frame_len - 1] {
|
||||||
self.b0 = b0;
|
self.b0 = b0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1884,7 +2002,7 @@ impl MachineState {
|
|||||||
let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
|
let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
|
|
||||||
match a2 {
|
match a2 {
|
||||||
Addr::Con(Constant::Usize(bp)) => {
|
Addr::Con(Constant::CutPoint(bp)) | Addr::Con(Constant::Usize(bp)) => {
|
||||||
let prev_b = self.stack.index_or_frame(self.b).prelude.b;
|
let prev_b = self.stack.index_or_frame(self.b).prelude.b;
|
||||||
|
|
||||||
if prev_b <= bp {
|
if prev_b <= bp {
|
||||||
@@ -1975,7 +2093,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
&SystemClauseType::GetCutPoint => {
|
&SystemClauseType::GetCutPoint => {
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)].clone();
|
||||||
let a2 = Addr::Con(Constant::Usize(self.b0));
|
let a2 = Addr::Con(Constant::CutPoint(self.b0));
|
||||||
|
|
||||||
self.unify(a1, a2);
|
self.unify(a1, a2);
|
||||||
}
|
}
|
||||||
@@ -1997,6 +2115,72 @@ impl MachineState {
|
|||||||
let target = self[temp_v!(1)].clone();
|
let target = self[temp_v!(1)].clone();
|
||||||
self.unify(Addr::Con(Constant::Char(c)), target);
|
self.unify(Addr::Con(Constant::Char(c)), target);
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::NextEP => {
|
||||||
|
let first_arg = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
|
match first_arg {
|
||||||
|
Addr::Con(Constant::Atom(ref name, _))
|
||||||
|
if name.as_str() == "first" => {
|
||||||
|
if self.e == 0 {
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let cp = (self.stack.index_and_frame(self.e).prelude.cp - 1).unwrap();
|
||||||
|
|
||||||
|
let e = self.stack.index_and_frame(self.e).prelude.e;
|
||||||
|
let e = Addr::Con(Constant::Usize(e));
|
||||||
|
|
||||||
|
let p = cp.as_functor(&mut self.heap);
|
||||||
|
|
||||||
|
self.unify(self[temp_v!(2)].clone(), e);
|
||||||
|
|
||||||
|
if !self.fail {
|
||||||
|
self.unify(self[temp_v!(3)].clone(), p);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Addr::Con(Constant::Usize(e)) => {
|
||||||
|
if e == 0 {
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the call site so that the number of active permanent variables can be read
|
||||||
|
// from it later.
|
||||||
|
let cp = (self.stack.index_and_frame(e).prelude.cp - 1).unwrap();
|
||||||
|
|
||||||
|
let p = cp.as_functor(&mut self.heap);
|
||||||
|
let e = self.stack.index_and_frame(e).prelude.e;
|
||||||
|
|
||||||
|
let e = Addr::Con(Constant::Usize(e));
|
||||||
|
|
||||||
|
self.unify(self[temp_v!(2)].clone(), e);
|
||||||
|
|
||||||
|
if !self.fail {
|
||||||
|
self.unify(self[temp_v!(3)].clone(), p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&SystemClauseType::PointsToContinuationResetMarker => {
|
||||||
|
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
|
let p = match self.heap.to_local_code_ptr(&addr) {
|
||||||
|
Some(p) => p + 1,
|
||||||
|
None => {
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if p.is_reset_cont_marker(code_repo, self.last_call) {
|
||||||
|
return return_from_clause!(self.last_call, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.fail = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
&SystemClauseType::ReadQueryTerm => {
|
&SystemClauseType::ReadQueryTerm => {
|
||||||
readline::set_prompt(true);
|
readline::set_prompt(true);
|
||||||
let result = self.read_term(current_input_stream, indices);
|
let result = self.read_term(current_input_stream, indices);
|
||||||
@@ -2013,6 +2197,8 @@ impl MachineState {
|
|||||||
self.reset_block(addr);
|
self.reset_block(addr);
|
||||||
}
|
}
|
||||||
&SystemClauseType::ResetContinuationMarker => {
|
&SystemClauseType::ResetContinuationMarker => {
|
||||||
|
self[temp_v!(3)] = Addr::Con(Constant::Integer(Integer::from(0)));
|
||||||
|
self[temp_v!(4)] = Addr::Con(Constant::Integer(Integer::from(0)));
|
||||||
}
|
}
|
||||||
&SystemClauseType::SetBall =>
|
&SystemClauseType::SetBall =>
|
||||||
self.set_ball(),
|
self.set_ball(),
|
||||||
@@ -2123,6 +2309,22 @@ impl MachineState {
|
|||||||
|
|
||||||
self.unify_with_occurs_check(a1, a2);
|
self.unify_with_occurs_check(a1, a2);
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::UnwindEnvironments => {
|
||||||
|
let mut e = self.e;
|
||||||
|
let mut cp = self.cp;
|
||||||
|
|
||||||
|
while e > 0 {
|
||||||
|
if cp.is_reset_cont_marker(code_repo, self.last_call) {
|
||||||
|
self.e = e;
|
||||||
|
self.p = CodePtr::Local(cp + 1); // skip the reset marker.
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = self.stack.index_and_frame(e).prelude.cp;
|
||||||
|
e = self.stack.index_and_frame(e).prelude.e;
|
||||||
|
}
|
||||||
|
}
|
||||||
&SystemClauseType::UnwindStack => self.unwind_stack(),
|
&SystemClauseType::UnwindStack => self.unwind_stack(),
|
||||||
&SystemClauseType::Variant => self.fail = self.structural_eq_test(),
|
&SystemClauseType::Variant => self.fail = self.structural_eq_test(),
|
||||||
&SystemClauseType::WAMInstructions => {
|
&SystemClauseType::WAMInstructions => {
|
||||||
|
|||||||
Reference in New Issue
Block a user