From: Mark Date: Sat, 17 Jun 2023 22:28:56 +0000 (-0600) Subject: implement new disjunction compilation X-Git-Tag: v0.9.2~123^2~27 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=0e583d620ab4ad95e55371905482c65dc5431bc9;p=scryer-prolog.git implement new disjunction compilation --- diff --git a/Cargo.lock b/Cargo.lock index 542afd09..8b4fc8a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2" version = "0.8.1" @@ -536,6 +548,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futf" version = "0.1.5" @@ -1526,6 +1544,12 @@ dependencies = [ "proc-macro2 1.0.47", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "radix_trie" version = "0.2.1" @@ -1856,6 +1880,7 @@ dependencies = [ "assert_cmd", "base64", "bit-set", + "bitvec", "blake2 0.8.1", "chrono", "cpu-time", @@ -2203,6 +2228,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.3.0" @@ -2592,21 +2623,6 @@ dependencies = [ "windows_x86_64_msvc 0.36.1", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -2628,24 +2644,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" -[[package]] -name = "windows_aarch64_msvc" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" - [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" - [[package]] name = "windows_aarch64_msvc" version = "0.42.1" @@ -2658,12 +2662,6 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" - [[package]] name = "windows_i686_gnu" version = "0.42.1" @@ -2676,12 +2674,6 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" - [[package]] name = "windows_i686_msvc" version = "0.42.1" @@ -2694,18 +2686,6 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" - [[package]] name = "windows_x86_64_gnu" version = "0.42.1" @@ -2714,9 +2694,9 @@ checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" @@ -2726,15 +2706,18 @@ checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.1" +name = "wyz" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] [[package]] name = "xmlparser" diff --git a/Cargo.toml b/Cargo.toml index f358126a..1f4fa7aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ walkdir = "2" [dependencies] bit-set = "0.5.3" +bitvec = "1" cpu-time = "1.0.0" crossterm = "0.20.0" dirs-next = "2.0.0" diff --git a/build/instructions_template.rs b/build/instructions_template.rs index d0a8c4d0..25036607 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -639,6 +639,10 @@ enum InstructionTemplate { Cut(RegType), #[strum_discriminants(strum(props(Arity = "1", Name = "get_level")))] GetLevel(RegType), + #[strum_discriminants(strum(props(Arity = "1", Name = "get_prev_level")))] + GetPrevLevel(RegType), + #[strum_discriminants(strum(props(Arity = "1", Name = "get_cut_point")))] + GetCutPoint(RegType), #[strum_discriminants(strum(props(Arity = "0", Name = "neck_cut")))] NeckCut, // choice instruction @@ -740,10 +744,8 @@ enum InstructionTemplate { Allocate(usize), // num_frames. #[strum_discriminants(strum(props(Arity = "0", Name = "deallocate")))] Deallocate, - #[strum_discriminants(strum(props(Arity = "arity", Name = "jmp_by_call")))] - JmpByCall(usize, usize), // arity, relative offset. - #[strum_discriminants(strum(props(Arity = "arity", Name = "jmp_by_execute")))] - JmpByExecute(usize, usize), // arity, relative offset. + #[strum_discriminants(strum(props(Arity = "1", Name = "jmp_by_call")))] + JmpByCall(usize), // relative offset. #[strum_discriminants(strum(props(Arity = "1", Name = "rev_jmp_by")))] RevJmpBy(usize), #[strum_discriminants(strum(props(Arity = "0", Name = "proceed")))] @@ -1114,6 +1116,7 @@ fn generate_instruction_preface() -> TokenStream { } pub type Code = Vec; + pub type CodeDeque = VecDeque; impl Instruction { #[inline] @@ -1296,6 +1299,14 @@ fn generate_instruction_preface() -> TokenStream { let rt_stub = reg_type_into_functor(r); functor!(atom!("get_level"), [str(h, 0)], [rt_stub]) } + &Instruction::GetPrevLevel(r) => { + let rt_stub = reg_type_into_functor(r); + functor!(atom!("get_prev_level"), [str(h, 0)], [rt_stub]) + } + &Instruction::GetCutPoint(r) => { + let rt_stub = reg_type_into_functor(r); + functor!(atom!("get_cut_point"), [str(h, 0)], [rt_stub]) + } &Instruction::NeckCut => { functor!(atom!("neck_cut")) } @@ -1449,30 +1460,30 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::DefaultExecuteNamed(arity, name, ..) => { functor!(atom!("execute_default"), [atom(name), fixnum(arity)]) } - &Instruction::CallN(arity, _) => { + &Instruction::CallN(arity) => { functor!(atom!("call_n"), [fixnum(arity)]) } - &Instruction::ExecuteN(arity, _) => { + &Instruction::ExecuteN(arity) => { functor!(atom!("execute_n"), [fixnum(arity)]) } - &Instruction::DefaultCallN(arity, _) => { + &Instruction::DefaultCallN(arity) => { functor!(atom!("call_default_n"), [fixnum(arity)]) } - &Instruction::DefaultExecuteN(arity, _) => { + &Instruction::DefaultExecuteN(arity) => { functor!(atom!("execute_default_n"), [fixnum(arity)]) } - &Instruction::CallInlineCallN(arity, _) => { + &Instruction::CallInlineCallN(arity) => { functor!(atom!("call_n_inline"), [fixnum(arity)]) } - &Instruction::ExecuteInlineCallN(arity, _) => { + &Instruction::ExecuteInlineCallN(arity) => { functor!(atom!("call_n_inline"), [fixnum(arity)]) } - &Instruction::CallTermGreaterThan(_) | - &Instruction::CallTermLessThan(_) | - &Instruction::CallTermGreaterThanOrEqual(_) | - &Instruction::CallTermLessThanOrEqual(_) | - &Instruction::CallTermEqual(_) | - &Instruction::CallTermNotEqual(_) | + &Instruction::CallTermGreaterThan | + &Instruction::CallTermLessThan | + &Instruction::CallTermGreaterThanOrEqual | + &Instruction::CallTermLessThanOrEqual | + &Instruction::CallTermEqual | + &Instruction::CallTermNotEqual | &Instruction::CallNumberGreaterThan(..) | &Instruction::CallNumberLessThan(..) | &Instruction::CallNumberGreaterThanOrEqual(..) | @@ -1480,563 +1491,561 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallNumberEqual(..) | &Instruction::CallNumberNotEqual(..) | &Instruction::CallIs(..) | - &Instruction::CallAcyclicTerm(_) | - &Instruction::CallArg(_) | - &Instruction::CallCompare(_) | - &Instruction::CallCopyTerm(_) | - &Instruction::CallFunctor(_) | - &Instruction::CallGround(_) | - &Instruction::CallKeySort(_) | - &Instruction::CallRead(_) | - &Instruction::CallSort(_) => { + &Instruction::CallAcyclicTerm | + &Instruction::CallArg | + &Instruction::CallCompare | + &Instruction::CallCopyTerm | + &Instruction::CallFunctor | + &Instruction::CallGround | + &Instruction::CallKeySort | + &Instruction::CallRead | + &Instruction::CallSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call"), [atom(name), fixnum(arity)]) } // - &Instruction::ExecuteTermGreaterThan(_) | - &Instruction::ExecuteTermLessThan(_) | - &Instruction::ExecuteTermGreaterThanOrEqual(_) | - &Instruction::ExecuteTermLessThanOrEqual(_) | - &Instruction::ExecuteTermEqual(_) | - &Instruction::ExecuteTermNotEqual(_) | + &Instruction::ExecuteTermGreaterThan | + &Instruction::ExecuteTermLessThan | + &Instruction::ExecuteTermGreaterThanOrEqual | + &Instruction::ExecuteTermLessThanOrEqual | + &Instruction::ExecuteTermEqual | + &Instruction::ExecuteTermNotEqual | &Instruction::ExecuteNumberGreaterThan(..) | &Instruction::ExecuteNumberLessThan(..) | &Instruction::ExecuteNumberGreaterThanOrEqual(..) | &Instruction::ExecuteNumberLessThanOrEqual(..) | &Instruction::ExecuteNumberEqual(..) | &Instruction::ExecuteNumberNotEqual(..) | - &Instruction::ExecuteAcyclicTerm(_) | - &Instruction::ExecuteArg(_) | - &Instruction::ExecuteCompare(_) | - &Instruction::ExecuteCopyTerm(_) | - &Instruction::ExecuteFunctor(_) | - &Instruction::ExecuteGround(_) | + &Instruction::ExecuteAcyclicTerm | + &Instruction::ExecuteArg | + &Instruction::ExecuteCompare | + &Instruction::ExecuteCopyTerm | + &Instruction::ExecuteFunctor | + &Instruction::ExecuteGround | &Instruction::ExecuteIs(..) | - &Instruction::ExecuteKeySort(_) | - &Instruction::ExecuteRead(_) | - &Instruction::ExecuteSort(_) => { + &Instruction::ExecuteKeySort | + &Instruction::ExecuteRead | + &Instruction::ExecuteSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute"), [atom(name), fixnum(arity)]) } // - &Instruction::DefaultCallTermGreaterThan(_) | - &Instruction::DefaultCallTermLessThan(_) | - &Instruction::DefaultCallTermGreaterThanOrEqual(_) | - &Instruction::DefaultCallTermLessThanOrEqual(_) | - &Instruction::DefaultCallTermEqual(_) | - &Instruction::DefaultCallTermNotEqual(_) | + &Instruction::DefaultCallTermGreaterThan | + &Instruction::DefaultCallTermLessThan | + &Instruction::DefaultCallTermGreaterThanOrEqual | + &Instruction::DefaultCallTermLessThanOrEqual | + &Instruction::DefaultCallTermEqual | + &Instruction::DefaultCallTermNotEqual | &Instruction::DefaultCallNumberGreaterThan(..) | &Instruction::DefaultCallNumberLessThan(..) | &Instruction::DefaultCallNumberGreaterThanOrEqual(..) | &Instruction::DefaultCallNumberLessThanOrEqual(..) | &Instruction::DefaultCallNumberEqual(..) | &Instruction::DefaultCallNumberNotEqual(..) | - &Instruction::DefaultCallAcyclicTerm(_) | - &Instruction::DefaultCallArg(_) | - &Instruction::DefaultCallCompare(_) | - &Instruction::DefaultCallCopyTerm(_) | - &Instruction::DefaultCallFunctor(_) | - &Instruction::DefaultCallGround(_) | + &Instruction::DefaultCallAcyclicTerm | + &Instruction::DefaultCallArg | + &Instruction::DefaultCallCompare | + &Instruction::DefaultCallCopyTerm | + &Instruction::DefaultCallFunctor | + &Instruction::DefaultCallGround | &Instruction::DefaultCallIs(..) | - &Instruction::DefaultCallKeySort(_) | - &Instruction::DefaultCallRead(_) | - &Instruction::DefaultCallSort(_) => { + &Instruction::DefaultCallKeySort | + &Instruction::DefaultCallRead | + &Instruction::DefaultCallSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call_default"), [atom(name), fixnum(arity)]) } // - &Instruction::DefaultExecuteTermGreaterThan(_) | - &Instruction::DefaultExecuteTermLessThan(_) | - &Instruction::DefaultExecuteTermGreaterThanOrEqual(_) | - &Instruction::DefaultExecuteTermLessThanOrEqual(_) | - &Instruction::DefaultExecuteTermEqual(_) | - &Instruction::DefaultExecuteTermNotEqual(_) | + &Instruction::DefaultExecuteTermGreaterThan | + &Instruction::DefaultExecuteTermLessThan | + &Instruction::DefaultExecuteTermGreaterThanOrEqual | + &Instruction::DefaultExecuteTermLessThanOrEqual | + &Instruction::DefaultExecuteTermEqual | + &Instruction::DefaultExecuteTermNotEqual | &Instruction::DefaultExecuteNumberGreaterThan(..) | &Instruction::DefaultExecuteNumberLessThan(..) | &Instruction::DefaultExecuteNumberGreaterThanOrEqual(..) | &Instruction::DefaultExecuteNumberLessThanOrEqual(..) | &Instruction::DefaultExecuteNumberEqual(..) | &Instruction::DefaultExecuteNumberNotEqual(..) | - &Instruction::DefaultExecuteAcyclicTerm(_) | - &Instruction::DefaultExecuteArg(_) | - &Instruction::DefaultExecuteCompare(_) | - &Instruction::DefaultExecuteCopyTerm(_) | - &Instruction::DefaultExecuteFunctor(_) | - &Instruction::DefaultExecuteGround(_) | + &Instruction::DefaultExecuteAcyclicTerm | + &Instruction::DefaultExecuteArg | + &Instruction::DefaultExecuteCompare | + &Instruction::DefaultExecuteCopyTerm | + &Instruction::DefaultExecuteFunctor | + &Instruction::DefaultExecuteGround | &Instruction::DefaultExecuteIs(..) | - &Instruction::DefaultExecuteKeySort(_) | - &Instruction::DefaultExecuteRead(_) | - &Instruction::DefaultExecuteSort(_) => { + &Instruction::DefaultExecuteKeySort | + &Instruction::DefaultExecuteRead | + &Instruction::DefaultExecuteSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute_default"), [atom(name), fixnum(arity)]) } - &Instruction::CallIsAtom(_, _) | - &Instruction::CallIsAtomic(_, _) | - &Instruction::CallIsCompound(_, _) | - &Instruction::CallIsInteger(_, _) | - &Instruction::CallIsNumber(_, _) | - &Instruction::CallIsRational(_, _) | - &Instruction::CallIsFloat(_, _) | - &Instruction::CallIsNonVar(_, _) | - &Instruction::CallIsVar(_, _) => { + &Instruction::CallIsAtom(_) | + &Instruction::CallIsAtomic(_) | + &Instruction::CallIsCompound(_) | + &Instruction::CallIsInteger(_) | + &Instruction::CallIsNumber(_) | + &Instruction::CallIsRational(_) | + &Instruction::CallIsFloat(_) | + &Instruction::CallIsNonVar(_) | + &Instruction::CallIsVar(_) => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call"), [atom(name), fixnum(arity)]) } - &Instruction::ExecuteIsAtom(_, _) | - &Instruction::ExecuteIsAtomic(_, _) | - &Instruction::ExecuteIsCompound(_, _) | - &Instruction::ExecuteIsInteger(_, _) | - &Instruction::ExecuteIsNumber(_, _) | - &Instruction::ExecuteIsRational(_, _) | - &Instruction::ExecuteIsFloat(_, _) | - &Instruction::ExecuteIsNonVar(_, _) | - &Instruction::ExecuteIsVar(_, _) => { + &Instruction::ExecuteIsAtom(_) | + &Instruction::ExecuteIsAtomic(_) | + &Instruction::ExecuteIsCompound(_) | + &Instruction::ExecuteIsInteger(_) | + &Instruction::ExecuteIsNumber(_) | + &Instruction::ExecuteIsRational(_) | + &Instruction::ExecuteIsFloat(_) | + &Instruction::ExecuteIsNonVar(_) | + &Instruction::ExecuteIsVar(_) => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute"), [atom(name), fixnum(arity)]) } // - &Instruction::CallAtomChars(_) | - &Instruction::CallAtomCodes(_) | - &Instruction::CallAtomLength(_) | - &Instruction::CallBindFromRegister(_) | - &Instruction::CallContinuation(_) | - &Instruction::CallCharCode(_) | - &Instruction::CallCharType(_) | - &Instruction::CallCharsToNumber(_) | - &Instruction::CallCodesToNumber(_) | - &Instruction::CallCopyTermWithoutAttrVars(_) | - &Instruction::CallCheckCutPoint(_) | - &Instruction::CallClose(_) | - &Instruction::CallCopyToLiftedHeap(_) | - &Instruction::CallCreatePartialString(_) | - &Instruction::CallCurrentHostname(_) | - &Instruction::CallCurrentInput(_) | - &Instruction::CallCurrentOutput(_) | - &Instruction::CallDirectoryFiles(_) | - &Instruction::CallFileSize(_) | - &Instruction::CallFileExists(_) | - &Instruction::CallDirectoryExists(_) | - &Instruction::CallDirectorySeparator(_) | - &Instruction::CallMakeDirectory(_) | - &Instruction::CallMakeDirectoryPath(_) | - &Instruction::CallDeleteFile(_) | - &Instruction::CallRenameFile(_) | - &Instruction::CallFileCopy(_) | - &Instruction::CallWorkingDirectory(_) | - &Instruction::CallDeleteDirectory(_) | - &Instruction::CallPathCanonical(_) | - &Instruction::CallFileTime(_) | + &Instruction::CallAtomChars | + &Instruction::CallAtomCodes | + &Instruction::CallAtomLength | + &Instruction::CallBindFromRegister | + &Instruction::CallContinuation | + &Instruction::CallCharCode | + &Instruction::CallCharType | + &Instruction::CallCharsToNumber | + &Instruction::CallCodesToNumber | + &Instruction::CallCopyTermWithoutAttrVars | + &Instruction::CallCheckCutPoint | + &Instruction::CallClose | + &Instruction::CallCopyToLiftedHeap | + &Instruction::CallCreatePartialString | + &Instruction::CallCurrentHostname | + &Instruction::CallCurrentInput | + &Instruction::CallCurrentOutput | + &Instruction::CallDirectoryFiles | + &Instruction::CallFileSize | + &Instruction::CallFileExists | + &Instruction::CallDirectoryExists | + &Instruction::CallDirectorySeparator | + &Instruction::CallMakeDirectory | + &Instruction::CallMakeDirectoryPath | + &Instruction::CallDeleteFile | + &Instruction::CallRenameFile | + &Instruction::CallFileCopy | + &Instruction::CallWorkingDirectory | + &Instruction::CallDeleteDirectory | + &Instruction::CallPathCanonical | + &Instruction::CallFileTime | &Instruction::CallDynamicModuleResolution(..) | &Instruction::CallPrepareCallClause(..) | - &Instruction::CallCompileInlineOrExpandedGoal(..) | - &Instruction::CallIsExpandedOrInlined(_) | - &Instruction::CallGetClauseP(_) | - &Instruction::CallInvokeClauseAtP(_) | - &Instruction::CallGetFromAttributedVarList(_) | - &Instruction::CallPutToAttributedVarList(_) | - &Instruction::CallDeleteFromAttributedVarList(_) | - &Instruction::CallDeleteAllAttributesFromVar(_) | - &Instruction::CallUnattributedVar(_) | - &Instruction::CallGetDBRefs(_) | - &Instruction::CallEnqueueAttributedVar(_) | - &Instruction::CallFetchGlobalVar(_) | - &Instruction::CallFirstStream(_) | - &Instruction::CallFlushOutput(_) | - &Instruction::CallGetByte(_) | - &Instruction::CallGetChar(_) | - &Instruction::CallGetNChars(_) | - &Instruction::CallGetCode(_) | - &Instruction::CallGetSingleChar(_) | - &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff(_) | - &Instruction::CallTruncateIfNoLiftedHeapGrowth(_) | - &Instruction::CallGetAttributedVariableList(_) | - &Instruction::CallGetAttrVarQueueDelimiter(_) | - &Instruction::CallGetAttrVarQueueBeyond(_) | - &Instruction::CallGetBValue(_) | - &Instruction::CallGetContinuationChunk(_) | - &Instruction::CallGetNextOpDBRef(_) | - &Instruction::CallLookupDBRef(_) | - &Instruction::CallIsPartialString(_) | - &Instruction::CallHalt(_) | - &Instruction::CallGetLiftedHeapFromOffset(_) | - &Instruction::CallGetLiftedHeapFromOffsetDiff(_) | - &Instruction::CallGetSCCCleaner(_) | - &Instruction::CallHeadIsDynamic(_) | - &Instruction::CallInstallSCCCleaner(_) | - &Instruction::CallInstallInferenceCounter(_) | - &Instruction::CallLiftedHeapLength(_) | - &Instruction::CallLoadLibraryAsStream(_) | - &Instruction::CallModuleExists(_) | - &Instruction::CallNextEP(_) | - &Instruction::CallNoSuchPredicate(_) | - &Instruction::CallNumberToChars(_) | - &Instruction::CallNumberToCodes(_) | - &Instruction::CallOpDeclaration(_) | - &Instruction::CallOpen(_) | - &Instruction::CallSetStreamOptions(_) | - &Instruction::CallNextStream(_) | - &Instruction::CallPartialStringTail(_) | - &Instruction::CallPeekByte(_) | - &Instruction::CallPeekChar(_) | - &Instruction::CallPeekCode(_) | - &Instruction::CallPointsToContinuationResetMarker(_) | - &Instruction::CallPutByte(_) | - &Instruction::CallPutChar(_) | - &Instruction::CallPutChars(_) | - &Instruction::CallPutCode(_) | - &Instruction::CallReadQueryTerm(_) | - &Instruction::CallReadTerm(_) | - &Instruction::CallRedoAttrVarBinding(_) | - &Instruction::CallRemoveCallPolicyCheck(_) | - &Instruction::CallRemoveInferenceCounter(_) | - &Instruction::CallResetContinuationMarker(_) | - &Instruction::CallRestoreCutPolicy(_) | + &Instruction::CallCompileInlineOrExpandedGoal | + &Instruction::CallIsExpandedOrInlined | + &Instruction::CallGetClauseP | + &Instruction::CallInvokeClauseAtP | + &Instruction::CallGetFromAttributedVarList | + &Instruction::CallPutToAttributedVarList | + &Instruction::CallDeleteFromAttributedVarList | + &Instruction::CallDeleteAllAttributesFromVar | + &Instruction::CallUnattributedVar | + &Instruction::CallGetDBRefs | + &Instruction::CallFetchGlobalVar | + &Instruction::CallFirstStream | + &Instruction::CallFlushOutput | + &Instruction::CallGetByte | + &Instruction::CallGetChar | + &Instruction::CallGetNChars | + &Instruction::CallGetCode | + &Instruction::CallGetSingleChar | + &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff | + &Instruction::CallTruncateIfNoLiftedHeapGrowth | + &Instruction::CallGetAttributedVariableList | + &Instruction::CallGetAttrVarQueueDelimiter | + &Instruction::CallGetAttrVarQueueBeyond | + &Instruction::CallGetBValue | + &Instruction::CallGetContinuationChunk | + &Instruction::CallGetNextOpDBRef | + &Instruction::CallLookupDBRef | + &Instruction::CallIsPartialString | + &Instruction::CallHalt | + &Instruction::CallGetLiftedHeapFromOffset | + &Instruction::CallGetLiftedHeapFromOffsetDiff | + &Instruction::CallGetSCCCleaner | + &Instruction::CallHeadIsDynamic | + &Instruction::CallInstallSCCCleaner | + &Instruction::CallInstallInferenceCounter | + &Instruction::CallLiftedHeapLength | + &Instruction::CallLoadLibraryAsStream | + &Instruction::CallModuleExists | + &Instruction::CallNextEP | + &Instruction::CallNoSuchPredicate | + &Instruction::CallNumberToChars | + &Instruction::CallNumberToCodes | + &Instruction::CallOpDeclaration | + &Instruction::CallOpen | + &Instruction::CallSetStreamOptions | + &Instruction::CallNextStream | + &Instruction::CallPartialStringTail | + &Instruction::CallPeekByte | + &Instruction::CallPeekChar | + &Instruction::CallPeekCode | + &Instruction::CallPointsToContinuationResetMarker | + &Instruction::CallPutByte | + &Instruction::CallPutChar | + &Instruction::CallPutChars | + &Instruction::CallPutCode | + &Instruction::CallReadQueryTerm | + &Instruction::CallReadTerm | + &Instruction::CallRedoAttrVarBinding | + &Instruction::CallRemoveCallPolicyCheck | + &Instruction::CallRemoveInferenceCounter | + &Instruction::CallResetContinuationMarker | + &Instruction::CallRestoreCutPolicy | &Instruction::CallSetCutPoint(..) | - &Instruction::CallSetInput(_) | - &Instruction::CallSetOutput(_) | - &Instruction::CallStoreBacktrackableGlobalVar(_) | - &Instruction::CallStoreGlobalVar(_) | - &Instruction::CallStreamProperty(_) | - &Instruction::CallSetStreamPosition(_) | - &Instruction::CallInferenceLevel(_) | - &Instruction::CallCleanUpBlock(_) | - &Instruction::CallFail(_) | - &Instruction::CallGetBall(_) | - &Instruction::CallGetCurrentBlock(_) | - &Instruction::CallGetCutPoint(_) | - &Instruction::CallGetDoubleQuotes(_) | - &Instruction::CallInstallNewBlock(_) | - &Instruction::CallMaybe(_) | - &Instruction::CallCpuNow(_) | - &Instruction::CallDeterministicLengthRundown(_) | - &Instruction::CallHttpOpen(_) | - &Instruction::CallHttpListen(_) | - &Instruction::CallHttpAccept(_) | - &Instruction::CallHttpAnswer(_) | - &Instruction::CallLoadForeignLib(_) | - &Instruction::CallForeignCall(_) | - &Instruction::CallDefineForeignStruct(_) | - &Instruction::CallPredicateDefined(_) | - &Instruction::CallStripModule(_) | - &Instruction::CallCurrentTime(_) | - &Instruction::CallQuotedToken(_) | - &Instruction::CallReadTermFromChars(_) | - &Instruction::CallResetBlock(_) | - &Instruction::CallReturnFromVerifyAttr(_) | - &Instruction::CallSetBall(_) | - &Instruction::CallPushBallStack(_) | - &Instruction::CallPopBallStack(_) | - &Instruction::CallPopFromBallStack(_) | + &Instruction::CallSetInput | + &Instruction::CallSetOutput | + &Instruction::CallStoreBacktrackableGlobalVar | + &Instruction::CallStoreGlobalVar | + &Instruction::CallStreamProperty | + &Instruction::CallSetStreamPosition | + &Instruction::CallInferenceLevel | + &Instruction::CallCleanUpBlock | + &Instruction::CallFail | + &Instruction::CallGetBall | + &Instruction::CallGetCurrentBlock | + &Instruction::CallGetCutPoint | + &Instruction::CallGetDoubleQuotes | + &Instruction::CallInstallNewBlock | + &Instruction::CallMaybe | + &Instruction::CallCpuNow | + &Instruction::CallDeterministicLengthRundown | + &Instruction::CallHttpOpen | + &Instruction::CallHttpListen | + &Instruction::CallHttpAccept | + &Instruction::CallHttpAnswer | + &Instruction::CallLoadForeignLib | + &Instruction::CallForeignCall | + &Instruction::CallDefineForeignStruct | + &Instruction::CallPredicateDefined | + &Instruction::CallStripModule | + &Instruction::CallCurrentTime | + &Instruction::CallQuotedToken | + &Instruction::CallReadTermFromChars | + &Instruction::CallResetBlock | + &Instruction::CallReturnFromVerifyAttr | + &Instruction::CallSetBall | + &Instruction::CallPushBallStack | + &Instruction::CallPopBallStack | + &Instruction::CallPopFromBallStack | &Instruction::CallSetCutPointByDefault(..) | - &Instruction::CallSetDoubleQuotes(_) | - &Instruction::CallSetSeed(_) | - &Instruction::CallSkipMaxList(_) | - &Instruction::CallSleep(_) | - &Instruction::CallSocketClientOpen(_) | - &Instruction::CallSocketServerOpen(_) | - &Instruction::CallSocketServerAccept(_) | - &Instruction::CallSocketServerClose(_) | - &Instruction::CallTLSAcceptClient(_) | - &Instruction::CallTLSClientConnect(_) | - &Instruction::CallSucceed(_) | - &Instruction::CallTermAttributedVariables(_) | - &Instruction::CallTermVariables(_) | - &Instruction::CallTermVariablesUnderMaxDepth(_) | - &Instruction::CallTruncateLiftedHeapTo(_) | - &Instruction::CallUnifyWithOccursCheck(_) | - &Instruction::CallUnwindEnvironments(_) | - &Instruction::CallUnwindStack(_) | - &Instruction::CallWAMInstructions(_) | - &Instruction::CallInlinedInstructions(_) | - &Instruction::CallWriteTerm(_) | - &Instruction::CallWriteTermToChars(_) | - &Instruction::CallScryerPrologVersion(_) | - &Instruction::CallCryptoRandomByte(_) | - &Instruction::CallCryptoDataHash(_) | - &Instruction::CallCryptoDataHKDF(_) | - &Instruction::CallCryptoPasswordHash(_) | - &Instruction::CallCryptoDataEncrypt(_) | - &Instruction::CallCryptoDataDecrypt(_) | - &Instruction::CallCryptoCurveScalarMult(_) | - &Instruction::CallEd25519Sign(_) | - &Instruction::CallEd25519Verify(_) | - &Instruction::CallEd25519NewKeyPair(_) | - &Instruction::CallEd25519KeyPairPublicKey(_) | - &Instruction::CallCurve25519ScalarMult(_) | - &Instruction::CallFirstNonOctet(_) | - &Instruction::CallLoadHTML(_) | - &Instruction::CallLoadXML(_) | - &Instruction::CallGetEnv(_) | - &Instruction::CallSetEnv(_) | - &Instruction::CallUnsetEnv(_) | - &Instruction::CallShell(_) | - &Instruction::CallPID(_) | - &Instruction::CallCharsBase64(_) | - &Instruction::CallDevourWhitespace(_) | - &Instruction::CallIsSTOEnabled(_) | - &Instruction::CallSetSTOAsUnify(_) | - &Instruction::CallSetNSTOAsUnify(_) | - &Instruction::CallSetSTOWithErrorAsUnify(_) | - &Instruction::CallHomeDirectory(_) | - &Instruction::CallDebugHook(_) | - &Instruction::CallAddDiscontiguousPredicate(_) | - &Instruction::CallAddDynamicPredicate(_) | - &Instruction::CallAddMultifilePredicate(_) | - &Instruction::CallAddGoalExpansionClause(_) | - &Instruction::CallAddTermExpansionClause(_) | - &Instruction::CallAddInSituFilenameModule(_) | - &Instruction::CallClauseToEvacuable(_) | - &Instruction::CallScopedClauseToEvacuable(_) | - &Instruction::CallConcludeLoad(_) | - &Instruction::CallDeclareModule(_) | - &Instruction::CallLoadCompiledLibrary(_) | - &Instruction::CallLoadContextSource(_) | - &Instruction::CallLoadContextFile(_) | - &Instruction::CallLoadContextDirectory(_) | - &Instruction::CallLoadContextModule(_) | - &Instruction::CallLoadContextStream(_) | - &Instruction::CallPopLoadContext(_) | - &Instruction::CallPopLoadStatePayload(_) | - &Instruction::CallPushLoadContext(_) | - &Instruction::CallPushLoadStatePayload(_) | - &Instruction::CallUseModule(_) | - &Instruction::CallBuiltInProperty(_) | - &Instruction::CallMetaPredicateProperty(_) | - &Instruction::CallMultifileProperty(_) | - &Instruction::CallDiscontiguousProperty(_) | - &Instruction::CallDynamicProperty(_) | - &Instruction::CallAbolishClause(_) | - &Instruction::CallAsserta(_) | - &Instruction::CallAssertz(_) | - &Instruction::CallRetract(_) | - &Instruction::CallIsConsistentWithTermQueue(_) | - &Instruction::CallFlushTermQueue(_) | - &Instruction::CallRemoveModuleExports(_) | - &Instruction::CallAddNonCountedBacktracking(_) | - &Instruction::CallPopCount(_) => { + &Instruction::CallSetDoubleQuotes | + &Instruction::CallSetSeed | + &Instruction::CallSkipMaxList | + &Instruction::CallSleep | + &Instruction::CallSocketClientOpen | + &Instruction::CallSocketServerOpen | + &Instruction::CallSocketServerAccept | + &Instruction::CallSocketServerClose | + &Instruction::CallTLSAcceptClient | + &Instruction::CallTLSClientConnect | + &Instruction::CallSucceed | + &Instruction::CallTermAttributedVariables | + &Instruction::CallTermVariables | + &Instruction::CallTermVariablesUnderMaxDepth | + &Instruction::CallTruncateLiftedHeapTo | + &Instruction::CallUnifyWithOccursCheck | + &Instruction::CallUnwindEnvironments | + &Instruction::CallUnwindStack | + &Instruction::CallWAMInstructions | + &Instruction::CallInlinedInstructions | + &Instruction::CallWriteTerm | + &Instruction::CallWriteTermToChars | + &Instruction::CallScryerPrologVersion | + &Instruction::CallCryptoRandomByte | + &Instruction::CallCryptoDataHash | + &Instruction::CallCryptoDataHKDF | + &Instruction::CallCryptoPasswordHash | + &Instruction::CallCryptoDataEncrypt | + &Instruction::CallCryptoDataDecrypt | + &Instruction::CallCryptoCurveScalarMult | + &Instruction::CallEd25519Sign | + &Instruction::CallEd25519Verify | + &Instruction::CallEd25519NewKeyPair | + &Instruction::CallEd25519KeyPairPublicKey | + &Instruction::CallCurve25519ScalarMult | + &Instruction::CallFirstNonOctet | + &Instruction::CallLoadHTML | + &Instruction::CallLoadXML | + &Instruction::CallGetEnv | + &Instruction::CallSetEnv | + &Instruction::CallUnsetEnv | + &Instruction::CallShell | + &Instruction::CallPID | + &Instruction::CallCharsBase64 | + &Instruction::CallDevourWhitespace | + &Instruction::CallIsSTOEnabled | + &Instruction::CallSetSTOAsUnify | + &Instruction::CallSetNSTOAsUnify | + &Instruction::CallSetSTOWithErrorAsUnify | + &Instruction::CallHomeDirectory | + &Instruction::CallDebugHook | + &Instruction::CallAddDiscontiguousPredicate | + &Instruction::CallAddDynamicPredicate | + &Instruction::CallAddMultifilePredicate | + &Instruction::CallAddGoalExpansionClause | + &Instruction::CallAddTermExpansionClause | + &Instruction::CallAddInSituFilenameModule | + &Instruction::CallClauseToEvacuable | + &Instruction::CallScopedClauseToEvacuable | + &Instruction::CallConcludeLoad | + &Instruction::CallDeclareModule | + &Instruction::CallLoadCompiledLibrary | + &Instruction::CallLoadContextSource | + &Instruction::CallLoadContextFile | + &Instruction::CallLoadContextDirectory | + &Instruction::CallLoadContextModule | + &Instruction::CallLoadContextStream | + &Instruction::CallPopLoadContext | + &Instruction::CallPopLoadStatePayload | + &Instruction::CallPushLoadContext | + &Instruction::CallPushLoadStatePayload | + &Instruction::CallUseModule | + &Instruction::CallBuiltInProperty | + &Instruction::CallMetaPredicateProperty | + &Instruction::CallMultifileProperty | + &Instruction::CallDiscontiguousProperty | + &Instruction::CallDynamicProperty | + &Instruction::CallAbolishClause | + &Instruction::CallAsserta | + &Instruction::CallAssertz | + &Instruction::CallRetract | + &Instruction::CallIsConsistentWithTermQueue | + &Instruction::CallFlushTermQueue | + &Instruction::CallRemoveModuleExports | + &Instruction::CallAddNonCountedBacktracking | + &Instruction::CallPopCount => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call"), [atom(name), fixnum(arity)]) } // - &Instruction::ExecuteAtomChars(_) | - &Instruction::ExecuteAtomCodes(_) | - &Instruction::ExecuteAtomLength(_) | - &Instruction::ExecuteBindFromRegister(_) | - &Instruction::ExecuteContinuation(_) | - &Instruction::ExecuteCharCode(_) | - &Instruction::ExecuteCharType(_) | - &Instruction::ExecuteCharsToNumber(_) | - &Instruction::ExecuteCodesToNumber(_) | - &Instruction::ExecuteCopyTermWithoutAttrVars(_) | - &Instruction::ExecuteCheckCutPoint(_) | - &Instruction::ExecuteClose(_) | - &Instruction::ExecuteCopyToLiftedHeap(_) | - &Instruction::ExecuteCreatePartialString(_) | - &Instruction::ExecuteCurrentHostname(_) | - &Instruction::ExecuteCurrentInput(_) | - &Instruction::ExecuteCurrentOutput(_) | - &Instruction::ExecuteDirectoryFiles(_) | - &Instruction::ExecuteFileSize(_) | - &Instruction::ExecuteFileExists(_) | - &Instruction::ExecuteDirectoryExists(_) | - &Instruction::ExecuteDirectorySeparator(_) | - &Instruction::ExecuteMakeDirectory(_) | - &Instruction::ExecuteMakeDirectoryPath(_) | - &Instruction::ExecuteDeleteFile(_) | - &Instruction::ExecuteRenameFile(_) | - &Instruction::ExecuteFileCopy(_) | - &Instruction::ExecuteWorkingDirectory(_) | - &Instruction::ExecuteDeleteDirectory(_) | - &Instruction::ExecutePathCanonical(_) | - &Instruction::ExecuteFileTime(_) | + &Instruction::ExecuteAtomChars | + &Instruction::ExecuteAtomCodes | + &Instruction::ExecuteAtomLength | + &Instruction::ExecuteBindFromRegister | + &Instruction::ExecuteContinuation | + &Instruction::ExecuteCharCode | + &Instruction::ExecuteCharType | + &Instruction::ExecuteCharsToNumber | + &Instruction::ExecuteCodesToNumber | + &Instruction::ExecuteCopyTermWithoutAttrVars | + &Instruction::ExecuteCheckCutPoint | + &Instruction::ExecuteClose | + &Instruction::ExecuteCopyToLiftedHeap | + &Instruction::ExecuteCreatePartialString | + &Instruction::ExecuteCurrentHostname | + &Instruction::ExecuteCurrentInput | + &Instruction::ExecuteCurrentOutput | + &Instruction::ExecuteDirectoryFiles | + &Instruction::ExecuteFileSize | + &Instruction::ExecuteFileExists | + &Instruction::ExecuteDirectoryExists | + &Instruction::ExecuteDirectorySeparator | + &Instruction::ExecuteMakeDirectory | + &Instruction::ExecuteMakeDirectoryPath | + &Instruction::ExecuteDeleteFile | + &Instruction::ExecuteRenameFile | + &Instruction::ExecuteFileCopy | + &Instruction::ExecuteWorkingDirectory | + &Instruction::ExecuteDeleteDirectory | + &Instruction::ExecutePathCanonical | + &Instruction::ExecuteFileTime | &Instruction::ExecuteDynamicModuleResolution(..) | &Instruction::ExecutePrepareCallClause(..) | - &Instruction::ExecuteCompileInlineOrExpandedGoal(..) | - &Instruction::ExecuteIsExpandedOrInlined(_) | - &Instruction::ExecuteGetClauseP(_) | - &Instruction::ExecuteInvokeClauseAtP(_) | - &Instruction::ExecuteGetFromAttributedVarList(_) | - &Instruction::ExecutePutToAttributedVarList(_) | - &Instruction::ExecuteDeleteFromAttributedVarList(_) | - &Instruction::ExecuteDeleteAllAttributesFromVar(_) | - &Instruction::ExecuteUnattributedVar(_) | - &Instruction::ExecuteGetDBRefs(_) | - &Instruction::ExecuteEnqueueAttributedVar(_) | - &Instruction::ExecuteFetchGlobalVar(_) | - &Instruction::ExecuteFirstStream(_) | - &Instruction::ExecuteFlushOutput(_) | - &Instruction::ExecuteGetByte(_) | - &Instruction::ExecuteGetChar(_) | - &Instruction::ExecuteGetNChars(_) | - &Instruction::ExecuteGetCode(_) | - &Instruction::ExecuteGetSingleChar(_) | - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff(_) | - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth(_) | - &Instruction::ExecuteGetAttributedVariableList(_) | - &Instruction::ExecuteGetAttrVarQueueDelimiter(_) | - &Instruction::ExecuteGetAttrVarQueueBeyond(_) | - &Instruction::ExecuteGetBValue(_) | - &Instruction::ExecuteGetContinuationChunk(_) | - &Instruction::ExecuteGetNextOpDBRef(_) | - &Instruction::ExecuteLookupDBRef(_) | - &Instruction::ExecuteIsPartialString(_) | - &Instruction::ExecuteHalt(_) | - &Instruction::ExecuteGetLiftedHeapFromOffset(_) | - &Instruction::ExecuteGetLiftedHeapFromOffsetDiff(_) | - &Instruction::ExecuteGetSCCCleaner(_) | - &Instruction::ExecuteHeadIsDynamic(_) | - &Instruction::ExecuteInstallSCCCleaner(_) | - &Instruction::ExecuteInstallInferenceCounter(_) | - &Instruction::ExecuteLiftedHeapLength(_) | - &Instruction::ExecuteLoadLibraryAsStream(_) | - &Instruction::ExecuteModuleExists(_) | - &Instruction::ExecuteNextEP(_) | - &Instruction::ExecuteNoSuchPredicate(_) | - &Instruction::ExecuteNumberToChars(_) | - &Instruction::ExecuteNumberToCodes(_) | - &Instruction::ExecuteOpDeclaration(_) | - &Instruction::ExecuteOpen(_) | - &Instruction::ExecuteSetStreamOptions(_) | - &Instruction::ExecuteNextStream(_) | - &Instruction::ExecutePartialStringTail(_) | - &Instruction::ExecutePeekByte(_) | - &Instruction::ExecutePeekChar(_) | - &Instruction::ExecutePeekCode(_) | - &Instruction::ExecutePointsToContinuationResetMarker(_) | - &Instruction::ExecutePutByte(_) | - &Instruction::ExecutePutChar(_) | - &Instruction::ExecutePutChars(_) | - &Instruction::ExecutePutCode(_) | - &Instruction::ExecuteReadQueryTerm(_) | - &Instruction::ExecuteReadTerm(_) | - &Instruction::ExecuteRedoAttrVarBinding(_) | - &Instruction::ExecuteRemoveCallPolicyCheck(_) | - &Instruction::ExecuteRemoveInferenceCounter(_) | - &Instruction::ExecuteResetContinuationMarker(_) | - &Instruction::ExecuteRestoreCutPolicy(_) | - &Instruction::ExecuteSetCutPoint(_, _) | - &Instruction::ExecuteSetInput(_) | - &Instruction::ExecuteSetOutput(_) | - &Instruction::ExecuteStoreBacktrackableGlobalVar(_) | - &Instruction::ExecuteStoreGlobalVar(_) | - &Instruction::ExecuteStreamProperty(_) | - &Instruction::ExecuteSetStreamPosition(_) | - &Instruction::ExecuteInferenceLevel(_) | - &Instruction::ExecuteCleanUpBlock(_) | - &Instruction::ExecuteFail(_) | - &Instruction::ExecuteGetBall(_) | - &Instruction::ExecuteGetCurrentBlock(_) | - &Instruction::ExecuteGetCutPoint(_) | - &Instruction::ExecuteGetDoubleQuotes(_) | - &Instruction::ExecuteInstallNewBlock(_) | - &Instruction::ExecuteMaybe(_) | - &Instruction::ExecuteCpuNow(_) | - &Instruction::ExecuteDeterministicLengthRundown(_) | - &Instruction::ExecuteHttpOpen(_) | - &Instruction::ExecuteHttpListen(_) | - &Instruction::ExecuteHttpAccept(_) | - &Instruction::ExecuteHttpAnswer(_) | - &Instruction::ExecuteLoadForeignLib(_) | - &Instruction::ExecuteForeignCall(_) | - &Instruction::ExecuteDefineForeignStruct(_) | - &Instruction::ExecutePredicateDefined(_) | - &Instruction::ExecuteStripModule(_) | - &Instruction::ExecuteCurrentTime(_) | - &Instruction::ExecuteQuotedToken(_) | - &Instruction::ExecuteReadTermFromChars(_) | - &Instruction::ExecuteResetBlock(_) | - &Instruction::ExecuteReturnFromVerifyAttr(_) | - &Instruction::ExecuteSetBall(_) | - &Instruction::ExecutePushBallStack(_) | - &Instruction::ExecutePopBallStack(_) | - &Instruction::ExecutePopFromBallStack(_) | - &Instruction::ExecuteSetCutPointByDefault(_, _) | - &Instruction::ExecuteSetDoubleQuotes(_) | - &Instruction::ExecuteSetSeed(_) | - &Instruction::ExecuteSkipMaxList(_) | - &Instruction::ExecuteSleep(_) | - &Instruction::ExecuteSocketClientOpen(_) | - &Instruction::ExecuteSocketServerOpen(_) | - &Instruction::ExecuteSocketServerAccept(_) | - &Instruction::ExecuteSocketServerClose(_) | - &Instruction::ExecuteTLSAcceptClient(_) | - &Instruction::ExecuteTLSClientConnect(_) | - &Instruction::ExecuteSucceed(_) | - &Instruction::ExecuteTermAttributedVariables(_) | - &Instruction::ExecuteTermVariables(_) | - &Instruction::ExecuteTermVariablesUnderMaxDepth(_) | - &Instruction::ExecuteTruncateLiftedHeapTo(_) | - &Instruction::ExecuteUnifyWithOccursCheck(_) | - &Instruction::ExecuteUnwindEnvironments(_) | - &Instruction::ExecuteUnwindStack(_) | - &Instruction::ExecuteWAMInstructions(_) | - &Instruction::ExecuteInlinedInstructions(_) | - &Instruction::ExecuteWriteTerm(_) | - &Instruction::ExecuteWriteTermToChars(_) | - &Instruction::ExecuteScryerPrologVersion(_) | - &Instruction::ExecuteCryptoRandomByte(_) | - &Instruction::ExecuteCryptoDataHash(_) | - &Instruction::ExecuteCryptoDataHKDF(_) | - &Instruction::ExecuteCryptoPasswordHash(_) | - &Instruction::ExecuteCryptoDataEncrypt(_) | - &Instruction::ExecuteCryptoDataDecrypt(_) | - &Instruction::ExecuteCryptoCurveScalarMult(_) | - &Instruction::ExecuteEd25519Sign(_) | - &Instruction::ExecuteEd25519Verify(_) | - &Instruction::ExecuteEd25519NewKeyPair(_) | - &Instruction::ExecuteEd25519KeyPairPublicKey(_) | - &Instruction::ExecuteCurve25519ScalarMult(_) | - &Instruction::ExecuteFirstNonOctet(_) | - &Instruction::ExecuteLoadHTML(_) | - &Instruction::ExecuteLoadXML(_) | - &Instruction::ExecuteGetEnv(_) | - &Instruction::ExecuteSetEnv(_) | - &Instruction::ExecuteUnsetEnv(_) | - &Instruction::ExecuteShell(_) | - &Instruction::ExecutePID(_) | - &Instruction::ExecuteCharsBase64(_) | - &Instruction::ExecuteDevourWhitespace(_) | - &Instruction::ExecuteIsSTOEnabled(_) | - &Instruction::ExecuteSetSTOAsUnify(_) | - &Instruction::ExecuteSetNSTOAsUnify(_) | - &Instruction::ExecuteSetSTOWithErrorAsUnify(_) | - &Instruction::ExecuteHomeDirectory(_) | - &Instruction::ExecuteDebugHook(_) | - &Instruction::ExecuteAddDiscontiguousPredicate(_) | - &Instruction::ExecuteAddDynamicPredicate(_) | - &Instruction::ExecuteAddMultifilePredicate(_) | - &Instruction::ExecuteAddGoalExpansionClause(_) | - &Instruction::ExecuteAddTermExpansionClause(_) | - &Instruction::ExecuteAddInSituFilenameModule(_) | - &Instruction::ExecuteClauseToEvacuable(_) | - &Instruction::ExecuteScopedClauseToEvacuable(_) | - &Instruction::ExecuteConcludeLoad(_) | - &Instruction::ExecuteDeclareModule(_) | - &Instruction::ExecuteLoadCompiledLibrary(_) | - &Instruction::ExecuteLoadContextSource(_) | - &Instruction::ExecuteLoadContextFile(_) | - &Instruction::ExecuteLoadContextDirectory(_) | - &Instruction::ExecuteLoadContextModule(_) | - &Instruction::ExecuteLoadContextStream(_) | - &Instruction::ExecutePopLoadContext(_) | - &Instruction::ExecutePopLoadStatePayload(_) | - &Instruction::ExecutePushLoadContext(_) | - &Instruction::ExecutePushLoadStatePayload(_) | - &Instruction::ExecuteUseModule(_) | - &Instruction::ExecuteBuiltInProperty(_) | - &Instruction::ExecuteMetaPredicateProperty(_) | - &Instruction::ExecuteMultifileProperty(_) | - &Instruction::ExecuteDiscontiguousProperty(_) | - &Instruction::ExecuteDynamicProperty(_) | - &Instruction::ExecuteAbolishClause(_) | - &Instruction::ExecuteAsserta(_) | - &Instruction::ExecuteAssertz(_) | - &Instruction::ExecuteRetract(_) | - &Instruction::ExecuteIsConsistentWithTermQueue(_) | - &Instruction::ExecuteFlushTermQueue(_) | - &Instruction::ExecuteRemoveModuleExports(_) | - &Instruction::ExecuteAddNonCountedBacktracking(_) | - &Instruction::ExecutePopCount(_) => { + &Instruction::ExecuteCompileInlineOrExpandedGoal | + &Instruction::ExecuteIsExpandedOrInlined | + &Instruction::ExecuteGetClauseP | + &Instruction::ExecuteInvokeClauseAtP | + &Instruction::ExecuteGetFromAttributedVarList | + &Instruction::ExecutePutToAttributedVarList | + &Instruction::ExecuteDeleteFromAttributedVarList | + &Instruction::ExecuteDeleteAllAttributesFromVar | + &Instruction::ExecuteUnattributedVar | + &Instruction::ExecuteGetDBRefs | + &Instruction::ExecuteFetchGlobalVar | + &Instruction::ExecuteFirstStream | + &Instruction::ExecuteFlushOutput | + &Instruction::ExecuteGetByte | + &Instruction::ExecuteGetChar | + &Instruction::ExecuteGetNChars | + &Instruction::ExecuteGetCode | + &Instruction::ExecuteGetSingleChar | + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff | + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth | + &Instruction::ExecuteGetAttributedVariableList | + &Instruction::ExecuteGetAttrVarQueueDelimiter | + &Instruction::ExecuteGetAttrVarQueueBeyond | + &Instruction::ExecuteGetBValue | + &Instruction::ExecuteGetContinuationChunk | + &Instruction::ExecuteGetNextOpDBRef | + &Instruction::ExecuteLookupDBRef | + &Instruction::ExecuteIsPartialString | + &Instruction::ExecuteHalt | + &Instruction::ExecuteGetLiftedHeapFromOffset | + &Instruction::ExecuteGetLiftedHeapFromOffsetDiff | + &Instruction::ExecuteGetSCCCleaner | + &Instruction::ExecuteHeadIsDynamic | + &Instruction::ExecuteInstallSCCCleaner | + &Instruction::ExecuteInstallInferenceCounter | + &Instruction::ExecuteLiftedHeapLength | + &Instruction::ExecuteLoadLibraryAsStream | + &Instruction::ExecuteModuleExists | + &Instruction::ExecuteNextEP | + &Instruction::ExecuteNoSuchPredicate | + &Instruction::ExecuteNumberToChars | + &Instruction::ExecuteNumberToCodes | + &Instruction::ExecuteOpDeclaration | + &Instruction::ExecuteOpen | + &Instruction::ExecuteSetStreamOptions | + &Instruction::ExecuteNextStream | + &Instruction::ExecutePartialStringTail | + &Instruction::ExecutePeekByte | + &Instruction::ExecutePeekChar | + &Instruction::ExecutePeekCode | + &Instruction::ExecutePointsToContinuationResetMarker | + &Instruction::ExecutePutByte | + &Instruction::ExecutePutChar | + &Instruction::ExecutePutChars | + &Instruction::ExecutePutCode | + &Instruction::ExecuteReadQueryTerm | + &Instruction::ExecuteReadTerm | + &Instruction::ExecuteRedoAttrVarBinding | + &Instruction::ExecuteRemoveCallPolicyCheck | + &Instruction::ExecuteRemoveInferenceCounter | + &Instruction::ExecuteResetContinuationMarker | + &Instruction::ExecuteRestoreCutPolicy | + &Instruction::ExecuteSetCutPoint(_) | + &Instruction::ExecuteSetInput | + &Instruction::ExecuteSetOutput | + &Instruction::ExecuteStoreBacktrackableGlobalVar | + &Instruction::ExecuteStoreGlobalVar | + &Instruction::ExecuteStreamProperty | + &Instruction::ExecuteSetStreamPosition | + &Instruction::ExecuteInferenceLevel | + &Instruction::ExecuteCleanUpBlock | + &Instruction::ExecuteFail | + &Instruction::ExecuteGetBall | + &Instruction::ExecuteGetCurrentBlock | + &Instruction::ExecuteGetCutPoint | + &Instruction::ExecuteGetDoubleQuotes | + &Instruction::ExecuteInstallNewBlock | + &Instruction::ExecuteMaybe | + &Instruction::ExecuteCpuNow | + &Instruction::ExecuteDeterministicLengthRundown | + &Instruction::ExecuteHttpOpen | + &Instruction::ExecuteHttpListen | + &Instruction::ExecuteHttpAccept | + &Instruction::ExecuteHttpAnswer | + &Instruction::ExecuteLoadForeignLib | + &Instruction::ExecuteForeignCall | + &Instruction::ExecuteDefineForeignStruct | + &Instruction::ExecutePredicateDefined | + &Instruction::ExecuteStripModule | + &Instruction::ExecuteCurrentTime | + &Instruction::ExecuteQuotedToken | + &Instruction::ExecuteReadTermFromChars | + &Instruction::ExecuteResetBlock | + &Instruction::ExecuteReturnFromVerifyAttr | + &Instruction::ExecuteSetBall | + &Instruction::ExecutePushBallStack | + &Instruction::ExecutePopBallStack | + &Instruction::ExecutePopFromBallStack | + &Instruction::ExecuteSetCutPointByDefault(_) | + &Instruction::ExecuteSetDoubleQuotes | + &Instruction::ExecuteSetSeed | + &Instruction::ExecuteSkipMaxList | + &Instruction::ExecuteSleep | + &Instruction::ExecuteSocketClientOpen | + &Instruction::ExecuteSocketServerOpen | + &Instruction::ExecuteSocketServerAccept | + &Instruction::ExecuteSocketServerClose | + &Instruction::ExecuteTLSAcceptClient | + &Instruction::ExecuteTLSClientConnect | + &Instruction::ExecuteSucceed | + &Instruction::ExecuteTermAttributedVariables | + &Instruction::ExecuteTermVariables | + &Instruction::ExecuteTermVariablesUnderMaxDepth | + &Instruction::ExecuteTruncateLiftedHeapTo | + &Instruction::ExecuteUnifyWithOccursCheck | + &Instruction::ExecuteUnwindEnvironments | + &Instruction::ExecuteUnwindStack | + &Instruction::ExecuteWAMInstructions | + &Instruction::ExecuteInlinedInstructions | + &Instruction::ExecuteWriteTerm | + &Instruction::ExecuteWriteTermToChars | + &Instruction::ExecuteScryerPrologVersion | + &Instruction::ExecuteCryptoRandomByte | + &Instruction::ExecuteCryptoDataHash | + &Instruction::ExecuteCryptoDataHKDF | + &Instruction::ExecuteCryptoPasswordHash | + &Instruction::ExecuteCryptoDataEncrypt | + &Instruction::ExecuteCryptoDataDecrypt | + &Instruction::ExecuteCryptoCurveScalarMult | + &Instruction::ExecuteEd25519Sign | + &Instruction::ExecuteEd25519Verify | + &Instruction::ExecuteEd25519NewKeyPair | + &Instruction::ExecuteEd25519KeyPairPublicKey | + &Instruction::ExecuteCurve25519ScalarMult | + &Instruction::ExecuteFirstNonOctet | + &Instruction::ExecuteLoadHTML | + &Instruction::ExecuteLoadXML | + &Instruction::ExecuteGetEnv | + &Instruction::ExecuteSetEnv | + &Instruction::ExecuteUnsetEnv | + &Instruction::ExecuteShell | + &Instruction::ExecutePID | + &Instruction::ExecuteCharsBase64 | + &Instruction::ExecuteDevourWhitespace | + &Instruction::ExecuteIsSTOEnabled | + &Instruction::ExecuteSetSTOAsUnify | + &Instruction::ExecuteSetNSTOAsUnify | + &Instruction::ExecuteSetSTOWithErrorAsUnify | + &Instruction::ExecuteHomeDirectory | + &Instruction::ExecuteDebugHook | + &Instruction::ExecuteAddDiscontiguousPredicate | + &Instruction::ExecuteAddDynamicPredicate | + &Instruction::ExecuteAddMultifilePredicate | + &Instruction::ExecuteAddGoalExpansionClause | + &Instruction::ExecuteAddTermExpansionClause | + &Instruction::ExecuteAddInSituFilenameModule | + &Instruction::ExecuteClauseToEvacuable | + &Instruction::ExecuteScopedClauseToEvacuable | + &Instruction::ExecuteConcludeLoad | + &Instruction::ExecuteDeclareModule | + &Instruction::ExecuteLoadCompiledLibrary | + &Instruction::ExecuteLoadContextSource | + &Instruction::ExecuteLoadContextFile | + &Instruction::ExecuteLoadContextDirectory | + &Instruction::ExecuteLoadContextModule | + &Instruction::ExecuteLoadContextStream | + &Instruction::ExecutePopLoadContext | + &Instruction::ExecutePopLoadStatePayload | + &Instruction::ExecutePushLoadContext | + &Instruction::ExecutePushLoadStatePayload | + &Instruction::ExecuteUseModule | + &Instruction::ExecuteBuiltInProperty | + &Instruction::ExecuteMetaPredicateProperty | + &Instruction::ExecuteMultifileProperty | + &Instruction::ExecuteDiscontiguousProperty | + &Instruction::ExecuteDynamicProperty | + &Instruction::ExecuteAbolishClause | + &Instruction::ExecuteAsserta | + &Instruction::ExecuteAssertz | + &Instruction::ExecuteRetract | + &Instruction::ExecuteIsConsistentWithTermQueue | + &Instruction::ExecuteFlushTermQueue | + &Instruction::ExecuteRemoveModuleExports | + &Instruction::ExecuteAddNonCountedBacktracking | + &Instruction::ExecutePopCount => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute"), [atom(name), fixnum(arity)]) } @@ -2044,12 +2053,9 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::Deallocate => { functor!(atom!("deallocate")) } - &Instruction::JmpByCall(_, offset, ..) => { + &Instruction::JmpByCall(offset) => { functor!(atom!("jmp_by_call"), [fixnum(offset)]) } - &Instruction::JmpByExecute(_, offset, ..) => { - functor!(atom!("jmp_by_execute"), [fixnum(offset)]) - } &Instruction::RevJmpBy(offset) => { functor!(atom!("rev_jmp_by"), [fixnum(offset)]) } @@ -2244,6 +2250,7 @@ pub fn generate_instructions_rs() -> TokenStream { let mut clause_type_to_instr_arms = vec![]; let mut clause_type_name_arms = vec![]; let mut is_inbuilt_arms = vec![]; + let mut is_inlined_arms = vec![]; for (name, arity, variant) in instr_data.compare_number_variants { let ident = variant.ident.clone(); @@ -2295,7 +2302,7 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::Inlined( InlinedClauseType::CompareNumber(CompareNumber::#ident(#(#placeholder_ids),*)) - ) => Instruction::#instr_ident(#(#placeholder_ids),*, 0) + ) => Instruction::#instr_ident(#(*#placeholder_ids),*) } ); @@ -2330,7 +2337,7 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::BuiltIn( BuiltInClauseType::CompareTerm(CompareTerm::#ident) - ) => Instruction::#instr_ident(0) + ) => Instruction::#instr_ident } ); @@ -2391,13 +2398,13 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::BuiltIn( BuiltInClauseType::#ident(#(#placeholder_ids),*) - ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + ) => Instruction::#instr_ident(#(*#placeholder_ids),*) } } else { quote! { ClauseType::BuiltIn( BuiltInClauseType::#ident - ) => Instruction::#instr_ident(0) + ) => Instruction::#instr_ident } }); @@ -2462,7 +2469,7 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::Inlined( InlinedClauseType::#ident(#(#placeholder_ids),*) - ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + ) => Instruction::#instr_ident(*#(#placeholder_ids),*) } ); @@ -2471,6 +2478,12 @@ pub fn generate_instructions_rs() -> TokenStream { (atom!(#name), #arity) => true } ); + + is_inlined_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.system_clause_type_variants { @@ -2552,13 +2565,13 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::System( SystemClauseType::#ident(#(#placeholder_ids),*) - ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + ) => Instruction::#instr_ident(#(*#placeholder_ids),*) } } else { quote! { ClauseType::System( SystemClauseType::#ident - ) => Instruction::#instr_ident(0) + ) => Instruction::#instr_ident } }); @@ -2629,13 +2642,13 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::System(SystemClauseType::REPL( REPLCodePtr::#ident(#(#placeholder_ids),*) - )) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + )) => Instruction::#instr_ident(#(*#placeholder_ids),*) } } else { quote! { ClauseType::System(SystemClauseType::REPL( REPLCodePtr::#ident - )) => Instruction::#instr_ident(0) + )) => Instruction::#instr_ident } }); @@ -2655,7 +2668,7 @@ pub fn generate_instructions_rs() -> TokenStream { }); clause_type_to_instr_arms.push(quote! { - ClauseType::Named(arity, name, idx) => Instruction::CallNamed(arity, name, idx, 0) + ClauseType::Named(arity, name, idx) => Instruction::CallNamed(*arity, *name, *idx) }); clause_type_name_arms.push(quote! { @@ -2706,11 +2719,11 @@ pub fn generate_instructions_rs() -> TokenStream { clause_type_to_instr_arms.push(if !variant_fields.is_empty() { quote! { ClauseType::#ident(#(#placeholder_ids),*) => - Instruction::#ident(#(#placeholder_ids),*,0) + Instruction::#ident(#(*#placeholder_ids),*) } } else { quote! { - ClauseType::#ident => Instruction::#ident(0) + ClauseType::#ident => Instruction::#ident } }); @@ -2767,11 +2780,6 @@ pub fn generate_instructions_rs() -> TokenStream { Instruction::#execute_ident(#(#placeholder_ids),*) } }) - } else if variant_string == "JmpByCall" { - Some(quote! { - Instruction::JmpByCall(#(#placeholder_ids),*) => - Instruction::JmpByExecute(#(#placeholder_ids),*) - }) } else { None } @@ -2835,16 +2843,23 @@ pub fn generate_instructions_rs() -> TokenStream { let enum_arity = if let Fields::Unnamed(fields) = &variant.fields { fields.unnamed.len() } else { - unreachable!() + 0 }; let placeholder_ids: Vec<_> = (0 .. enum_arity) .map(|n| format_ident!("f_{}", n)) .collect(); - Some(quote! { - Instruction::#variant_ident(#(#placeholder_ids),*) => - Instruction::#def_variant_ident(#(#placeholder_ids),*) + Some(if enum_arity == 0 { + quote! { + Instruction::#variant_ident => + Instruction::#def_variant_ident + } + } else { + quote! { + Instruction::#variant_ident(#(#placeholder_ids),*) => + Instruction::#def_variant_ident(#(#placeholder_ids),*) + } }) } else { None @@ -2852,7 +2867,7 @@ pub fn generate_instructions_rs() -> TokenStream { }) .collect(); - let perm_vars_mut_arms: Vec<_> = instr_data.instr_variants + let control_flow_arms: Vec<_> = instr_data.instr_variants .iter() .cloned() .filter_map(|(_, _, _, variant)| { @@ -2860,46 +2875,26 @@ pub fn generate_instructions_rs() -> TokenStream { return None; } - let variant_ident = variant.ident.clone(); let enum_arity = if let Fields::Unnamed(fields) = &variant.fields { fields.unnamed.len() } else { 0 }; - let placeholder_ids: Vec<_> = (1 .. enum_arity) - .map(|_| format_ident!("_")) - .collect(); + let variant_ident = variant.ident.clone(); - Some(if enum_arity == 1 { + Some(if enum_arity == 0 { quote! { - Instruction::#variant_ident(ref mut perm_vars) => Some(perm_vars) + Instruction::#variant_ident => true } } else { quote! { - Instruction::#variant_ident(#(#placeholder_ids),*, ref mut perm_vars) => - Some(perm_vars) + Instruction::#variant_ident(..) => true } }) }) .collect(); - let control_flow_arms: Vec<_> = instr_data.instr_variants - .iter() - .cloned() - .filter_map(|(_, _, _, variant)| { - if !is_callable(&variant.ident) && !is_jmp(&variant.ident) { - return None; - } - - let variant_ident = variant.ident.clone(); - - Some(quote! { - Instruction::#variant_ident(..) => true - }) - }) - .collect(); - let instr_macro_arms: Vec<_> = instr_data.instr_variants .iter() .rev() // produce default, execute & default & execute cases first. @@ -2913,27 +2908,59 @@ pub fn generate_instructions_rs() -> TokenStream { }; Some(if variant_string.starts_with("Execute") { - quote! { - (#name, execute, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name, execute) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, execute, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else if variant_string.starts_with("Call") { - quote! { - (#name, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else if variant_string.starts_with("DefaultExecute") { - quote! { - (#name, execute, default, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name, execute, default) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, execute, default, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else if variant_string.starts_with("DefaultCall") { - quote! { - (#name, default, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name, default) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, default, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else { @@ -3061,7 +3088,7 @@ pub fn generate_instructions_rs() -> TokenStream { } } - pub fn to_instr(self) -> Instruction { + pub fn to_instr(&self) -> Instruction { match self { #( #clause_type_to_instr_arms, @@ -3085,6 +3112,15 @@ pub fn generate_instructions_rs() -> TokenStream { )* } } + + pub fn is_inlined(name: Atom, arity: usize) -> bool { + match (name, arity) { + #( + #is_inlined_arms, + )* + _ => false, + } + } } #[derive(Clone, Debug)] @@ -3130,15 +3166,6 @@ pub fn generate_instructions_rs() -> TokenStream { } } - pub fn perm_vars_mut(&mut self) -> Option<&mut usize> { - match self { - #( - #perm_vars_mut_arms, - )* - _ => None, - } - } - pub fn is_ctrl_instr(&self) -> bool { match self { &Instruction::Allocate(_) | @@ -3201,41 +3228,6 @@ fn is_jmp(id: &Ident) -> bool { } fn create_instr_variant(id: Ident, mut variant: Variant) -> Variant { - use proc_macro2::Span; - use syn::punctuated::Punctuated; - use syn::token::Paren; - - // add the perm_vars usize field to the variant. - - if is_callable(&id) || is_jmp(&id) { - let field = Field { - attrs: vec![], - vis: Visibility::Inherited, - ident: None, - colon_token: None, - ty: parse_quote! { usize }, - }; - - match &mut variant.fields { - Fields::Unnamed(ref mut fields) => { - fields.unnamed.push(field); - } - Fields::Unit => { - variant.fields = Fields::Unnamed(FieldsUnnamed { - paren_token: Paren(Span::call_site()), - unnamed: { - let mut fields_seq = Punctuated::new(); - fields_seq.push(field); - fields_seq - } - }); - } - _ => { - unreachable!(); - } - } - } - variant.ident = id; variant.attrs.clear(); diff --git a/src/allocator.rs b/src/allocator.rs index 50e9c7c3..f689a802 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,10 +1,7 @@ use crate::parser::ast::*; -use crate::temp_v; -use crate::fixtures::*; use crate::forms::*; use crate::instructions::*; -use crate::machine::machine_indices::*; use crate::targets::*; use std::cell::Cell; @@ -16,7 +13,7 @@ pub(crate) trait Allocator { &mut self, lvl: Level, context: GenContext, - code: &mut Code, + code: &mut CodeDeque, ); fn mark_non_var<'a, Target: CompilationTarget<'a>>( @@ -24,40 +21,44 @@ pub(crate) trait Allocator { lvl: Level, context: GenContext, cell: &'a Cell, - code: &mut Code, + code: &mut CodeDeque, ); fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( &mut self, - var_name: Var, + var_num: usize, lvl: Level, cell: &'a Cell, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, r: RegType, is_new_var: bool, ); + fn mark_cut_var(&mut self, var_num: usize, chunk_num: usize) -> RegType; + fn mark_var<'a, Target: CompilationTarget<'a>>( &mut self, - var_name: Var, + var_num: usize, lvl: Level, cell: &'a Cell, context: GenContext, - code: &mut Code, + code: &mut CodeDeque, ); fn reset(&mut self); - fn reset_contents(&mut self) {} fn reset_arg(&mut self, arg_num: usize); fn reset_at_head(&mut self, args: &Vec); + fn reset_contents(&mut self); fn advance_arg(&mut self); + /* fn bindings(&self) -> &AllocVarDict; fn bindings_mut(&mut self) -> &mut AllocVarDict; - fn take_bindings(self) -> AllocVarDict; + */ + fn max_reg_allocated(&self) -> usize; // TODO: wha.. why?? grrr. it drains the VarStatus data from vs (which it owns!) @@ -87,21 +88,4 @@ pub(crate) trait Allocator { perm_vs } */ - - fn get(&self, var: Var) -> RegType { - self.bindings() - .get(&var) - .map_or(temp_v!(0), |v| v.as_reg_type()) - } - - fn is_unbound(&self, var: Var) -> bool { - self.get(var).reg_num() == 0 - } - - fn record_register(&mut self, var: Var, r: RegType) { - match self.bindings_mut().get_mut(&var).unwrap() { - &mut VarAlloc::Temp(_, ref mut s, _) => *s = r.reg_num(), - &mut VarAlloc::Perm(ref mut s) => *s = r.reg_num(), - } - } } diff --git a/src/arithmetic.rs b/src/arithmetic.rs index 94974a51..0fbd91d5 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -52,7 +52,7 @@ pub(crate) struct ArithInstructionIterator<'a> { state_stack: Vec>, } -pub(crate) type ArithCont = (Code, Option); +pub(crate) type ArithCont = (CodeDeque, Option); impl<'a> ArithInstructionIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { @@ -73,7 +73,7 @@ impl<'a> ArithInstructionIterator<'a> { 2, )) } - Term::Var(cell, var) => TermIterState::Var(Level::Shallow, cell, VarPtr::from(var)), + Term::Var(cell, var_ptr) => TermIterState::Var(Level::Shallow, cell, var_ptr.clone()), }; Ok(ArithInstructionIterator { @@ -86,7 +86,7 @@ impl<'a> ArithInstructionIterator<'a> { pub(crate) enum ArithTermRef<'a> { Literal(&'a Literal), Op(Atom, usize), // name, arity. - Var(Level, &'a Cell, Var), + Var(Level, &'a Cell, VarPtr), } impl<'a> Iterator for ArithInstructionIterator<'a> { @@ -114,8 +114,8 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { } } TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))), - TermIterState::Var(lvl, cell, var_ref) => { - return Some(Ok(ArithTermRef::Var(lvl, cell, Var::from(var_ref)))); + TermIterState::Var(lvl, cell, var_ptr) => { + return Some(Ok(ArithTermRef::Var(lvl, cell, var_ptr))); } _ => { return Some(Err(ArithmeticError::NonEvaluableFunctor( @@ -307,43 +307,48 @@ impl<'a> ArithmeticEvaluator<'a> { term_loc: GenContext, arg: usize, ) -> Result { - let mut code = vec![]; + let mut code = CodeDeque::new(); let mut iter = src.iter()?; while let Some(term_ref) = iter.next() { match term_ref? { ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?, ArithTermRef::Var(lvl, cell, name) => { + let var_num = name.to_var_num().unwrap(); + let r = if lvl == Level::Shallow { self.marker.mark_non_callable( - name, + var_num, arg, term_loc, cell, &mut code, ) } else if term_loc.is_last() || cell.get().norm().reg_num() == 0 { - if let Some(r) = self.marker.get_binding(&name) { - r - } else { + let r = self.marker.get_binding(var_num); + + if r.reg_num() == 0 { self.marker.mark_var::( - name.clone(), + var_num, lvl, cell, term_loc, &mut code, ); - - self.marker.get_binding(&name).unwrap() + } else { + self.marker.increment_running_count(var_num); } + + r } else { + self.marker.increment_running_count(var_num); cell.get().norm() }; self.interm.push(ArithmeticTerm::Reg(r)); } ArithTermRef::Op(name, arity) => { - code.push(self.instr_from_clause(name, arity)?); + code.push_back(self.instr_from_clause(name, arity)?); } } } diff --git a/src/codegen.rs b/src/codegen.rs index e7c6e2ac..794ec65b 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,10 +1,9 @@ use crate::atom_table::*; use crate::parser::ast::*; -use crate::{perm_v, temp_v}; +use crate::temp_v; use crate::allocator::*; use crate::arithmetic::*; use crate::debray_allocator::*; -use crate::fixtures::*; use crate::forms::*; use crate::indexing::*; use crate::instructions::*; @@ -13,39 +12,139 @@ use crate::targets::*; use crate::types::*; use crate::instr; +use crate::machine::disjuncts::*; use crate::machine::machine_errors::*; -use indexmap::{IndexMap, IndexSet}; +use fxhash::FxBuildHasher; +use indexmap::IndexSet; use std::cell::Cell; use std::collections::VecDeque; #[derive(Debug)] -pub(crate) struct ConjunctInfo { - pub(crate) perm_vs: VariableFixtures, - pub(crate) num_of_chunks: usize, - pub(crate) has_deep_cut: bool, +pub struct BranchCodeStack { + pub stack: Vec>, } -impl ConjunctInfo { - fn new(perm_vs: VariableFixtures, num_of_chunks: usize, has_deep_cut: bool) -> Self { - ConjunctInfo { - perm_vs, - num_of_chunks, - has_deep_cut, +pub type SubsumedBranchHits = IndexSet; + +impl BranchCodeStack { + fn new() -> Self { + Self { stack: vec![] } + } + + fn add_new_branch_stack(&mut self) { + self.stack.push(vec![]); + } + + fn add_new_branch(&mut self) { + if self.stack.is_empty() { + self.add_new_branch_stack(); + } + + if let Some(branches) = self.stack.last_mut() { + branches.push(CodeDeque::new()); } } - fn allocates(&self) -> bool { - self.perm_vs.size() > 0 || self.num_of_chunks > 1 || self.has_deep_cut + fn code<'a>(&'a mut self, default_code: &'a mut CodeDeque) -> &'a mut CodeDeque { + self.stack.last_mut() + .and_then(|stack| stack.last_mut()) + .unwrap_or(default_code) + } + + fn push_missing_vars(&mut self, depth: usize, marker: &mut DebrayAllocator) -> SubsumedBranchHits { + let mut subsumed_hits = SubsumedBranchHits::with_hasher(FxBuildHasher::default()); + + for idx in (self.stack.len() - depth .. self.stack.len()).rev() { + let branch = &mut marker.branch_stack[idx]; + let branch_hits = &branch.hits; + + for (&var_num, branches) in branch_hits.iter() { + let record = &marker.var_data.records[var_num]; + + if record.running_count < record.num_occurrences { + if !branches.all() { + branch.deep_safety.insert(var_num); + branch.shallow_safety.insert(var_num); + + let r = record.allocation.as_reg_type(); + + // iterate over unset bits. + for branch_idx in branches.iter_zeros() { + if branch_idx + 1 == branches.len() && idx + 1 != self.stack.len() { + break; + } + + self.stack[idx][branch_idx].push_back(instr!("put_variable", r, 0)); + } + } + + subsumed_hits.insert(var_num); + } + } + } + + subsumed_hits } - fn perm_vars(&self) -> usize { - self.perm_vs.size() + self.perm_var_offset() + fn push_jump_instrs(&mut self, depth: usize) { + // add 2 in each arm length to compensate for each jump + // instruction and each branch instruction not yet added. + let mut jump_span: usize = self.stack[self.stack.len() - depth ..] + .iter() + .map(|branch| branch.iter().map(|code| code.len() + 2).sum::()) + .sum(); + + jump_span -= depth; + + for idx in self.stack.len() - depth .. self.stack.len() { + let inner_len = self.stack[idx].len(); + + for (inner_idx, code) in self.stack[idx].iter_mut().enumerate() { + if inner_idx + 1 == inner_len { + jump_span -= code.len() + 1; // = jump_span.saturating_sub(code.len() + 1); + } else { + jump_span -= code.len() + 1; + code.push_back(instr!("jmp_by_call", jump_span as usize)); + + // saturate at 0 if underflow happens, which only + // happens when jump_span is no longer needed + // anyway. still, we don't want to panic at + // underflow. + jump_span -= 1; + } + } + } + + // eliminate terminating jump instruction in last arm of last + // branch. + // self.stack.last_mut() + // .and_then(|branch| branch.last_mut()) + // .map(|code| code.pop_back()); } - fn perm_var_offset(&self) -> usize { - self.has_deep_cut as usize + fn pop_branch(&mut self, depth: usize, settings: CodeGenSettings) -> CodeDeque { + let mut combined_code = CodeDeque::new(); + + for mut branch_arm in self.stack.drain(self.stack.len() - depth ..).rev() { + let num_branch_arms = branch_arm.len(); + branch_arm.last_mut().map(|code| code.extend(combined_code.drain(..))); + + for (idx, code) in branch_arm.into_iter().enumerate() { + combined_code.push_back(if idx == 0 { + Instruction::TryMeElse(code.len() + 1) + } else if idx + 1 < num_branch_arms { + settings.retry_me_else(code.len() + 1) + } else { + settings.trust_me() + }); + + combined_code.extend(code.into_iter()); + } + } + + combined_code } } @@ -168,53 +267,49 @@ impl CodeGenSettings { pub(crate) struct CodeGenerator<'a> { pub(crate) atom_tbl: &'a mut AtomTable, marker: DebrayAllocator, - pub(crate) var_count: IndexMap, settings: CodeGenSettings, pub(crate) skeleton: PredicateSkeleton, - pub(crate) jmp_by_locs: Vec, - global_jmp_by_locs_offset: usize, } impl DebrayAllocator { fn mark_var_in_non_callable( &mut self, - name: Var, + var_num: usize, term_loc: GenContext, vr: &Cell, - code: &mut Code, + code: &mut CodeDeque, ) -> RegType { - self.mark_var::(name, Level::Shallow, vr, term_loc, code); - vr.get().norm() - } + self.mark_var::( + var_num, + Level::Shallow, + vr, + term_loc, + code, + ); - #[inline(always)] - pub(crate) fn get_binding(&self, name: &Var) -> Option { - match self.bindings().get(name) { - Some(&VarAlloc::Temp(_, t, _)) if t != 0 => Some(RegType::Temp(t)), - Some(&VarAlloc::Perm(p)) if p != 0 => Some(RegType::Perm(p)), - _ => None, - } + vr.get().norm() } pub(crate) fn mark_non_callable( &mut self, - name: Var, + var_num: usize, arg: usize, term_loc: GenContext, vr: &Cell, - code: &mut Code, + code: &mut CodeDeque, ) -> RegType { - match self.get_binding(&name) { - Some(RegType::Temp(t)) => RegType::Temp(t), - Some(RegType::Perm(p)) => { + match self.get_binding(var_num) { + RegType::Temp(t) if t != 0 => RegType::Temp(t), + RegType::Perm(p) if p != 0 => { if let GenContext::Last(_) = term_loc { - self.mark_var_in_non_callable(name.clone(), term_loc, vr, code); + self.mark_var_in_non_callable(var_num, term_loc, vr, code); temp_v!(arg) } else { + self.increment_running_count(var_num); RegType::Perm(p) } } - None => self.mark_var_in_non_callable(name, term_loc, vr, code), + _ => self.mark_var_in_non_callable(var_num, term_loc, vr, code), } } } @@ -280,50 +375,34 @@ impl<'b> CodeGenerator<'b> { CodeGenerator { atom_tbl, marker: DebrayAllocator::new(), - var_count: IndexMap::new(), settings, skeleton: PredicateSkeleton::new(), - jmp_by_locs: vec![], - global_jmp_by_locs_offset: 0, - } - } - - fn update_var_count<'a, Iter: Iterator>>(&mut self, iter: Iter) { - for term in iter { - if let TermRef::Var(_, _, var) = term { - let entry = self.var_count.entry(var).or_insert(0); - *entry += 1; - } } } - fn get_var_count(&self, var: &Var) -> usize { - *self.var_count.get(var).unwrap() - } - - fn add_or_increment_void_instr<'a, Target>(target: &mut Code) + fn add_or_increment_void_instr<'a, Target>(target: &mut CodeDeque) where Target: crate::targets::CompilationTarget<'a>, { - if let Some(ref mut instr) = target.last_mut() { + if let Some(ref mut instr) = target.back_mut() { if Target::is_void_instr(&*instr) { Target::incr_void_instr(instr); return; } } - target.push(Target::to_void(1)); + target.push_back(Target::to_void(1)); } fn deep_var_instr<'a, Target: crate::targets::CompilationTarget<'a>>( &mut self, cell: &'a Cell, - var: &Var, + var_num: usize, term_loc: GenContext, - target: &mut Code, + target: &mut CodeDeque, ) { - if self.get_var_count(var.as_ref()) > 1 { - self.marker.mark_var::(var.clone(), Level::Deep, cell, term_loc, target); + if self.marker.var_data.records[var_num].num_occurrences > 1 { + self.marker.mark_var::(var_num, Level::Deep, cell, term_loc, target); } else { Self::add_or_increment_void_instr::(target); } @@ -333,7 +412,7 @@ impl<'b> CodeGenerator<'b> { &mut self, subterm: &'a Term, term_loc: GenContext, - target: &mut Code, + target: &mut CodeDeque, ) { match subterm { &Term::AnonVar => { @@ -344,13 +423,13 @@ impl<'b> CodeGenerator<'b> { Term::PartialString(ref cell, ..) | Term::CompleteString(ref cell, ..) => { self.marker.mark_non_var::(Level::Deep, term_loc, cell, target); - target.push(Target::clause_arg_to_instr(cell.get())); + target.push_back(Target::clause_arg_to_instr(cell.get())); } &Term::Literal(_, ref constant) => { - target.push(Target::constant_subterm(constant.clone())); + target.push_back(Target::constant_subterm(constant.clone())); } - &Term::Var(ref cell, ref var) => { - self.deep_var_instr::(cell, var, term_loc, target); + &Term::Var(ref cell, ref var_ptr) => { + self.deep_var_instr::(cell, var_ptr.to_var_num().unwrap(), term_loc, target); } }; } @@ -359,13 +438,13 @@ impl<'b> CodeGenerator<'b> { &mut self, iter: Iter, term_loc: GenContext, - ) -> Code + ) -> CodeDeque where Target: crate::targets::CompilationTarget<'a>, Iter: Iterator>, CodeGenerator<'b>: AddToFreeList<'a, Target> { - let mut target: Code = Vec::new(); + let mut target = CodeDeque::new(); for term in iter { match term { @@ -378,11 +457,11 @@ impl<'b> CodeGenerator<'b> { } TermRef::Clause(lvl, cell, name, terms) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_structure(name, terms.len(), cell.get())); + target.push_back(Target::to_structure(name, terms.len(), cell.get())); as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get()); - if let Some(instr) = target.last_mut() { + if let Some(instr) = target.back_mut() { if let Some(term) = terms.last() { trim_structure_by_last_arg(instr, term); } @@ -398,7 +477,7 @@ impl<'b> CodeGenerator<'b> { } TermRef::Cons(lvl, cell, head, tail) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_list(lvl, cell.get())); + target.push_back(Target::to_list(lvl, cell.get())); as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get()); @@ -410,44 +489,31 @@ impl<'b> CodeGenerator<'b> { } TermRef::Literal(lvl @ Level::Shallow, cell, Literal::String(ref string)) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_pstr(lvl, *string, cell.get(), false)); + target.push_back(Target::to_pstr(lvl, *string, cell.get(), false)); } TermRef::Literal(lvl @ Level::Shallow, cell, constant) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_constant(lvl, *constant, cell.get())); + target.push_back(Target::to_constant(lvl, *constant, cell.get())); } TermRef::PartialString(lvl, cell, string, tail) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); let atom = self.atom_tbl.build_with(&string); - target.push(Target::to_pstr(lvl, atom, cell.get(), true)); + target.push_back(Target::to_pstr(lvl, atom, cell.get(), true)); self.subterm_to_instr::(tail, term_loc, &mut target); } TermRef::CompleteString(lvl, cell, atom) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_pstr(lvl, atom, cell.get(), false)); - } - TermRef::Var(lvl @ Level::Shallow, cell, var) if var.as_str() == Some("!") => { - if self.marker.is_unbound(var.clone()) { - if term_loc != GenContext::Head { - self.marker.mark_reserved_var::( - var.clone(), - lvl, - cell, - term_loc, - &mut target, - perm_v!(1), - false, - ); - - continue; - } - } - - self.marker.mark_var::(var.clone(), lvl, cell, term_loc, &mut target); + target.push_back(Target::to_pstr(lvl, atom, cell.get(), false)); } TermRef::Var(lvl @ Level::Shallow, cell, var) => { - self.marker.mark_var::(var.clone(), lvl, cell, term_loc, &mut target); + self.marker.mark_var::( + var.to_var_num().unwrap(), + lvl, + cell, + term_loc, + &mut target, + ); } _ => {} }; @@ -456,82 +522,27 @@ impl<'b> CodeGenerator<'b> { target } - /* - fn collect_var_data<'a>(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> { - let mut vs = VariableFixtures::new(); - - while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() { - for (i, chunked_term) in chunked_terms.iter().enumerate() { - let term_loc = match chunked_term { - &ChunkedTerm::HeadClause(..) => GenContext::Head, - &ChunkedTerm::BodyTerm(_) => { - if i < chunked_terms.len() - 1 { - GenContext::Mid(chunk_num) - } else { - GenContext::Last(chunk_num) - } - } - }; - - self.update_var_count(chunked_term.post_order_iter()); - vs.mark_vars_in_chunk(chunked_term.post_order_iter(), lt_arity, term_loc); - } - } - - let num_of_chunks = iter.chunk_num; - let has_deep_cut = iter.encountered_deep_cut(); - - vs.populate_restricting_sets(); - vs.set_perm_vals(has_deep_cut); - - let vs = self.marker.drain_var_data(vs, num_of_chunks); - ConjunctInfo::new(vs, num_of_chunks, has_deep_cut) - } - */ - - fn add_conditional_call(&mut self, code: &mut Code, qt: &QueryTerm, pvs: usize) { - match qt { - &QueryTerm::Jump(ref vars) => { - self.jmp_by_locs.push(code.len()); - code.push(instr!("jmp_by_call", vars.len(), 0, pvs)); - } - &QueryTerm::Clause(_, ref ct, _, CallPolicy::Default) => { - code.push(call_clause_by_default!(ct.clone(), pvs)); - } - &QueryTerm::Clause(_, ref ct, _, CallPolicy::Counted) => { - code.push(call_clause!(ct.clone(), pvs)); - } - _ => {} + fn add_call(&mut self, code: &mut CodeDeque, call_instr: Instruction, call_policy: CallPolicy) { + if self.marker.in_tail_position && self.marker.var_data.allocates { + code.push_back(instr!("deallocate")); } - } - - fn lco(code: &mut Code) -> usize { - let mut dealloc_index = code.len() - 1; - let last_instr = code.pop(); - match last_instr { - Some(instr @ Instruction::Proceed) => { - code.push(instr); - } - Some(instr @ Instruction::Cut(_)) => { - dealloc_index += 1; - code.push(instr); - } - Some(mut instr) if instr.is_ctrl_instr() => { - code.push(if instr.perm_vars_mut().is_some() { - instr.to_execute() + match call_policy { + CallPolicy::Default => { + if self.marker.in_tail_position { + code.push_back(call_instr.to_execute().to_default()); } else { - dealloc_index += 1; - instr - }); + code.push_back(call_instr.to_default()) + } } - Some(instr) => { - code.push(instr); + CallPolicy::Counted => { + if self.marker.in_tail_position { + code.push_back(call_instr.to_execute()); + } else { + code.push_back(call_instr) + } } - None => {} } - - dealloc_index } fn compile_inlined<'a>( @@ -539,9 +550,9 @@ impl<'b> CodeGenerator<'b> { ct: &InlinedClauseType, terms: &'a Vec, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, ) -> Result<(), CompilationError> { - match ct { + let call_instr = match ct { &InlinedClauseType::CompareNumber(mut cmp) => { self.marker.reset_arg(2); @@ -559,29 +570,29 @@ impl<'b> CodeGenerator<'b> { let at_1 = at_1.unwrap_or(interm!(1)); let at_2 = at_2.unwrap_or(interm!(2)); - code.push(compare_number_instr!(cmp, at_1, at_2)); + compare_number_instr!(cmp, at_1, at_2) } &InlinedClauseType::IsAtom(..) => match &terms[0] { &Term::Literal(_, Literal::Char(_)) | &Term::Literal(_, Literal::Atom(atom!("[]"))) | &Term::Literal(_, Literal::Atom(..)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("atom", r, 0)); + instr!("atom", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsAtomic(..) => match &terms[0] { @@ -590,26 +601,26 @@ impl<'b> CodeGenerator<'b> { &Term::Cons(..) | &Term::PartialString(..) | &Term::CompleteString(..) => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::Literal(_, Literal::String(_)) => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::Literal(..) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("atomic", r, 0)); + instr!("atomic", r) } }, &InlinedClauseType::IsCompound(..) => match &terms[0] { @@ -618,57 +629,57 @@ impl<'b> CodeGenerator<'b> { &Term::PartialString(..) | &Term::CompleteString(..) | &Term::Literal(_, Literal::String(..)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("compound", r, 0)); + instr!("compound", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsRational(..) => match &terms[0] { &Term::Literal(_, Literal::Rational(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); - let r = self.marker.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(instr!("rational", r, 0)); + let r = self.marker.mark_non_callable(name.to_var_num().unwrap(), 1, term_loc, vr, code); + instr!("rational", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsFloat(..) => match &terms[0] { &Term::Literal(_, Literal::Float(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("float", r, 0)); + instr!("float", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsNumber(..) => match &terms[0] { @@ -676,66 +687,66 @@ impl<'b> CodeGenerator<'b> { &Term::Literal(_, Literal::Rational(_)) | &Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("number", r, 0)); + instr!("number", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsNonVar(..) => match &terms[0] { &Term::AnonVar => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("nonvar", r, 0)); + instr!("nonvar", r) } _ => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } }, &InlinedClauseType::IsInteger(..) => match &terms[0] { &Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("integer", r, 0)); + instr!("integer", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsVar(..) => match &terms[0] { @@ -744,26 +755,29 @@ impl<'b> CodeGenerator<'b> { &Term::Cons(..) | &Term::PartialString(..) | &Term::CompleteString(..) => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::AnonVar => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("var", r, 0)); + instr!("var", r) } }, - } + }; + + // inlined predicates are never counted, so this overrides nothing. + self.add_call(code, call_instr, CallPolicy::Counted); Ok(()) } @@ -782,7 +796,7 @@ impl<'b> CodeGenerator<'b> { fn compile_is_call( &mut self, terms: &Vec, - code: &mut Code, + code: &mut CodeDeque, term_loc: GenContext, call_policy: CallPolicy, ) -> Result<(), CompilationError> { @@ -798,8 +812,11 @@ impl<'b> CodeGenerator<'b> { let at = match &terms[0] { &Term::Var(ref vr, ref name) => { + let var_num = name.to_var_num().unwrap(); + self.marker.mark_temp_to_safe_perm(var_num); + self.marker.mark_var::( - name.clone(), + var_num, Level::Shallow, vr, term_loc, @@ -813,208 +830,189 @@ impl<'b> CodeGenerator<'b> { c @ Literal::Rational(_) | c @ Literal::Fixnum(_)) => { let v = HeapCellValue::from(c); - code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1))); + code.push_back(instr!("put_constant", Level::Shallow, v, temp_v!(1))); self.marker.advance_arg(); compile_expr!(self, &terms[1], term_loc, code) } _ => { - code.push(instr!("$fail", 0)); + code.push_back(instr!("$fail")); return Ok(()); } }; let at = at.unwrap_or(interm!(1)); + self.add_call(code, instr!("is", temp_v!(1), at), call_policy); - Ok(if let CallPolicy::Default = call_policy { - code.push(instr!("is", default, temp_v!(1), at, 0)); - } else { - code.push(instr!("is", temp_v!(1), at, 0)); - }) - } - - #[inline] - fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &Cell) { - let r = self.marker.get(Var::from("!")); - cell.set(VarReg::Norm(r)); - code.push(instr!("$set_cp", cell.get().norm(), 0)); + Ok(()) } fn compile_seq<'a>( &mut self, - iter: ChunkedIterator<'a>, - conjunct_info: &ConjunctInfo, - code: &mut Code, + clauses: &ChunkedTermVec, + code: &mut CodeDeque, ) -> Result<(), CompilationError> { - for (chunk_num, _, terms) in iter.rule_body_iter() { - for (i, term) in terms.iter().enumerate() { - let term_loc = if i + 1 < terms.len() { - GenContext::Mid(chunk_num) - } else { - GenContext::Last(chunk_num) - }; - - match *term { - &QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell), - &QueryTerm::BlockedCut => code.push(if chunk_num == 0 { - Instruction::NeckCut - } else { - Instruction::Cut(perm_v!(1)) - }), - &QueryTerm::Clause( - _, - ClauseType::BuiltIn(BuiltInClauseType::Is(..)), - ref terms, - call_policy, - ) => self.compile_is_call(terms, code, term_loc, call_policy)?, - &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { - self.compile_inlined(ct, terms, term_loc, code)? - } - _ => { - let num_perm_vars = if chunk_num == 0 { - conjunct_info.perm_vars() + let mut chunk_num = 0; + let mut branch_code_stack = BranchCodeStack::new(); + let mut clause_iter = ClauseIterator::new(clauses); + + while let Some(clause_item) = clause_iter.next() { + match clause_item { + ClauseItem::Chunk(chunk) => { + for (idx, term) in chunk.iter().enumerate() { + let term_loc = if idx + 1 < chunk.len() { + GenContext::Mid(chunk_num) } else { - conjunct_info.perm_vs.vars_above_threshold(i + 1) + self.marker.in_tail_position = clause_iter.in_tail_position(); + GenContext::Last(chunk_num) }; - self.compile_query_line(term, term_loc, code, num_perm_vars); + match term { + &QueryTerm::GetLevel(var_num) => { + let code = branch_code_stack.code(code); + let r = self.marker.mark_cut_var(var_num, chunk_num); + code.push_back(instr!("get_level", r)); + } + &QueryTerm::GetCutPoint { var_num, prev_b } => { + let code = branch_code_stack.code(code); + let r = self.marker.mark_cut_var(var_num, chunk_num); + + code.push_back(if prev_b { + instr!("get_prev_level", r) + } else { + instr!("get_cut_point", r) + }); + } + &QueryTerm::GlobalCut(var_num) => { + let code = branch_code_stack.code(code); + + if chunk_num == 0 { + code.push_back(instr!("neck_cut")); + } else { + let r = self.marker.get_binding(var_num); + // let r = self.marker.mark_cut_var(var_num, chunk_num); + code.push_back(instr!("cut", r)); + } + + if self.marker.in_tail_position { + if self.marker.var_data.allocates { + code.push_back(instr!("deallocate")); + } + + code.push_back(instr!("proceed")); + } + } + &QueryTerm::LocalCut(var_num) => { + let code = branch_code_stack.code(code); + let r = self.marker.get_binding(var_num); + // let r = self.marker.mark_cut_var(var_num, chunk_num); + code.push_back(instr!("cut", r)); + + if self.marker.in_tail_position { + if self.marker.var_data.allocates { + code.push_back(instr!("deallocate")); + } + + code.push_back(instr!("proceed")); + } + } + &QueryTerm::Clause( + _, + ClauseType::BuiltIn(BuiltInClauseType::Is(..)), + ref terms, + call_policy, + ) => self.compile_is_call(terms, branch_code_stack.code(code), term_loc, call_policy)?, + &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { + self.compile_inlined(ct, terms, term_loc, branch_code_stack.code(code))? + } + &QueryTerm::Fail => { + branch_code_stack.code(code).push_back(instr!("$fail")); + } + term @ &QueryTerm::Clause(..) => { + self.compile_query_line(term, term_loc, branch_code_stack.code(code)); - if self.marker.max_reg_allocated() > MAX_ARITY { - return Err(CompilationError::ExceededMaxArity); + if self.marker.max_reg_allocated() > MAX_ARITY { + return Err(CompilationError::ExceededMaxArity); + } + } } } - } - } - - self.marker.reset_contents(); - } - Ok(()) - } + chunk_num += 1; + self.marker.in_tail_position = false; + self.marker.reset_contents(); + } + ClauseItem::FirstBranch(num_branches) => { + branch_code_stack.add_new_branch_stack(); + branch_code_stack.add_new_branch(); - fn compile_seq_prelude(&mut self, var_data: &VarData, body: &mut Code) { - /* - if conjunct_info.allocates() { - let perm_vars = conjunct_info.perm_vars(); + self.marker.add_branch_stack(num_branches); + self.marker.add_branch(); + } + ClauseItem::NextBranch => { + branch_code_stack.add_new_branch(); + self.marker.add_branch(); + self.marker.incr_current_branch(); + } + ClauseItem::BranchEnd(depth) => { + if !clause_iter.in_tail_position() { + let subsumed_hits = branch_code_stack.push_missing_vars(depth, &mut self.marker); + self.marker.pop_branch(depth, subsumed_hits); + branch_code_stack.push_jump_instrs(depth); + } else { + self.marker.drain_branches(depth); + } - body.push(Instruction::Allocate(perm_vars)); + let settings = CodeGenSettings { + non_counted_bt: self.settings.non_counted_bt, + is_extensible: false, + global_clock_tick: None, + }; - if conjunct_info.has_deep_cut { - body.push(Instruction::GetLevel(perm_v!(1))); + let branch_code = branch_code_stack.pop_branch(depth, settings); + branch_code_stack.code(code).extend(branch_code); + } } } - */ - } - fn compile_cleanup( - &mut self, - code: &mut Code, - conjunct_info: &ConjunctInfo, - toc: &QueryTerm, - ) { - // add a proceed to bookend any trailing cuts. - match toc { - &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => { - code.push(instr!("proceed")); - } - _ => {} + if self.marker.var_data.allocates { + code.push_front(instr!("allocate", self.marker.num_perm_vars())); } - // perform lco. - let dealloc_index = Self::lco(code); - - if conjunct_info.allocates() { - let offset = self.global_jmp_by_locs_offset; - - if let Some(jmp_by_offset) = self.jmp_by_locs[offset..].last_mut() { - if *jmp_by_offset == dealloc_index { - *jmp_by_offset += 1; - } - } - - code.insert(dealloc_index, instr!("deallocate")); - } + Ok(()) } - pub(crate) fn compile_rule(&mut self, rule: &Rule) -> Result { - // let iter = ChunkedIterator::from_rule(rule); - // let conjunct_info = self.collect_var_data(iter); - - let &Rule { - head: (_, ref args, ref p1), - ref clauses, - ref var_data, - } = rule; - - let mut code = Code::new(); + pub(crate) fn compile_rule(&mut self, rule: &Rule, var_data: VarData) -> Result { + let Rule { head: (_, args), clauses } = rule; + self.marker.var_data = var_data; + let mut code = VecDeque::new(); self.marker.reset_at_head(args); - self.compile_seq_prelude(&var_data, &mut code); - let iter = FactIterator::from_rule_head_clause(args); - let mut fact = self.compile_target::(iter, GenContext::Head); + let iter = FactIterator::from_rule_head_clause(&args); + let fact = self.compile_target::(iter, GenContext::Head); if self.marker.max_reg_allocated() > MAX_ARITY { return Err(CompilationError::ExceededMaxArity); } self.marker.reset_free_list(); + code.extend(fact.into_iter()); - let mut unsafe_var_marker = UnsafeVarMarker::new(); + self.compile_seq(clauses, &mut code)?; - if !fact.is_empty() { - unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact); - code.extend(fact.into_iter()); - } - - let iter = ChunkedIterator::from_rule_body(p1, clauses); - self.compile_seq(iter, &conjunct_info, &mut code)?; - - unsafe_var_marker.mark_unsafe_instrs(&mut code); - - self.compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1)); - - Ok(code) - } - - 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 Instruction::UnifyValue(r) => { - if !safe_vars.contains(&r) { - *fact_instr = Instruction::UnifyLocalValue(r); - safe_vars.insert(r); - } - } - &mut Instruction::UnifyVariable(r) => { - safe_vars.insert(r); - } - _ => {} - } - } - - UnsafeVarMarker::from_fact_vars(safe_vars) + Ok(Vec::from(code)) } - pub(crate) fn compile_fact(&mut self, fact: &Fact) -> Result { - self.update_var_count(post_order_iter(term)); - - // let mut vs = VariableFixtures::new(); - - // vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head); - - // vs.populate_restricting_sets(); - // self.marker.drain_var_data(vs, 1); - + pub(crate) fn compile_fact(&mut self, fact: &Fact, var_data: VarData) -> Result { let mut code = Vec::new(); + self.marker.var_data = var_data; - if let &Term::Clause(_, _, ref args) = term { + if let Term::Clause(_, _, args) = &fact.head { self.marker.reset_at_head(args); - let iter = FactInstruction::iter(term); - let mut compiled_fact = self.compile_target::( + let iter = FactInstruction::iter(&fact.head); + let compiled_fact = self.compile_target::( iter, GenContext::Head, ); @@ -1023,40 +1021,27 @@ impl<'b> CodeGenerator<'b> { return Err(CompilationError::ExceededMaxArity); } - self.mark_unsafe_fact_vars(&mut compiled_fact); - - if !compiled_fact.is_empty() { - code.extend(compiled_fact.into_iter()); - } + code.extend(compiled_fact.into_iter()); } code.push(instr!("proceed")); Ok(code) } - fn compile_query_line( - &mut self, - term: &QueryTerm, - term_loc: GenContext, - code: &mut Code, - num_perm_vars_left: usize, - ) { + fn compile_query_line(&mut self, term: &QueryTerm, term_loc: GenContext, code: &mut CodeDeque) { self.marker.reset_arg(term.arity()); - let iter = query_term_post_order_iter(term); + let iter = QueryIterator::new(term); let query = self.compile_target::(iter, term_loc); code.extend(query.into_iter()); - self.add_conditional_call(code, term, num_perm_vars_left); - } - - #[inline] - fn increment_jmp_by_locs_by(&mut self, incr: usize) { - let offset = self.global_jmp_by_locs_offset; - for loc in &mut self.jmp_by_locs[offset..] { - *loc += incr; - } + match term { + &QueryTerm::Clause(_, ref ct, _, call_policy) => { + self.add_call(code, ct.to_instr(), call_policy); + } + _ => unreachable!() + }; } fn split_predicate(clauses: &[PredicateClause]) -> Vec { @@ -1121,30 +1106,35 @@ impl<'b> CodeGenerator<'b> { fn compile_pred_subseq( &mut self, - clauses: &[PredicateClause], + clauses: &mut [PredicateClause], optimal_index: usize, ) -> Result { let mut code = VecDeque::new(); let mut code_offsets = CodeOffsets::new(I::new(), optimal_index + 1); let mut skip_stub_try_me_else = false; - let jmp_by_locs_len = self.jmp_by_locs.len(); + let clauses_len = clauses.len(); - for (i, clause) in clauses.iter().enumerate() { + for (i, clause) in clauses.iter_mut().enumerate() { self.marker.reset(); let mut clause_index_info = ClauseIndexInfo::new(code.len()); - self.global_jmp_by_locs_offset = self.jmp_by_locs.len(); let clause_code = match clause { - &PredicateClause::Fact(ref fact, ..) => self.compile_fact(fact)?, - &PredicateClause::Rule(ref rule, ..) => self.compile_rule(rule)?, + PredicateClause::Fact(fact, var_data) => { + let var_data = std::mem::replace(var_data, VarData::default()); + self.compile_fact(&fact, var_data)? + } + PredicateClause::Rule(rule, var_data) => { + let var_data = std::mem::replace(var_data, VarData::default()); + self.compile_rule(&rule, var_data)? + } }; - if clauses.len() > 1 { + if clauses_len > 1 { let choice = match i { 0 => self.settings.internal_try_me_else(clause_code.len() + 1), - _ if i == clauses.len() - 1 => self.settings.internal_trust_me(), + _ if i + 1 == clauses_len => self.settings.internal_trust_me(), _ => self.settings.internal_retry_me_else(clause_code.len() + 1), }; @@ -1170,45 +1160,23 @@ impl<'b> CodeGenerator<'b> { if let Some(arg) = arg { let index = code.len(); - if clauses.len() > 1 || self.settings.is_extensible { + if clauses_len > 1 || self.settings.is_extensible { code_offsets.index_term(arg, index, &mut clause_index_info, self.atom_tbl); } } - if !(code_offsets.no_indices() && clauses.len() == 1 && self.settings.is_extensible) { - // the peculiar condition of this block, when false, - // anticipates code.pop_front() being called about a - // dozen lines below. - - if !skip_stub_try_me_else { - // if the condition is false, code_offsets.no_indices() is false, - // so don't repeat the work of the condition on skip_stub_try_me_else - // below. - self.increment_jmp_by_locs_by(code.len()); - } - } - self.skeleton.clauses.push_back(clause_index_info); code.extend(clause_code.into_iter()); } - let index_code = if clauses.len() > 1 || self.settings.is_extensible { + let index_code = if clauses_len > 1 || self.settings.is_extensible { code_offsets.compute_indices(skip_stub_try_me_else) } else { vec![] }; - self.global_jmp_by_locs_offset = jmp_by_locs_len; - if !index_code.is_empty() { code.push_front(Instruction::IndexingCode(index_code)); - - if skip_stub_try_me_else { - // skip the TryMeElse(0) also. - self.increment_jmp_by_locs_by(2); - } else { - self.increment_jmp_by_locs_by(1); - } } else if clauses.len() == 1 && self.settings.is_extensible { // the condition is the value of skip_stub_try_me_else, which is // true if the predicate is not dynamic. This operation must apply @@ -1223,7 +1191,7 @@ impl<'b> CodeGenerator<'b> { pub(crate) fn compile_predicate( &mut self, - clauses: &Vec, + mut clauses: Vec, ) -> Result { let mut code = Code::new(); @@ -1234,12 +1202,12 @@ impl<'b> CodeGenerator<'b> { let skel_lower_bound = self.skeleton.clauses.len(); let code_segment = if self.settings.is_dynamic() { self.compile_pred_subseq::( - &clauses[left..right], + &mut clauses[left..right], instantiated_arg_index, )? } else { self.compile_pred_subseq::( - &clauses[left..right], + &mut clauses[left..right], instantiated_arg_index, )? }; @@ -1271,12 +1239,17 @@ impl<'b> CodeGenerator<'b> { } } - self.increment_jmp_by_locs_by(code.len()); - self.global_jmp_by_locs_offset = self.jmp_by_locs.len(); - code.extend(code_segment.into_iter()); } + /* + for line in &code { + println!("{:?}", line); + } + + println!(""); + */ + Ok(code) } } diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs index 2ad19cab..2f8d442e 100644 --- a/src/debray_allocator.rs +++ b/src/debray_allocator.rs @@ -1,42 +1,179 @@ -use indexmap::IndexMap; - use crate::allocator::*; -use crate::fixtures::*; +use crate::codegen::SubsumedBranchHits; use crate::forms::Level; use crate::instructions::*; -use crate::machine::machine_indices::*; +use crate::machine::disjuncts::VarData; use crate::parser::ast::*; use crate::targets::*; +use crate::variable_records::*; -use crate::temp_v; - +use bit_set::*; +use bitvec::prelude::*; use fxhash::FxBuildHasher; +use indexmap::IndexMap; use std::cell::Cell; -use std::collections::BTreeSet; +use std::collections::VecDeque; + +pub type BranchHits = IndexMap; // key: var_num, value: branch arm occurrences. + +#[derive(Debug, Default)] +pub struct BranchOccurrences { + pub hits: BranchHits, + pub shallow_safety: BitSet, // unset means safe, set means unsafe (after the branch merge) + pub deep_safety: BitSet, + pub num_branches: usize, + pub current_branch: usize, + pub subsumed_hits: SubsumedBranchHits, +} + +impl BranchOccurrences { + fn new(num_branches: usize) -> Self { + Self { + hits: BranchHits::with_hasher(FxBuildHasher::default()), + shallow_safety: BitSet::default(), + deep_safety: BitSet::default(), + num_branches, + current_branch: 0, + subsumed_hits: SubsumedBranchHits::with_hasher(FxBuildHasher::default()), + } + } +} #[derive(Debug)] pub(crate) struct DebrayAllocator { - bindings: IndexMap, + pub(crate) var_data: VarData, // var_data replaces bindings. + pub(crate) branch_stack: Vec, + pub(crate) in_tail_position: bool, + // bindings: IndexMap, // VarNum -> VarWitness arg_c: usize, temp_lb: usize, + perm_lb: usize, arity: usize, // 0 if not at head. - contents: IndexMap, - in_use: BTreeSet, - free_list: Vec, + shallow_temp_mappings: IndexMap, + in_use: BitSet, // deep and non-var allocations + temp_free_list: Vec, + perm_free_list: VecDeque<(usize, usize)>, // chunk_num, var_num } impl DebrayAllocator { - fn is_curr_arg_distinct_from(&self, var: &Var) -> bool { - match self.contents.get(&self.arg_c) { - Some(t_var) if *t_var != *var => true, + pub(crate) fn add_branch_occurrence(&mut self, var_num: usize) { + if let Some(occurrences) = self.branch_stack.last_mut() { + debug_assert!(occurrences.current_branch < occurrences.num_branches); + + let num_branches = occurrences.num_branches; + + let entry = occurrences.hits.entry(var_num) + .or_insert_with(|| BitVec::repeat(false, num_branches)); + + entry.set(occurrences.current_branch, true); + occurrences.subsumed_hits.insert(var_num); + } + } + + pub(crate) fn add_branch_stack(&mut self, num_branches: usize) { + self.branch_stack.push(BranchOccurrences::new(num_branches)); + } + + pub(crate) fn add_branch(&mut self) { + let branch_occurrences = self.branch_stack.last_mut().unwrap(); + + for var_num in branch_occurrences.subsumed_hits.drain(..) { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, ref mut allocation) => { + match allocation { + PermVarAllocation::Done { shallow_safety, deep_safety, .. } => { + if !shallow_safety.unneeded() { + branch_occurrences.shallow_safety.insert(var_num); + } + + if !deep_safety.unneeded() { + branch_occurrences.deep_safety.insert(var_num); + } + } + _ => { + unreachable!(); + } + } + + *allocation = PermVarAllocation::Pending; + } + _ => unreachable!(), + } + } + } + + #[inline] + pub(crate) fn incr_current_branch(&mut self) { + let branch_occurrences = self.branch_stack.last_mut().unwrap(); + branch_occurrences.current_branch += 1; + } + + #[inline] + pub(crate) fn drain_branches(&mut self, depth: usize) -> std::vec::Drain { + let start_idx = self.branch_stack.len() - depth; + self.branch_stack.drain(start_idx ..) + } + + pub(crate) fn pop_branch(&mut self, depth: usize, subsumed_hits: SubsumedBranchHits) { + let removed_branches = self.drain_branches(depth); + + let (deep_safety, shallow_safety) = removed_branches + .into_iter() + .fold((BitSet::default(), BitSet::default()), + |(mut deep_safety, mut shallow_safety), branch_occurrences| { + deep_safety.union_with(&branch_occurrences.deep_safety); + shallow_safety.union_with(&branch_occurrences.shallow_safety); + + (deep_safety, shallow_safety) + }); + + let (deep_safety, shallow_safety) = match self.branch_stack.last_mut() { + Some(latest_branch) => { + latest_branch.deep_safety.union_with(&deep_safety); + latest_branch.shallow_safety.union_with(&shallow_safety); + + (&latest_branch.deep_safety, &latest_branch.shallow_safety) + } + None => (&deep_safety, &shallow_safety) + }; + + for var_num in subsumed_hits.iter().cloned() { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, ref mut allocation) => { + let shallow_safety = VarSafetyStatus::needed_if( + shallow_safety.contains(var_num), + ); + + let deep_safety = VarSafetyStatus::needed_if( + deep_safety.contains(var_num), + ); + + *allocation = PermVarAllocation::Done { shallow_safety, deep_safety }; + } + _ => unreachable!() + } + } + + if self.branch_stack.len() > 0 { + for var_num in subsumed_hits { + self.add_branch_occurrence(var_num); + } + } + } + + fn is_curr_arg_distinct_from(&self, var_num: usize) -> bool { + match self.shallow_temp_mappings.get(&self.arg_c).cloned() { + Some(t_var) => t_var != var_num, _ => false, } } - fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool { - match self.bindings.get(var).unwrap() { - &VarAlloc::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)), + fn occurs_shallowly_in_head(&self, var_num: usize, r: usize) -> bool { + match &self.var_data.records[var_num].allocation { + VarAlloc::Temp { temp_var_data, term_loc: GenContext::Head, .. } => { + temp_var_data.use_set.contains(&(GenContext::Head, r)) + } _ => false, } } @@ -44,13 +181,13 @@ impl DebrayAllocator { #[inline] fn is_in_use(&self, r: usize) -> bool { let in_use_range = r <= self.arity && r >= self.arg_c; - in_use_range || self.in_use.contains(&r) + in_use_range || self.in_use.contains(r) } - fn alloc_with_cr(&self, var: &Var) -> usize { - match self.bindings.get(var) { - Some(&VarAlloc::Temp(_, _, ref tvd)) => { - for &(_, reg) in tvd.use_set.iter() { + fn alloc_with_cr(&self, var_num: usize) -> usize { + match &self.var_data.records[var_num].allocation { + VarAlloc::Temp { temp_var_data, .. } => { + for &(_, reg) in temp_var_data.use_set.iter() { if !self.is_in_use(reg) { return reg; } @@ -60,7 +197,7 @@ impl DebrayAllocator { for reg in self.temp_lb.. { if !self.is_in_use(reg) { - if !tvd.no_use_set.contains(®) { + if !temp_var_data.no_use_set.contains(reg) { result = reg; break; } @@ -73,10 +210,10 @@ impl DebrayAllocator { } } - fn alloc_with_ca(&self, var: &Var) -> usize { - match self.bindings.get(var) { - Some(&VarAlloc::Temp(_, _, ref tvd)) => { - for &(_, reg) in tvd.use_set.iter() { + fn alloc_with_ca(&self, var_num: usize) -> usize { + match &self.var_data.records[var_num].allocation { + VarAlloc::Temp { temp_var_data, .. } => { + for &(_, reg) in temp_var_data.use_set.iter() { if !self.is_in_use(reg) { return reg; } @@ -86,8 +223,8 @@ impl DebrayAllocator { for reg in self.temp_lb.. { if !self.is_in_use(reg) { - if !tvd.no_use_set.contains(®) { - if !tvd.conflict_set.contains(®) { + if !temp_var_data.no_use_set.contains(reg) { + if !temp_var_data.conflict_set.contains(reg) { result = reg; break; } @@ -101,22 +238,25 @@ impl DebrayAllocator { } } - fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Var, usize)> { + fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(usize, usize)> { // we want to allocate a register to the k^{th} parameter, par_k. // par_k may not be a temporary variable. let k = self.arg_c; - match self.contents.get(&k) { + match self.shallow_temp_mappings.get(&k).cloned() { Some(t_var) => { // suppose this branch fires. then t_var is a // temp. var. belonging to the current chunk. // consider its use set. T == par_k iff // (GenContext::Last(_), k) is in t_var.use_set. - let tvd = self.bindings.get(t_var).unwrap(); - if let &VarAlloc::Temp(_, _, ref tvd) = tvd { - if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) { - return Some((t_var.clone(), self.alloc_with_ca(t_var))); + match &self.var_data.records[t_var].allocation { + VarAlloc::Temp { temp_var_data, .. } => { + if !temp_var_data.use_set.contains(&(GenContext::Last(chunk_num), k)) { + return Some((t_var, self.alloc_with_ca(t_var))); + } + } + _ => { } } @@ -129,21 +269,21 @@ impl DebrayAllocator { fn evacuate_arg<'a, Target: CompilationTarget<'a>>( &mut self, chunk_num: usize, - code: &mut Code, + code: &mut CodeDeque, ) { match self.alloc_in_last_goal_hint(chunk_num) { - Some((var, r)) => { + Some((var_num, r)) => { let k = self.arg_c; if r != k { let r = RegType::Temp(r); - code.push(Target::move_to_register(r, k)); + code.push_back(Target::move_to_register(r, k)); - self.contents.swap_remove(&k); - self.contents.insert(r.reg_num(), var.clone()); + self.shallow_temp_mappings.swap_remove(&k); + self.shallow_temp_mappings.insert(r.reg_num(), var_num); - self.record_register(var, r); + self.var_data.records[var_num].allocation.set_register(r.reg_num()); self.in_use.insert(r.reg_num()); } } @@ -153,27 +293,27 @@ impl DebrayAllocator { fn alloc_reg_to_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: &Var, + var_num: usize, lvl: Level, term_loc: GenContext, - target: &mut Vec, + target: &mut CodeDeque, ) -> usize { match term_loc { GenContext::Head => { if let Level::Shallow = lvl { self.evacuate_arg::(0, target); - self.alloc_with_cr(var) + self.alloc_with_cr(var_num) } else { - self.alloc_with_ca(var) + self.alloc_with_ca(var_num) } } - GenContext::Mid(_) => self.alloc_with_ca(var), + GenContext::Mid(_) => self.alloc_with_ca(var_num), GenContext::Last(chunk_num) => { if let Level::Shallow = lvl { self.evacuate_arg::(chunk_num, target); - self.alloc_with_cr(var) + self.alloc_with_cr(var_num) } else { - self.alloc_with_ca(var) + self.alloc_with_ca(var_num) } } } @@ -182,15 +322,15 @@ impl DebrayAllocator { fn alloc_reg_to_non_var(&mut self) -> usize { let mut final_index = 0; - while let Some(r) = self.free_list.pop() { - if !self.in_use.contains(&r) { + while let Some(r) = self.temp_free_list.pop() { + if !self.is_in_use(r) { self.in_use.insert(r); return r; } } for index in self.temp_lb.. { - if !self.in_use.contains(&index) { + if !self.in_use.contains(index) { final_index = index; self.in_use.insert(final_index); break; @@ -201,38 +341,194 @@ impl DebrayAllocator { final_index } - fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool { + fn in_place(&self, var_num: usize, term_loc: GenContext, r: RegType, k: usize) -> bool { match term_loc { GenContext::Head if !r.is_perm() => r.reg_num() == k, - _ => match self.bindings().get(var).unwrap() { - &VarAlloc::Temp(_, o, _) if r.reg_num() == k => o == k, - _ => false, + _ => { + match &self.var_data.records[var_num].allocation { + &VarAlloc::Temp { temp_reg, .. } if r.reg_num() == k => + temp_reg == k, + _ => false, + } }, } } + fn alloc_perm_var(&mut self, var_num: usize, chunk_num: usize) -> usize { + let p = if let Some(p) = self.pop_free_perm(chunk_num) { + p + } else { + let p = self.perm_lb; + self.perm_lb += 1; + + p + }; + + self.var_data.records[var_num].allocation = VarAlloc::Perm(p, PermVarAllocation::done()); + p + } + pub fn add_to_free_list(&mut self, r: RegType) { if let RegType::Temp(r) = r { - self.in_use.remove(&r); - self.free_list.push(r); + self.in_use.remove(r); + self.temp_free_list.push(r); } } pub fn reset_free_list(&mut self) { - self.free_list.clear(); + self.temp_free_list.clear(); + } + + #[inline(always)] + pub fn get_binding(&self, var_num: usize) -> RegType { + self.var_data.records[var_num].allocation.as_reg_type() + } + + pub fn num_perm_vars(&self) -> usize { + self.perm_lb - 1 + } + + pub fn increment_running_count(&mut self, var_num: usize) { + self.var_data.records[var_num].running_count += 1; + } + + fn pop_free_perm(&mut self, chunk_num: usize) -> Option { + if let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() { + if chunk_num == perm_chunk_num { + None + } else { + self.perm_free_list.pop_front(); + + match &mut self.var_data.records[var_num].allocation { + &mut VarAlloc::Perm(p, ref mut allocation) => { + *allocation = PermVarAllocation::Pending; + Some(p) + } + _ => unreachable!() + } + } + } else { + None + } + } + + pub(crate) fn mark_temp_to_safe_perm(&mut self, var_num: usize) { + match &self.var_data.records[var_num].allocation { + &VarAlloc::Temp { to_perm_var_num: Some(perm_var_num), .. } => { + match &mut self.var_data.records[perm_var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => { + *deep_safety = VarSafetyStatus::Unneeded; + *shallow_safety = VarSafetyStatus::Unneeded; + } + _ => unreachable!() + } + } + _ => { + } + } + } + + fn mark_safe_var(&mut self, var_num: usize, lvl: Level, term_loc: GenContext) { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => { + // GetVariable in head chunk is considered safe. + if lvl == Level::Deep { + *deep_safety = VarSafetyStatus::Unneeded; + *shallow_safety = VarSafetyStatus::Unneeded; + } else if term_loc == GenContext::Head { + *shallow_safety = VarSafetyStatus::Unneeded; + } else { + if let Some(temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c).cloned() { + match &mut self.var_data.records[temp_var_num].allocation { + VarAlloc::Temp { ref mut to_perm_var_num, .. } => { + *to_perm_var_num = Some(var_num); + } + _ => unreachable!() + } + } + } + } + VarAlloc::Temp { ref mut safety, .. } => { + *safety = VarSafetyStatus::Unneeded; + } + _ => { + unreachable!() + } + } + } + + fn argument_to_value<'a, Target: CompilationTarget<'a>>( + &mut self, + var_num: usize, + r: RegType, + arg_c: usize, + ) -> Instruction { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { ref mut shallow_safety, .. }) => { + if !self.in_tail_position || shallow_safety.unneeded() { + Target::argument_to_value(r, arg_c) + } else { + *shallow_safety = VarSafetyStatus::Unneeded; + Target::unsafe_argument_to_value(r, arg_c) + } + } + VarAlloc::Temp { ref mut safety, .. } => { + if safety.unneeded() { + Target::argument_to_value(r, arg_c) + } else { + *safety = VarSafetyStatus::Unneeded; + Target::unsafe_argument_to_value(r, arg_c) + } + } + _ => { + unreachable!() + } + } + } + + fn subterm_to_value<'a, Target: CompilationTarget<'a>>( + &mut self, + var_num: usize, + r: RegType, + ) -> Instruction { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { ref mut deep_safety, .. }) => { + if deep_safety.unneeded() { + Target::subterm_to_value(r) + } else { + *deep_safety = VarSafetyStatus::Unneeded; + Target::unsafe_subterm_to_value(r) + } + } + VarAlloc::Temp { ref mut safety, .. } => { + if safety.unneeded() { + Target::subterm_to_value(r) + } else { + *safety = VarSafetyStatus::Unneeded; + Target::unsafe_subterm_to_value(r) + } + } + _ => { + unreachable!() + } + } } } impl Allocator for DebrayAllocator { fn new() -> DebrayAllocator { - DebrayAllocator { + Self { + var_data: VarData::default(), + in_tail_position: false, arity: 0, arg_c: 1, temp_lb: 1, - bindings: IndexMap::with_hasher(FxBuildHasher::default()), - contents: IndexMap::with_hasher(FxBuildHasher::default()), - in_use: BTreeSet::new(), - free_list: vec![], + perm_lb: 1, + shallow_temp_mappings: IndexMap::with_hasher(FxBuildHasher::default()), + in_use: BitSet::default(), + temp_free_list: vec![], + perm_free_list: VecDeque::new(), + branch_stack: vec![], } } @@ -240,12 +536,12 @@ impl Allocator for DebrayAllocator { &mut self, lvl: Level, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, ) { let r = RegType::Temp(self.alloc_reg_to_non_var()); match lvl { - Level::Deep => code.push(Target::subterm_to_variable(r)), + Level::Deep => code.push_back(Target::subterm_to_variable(r)), Level::Root | Level::Shallow => { let k = self.arg_c; @@ -255,7 +551,7 @@ impl Allocator for DebrayAllocator { self.arg_c += 1; - code.push(Target::argument_to_variable(r, k)); + code.push_back(Target::argument_to_variable(r, k)); } }; } @@ -265,7 +561,7 @@ impl Allocator for DebrayAllocator { lvl: Level, term_loc: GenContext, cell: &'a Cell, - code: &mut Code, + code: &mut CodeDeque, ) { let r = cell.get(); @@ -292,39 +588,49 @@ impl Allocator for DebrayAllocator { fn mark_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: Var, + var_num: usize, lvl: Level, cell: &'a Cell, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, ) { - let (r, is_new_var) = match self.get(var.clone()) { + let (r, is_new_var) = match self.get_binding(var_num) { RegType::Temp(0) => { - // here, r is temporary *and* unassigned. - let o = self.alloc_reg_to_var::(&var, lvl, term_loc, code); + let o = self.alloc_reg_to_var::(var_num, lvl, term_loc, code); cell.set(VarReg::Norm(RegType::Temp(o))); (RegType::Temp(o), true) } RegType::Perm(0) => { - let pr = cell.get().norm(); - self.record_register(var.clone(), pr); + let p = self.alloc_perm_var(var_num, term_loc.chunk_num()); + (RegType::Perm(p), true) + } + r @ RegType::Perm(_) => { + let is_new_var = match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, allocation) => if allocation.pending() { + *allocation = PermVarAllocation::done(); + true + } else { + false + }, + _ => unreachable!(), + }; - (pr, true) + (r, is_new_var) } r => (r, false), }; - self.mark_reserved_var::(var, lvl, cell, term_loc, code, r, is_new_var); + self.mark_reserved_var::(var_num, lvl, cell, term_loc, code, r, is_new_var); } fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: Var, + var_num: usize, lvl: Level, cell: &'a Cell, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, r: RegType, is_new_var: bool, ) { @@ -332,86 +638,104 @@ impl Allocator for DebrayAllocator { Level::Root | Level::Shallow => { let k = self.arg_c; - if self.is_curr_arg_distinct_from(&var) { + if self.is_curr_arg_distinct_from(var_num) { self.evacuate_arg::(term_loc.chunk_num(), code); } - self.arg_c += 1; - cell.set(VarReg::ArgAndNorm(r, k)); - if !self.in_place(&var, term_loc, r, k) { + if !self.in_place(var_num, term_loc, r, k) { if is_new_var { - code.push(Target::argument_to_variable(r, k)); + self.mark_safe_var(var_num, lvl, term_loc); + code.push_back(Target::argument_to_variable(r, k)); } else { - code.push(Target::argument_to_value(r, k)); + code.push_back(self.argument_to_value::(var_num, r, k)); } } + + self.arg_c += 1; } Level::Deep if is_new_var => { if let GenContext::Head = term_loc { - if self.occurs_shallowly_in_head(&var, r.reg_num()) { - code.push(Target::subterm_to_value(r)); + if self.occurs_shallowly_in_head(var_num, r.reg_num()) { + code.push_back(self.subterm_to_value::(var_num, r)); } else { - code.push(Target::subterm_to_variable(r)); + self.mark_safe_var(var_num, lvl, term_loc); + code.push_back(Target::subterm_to_variable(r)); } } else { - code.push(Target::subterm_to_variable(r)); + self.mark_safe_var(var_num, lvl, term_loc); + code.push_back(Target::subterm_to_variable(r)); } } - Level::Deep => code.push(Target::subterm_to_value(r)), - }; + Level::Deep => code.push_back(self.subterm_to_value::(var_num, r)), + } + + let o = r.reg_num(); if !r.is_perm() { - let o = r.reg_num(); + self.shallow_temp_mappings.insert(o, var_num); + } else if r.is_perm() && is_new_var { + self.add_branch_occurrence(var_num); + } + + let record = &mut self.var_data.records[var_num]; + + record.allocation.set_register(o); + + if record.running_count < record.num_occurrences { + record.running_count += 1; + } else if r.is_perm() { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, allocation) => *allocation = PermVarAllocation::Pending, + _ => unreachable!(), + } + + self.perm_free_list.push_back((term_loc.chunk_num(), var_num)); + } - self.contents.insert(o, var.clone()); - self.record_register(var.clone(), r); - self.in_use.insert(o); + self.in_use.insert(o); + } + + fn mark_cut_var(&mut self, var_num: usize, chunk_num: usize) -> RegType { + match self.get_binding(var_num) { + RegType::Perm(0) | RegType::Temp(0) => { + RegType::Perm(self.alloc_perm_var(var_num, chunk_num)) + } + r => r, } } fn reset(&mut self) { - self.bindings.clear(); - self.contents.clear(); + self.perm_lb = 1; + self.shallow_temp_mappings.clear(); self.in_use.clear(); - self.free_list.clear(); + self.temp_free_list.clear(); } fn reset_contents(&mut self) { - self.contents.clear(); self.in_use.clear(); - self.free_list.clear(); + self.shallow_temp_mappings.clear(); + self.temp_free_list.clear(); } fn advance_arg(&mut self) { self.arg_c += 1; } - fn bindings(&self) -> &AllocVarDict { - &self.bindings - } - - fn bindings_mut(&mut self) -> &mut AllocVarDict { - &mut self.bindings - } - - fn take_bindings(self) -> AllocVarDict { - self.bindings - } - fn reset_at_head(&mut self, args: &Vec) { self.reset_arg(args.len()); self.arity = args.len(); for (idx, arg) in args.iter().enumerate() { if let &Term::Var(_, ref var) = arg { - let r = self.get(var.clone()); + let var_num = var.to_var_num().unwrap(); + let r = self.get_binding(var_num); if !r.is_perm() && r.reg_num() == 0 { self.in_use.insert(idx + 1); - self.contents.insert(idx + 1, var.clone()); - self.record_register(var.clone(), temp_v!(idx + 1)); + self.shallow_temp_mappings.insert(idx + 1, var_num); + self.var_data.records[var_num].allocation.set_register(idx + 1); } } } diff --git a/src/fixtures.rs b/src/fixtures.rs deleted file mode 100644 index 66734320..00000000 --- a/src/fixtures.rs +++ /dev/null @@ -1,342 +0,0 @@ -use crate::forms::*; -use crate::instructions::*; -use crate::machine::disjuncts::ClassifyInfo; -use crate::parser::ast::*; - -use bit_set::*; -use indexmap::{IndexMap, IndexSet}; - -pub(crate) type OccurrenceSet = IndexSet<(GenContext, usize)>; - -#[derive(Debug)] -pub(crate) struct TempVarData { - pub(crate) last_term_arity: usize, - pub(crate) use_set: OccurrenceSet, - pub(crate) no_use_set: BitSet, - pub(crate) conflict_set: BitSet, -} - -#[derive(Debug)] -pub(crate) struct TempVarStatus { - chunk_num: usize, - temp_var_data: TempVarData, -} - -// Perm: 0 initially, a stack register once processed. -// Temp: labeled with chunk_num and temp offset (unassigned if 0). -#[derive(Debug)] -pub(crate) enum VarAlloc { - Perm(usize), - Temp(usize, usize, TempVarData), -} - -impl VarAlloc { - pub(crate) fn as_reg_type(&self) -> RegType { - match self { - &VarAlloc::Temp(_, r, _) => RegType::Temp(r), - &VarAlloc::Perm(r) => RegType::Perm(r), - } - } -} - -impl TempVarData { - pub(crate) fn new(last_term_arity: usize) -> Self { - TempVarData { - last_term_arity: last_term_arity, - use_set: BitSet::::new(), - no_use_set: BitSet::new(), - conflict_set: BitSet::new(), - } - } - - pub(crate) fn uses_reg(&self, reg: usize) -> bool { - for &(_, nreg) in self.use_set.iter() { - if reg == nreg { - return true; - } - } - - return false; - } - - pub(crate) fn populate_conflict_set(&mut self) { - if self.last_term_arity > 0 { - let arity = self.last_term_arity; - let mut conflict_set: BitSet = (1..arity).collect(); - - for &(_, reg) in self.use_set.iter() { - conflict_set.remove(reg); - } - - self.conflict_set = conflict_set; - } - } -} - -#[derive(Debug)] -pub(crate) struct VariableFixtures { - temp_vars: IndexMap, -} - -impl VariableFixtures { - pub(crate) fn new() -> Self { - VariableFixtures { - temp_vars: IndexMap::new(), - } - } - - // computes no_use and conflict sets for all temp vars. - pub(crate) fn populate_restricting_sets(&mut self) { - // three stages: - // 1. move the use sets of each variable to a local IndexMap, use_set - // (iterate mutably, swap mutable refs). - // 2. drain use_set. For each use set of U, add into the - // no-use sets of appropriate variables T =/= U. - // 3. Move the use sets back to their original locations in the fixture. - // Compute the conflict set of u. - - // 1. - let mut use_sets: IndexMap = IndexMap::new(); - - for (var_gen_index, ref mut var_status) in self.temp_vars.iter_mut() { - let TempVarStatus { ref mut temp_var_data, .. } = var_status; - let mut use_set = OccurrenceSet::new(); - - std::mem::swap(&mut temp_var_data.use_set, &mut use_set); - use_sets.insert(var_gen_index, use_set); - } - - for (u, use_set) in use_sets.drain(..) { - // 2. - for &(term_loc, reg) in use_set.iter() { - if let GenContext::Last(cn_u) = term_loc { - for (var_gen_index, ref mut var_status) in self.terms_vars.iter_mut() { - let TempVarStatus { chunk_num, ref mut temp_var_data } = var_status; - - if cn_u == chunk_num && u != var_gen_index { - if !temp_var_data.uses_reg(reg) { - temp_var_data.no_use_set.insert(reg); - } - } - } - } - } - - // 3. - let TempVarStatus { ref mut temp_var_data, ..} = self.temp_vars.get_mut(u).unwrap(); - - temp_var_data.use_set = use_set; - temp_var_data.populate_conflict_set(); - } - } - - fn record_temp_info(&mut self, tvd: &mut TempVarData, arg_c: usize, term_loc: GenContext) { - match term_loc { - GenContext::Head | GenContext::Last(_) => { - tvd.use_set.insert((term_loc, arg_c)); - } - _ => {} - }; - } - - pub(crate) fn mark_temp_var(&mut self, var_info: &VarInfo) { - let chunk_num = term_loc.chunk_num(); - let var = Var::from(var_info.var_ptr); - - let mut status = self.temp_vars.swap_remove(&var).unwrap_or_else(|| { - TempVarStatus { - chunk_num, - temp_var_data: TempVarData::new(var_info.classify_info.arity), - } - }); - - if let Level::Shallow = var_info.lvl { - self.record_temp_info(&mut status, var_info.classify_info.arg_c, term_loc); - } - - self.temp_vars.insert(var, status); - } -} - -#[derive(Debug)] -pub(crate) struct UnsafeVarMarker { - pub(crate) unsafe_perm_vars: IndexMap, - pub(crate) unsafe_temp_vars: IndexSet, - pub(crate) safe_perm_vars: IndexSet, - pub(crate) safe_temp_vars: IndexSet, - pub(crate) temp_vars_to_perm_vars: IndexMap, -} - -impl UnsafeVarMarker { - pub(crate) fn new() -> Self { - UnsafeVarMarker { - unsafe_perm_vars: IndexMap::new(), - unsafe_temp_vars: IndexSet::new(), - safe_perm_vars: IndexSet::new(), - safe_temp_vars: IndexSet::new(), - temp_vars_to_perm_vars: IndexMap::new(), - } - } - - pub(crate) fn from_fact_vars(safe_vars: IndexSet) -> Self { - let mut unsafe_var_marker = Self::new(); - - for r in safe_vars { - unsafe_var_marker.mark_var_as_safe(r); - } - - unsafe_var_marker - } - - fn mark_var_as_safe(&mut self, r: RegType) { - match r { - RegType::Temp(t) => { - self.safe_temp_vars.insert(t); - } - RegType::Perm(p) => { - self.safe_perm_vars.insert(p); - } - }; - } - - fn mark_var_as_unsafe(&mut self, r: RegType, phase: usize) { - match r { - RegType::Temp(t) => { - self.unsafe_temp_vars.insert(t); - } - RegType::Perm(p) => { - self.unsafe_perm_vars.insert(p, phase); - } - } - } - - // returns true if the instruction at *query_instr cannot be - // changed by mark_unsafe_vars. - fn mark_safe_vars(&mut self, query_instr: &Instruction) -> bool { - match query_instr { - &Instruction::PutVariable(r @ RegType::Temp(_), _) | - &Instruction::SetVariable(r) => { - self.mark_var_as_safe(r); - true - } - &Instruction::PutVariable(RegType::Perm(p), t) => { - self.temp_vars_to_perm_vars.insert(t, p); - true - } - &Instruction::CallIs(RegType::Temp(t), ..) => { - if let Some(p) = self.temp_vars_to_perm_vars.get(&t) { - self.mark_var_as_safe(RegType::Perm(*p)); - } - - true - } - _ => false, - } - } - - fn mark_phase(&mut self, query_instr: &Instruction, phase: usize) { - match query_instr { - &Instruction::PutValue(r @ RegType::Perm(_), _) | - &Instruction::SetValue(r) => { - self.mark_var_as_unsafe(r, phase); - } - _ => {} - } - } - - fn mark_unsafe_perm_vars(&mut self, query_instr: &mut Instruction, phase: usize) { - match query_instr { - &mut Instruction::PutValue(RegType::Perm(p), arg) - if !self.safe_perm_vars.contains(&p) => { - if let Some(ph) = self.unsafe_perm_vars.swap_remove(&p) { - if ph == phase { - *query_instr = Instruction::PutUnsafeValue(p, arg); - self.safe_perm_vars.insert(p); - } else { - self.unsafe_perm_vars.insert(p, ph); - } - } - } - &mut Instruction::SetValue(r @ RegType::Perm(p)) - if !self.safe_perm_vars.contains(&p) => { - *query_instr = Instruction::SetLocalValue(r); - - self.safe_perm_vars.insert(p); - self.unsafe_perm_vars.remove(&p); - } - _ => {} - } - } - - fn mark_unsafe_temp_vars(&mut self, query_instr: &mut Instruction) { - match query_instr { - &mut Instruction::SetValue(r @ RegType::Temp(t)) - if !self.safe_temp_vars.contains(&t) => { - *query_instr = Instruction::SetLocalValue(r); - - self.safe_temp_vars.insert(t); - self.unsafe_temp_vars.remove(&t); - } - _ => { - } - } - } - - fn clear_temp_vars(&mut self) { - self.safe_temp_vars.clear(); - self.unsafe_temp_vars.clear(); - self.temp_vars_to_perm_vars.clear(); - } - - pub(crate) fn mark_unsafe_instrs(&mut self, code: &mut Code) { - if code.is_empty() { - return; - } - - let mut code_index = 0; - - for phase in 0.. { - while code[code_index].is_query_instr() { - let query_instr = &mut code[code_index]; - - if !self.mark_safe_vars(query_instr) { - self.mark_phase(query_instr, phase); - self.mark_unsafe_temp_vars(query_instr); - } - - code_index += 1; - } - - while code_index < code.len() && !code[code_index].is_query_instr() { - self.mark_safe_vars(&code[code_index]); - code_index += 1; - } - - self.clear_temp_vars(); - - if code_index >= code.len() { - break; - } - } - - code_index = 0; - - for phase in 0.. { - while code[code_index].is_query_instr() { - let query_instr = &mut code[code_index]; - self.mark_unsafe_perm_vars(query_instr, phase); - code_index += 1; - } - - // ensure phase->instruction assignments match those of - // the previous for loop. - while code_index < code.len() && !code[code_index].is_query_instr() { - code_index += 1; - } - - if code_index >= code.len() { - break; - } - } - } -} diff --git a/src/forms.rs b/src/forms.rs index 3ed83866..627fb4b2 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -20,25 +20,23 @@ use std::cell::Cell; use std::collections::VecDeque; use std::convert::TryFrom; use std::fmt; -use std::ops::AddAssign; +use std::ops::{AddAssign, Deref, DerefMut}; use std::path::PathBuf; use crate::{is_infix, is_postfix}; pub type PredicateKey = (Atom, usize); // name, arity. -pub type Predicate = Vec; - +/* // vars of predicate, toplevel offset. Vec is always a vector // of vars (we get their adjoining cells this way). pub type JumpStub = Vec; +*/ -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum TopLevel { - Fact(Fact), // Term, line_num, col_num - Predicate(Predicate), - Query(Vec), - Rule(Rule), // Rule, line_num, col_num + Fact(Fact, VarData), // Term, line_num, col_num + Rule(Rule, VarData), // Rule, line_num, col_num } #[derive(Debug, Clone, Copy)] @@ -79,13 +77,30 @@ pub enum CallPolicy { Counted, } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ChunkType { Head, Mid, Last, } +#[derive(Debug)] +pub enum RootIterationPolicy { + Iterated, + NotIterated, +} + +impl RootIterationPolicy { + #[inline(always)] + pub fn iterable(&self) -> bool { + if let RootIterationPolicy::Iterated = self { + true + } else { + false + } + } +} + impl ChunkType { #[inline(always)] pub fn to_gen_context(self, chunk_num: usize) -> GenContext { @@ -102,47 +117,104 @@ impl ChunkType { } } +#[derive(Debug)] +pub enum ChunkedTerms { + Branch(Vec>), + Chunk(VecDeque), +} + +#[derive(Debug)] +pub struct ChunkedTermVec { + pub chunk_vec: VecDeque, +} + +impl Deref for ChunkedTermVec { + type Target = VecDeque; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.chunk_vec + } +} + +impl DerefMut for ChunkedTermVec { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.chunk_vec + } +} + +impl ChunkedTermVec { + #[inline] + pub fn new() -> Self { + Self { chunk_vec: VecDeque::new() } + } + + pub fn reserve_branch(&mut self, capacity: usize) { + self.chunk_vec.push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity))); + } + + pub fn push_branch_arm(&mut self, branch: VecDeque) { + match self.chunk_vec.back_mut().unwrap() { + ChunkedTerms::Branch(branches) => { + branches.push(branch); + } + ChunkedTerms::Chunk(_) => { + self.chunk_vec.push_back(ChunkedTerms::Branch(vec![branch])); + } + } + } + + #[inline] + pub fn add_chunk(&mut self) { + self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![]))); + } + + pub fn push_chunk_term(&mut self, term: QueryTerm) { + match self.chunk_vec.back_mut() { + Some(ChunkedTerms::Branch(_)) => { + self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term]))); + } + Some(ChunkedTerms::Chunk(chunk)) => { + chunk.push_back(term); + } + None => { + self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term]))); + } + } + } +} + #[derive(Debug)] pub enum QueryTerm { // register, clause type, subterms, clause call policy. Clause(Cell, ClauseType, Vec, CallPolicy), Fail, - GlobalCut, - GetCutPoint(usize), - LocalCut(usize), - Branch(Vec>), - ChunkTypeBoundary(ChunkType), + LocalCut(usize), // var_num + GlobalCut(usize), // var_num + GetCutPoint { var_num: usize, prev_b: bool }, + GetLevel(usize), // var_num } impl QueryTerm { - pub(crate) fn set_call_policy(&mut self, cp: CallPolicy) { - match self { - &mut QueryTerm::Clause(_, _, _, ref mut clause_cp) => *clause_cp = cp, - _ => {} - } - } - pub(crate) fn arity(&self) -> usize { match self { &QueryTerm::Clause(_, _, ref subterms, ..) => subterms.len(), - &QueryTerm::Cut | &QueryTerm::Branch(_) => 0, - &QueryTerm::IfThen(..) => 2, - &QueryTerm::Not(_) => 1, + &QueryTerm::GetLevel(_) | &QueryTerm::GetCutPoint { .. } => 1, + _ => 0, } } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Fact { pub(crate) head: Term, - pub(crate) var_data: VarData, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Rule { - pub(crate) head: (Atom, Vec, QueryTerm), - pub(crate) clauses: Vec, - pub(crate) var_data: VarData, + pub(crate) head: (Atom, Vec), + pub(crate) clauses: ChunkedTermVec, } #[derive(Clone, Debug, Hash)] @@ -233,29 +305,29 @@ impl ClauseInfo for Rule { impl ClauseInfo for PredicateClause { fn name(&self) -> Option { match self { - &PredicateClause::Fact(ref term, ..) => term.name(), + &PredicateClause::Fact(ref term, ..) => term.head.name(), &PredicateClause::Rule(ref rule, ..) => rule.name(), } } fn arity(&self) -> usize { match self { - &PredicateClause::Fact(ref term, ..) => term.arity(), + &PredicateClause::Fact(ref term, ..) => term.head.arity(), &PredicateClause::Rule(ref rule, ..) => rule.arity(), } } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum PredicateClause { - Fact(Fact), - Rule(Rule), + Fact(Fact, VarData), + Rule(Rule, VarData), } impl PredicateClause { pub(crate) fn args(&self) -> Option<&[Term]> { match self { - PredicateClause::Fact(term, ..) => match term { + PredicateClause::Fact(term, ..) => match &term.head { Term::Clause(_, _, args) => Some(&args), _ => None, }, diff --git a/src/heap_iter.rs b/src/heap_iter.rs index 9760be9e..d7f1f2e4 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -424,7 +424,6 @@ mod tests { use super::*; use crate::machine::mock_wam::*; - #[test] fn heap_stackless_iter_tests() { let mut wam = MockWAM::new(); diff --git a/src/heap_print.rs b/src/heap_print.rs index d09211d1..aa93ad29 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -472,7 +472,7 @@ pub struct HCPrinter<'a, Outputter> { state_stack: Vec, toplevel_spec: Option, last_item_idx: usize, - pub var_names: IndexMap, + pub var_names: IndexMap, pub numbervars_offset: Integer, pub numbervars: bool, pub quoted: bool, @@ -803,7 +803,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { if let Some(var) = self.var_names.get(&addr) { read_heap_cell!(addr, (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => { - return Some(var.to_string()); + return Some(var.borrow().to_string()); } _ => { self.iter.push_stack(h); @@ -847,7 +847,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { // short-circuits handle_heap_term. // self.iter.pop_stack(); - let var_str = var.to_string(); + let var_str = var.borrow().to_string(); push_space_if_amb!(self, &var_str, { append_str!(self, &var_str); @@ -862,7 +862,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { Some(var) => { // If the term is bound to a named variable, // print the variable's name to output. - let var_str = var.to_string(); + let var_str = var.borrow().to_string(); push_space_if_amb!(self, &var_str, { append_str!(self, &var_str); diff --git a/src/iterators.rs b/src/iterators.rs index 529c453c..adec2e4c 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -5,100 +5,40 @@ use crate::parser::ast::*; use std::cell::Cell; use std::collections::VecDeque; -use std::fmt; -use std::fmt::Debug; -use std::hash::{Hash}; use std::iter::*; use std::vec::Vec; -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub(crate) enum VarPtr { - ToVar(std::ptr::NonNull), - InSitu(usize), -} - -impl From<&Var> for VarPtr { - #[inline] - fn from(value: &Var) -> VarPtr { - unsafe { - VarPtr { ptr: std::ptr::NonNull::new_unchecked(value as *const _ as *mut _) } - } - } -} - -impl From for Var { - #[inline(always)] - fn from(value: VarPtr) -> Var { - match value { - VarPtr::ToPtr(ptr) => unsafe { - (*ptr.ptr.as_ptr()).clone() - }, - VarPtr::InSitu(var_num) => { - Var::Generated(var_num) - } - } - } -} - -impl VarPtr { - pub(crate) fn set(&mut self, value: Var) { - match self { - VarPtr::ToVar(ref mut ptr) => - unsafe { *ptr.as_mut() = value }, - VarPtr::InSitu(_) => { - } - } - } -} - #[derive(Debug, Clone)] pub(crate) enum TermRef<'a> { AnonVar(Level), - Cut(Level), - GetLevel(Level), Cons(Level, &'a Cell, &'a Term, &'a Term), - Fail(Level), Literal(Level, &'a Cell, &'a Literal), Clause(Level, &'a Cell, Atom, &'a Vec), PartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), - Var(Level, &'a Cell, Var), - InitialBranch(Level), - MiddleBranch(Level), - FinalBranch(Level), + Var(Level, &'a Cell, VarPtr), } +/* impl<'a> TermRef<'a> { - pub(crate) fn level(self) -> Level { + pub(crate) fn level(&self) -> Level { match self { TermRef::AnonVar(lvl) | TermRef::Cons(lvl, ..) | - TermRef::Cut(lvl) | - TermRef::GetLevel(lvl) | TermRef::Literal(lvl, ..) | TermRef::Var(lvl, ..) | TermRef::Clause(lvl, ..) | TermRef::CompleteString(lvl, ..) | - TermRef::PartialString(lvl, ..) | - TermRef::InitialBranch(lvl) | - TermRef::MiddleBranch(lvl) | - TermRef::FinalBranch(lvl) | - TermRef::Fail(lvl) => lvl, + TermRef::PartialString(lvl, ..) => *lvl, } } } +*/ #[derive(Debug)] pub(crate) enum TermIterState<'a> { AnonVar(Level), Clause(Level, usize, &'a Cell, Atom, &'a Vec), - Cut(Level), - Fail(Level), - GetLevel(Level), - InitialBranch(Level, &'a Vec), - MiddleBranch(Level, &'a Vec), - FinalBranch(Level, &'a Vec), - Sequence(Level, &'a Vec), Literal(Level, &'a Cell, &'a Literal), InitialCons(Level, &'a Cell, &'a Term, &'a Term), FinalCons(Level, &'a Cell, &'a Term, &'a Term), @@ -125,7 +65,7 @@ impl<'a> TermIterState<'a> { Term::CompleteString(cell, atom) => { TermIterState::CompleteString(lvl, cell, *atom) } - Term::Var(cell, var) => TermIterState::Var(lvl, cell, VarPtr::from(var)), + Term::Var(cell, var_ptr) => TermIterState::Var(lvl, cell, var_ptr.clone()), } } } @@ -140,6 +80,7 @@ impl<'a> QueryIterator<'a> { self.state_stack.push(TermIterState::subterm_to_state(lvl, term)); } + /* fn from_rule_head_clause(terms: &'a Vec) -> Self { let state_stack = terms .iter() @@ -149,6 +90,7 @@ impl<'a> QueryIterator<'a> { QueryIterator { state_stack } } + */ fn from_term(term: &'a Term) -> Self { let state = match term { @@ -165,7 +107,7 @@ impl<'a> QueryIterator<'a> { *name, terms, ), - Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, VarPtr::from(var)), + Term::Var(cell, var_ptr) => TermIterState::Var(Level::Root, cell, var_ptr.clone()), }; QueryIterator { @@ -181,36 +123,12 @@ impl<'a> QueryIterator<'a> { &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => { self.state_stack.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms)); } - &QueryTerm::Cut => { - self.state_stack.push(TermIterState::Cut(lvl)); - } - &QueryTerm::Not(ref terms) => { - self.state_stack.push(TermIterState::Fail(lvl)); - self.state_stack.push(TermIterState::Cut(lvl)); - self.state_stack.push(TermIterState::Sequence(lvl, terms)); - } - &QueryTerm::IfThen(ref if_terms, ref then_terms) => { - self.state_stack.push(TermIterState::Sequence(lvl, then_terms)); - self.state_stack.push(TermIterState::Cut(lvl)); - self.state_stack.push(TermIterState::Sequence(lvl, if_terms)); - self.state_stack.push(TermIterState::GetLevel(lvl)); - } - &QueryTerm::Branch(ref branches) => { - let len = branches.len(); - self.state_stack.push(TermIterState::FinalBranch(lvl, &branches[len - 1])); - - self.state_stack.extend(branches[1 .. len - 1] - .iter() - .rev() - .map(|t| TermIterState::MiddleBranch(lvl, t)), - ); - - self.state_stack.push(TermIterState::InitialBranch(lvl, &branches[0])); + _ => { } } } - fn new(term: &'a QueryTerm) -> Self { + pub fn new(term: &'a QueryTerm) -> Self { let mut iter = QueryIterator { state_stack: vec![] }; iter.extend_state(Level::Root, term); iter @@ -273,34 +191,8 @@ impl<'a> Iterator for QueryIterator<'a> { TermIterState::Literal(lvl, cell, constant) => { return Some(TermRef::Literal(lvl, cell, constant)); } - TermIterState::Var(lvl, cell, var) => { - return Some(TermRef::Var(lvl, cell, Var::from(var))); - } - TermIterState::Cut(lvl) => { - return Some(TermRef::Cut(lvl)); - } - TermIterState::GetLevel(lvl) => { - return Some(TermRef::GetLevel(lvl)); - } - TermIterState::InitialBranch(lvl, ref branch) => { - self.state_stack.push(TermIterState::Sequence(lvl, branch)); - return Some(TermRef::InitialBranch(lvl)); - } - TermIterState::MiddleBranch(lvl, ref branch) => { - self.state_stack.push(TermIterState::Sequence(lvl, branch)); - return Some(TermRef::MiddleBranch(lvl)); - } - TermIterState::FinalBranch(lvl, ref branch) => { - self.state_stack.push(TermIterState::Sequence(lvl, branch)); - return Some(TermRef::FinalBranch(lvl)); - } - TermIterState::Sequence(lvl, ref terms) => { - for term in branch.iter().rev() { - self.extend_state(lvl, term); - } - } - TermIterState::Fail(lvl) => { - return Some(TermRef::Fail(lvl)); + TermIterState::Var(lvl, cell, var_ptr) => { + return Some(TermRef::Var(lvl, cell, var_ptr)); } }; } @@ -312,7 +204,7 @@ impl<'a> Iterator for QueryIterator<'a> { #[derive(Debug)] pub(crate) struct FactIterator<'a> { state_queue: VecDeque>, - iterable_root: bool, + iterable_root: RootIterationPolicy, } impl<'a> FactIterator<'a> { @@ -329,11 +221,11 @@ impl<'a> FactIterator<'a> { FactIterator { state_queue, - iterable_root: false, + iterable_root: RootIterationPolicy::NotIterated, } } - fn new(term: &'a Term, iterable_root: bool) -> Self { + fn new(term: &'a Term, iterable_root: RootIterationPolicy) -> Self { let states = match term { Term::AnonVar => { vec![TermIterState::AnonVar(Level::Root)] @@ -365,8 +257,8 @@ impl<'a> FactIterator<'a> { Term::Literal(cell, constant) => { vec![TermIterState::Literal(Level::Root, cell, constant)] } - Term::Var(cell, var) => { - vec![TermIterState::Var(Level::Root, cell, VarPtr::from(var))] + Term::Var(cell, var_ptr) => { + vec![TermIterState::Var(Level::Root, cell, var_ptr.clone())] } }; @@ -392,7 +284,7 @@ impl<'a> Iterator for FactIterator<'a> { } match lvl { - Level::Root if !self.iterable_root => continue, + Level::Root if !self.iterable_root.iterable() => continue, _ => return Some(TermRef::Clause(lvl, cell, name, child_terms)), }; } @@ -412,8 +304,8 @@ impl<'a> Iterator for FactIterator<'a> { TermIterState::Literal(lvl, cell, constant) => { return Some(TermRef::Literal(lvl, cell, constant)) } - TermIterState::Var(lvl, cell, var) => { - return Some(TermRef::Var(lvl, cell, Var::from(var))); + TermIterState::Var(lvl, cell, var_ptr) => { + return Some(TermRef::Var(lvl, cell, var_ptr)); } _ => {} } @@ -427,143 +319,130 @@ pub(crate) fn post_order_iter<'a>(term: &'a Term) -> QueryIterator<'a> { QueryIterator::from_term(term) } -pub(crate) fn breadth_first_iter<'a>(term: &'a Term, iterable_root: bool) -> FactIterator<'a> { +pub(crate) fn breadth_first_iter<'a>(term: &'a Term, iterable_root: RootIterationPolicy) -> FactIterator<'a> { FactIterator::new(term, iterable_root) } -/* -#[derive(Debug)] -pub(crate) enum ChunkedTerm<'a> { - HeadClause(Atom, &'a Vec), - BodyTerm(&'a QueryTerm), -} - -pub(crate) fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterator<'a> { - QueryIterator::new(query_term) +#[derive(Debug, Copy, Clone)] +enum ClauseIteratorState<'a> { + RemainingChunks(&'a VecDeque, usize), + RemainingBranches(&'a Vec>, usize), } -impl<'a> ChunkedTerm<'a> { - pub(crate) fn post_order_iter(&self) -> QueryIterator<'a> { - match self { - &ChunkedTerm::BodyTerm(qt) => QueryIterator::new(qt), - &ChunkedTerm::HeadClause(_, terms) => QueryIterator::from_rule_head_clause(terms), - } - } +#[derive(Debug, Clone)] +pub(crate) enum ClauseItem<'a> { + FirstBranch(usize), + NextBranch, + BranchEnd(usize), + Chunk(&'a VecDeque), } -pub(crate) struct ChunkedIterator<'a> { - pub(crate) chunk_num: usize, - iter: Box> + 'a>, +#[derive(Debug)] +pub(crate) struct ClauseIterator<'a> { + state_stack: Vec>, + remaining_chunks_on_stack: usize, } -impl<'a> fmt::Debug for ChunkedIterator<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("ChunkedIterator") - .field("chunk_num", &self.chunk_num) - // Hacky solution. - .field("iter", &"Box> + 'a>") - .finish() +fn state_from_chunked_terms<'a>(chunk_vec: &'a VecDeque) -> ClauseIteratorState<'a> { + if chunk_vec.len() == 1 { + if let Some(ChunkedTerms::Branch(ref branches)) = chunk_vec.front() { + return ClauseIteratorState::RemainingBranches(branches, 0); + } } + + ClauseIteratorState::RemainingChunks(chunk_vec, 0) } -type ChunkedIteratorItem<'a> = (usize, usize, Vec>); -type RuleBodyIteratorItem<'a> = (usize, usize, Vec<&'a QueryTerm>); - -impl<'a> ChunkedIterator<'a> { - pub(crate) fn rule_body_iter(self) -> Box> + 'a> { - Box::new(self.filter_map(|(cn, lt_arity, terms)| { - let filtered_terms: Vec<_> = terms - .into_iter() - .filter_map(|ct| match ct { - ChunkedTerm::BodyTerm(qt) => Some(qt), - _ => None, - }) - .collect(); - - if filtered_terms.is_empty() { - None - } else { - Some((cn, lt_arity, filtered_terms)) +impl<'a> ClauseIterator<'a> { + pub fn new(clauses: &'a ChunkedTermVec) -> Self { + match state_from_chunked_terms(&clauses.chunk_vec) { + state @ ClauseIteratorState::RemainingBranches(..) => { + Self { + state_stack: vec![state], + remaining_chunks_on_stack: 0, + } + } + state @ ClauseIteratorState::RemainingChunks(..) => { + Self { + state_stack: vec![state], + remaining_chunks_on_stack: 1, + } } - })) - } - - pub(crate) fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec) -> Self { - let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); - let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); - - ChunkedIterator { - chunk_num: 0, - iter: Box::new(iter), } } - pub(crate) fn from_rule(rule: &'a Rule) -> Self { - let &Rule { - head: (ref name, ref args, ref p1), - ref clauses, - .. - } = rule; - - let iter = once(ChunkedTerm::HeadClause(name.clone(), args)); - let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); - let iter = iter.chain(inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)))); - - ChunkedIterator { - chunk_num: 0, - iter: Box::new(iter), - } + #[inline(always)] + pub fn in_tail_position(&self) -> bool { + self.remaining_chunks_on_stack == 0 } - fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec>) { - let mut arity = 0; - let mut item = Some(term); - let mut result = Vec::new(); + fn branch_end_depth(&mut self) -> usize { + let mut depth = 1; - while let Some(term) = item { - match term { - ChunkedTerm::HeadClause(_, terms) => { - result.push(term); - } - ChunkedTerm::BodyTerm(&QueryTerm::Cut) => { - result.push(term); - } - ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => { - result.push(term); - } - ChunkedTerm::BodyTerm(&QueryTerm::Clause( - _, - ClauseType::CallN(_), - ref subterms, - _, - )) => { - result.push(term); - arity = subterms.len() + 1; - break; + while let Some(state) = self.state_stack.pop() { + match state { + ClauseIteratorState::RemainingBranches(terms, focus) if terms.len() == focus => { + depth += 1; } - ChunkedTerm::BodyTerm(qt) => { - result.push(term); - arity = qt.arity(); + _ => { + self.state_stack.push(state); break; } - }; - - item = self.iter.next(); + } } - let chunk_num = self.chunk_num; - self.chunk_num += 1; - - (chunk_num, arity, result) + depth } } -impl<'a> Iterator for ChunkedIterator<'a> { - // the chunk number, last term arity, and vector of references. - type Item = ChunkedIteratorItem<'a>; +impl<'a> Iterator for ClauseIterator<'a> { + type Item = ClauseItem<'a>; fn next(&mut self) -> Option { - self.iter.next().map(|term| self.take_chunk(term)) + while let Some(state) = self.state_stack.pop() { + match state { + ClauseIteratorState::RemainingChunks(chunks, focus) if focus < chunks.len() => { + if focus + 1 < chunks.len() { + self.state_stack.push(ClauseIteratorState::RemainingChunks(chunks, focus + 1)); + } else { + self.remaining_chunks_on_stack -= 1; + } + + match &chunks[focus] { + ChunkedTerms::Branch(branches) => { + self.state_stack.push(ClauseIteratorState::RemainingBranches(branches, 0)); + } + ChunkedTerms::Chunk(chunk) => { + return Some(ClauseItem::Chunk(chunk)); + } + } + } + ClauseIteratorState::RemainingChunks(chunks, focus) => { + debug_assert_eq!(chunks.len(), focus); + } + ClauseIteratorState::RemainingBranches(branches, focus) if focus < branches.len() => { + self.state_stack.push(ClauseIteratorState::RemainingBranches(&branches, focus + 1)); + let state = state_from_chunked_terms(&branches[focus]); + + if let ClauseIteratorState::RemainingChunks(..) = &state { + self.remaining_chunks_on_stack += 1; + } + + self.state_stack.push(state); + + return if focus == 0 { + Some(ClauseItem::FirstBranch(branches.len())) + } else { + Some(ClauseItem::NextBranch) + }; + } + ClauseIteratorState::RemainingBranches(branches, focus) => { + debug_assert_eq!(branches.len(), focus); + return Some(ClauseItem::BranchEnd(self.branch_end_depth())); + } + } + } + + None } } -*/ diff --git a/src/lib.rs b/src/lib.rs index 45dc2385..36f7a45b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ mod arithmetic; pub mod codegen; mod debray_allocator; mod ffi; -mod fixtures; +mod variable_records; mod forms; mod heap_iter; pub mod heap_print; diff --git a/src/lib/builtins.pl b/src/lib/builtins.pl index 0005d395..1c183a0c 100644 --- a/src/lib/builtins.pl +++ b/src/lib/builtins.pl @@ -218,13 +218,13 @@ fail :- '$fail'. %% \+(Goal) % % True iff Goal fails -\+ G :- call(G), !, false. +\+ G :- call(G), !, '$fail'. \+ _. %% \=(?X, ?Y) % % True iff X and Y can't be unified -X \= X :- !, false. +X \= X :- !, '$fail'. _ \= _. diff --git a/src/lib/format.pl b/src/lib/format.pl index 32ad2ff9..be1cd532 100644 --- a/src/lib/format.pl +++ b/src/lib/format.pl @@ -513,10 +513,12 @@ portray_clause(Stream, Term) :- phrase_to_stream(portray_clause_(Term), Stream), flush_output(Stream). +% called once. portray_clause_(Term) --> { unique_variable_names(Term, VNs) }, portray_(Term, VNs), ".\n". +% mysteriously called twice, the second time with the truncated B3. unique_variable_names(Term, VNs) :- term_variables(Term, Vs), foldl(var_name, Vs, VNs, 0, _). diff --git a/src/loader.pl b/src/loader.pl index 896d6bff..5c35822e 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -541,6 +541,7 @@ open_file(Path, Stream) :- ) ). + use_module(Module, Exports, Evacuable) :- ( var(Module) -> instantiation_error(load/1) @@ -562,12 +563,11 @@ use_module(Module, Exports, Evacuable) :- stream_property(Stream, file_name(PathFileName)), file_load(Stream, PathFileName, Subevacuable), '$use_module'(Evacuable, Subevacuable, Exports) - ; type_error(atom, Library, load/1) + ; type_error(atom, Module, load/1) ) ). - check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm) :- '$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm). check_predicate_property(built_in, _, Name, Arity, built_in) :- diff --git a/src/machine/code_walker.rs b/src/machine/code_walker.rs index fcda8710..1244eb20 100644 --- a/src/machine/code_walker.rs +++ b/src/machine/code_walker.rs @@ -23,13 +23,9 @@ fn capture_offset(line: &Instruction, index: usize, stack: &mut Vec) -> b { stack.push(index + offset); } - &Instruction::JmpByCall(_, offset, _) => { + &Instruction::JmpByCall(offset) => { stack.push(index + offset); } - &Instruction::JmpByExecute(_, offset, _) => { - stack.push(index + offset); - return true; - } &Instruction::Proceed => { return true; } diff --git a/src/machine/compile.rs b/src/machine/compile.rs index 428e2952..0faf34c3 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -44,62 +44,6 @@ pub(super) fn bootstrapping_compile( Ok(()) } -// throw errors if declaration or query found. -pub(super) fn compile_relation( - cg: &mut CodeGenerator, - tl: &TopLevel, -) -> Result { - match tl { - &TopLevel::Query(_) => Err(CompilationError::ExpectedRel), - &TopLevel::Predicate(ref clauses) => cg.compile_predicate(&clauses), - &TopLevel::Fact(ref fact, ..) => cg.compile_fact(fact), - &TopLevel::Rule(ref rule, ..) => cg.compile_rule(rule), - } -} - -/* -pub(super) fn compile_appendix( - code: &mut Code, - mut queue: VecDeque, - jmp_by_locs: Vec, - non_counted_bt: bool, - atom_tbl: &mut AtomTable, -) -> Result<(), CompilationError> { - let mut jmp_by_locs = VecDeque::from(jmp_by_locs); - - while let Some(jmp_by_offset) = jmp_by_locs.pop_front() { - let code_len = code.len(); - - match &mut code[jmp_by_offset] { - &mut Instruction::JmpByCall(_, ref mut offset, ..) | - &mut Instruction::JmpByExecute(_, ref mut offset, ..) => { - *offset = code_len - jmp_by_offset; - } - _ => { - unreachable!() - } - } - - // false because the inner predicate is a one-off, hence not extensible. - let settings = CodeGenSettings { - global_clock_tick: None, - is_extensible: false, - non_counted_bt, - }; - - let mut cg = CodeGenerator::new(atom_tbl, settings); - - let tl = queue.pop_front().unwrap(); - let decl_code = compile_relation(&mut cg, &tl)?; - - jmp_by_locs.extend(cg.jmp_by_locs.into_iter().map(|offset| offset + code.len())); - code.extend(decl_code.into_iter()); - } - - Ok(()) -} -*/ - fn lower_bound_of_target_clause(skeleton: &PredicateSkeleton, target_pos: usize) -> usize { if target_pos == 0 { return 0; @@ -1351,17 +1295,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { settings, ); - let mut clause_code = cg.compile_predicate(&vec![clause])?; - - /* - compile_appendix( - &mut clause_code, - queue, - cg.jmp_by_locs, - settings.non_counted_bt, - cg.atom_tbl, - )?; - */ + let clause_code = cg.compile_predicate(vec![clause])?; Ok(StandaloneCompileResult { clause_code, @@ -1389,24 +1323,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { clauses.push(self.try_term_to_tl(term, &mut preprocessor)?); } - // let queue = preprocessor.parse_queue(self)?; - let mut cg = CodeGenerator::new( &mut LS::machine_st(&mut self.payload).atom_tbl, settings, ); - let mut code = cg.compile_predicate(&clauses)?; - - /* - compile_appendix( - &mut code, - queue, - cg.jmp_by_locs, - settings.non_counted_bt, - cg.atom_tbl, - )?; - */ + let mut code = cg.compile_predicate(clauses)?; if settings.is_extensible { let mut clause_clause_locs = VecDeque::new(); diff --git a/src/machine/disjuncts.rs b/src/machine/disjuncts.rs index 98875bc8..1b65ef9e 100644 --- a/src/machine/disjuncts.rs +++ b/src/machine/disjuncts.rs @@ -1,4 +1,3 @@ - /* ================================================================================ @@ -9,7 +8,6 @@ paper "Compiling Large Disjunctions" to Scryer Prolog. */ use crate::atom_table::*; -use crate::fixtures::VariableFixtures; use crate::forms::*; use crate::instructions::*; use crate::iterators::*; @@ -18,16 +16,18 @@ use crate::machine::machine_errors::CompilationError; use crate::machine::preprocessor::*; use crate::parser::ast::*; use crate::parser::rug::Rational; +use crate::variable_records::*; use indexmap::{IndexMap, IndexSet}; use std::cell::Cell; use std::cmp::Ordering; +use std::collections::VecDeque; use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; -#[derive(Debug, Clone)] -struct BranchNumber { +#[derive(Debug, Clone)] //, PartialOrd, PartialEq, Eq, Hash)] +pub struct BranchNumber { branch_num: Rational, delta: Rational, } @@ -35,7 +35,7 @@ struct BranchNumber { impl Default for BranchNumber { fn default() -> Self { Self { - branch_num: Rational::from(1 << 63), + branch_num: Rational::from(1usize << 63), delta: Rational::from(1), } } @@ -87,9 +87,10 @@ impl BranchNumber { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct VarInfo { var_ptr: VarPtr, + chunk_type: ChunkType, classify_info: ClassifyInfo, lvl: Level, } @@ -102,6 +103,11 @@ pub struct ChunkInfo { vars: Vec, } +#[derive(Debug)] +pub struct BranchArm { + pub arm_terms: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BranchInfo { branch_num: BranchNumber, @@ -114,7 +120,7 @@ impl BranchInfo { } } -type BranchMapInt = IndexMap>; +type BranchMapInt = IndexMap>; #[derive(Debug, Clone)] pub struct BranchMap(BranchMapInt); @@ -145,82 +151,77 @@ pub struct ClassifyInfo { enum TraversalState { // construct a QueryTerm::Branch with number of disjuncts, reset - // the chunk type to that of the chunk preceding the disjunct. - BuildDisjunct(ChunkType, usize), + // the chunk type to that of the chunk preceding the disjunct and the chunk_num. + BuildDisjunct(usize), // add the last disjunct to a QueryTerm::Branch, continuing from // where it leaves off. BuildFinalDisjunct(usize), Fail, - GetCutPoint(usize), - LocalCut(usize), + GetCutPoint{ var_num: usize, prev_b: bool }, + Cut { var_num: usize, is_global: bool }, ResetCallPolicy(CallPolicy), Term(Term), - AddBranchNum(BranchNumber), // set current_branch_number, add it to the root set - RemoveBranchNum, // remove latest branch number from the root set - RepBranchNum(BranchNumber), // replace current_branch_number and the latest in the root set - IncrChunkNum, // increment self.current_chunk_number - SetLastChunkType, // consider remaining terms as belonging to a last chunk -} - -impl Term { - #[inline] - fn is_var(&self) -> bool { - if let Term::Var(..) = self { - true - } else { - false - } - } - - #[inline] - fn is_compound(&self) -> bool { - match self { - Term::Clause(..) | Term::Cons(..) => true, - _ => false, - } - } + RemoveBranchNum, // pop the current_branch_num and from the root set. + AddBranchNum(BranchNumber), // set current_branch_num, add it to the root set + RepBranchNum(BranchNumber), // replace current_branch_num and the latest in the root set + // SetChunkType(ChunkType), // consider remaining terms as belonging to a last chunk } +#[derive(Debug)] pub struct VariableClassifier { call_policy: CallPolicy, current_branch_num: BranchNumber, current_chunk_num: usize, + current_chunk_type: ChunkType, branch_map: BranchMap, var_num: usize, root_set: RootSet, + global_cut_var_num: Option, } -#[derive(Debug)] -pub enum VarClassification { - Void, - Temp, - Perm, +#[derive(Debug, Default)] +pub struct VarData { + pub records: VariableRecords, + pub global_cut_var_num: Option, + pub allocates: bool, } -#[derive(Clone, Debug)] -pub struct VarRecord { - pub classification: VarClassification, - pub chunk_occurrences: Vec, - pub num_occurrences: usize, -} +impl VarData { + fn emit_initial_get_level(&mut self, build_stack: &mut ChunkedTermVec) { + let global_cut_var_num = + if let &Some(global_cut_var_num) = &self.global_cut_var_num { + match &self.records[global_cut_var_num].allocation { + VarAlloc::Perm(..) => Some(global_cut_var_num), + VarAlloc::Temp { term_loc, .. } if term_loc.chunk_num() > 0 => { + Some(global_cut_var_num) + } + _ => None + } + } else { + None + }; -impl Default for VarRecord { - fn default() -> Self { - VarRecord { - classification: VarClassification::Void, - chunk_occurrences: vec![], - num_occurrences: 0, + if let Some(global_cut_var_num) = global_cut_var_num { + let term = QueryTerm::GetLevel(global_cut_var_num); + self.records[global_cut_var_num].allocation = VarAlloc::Perm(0, PermVarAllocation::Pending); + + match build_stack.front_mut() { + Some(ChunkedTerms::Branch(_)) => { + build_stack.push_front(ChunkedTerms::Chunk(VecDeque::from(vec![term]))); + } + Some(ChunkedTerms::Chunk(chunk)) => { + chunk.push_front(term); + } + None => { + unreachable!() + } + } } } } -pub struct VarData { - pub records: Vec, - pub fixtures: VariableFixtures, -} - pub type ClassifyFactResult = (Term, VarData); -pub type ClassifyRuleResult = (Term, Vec, VarData); +pub type ClassifyRuleResult = (Term, ChunkedTermVec, VarData); fn merge_branch_seq>(branches: Iter) -> BranchInfo { let mut branch_info = BranchInfo::new(BranchNumber::default()); @@ -228,6 +229,7 @@ fn merge_branch_seq>(branches: Iter) -> Branch for mut branch in branches { branch_info.branch_num = branch.branch_num; + /* if let Some(last_chunk) = branch_info.chunks.last_mut() { if let Some(first_moved_chunk) = branch.chunks.first_mut() { if last_chunk.chunk_num == first_moved_chunk.chunk_num { @@ -238,6 +240,7 @@ fn merge_branch_seq>(branches: Iter) -> Branch } } } + */ branch_info.chunks.extend(branch.chunks.drain(..)); } @@ -248,82 +251,37 @@ fn merge_branch_seq>(branches: Iter) -> Branch branch_info } -fn flatten_into_disjunct(build_stack: &mut Vec, preceding_len: usize) { - let iter = build_stack.drain(preceding_len + 1 ..); +fn flatten_into_disjunct(build_stack: &mut ChunkedTermVec, preceding_len: usize) { + let branch_vec = build_stack.drain(preceding_len + 1 ..).collect(); - if let QueryTerm::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] { - disjuncts.push(iter.collect()); + if let ChunkedTerms::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] { + disjuncts.push(branch_vec); } else { unreachable!(); } } -fn term_in_other_chunk(term: &Term) -> Option { - match term { - Term::Clause(_, name, terms) => Some(!ClauseType::is_inbuilt(*name, terms.len())), - Term::Literal(_, Literal::Atom(atom!("!")) | Literal::Char('!')) => Some(false), - Term::Literal(_, Literal::Atom(name)) => Some(!ClauseType::is_inbuilt(*name, 0)), - Term::Var(..) => Some(true), - _ => None, - } -} - -// returns true if SetLastChunkType was pushed. -// expects that iter iterates over a conjunct of Terms in reverse order. -fn insert_set_last_chunk_type( - state_stack: &mut Vec, - mut iter: impl Iterator, -) -> bool { - let beg = state_stack.len(); - - let mut will_break = false; - let mut last_chunk_delim = beg; - - while let Some(traversal_st) = iter.next() { - match traversal_st { - TraversalState::Term(term) => { - will_break = false; - - match term_in_other_chunk(&term) { - Some(true) if last_chunk_delim > beg => will_break = true, - Some(_) => last_chunk_delim += 1, - None => will_break = true, - } - - if will_break { - // recall that iter iterates in reverse order. - // therefore this is the correct push order. - state_stack.push(TraversalState::SetLastChunkType); - state_stack.push(traversal_st); - - break; - } - } - _ => { - state_stack.push(traversal_st); - } - } - } - - state_stack.extend(iter); - will_break -} - impl VariableClassifier { pub fn new(call_policy: CallPolicy) -> Self { Self { call_policy, current_branch_num: BranchNumber::default(), current_chunk_num: 0, + current_chunk_type: ChunkType::Head, branch_map: BranchMap(BranchMapInt::new()), root_set: RootSet::new(), var_num: 0, + global_cut_var_num: None, } } pub fn classify_fact(mut self, term: Term) -> Result { self.classify_head_variables(&term)?; - Ok((term, self.branch_map.separate_and_classify_variables(self.var_num))) + Ok((term, self.branch_map.separate_and_classify_variables( + self.var_num, + self.global_cut_var_num, + self.current_chunk_num, + ))) } pub fn classify_rule<'a, LS: LoadState<'a>>( @@ -333,9 +291,21 @@ impl VariableClassifier { body: Term, ) -> Result { self.classify_head_variables(&head)?; - let query_terms = self.classify_body_variables(loader, body)?; + self.root_set.insert(self.current_branch_num.clone()); + + let mut query_terms = self.classify_body_variables(loader, body)?; - Ok((head, query_terms, self.branch_map.separate_and_classify_variables(self.var_num))) + self.merge_branches(); + + let mut var_data = self.branch_map.separate_and_classify_variables( + self.var_num, + self.global_cut_var_num, + self.current_chunk_num, + ); + + var_data.emit_initial_get_level(&mut query_terms); + + Ok((head, query_terms, var_data)) } fn merge_branches(&mut self) { @@ -359,24 +329,49 @@ impl VariableClassifier { } } - fn probe_body_term(&mut self, term: &Term, term_loc: GenContext) { - let mut classify_info = ClassifyInfo { arg_c: 0, arity: term.arity() }; + fn try_set_chunk_at_inlined_boundary(&mut self) -> bool { + if self.current_chunk_type.is_last() { + self.current_chunk_type = ChunkType::Mid; + self.current_chunk_num += 1; + true + } else { + false + } + } - // second arg is true to iterate the root, which may be a variable - for term_ref in breadth_first_iter(term, true) { - if let TermRef::Var(lvl, _, var_name) = term_ref { - let var_info = VarInfo { var_ptr: VarPtr::from(&var_name), lvl, classify_info }; - self.probe_body_var(var_name, term_loc, var_info); - } + fn try_set_chunk_at_call_boundary(&mut self) -> bool { + if self.current_chunk_type.is_last() { + self.current_chunk_num += 1; + true + } else { + self.current_chunk_type = ChunkType::Last; + false + } + } - if let Level::Shallow = term_ref.level() { - classify_info.arg_c += 1; + fn probe_body_term(&mut self, arg_c: usize, arity: usize, term: &Term) { + let classify_info = ClassifyInfo { arg_c, arity }; + + // second arg is true to iterate the root, which may be a variable + for term_ref in breadth_first_iter(term, RootIterationPolicy::Iterated) { + if let TermRef::Var(lvl, _, var_ptr) = term_ref { + // root terms are shallow here (since we're iterating a + // body term) so take the child level. + let lvl = lvl.child_level(); + self.probe_body_var(VarInfo { + var_ptr, + lvl, + classify_info, + chunk_type: self.current_chunk_type, + }); } } } - fn probe_body_var(&mut self, var_name: Var, term_loc: GenContext, var_info: VarInfo) { - let branch_info_v = self.branch_map.entry(var_name) + fn probe_body_var(&mut self, var_info: VarInfo) { + let term_loc = self.current_chunk_type.to_gen_context(self.current_chunk_num); + + let branch_info_v = self.branch_map.entry(var_info.var_ptr.clone()) .or_insert_with(|| vec![]); let needs_new_branch = if let Some(last_bi) = branch_info_v.last() { @@ -409,18 +404,17 @@ impl VariableClassifier { chunk_info.vars.push(var_info); } - fn probe_in_situ_var(&mut self, chunk_type: ChunkType, var_num: usize) { - let classify_info = ClassifyInfo { arg_c: 0, arity: 0 }; + fn probe_in_situ_var(&mut self, var_num: usize) { + let classify_info = ClassifyInfo { arg_c: 1, arity: 1 }; let var_info = VarInfo { - var_ptr: VarPtr::InSitu(var_num), + var_ptr: VarPtr::from(Var::InSitu(var_num)), classify_info, + chunk_type: self.current_chunk_type, lvl: Level::Shallow, }; - let term_loc = chunk_type.to_gen_context(self.current_chunk_num); - - self.probe_body_var(Var::Generated(var_num), term_loc, var_info); + self.probe_body_var(var_info); } fn classify_head_variables(&mut self, term: &Term) -> Result<(), CompilationError> { @@ -430,43 +424,55 @@ impl VariableClassifier { _ => return Err(CompilationError::InvalidRuleHead), } - let mut classify_info = ClassifyInfo { arg_c: 0, arity: term.arity() }; - - // false argument to breadth_first_iter because the root is not iterable. - for term_ref in breadth_first_iter(term, false) { - if let TermRef::Var(lvl, _, var_name) = term_ref { - // the body of the if let here is an inlined - // "probe_head_var". note the difference between it - // and "probe_body_var". - let branch_info_v = self.branch_map.entry(Var::from(var_name)) - .or_insert_with(|| vec![]); - - let needs_new_branch = branch_info_v.is_empty(); + let mut classify_info = ClassifyInfo { arg_c: 1, arity: term.arity() }; - if needs_new_branch { - branch_info_v.push(BranchInfo::new(self.current_branch_num.clone())); - } + match term { + Term::Clause(_, _, terms) => { + for term in terms.into_iter() { + for term_ref in breadth_first_iter(term, RootIterationPolicy::Iterated) { + if let TermRef::Var(lvl, _, var_ptr) = term_ref { + // a body term, so we need the child level here. + let lvl = lvl.child_level(); + + // the body of the if let here is an inlined + // "probe_head_var". note the difference between it + // and "probe_body_var". + let branch_info_v = self.branch_map.entry(var_ptr.clone()) + .or_insert_with(|| vec![]); + + let needs_new_branch = branch_info_v.is_empty(); + + if needs_new_branch { + branch_info_v.push(BranchInfo::new(self.current_branch_num.clone())); + } - let branch_info = branch_info_v.last_mut().unwrap(); - let needs_new_chunk = branch_info.chunks.is_empty(); + let branch_info = branch_info_v.last_mut().unwrap(); + let needs_new_chunk = branch_info.chunks.is_empty(); - if needs_new_chunk { - branch_info.chunks.push(ChunkInfo { - chunk_num: self.current_chunk_num, - term_loc: GenContext::Head, - vars: vec![] - }); - } + if needs_new_chunk { + branch_info.chunks.push(ChunkInfo { + chunk_num: self.current_chunk_num, + term_loc: GenContext::Head, + vars: vec![], + }); + } - let chunk_info = branch_info.chunks.last_mut().unwrap(); - let var_info = VarInfo { var_ptr: VarPtr::from(&var_name), classify_info, lvl }; + let chunk_info = branch_info.chunks.last_mut().unwrap(); + let var_info = VarInfo { + var_ptr, + classify_info, + chunk_type: self.current_chunk_type, + lvl, + }; - chunk_info.vars.push(var_info); - } + chunk_info.vars.push(var_info); + } + } - if let Level::Shallow = term_ref.level() { - classify_info.arg_c += 1; + classify_info.arg_c += 1; + } } + _ => {} } Ok(()) @@ -476,10 +482,11 @@ impl VariableClassifier { &mut self, loader: &mut Loader<'a, LS>, term: Term, - ) -> Result, CompilationError> { + ) -> Result { let mut state_stack = vec![TraversalState::Term(term)]; - let mut build_stack = vec![]; - let mut chunk_type = ChunkType::Head; + let mut build_stack = ChunkedTermVec::new(); + + self.current_chunk_type = ChunkType::Mid; while let Some(traversal_st) = state_stack.pop() { match traversal_st { @@ -495,64 +502,78 @@ impl VariableClassifier { self.root_set.insert(branch_num.clone()); self.current_branch_num = branch_num; } - TraversalState::IncrChunkNum => { - self.current_chunk_num += 1; - chunk_type = ChunkType::Mid; - build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type)); - } TraversalState::ResetCallPolicy(call_policy) => { self.call_policy = call_policy; } - TraversalState::SetLastChunkType => { - chunk_type = ChunkType::Last; - build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type)); - } - TraversalState::BuildDisjunct(reset_chunk_type, preceding_len) => { - chunk_type = reset_chunk_type; - build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type)); + TraversalState::BuildDisjunct(preceding_len) => { flatten_into_disjunct(&mut build_stack, preceding_len); + + // self.current_chunk_type = ChunkType::Last; + self.current_chunk_type = ChunkType::Mid; + self.current_chunk_num += 1; } TraversalState::BuildFinalDisjunct(preceding_len) => { flatten_into_disjunct(&mut build_stack, preceding_len); + + self.current_chunk_type = ChunkType::Mid; + self.current_chunk_num += 1; } - TraversalState::GetCutPoint(var_num) => { - let term_loc = chunk_type.to_gen_context(self.current_chunk_num); + TraversalState::GetCutPoint { var_num, prev_b } => { + if self.try_set_chunk_at_inlined_boundary() { + build_stack.add_chunk(); + } - self.probe_in_situ_var(term_loc, var_num); - build_stack.push(QueryTerm::GetCutPoint(var_num)); + self.probe_in_situ_var(var_num); + build_stack.push_chunk_term(QueryTerm::GetCutPoint { var_num, prev_b }); } - TraversalState::LocalCut(var_num) => { - let term_loc = chunk_type.to_gen_context(self.current_chunk_num); + TraversalState::Cut { var_num, is_global } => { + if self.try_set_chunk_at_inlined_boundary() { + build_stack.add_chunk(); + } + + self.probe_in_situ_var(var_num); - self.probe_in_situ_var(term_loc, var_num); - build_stack.push(QueryTerm::LocalCut(var_num)); + build_stack.push_chunk_term( + if is_global { + QueryTerm::GlobalCut(var_num) + } else { + QueryTerm::LocalCut(var_num) + } + ); } TraversalState::Fail => { - build_stack.push(QueryTerm::Fail); + build_stack.push_chunk_term(QueryTerm::Fail); } TraversalState::Term(term) => { + // return true iff new chunk should be added. + let update_chunk_data = |classifier: &mut Self, predicate_name, arity| { + if ClauseType::is_inlined(predicate_name, arity) { + classifier.try_set_chunk_at_inlined_boundary() + } else { + classifier.try_set_chunk_at_call_boundary() + } + }; + match term { - Term::Clause(_, atom!(","), terms) if terms.len() == 2 => { - let iter = unfold_by_str(terms[1], atom!(",")) + Term::Clause(_, atom!(","), mut terms) if terms.len() == 2 => { + let tail = terms.pop().unwrap(); + let head = terms.pop().unwrap(); + + let iter = unfold_by_str(tail, atom!(",")) .into_iter() .rev() - .chain(std::iter::once(terms[0])) + .chain(std::iter::once(head)) .map(TraversalState::Term); - if ChunkType::Mid != chunk_type { - if insert_set_last_chunk_type(&mut state_stack, iter) { - if chunk_type.is_last() { - chunk_type = ChunkType::Mid; - } - } - } else { - state_stack.extend(iter); - } + state_stack.extend(iter); } - Term::Clause(_, atom!(";"), terms) if terms.len() == 2 => { + Term::Clause(_, atom!(";"), mut terms) if terms.len() == 2 => { + let tail = terms.pop().unwrap(); + let head = terms.pop().unwrap(); + let first_branch_num = self.current_branch_num.split(); - let branches: Vec<_> = std::iter::once(terms[0]) - .chain(unfold_by_str(terms[1], atom!(";")).into_iter()) + let branches: Vec<_> = std::iter::once(head) + .chain(unfold_by_str(tail, atom!(";")).into_iter()) .collect(); let mut branch_numbers = vec![first_branch_num]; @@ -568,7 +589,7 @@ impl VariableClassifier { } let build_stack_len = build_stack.len(); - build_stack.push(QueryTerm::Branch(Vec::with_capacity(branches.len()))); + build_stack.reserve_branch(branches.len()); state_stack.push(TraversalState::RepBranchNum( self.current_branch_num.halve_delta(), @@ -578,47 +599,52 @@ impl VariableClassifier { let final_disjunct_loc = state_stack.len(); for (term, branch_num) in iter.rev() { - state_stack.push(TraversalState::BuildDisjunct(chunk_type, build_stack_len)); - + state_stack.push(TraversalState::BuildDisjunct(build_stack_len)); state_stack.push(TraversalState::RemoveBranchNum); state_stack.push(TraversalState::Term(term)); state_stack.push(TraversalState::AddBranchNum(branch_num)); } - state_stack[final_disjunct_loc] = - TraversalState::BuildFinalDisjunct(build_stack_len); + if let TraversalState::BuildDisjunct(build_stack_len) = state_stack[final_disjunct_loc] { + state_stack[final_disjunct_loc] = TraversalState::BuildFinalDisjunct(build_stack_len); + } } Term::Clause(_, atom!("->"), mut terms) if terms.len() == 2 => { let then_term = terms.pop().unwrap(); let if_term = terms.pop().unwrap(); - let iter = vec![TraversalState::Term(then_term), - TraversalState::LocalCut(self.var_num), - TraversalState::Term(if_term), - TraversalState::GetCutPoint(self.var_num)] - .into_iter(); + let prev_b = if matches!(state_stack.last(), Some(TraversalState::RemoveBranchNum)) { + // check if the second-to-last element is a regular BuildDisjunct, as we don't + // want to add GetPrevLevel in case of a TrustMe. + matches!(state_stack.iter().rev().nth(1), Some(TraversalState::BuildDisjunct(..))) + } else { + false + }; - self.var_num += 1; + state_stack.push(TraversalState::Term(then_term)); + state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false }); + state_stack.push(TraversalState::Term(if_term)); + state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b }); - if ChunkType::Mid != chunk_type { - if insert_set_last_chunk_type(&mut state_stack, iter) { - if chunk_type.is_last() { - chunk_type = ChunkType::Mid; - } - } - } + self.var_num += 1; } - Term::Clause(_, atom!("\\+"), terms) if terms.len() == 1 => { + Term::Clause(_, atom!("\\+"), mut terms) if terms.len() == 1 => { + let not_term = terms.pop().unwrap(); + let build_stack_len = build_stack.len(); + + build_stack.reserve_branch(2); + + state_stack.push(TraversalState::BuildFinalDisjunct(build_stack_len)); + state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), atom!("$succeed"), vec![]))); + state_stack.push(TraversalState::BuildDisjunct(build_stack_len)); state_stack.push(TraversalState::Fail); - state_stack.push(TraversalState::LocalCut(self.var_num)); - state_stack.push(TraversalState::Term(terms[0])); - state_stack.push(TraversalState::GetCutPoint(self.var_num)); + state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false }); + state_stack.push(TraversalState::Term(not_term)); + state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b: true }); self.var_num += 1; } Term::Clause(_, atom!(":"), mut terms) if terms.len() == 2 => { - let term_loc = chunk_type.to_gen_context(self.current_chunk_num); - let predicate_name = terms.pop().unwrap(); let module_name = terms.pop().unwrap(); @@ -627,11 +653,11 @@ impl VariableClassifier { Term::Literal(_, Literal::Atom(module_name)), Term::Literal(_, Literal::Atom(predicate_name)), ) => { - if !ClauseType::is_inbuilt(predicate_name, 0) { - state_stack.push(TraversalState::IncrChunkNum); + if update_chunk_data(self, predicate_name, 0) { + build_stack.add_chunk(); } - build_stack.push( + build_stack.push_chunk_term( qualified_clause_to_query_term( loader, module_name, @@ -645,15 +671,15 @@ impl VariableClassifier { Term::Literal(_, Literal::Atom(module_name)), Term::Clause(_, name, terms), ) => { - if !ClauseType::is_inbuilt(name, terms.len()) { - state_stack.push(TraversalState::IncrChunkNum); + if update_chunk_data(self, name, terms.len()) { + build_stack.add_chunk(); } - for term in terms.iter() { - self.probe_body_term(term, term_loc); + for (arg_c, term) in terms.iter().enumerate() { + self.probe_body_term(arg_c + 1, terms.len(), term); } - build_stack.push( + build_stack.push_chunk_term( qualified_clause_to_query_term( loader, module_name, @@ -664,15 +690,17 @@ impl VariableClassifier { ); } (module_name, predicate_name) => { - state_stack.push(TraversalState::IncrChunkNum); + if update_chunk_data(self, atom!("call"), 2) { + build_stack.add_chunk(); + } - self.probe_body_term(&module_name, term_loc); - self.probe_body_term(&predicate_name, term_loc); + self.probe_body_term(1, 0, &module_name); + self.probe_body_term(2, 0, &predicate_name); terms.push(module_name); terms.push(predicate_name); - build_stack.push( + build_stack.push_chunk_term( clause_to_query_term( loader, atom!("call"), @@ -683,30 +711,22 @@ impl VariableClassifier { } } } - Term::Clause(cell, atom!("$call_with_inference_counting"), terms) if terms.len() == 1 => { - let term_loc = chunk_type.to_gen_context(self.current_chunk_num); - - for term in terms.iter() { - self.probe_body_term(term, term_loc); - } - + Term::Clause(_, atom!("$call_with_inference_counting"), mut terms) if terms.len() == 1 => { state_stack.push(TraversalState::ResetCallPolicy(self.call_policy)); - state_stack.push(TraversalState::Term(terms[0])); + state_stack.push(TraversalState::Term(terms.pop().unwrap())); self.call_policy = CallPolicy::Counted; } - Term::Clause(cell, name, terms) => { - if !ClauseType::is_inbuilt(name, terms.len()) { - state_stack.push(TraversalState::IncrChunkNum); + Term::Clause(_, name, terms) => { + if update_chunk_data(self, name, terms.len()) { + build_stack.add_chunk(); } - let term_loc = chunk_type.to_gen_context(self.current_chunk_num); - - for term in terms.iter() { - self.probe_body_term(term, term_loc); + for (arg_c, term) in terms.iter().enumerate() { + self.probe_body_term(arg_c + 1, terms.len(), term); } - build_stack.push( + build_stack.push_chunk_term( clause_to_query_term( loader, name, @@ -716,14 +736,24 @@ impl VariableClassifier { ); } Term::Literal(_, Literal::Atom(atom!("!")) | Literal::Char('!')) => { - build_stack.push(QueryTerm::GlobalCut); + if self.global_cut_var_num.is_none() { + self.global_cut_var_num = Some(self.var_num); + self.var_num += 1; + } + + self.probe_in_situ_var(self.global_cut_var_num.unwrap()); + + state_stack.push(TraversalState::Cut { + var_num: self.global_cut_var_num.unwrap(), + is_global: true, + }); } - Term::Literal(cell, Literal::Atom(name)) => { - if !ClauseType::is_inbuilt(name, 0) { - state_stack.push(TraversalState::IncrChunkNum); + Term::Literal(_, Literal::Atom(name)) => { + if update_chunk_data(self, name, 0) { + build_stack.add_chunk(); } - build_stack.push( + build_stack.push_chunk_term( clause_to_query_term( loader, name, @@ -732,7 +762,6 @@ impl VariableClassifier { ), ); } - _ => { return Err(CompilationError::InadmissibleQueryTerm); } @@ -746,61 +775,76 @@ impl VariableClassifier { } impl BranchMap { - pub fn separate_and_classify_variables(&mut self, mut var_num: usize) -> VarData { + pub fn separate_and_classify_variables( + &mut self, + var_num: usize, + global_cut_var_num: Option, + current_chunk_num: usize, + ) -> VarData { let mut var_data = VarData { - records: vec![VarRecord::default(); self.len()], - fixtures: VariableFixtures::new(), + records: VariableRecords::new(var_num), + global_cut_var_num, + allocates: current_chunk_num > 0, }; for (var, branches) in self.iter_mut() { - for branch in branches.iter_mut() { - let mut num_occurrences = 0; - - let idx = if let Var::Generated(var_num) = var { - *var_num + let (mut var_num, var_num_incr) = + if let Var::InSitu(var_num) = *var.borrow() { + (var_num, false) } else { - var_num += 1; - var_num - 1 + (var_data.records.len(), true) }; - var_data.records[idx].classification = - if branch.chunks.len() > 1 { - VarClassification::Perm - } else { - branch.chunks - .first() - .map(|chunk| if chunk.vars.len() > 1 { - VarClassification::Temp - } else { - VarClassification::Void - }) - .unwrap_or(VarClassification::Void) - }; + for branch in branches.iter_mut() { + if var_num_incr { + var_num = var_data.records.len(); + var_data.records.push(VariableRecord::default()); + } - var_data.records[idx].chunk_occurrences.reserve(branch.chunks.len()); + if branch.chunks.len() <= 1 { // true iff var is a temporary variable. + debug_assert_eq!(branch.chunks.len(), 1); - for chunk in branch.chunks.iter_mut() { - var_data.records[idx].num_occurrences += chunk.vars.len(); + let chunk = &mut branch.chunks[0]; + let mut temp_var_data = TempVarData::new(); - if let VarClassification::Temp = classification { - for var_info in chunk.vars.iter_mut() { - var_info.var_ptr.set(Var::Generated(var_num)); - var_data.fixtures.mark_temp_var(&var_info); - } - } else { - for var_info in chunk.vars.iter_mut() { - var_info.var_ptr.set(Var::Generated(var_num)); + for var_info in chunk.vars.iter_mut() { + if var_info.lvl == Level::Shallow { + let term_loc = var_info.chunk_type.to_gen_context(chunk.chunk_num); + temp_var_data.use_set.insert((term_loc, var_info.classify_info.arg_c)); } } - var_data.records[idx].chunk_occurrences.push(chunk.chunk_num); + var_data.records[var_num].allocation = VarAlloc::Temp { + term_loc: chunk.term_loc, + temp_reg: 0, + temp_var_data, + safety: VarSafetyStatus::Needed, + to_perm_var_num: None, + }; + } // else VarAlloc is already a Perm variant, as it's the default. + + for chunk in branch.chunks.iter_mut() { + var_data.records[var_num].num_occurrences += chunk.vars.len(); + + for var_info in chunk.vars.iter_mut() { + var_info.var_ptr.set(Var::Generated(var_num)); + } } } } - debug_assert_eq!(var_data.records.len(), var_num); + // debug_assert_eq!(var_data.records.len(), var_num); - var_data.fixtures.populate_restricting_sets(); + var_data.records.populate_restricting_sets(); var_data } } + +#[cfg(test)] +mod tests { + #[test] + fn disjunct_compilation() { + let mut wam = MachineState::new(); + let mut op_dir = default_op_dir(); + } +} diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 92eca80f..1d310bcd 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -1152,6 +1152,16 @@ impl Machine { self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(b0 as i64)); self.machine_st.p += 1; } + &Instruction::GetPrevLevel(r) => { + let prev_b = self.machine_st.stack.index_or_frame(self.machine_st.b).prelude.b; + + self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(prev_b as i64)); + self.machine_st.p += 1; + } + &Instruction::GetCutPoint(r) => { + self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(self.machine_st.b as i64)); + self.machine_st.p += 1; + } &Instruction::Cut(r) => { let value = self.machine_st[r]; self.machine_st.cut_body(value); @@ -1170,7 +1180,7 @@ impl Machine { &Instruction::Allocate(num_cells) => { self.machine_st.allocate(num_cells); } - &Instruction::DefaultCallAcyclicTerm(_) => { + &Instruction::DefaultCallAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1179,7 +1189,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteAcyclicTerm(_) => { + &Instruction::DefaultExecuteAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1188,23 +1198,23 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallArg(_) => { + &Instruction::DefaultCallArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteArg(_) => { + &Instruction::DefaultExecuteArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::DefaultCallCompare(_) => { + &Instruction::DefaultCallCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteCompare(_) => { + &Instruction::DefaultExecuteCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::DefaultCallTermGreaterThan(_) => { + &Instruction::DefaultCallTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1214,7 +1224,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteTermGreaterThan(_) => { + &Instruction::DefaultExecuteTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1224,7 +1234,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultCallTermLessThan(_) => { + &Instruction::DefaultCallTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1234,7 +1244,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteTermLessThan(_) => { + &Instruction::DefaultExecuteTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1244,7 +1254,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultCallTermGreaterThanOrEqual(_) => { + &Instruction::DefaultCallTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1257,7 +1267,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteTermGreaterThanOrEqual(_) => { + &Instruction::DefaultExecuteTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1270,7 +1280,7 @@ impl Machine { } } } - &Instruction::DefaultCallTermLessThanOrEqual(_) => { + &Instruction::DefaultCallTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1283,7 +1293,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteTermLessThanOrEqual(_) => { + &Instruction::DefaultExecuteTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1296,11 +1306,11 @@ impl Machine { } } } - &Instruction::DefaultCallRead(_) => { + &Instruction::DefaultCallRead => { try_or_throw!(self.machine_st, self.read()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteRead(_) => { + &Instruction::DefaultExecuteRead => { try_or_throw!(self.machine_st, self.read()); if self.machine_st.fail { @@ -1309,11 +1319,11 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallCopyTerm(_) => { + &Instruction::DefaultCallCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteCopyTerm(_) => { + &Instruction::DefaultExecuteCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); if self.machine_st.fail { @@ -1322,7 +1332,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallTermEqual(_) => { + &Instruction::DefaultCallTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1332,7 +1342,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteTermEqual(_) => { + &Instruction::DefaultExecuteTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1342,26 +1352,26 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallGround(_) => { + &Instruction::DefaultCallGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteGround(_) => { + &Instruction::DefaultExecuteGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallFunctor(_) => { + &Instruction::DefaultCallFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteFunctor(_) => { + &Instruction::DefaultExecuteFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); if self.machine_st.fail { @@ -1370,7 +1380,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallTermNotEqual(_) => { + &Instruction::DefaultCallTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1380,7 +1390,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteTermNotEqual(_) => { + &Instruction::DefaultExecuteTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1390,19 +1400,19 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallSort(_) => { + &Instruction::DefaultCallSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteSort(_) => { + &Instruction::DefaultExecuteSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::DefaultCallKeySort(_) => { + &Instruction::DefaultCallKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteKeySort(_) => { + &Instruction::DefaultExecuteKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); if self.machine_st.fail { @@ -1411,15 +1421,15 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallIs(r, at, _) => { + &Instruction::DefaultCallIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteIs(r, at, _) => { + &Instruction::DefaultExecuteIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallAcyclicTerm(_) => { + &Instruction::CallAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1433,7 +1443,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteAcyclicTerm(_) => { + &Instruction::ExecuteAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1447,7 +1457,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallArg(_) => { + &Instruction::CallArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); if self.machine_st.fail { @@ -1461,7 +1471,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteArg(_) => { + &Instruction::ExecuteArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); if self.machine_st.fail { @@ -1475,7 +1485,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallCompare(_) => { + &Instruction::CallCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); if self.machine_st.fail { @@ -1489,7 +1499,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteCompare(_) => { + &Instruction::ExecuteCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); if self.machine_st.fail { @@ -1503,7 +1513,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallTermGreaterThan(_) => { + &Instruction::CallTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1518,7 +1528,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::ExecuteTermGreaterThan(_) => { + &Instruction::ExecuteTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1533,7 +1543,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallTermLessThan(_) => { + &Instruction::CallTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1548,7 +1558,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::ExecuteTermLessThan(_) => { + &Instruction::ExecuteTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1563,7 +1573,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallTermGreaterThanOrEqual(_) => { + &Instruction::CallTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1581,7 +1591,7 @@ impl Machine { } } } - &Instruction::ExecuteTermGreaterThanOrEqual(_) => { + &Instruction::ExecuteTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1599,7 +1609,7 @@ impl Machine { } } } - &Instruction::CallTermLessThanOrEqual(_) => { + &Instruction::CallTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1617,7 +1627,7 @@ impl Machine { } } } - &Instruction::ExecuteTermLessThanOrEqual(_) => { + &Instruction::ExecuteTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1635,7 +1645,7 @@ impl Machine { } } } - &Instruction::CallRead(_) => { + &Instruction::CallRead => { try_or_throw!(self.machine_st, self.read()); if self.machine_st.fail { @@ -1649,7 +1659,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteRead(_) => { + &Instruction::ExecuteRead => { try_or_throw!(self.machine_st, self.read()); if self.machine_st.fail { @@ -1663,7 +1673,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallCopyTerm(_) => { + &Instruction::CallCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); if self.machine_st.fail { @@ -1677,7 +1687,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteCopyTerm(_) => { + &Instruction::ExecuteCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); if self.machine_st.fail { @@ -1691,7 +1701,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallTermEqual(_) => { + &Instruction::CallTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1706,7 +1716,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteTermEqual(_) => { + &Instruction::ExecuteTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1721,7 +1731,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallGround(_) => { + &Instruction::CallGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { @@ -1733,7 +1743,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteGround(_) => { + &Instruction::ExecuteGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { @@ -1745,7 +1755,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallFunctor(_) => { + &Instruction::CallFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); if self.machine_st.fail { @@ -1759,7 +1769,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteFunctor(_) => { + &Instruction::ExecuteFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); if self.machine_st.fail { @@ -1773,7 +1783,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallTermNotEqual(_) => { + &Instruction::CallTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1788,7 +1798,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteTermNotEqual(_) => { + &Instruction::ExecuteTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1803,7 +1813,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallSort(_) => { + &Instruction::CallSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); if self.machine_st.fail { @@ -1817,7 +1827,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteSort(_) => { + &Instruction::ExecuteSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); if self.machine_st.fail { @@ -1831,7 +1841,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallKeySort(_) => { + &Instruction::CallKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); if self.machine_st.fail { @@ -1845,7 +1855,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteKeySort(_) => { + &Instruction::ExecuteKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); if self.machine_st.fail { @@ -1859,7 +1869,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallIs(r, at, _) => { + &Instruction::CallIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); if self.machine_st.fail { @@ -1873,7 +1883,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteIs(r, at, _) => { + &Instruction::ExecuteIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); if self.machine_st.fail { @@ -1887,7 +1897,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallN(arity, _) => { + &Instruction::CallN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1910,7 +1920,7 @@ impl Machine { ); } } - &Instruction::ExecuteN(arity, _) => { + &Instruction::ExecuteN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1933,7 +1943,7 @@ impl Machine { ); } } - &Instruction::DefaultCallN(arity, _) => { + &Instruction::DefaultCallN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1951,7 +1961,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteN(arity, _) => { + &Instruction::DefaultExecuteN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1969,7 +1979,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -1987,7 +1997,7 @@ impl Machine { } } } - &Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2005,7 +2015,7 @@ impl Machine { } } } - &Instruction::CallNumberEqual(ref at_1, ref at_2, _) => { + &Instruction::CallNumberEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2023,7 +2033,7 @@ impl Machine { } } } - &Instruction::ExecuteNumberEqual(ref at_1, ref at_2, _) => { + &Instruction::ExecuteNumberEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2041,7 +2051,7 @@ impl Machine { } } } - &Instruction::CallNumberNotEqual(ref at_1, ref at_2, _) => { + &Instruction::CallNumberNotEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2059,7 +2069,7 @@ impl Machine { } } } - &Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2, _) => { + &Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2077,7 +2087,7 @@ impl Machine { } } } - &Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2095,7 +2105,7 @@ impl Machine { } } } - &Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2113,7 +2123,7 @@ impl Machine { } } } - &Instruction::CallNumberGreaterThan(ref at_1, ref at_2, _) => { + &Instruction::CallNumberGreaterThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2131,7 +2141,7 @@ impl Machine { } } } - &Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2, _) => { + &Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2149,7 +2159,7 @@ impl Machine { } } } - &Instruction::CallNumberLessThan(ref at_1, ref at_2, _) => { + &Instruction::CallNumberLessThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2167,7 +2177,7 @@ impl Machine { } } } - &Instruction::ExecuteNumberLessThan(ref at_1, ref at_2, _) => { + &Instruction::ExecuteNumberLessThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2185,7 +2195,7 @@ impl Machine { } } } - &Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2198,7 +2208,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2211,7 +2221,7 @@ impl Machine { } } } - &Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2224,7 +2234,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2237,7 +2247,7 @@ impl Machine { } } } - &Instruction::DefaultCallNumberEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultCallNumberEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2250,7 +2260,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2263,7 +2273,7 @@ impl Machine { } } } - &Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2276,7 +2286,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2, _) => { + &Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2289,7 +2299,7 @@ impl Machine { } } } - &Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2, _) => { + &Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2302,7 +2312,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2, _) => { + &Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2315,7 +2325,7 @@ impl Machine { } } } - &Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2, _) => { + &Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2328,7 +2338,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2, _) => { + &Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2) => { let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2342,7 +2352,7 @@ impl Machine { } } // - &Instruction::CallIsAtom(r, _) => { + &Instruction::CallIsAtom(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2371,7 +2381,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsAtom(r, _) => { + &Instruction::ExecuteIsAtom(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2400,7 +2410,7 @@ impl Machine { } ); } - &Instruction::CallIsAtomic(r, _) => { + &Instruction::CallIsAtomic(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2430,7 +2440,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsAtomic(r, _) => { + &Instruction::ExecuteIsAtomic(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2460,7 +2470,7 @@ impl Machine { } ); } - &Instruction::CallIsCompound(r, _) => { + &Instruction::CallIsCompound(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2491,7 +2501,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsCompound(r, _) => { + &Instruction::ExecuteIsCompound(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2522,7 +2532,7 @@ impl Machine { } ); } - &Instruction::CallIsInteger(r, _) => { + &Instruction::CallIsInteger(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2541,7 +2551,7 @@ impl Machine { } } } - &Instruction::ExecuteIsInteger(r, _) => { + &Instruction::ExecuteIsInteger(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2560,7 +2570,7 @@ impl Machine { } } } - &Instruction::CallIsNumber(r, _) => { + &Instruction::CallIsNumber(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2572,7 +2582,7 @@ impl Machine { } } } - &Instruction::ExecuteIsNumber(r, _) => { + &Instruction::ExecuteIsNumber(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2584,7 +2594,7 @@ impl Machine { } } } - &Instruction::CallIsRational(r, _) => { + &Instruction::CallIsRational(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2603,7 +2613,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsRational(r, _) => { + &Instruction::ExecuteIsRational(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2622,7 +2632,7 @@ impl Machine { } ); } - &Instruction::CallIsFloat(r, _) => { + &Instruction::CallIsFloat(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2634,7 +2644,7 @@ impl Machine { } } } - &Instruction::ExecuteIsFloat(r, _) => { + &Instruction::ExecuteIsFloat(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2646,7 +2656,7 @@ impl Machine { } } } - &Instruction::CallIsNonVar(r, _) => { + &Instruction::CallIsNonVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2660,7 +2670,7 @@ impl Machine { } } } - &Instruction::ExecuteIsNonVar(r, _) => { + &Instruction::ExecuteIsNonVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2674,7 +2684,7 @@ impl Machine { } } } - &Instruction::CallIsVar(r, _) => { + &Instruction::CallIsVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2688,7 +2698,7 @@ impl Machine { } } } - &Instruction::ExecuteIsVar(r, _) => { + &Instruction::ExecuteIsVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2702,7 +2712,7 @@ impl Machine { } } } - &Instruction::CallNamed(arity, name, ref idx, _) => { + &Instruction::CallNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2719,7 +2729,7 @@ impl Machine { ); } } - &Instruction::ExecuteNamed(arity, name, ref idx, _) => { + &Instruction::ExecuteNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2736,7 +2746,7 @@ impl Machine { ); } } - &Instruction::DefaultCallNamed(arity, name, ref idx, _) => { + &Instruction::DefaultCallNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2748,7 +2758,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteNamed(arity, name, ref idx, _) => { + &Instruction::DefaultExecuteNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2763,15 +2773,7 @@ impl Machine { &Instruction::Deallocate => { self.machine_st.deallocate() } - &Instruction::JmpByCall(arity, offset, _) => { - self.machine_st.num_of_args = arity; - self.machine_st.b0 = self.machine_st.b; - self.machine_st.cp = self.machine_st.p + 1; - self.machine_st.p += offset; - } - &Instruction::JmpByExecute(arity, offset, _) => { - self.machine_st.num_of_args = arity; - self.machine_st.b0 = self.machine_st.b; + &Instruction::JmpByCall(offset) => { self.machine_st.p += offset; } &Instruction::RevJmpBy(offset) => { @@ -3219,8 +3221,8 @@ impl Machine { self.machine_st.p += 1; } - &Instruction::PutUnsafeValue(n, arg) => { - let s = stack_loc!(AndFrame, self.machine_st.e, n); + &Instruction::PutUnsafeValue(perm_slot, arg) => { + let s = stack_loc!(AndFrame, self.machine_st.e, perm_slot); let addr = self.machine_st.store(self.machine_st.deref(stack_loc_as_cell!(s))); if addr.is_protected(self.machine_st.e) { @@ -3298,11 +3300,11 @@ impl Machine { self.machine_st.p += 1; } // - &Instruction::CallAtomChars(_) => { + &Instruction::CallAtomChars => { self.atom_chars(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteAtomChars(_) => { + &Instruction::ExecuteAtomChars => { self.atom_chars(); if self.machine_st.fail { @@ -3311,7 +3313,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallAtomCodes(_) => { + &Instruction::CallAtomCodes => { try_or_throw!(self.machine_st, self.atom_codes()); if self.machine_st.fail { @@ -3320,7 +3322,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteAtomCodes(_) => { + &Instruction::ExecuteAtomCodes => { try_or_throw!(self.machine_st, self.atom_codes()); if self.machine_st.fail { @@ -3329,237 +3331,237 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallAtomLength(_) => { + &Instruction::CallAtomLength => { self.atom_length(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteAtomLength(_) => { + &Instruction::ExecuteAtomLength => { self.atom_length(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallBindFromRegister(_) => { + &Instruction::CallBindFromRegister => { self.bind_from_register(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteBindFromRegister(_) => { + &Instruction::ExecuteBindFromRegister => { self.bind_from_register(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallContinuation(_) => { + &Instruction::CallContinuation => { try_or_throw!(self.machine_st, self.call_continuation(false)); } - &Instruction::ExecuteContinuation(_) => { + &Instruction::ExecuteContinuation => { try_or_throw!(self.machine_st, self.call_continuation(true)); } - &Instruction::CallCharCode(_) => { + &Instruction::CallCharCode => { try_or_throw!(self.machine_st, self.char_code()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharCode(_) => { + &Instruction::ExecuteCharCode => { try_or_throw!(self.machine_st, self.char_code()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCharType(_) => { + &Instruction::CallCharType => { self.char_type(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharType(_) => { + &Instruction::ExecuteCharType => { self.char_type(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCharsToNumber(_) => { + &Instruction::CallCharsToNumber => { try_or_throw!(self.machine_st, self.chars_to_number()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharsToNumber(_) => { + &Instruction::ExecuteCharsToNumber => { try_or_throw!(self.machine_st, self.chars_to_number()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCodesToNumber(_) => { + &Instruction::CallCodesToNumber => { try_or_throw!(self.machine_st, self.codes_to_number()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCodesToNumber(_) => { + &Instruction::ExecuteCodesToNumber => { try_or_throw!(self.machine_st, self.codes_to_number()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCopyTermWithoutAttrVars(_) => { + &Instruction::CallCopyTermWithoutAttrVars => { self.copy_term_without_attr_vars(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCopyTermWithoutAttrVars(_) => { + &Instruction::ExecuteCopyTermWithoutAttrVars => { self.copy_term_without_attr_vars(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCheckCutPoint(_) => { + &Instruction::CallCheckCutPoint => { self.check_cut_point(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCheckCutPoint(_) => { + &Instruction::ExecuteCheckCutPoint => { self.check_cut_point(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallClose(_) => { + &Instruction::CallClose => { try_or_throw!(self.machine_st, self.close()); self.machine_st.p += 1; } - &Instruction::ExecuteClose(_) => { + &Instruction::ExecuteClose => { try_or_throw!(self.machine_st, self.close()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallCopyToLiftedHeap(_) => { + &Instruction::CallCopyToLiftedHeap => { self.copy_to_lifted_heap(); self.machine_st.p += 1; } - &Instruction::ExecuteCopyToLiftedHeap(_) => { + &Instruction::ExecuteCopyToLiftedHeap => { self.copy_to_lifted_heap(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallCreatePartialString(_) => { + &Instruction::CallCreatePartialString => { self.create_partial_string(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCreatePartialString(_) => { + &Instruction::ExecuteCreatePartialString => { self.create_partial_string(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentHostname(_) => { + &Instruction::CallCurrentHostname => { self.current_hostname(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentHostname(_) => { + &Instruction::ExecuteCurrentHostname => { self.current_hostname(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentInput(_) => { + &Instruction::CallCurrentInput => { try_or_throw!(self.machine_st, self.current_input()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentInput(_) => { + &Instruction::ExecuteCurrentInput => { try_or_throw!(self.machine_st, self.current_input()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentOutput(_) => { + &Instruction::CallCurrentOutput => { try_or_throw!(self.machine_st, self.current_output()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentOutput(_) => { + &Instruction::ExecuteCurrentOutput => { try_or_throw!(self.machine_st, self.current_output()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDirectoryFiles(_) => { + &Instruction::CallDirectoryFiles => { try_or_throw!(self.machine_st, self.directory_files()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDirectoryFiles(_) => { + &Instruction::ExecuteDirectoryFiles => { try_or_throw!(self.machine_st, self.directory_files()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileSize(_) => { + &Instruction::CallFileSize => { self.file_size(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileSize(_) => { + &Instruction::ExecuteFileSize => { self.file_size(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileExists(_) => { + &Instruction::CallFileExists => { self.file_exists(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileExists(_) => { + &Instruction::ExecuteFileExists => { self.file_exists(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDirectoryExists(_) => { + &Instruction::CallDirectoryExists => { self.directory_exists(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDirectoryExists(_) => { + &Instruction::ExecuteDirectoryExists => { self.directory_exists(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDirectorySeparator(_) => { + &Instruction::CallDirectorySeparator => { self.directory_separator(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDirectorySeparator(_) => { + &Instruction::ExecuteDirectorySeparator => { self.directory_separator(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMakeDirectory(_) => { + &Instruction::CallMakeDirectory => { self.make_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMakeDirectory(_) => { + &Instruction::ExecuteMakeDirectory => { self.make_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMakeDirectoryPath(_) => { + &Instruction::CallMakeDirectoryPath => { self.make_directory_path(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMakeDirectoryPath(_) => { + &Instruction::ExecuteMakeDirectoryPath => { self.make_directory_path(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteFile(_) => { + &Instruction::CallDeleteFile => { self.delete_file(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeleteFile(_) => { + &Instruction::ExecuteDeleteFile => { self.delete_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallRenameFile(_) => { + &Instruction::CallRenameFile => { self.rename_file(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteRenameFile(_) => { + &Instruction::ExecuteRenameFile => { self.rename_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileCopy(_) => { + &Instruction::CallFileCopy => { self.file_copy(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileCopy(_) => { + &Instruction::ExecuteFileCopy => { self.file_copy(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallWorkingDirectory(_) => { + &Instruction::CallWorkingDirectory => { try_or_throw!(self.machine_st, self.working_directory()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWorkingDirectory(_) => { + &Instruction::ExecuteWorkingDirectory => { try_or_throw!(self.machine_st, self.working_directory()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteDirectory(_) => { + &Instruction::CallDeleteDirectory => { self.delete_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeleteDirectory(_) => { + &Instruction::ExecuteDeleteDirectory => { self.delete_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPathCanonical(_) => { + &Instruction::CallPathCanonical => { try_or_throw!(self.machine_st, self.path_canonical()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePathCanonical(_) => { + &Instruction::ExecutePathCanonical => { try_or_throw!(self.machine_st, self.path_canonical()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileTime(_) => { + &Instruction::CallFileTime => { self.file_time(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileTime(_) => { + &Instruction::ExecuteFileTime => { self.file_time(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDynamicModuleResolution(arity, _) => { + &Instruction::CallDynamicModuleResolution(arity) => { let (module_name, key) = try_or_throw!( self.machine_st, self.dynamic_module_resolution(arity - 2) @@ -3574,7 +3576,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::ExecuteDynamicModuleResolution(arity, _) => { + &Instruction::ExecuteDynamicModuleResolution(arity) => { let (module_name, key) = try_or_throw!( self.machine_st, self.dynamic_module_resolution(arity - 2) @@ -3589,428 +3591,428 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallFetchGlobalVar(_) => { + &Instruction::CallFetchGlobalVar => { self.fetch_global_var(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFetchGlobalVar(_) => { + &Instruction::ExecuteFetchGlobalVar => { self.fetch_global_var(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFirstStream(_) => { + &Instruction::CallFirstStream => { self.first_stream(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFirstStream(_) => { + &Instruction::ExecuteFirstStream => { self.first_stream(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFlushOutput(_) => { + &Instruction::CallFlushOutput => { try_or_throw!(self.machine_st, self.flush_output()); self.machine_st.p += 1; } - &Instruction::ExecuteFlushOutput(_) => { + &Instruction::ExecuteFlushOutput => { try_or_throw!(self.machine_st, self.flush_output()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallGetByte(_) => { + &Instruction::CallGetByte => { try_or_throw!(self.machine_st, self.get_byte()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetByte(_) => { + &Instruction::ExecuteGetByte => { try_or_throw!(self.machine_st, self.get_byte()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetChar(_) => { + &Instruction::CallGetChar => { try_or_throw!(self.machine_st, self.get_char()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetChar(_) => { + &Instruction::ExecuteGetChar => { try_or_throw!(self.machine_st, self.get_char()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetNChars(_) => { + &Instruction::CallGetNChars => { try_or_throw!(self.machine_st, self.get_n_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetNChars(_) => { + &Instruction::ExecuteGetNChars => { try_or_throw!(self.machine_st, self.get_n_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetCode(_) => { + &Instruction::CallGetCode => { try_or_throw!(self.machine_st, self.get_code()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetCode(_) => { + &Instruction::ExecuteGetCode => { try_or_throw!(self.machine_st, self.get_code()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetSingleChar(_) => { + &Instruction::CallGetSingleChar => { try_or_throw!(self.machine_st, self.get_single_char()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetSingleChar(_) => { + &Instruction::ExecuteGetSingleChar => { try_or_throw!(self.machine_st, self.get_single_char()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff(_) => { + &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff => { self.truncate_if_no_lifted_heap_growth_diff(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff(_) => { + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff => { self.truncate_if_no_lifted_heap_growth_diff(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTruncateIfNoLiftedHeapGrowth(_) => { + &Instruction::CallTruncateIfNoLiftedHeapGrowth => { self.truncate_if_no_lifted_heap_growth(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth(_) => { + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth => { self.truncate_if_no_lifted_heap_growth(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetAttributedVariableList(_) => { + &Instruction::CallGetAttributedVariableList => { self.get_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetAttributedVariableList(_) => { + &Instruction::ExecuteGetAttributedVariableList => { self.get_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetAttrVarQueueDelimiter(_) => { + &Instruction::CallGetAttrVarQueueDelimiter => { self.get_attr_var_queue_delimiter(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetAttrVarQueueDelimiter(_) => { + &Instruction::ExecuteGetAttrVarQueueDelimiter => { self.get_attr_var_queue_delimiter(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetAttrVarQueueBeyond(_) => { + &Instruction::CallGetAttrVarQueueBeyond => { self.get_attr_var_queue_beyond(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetAttrVarQueueBeyond(_) => { + &Instruction::ExecuteGetAttrVarQueueBeyond => { self.get_attr_var_queue_beyond(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetBValue(_) => { + &Instruction::CallGetBValue => { self.get_b_value(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetBValue(_) => { + &Instruction::ExecuteGetBValue => { self.get_b_value(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetContinuationChunk(_) => { + &Instruction::CallGetContinuationChunk => { self.get_continuation_chunk(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetContinuationChunk(_) => { + &Instruction::ExecuteGetContinuationChunk => { self.get_continuation_chunk(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLookupDBRef(_) => { + &Instruction::CallLookupDBRef => { self.lookup_db_ref(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLookupDBRef(_) => { + &Instruction::ExecuteLookupDBRef => { self.lookup_db_ref(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetNextOpDBRef(_) => { + &Instruction::CallGetNextOpDBRef => { self.get_next_op_db_ref(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetNextOpDBRef(_) => { + &Instruction::ExecuteGetNextOpDBRef => { self.get_next_op_db_ref(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallIsPartialString(_) => { + &Instruction::CallIsPartialString => { self.is_partial_string(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsPartialString(_) => { + &Instruction::ExecuteIsPartialString => { self.is_partial_string(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHalt(_) => { + &Instruction::CallHalt => { self.halt(); self.machine_st.p += 1; } - &Instruction::ExecuteHalt(_) => { + &Instruction::ExecuteHalt => { self.halt(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallGetLiftedHeapFromOffset(_) => { + &Instruction::CallGetLiftedHeapFromOffset => { self.get_lifted_heap_from_offset(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetLiftedHeapFromOffset(_) => { + &Instruction::ExecuteGetLiftedHeapFromOffset => { self.get_lifted_heap_from_offset(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetLiftedHeapFromOffsetDiff(_) => { + &Instruction::CallGetLiftedHeapFromOffsetDiff => { self.get_lifted_heap_from_offset_diff(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetLiftedHeapFromOffsetDiff(_) => { + &Instruction::ExecuteGetLiftedHeapFromOffsetDiff => { self.get_lifted_heap_from_offset_diff(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetSCCCleaner(_) => { + &Instruction::CallGetSCCCleaner => { self.get_scc_cleaner(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetSCCCleaner(_) => { + &Instruction::ExecuteGetSCCCleaner => { self.get_scc_cleaner(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHeadIsDynamic(_) => { + &Instruction::CallHeadIsDynamic => { self.head_is_dynamic(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHeadIsDynamic(_) => { + &Instruction::ExecuteHeadIsDynamic => { self.head_is_dynamic(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInstallSCCCleaner(_) => { + &Instruction::CallInstallSCCCleaner => { self.install_scc_cleaner(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInstallSCCCleaner(_) => { + &Instruction::ExecuteInstallSCCCleaner => { self.install_scc_cleaner(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInstallInferenceCounter(_) => { + &Instruction::CallInstallInferenceCounter => { try_or_throw!(self.machine_st, self.install_inference_counter()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInstallInferenceCounter(_) => { + &Instruction::ExecuteInstallInferenceCounter => { try_or_throw!(self.machine_st, self.install_inference_counter()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLiftedHeapLength(_) => { + &Instruction::CallLiftedHeapLength => { self.lifted_heap_length(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLiftedHeapLength(_) => { + &Instruction::ExecuteLiftedHeapLength => { self.lifted_heap_length(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadLibraryAsStream(_) => { + &Instruction::CallLoadLibraryAsStream => { try_or_throw!(self.machine_st, self.load_library_as_stream()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadLibraryAsStream(_) => { + &Instruction::ExecuteLoadLibraryAsStream => { try_or_throw!(self.machine_st, self.load_library_as_stream()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallModuleExists(_) => { + &Instruction::CallModuleExists => { self.module_exists(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteModuleExists(_) => { + &Instruction::ExecuteModuleExists => { self.module_exists(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNextEP(_) => { + &Instruction::CallNextEP => { self.next_ep(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNextEP(_) => { + &Instruction::ExecuteNextEP => { self.next_ep(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNoSuchPredicate(_) => { + &Instruction::CallNoSuchPredicate => { try_or_throw!(self.machine_st, self.no_such_predicate()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNoSuchPredicate(_) => { + &Instruction::ExecuteNoSuchPredicate => { try_or_throw!(self.machine_st, self.no_such_predicate()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNumberToChars(_) => { + &Instruction::CallNumberToChars => { self.number_to_chars(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNumberToChars(_) => { + &Instruction::ExecuteNumberToChars => { self.number_to_chars(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNumberToCodes(_) => { + &Instruction::CallNumberToCodes => { self.number_to_codes(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNumberToCodes(_) => { + &Instruction::ExecuteNumberToCodes => { self.number_to_codes(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallOpDeclaration(_) => { + &Instruction::CallOpDeclaration => { try_or_throw!(self.machine_st, self.op_declaration()); self.machine_st.p += 1; } - &Instruction::ExecuteOpDeclaration(_) => { + &Instruction::ExecuteOpDeclaration => { try_or_throw!(self.machine_st, self.op_declaration()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallOpen(_) => { + &Instruction::CallOpen => { try_or_throw!(self.machine_st, self.open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteOpen(_) => { + &Instruction::ExecuteOpen => { try_or_throw!(self.machine_st, self.open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetStreamOptions(_) => { + &Instruction::CallSetStreamOptions => { try_or_throw!(self.machine_st, self.set_stream_options()); self.machine_st.p += 1; } - &Instruction::ExecuteSetStreamOptions(_) => { + &Instruction::ExecuteSetStreamOptions => { try_or_throw!(self.machine_st, self.set_stream_options()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallNextStream(_) => { + &Instruction::CallNextStream => { self.next_stream(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNextStream(_) => { + &Instruction::ExecuteNextStream => { self.next_stream(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPartialStringTail(_) => { + &Instruction::CallPartialStringTail => { self.partial_string_tail(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePartialStringTail(_) => { + &Instruction::ExecutePartialStringTail => { self.partial_string_tail(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPeekByte(_) => { + &Instruction::CallPeekByte => { try_or_throw!(self.machine_st, self.peek_byte()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePeekByte(_) => { + &Instruction::ExecutePeekByte => { try_or_throw!(self.machine_st, self.peek_byte()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPeekChar(_) => { + &Instruction::CallPeekChar => { try_or_throw!(self.machine_st, self.peek_char()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePeekChar(_) => { + &Instruction::ExecutePeekChar => { try_or_throw!(self.machine_st, self.peek_char()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPeekCode(_) => { + &Instruction::CallPeekCode => { try_or_throw!(self.machine_st, self.peek_code()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePeekCode(_) => { + &Instruction::ExecutePeekCode => { try_or_throw!(self.machine_st, self.peek_code()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPointsToContinuationResetMarker(_) => { + &Instruction::CallPointsToContinuationResetMarker => { self.points_to_continuation_reset_marker(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePointsToContinuationResetMarker(_) => { + &Instruction::ExecutePointsToContinuationResetMarker => { self.points_to_continuation_reset_marker(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPutByte(_) => { + &Instruction::CallPutByte => { try_or_throw!(self.machine_st, self.put_byte()); self.machine_st.p += 1; } - &Instruction::ExecutePutByte(_) => { + &Instruction::ExecutePutByte => { try_or_throw!(self.machine_st, self.put_byte()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPutChar(_) => { + &Instruction::CallPutChar => { try_or_throw!(self.machine_st, self.put_char()); self.machine_st.p += 1; } - &Instruction::ExecutePutChar(_) => { + &Instruction::ExecutePutChar => { try_or_throw!(self.machine_st, self.put_char()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPutChars(_) => { + &Instruction::CallPutChars => { try_or_throw!(self.machine_st, self.put_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePutChars(_) => { + &Instruction::ExecutePutChars => { try_or_throw!(self.machine_st, self.put_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPutCode(_) => { + &Instruction::CallPutCode => { try_or_throw!(self.machine_st, self.put_code()); self.machine_st.p += 1; } - &Instruction::ExecutePutCode(_) => { + &Instruction::ExecutePutCode => { try_or_throw!(self.machine_st, self.put_code()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallReadQueryTerm(_) => { + &Instruction::CallReadQueryTerm => { try_or_throw!(self.machine_st, self.read_query_term()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteReadQueryTerm(_) => { + &Instruction::ExecuteReadQueryTerm => { try_or_throw!(self.machine_st, self.read_query_term()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallReadTerm(_) => { + &Instruction::CallReadTerm => { try_or_throw!(self.machine_st, self.read_term()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteReadTerm(_) => { + &Instruction::ExecuteReadTerm => { try_or_throw!(self.machine_st, self.read_term()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallRedoAttrVarBinding(_) => { + &Instruction::CallRedoAttrVarBinding => { self.redo_attr_var_binding(); self.machine_st.p += 1; } - &Instruction::ExecuteRedoAttrVarBinding(_) => { + &Instruction::ExecuteRedoAttrVarBinding => { self.redo_attr_var_binding(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRemoveCallPolicyCheck(_) => { + &Instruction::CallRemoveCallPolicyCheck => { self.remove_call_policy_check(); self.machine_st.p += 1; } - &Instruction::ExecuteRemoveCallPolicyCheck(_) => { + &Instruction::ExecuteRemoveCallPolicyCheck => { self.remove_call_policy_check(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRemoveInferenceCounter(_) => { + &Instruction::CallRemoveInferenceCounter => { self.remove_inference_counter(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteRemoveInferenceCounter(_) => { + &Instruction::ExecuteRemoveInferenceCounter => { self.remove_inference_counter(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallResetContinuationMarker(_) => { + &Instruction::CallResetContinuationMarker => { self.reset_continuation_marker(); self.machine_st.p += 1; } - &Instruction::ExecuteResetContinuationMarker(_) => { + &Instruction::ExecuteResetContinuationMarker => { self.reset_continuation_marker(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRestoreCutPolicy(_) => { + &Instruction::CallRestoreCutPolicy => { self.restore_cut_policy(); self.machine_st.p += 1; } - &Instruction::ExecuteRestoreCutPolicy(_) => { + &Instruction::ExecuteRestoreCutPolicy => { self.restore_cut_policy(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetCutPoint(r, _) => { + &Instruction::CallSetCutPoint(r) => { if !self.set_cut_point(r) { step_or_fail!(self, self.machine_st.p += 1); } } - &Instruction::ExecuteSetCutPoint(r, _) => { + &Instruction::ExecuteSetCutPoint(r) => { let cp = self.machine_st.cp; if !self.set_cut_point(r) { @@ -4023,962 +4025,962 @@ impl Machine { self.machine_st.cp = cp; } } - &Instruction::CallSetInput(_) => { + &Instruction::CallSetInput => { try_or_throw!(self.machine_st, self.set_input()); self.machine_st.p += 1; } - &Instruction::ExecuteSetInput(_) => { + &Instruction::ExecuteSetInput => { try_or_throw!(self.machine_st, self.set_input()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetOutput(_) => { + &Instruction::CallSetOutput => { try_or_throw!(self.machine_st, self.set_output()); self.machine_st.p += 1; } - &Instruction::ExecuteSetOutput(_) => { + &Instruction::ExecuteSetOutput => { try_or_throw!(self.machine_st, self.set_output()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallStoreBacktrackableGlobalVar(_) => { + &Instruction::CallStoreBacktrackableGlobalVar => { self.store_backtrackable_global_var(); self.machine_st.p += 1; } - &Instruction::ExecuteStoreBacktrackableGlobalVar(_) => { + &Instruction::ExecuteStoreBacktrackableGlobalVar => { self.store_backtrackable_global_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallStoreGlobalVar(_) => { + &Instruction::CallStoreGlobalVar => { self.store_global_var(); self.machine_st.p += 1; } - &Instruction::ExecuteStoreGlobalVar(_) => { + &Instruction::ExecuteStoreGlobalVar => { self.store_global_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallStreamProperty(_) => { + &Instruction::CallStreamProperty => { try_or_throw!(self.machine_st, self.stream_property()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteStreamProperty(_) => { + &Instruction::ExecuteStreamProperty => { try_or_throw!(self.machine_st, self.stream_property()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetStreamPosition(_) => { + &Instruction::CallSetStreamPosition => { try_or_throw!(self.machine_st, self.set_stream_position()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetStreamPosition(_) => { + &Instruction::ExecuteSetStreamPosition => { try_or_throw!(self.machine_st, self.set_stream_position()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInferenceLevel(_) => { + &Instruction::CallInferenceLevel => { self.inference_level(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInferenceLevel(_) => { + &Instruction::ExecuteInferenceLevel => { self.inference_level(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCleanUpBlock(_) => { + &Instruction::CallCleanUpBlock => { self.clean_up_block(); self.machine_st.p += 1; } - &Instruction::ExecuteCleanUpBlock(_) => { + &Instruction::ExecuteCleanUpBlock => { self.clean_up_block(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallFail(_) | &Instruction::ExecuteFail(_) => { + &Instruction::CallFail | &Instruction::ExecuteFail => { self.machine_st.backtrack(); } - &Instruction::CallGetBall(_) => { + &Instruction::CallGetBall => { self.get_ball(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetBall(_) => { + &Instruction::ExecuteGetBall => { self.get_ball(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetCurrentBlock(_) => { + &Instruction::CallGetCurrentBlock => { self.get_current_block(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetCurrentBlock(_) => { + &Instruction::ExecuteGetCurrentBlock => { self.get_current_block(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetCutPoint(_) => { + &Instruction::CallGetCutPoint => { self.get_cut_point(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetCutPoint(_) => { + &Instruction::ExecuteGetCutPoint => { self.get_cut_point(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetDoubleQuotes(_) => { + &Instruction::CallGetDoubleQuotes => { self.get_double_quotes(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetDoubleQuotes(_) => { + &Instruction::ExecuteGetDoubleQuotes => { self.get_double_quotes(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInstallNewBlock(_) => { + &Instruction::CallInstallNewBlock => { self.machine_st.install_new_block(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInstallNewBlock(_) => { + &Instruction::ExecuteInstallNewBlock => { self.machine_st.install_new_block(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMaybe(_) => { + &Instruction::CallMaybe => { self.maybe(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMaybe(_) => { + &Instruction::ExecuteMaybe => { self.maybe(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCpuNow(_) => { + &Instruction::CallCpuNow => { self.cpu_now(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCpuNow(_) => { + &Instruction::ExecuteCpuNow => { self.cpu_now(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeterministicLengthRundown(_) => { + &Instruction::CallDeterministicLengthRundown => { try_or_throw!(self.machine_st, self.det_length_rundown()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeterministicLengthRundown(_) => { + &Instruction::ExecuteDeterministicLengthRundown => { try_or_throw!(self.machine_st, self.det_length_rundown()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpOpen(_) => { + &Instruction::CallHttpOpen => { try_or_throw!(self.machine_st, self.http_open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpOpen(_) => { + &Instruction::ExecuteHttpOpen => { try_or_throw!(self.machine_st, self.http_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpListen(_) => { + &Instruction::CallHttpListen => { try_or_throw!(self.machine_st, self.http_listen()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpListen(_) => { + &Instruction::ExecuteHttpListen => { try_or_throw!(self.machine_st, self.http_listen()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpAccept(_) => { + &Instruction::CallHttpAccept => { try_or_throw!(self.machine_st, self.http_accept()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpAccept(_) => { + &Instruction::ExecuteHttpAccept => { try_or_throw!(self.machine_st, self.http_accept()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpAnswer(_) => { + &Instruction::CallHttpAnswer => { try_or_throw!(self.machine_st, self.http_answer()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpAnswer(_) => { + &Instruction::ExecuteHttpAnswer => { try_or_throw!(self.machine_st, self.http_answer()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadForeignLib(_) => { + &Instruction::CallLoadForeignLib => { try_or_throw!(self.machine_st, self.load_foreign_lib()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadForeignLib(_) => { + &Instruction::ExecuteLoadForeignLib => { try_or_throw!(self.machine_st, self.load_foreign_lib()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallForeignCall(_) => { + &Instruction::CallForeignCall => { try_or_throw!(self.machine_st, self.foreign_call()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteForeignCall(_) => { + &Instruction::ExecuteForeignCall => { try_or_throw!(self.machine_st, self.foreign_call()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDefineForeignStruct(_) => { + &Instruction::CallDefineForeignStruct => { try_or_throw!(self.machine_st, self.define_foreign_struct()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDefineForeignStruct(_) => { + &Instruction::ExecuteDefineForeignStruct => { try_or_throw!(self.machine_st, self.define_foreign_struct()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentTime(_) => { + &Instruction::CallCurrentTime => { self.current_time(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentTime(_) => { + &Instruction::ExecuteCurrentTime => { self.current_time(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallQuotedToken(_) => { + &Instruction::CallQuotedToken => { self.quoted_token(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteQuotedToken(_) => { + &Instruction::ExecuteQuotedToken => { self.quoted_token(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallReadTermFromChars(_) => { + &Instruction::CallReadTermFromChars => { try_or_throw!(self.machine_st, self.read_term_from_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteReadTermFromChars(_) => { + &Instruction::ExecuteReadTermFromChars => { try_or_throw!(self.machine_st, self.read_term_from_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallResetBlock(_) => { + &Instruction::CallResetBlock => { self.reset_block(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteResetBlock(_) => { + &Instruction::ExecuteResetBlock => { self.reset_block(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallReturnFromVerifyAttr(_) | - &Instruction::ExecuteReturnFromVerifyAttr(_) => { + &Instruction::CallReturnFromVerifyAttr | + &Instruction::ExecuteReturnFromVerifyAttr => { self.return_from_verify_attr(); } - &Instruction::CallSetBall(_) => { + &Instruction::CallSetBall => { self.set_ball(); self.machine_st.p += 1; } - &Instruction::ExecuteSetBall(_) => { + &Instruction::ExecuteSetBall => { self.set_ball(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPushBallStack(_) => { + &Instruction::CallPushBallStack => { self.push_ball_stack(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePushBallStack(_) => { + &Instruction::ExecutePushBallStack => { self.push_ball_stack(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPopBallStack(_) => { + &Instruction::CallPopBallStack => { self.pop_ball_stack(); self.machine_st.p += 1; } - &Instruction::ExecutePopBallStack(_) => { + &Instruction::ExecutePopBallStack => { self.pop_ball_stack(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPopFromBallStack(_) => { + &Instruction::CallPopFromBallStack => { self.pop_from_ball_stack(); self.machine_st.p += 1; } - &Instruction::ExecutePopFromBallStack(_) => { + &Instruction::ExecutePopFromBallStack => { self.pop_from_ball_stack(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetCutPointByDefault(r, _) => { + &Instruction::CallSetCutPointByDefault(r) => { self.set_cut_point_by_default(r); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetCutPointByDefault(r, _) => { + &Instruction::ExecuteSetCutPointByDefault(r) => { self.set_cut_point_by_default(r); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetDoubleQuotes(_) => { + &Instruction::CallSetDoubleQuotes => { self.set_double_quotes(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetDoubleQuotes(_) => { + &Instruction::ExecuteSetDoubleQuotes => { self.set_double_quotes(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetSeed(_) => { + &Instruction::CallSetSeed => { self.set_seed(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetSeed(_) => { + &Instruction::ExecuteSetSeed => { self.set_seed(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSkipMaxList(_) => { + &Instruction::CallSkipMaxList => { try_or_throw!(self.machine_st, self.machine_st.skip_max_list()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSkipMaxList(_) => { + &Instruction::ExecuteSkipMaxList => { try_or_throw!(self.machine_st, self.machine_st.skip_max_list()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSleep(_) => { + &Instruction::CallSleep => { self.sleep(); self.machine_st.p += 1; } - &Instruction::ExecuteSleep(_) => { + &Instruction::ExecuteSleep => { self.sleep(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSocketClientOpen(_) => { + &Instruction::CallSocketClientOpen => { try_or_throw!(self.machine_st, self.socket_client_open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSocketClientOpen(_) => { + &Instruction::ExecuteSocketClientOpen => { try_or_throw!(self.machine_st, self.socket_client_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSocketServerOpen(_) => { + &Instruction::CallSocketServerOpen => { try_or_throw!(self.machine_st, self.socket_server_open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSocketServerOpen(_) => { + &Instruction::ExecuteSocketServerOpen => { try_or_throw!(self.machine_st, self.socket_server_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSocketServerAccept(_) => { + &Instruction::CallSocketServerAccept => { try_or_throw!(self.machine_st, self.socket_server_accept()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSocketServerAccept(_) => { + &Instruction::ExecuteSocketServerAccept => { try_or_throw!(self.machine_st, self.socket_server_accept()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSocketServerClose(_) => { + &Instruction::CallSocketServerClose => { try_or_throw!(self.machine_st, self.socket_server_close()); self.machine_st.p += 1; } - &Instruction::ExecuteSocketServerClose(_) => { + &Instruction::ExecuteSocketServerClose => { try_or_throw!(self.machine_st, self.socket_server_close()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallTLSAcceptClient(_) => { + &Instruction::CallTLSAcceptClient => { try_or_throw!(self.machine_st, self.tls_accept_client()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTLSAcceptClient(_) => { + &Instruction::ExecuteTLSAcceptClient => { try_or_throw!(self.machine_st, self.tls_accept_client()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTLSClientConnect(_) => { + &Instruction::CallTLSClientConnect => { try_or_throw!(self.machine_st, self.tls_client_connect()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTLSClientConnect(_) => { + &Instruction::ExecuteTLSClientConnect => { try_or_throw!(self.machine_st, self.tls_client_connect()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSucceed(_) => { + &Instruction::CallSucceed => { self.machine_st.p += 1; } - &Instruction::ExecuteSucceed(_) => { + &Instruction::ExecuteSucceed => { self.machine_st.p = self.machine_st.cp; } - &Instruction::CallTermAttributedVariables(_) => { + &Instruction::CallTermAttributedVariables => { self.term_attributed_variables(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTermAttributedVariables(_) => { + &Instruction::ExecuteTermAttributedVariables => { self.term_attributed_variables(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTermVariables(_) => { + &Instruction::CallTermVariables => { self.term_variables(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTermVariables(_) => { + &Instruction::ExecuteTermVariables => { self.term_variables(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTermVariablesUnderMaxDepth(_) => { + &Instruction::CallTermVariablesUnderMaxDepth => { self.term_variables_under_max_depth(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTermVariablesUnderMaxDepth(_) => { + &Instruction::ExecuteTermVariablesUnderMaxDepth => { self.term_variables_under_max_depth(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTruncateLiftedHeapTo(_) => { + &Instruction::CallTruncateLiftedHeapTo => { self.truncate_lifted_heap_to(); self.machine_st.p += 1; } - &Instruction::ExecuteTruncateLiftedHeapTo(_) => { + &Instruction::ExecuteTruncateLiftedHeapTo => { self.truncate_lifted_heap_to(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallUnifyWithOccursCheck(_) => { + &Instruction::CallUnifyWithOccursCheck => { self.unify_with_occurs_check(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteUnifyWithOccursCheck(_) => { + &Instruction::ExecuteUnifyWithOccursCheck => { self.unify_with_occurs_check(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallUnwindEnvironments(_) => { + &Instruction::CallUnwindEnvironments => { if !self.unwind_environments() { self.machine_st.p += 1; } } - &Instruction::ExecuteUnwindEnvironments(_) => { + &Instruction::ExecuteUnwindEnvironments => { if !self.unwind_environments() { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallUnwindStack(_) | &Instruction::ExecuteUnwindStack(_) => { + &Instruction::CallUnwindStack | &Instruction::ExecuteUnwindStack => { self.machine_st.unwind_stack(); self.machine_st.backtrack(); } - &Instruction::CallWAMInstructions(_) => { + &Instruction::CallWAMInstructions => { try_or_throw!(self.machine_st, self.wam_instructions()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWAMInstructions(_) => { + &Instruction::ExecuteWAMInstructions => { try_or_throw!(self.machine_st, self.wam_instructions()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInlinedInstructions(_) => { + &Instruction::CallInlinedInstructions => { self.inlined_instructions(); self.machine_st.p += 1; } - &Instruction::ExecuteInlinedInstructions(_) => { + &Instruction::ExecuteInlinedInstructions => { self.inlined_instructions(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallWriteTerm(_) => { + &Instruction::CallWriteTerm => { try_or_throw!(self.machine_st, self.write_term()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWriteTerm(_) => { + &Instruction::ExecuteWriteTerm => { try_or_throw!(self.machine_st, self.write_term()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallWriteTermToChars(_) => { + &Instruction::CallWriteTermToChars => { try_or_throw!(self.machine_st, self.write_term_to_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWriteTermToChars(_) => { + &Instruction::ExecuteWriteTermToChars => { try_or_throw!(self.machine_st, self.write_term_to_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallScryerPrologVersion(_) => { + &Instruction::CallScryerPrologVersion => { self.scryer_prolog_version(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteScryerPrologVersion(_) => { + &Instruction::ExecuteScryerPrologVersion => { self.scryer_prolog_version(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoRandomByte(_) => { + &Instruction::CallCryptoRandomByte => { self.crypto_random_byte(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoRandomByte(_) => { + &Instruction::ExecuteCryptoRandomByte => { self.crypto_random_byte(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataHash(_) => { + &Instruction::CallCryptoDataHash => { self.crypto_data_hash(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataHash(_) => { + &Instruction::ExecuteCryptoDataHash => { self.crypto_data_hash(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataHKDF(_) => { + &Instruction::CallCryptoDataHKDF => { self.crypto_data_hkdf(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataHKDF(_) => { + &Instruction::ExecuteCryptoDataHKDF => { self.crypto_data_hkdf(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoPasswordHash(_) => { + &Instruction::CallCryptoPasswordHash => { self.crypto_password_hash(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoPasswordHash(_) => { + &Instruction::ExecuteCryptoPasswordHash => { self.crypto_password_hash(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataEncrypt(_) => { + &Instruction::CallCryptoDataEncrypt => { self.crypto_data_encrypt(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataEncrypt(_) => { + &Instruction::ExecuteCryptoDataEncrypt => { self.crypto_data_encrypt(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataDecrypt(_) => { + &Instruction::CallCryptoDataDecrypt => { self.crypto_data_decrypt(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataDecrypt(_) => { + &Instruction::ExecuteCryptoDataDecrypt => { self.crypto_data_decrypt(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoCurveScalarMult(_) => { + &Instruction::CallCryptoCurveScalarMult => { self.crypto_curve_scalar_mult(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoCurveScalarMult(_) => { + &Instruction::ExecuteCryptoCurveScalarMult => { self.crypto_curve_scalar_mult(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519Sign(_) => { + &Instruction::CallEd25519Sign => { self.ed25519_sign(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519Sign(_) => { + &Instruction::ExecuteEd25519Sign => { self.ed25519_sign(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519Verify(_) => { + &Instruction::CallEd25519Verify => { self.ed25519_verify(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519Verify(_) => { + &Instruction::ExecuteEd25519Verify => { self.ed25519_verify(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519NewKeyPair(_) => { + &Instruction::CallEd25519NewKeyPair => { self.ed25519_new_key_pair(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519NewKeyPair(_) => { + &Instruction::ExecuteEd25519NewKeyPair => { self.ed25519_new_key_pair(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519KeyPairPublicKey(_) => { + &Instruction::CallEd25519KeyPairPublicKey => { self.ed25519_key_pair_public_key(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519KeyPairPublicKey(_) => { + &Instruction::ExecuteEd25519KeyPairPublicKey => { self.ed25519_key_pair_public_key(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurve25519ScalarMult(_) => { + &Instruction::CallCurve25519ScalarMult => { self.curve25519_scalar_mult(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurve25519ScalarMult(_) => { + &Instruction::ExecuteCurve25519ScalarMult => { self.curve25519_scalar_mult(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFirstNonOctet(_) => { + &Instruction::CallFirstNonOctet => { self.first_non_octet(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFirstNonOctet(_) => { + &Instruction::ExecuteFirstNonOctet => { self.first_non_octet(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadHTML(_) => { + &Instruction::CallLoadHTML => { self.load_html(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadHTML(_) => { + &Instruction::ExecuteLoadHTML => { self.load_html(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadXML(_) => { + &Instruction::CallLoadXML => { self.load_xml(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadXML(_) => { + &Instruction::ExecuteLoadXML => { self.load_xml(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetEnv(_) => { + &Instruction::CallGetEnv => { self.get_env(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetEnv(_) => { + &Instruction::ExecuteGetEnv => { self.get_env(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetEnv(_) => { + &Instruction::CallSetEnv => { self.set_env(); self.machine_st.p += 1; } - &Instruction::ExecuteSetEnv(_) => { + &Instruction::ExecuteSetEnv => { self.set_env(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallUnsetEnv(_) => { + &Instruction::CallUnsetEnv => { self.unset_env(); self.machine_st.p += 1; } - &Instruction::ExecuteUnsetEnv(_) => { + &Instruction::ExecuteUnsetEnv => { self.unset_env(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallShell(_) => { + &Instruction::CallShell => { self.shell(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteShell(_) => { + &Instruction::ExecuteShell => { self.shell(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPID(_) => { + &Instruction::CallPID => { self.pid(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePID(_) => { + &Instruction::ExecutePID => { self.pid(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCharsBase64(_) => { + &Instruction::CallCharsBase64 => { try_or_throw!(self.machine_st, self.chars_base64()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharsBase64(_) => { + &Instruction::ExecuteCharsBase64 => { try_or_throw!(self.machine_st, self.chars_base64()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDevourWhitespace(_) => { + &Instruction::CallDevourWhitespace => { try_or_throw!(self.machine_st, self.devour_whitespace()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDevourWhitespace(_) => { + &Instruction::ExecuteDevourWhitespace => { try_or_throw!(self.machine_st, self.devour_whitespace()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallIsSTOEnabled(_) => { + &Instruction::CallIsSTOEnabled => { self.is_sto_enabled(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsSTOEnabled(_) => { + &Instruction::ExecuteIsSTOEnabled => { self.is_sto_enabled(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetSTOAsUnify(_) => { + &Instruction::CallSetSTOAsUnify => { self.set_sto_as_unify(); self.machine_st.p += 1; } - &Instruction::ExecuteSetSTOAsUnify(_) => { + &Instruction::ExecuteSetSTOAsUnify => { self.set_sto_as_unify(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetNSTOAsUnify(_) => { + &Instruction::CallSetNSTOAsUnify => { self.set_nsto_as_unify(); self.machine_st.p += 1; } - &Instruction::ExecuteSetNSTOAsUnify(_) => { + &Instruction::ExecuteSetNSTOAsUnify => { self.set_nsto_as_unify(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetSTOWithErrorAsUnify(_) => { + &Instruction::CallSetSTOWithErrorAsUnify => { self.set_sto_with_error_as_unify(); self.machine_st.p += 1; } - &Instruction::ExecuteSetSTOWithErrorAsUnify(_) => { + &Instruction::ExecuteSetSTOWithErrorAsUnify => { self.set_sto_with_error_as_unify(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallHomeDirectory(_) => { + &Instruction::CallHomeDirectory => { self.home_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHomeDirectory(_) => { + &Instruction::ExecuteHomeDirectory => { self.home_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDebugHook(_) => { + &Instruction::CallDebugHook => { self.debug_hook(); self.machine_st.p += 1; } - &Instruction::ExecuteDebugHook(_) => { + &Instruction::ExecuteDebugHook => { self.debug_hook(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPopCount(_) => { + &Instruction::CallPopCount => { self.pop_count(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePopCount(_) => { + &Instruction::ExecutePopCount => { self.pop_count(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallAddDiscontiguousPredicate(_) => { + &Instruction::CallAddDiscontiguousPredicate => { try_or_throw!(self.machine_st, self.add_discontiguous_predicate()); self.machine_st.p += 1; } - &Instruction::ExecuteAddDiscontiguousPredicate(_) => { + &Instruction::ExecuteAddDiscontiguousPredicate => { try_or_throw!(self.machine_st, self.add_discontiguous_predicate()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddDynamicPredicate(_) => { + &Instruction::CallAddDynamicPredicate => { try_or_throw!(self.machine_st, self.add_dynamic_predicate()); self.machine_st.p += 1; } - &Instruction::ExecuteAddDynamicPredicate(_) => { + &Instruction::ExecuteAddDynamicPredicate => { try_or_throw!(self.machine_st, self.add_dynamic_predicate()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddMultifilePredicate(_) => { + &Instruction::CallAddMultifilePredicate => { try_or_throw!(self.machine_st, self.add_multifile_predicate()); self.machine_st.p += 1; } - &Instruction::ExecuteAddMultifilePredicate(_) => { + &Instruction::ExecuteAddMultifilePredicate => { try_or_throw!(self.machine_st, self.add_multifile_predicate()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddGoalExpansionClause(_) => { + &Instruction::CallAddGoalExpansionClause => { try_or_throw!(self.machine_st, self.add_goal_expansion_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteAddGoalExpansionClause(_) => { + &Instruction::ExecuteAddGoalExpansionClause => { try_or_throw!(self.machine_st, self.add_goal_expansion_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddTermExpansionClause(_) => { + &Instruction::CallAddTermExpansionClause => { try_or_throw!(self.machine_st, self.add_term_expansion_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteAddTermExpansionClause(_) => { + &Instruction::ExecuteAddTermExpansionClause => { try_or_throw!(self.machine_st, self.add_term_expansion_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddInSituFilenameModule(_) => { + &Instruction::CallAddInSituFilenameModule => { try_or_throw!(self.machine_st, self.add_in_situ_filename_module()); self.machine_st.p += 1; } - &Instruction::ExecuteAddInSituFilenameModule(_) => { + &Instruction::ExecuteAddInSituFilenameModule => { try_or_throw!(self.machine_st, self.add_in_situ_filename_module()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallClauseToEvacuable(_) => { + &Instruction::CallClauseToEvacuable => { try_or_throw!(self.machine_st, self.clause_to_evacuable()); self.machine_st.p += 1; } - &Instruction::ExecuteClauseToEvacuable(_) => { + &Instruction::ExecuteClauseToEvacuable => { try_or_throw!(self.machine_st, self.clause_to_evacuable()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallScopedClauseToEvacuable(_) => { + &Instruction::CallScopedClauseToEvacuable => { try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable()); self.machine_st.p += 1; } - &Instruction::ExecuteScopedClauseToEvacuable(_) => { + &Instruction::ExecuteScopedClauseToEvacuable => { try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallConcludeLoad(_) => { + &Instruction::CallConcludeLoad => { try_or_throw!(self.machine_st, self.conclude_load()); self.machine_st.p += 1; } - &Instruction::ExecuteConcludeLoad(_) => { + &Instruction::ExecuteConcludeLoad => { try_or_throw!(self.machine_st, self.conclude_load()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallDeclareModule(_) => { + &Instruction::CallDeclareModule => { try_or_throw!(self.machine_st, self.declare_module()); self.machine_st.p += 1; } - &Instruction::ExecuteDeclareModule(_) => { + &Instruction::ExecuteDeclareModule => { try_or_throw!(self.machine_st, self.declare_module()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallLoadCompiledLibrary(_) => { + &Instruction::CallLoadCompiledLibrary => { try_or_throw!(self.machine_st, self.load_compiled_library()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadCompiledLibrary(_) => { + &Instruction::ExecuteLoadCompiledLibrary => { try_or_throw!(self.machine_st, self.load_compiled_library()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextSource(_) => { + &Instruction::CallLoadContextSource => { self.load_context_source(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextSource(_) => { + &Instruction::ExecuteLoadContextSource => { self.load_context_source(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextFile(_) => { + &Instruction::CallLoadContextFile => { self.load_context_file(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextFile(_) => { + &Instruction::ExecuteLoadContextFile => { self.load_context_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextDirectory(_) => { + &Instruction::CallLoadContextDirectory => { self.load_context_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextDirectory(_) => { + &Instruction::ExecuteLoadContextDirectory => { self.load_context_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextModule(_) => { + &Instruction::CallLoadContextModule => { self.load_context_module(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextModule(_) => { + &Instruction::ExecuteLoadContextModule => { self.load_context_module(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextStream(_) => { + &Instruction::CallLoadContextStream => { self.load_context_stream(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextStream(_) => { + &Instruction::ExecuteLoadContextStream => { self.load_context_stream(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPopLoadContext(_) => { + &Instruction::CallPopLoadContext => { self.pop_load_context(); self.machine_st.p += 1; } - &Instruction::ExecutePopLoadContext(_) => { + &Instruction::ExecutePopLoadContext => { self.pop_load_context(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPopLoadStatePayload(_) => { + &Instruction::CallPopLoadStatePayload => { self.pop_load_state_payload(); self.machine_st.p += 1; } - &Instruction::ExecutePopLoadStatePayload(_) => { + &Instruction::ExecutePopLoadStatePayload => { self.pop_load_state_payload(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPushLoadContext(_) => { + &Instruction::CallPushLoadContext => { try_or_throw!(self.machine_st, self.push_load_context()); self.machine_st.p += 1; } - &Instruction::ExecutePushLoadContext(_) => { + &Instruction::ExecutePushLoadContext => { try_or_throw!(self.machine_st, self.push_load_context()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPushLoadStatePayload(_) => { + &Instruction::CallPushLoadStatePayload => { self.push_load_state_payload(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePushLoadStatePayload(_) => { + &Instruction::ExecutePushLoadStatePayload => { self.push_load_state_payload(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallUseModule(_) => { + &Instruction::CallUseModule => { try_or_throw!(self.machine_st, self.use_module()); self.machine_st.p += 1; } - &Instruction::ExecuteUseModule(_) => { + &Instruction::ExecuteUseModule => { try_or_throw!(self.machine_st, self.use_module()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallBuiltInProperty(_) => { + &Instruction::CallBuiltInProperty => { self.builtin_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteBuiltInProperty(_) => { + &Instruction::ExecuteBuiltInProperty => { self.builtin_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMetaPredicateProperty(_) => { + &Instruction::CallMetaPredicateProperty => { self.meta_predicate_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMetaPredicateProperty(_) => { + &Instruction::ExecuteMetaPredicateProperty => { self.meta_predicate_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMultifileProperty(_) => { + &Instruction::CallMultifileProperty => { self.multifile_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMultifileProperty(_) => { + &Instruction::ExecuteMultifileProperty => { self.multifile_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDiscontiguousProperty(_) => { + &Instruction::CallDiscontiguousProperty => { self.discontiguous_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDiscontiguousProperty(_) => { + &Instruction::ExecuteDiscontiguousProperty => { self.discontiguous_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDynamicProperty(_) => { + &Instruction::CallDynamicProperty => { self.dynamic_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDynamicProperty(_) => { + &Instruction::ExecuteDynamicProperty => { self.dynamic_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallAbolishClause(_) => { + &Instruction::CallAbolishClause => { try_or_throw!(self.machine_st, self.abolish_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteAbolishClause(_) => { + &Instruction::ExecuteAbolishClause => { try_or_throw!(self.machine_st, self.abolish_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAsserta(_) => { + &Instruction::CallAsserta => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Prepend)); self.machine_st.p += 1; } - &Instruction::ExecuteAsserta(_) => { + &Instruction::ExecuteAsserta => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Prepend)); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAssertz(_) => { + &Instruction::CallAssertz => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Append)); self.machine_st.p += 1; } - &Instruction::ExecuteAssertz(_) => { + &Instruction::ExecuteAssertz => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Append)); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRetract(_) => { + &Instruction::CallRetract => { try_or_throw!(self.machine_st, self.retract_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteRetract(_) => { + &Instruction::ExecuteRetract => { try_or_throw!(self.machine_st, self.retract_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallIsConsistentWithTermQueue(_) => { + &Instruction::CallIsConsistentWithTermQueue => { try_or_throw!(self.machine_st, self.is_consistent_with_term_queue()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsConsistentWithTermQueue(_) => { + &Instruction::ExecuteIsConsistentWithTermQueue => { try_or_throw!(self.machine_st, self.is_consistent_with_term_queue()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::CallFlushTermQueue(_) => { + &Instruction::CallFlushTermQueue => { try_or_throw!(self.machine_st, self.flush_term_queue()); self.machine_st.p += 1; } - &Instruction::ExecuteFlushTermQueue(_) => { + &Instruction::ExecuteFlushTermQueue => { try_or_throw!(self.machine_st, self.flush_term_queue()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRemoveModuleExports(_) => { + &Instruction::CallRemoveModuleExports => { try_or_throw!(self.machine_st, self.remove_module_exports()); self.machine_st.p += 1; } - &Instruction::ExecuteRemoveModuleExports(_) => { + &Instruction::ExecuteRemoveModuleExports => { try_or_throw!(self.machine_st, self.remove_module_exports()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddNonCountedBacktracking(_) => { + &Instruction::CallAddNonCountedBacktracking => { try_or_throw!(self.machine_st, self.add_non_counted_backtracking()); self.machine_st.p += 1; } - &Instruction::ExecuteAddNonCountedBacktracking(_) => { + &Instruction::ExecuteAddNonCountedBacktracking => { try_or_throw!(self.machine_st, self.add_non_counted_backtracking()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPredicateDefined(_) => { + &Instruction::CallPredicateDefined => { self.machine_st.fail = !self.predicate_defined(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePredicateDefined(_) => { + &Instruction::ExecutePredicateDefined => { self.machine_st.fail = !self.predicate_defined(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallStripModule(_) => { + &Instruction::CallStripModule => { let (module_loc, qualified_goal) = self.machine_st.strip_module( self.machine_st.registers[1], self.machine_st.registers[2], @@ -5002,7 +5004,7 @@ impl Machine { step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteStripModule(_) => { + &Instruction::ExecuteStripModule => { let (module_loc, qualified_goal) = self.machine_st.strip_module( self.machine_st.registers[1], self.machine_st.registers[2], @@ -5026,31 +5028,31 @@ impl Machine { step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPrepareCallClause(arity, _) => { + &Instruction::CallPrepareCallClause(arity) => { try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePrepareCallClause(arity, _) => { + &Instruction::ExecutePrepareCallClause(arity) => { try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCompileInlineOrExpandedGoal(_) => { + &Instruction::CallCompileInlineOrExpandedGoal => { try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCompileInlineOrExpandedGoal(_) => { + &Instruction::ExecuteCompileInlineOrExpandedGoal => { try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallIsExpandedOrInlined(_) => { + &Instruction::CallIsExpandedOrInlined => { self.machine_st.fail = !self.is_expanded_or_inlined(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsExpandedOrInlined(_) => { + &Instruction::ExecuteIsExpandedOrInlined => { self.machine_st.fail = !self.is_expanded_or_inlined(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInlineCallN(arity, _) => { + &Instruction::CallInlineCallN(arity) => { let call_at_index = |wam: &mut Machine, name, arity, ptr| { wam.try_call(name, arity, ptr) }; @@ -5066,7 +5068,7 @@ impl Machine { ); } } - &Instruction::ExecuteInlineCallN(arity, _) => { + &Instruction::ExecuteInlineCallN(arity) => { let call_at_index = |wam: &mut Machine, name, arity, ptr| { wam.try_execute(name, arity, ptr) }; @@ -5082,7 +5084,7 @@ impl Machine { ); } } - &Instruction::CallGetClauseP(_) => { + &Instruction::CallGetClauseP => { let module_name = cell_as_atom!(self.deref_register(3)); let (n, p) = self.get_clause_p(module_name); @@ -5098,7 +5100,7 @@ impl Machine { step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetClauseP(_) => { + &Instruction::ExecuteGetClauseP => { let module_name = cell_as_atom!(self.deref_register(3)); let (n, p) = self.get_clause_p(module_name); @@ -5114,7 +5116,7 @@ impl Machine { step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInvokeClauseAtP(_) => { + &Instruction::CallInvokeClauseAtP => { let key_cell = self.machine_st.registers[1]; let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap(); @@ -5159,7 +5161,7 @@ impl Machine { self.machine_st.call_at_index(2, p); } - &Instruction::ExecuteInvokeClauseAtP(_) => { + &Instruction::ExecuteInvokeClauseAtP => { let key_cell = self.machine_st.registers[1]; let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap(); @@ -5204,51 +5206,51 @@ impl Machine { self.machine_st.execute_at_index(2, p); } - &Instruction::CallGetFromAttributedVarList(_) => { + &Instruction::CallGetFromAttributedVarList => { self.get_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetFromAttributedVarList(_) => { + &Instruction::ExecuteGetFromAttributedVarList => { self.get_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPutToAttributedVarList(_) => { + &Instruction::CallPutToAttributedVarList => { self.put_to_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePutToAttributedVarList(_) => { + &Instruction::ExecutePutToAttributedVarList => { self.put_to_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteFromAttributedVarList(_) => { + &Instruction::CallDeleteFromAttributedVarList => { self.delete_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeleteFromAttributedVarList(_) => { + &Instruction::ExecuteDeleteFromAttributedVarList => { self.delete_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteAllAttributesFromVar(_) => { + &Instruction::CallDeleteAllAttributesFromVar => { self.delete_all_attributes_from_var(); self.machine_st.p += 1; } - &Instruction::ExecuteDeleteAllAttributesFromVar(_) => { + &Instruction::ExecuteDeleteAllAttributesFromVar => { self.delete_all_attributes_from_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallUnattributedVar(_) => { + &Instruction::CallUnattributedVar => { self.machine_st.unattributed_var(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteUnattributedVar(_) => { + &Instruction::ExecuteUnattributedVar => { self.machine_st.unattributed_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallGetDBRefs(_) => { + &Instruction::CallGetDBRefs => { self.get_db_refs(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetDBRefs(_) => { + &Instruction::ExecuteGetDBRefs => { self.get_db_refs(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index 3d0a638a..56aa88eb 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -444,10 +444,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { let tl = preprocessor.try_term_to_tl(self, term)?; Ok(match tl { - TopLevel::Fact(fact) => PredicateClause::Fact(fact), - TopLevel::Rule(rule) => PredicateClause::Rule(rule), - TopLevel::Query(_) => return Err(SessionError::QueryCannotBeDefinedAsFact), - _ => unreachable!(), + TopLevel::Fact(fact, var_data) => PredicateClause::Fact(fact, var_data), + TopLevel::Rule(rule, var_data) => PredicateClause::Rule(rule, var_data), }) } diff --git a/src/machine/loader.rs b/src/machine/loader.rs index bb093a0e..51815c7e 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -1428,7 +1428,7 @@ impl MachineState { } } (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, h) => { - term_stack.push(Term::Var(Cell::default(), Var::Generated(h))); + term_stack.push(Term::Var(Cell::default(), VarPtr::from(format!("_{}", h)))); } (HeapCellValueTag::Cons | HeapCellValueTag::CStr | HeapCellValueTag::Fixnum | HeapCellValueTag::Char | HeapCellValueTag::F64) => { diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index afa2bea2..fdc60e0b 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -2,7 +2,6 @@ use crate::parser::ast::*; use crate::arena::*; use crate::atom_table::*; -use crate::fixtures::*; use crate::forms::*; use crate::machine::loader::*; use crate::machine::machine_state::*; @@ -227,8 +226,8 @@ impl CodeIndex { } } -pub(crate) type HeapVarDict = IndexMap; -pub(crate) type AllocVarDict = IndexMap; +pub(crate) type HeapVarDict = IndexMap; +// pub(crate) type AllocVarDict = IndexMap; pub(crate) type GlobalVarDir = IndexMap), FxBuildHasher>; diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 6d0de7d9..26d0309b 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -500,13 +500,13 @@ impl MachineState { pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult { fn push_var_eq_functors<'a>( heap: &mut Heap, - iter: impl Iterator, + iter: impl Iterator, atom_tbl: &mut AtomTable, ) -> Vec { let mut list_of_var_eqs = vec![]; for (var, binding) in iter { - let var_atom = atom_tbl.build_with(&var.to_string()); + let var_atom = atom_tbl.build_with(&var.borrow().to_string()); let h = heap.len(); heap.push(atom_as_cell!(atom!("="), 2)); @@ -672,7 +672,7 @@ impl MachineState { let printer = match self.try_from_list(self.registers[6], stub_gen) { Ok(addrs) => { - let mut var_names: IndexMap = IndexMap::new(); + let mut var_names: IndexMap = IndexMap::new(); for addr in addrs { read_heap_cell!(addr, @@ -690,18 +690,18 @@ impl MachineState { read_heap_cell!(atom, (HeapCellValueTag::Char, c) => { - var_names.insert(var, Var::from(c.to_string())); + var_names.insert(var, VarPtr::from(c.to_string())); } (HeapCellValueTag::Atom, (name, _arity)) => { debug_assert_eq!(_arity, 0); - var_names.insert(var, Var::from(name.as_str())); + var_names.insert(var, VarPtr::from(name.as_str())); } (HeapCellValueTag::Str, s) => { let (name, arity) = cell_as_atom_cell!(self.heap[s]) .get_name_and_arity(); debug_assert_eq!(arity, 0); - var_names.insert(var, Var::from(name.as_str())); + var_names.insert(var, VarPtr::from(name.as_str())); } _ => { unreachable!(); diff --git a/src/machine/mod.rs b/src/machine/mod.rs index dab4c54c..ddf64d34 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -68,7 +68,7 @@ pub struct Machine { pub(super) user_error: Stream, pub(super) load_contexts: Vec, pub(super) runtime: Runtime, - pub(super) foreign_function_table: ForeignFunctionTable, + pub(super) foreign_function_table: ForeignFunctionTable, } #[derive(Debug)] @@ -365,46 +365,46 @@ impl Machine { Instruction::BreakFromDispatchLoop, Instruction::InstallVerifyAttr, Instruction::VerifyAttrInterrupt, - Instruction::ExecuteTermGreaterThan(0), - Instruction::ExecuteTermLessThan(0), - Instruction::ExecuteTermGreaterThanOrEqual(0), - Instruction::ExecuteTermLessThanOrEqual(0), - Instruction::ExecuteTermEqual(0), - Instruction::ExecuteTermNotEqual(0), - Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberGreaterThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteAcyclicTerm(0), - Instruction::ExecuteArg(0), - Instruction::ExecuteCompare(0), - Instruction::ExecuteCopyTerm(0), - Instruction::ExecuteFunctor(0), - Instruction::ExecuteGround(0), - Instruction::ExecuteKeySort(0), - Instruction::ExecuteRead(0), - Instruction::ExecuteSort(0), - Instruction::ExecuteN(1, 0), - Instruction::ExecuteN(2, 0), - Instruction::ExecuteN(3, 0), - Instruction::ExecuteN(4, 0), - Instruction::ExecuteN(5, 0), - Instruction::ExecuteN(6, 0), - Instruction::ExecuteN(7, 0), - Instruction::ExecuteN(8, 0), - Instruction::ExecuteN(9, 0), - Instruction::ExecuteIsAtom(temp_v!(1), 0), - Instruction::ExecuteIsAtomic(temp_v!(1), 0), - Instruction::ExecuteIsCompound(temp_v!(1), 0), - Instruction::ExecuteIsInteger(temp_v!(1), 0), - Instruction::ExecuteIsNumber(temp_v!(1), 0), - Instruction::ExecuteIsRational(temp_v!(1), 0), - Instruction::ExecuteIsFloat(temp_v!(1), 0), - Instruction::ExecuteIsNonVar(temp_v!(1), 0), - Instruction::ExecuteIsVar(temp_v!(1), 0) + Instruction::ExecuteTermGreaterThan, + Instruction::ExecuteTermLessThan, + Instruction::ExecuteTermGreaterThanOrEqual, + Instruction::ExecuteTermLessThanOrEqual, + Instruction::ExecuteTermEqual, + Instruction::ExecuteTermNotEqual, + Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberGreaterThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2))), + Instruction::ExecuteAcyclicTerm, + Instruction::ExecuteArg, + Instruction::ExecuteCompare, + Instruction::ExecuteCopyTerm, + Instruction::ExecuteFunctor, + Instruction::ExecuteGround, + Instruction::ExecuteKeySort, + Instruction::ExecuteRead, + Instruction::ExecuteSort, + Instruction::ExecuteN(1), + Instruction::ExecuteN(2), + Instruction::ExecuteN(3), + Instruction::ExecuteN(4), + Instruction::ExecuteN(5), + Instruction::ExecuteN(6), + Instruction::ExecuteN(7), + Instruction::ExecuteN(8), + Instruction::ExecuteN(9), + Instruction::ExecuteIsAtom(temp_v!(1)), + Instruction::ExecuteIsAtomic(temp_v!(1)), + Instruction::ExecuteIsCompound(temp_v!(1)), + Instruction::ExecuteIsInteger(temp_v!(1)), + Instruction::ExecuteIsNumber(temp_v!(1)), + Instruction::ExecuteIsRational(temp_v!(1)), + Instruction::ExecuteIsFloat(temp_v!(1)), + Instruction::ExecuteIsNonVar(temp_v!(1)), + Instruction::ExecuteIsVar(temp_v!(1)) ].into_iter()); for (p, instr) in self.code[impls_offset ..].iter().enumerate() { @@ -690,6 +690,8 @@ impl Machine { fn try_call(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult { let compiled_tl_index = idx.p() as usize; + // println!("calling {}/{}", name.as_str(), arity); + match idx.tag() { IndexPtrTag::DynamicUndefined => { self.machine_st.fail = true; @@ -713,6 +715,8 @@ impl Machine { fn try_execute(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult { let compiled_tl_index = idx.p() as usize; + // println!("executing {}/{}", name.as_str(), arity); + match idx.tag() { IndexPtrTag::DynamicUndefined => { self.machine_st.fail = true; diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 02e0e29f..a0cab869 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -10,20 +10,8 @@ use crate::parser::ast::*; use indexmap::IndexSet; use std::cell::Cell; -use std::collections::VecDeque; use std::convert::TryFrom; -pub(crate) fn fold_by_str(terms: I, mut term: Term, sym: Atom) -> Term -where - I: DoubleEndedIterator, -{ - for prec in terms.rev() { - term = Term::Clause(Cell::default(), sym, vec![prec, term]); - } - - term -} - pub(crate) fn to_op_decl( prec: u16, spec: Atom, @@ -546,16 +534,15 @@ impl Preprocessor { } } - fn setup_fact(&mut self, term: Term) -> Result { + fn setup_fact(&mut self, term: Term) -> Result<(Fact, VarData), CompilationError> { match term { Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => { - let mut classifier = VariableClassifier::new( + let classifier = VariableClassifier::new( self.settings.default_call_policy(), ); let (head, var_data) = classifier.classify_fact(term)?; - - Ok(Fact { head, var_data }) + Ok((Fact { head }, var_data)) } _ => Err(CompilationError::InadmissibleFact), } @@ -566,28 +553,22 @@ impl Preprocessor { loader: &mut Loader<'a, LS>, head: Term, body: Term, - ) -> Result { - let mut classifier = VariableClassifier::new( + ) -> Result<(Rule, VarData), CompilationError> { + let classifier = VariableClassifier::new( self.settings.default_call_policy(), ); - let (head, mut query_terms, var_data) = - classifier.classify_rule(loader, head, body)?; - - let clauses = query_terms.drain(1..).collect(); - let qt = query_terms.pop().unwrap(); + let (head, clauses, var_data) = classifier.classify_rule(loader, head, body)?; match head { - Term::Clause(_, name, terms) => Ok(Rule { - head: (name, terms, qt), + Term::Clause(_, name, terms) => Ok((Rule { + head: (name, terms), clauses, - var_data, - }), - Term::Literal(_, Literal::Atom(name)) => Ok(Rule { - head: (name, vec![], qt), + }, var_data)), + Term::Literal(_, Literal::Atom(name)) => Ok((Rule { + head: (name, vec![]), clauses, - var_data, - }), + }, var_data)), _ => Err(CompilationError::InvalidRuleHead), } } @@ -613,20 +594,29 @@ impl Preprocessor { term: Term, ) -> Result { match term { - Term::Clause(r, name, terms) => { + Term::Clause(r, name, mut terms) => { let is_rule = name == atom!(":-") && terms.len() == 2; if is_rule { - Ok(TopLevel::Rule(self.setup_rule(loader, terms[0], terms[1])?)) + let tail = terms.pop().unwrap(); + let head = terms.pop().unwrap(); + + let (rule, var_data) = self.setup_rule(loader, head, tail)?; + Ok(TopLevel::Rule(rule, var_data)) } else { let term = Term::Clause(r, name, terms); - Ok(TopLevel::Fact(self.setup_fact(term)?)) + let (fact, var_data) = self.setup_fact(term)?; + Ok(TopLevel::Fact(fact, var_data)) } } - term => Ok(TopLevel::Fact(self.setup_fact(term)?)), + term => { + let (fact, var_data) = self.setup_fact(term)?; + Ok(TopLevel::Fact(fact, var_data)) + } } } + /* fn try_terms_to_tls<'a, I: IntoIterator, LS: LoadState<'a>>( &mut self, loader: &mut Loader<'a, LS>, @@ -640,4 +630,5 @@ impl Preprocessor { Ok(results) } + */ } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index d26468da..7985f5fe 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -1409,7 +1409,7 @@ impl Machine { let vars: Vec<_> = vars .union(&result.supp_vars) // difference + union does not cancel. - .map(|v| Term::Var(Cell::default(), Var::Generated(v.get_value()))) + .map(|v| Term::Var(Cell::default(), VarPtr::from(format!("_{}", v.get_value())))) .collect(); let helper_clause_loc = self.code.len(); @@ -1571,8 +1571,8 @@ impl Machine { #[inline(always)] pub(crate) fn is_reset_cont_marker(&self, p: usize) -> bool { match &self.code[p] { - &Instruction::CallResetContinuationMarker(_) | - &Instruction::ExecuteResetContinuationMarker(_) => true, + &Instruction::CallResetContinuationMarker | + &Instruction::ExecuteResetContinuationMarker => true, _ => false } } @@ -4911,9 +4911,7 @@ impl Machine { let p_functor = self.deref_register(2); - let p = to_local_code_ptr(&self.machine_st.heap, p_functor).unwrap(); - - let num_cells = *self.code[p].perm_vars_mut().unwrap(); + let num_cells = self.machine_st.stack.index_and_frame(e).prelude.num_cells; let mut addrs = vec![]; for idx in 1..num_cells + 1 { diff --git a/src/macros.rs b/src/macros.rs index 85e2e086..c1f1552f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -540,23 +540,7 @@ 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 + ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp)).to_instr() }}; } diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 73c91c6a..283a9dc0 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -4,11 +4,11 @@ use crate::machine::machine_indices::*; use crate::parser::char_reader::*; use crate::types::HeapCellValueTag; -use std::cell::Cell; +use std::cell::{Cell, Ref, RefCell, RefMut}; use std::fmt; -use std::hash::Hash; +use std::hash::{Hash, Hasher}; use std::io::{Error as IOError}; -use std::ops::Neg; +use std::ops::{Deref, Neg}; use std::rc::Rc; use std::vec::Vec; @@ -572,23 +572,89 @@ impl Literal { } } + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VarPtr(Rc>); + +impl Hash for VarPtr { + #[inline(always)] + fn hash(&self, hasher: &mut H) { + self.borrow().hash(hasher) + } +} + +impl Deref for VarPtr { + type Target = RefCell; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + self.0.deref() + } +} + +impl VarPtr { + #[inline(always)] + pub(crate) fn borrow(&self) -> Ref<'_, Var> { + self.0.borrow() + } + + #[inline(always)] + pub(crate) fn borrow_mut(&self) -> RefMut<'_, Var> { + self.0.borrow_mut() + } + + pub(crate) fn to_var_num(&self) -> Option { + match *self.borrow() { + Var::Generated(var_num) => Some(var_num), + _ => None, + } + } + + pub(crate) fn set(&self, var: Var) { + let mut var_ref = self.borrow_mut(); + *var_ref = var; + } +} + +impl From for VarPtr { + #[inline(always)] + fn from(value: Var) -> VarPtr { + VarPtr(Rc::new(RefCell::new(value))) + } +} + +impl From for VarPtr { + #[inline(always)] + fn from(value: String) -> VarPtr { + VarPtr::from(Var::from(value)) + } +} + +impl From<&str> for VarPtr { + #[inline(always)] + fn from(value: &str) -> VarPtr { + VarPtr::from(value.to_owned()) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Var { Generated(usize), - Named(Rc), + InSitu(usize), + Named(String), } impl From for Var { #[inline(always)] fn from(value: String) -> Var { - Var::Named(Rc::new(value)) + Var::Named(value) } } impl From<&str> for Var { #[inline(always)] fn from(value: &str) -> Var { - Var::Named(Rc::new(value.to_owned())) + Var::Named(value.to_owned()) } } @@ -596,16 +662,16 @@ impl Var { #[inline(always)] pub fn as_str(&self) -> Option<&str> { match self { - Var::Generated(_) => None, Var::Named(value) => Some(&value), + _ => None, } } #[inline(always)] pub fn to_string(&self) -> String { match self { - Var::Generated(n) => format!("_{}", n), - Var::Named(value) => value.to_string(), + Var::InSitu(n) | Var::Generated(n) => format!("_{}", n), + Var::Named(value) => value.to_owned(), } } } @@ -620,7 +686,7 @@ pub enum Term { // other PartialString variants in as_partial_string. PartialString(Cell, String, Box), CompleteString(Cell, Atom), - Var(Cell, Var), + Var(Cell, VarPtr), } impl Term { diff --git a/src/parser/parser.rs b/src/parser/parser.rs index ce633b94..021147ea 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -426,7 +426,7 @@ impl<'a, R: CharRead> Parser<'a, R> { if v.trim() == "_" { self.terms.push(Term::AnonVar); } else { - self.terms.push(Term::Var(Cell::default(), Var::from(v))); + self.terms.push(Term::Var(Cell::default(), VarPtr::from(v))); } TokenType::Term diff --git a/src/read.rs b/src/read.rs index c8743c2f..8f70eeec 100644 --- a/src/read.rs +++ b/src/read.rs @@ -317,7 +317,7 @@ impl<'a, 'b> TermWriter<'a, 'b> { fn write_term_to_heap(mut self, term: &'a Term) -> Result { let heap_loc = self.heap.len(); - for term in breadth_first_iter(term, true) { + for term in breadth_first_iter(term, RootIterationPolicy::Iterated) { let h = self.heap.len(); match &term { @@ -372,9 +372,9 @@ impl<'a, 'b> TermWriter<'a, 'b> { let addr = self.term_as_addr(&term, h); self.heap.push(addr); } - &TermRef::Var(Level::Root, _, ref var) => { + &TermRef::Var(Level::Root, _, ref var_ptr) => { let addr = self.term_as_addr(&term, h); - self.var_dict.insert(var.clone(), heap_loc_as_cell!(h)); + self.var_dict.insert(var_ptr.clone(), heap_loc_as_cell!(h)); self.heap.push(addr); } &TermRef::AnonVar(_) => { diff --git a/src/targets.rs b/src/targets.rs index cbb469f9..56a4c127 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -29,11 +29,13 @@ pub(crate) trait CompilationTarget<'a> { fn argument_to_variable(r: RegType, r: usize) -> Instruction; fn argument_to_value(r: RegType, val: usize) -> Instruction; + fn unsafe_argument_to_value(r: RegType, val: usize) -> Instruction; fn move_to_register(r: RegType, val: usize) -> Instruction; fn subterm_to_variable(r: RegType) -> Instruction; fn subterm_to_value(r: RegType) -> Instruction; + fn unsafe_subterm_to_value(r: RegType) -> Instruction; fn clause_arg_to_instr(r: RegType) -> Instruction; } @@ -42,7 +44,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction { type Iterator = FactIterator<'a>; fn iter(term: &'a Term) -> Self::Iterator { - breadth_first_iter(term, false) // do not iterate over the root clause if one exists. + breadth_first_iter(term, RootIterationPolicy::NotIterated) } fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Instruction { @@ -95,6 +97,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction { Instruction::GetValue(arg, val) } + fn unsafe_argument_to_value(arg: RegType, val: usize) -> Instruction { + Instruction::GetValue(arg, val) + } + fn subterm_to_variable(val: RegType) -> Instruction { Instruction::UnifyVariable(val) } @@ -103,6 +109,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction { Instruction::UnifyValue(val) } + fn unsafe_subterm_to_value(val: RegType) -> Instruction { + Instruction::UnifyLocalValue(val) + } + fn clause_arg_to_instr(val: RegType) -> Instruction { Instruction::UnifyVariable(val) } @@ -165,6 +175,13 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { Instruction::PutValue(arg, val) } + fn unsafe_argument_to_value(arg: RegType, val: usize) -> Instruction { + match arg { + RegType::Perm(p) => Instruction::PutUnsafeValue(p, val), + RegType::Temp(_) => Instruction::PutValue(arg, val), + } + } + fn subterm_to_variable(val: RegType) -> Instruction { Instruction::SetVariable(val) } @@ -173,6 +190,10 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { Instruction::SetValue(val) } + fn unsafe_subterm_to_value(val: RegType) -> Instruction { + Instruction::SetLocalValue(val) + } + fn clause_arg_to_instr(val: RegType) -> Instruction { Instruction::SetValue(val) }