fix duplicate_term bug

This commit is contained in:
Mark Thom
2018-01-14 23:05:15 -07:00
parent 08b94dcdf5
commit a4022d569f
10 changed files with 60 additions and 32 deletions

View File

@@ -338,6 +338,7 @@ pub enum QueryTerm {
Catch(Vec<Box<Term>>),
Cut,
Display(Vec<Box<Term>>),
DuplicateTerm(Vec<Box<Term>>),
Functor(Vec<Box<Term>>),
Inlined(InlinedQueryTerm),
Is(Vec<Box<Term>>),
@@ -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<Atom>, 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,

View File

@@ -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)
}

View File

@@ -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 =>

View File

@@ -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;
},

View File

@@ -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 =>

View File

@@ -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;

View File

@@ -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) =>

View File

@@ -356,7 +356,7 @@ impl Machine {
result += var.as_str();
result += " = ";
result += self.ms.print_term(addr, TermFormatter {}).as_str();
}

View File

@@ -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)
)
}