assert_eq!(submit(&mut wam, "?- catch(f(z), x, handle(y))."), true);
assert_eq!(submit(&mut wam, "?- catch(f(z), x, handle(z))."), false);
- submit(&mut wam, "f(X) :- throw(stuff). f(X) :- throw(other_stuff).");
+ submit(&mut wam, "f(X) :- throw(stuff).");
submit(&mut wam, "handle(stuff). handle(other_stuff).");
- // this should deterministically succeed with Exception = stuff.
+ // the first 3 cases should deterministically succeed.
assert_eq!(submit(&mut wam, "?- catch(f(X), Exception, handle(Exception))."), true);
assert_eq!(submit(&mut wam, "?- catch(f(X), Exception, handle(stuff))."), true);
assert_eq!(submit(&mut wam, "?- catch(f(X), Exception, handle(other_stuff))."), true);
#[derive(Clone, Hash, PartialEq, Eq)]
pub enum Constant {
Atom(Atom),
- UInt64(usize),
+ BlockNum(usize),
EmptyList
}
pub enum BuiltInInstruction {
CleanUpBlock,
- CopyTerm,
+ DuplicateTerm,
+ EraseBall,
Fail,
GetBall,
GetCurrentBlock,
Allocate(usize),
Call(Atom, usize, usize),
CallN(usize),
- Catch,
+ CatchCall,
+ CatchExecute,
Deallocate,
Execute(Atom, usize),
ExecuteN(usize),
Proceed,
- Throw
+ ThrowCall,
+ ThrowExecute
}
impl ControlInstruction {
pub fn is_jump_instr(&self) -> bool {
match self {
&ControlInstruction::Call(_, _, _) => true,
- &ControlInstruction::Catch => true,
+ &ControlInstruction::CatchCall => true,
+ &ControlInstruction::CatchExecute => true,
&ControlInstruction::Execute(_, _) => true,
&ControlInstruction::CallN(_) => true,
&ControlInstruction::ExecuteN(_) => true,
- &ControlInstruction::Throw => true,
+ &ControlInstruction::ThrowCall => true,
+ &ControlInstruction::ThrowExecute => true,
_ => false
}
}
is_var!(), // var/1, 3.
proceed!(),
allocate!(4), // catch/3, 5.
- query![get_var_in_query!(perm_v!(2), 1),
- get_var_in_query!(perm_v!(3), 2),
- get_var_in_query!(perm_v!(1), 3),
- put_var!(perm_v!(4), 1)],
+ fact![get_var_in_fact!(perm_v!(2), 1),
+ get_var_in_fact!(perm_v!(3), 2),
+ get_var_in_fact!(perm_v!(1), 3)],
+ query![put_var!(perm_v!(4), 1)],
get_current_block!(),
query![put_value!(perm_v!(2), 1),
put_value!(perm_v!(3), 2),
put_value!(perm_v!(1), 3),
put_unsafe_value!(4, 4)],
deallocate!(),
- goto!(11, 4),
- try_me_else!(9), // catch/4, 11.
+ goto!(12, 4), // goto catch/4.
+ try_me_else!(10), // catch/4, 12.
allocate!(3),
- query![get_var_in_query!(perm_v!(3), 1),
- get_var_in_query!(perm_v!(2), 4),
- put_var!(perm_v!(1), 1)],
+ fact![get_var_in_fact!(perm_v!(3), 1),
+ get_var_in_fact!(perm_v!(2), 4)],
+ query![put_var!(perm_v!(1), 1)],
install_new_block!(),
query![put_value!(perm_v!(3), 1)],
call_n!(1),
query![put_value!(perm_v!(2), 1),
put_unsafe_value!(1, 2)],
deallocate!(),
- goto!(42, 2), // goto end_block/2 at 42.
+ goto!(44, 2), //21: goto end_block/2.
trust_me!(),
- allocate!(4),
- query![get_var_in_query!(perm_v!(2), 2),
- get_var_in_query!(perm_v!(1), 3),
- get_var_in_query!(temp_v!(2), 1),
+ allocate!(3),
+ fact![get_var_in_fact!(perm_v!(2), 2),
+ get_var_in_fact!(perm_v!(1), 3)],
+ query![get_var_in_query!(temp_v!(2), 1),
put_value!(temp_v!(4), 1)],
reset_block!(),
- query![put_var!(perm_v!(4), 1)],
+ query![put_var!(perm_v!(3), 1)],
get_ball!(),
- query![put_value!(perm_v!(4), 1),
- put_var!(perm_v!(3), 2)],
- copy_term!(),
query![put_unsafe_value!(3, 1),
put_value!(perm_v!(2), 2),
put_value!(perm_v!(1), 3)],
deallocate!(),
- goto!(31, 2), // goto handle_ball/2.
- try_me_else!(10), // handle_ball/2, 31.
+ goto!(32, 2), // goto handle_ball/2.
+ try_me_else!(10), // handle_ball/2, 32.
allocate!(2),
get_level!(),
- query![get_var_in_query!(perm_v!(2), 3)],
+ fact![get_var_in_fact!(perm_v!(2), 3)],
unify!(),
cut!(non_terminal!()),
+ erase_ball!(),
query![put_value!(perm_v!(2), 1)],
deallocate!(),
execute_n!(1),
trust_me!(),
unwind_stack!(),
- try_me_else!(8), // end_block/2, 42.
+ try_me_else!(9), // end_block/2, 44.
allocate!(1),
- query![get_var_in_query!(perm_v!(1), 1),
- put_value!(temp_v!(2), 1)],
+ fact![get_var_in_fact!(perm_v!(1), 1)],
+ query![put_value!(temp_v!(2), 1)],
clean_up_block!(),
query![put_value!(perm_v!(1), 1)],
deallocate!(),
reset_block!(),
proceed!(),
- trust_me!(),
- allocate!(0),
+ trust_me!(), // 53.
+ allocate!(0),
query![get_var_in_query!(temp_v!(3), 1),
put_value!(temp_v!(2), 1)],
reset_block!(),
deallocate!(),
- goto!(58, 0), // goto false.
- set_ball!(), // throw/1, 56.
+ goto!(61, 0),
+ set_ball!(), // throw/1, 59.
unwind_stack!(),
- fail!(), // false/0, 58.
- proceed!(),
- try_me_else!(7), // not/1, 60.
+ fail!(), // false/0, 61.
+ try_me_else!(7), // not/1, 62.
allocate!(1),
get_level!(),
call_n!(1),
cut!(non_terminal!()),
deallocate!(),
- goto!(58, 0), // goto false.
+ goto!(61, 0),
trust_me!(),
proceed!(),
- copy_term!(), // copy_term/2, 69.
+ duplicate_term!(), // duplicate_term/2, 71.
proceed!()]
}
code_dir.insert((String::from("atomic"), 1), (PredicateKeyType::BuiltIn, 1));
code_dir.insert((String::from("var"), 1), (PredicateKeyType::BuiltIn, 3));
- code_dir.insert((String::from("false"), 0), (PredicateKeyType::BuiltIn, 58));
- code_dir.insert((String::from("not"), 1), (PredicateKeyType::BuiltIn, 60));
- code_dir.insert((String::from("copy_term"), 2), (PredicateKeyType::BuiltIn, 69));
+ code_dir.insert((String::from("false"), 0), (PredicateKeyType::BuiltIn, 61));
+ code_dir.insert((String::from("not"), 1), (PredicateKeyType::BuiltIn, 62));
+ code_dir.insert((String::from("duplicate_term"), 2), (PredicateKeyType::BuiltIn, 71));
code_dir.insert((String::from("catch"), 3), (PredicateKeyType::BuiltIn, 5));
- code_dir.insert((String::from("throw"), 1), (PredicateKeyType::BuiltIn, 56));
+ code_dir.insert((String::from("throw"), 1), (PredicateKeyType::BuiltIn, 59));
(builtin_code, code_dir)
}
compiled_query.push(Line::Control(call));
},
QueryTermRef::Catch(_) =>
- compiled_query.push(Line::Control(ControlInstruction::Catch)),
+ compiled_query.push(Line::Control(ControlInstruction::CatchCall)),
QueryTermRef::Term(&Term::Constant(_, Constant::Atom(ref atom))) => {
let call = ControlInstruction::Call(atom.clone(), 0, pvs);
compiled_query.push(Line::Control(call));
compiled_query.push(Line::Control(call));
},
QueryTermRef::Throw(_) =>
- compiled_query.push(Line::Control(ControlInstruction::Throw)),
+ compiled_query.push(Line::Control(ControlInstruction::ThrowCall)),
_ => {}
}
}
if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
*ctrl = ControlInstruction::ExecuteN(terms.len());
},
+ QueryTermRef::Catch(_) =>
+ if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
+ *ctrl = ControlInstruction::CatchExecute;
+ },
+ QueryTermRef::Throw(_) =>
+ if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
+ *ctrl = ControlInstruction::ThrowExecute;
+ },
_ => dealloc_index = body.len()
};
--- /dev/null
+use prolog::and_stack::*;
+use prolog::ast::*;
+
+use std::ops::IndexMut;
+
+pub trait CopierTarget
+{
+ fn source(&self) -> usize;
+ fn threshold(&self) -> usize;
+ fn push(&mut self, HeapCellValue);
+ fn store(&self, Addr) -> Addr;
+ fn deref(&self, Addr) -> Addr;
+ fn stack(&mut self) -> &mut AndStack;
+
+ // duplicate_term(L1, L2) uses Cheney's algorithm to copy the term at
+ // L1 to L2. forwarding_terms is kept to restore the innards of L1
+ // after it's been copied to L2.
+ fn duplicate_term(&mut self, a: Addr) where Self: IndexMut<usize, Output=HeapCellValue>
+ {
+ let mut forward_trail: Vec<(Ref, HeapCellValue)>= Vec::new();
+ let mut scan = self.source();
+ let old_h = self.threshold();
+
+ self.push(HeapCellValue::from(a));
+
+ while scan < self.threshold() {
+ match self[scan].clone() {
+ HeapCellValue::Con(_) | HeapCellValue::NamedStr(_, _) =>
+ scan += 1,
+ HeapCellValue::Lis(a) => {
+ self[scan] = HeapCellValue::Lis(self.threshold());
+
+ let hcv = self[a].clone();
+ self.push(hcv);
+
+ let hcv = self[a+1].clone();
+ self.push(hcv);
+
+ scan += 1;
+ },
+ HeapCellValue::Ref(r) => {
+ let ra = Addr::from(r);
+ let rd = self.store(self.deref(ra.clone()));
+
+ match rd {
+ Addr::HeapCell(hc) if hc >= old_h => {
+ self[scan] = HeapCellValue::Ref(Ref::HeapCell(hc));
+ scan += 1;
+ },
+ _ if ra == rd => {
+ self[scan] = HeapCellValue::Ref(Ref::HeapCell(scan));
+
+ match r {
+ Ref::HeapCell(hc) =>
+ self[hc] = HeapCellValue::Ref(Ref::HeapCell(scan)),
+ Ref::StackCell(fr, sc) =>
+ self.stack()[fr][sc] = Addr::HeapCell(scan)
+ };
+
+ forward_trail.push((r, HeapCellValue::Ref(r)));
+ scan += 1;
+ },
+ _ => self[scan] = HeapCellValue::from(rd)
+ }
+ },
+ HeapCellValue::Str(s) => {
+ match self[s].clone() {
+ HeapCellValue::NamedStr(arity, name) => {
+ let threshold = self.threshold();
+
+ self[scan] = HeapCellValue::Str(threshold);
+ self[s] = HeapCellValue::Str(threshold);
+
+ forward_trail.push((Ref::HeapCell(s),
+ HeapCellValue::NamedStr(arity, name.clone())));
+
+ self.push(HeapCellValue::NamedStr(arity, name));
+
+ for i in 0 .. arity {
+ let hcv = self[s + 1 + i].clone();
+ self.push(hcv);
+ }
+ },
+ HeapCellValue::Str(o) =>
+ self[scan] = HeapCellValue::Str(o),
+ _ => {}
+ };
+
+ scan += 1;
+ }
+ };
+ }
+
+ for (r, hcv) in forward_trail {
+ match r {
+ Ref::HeapCell(hc) => self[hc] = hcv,
+ Ref::StackCell(fr, sc) => self.stack()[fr][sc] = hcv.as_addr(0)
+ }
+ }
+ }
+}
+
write!(f, "{}", atom),
&Constant::EmptyList =>
write!(f, "[]"),
- &Constant::UInt64(integer) =>
+ &Constant::BlockNum(integer) =>
write!(f, "u{}", integer)
}
}
&FactInstruction::GetValue(ref x, ref a) =>
write!(f, "get_value {}, A{}", x, a),
&FactInstruction::GetVariable(ref x, ref a) =>
- write!(f, "get_variable {}, A{}", x, a),
+ write!(f, "fact:get_variable {}, A{}", x, a),
&FactInstruction::UnifyConstant(ref constant) =>
write!(f, "unify_constant {}", constant),
&FactInstruction::UnifyVariable(ref r) =>
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&QueryInstruction::GetVariable(ref x, ref a) =>
- write!(f, "get_variable {}, A{}", x, a),
+ write!(f, "query:get_variable {}, A{}", x, a),
&QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
write!(f, "put_constant {}, A{}", constant, r.reg_num()),
&QueryInstruction::PutConstant(Level::Deep, ref constant, ref r) =>
write!(f, "call {}/{}, {}", name, arity, pvs),
&ControlInstruction::CallN(arity) =>
write!(f, "call_N {}", arity),
- &ControlInstruction::Catch =>
- write!(f, "catch"),
+ &ControlInstruction::CatchCall =>
+ write!(f, "call_catch"),
+ &ControlInstruction::CatchExecute =>
+ write!(f, "execute_catch"),
&ControlInstruction::ExecuteN(arity) =>
write!(f, "execute_N {}", arity),
&ControlInstruction::Deallocate =>
write!(f, "execute {}/{}", name, arity),
&ControlInstruction::Proceed =>
write!(f, "proceed"),
- &ControlInstruction::Throw =>
- write!(f, "throw")
+ &ControlInstruction::ThrowCall =>
+ write!(f, "call_throw"),
+ &ControlInstruction::ThrowExecute =>
+ write!(f, "execute_throw")
}
}
}
if is_consistent(clauses) {
let compiled_pred = cg.compile_predicate(clauses);
+ print_code(&compiled_pred);
wam.add_predicate(clauses, compiled_pred)
} else {
let msg = r"Error: predicate is inconsistent.
let mut cg = CodeGenerator::<DebrayAllocator>::new();
let compiled_rule = cg.compile_rule(rule);
+ print_code(&compiled_rule);
wam.add_rule(rule, compiled_rule)
},
&TopLevel::Query(ref query) => {
let mut cg = CodeGenerator::<DebrayAllocator>::new();
let compiled_query = cg.compile_query(query);
+ print_code(&compiled_query);
wam.submit_query(compiled_query, cg.take_vars())
}
}
use prolog::ast::*;
use prolog::builtins::*;
use prolog::codegen::*;
+use prolog::copier::*;
use prolog::heapview::*;
use prolog::and_stack::*;
use prolog::or_stack::*;
tr: usize,
hb: usize,
block: usize, // an offset into the OR stack.
- ball: Addr
+ ball: Heap
+}
+
+struct DuplicateTerm<'a> {
+ state: &'a mut MachineState
+}
+
+impl<'a> DuplicateTerm<'a> {
+ fn new(state: &'a mut MachineState) -> Self {
+ DuplicateTerm { state: state }
+ }
+}
+
+impl<'a> Index<usize> for DuplicateTerm<'a> {
+ type Output = HeapCellValue;
+
+ fn index(&self, index: usize) -> &Self::Output {
+ &self.state.heap[index]
+ }
+}
+
+impl<'a> IndexMut<usize> for DuplicateTerm<'a> {
+ fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+ &mut self.state.heap[index]
+ }
+}
+
+// the ordinary, heap term copier, used by duplicate_term.
+impl<'a> CopierTarget for DuplicateTerm<'a> {
+ fn source(&self) -> usize {
+ self.state.h
+ }
+
+ fn threshold(&self) -> usize {
+ self.state.h
+ }
+
+ fn push(&mut self, hcv: HeapCellValue) {
+ self.state.heap.push(hcv);
+ self.state.h += 1;
+ }
+
+ fn store(&self, a: Addr) -> Addr {
+ self.state.store(a)
+ }
+
+ fn deref(&self, a: Addr) -> Addr {
+ self.state.deref(a)
+ }
+
+ fn stack(&mut self) -> &mut AndStack {
+ &mut self.state.and_stack
+ }
+}
+
+struct DuplicateBallTerm<'a> {
+ state: &'a mut MachineState,
+ heap_boundary: usize
+}
+
+impl<'a> DuplicateBallTerm<'a> {
+ fn new(state: &'a mut MachineState) -> Self {
+ let hb = state.heap.len();
+ DuplicateBallTerm { state: state, heap_boundary: hb }
+ }
+}
+
+impl<'a> Index<usize> for DuplicateBallTerm<'a> {
+ type Output = HeapCellValue;
+
+ fn index(&self, index: usize) -> &Self::Output {
+ if index < self.heap_boundary {
+ &self.state.heap[index]
+ } else {
+ let index = index - self.heap_boundary;
+ &self.state.ball[index]
+ }
+ }
+}
+
+impl<'a> IndexMut<usize> for DuplicateBallTerm<'a> {
+ fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+ if index < self.heap_boundary {
+ &mut self.state.heap[index]
+ } else {
+ let index = index - self.heap_boundary;
+ &mut self.state.ball[index]
+ }
+ }
+}
+
+// the ordinary, heap term copier, used by duplicate_term.
+impl<'a> CopierTarget for DuplicateBallTerm<'a> {
+ fn source(&self) -> usize {
+ self.heap_boundary
+ }
+
+ fn threshold(&self) -> usize {
+ self.heap_boundary + self.state.ball.len()
+ }
+
+ fn push(&mut self, hcv: HeapCellValue) {
+ self.state.ball.push(hcv);
+ }
+
+ fn store(&self, a: Addr) -> Addr {
+ self.state.store(a)
+ }
+
+ fn deref(&self, a: Addr) -> Addr {
+ self.state.deref(a)
+ }
+
+ fn stack(&mut self) -> &mut AndStack {
+ &mut self.state.and_stack
+ }
}
pub struct Machine {
while let Some(view) = viewer.next() {
match view {
- CellView::Con(&Constant::UInt64(integer)) =>
+ CellView::Con(&Constant::BlockNum(integer)) =>
result += integer.to_string().as_str(),
CellView::Con(&Constant::EmptyList) =>
result += "[]",
tr: 0,
hb: 0,
block: 0,
- ball: Addr::Con(Constant::UInt64(0))
+ ball: Vec::new()
}
}
-
+
fn num_frames(&self) -> usize {
self.and_stack.len() + self.or_stack.len()
}
};
}
- // copy_term(L1, L2) uses Cheney's algorithm to copy the term at
- // L1 to L2. forwarding_terms is kept to restore the innards of L1
- // after it's been copied to L2.
- fn copy_term(&mut self, a: Addr)
- {
- let mut forward_trail = Vec::new(); // list of (Ref, HeapCellValue) items.
- let mut scan = self.h;
- let old_h = self.h;
-
- self.heap.push(HeapCellValue::from(a));
- self.h += 1;
-
- while scan < self.h {
- match self.heap[scan].clone() {
- HeapCellValue::Con(_) | HeapCellValue::NamedStr(_, _) =>
- scan += 1,
- HeapCellValue::Lis(a) => {
- let hcv = self.heap[a].clone();
- self.heap.push(hcv);
-
- let hcv = self.heap[a+1].clone();
- self.heap.push(hcv);
-
- self.heap[scan] = HeapCellValue::Lis(self.h);
-
- self.h += 2;
- scan += 1;
- },
- HeapCellValue::Ref(r) => {
- let ra = Addr::from(r);
- let rd = self.store(self.deref(ra.clone()));
-
- match rd {
- Addr::HeapCell(hc) if hc >= old_h => {
- self.heap[scan] = HeapCellValue::Ref(Ref::HeapCell(hc));
- scan += 1;
- },
- _ if ra == rd => {
- self.heap[scan] = HeapCellValue::Ref(Ref::HeapCell(scan));
-
- match r {
- Ref::HeapCell(hc) =>
- self.heap[hc] = HeapCellValue::Ref(Ref::HeapCell(scan)),
- Ref::StackCell(fr, sc) =>
- self.and_stack[fr][sc] = Addr::HeapCell(scan),
- };
-
- forward_trail.push((r, HeapCellValue::Ref(r)));
- scan += 1;
- },
- _ => self.heap[scan] = HeapCellValue::from(rd)
- }
- },
- HeapCellValue::Str(s) => {
- match self.heap[s].clone() {
- HeapCellValue::NamedStr(arity, name) => {
- self.heap[scan] = HeapCellValue::Str(self.h);
- self.heap[s] = HeapCellValue::Str(self.h);
-
- forward_trail.push((Ref::HeapCell(s),
- HeapCellValue::NamedStr(arity, name.clone())));
-
- self.heap.push(HeapCellValue::NamedStr(arity, name));
- self.h += 1;
-
- for i in 0 .. arity {
- let hcv = self.heap[s + 1 + i].clone();
- self.heap.push(hcv);
- self.h += 1;
- }
-
- },
- HeapCellValue::Str(o) =>
- self.heap[scan] = HeapCellValue::Str(o),
- _ => {}
- }
-
- scan += 1;
- }
- };
- }
-
- for (r, hcv) in forward_trail {
- match r {
- Ref::HeapCell(hc) => self.heap[hc] = hcv,
- Ref::StackCell(fr, sc) => self.and_stack[fr][sc] = hcv.as_addr(0)
- }
- }
- }
-
fn handle_internal_call_n(&mut self, code_dir: &CodeDir)
{
let arity = self.num_of_args + 1;
Some((name, arity + narity - 1))
}
- fn has_null_ball(&self) -> bool
- {
- if let &Addr::Con(Constant::UInt64(_)) = &self.ball {
- true
- } else {
- false
- }
- }
-
fn execute_built_in_instr(&mut self, code_dir: &CodeDir, instr: &BuiltInInstruction)
{
match instr {
- &BuiltInInstruction::CopyTerm => {
+ &BuiltInInstruction::DuplicateTerm => {
let old_h = self.h;
- let a = self[temp_v!(1)].clone();
- self.copy_term(a);
-
+
+ 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::GetCurrentBlock => {
- let c = Constant::UInt64(self.block);
+ let c = Constant::BlockNum(self.block);
let addr = self[temp_v!(1)].clone();
self.write_constant_to_var(addr, &c);
self.unify(a1, a2);
self.p += 1;
},
+ &BuiltInInstruction::EraseBall => {
+ self.ball.truncate(0);
+ self.p += 1;
+ },
&BuiltInInstruction::GetBall => {
- let addr = self.store(self.deref(self[temp_v!(1)].clone()));
- let ball = self.ball.clone();
+ let addr = self.store(self.deref(self[temp_v!(1)].clone()));
+ let h = self.h;
- if self.has_null_ball() {
+ if self.ball.len() > 0 {
+ let copied_ball_iter = self.ball.iter().cloned();
+ self.heap.extend(copied_ball_iter);
+ self.h += self.ball.len();
+ } else {
self.fail = true;
return;
}
+ let ball = self.heap[h].as_addr(h);
+
match addr.as_ref() {
Some(r) => {
self.bind(r, ball);
};
},
&BuiltInInstruction::SetBall => {
- self.ball = self[temp_v!(1)].clone();
+ let addr = self[temp_v!(1)].clone();
+
+ {
+ let mut duplicator = DuplicateBallTerm::new(self);
+ duplicator.duplicate_term(addr);
+ }
+
self.p += 1;
},
&BuiltInInstruction::CleanUpBlock => {
let nb = self.store(self.deref(self[temp_v!(1)].clone()));
match nb {
- Addr::Con(Constant::UInt64(nb)) => {
+ Addr::Con(Constant::BlockNum(nb)) => {
let b = self.b - 1;
if nb > 0 && self.or_stack[b].b == nb {
},
&BuiltInInstruction::InstallNewBlock => {
self.block = self.b;
- let c = Constant::UInt64(self.block);
+ let c = Constant::BlockNum(self.block);
let addr = self[temp_v!(1)].clone();
self.write_constant_to_var(addr, &c);
let addr = self.deref(self[temp_v!(1)].clone());
match self.store(addr) {
- Addr::Con(Constant::UInt64(b)) => {
+ Addr::Con(Constant::BlockNum(b)) => {
self.block = b;
self.p += 1;
},
},
&ControlInstruction::Call(ref name, arity, _) =>
self.try_call_predicate(code_dir, name.clone(), arity),
- &ControlInstruction::Catch => {
+ &ControlInstruction::CatchCall => {
self.cp = self.p + 1;
self.num_of_args = 3;
self.b0 = self.b;
self.p = CodePtr::DirEntry(5);
},
+ &ControlInstruction::CatchExecute => {
+ self.num_of_args = 3;
+ self.b0 = self.b;
+ self.p = CodePtr::DirEntry(5);
+ },
&ControlInstruction::CallN(arity) =>
if let Some((name, arity)) = self.setup_call_n(arity) {
self.try_call_predicate(code_dir, name, arity);
},
&ControlInstruction::Proceed =>
self.p = self.cp,
- &ControlInstruction::Throw => {
+ &ControlInstruction::ThrowCall => {
self.cp = self.p + 1;
self.num_of_args = 1;
self.b0 = self.b;
- self.p = CodePtr::DirEntry(56);
+ self.p = CodePtr::DirEntry(59);
+ },
+ &ControlInstruction::ThrowExecute => {
+ self.num_of_args = 1;
+ self.b0 = self.b;
+ self.p = CodePtr::DirEntry(59);
}
};
}
)
}
+macro_rules! fact {
+ [$($x:expr),+] => (
+ Line::Fact(vec![$($x),+])
+ )
+}
+
macro_rules! temp_v {
($x:expr) => (
RegType::Temp($x)
)
}
+macro_rules! get_var_in_fact {
+ ($r:expr, $arg:expr) => (
+ FactInstruction::GetVariable($r, $arg)
+ )
+}
+
macro_rules! put_var {
($r:expr, $arg:expr) => (
QueryInstruction::PutVariable($r, $arg)
)
}
+macro_rules! erase_ball {
+ () => (
+ Line::BuiltIn(BuiltInInstruction::EraseBall)
+ )
+}
+
macro_rules! unify {
() => (
Line::BuiltIn(BuiltInInstruction::Unify)
)
}
-macro_rules! copy_term {
+macro_rules! duplicate_term {
() => (
- Line::BuiltIn(BuiltInInstruction::CopyTerm)
+ Line::BuiltIn(BuiltInInstruction::DuplicateTerm)
)
}
pub mod and_stack;
pub mod ast;
pub mod codegen;
+pub mod copier;
pub mod debray_allocator;
pub mod fixtures;
pub mod heapview;