}
fn push(&mut self, hcv: HeapCellValue) {
- self.state.heap.push(hcv);
+ self.state.heap.push(hcv);
}
fn store(&self, a: Addr) -> Addr {
}
}
- pub(crate) fn deref(&self, mut a: Addr) -> Addr {
+ pub(crate) fn deref(&self, mut a: Addr) -> Addr {
loop {
let value = self.store(a.clone());
self.trail(r1);
}
-
+
fn print_var<Fmt, Outputter>(&self, r: Ref, fmt: Fmt, output: Outputter) -> Outputter
where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
- {
- let iter = HeapCellIterator::new(&self, r);
+ {
+ let iter = HeapCellPreOrderIterator::new(&self, r);
let printer = HeapCellPrinter::new(iter, fmt, output);
printer.print()
self.print_var(Ref::StackCell(fr, sc), fmt, output)
}
}
-
+
fn unify(&mut self, a1: Addr, a2: Addr) {
let mut pdl = vec![a1, a2];
};
}
- fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, Vec<HeapCellValue>> {
-
+ fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, Vec<HeapCellValue>> {
+
match at {
&ArithmeticTerm::Reg(r) => {
let addr = self[r].clone();
}
}
- fn signed_bitwise_op<Op>(&mut self, n1: &BigInt, n2: &BigInt, t: usize, f: Op)
+ fn signed_bitwise_op<Op>(&self, n1: &BigInt, n2: &BigInt, f: Op) -> Rc<BigInt>
where Op: FnOnce(&BigUint, &BigUint) -> BigUint
{
let n1_b = n1.to_signed_bytes_le();
let u_n1 = BigUint::from_bytes_le(&n1_b);
let u_n2 = BigUint::from_bytes_le(&n2_b);
- let result = BigInt::from_signed_bytes_le(&f(&u_n1, &u_n2).to_bytes_le());
+ Rc::new(BigInt::from_signed_bytes_le(&f(&u_n1, &u_n2).to_bytes_le()))
+ }
+
+ fn arith_eval_by_metacall(&self) -> Result<Number, Vec<HeapCellValue>>
+ {
+ let instantiation_err = functor!(self.atom_tbl.clone(), "instantiation_error", 1,
+ [heap_atom!("(is)/2", self.atom_tbl.clone())]);
+
+ let a = self[temp_v!(2)].clone();
+
+ if let &Addr::Con(Constant::Number(ref n)) = &a {
+ return Ok(n.clone());
+ }
+
+ let r = match a {
+ Addr::Str(h) | Addr::HeapCell(h) => Ok(Ref::HeapCell(h)),
+ Addr::StackCell(fr, sc) => Ok(Ref::StackCell(fr, sc)),
+ _ => Err(instantiation_err.clone())
+ }?;
+
+ let mut interms: Vec<Number> = Vec::with_capacity(64);
+
+ for heap_val in self.post_order_iter(r) {
+ match heap_val {
+ HeapCellValue::NamedStr(2, name, Some(Fixity::In)) => {
+ let a2 = interms.pop().unwrap();
+ let a1 = interms.pop().unwrap();
+
+ match name.as_str() {
+ "+" => interms.push(a1 + a2),
+ "-" => interms.push(a1 - a2),
+ "*" => interms.push(a1 * a2),
+ "rdiv" =>
+ match NumberPair::from(a1, a2) {
+ NumberPair::Rational(r1, r2) =>
+ interms.push(Number::Rational(self.rdiv(r1, r2)?)),
+ _ =>
+ return Err(instantiation_err)
+ },
+ "//" => interms.push(Number::Integer(self.idiv(a1, a2)?)),
+ "div" => interms.push(Number::Integer(self.fidiv(a1, a2)?)),
+ ">>" => interms.push(Number::Integer(self.shr(a1, a2)?)),
+ "<<" => interms.push(Number::Integer(self.shl(a1, a2)?)),
+ "/\\" => interms.push(Number::Integer(self.and(a1, a2)?)),
+ "\\/" => interms.push(Number::Integer(self.or(a1, a2)?)),
+ "xor" => interms.push(Number::Integer(self.xor(a1, a2)?)),
+ "mod" => interms.push(Number::Integer(self.modulus(a1, a2)?)),
+ "rem" => interms.push(Number::Integer(self.remainder(a1, a2)?)),
+ _ => return Err(instantiation_err)
+ }
+ },
+ HeapCellValue::NamedStr(1, name, Some(Fixity::Pre)) => {
+ let a1 = interms.pop().unwrap();
+
+ match name.as_str() {
+ "-" => interms.push(- a1),
+ _ => return Err(instantiation_err)
+ }
+ },
+ HeapCellValue::Addr(Addr::Con(Constant::Number(n))) =>
+ interms.push(n),
+ _ =>
+ return Err(instantiation_err)
+ }
+ };
+
+ Ok(interms.pop().unwrap())
+ }
+
+ fn rdiv(&self, r1: Rc<Ratio<BigInt>>, r2: Rc<Ratio<BigInt>>)
+ -> Result<Rc<Ratio<BigInt>>, Vec<HeapCellValue>>
+ {
+ if *r2 == Ratio::zero() {
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("zero_divisor", self.atom_tbl.clone())]))
+ } else {
+ Ok(Rc::new(&*r1 / &*r2))
+ }
+ }
+
+ fn fidiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ if *n2 == BigInt::zero() {
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("zero_divisor", self.atom_tbl.clone())]))
+ } else {
+ Ok(Rc::new(n1.div_floor(&n2)))
+ },
+ _ => Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn idiv(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ if *n2 == BigInt::zero() {
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("zero_divisor", self.atom_tbl.clone())]))
+ } else {
+ Ok(Rc::new(&*n1 / &*n2))
+ },
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn div(&self, n1: Number, n2: Number) -> Result<Number, Vec<HeapCellValue>>
+ {
+ if n2.is_zero() {
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("zero_divisor", self.atom_tbl.clone())]))
+ } else {
+ Ok(n1 / n2)
+ }
+ }
+
+ fn shr(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ match n2.to_usize() {
+ Some(n2) => Ok(Rc::new(&*n1 >> n2)),
+ _ => Ok(Rc::new(&*n1 >> usize::max_value()))
+ },
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn shl(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ match n2.to_usize() {
+ Some(n2) => Ok(Rc::new(&*n1 << n2)),
+ _ => Ok(Rc::new(&*n1 << usize::max_value()))
+ },
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn xor(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 ^ u_n2)),
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn and(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)),
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
- self.interms[t - 1] = Number::Integer(Rc::new(result));
+ fn modulus(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ if *n2 == BigInt::zero() {
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("zero_divisor", self.atom_tbl.clone())]))
+ } else {
+ Ok(Rc::new(n1.mod_floor(&n2)))
+ },
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn remainder(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ if *n2 == BigInt::zero() {
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("zero_divisor", self.atom_tbl.clone())]))
+ } else {
+ Ok(Rc::new(&*n1 % &*n2))
+ },
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
+ }
+
+ fn or(&self, n1: Number, n2: Number) -> Result<Rc<BigInt>, Vec<HeapCellValue>>
+ {
+ match (n1, n2) {
+ (Number::Integer(n1), Number::Integer(n2)) =>
+ Ok(self.signed_bitwise_op(&*n1, &*n2, |u_n1, u_n2| u_n1 & u_n2)),
+ _ =>
+ Err(functor!(self.atom_tbl.clone(), "evaluation_error", 1,
+ [heap_atom!("expected_integer_args", self.atom_tbl.clone())]))
+ }
}
pub(super) fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction) {
let r1 = try_or_fail!(self, self.get_rational(a1));
let r2 = try_or_fail!(self, self.get_rational(a2));
- if *r2 == Ratio::zero() {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("zero_divisor", atom_tbl)]));
- return;
- }
-
- self.interms[t - 1] = Number::Rational(Rc::new(&*r1 / &*r2));
+ self.interms[t - 1] = Number::Rational(try_or_fail!(self, self.rdiv(r1, r2)));
self.p += 1;
},
&ArithmeticInstruction::FIDiv(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) => {
- if *n2 == BigInt::zero() {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("zero_divisor", atom_tbl)]));
- return;
- }
-
- self.interms[t - 1] = Number::Integer(Rc::new(n1.div_floor(&n2)));
- },
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- }
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.fidiv(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::IDiv(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) => {
- if *n2 == BigInt::zero() {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("zero_divisor", atom_tbl)]));
- return;
- }
-
- self.interms[t - 1] = Number::Integer(Rc::new(&*n1 / &*n2));
- self.p += 1;
- },
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- }
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.idiv(n1, n2)));
+ self.p += 1;
},
&ArithmeticInstruction::Neg(ref a1, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- if n2.is_zero() {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("zero_divisor", atom_tbl)]));
- return;
- }
-
- self.interms[t - 1] = n1 / n2;
+ self.interms[t - 1] = try_or_fail!(self, self.div(n1, n2));
self.p += 1;
},
&ArithmeticInstruction::Shr(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- match n2.to_usize() {
- Some(n2) => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 >> n2)),
- _ => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 >> usize::max_value()))
- },
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- }
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.shr(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::Shl(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- match n2.to_usize() {
- Some(n2) => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 << n2)),
- _ => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 << usize::max_value()))
- },
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- }
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.shl(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::Xor(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- self.signed_bitwise_op(&*n1, &*n2, t, |u_n1, u_n2| u_n1 ^ u_n2),
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- };
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.xor(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::And(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- self.signed_bitwise_op(&*n1, &*n2, t, |u_n1, u_n2| u_n1 & u_n2),
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- };
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.and(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::Or(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) =>
- self.signed_bitwise_op(&*n1, &*n2, t, |u_n1, u_n2| u_n1 | u_n2),
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- };
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.or(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::Mod(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) => {
- if *n2 == BigInt::zero() {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("zero_divisor", atom_tbl)]));
- return;
- }
-
- self.interms[t - 1] = Number::Integer(Rc::new(n1.mod_floor(&n2)));
- },
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- }
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.modulus(n1, n2)));
self.p += 1;
},
&ArithmeticInstruction::Rem(ref a1, ref a2, t) => {
let n1 = try_or_fail!(self, self.get_number(a1));
let n2 = try_or_fail!(self, self.get_number(a2));
- match (n1, n2) {
- (Number::Integer(n1), Number::Integer(n2)) => {
- if *n2 == BigInt::zero() {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("zero_divisor", atom_tbl)]));
- return;
- }
-
- self.interms[t - 1] = Number::Integer(Rc::new(&*n1 % &*n2));
- },
- _ => {
- let atom_tbl = self.atom_tbl.clone();
- self.throw_exception(functor!(atom_tbl,
- "evaluation_error",
- 1,
- [heap_atom!("expected_integer_args", atom_tbl)]));
- return;
- }
- }
-
+ self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.remainder(n1, n2)));
self.p += 1;
}
};
fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
let h = self.heap.h;
-
+
self.registers[1] = Addr::HeapCell(h);
-
+
self.heap.append(hcv);
self.goto_throw();
}
fn try_get_arg(&mut self) -> Result<(), Vec<HeapCellValue>>
{
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
-
+
if let Addr::Con(Constant::Number(Number::Integer(i))) = a1 {
let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
Some(i) if 1 <= i && i <= arity => {
let a3 = self[temp_v!(3)].clone();
let h_a = Addr::HeapCell(o + i);
-
+
self.unify(a3, h_a);
},
_ => self.fail = true
},
_ => self.fail = true
- };
+ };
} else {
return Err(functor!(self.atom_tbl,
"type_error",
Ok(())
}
-
+
pub(super) fn execute_built_in_instr(&mut self, code_dir: &CodeDir, instr: &BuiltInInstruction)
{
match instr {
};
self.p += 1;
- },
- &BuiltInInstruction::GetArg =>
+ },
+ &BuiltInInstruction::GetArg =>
try_or_fail!(self, {
let val = self.try_get_arg();
self.p = self.cp;
&BuiltInInstruction::GetCutPoint(r) => {
let c = Constant::Usize(self.b);
self[r] = Addr::Con(c);
-
+
+ self.p += 1;
+ },
+ &BuiltInInstruction::IsOnHeap => {
+ let a1 = self[temp_v!(1)].clone();
+ let result = try_or_fail!(self, self.arith_eval_by_metacall());
+
+ self.unify(a1, Addr::Con(Constant::Number(result)));
self.p += 1;
},
&BuiltInInstruction::SetBall => {
match a1.clone() {
Addr::Str(o) =>
match self.heap[o].clone() {
- HeapCellValue::NamedStr(arity, name, _) => {
+ HeapCellValue::NamedStr(arity, name, _) => {
let name = Addr::Con(Constant::Atom(name)); // A2
let arity = Addr::Con(Constant::Number(rc_integer!(arity)));
let a2 = self[temp_v!(2)].clone();
self.unify(a2, name);
-
+
if !self.fail {
let a3 = self[temp_v!(3)].clone();
self.unify(a3, arity);
return Ok(());
}
};
-
+
self.heap.push(HeapCellValue::NamedStr(arity, name, None));
for _ in 0 .. arity {
let h = self.heap.h;
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
}
-
- self.unify(a1, f_a);
+
+ self.unify(a1, f_a);
} else {
return Err(functor!(self.atom_tbl, "instantiation_error", 0, []));
}
} else {
return Err(functor!(self.atom_tbl, "instantiation_error", 0, []));
- }
+ }
},
_ => {
let a2 = self[temp_v!(2)].clone();
self.unify(a1, a2);
-
+
if !self.fail {
let a3 = self[temp_v!(3)].clone();
self.unify(a3, Addr::Con(Constant::Number(rc_integer!(0))));
gadget.duplicate_term(a1);
}
- self.unify(Addr::HeapCell(old_h), a2);
+ self.unify(Addr::HeapCell(old_h), a2);
}
-
+
pub(super) fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
{
match instr {
let gi = self.next_global_index();
self.p += 1;
-
+
if self.e + 1 < self.and_stack.len() {
let and_gi = self.and_stack[self.e].global_index;
let or_gi = self.or_stack.top()
self.and_stack[index].e = self.e;
self.and_stack[index].cp = self.cp;
self.and_stack[index].global_index = gi;
-
+
self.and_stack.resize(index, num_cells);
self.e = index;
-
+
return;
}
}
-
+
self.and_stack.push(gi, self.e, self.cp, num_cells);
self.e = self.and_stack.len() - 1;
},
},
&ControlInstruction::Deallocate => {
let e = self.e;
-
+
self.cp = self.and_stack[e].cp;
- self.e = self.and_stack[e].e;
-
+ self.e = self.and_stack[e].e;
+
self.p += 1;
},
- &ControlInstruction::DisplayCall => {
+ &ControlInstruction::DisplayCall => {
let output = self.print_term(&self[temp_v!(1)],
DisplayFormatter {},
PrinterOutputter::new());
-
+
println!("{}", output.result());
-
+
self.p += 1;
},
- &ControlInstruction::DisplayExecute => {
+ &ControlInstruction::DisplayExecute => {
let output = self.print_term(&self[temp_v!(1)],
DisplayFormatter {},
PrinterOutputter::new());
-
+
println!("{}", output.result());
-
+
self.p = self.cp;
},
&ControlInstruction::DuplicateTermCall => {
let a1 = self[r].clone();
let a2 = try_or_fail!(self, self.get_number(at));
- self.unify(a1, Addr::Con(Constant::Number(a2)));
+ self.unify(a1, Addr::Con(Constant::Number(a2)));
self.p = self.cp;
},
&ControlInstruction::Proceed =>
&IndexedChoiceInstruction::Try(l) => {
let n = self.num_of_args;
let gi = self.next_global_index();
-
+
self.or_stack.push(gi,
self.e,
self.cp,
&ChoiceInstruction::TryMeElse(offset) => {
let n = self.num_of_args;
let gi = self.next_global_index();
-
+
self.or_stack.push(gi,
self.e,
self.cp,
self.tidy_trail();
}
- self.p += 1;
+ self.p += 1;
},
&CutInstruction::GetLevel => {
let b0 = self.b0;
self.tidy_trail();
}
- self.p += 1;
+ self.p += 1;
}
}
}