fix duplicate_term bug
This commit is contained in:
@@ -338,6 +338,7 @@ pub enum QueryTerm {
|
|||||||
Catch(Vec<Box<Term>>),
|
Catch(Vec<Box<Term>>),
|
||||||
Cut,
|
Cut,
|
||||||
Display(Vec<Box<Term>>),
|
Display(Vec<Box<Term>>),
|
||||||
|
DuplicateTerm(Vec<Box<Term>>),
|
||||||
Functor(Vec<Box<Term>>),
|
Functor(Vec<Box<Term>>),
|
||||||
Inlined(InlinedQueryTerm),
|
Inlined(InlinedQueryTerm),
|
||||||
Is(Vec<Box<Term>>),
|
Is(Vec<Box<Term>>),
|
||||||
@@ -350,8 +351,9 @@ impl QueryTerm {
|
|||||||
match self {
|
match self {
|
||||||
&QueryTerm::Arg(_) => 3,
|
&QueryTerm::Arg(_) => 3,
|
||||||
&QueryTerm::Catch(_) => 3,
|
&QueryTerm::Catch(_) => 3,
|
||||||
&QueryTerm::Throw(_) => 1,
|
&QueryTerm::Throw(_) => 1,
|
||||||
&QueryTerm::Display(_) => 1,
|
&QueryTerm::Display(_) => 1,
|
||||||
|
&QueryTerm::DuplicateTerm(_) => 2,
|
||||||
&QueryTerm::Functor(_) => 3,
|
&QueryTerm::Functor(_) => 3,
|
||||||
&QueryTerm::Inlined(ref term) => term.arity(),
|
&QueryTerm::Inlined(ref term) => term.arity(),
|
||||||
&QueryTerm::Is(_) => 2,
|
&QueryTerm::Is(_) => 2,
|
||||||
@@ -720,7 +722,6 @@ pub enum ArithmeticInstruction {
|
|||||||
pub enum BuiltInInstruction {
|
pub enum BuiltInInstruction {
|
||||||
CleanUpBlock,
|
CleanUpBlock,
|
||||||
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
|
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
|
||||||
DuplicateTerm,
|
|
||||||
EraseBall,
|
EraseBall,
|
||||||
Fail,
|
Fail,
|
||||||
GetArg,
|
GetArg,
|
||||||
@@ -751,6 +752,8 @@ pub enum ControlInstruction {
|
|||||||
Deallocate,
|
Deallocate,
|
||||||
DisplayCall,
|
DisplayCall,
|
||||||
DisplayExecute,
|
DisplayExecute,
|
||||||
|
DuplicateTermCall,
|
||||||
|
DuplicateTermExecute,
|
||||||
Execute(Rc<Atom>, usize),
|
Execute(Rc<Atom>, usize),
|
||||||
ExecuteN(usize),
|
ExecuteN(usize),
|
||||||
FunctorCall,
|
FunctorCall,
|
||||||
@@ -773,6 +776,8 @@ impl ControlInstruction {
|
|||||||
&ControlInstruction::CatchExecute => true,
|
&ControlInstruction::CatchExecute => true,
|
||||||
&ControlInstruction::DisplayCall => true,
|
&ControlInstruction::DisplayCall => true,
|
||||||
&ControlInstruction::DisplayExecute => true,
|
&ControlInstruction::DisplayExecute => true,
|
||||||
|
&ControlInstruction::DuplicateTermCall => true,
|
||||||
|
&ControlInstruction::DuplicateTermExecute => true,
|
||||||
&ControlInstruction::Execute(_, _) => true,
|
&ControlInstruction::Execute(_, _) => true,
|
||||||
&ControlInstruction::CallN(_) => true,
|
&ControlInstruction::CallN(_) => true,
|
||||||
&ControlInstruction::ExecuteN(_) => true,
|
&ControlInstruction::ExecuteN(_) => true,
|
||||||
|
|||||||
@@ -271,7 +271,9 @@ fn get_builtins() -> Code {
|
|||||||
put_value!(perm_v!(3), 4),
|
put_value!(perm_v!(3), 4),
|
||||||
put_value!(perm_v!(5), 5)],
|
put_value!(perm_v!(5), 5)],
|
||||||
deallocate!(),
|
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!("arg"), 3), (PredicateKeyType::BuiltIn, 150));
|
||||||
code_dir.insert((rc_atom!("integer"), 1), (PredicateKeyType::BuiltIn, 147));
|
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)
|
(builtin_code, code_dir, op_dir)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,6 +249,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
code.push(Line::Control(ControlInstruction::CatchCall)),
|
code.push(Line::Control(ControlInstruction::CatchCall)),
|
||||||
&QueryTerm::Display(_) =>
|
&QueryTerm::Display(_) =>
|
||||||
code.push(Line::Control(ControlInstruction::DisplayCall)),
|
code.push(Line::Control(ControlInstruction::DisplayCall)),
|
||||||
|
&QueryTerm::DuplicateTerm(_) =>
|
||||||
|
code.push(Line::Control(ControlInstruction::DuplicateTermCall)),
|
||||||
&QueryTerm::Functor(_) =>
|
&QueryTerm::Functor(_) =>
|
||||||
code.push(Line::Control(ControlInstruction::FunctorCall)),
|
code.push(Line::Control(ControlInstruction::FunctorCall)),
|
||||||
&QueryTerm::Inlined(_) =>
|
&QueryTerm::Inlined(_) =>
|
||||||
@@ -285,6 +287,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
*ctrl = ControlInstruction::ExecuteN(arity),
|
*ctrl = ControlInstruction::ExecuteN(arity),
|
||||||
ControlInstruction::DisplayCall =>
|
ControlInstruction::DisplayCall =>
|
||||||
*ctrl = ControlInstruction::DisplayExecute,
|
*ctrl = ControlInstruction::DisplayExecute,
|
||||||
|
ControlInstruction::DuplicateTermCall =>
|
||||||
|
*ctrl = ControlInstruction::DuplicateTermExecute,
|
||||||
ControlInstruction::FunctorCall =>
|
ControlInstruction::FunctorCall =>
|
||||||
*ctrl = ControlInstruction::FunctorExecute,
|
*ctrl = ControlInstruction::FunctorExecute,
|
||||||
ControlInstruction::CatchCall =>
|
ControlInstruction::CatchCall =>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub trait CopierTarget
|
|||||||
|
|
||||||
while scan < self.threshold() {
|
while scan < self.threshold() {
|
||||||
match self[scan].clone() {
|
match self[scan].clone() {
|
||||||
HeapCellValue::NamedStr(_, _, _) =>
|
HeapCellValue::NamedStr(..) =>
|
||||||
scan += 1,
|
scan += 1,
|
||||||
HeapCellValue::Addr(a) =>
|
HeapCellValue::Addr(a) =>
|
||||||
match a.clone() {
|
match a.clone() {
|
||||||
@@ -88,7 +88,7 @@ pub trait CopierTarget
|
|||||||
HeapCellValue::Addr(Addr::Str(o)) =>
|
HeapCellValue::Addr(Addr::Str(o)) =>
|
||||||
self[scan] = HeapCellValue::Addr(Addr::Str(o)),
|
self[scan] = HeapCellValue::Addr(Addr::Str(o)),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
};
|
||||||
|
|
||||||
scan += 1;
|
scan += 1;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ impl fmt::Display for ControlInstruction {
|
|||||||
write!(f, "call_display"),
|
write!(f, "call_display"),
|
||||||
&ControlInstruction::DisplayExecute =>
|
&ControlInstruction::DisplayExecute =>
|
||||||
write!(f, "execute_display"),
|
write!(f, "execute_display"),
|
||||||
|
&ControlInstruction::DuplicateTermCall =>
|
||||||
|
write!(f, "call_duplicate_term"),
|
||||||
|
&ControlInstruction::DuplicateTermExecute =>
|
||||||
|
write!(f, "execute_duplicate_term"),
|
||||||
&ControlInstruction::ExecuteN(arity) =>
|
&ControlInstruction::ExecuteN(arity) =>
|
||||||
write!(f, "execute_N {}", arity),
|
write!(f, "execute_N {}", arity),
|
||||||
&ControlInstruction::FunctorCall =>
|
&ControlInstruction::FunctorCall =>
|
||||||
@@ -160,8 +164,6 @@ impl fmt::Display for BuiltInInstruction {
|
|||||||
write!(f, "clean_up_block"),
|
write!(f, "clean_up_block"),
|
||||||
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
|
&BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
|
||||||
write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2),
|
write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2),
|
||||||
&BuiltInInstruction::DuplicateTerm =>
|
|
||||||
write!(f, "duplicate_term X1"),
|
|
||||||
&BuiltInInstruction::EraseBall =>
|
&BuiltInInstruction::EraseBall =>
|
||||||
write!(f, "erase_ball"),
|
write!(f, "erase_ball"),
|
||||||
&BuiltInInstruction::Fail =>
|
&BuiltInInstruction::Fail =>
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ impl<'a> QueryIterator<'a> {
|
|||||||
let state = TermIterState::Clause(0, ClauseType::Catch, terms);
|
let state = TermIterState::Clause(0, ClauseType::Catch, terms);
|
||||||
QueryIterator { state_stack: vec![state] }
|
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);
|
let state = TermIterState::Clause(0, ClauseType::Root, terms);
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
@@ -292,7 +293,7 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
arity = 3;
|
arity = 3;
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
&QueryTerm::Is(_) => {
|
&QueryTerm::Is(_) | &QueryTerm::DuplicateTerm(_) => {
|
||||||
result.push(term);
|
result.push(term);
|
||||||
arity = 2;
|
arity = 2;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ impl<'a> CopierTarget for DuplicateTerm<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, hcv: HeapCellValue) {
|
fn push(&mut self, hcv: HeapCellValue) {
|
||||||
self.state.heap.push(hcv);
|
self.state.heap.push(hcv);
|
||||||
self.state.heap.h += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store(&self, a: Addr) -> Addr {
|
fn store(&self, a: Addr) -> Addr {
|
||||||
@@ -1216,24 +1215,7 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.p += 1;
|
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 =>
|
&BuiltInInstruction::GetArg =>
|
||||||
try_or_fail!(self, {
|
try_or_fail!(self, {
|
||||||
let val = self.try_get_arg();
|
let val = self.try_get_arg();
|
||||||
@@ -1453,6 +1435,22 @@ impl MachineState {
|
|||||||
|
|
||||||
Ok(())
|
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)
|
pub(super) fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
|
||||||
{
|
{
|
||||||
@@ -1534,6 +1532,14 @@ impl MachineState {
|
|||||||
|
|
||||||
self.p = self.cp;
|
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) =>
|
&ControlInstruction::Execute(ref name, arity) =>
|
||||||
self.try_execute_predicate(code_dir, name.clone(), arity),
|
self.try_execute_predicate(code_dir, name.clone(), arity),
|
||||||
&ControlInstruction::ExecuteN(arity) =>
|
&ControlInstruction::ExecuteN(arity) =>
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ impl Machine {
|
|||||||
|
|
||||||
result += var.as_str();
|
result += var.as_str();
|
||||||
result += " = ";
|
result += " = ";
|
||||||
|
|
||||||
result += self.ms.print_term(addr, TermFormatter {}).as_str();
|
result += self.ms.print_term(addr, TermFormatter {}).as_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ macro_rules! succeed {
|
|||||||
|
|
||||||
macro_rules! duplicate_term {
|
macro_rules! duplicate_term {
|
||||||
() => (
|
() => (
|
||||||
Line::BuiltIn(BuiltInInstruction::DuplicateTerm)
|
Line::Control(ControlInstruction::DuplicateTermCall)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,3 +393,9 @@ macro_rules! infix {
|
|||||||
Fixity::In
|
Fixity::In
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! display {
|
||||||
|
() => (
|
||||||
|
Line::Control(ControlInstruction::DisplayCall)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Submodule src/prolog/parser updated: d2d6cd53af...dcf51680fb
Reference in New Issue
Block a user