Catch(Vec<Box<Term>>),
Cut,
Display(Vec<Box<Term>>),
+ DuplicateTerm(Vec<Box<Term>>),
Functor(Vec<Box<Term>>),
Inlined(InlinedQueryTerm),
Is(Vec<Box<Term>>),
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,
pub enum BuiltInInstruction {
CleanUpBlock,
CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
- DuplicateTerm,
EraseBall,
Fail,
GetArg,
Deallocate,
DisplayCall,
DisplayExecute,
+ DuplicateTermCall,
+ DuplicateTermExecute,
Execute(Rc<Atom>, usize),
ExecuteN(usize),
FunctorCall,
&ControlInstruction::CatchExecute => true,
&ControlInstruction::DisplayCall => true,
&ControlInstruction::DisplayExecute => true,
+ &ControlInstruction::DuplicateTermCall => true,
+ &ControlInstruction::DuplicateTermExecute => true,
&ControlInstruction::Execute(_, _) => true,
&ControlInstruction::CallN(_) => true,
&ControlInstruction::ExecuteN(_) => true,
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!()
]
}
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)
}
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(_) =>
*ctrl = ControlInstruction::ExecuteN(arity),
ControlInstruction::DisplayCall =>
*ctrl = ControlInstruction::DisplayExecute,
+ ControlInstruction::DuplicateTermCall =>
+ *ctrl = ControlInstruction::DuplicateTermExecute,
ControlInstruction::FunctorCall =>
*ctrl = ControlInstruction::FunctorExecute,
ControlInstruction::CatchCall =>
while scan < self.threshold() {
match self[scan].clone() {
- HeapCellValue::NamedStr(_, _, _) =>
+ HeapCellValue::NamedStr(..) =>
scan += 1,
HeapCellValue::Addr(a) =>
match a.clone() {
HeapCellValue::Addr(Addr::Str(o)) =>
self[scan] = HeapCellValue::Addr(Addr::Str(o)),
_ => {}
- }
+ };
scan += 1;
},
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 =>
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 =>
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] }
},
arity = 3;
break;
},
- &QueryTerm::Is(_) => {
+ &QueryTerm::Is(_) | &QueryTerm::DuplicateTerm(_) => {
result.push(term);
arity = 2;
break;
}
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 {
};
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();
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)
{
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) =>
result += var.as_str();
result += " = ";
-
+
result += self.ms.print_term(addr, TermFormatter {}).as_str();
}
macro_rules! duplicate_term {
() => (
- Line::BuiltIn(BuiltInInstruction::DuplicateTerm)
+ Line::Control(ControlInstruction::DuplicateTermCall)
)
}
Fixity::In
)
}
+
+macro_rules! display {
+ () => (
+ Line::Control(ControlInstruction::DisplayCall)
+ )
+}
-Subproject commit d2d6cd53af484607b89f3a979f51db66b3710c84
+Subproject commit dcf51680fb2f030ad2dcdd77237c8faedc8f7107