From: Mark Thom Date: Mon, 15 Jan 2018 06:05:15 +0000 (-0700) Subject: fix duplicate_term bug X-Git-Tag: v0.8.110~627 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=a4022d569f3b11bfb806bd9e2914abe84e3a80a3;p=scryer-prolog.git fix duplicate_term bug --- diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index 6e5f5503..e489d099 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -338,6 +338,7 @@ pub enum QueryTerm { Catch(Vec>), Cut, Display(Vec>), + DuplicateTerm(Vec>), Functor(Vec>), Inlined(InlinedQueryTerm), Is(Vec>), @@ -350,8 +351,9 @@ impl QueryTerm { match self { &QueryTerm::Arg(_) => 3, &QueryTerm::Catch(_) => 3, - &QueryTerm::Throw(_) => 1, + &QueryTerm::Throw(_) => 1, &QueryTerm::Display(_) => 1, + &QueryTerm::DuplicateTerm(_) => 2, &QueryTerm::Functor(_) => 3, &QueryTerm::Inlined(ref term) => term.arity(), &QueryTerm::Is(_) => 2, @@ -720,7 +722,6 @@ pub enum ArithmeticInstruction { pub enum BuiltInInstruction { CleanUpBlock, CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm), - DuplicateTerm, EraseBall, Fail, GetArg, @@ -751,6 +752,8 @@ pub enum ControlInstruction { Deallocate, DisplayCall, DisplayExecute, + DuplicateTermCall, + DuplicateTermExecute, Execute(Rc, usize), ExecuteN(usize), FunctorCall, @@ -773,6 +776,8 @@ impl ControlInstruction { &ControlInstruction::CatchExecute => true, &ControlInstruction::DisplayCall => true, &ControlInstruction::DisplayExecute => true, + &ControlInstruction::DuplicateTermCall => true, + &ControlInstruction::DuplicateTermExecute => true, &ControlInstruction::Execute(_, _) => true, &ControlInstruction::CallN(_) => true, &ControlInstruction::ExecuteN(_) => true, diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index d87ac5b2..0048004f 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -271,7 +271,9 @@ fn get_builtins() -> Code { put_value!(perm_v!(3), 4), put_value!(perm_v!(5), 5)], deallocate!(), - goto!(173, 3) // goto arg_/3. + goto!(173, 3), // goto arg_/3. + display!(), // display/1, 192. + proceed!() ] } @@ -344,5 +346,7 @@ pub fn build_code_dir() -> (Code, CodeDir, OpDir) code_dir.insert((rc_atom!("arg"), 3), (PredicateKeyType::BuiltIn, 150)); code_dir.insert((rc_atom!("integer"), 1), (PredicateKeyType::BuiltIn, 147)); + code_dir.insert((rc_atom!("display"), 1), (PredicateKeyType::BuiltIn, 192)); + (builtin_code, code_dir, op_dir) } diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 252fa1c1..384423c3 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -249,6 +249,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> code.push(Line::Control(ControlInstruction::CatchCall)), &QueryTerm::Display(_) => code.push(Line::Control(ControlInstruction::DisplayCall)), + &QueryTerm::DuplicateTerm(_) => + code.push(Line::Control(ControlInstruction::DuplicateTermCall)), &QueryTerm::Functor(_) => code.push(Line::Control(ControlInstruction::FunctorCall)), &QueryTerm::Inlined(_) => @@ -285,6 +287,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> *ctrl = ControlInstruction::ExecuteN(arity), ControlInstruction::DisplayCall => *ctrl = ControlInstruction::DisplayExecute, + ControlInstruction::DuplicateTermCall => + *ctrl = ControlInstruction::DuplicateTermExecute, ControlInstruction::FunctorCall => *ctrl = ControlInstruction::FunctorExecute, ControlInstruction::CatchCall => diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index 6c598543..ce738218 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -25,7 +25,7 @@ pub trait CopierTarget while scan < self.threshold() { match self[scan].clone() { - HeapCellValue::NamedStr(_, _, _) => + HeapCellValue::NamedStr(..) => scan += 1, HeapCellValue::Addr(a) => match a.clone() { @@ -88,7 +88,7 @@ pub trait CopierTarget HeapCellValue::Addr(Addr::Str(o)) => self[scan] = HeapCellValue::Addr(Addr::Str(o)), _ => {} - } + }; scan += 1; }, diff --git a/src/prolog/io.rs b/src/prolog/io.rs index a50abf80..5ff9bb27 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -114,6 +114,10 @@ impl fmt::Display for ControlInstruction { write!(f, "call_display"), &ControlInstruction::DisplayExecute => write!(f, "execute_display"), + &ControlInstruction::DuplicateTermCall => + write!(f, "call_duplicate_term"), + &ControlInstruction::DuplicateTermExecute => + write!(f, "execute_duplicate_term"), &ControlInstruction::ExecuteN(arity) => write!(f, "execute_N {}", arity), &ControlInstruction::FunctorCall => @@ -160,8 +164,6 @@ impl fmt::Display for BuiltInInstruction { write!(f, "clean_up_block"), &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2), - &BuiltInInstruction::DuplicateTerm => - write!(f, "duplicate_term X1"), &BuiltInInstruction::EraseBall => write!(f, "erase_ball"), &BuiltInInstruction::Fail => diff --git a/src/prolog/iterators.rs b/src/prolog/iterators.rs index 17ba7847..90701d49 100644 --- a/src/prolog/iterators.rs +++ b/src/prolog/iterators.rs @@ -40,7 +40,8 @@ impl<'a> QueryIterator<'a> { let state = TermIterState::Clause(0, ClauseType::Catch, terms); QueryIterator { state_stack: vec![state] } }, - &QueryTerm::Display(ref terms) => { + &QueryTerm::Display(ref terms) + | &QueryTerm::DuplicateTerm(ref terms) => { let state = TermIterState::Clause(0, ClauseType::Root, terms); QueryIterator { state_stack: vec![state] } }, @@ -292,7 +293,7 @@ impl<'a> ChunkedIterator<'a> arity = 3; break; }, - &QueryTerm::Is(_) => { + &QueryTerm::Is(_) | &QueryTerm::DuplicateTerm(_) => { result.push(term); arity = 2; break; diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 8b25cb14..53d4c4ee 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -48,8 +48,7 @@ impl<'a> CopierTarget for DuplicateTerm<'a> { } fn push(&mut self, hcv: HeapCellValue) { - self.state.heap.push(hcv); - self.state.heap.h += 1; + self.state.heap.push(hcv); } fn store(&self, a: Addr) -> Addr { @@ -1216,24 +1215,7 @@ impl MachineState { }; self.p += 1; - }, - &BuiltInInstruction::DuplicateTerm => { - let old_h = self.heap.h; - - let a1 = self[temp_v!(1)].clone(); - let a2 = self[temp_v!(2)].clone(); - - // drop the mutable references contained in gadget - // once the term has been duplicated. - { - let mut gadget = DuplicateTerm::new(self); - gadget.duplicate_term(a1); - } - - self.unify(Addr::HeapCell(old_h), a2); - - self.p += 1; - }, + }, &BuiltInInstruction::GetArg => try_or_fail!(self, { let val = self.try_get_arg(); @@ -1453,6 +1435,22 @@ impl MachineState { Ok(()) } + + fn duplicate_term(&mut self) { + let old_h = self.heap.h; + + let a1 = self[temp_v!(1)].clone(); + let a2 = self[temp_v!(2)].clone(); + + // drop the mutable references contained in gadget + // once the term has been duplicated. + { + let mut gadget = DuplicateTerm::new(self); + gadget.duplicate_term(a1); + } + + self.unify(Addr::HeapCell(old_h), a2); + } pub(super) fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction) { @@ -1534,6 +1532,14 @@ impl MachineState { self.p = self.cp; }, + &ControlInstruction::DuplicateTermCall => { + self.duplicate_term(); + self.p += 1; + }, + &ControlInstruction::DuplicateTermExecute => { + self.duplicate_term(); + self.p = self.cp; + }, &ControlInstruction::Execute(ref name, arity) => self.try_execute_predicate(code_dir, name.clone(), arity), &ControlInstruction::ExecuteN(arity) => diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 019e56e8..0562ef45 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -356,7 +356,7 @@ impl Machine { result += var.as_str(); result += " = "; - + result += self.ms.print_term(addr, TermFormatter {}).as_str(); } diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index b5b11d18..53cc2144 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -276,7 +276,7 @@ macro_rules! succeed { macro_rules! duplicate_term { () => ( - Line::BuiltIn(BuiltInInstruction::DuplicateTerm) + Line::Control(ControlInstruction::DuplicateTermCall) ) } @@ -393,3 +393,9 @@ macro_rules! infix { Fixity::In ) } + +macro_rules! display { + () => ( + Line::Control(ControlInstruction::DisplayCall) + ) +} diff --git a/src/prolog/parser b/src/prolog/parser index d2d6cd53..dcf51680 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit d2d6cd53af484607b89f3a979f51db66b3710c84 +Subproject commit dcf51680fb2f030ad2dcdd77237c8faedc8f7107