fix duplicate_term bug
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 =>
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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 =>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -356,7 +356,7 @@ impl Machine {
|
||||
|
||||
result += var.as_str();
|
||||
result += " = ";
|
||||
|
||||
|
||||
result += self.ms.print_term(addr, TermFormatter {}).as_str();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
Submodule src/prolog/parser updated: d2d6cd53af...dcf51680fb
Reference in New Issue
Block a user