use ordered_float::{Float, OrderedFloat};
use std::cell::Cell;
-use std::cmp::{max, min, Ordering};
+use std::cmp::Ordering;
use std::convert::TryFrom;
use std::f64;
use std::num::FpCategory;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ArithmeticTerm {
+ IntermReg(usize),
Reg(RegType),
- Interm(usize),
Number(Number),
}
-impl ArithmeticTerm {
- pub(crate) fn interm_or(&self, interm: usize) -> usize {
- if let &ArithmeticTerm::Interm(interm) = self {
- interm
- } else {
- interm
- }
- }
-}
-
impl Default for ArithmeticTerm {
fn default() -> Self {
ArithmeticTerm::Number(Number::default())
state_stack: Vec<TermIterState<'a>>,
}
-pub(crate) type ArithCont = (CodeDeque, Option<ArithmeticTerm>);
+pub(crate) type ArithCont = (CodeDeque, ArithmeticTerm);
impl<'a> ArithInstructionIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
#[derive(Debug)]
pub(crate) enum ArithTermRef<'a> {
Literal(Literal),
- Op(Atom, usize), // name, arity.
+ Op(Level, &'a Cell<RegType>, Atom, usize), // name, arity.
Var(Level, &'a Cell<VarReg>, VarPtr),
}
let arity = subterms.len();
if child_num == arity {
- return Some(Ok(ArithTermRef::Op(name, arity)));
+ return Some(Ok(ArithTermRef::Op(lvl, cell, name, arity)));
} else {
self.state_stack.push(TermIterState::Clause(
lvl,
pub(crate) struct ArithmeticEvaluator<'a> {
marker: &'a mut DebrayAllocator,
interm: Vec<ArithmeticTerm>,
- interm_c: usize,
}
pub(crate) trait ArithmeticTermIter<'a> {
}
impl<'a> ArithmeticEvaluator<'a> {
- pub(crate) fn new(marker: &'a mut DebrayAllocator, target_int: usize) -> Self {
+ pub(crate) fn new(marker: &'a mut DebrayAllocator) -> Self {
ArithmeticEvaluator {
marker,
interm: Vec::new(),
- interm_c: target_int,
}
}
}
}
- fn incr_interm(&mut self) -> usize {
- let temp = self.interm_c;
-
- self.interm.push(ArithmeticTerm::Interm(temp));
- self.interm_c += 1;
-
- temp
+ fn try_add_to_free_list(&mut self, a1: ArithmeticTerm) {
+ if let ArithmeticTerm::IntermReg(t) = a1 {
+ self.marker.add_reg_to_free_list(RegType::Temp(t));
+ }
}
fn instr_from_clause(
&mut self,
name: Atom,
arity: usize,
+ arg: usize,
) -> Result<Instruction, ArithmeticError> {
match arity {
1 => {
let a1 = self.interm.pop().unwrap();
- let ninterm = if a1.interm_or(0) == 0 {
- self.incr_interm()
- } else {
- self.interm.push(a1);
- a1.interm_or(0)
- };
+ self.interm.push(ArithmeticTerm::IntermReg(arg));
+ self.try_add_to_free_list(a1);
- self.get_unary_instr(name, a1, ninterm)
+ self.get_unary_instr(name, a1, arg)
}
2 => {
let a2 = self.interm.pop().unwrap();
let a1 = self.interm.pop().unwrap();
- let min_interm = min(a1.interm_or(0), a2.interm_or(0));
-
- let ninterm = if min_interm == 0 {
- let max_interm = max(a1.interm_or(0), a2.interm_or(0));
+ self.interm.push(ArithmeticTerm::IntermReg(arg));
- if max_interm == 0 {
- self.incr_interm()
- } else {
- self.interm.push(ArithmeticTerm::Interm(max_interm));
- self.interm_c = max_interm + 1;
- max_interm
- }
- } else {
- self.interm.push(ArithmeticTerm::Interm(min_interm));
- self.interm_c = min_interm + 1;
- min_interm
- };
+ self.try_add_to_free_list(a1);
+ self.try_add_to_free_list(a2);
- self.get_binary_instr(name, a1, a2, ninterm)
+ self.get_binary_instr(name, a1, a2, arg)
}
_ => Err(ArithmeticError::NonEvaluableFunctor(
Literal::Atom(name),
self.interm.push(ArithmeticTerm::Reg(r));
}
- ArithTermRef::Op(name, arity) => {
- code.push_back(self.instr_from_clause(name, arity)?);
+ ArithTermRef::Op(lvl, cell, name, arity) => {
+ self.marker
+ .mark_non_var::<QueryInstruction>(lvl, term_loc, cell, &mut code);
+
+ if let RegType::Temp(t) = cell.get() {
+ code.push_back(self.instr_from_clause(name, arity, t)?);
+ } else {
+ unreachable!()
+ }
}
}
}
- Ok((code, self.interm.pop()))
+ Ok((code, self.interm.pop().unwrap()))
}
}
use std::cmp;
use std::convert::TryFrom;
use std::f64;
-use std::mem;
macro_rules! try_numeric_result {
($e: expr, $stub_gen: expr) => {
impl MachineState {
#[inline]
pub fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
- match at {
- &ArithmeticTerm::Reg(r) => {
- let value = self.store(self.deref(self[r]));
-
- match Number::try_from((value, &self.arena.f64_tbl)) {
- Ok(n) => Ok(n),
- Err(_) => {
- self.heap[0] = value;
- self.arith_eval_by_metacall(0)
- }
- }
+ let value = match at {
+ &ArithmeticTerm::Reg(r) => self.store(self.deref(self[r])),
+ &ArithmeticTerm::IntermReg(i) => self.registers[i],
+ ArithmeticTerm::Number(n) => return Ok(*n),
+ };
+
+ match Number::try_from((value, &self.arena.f64_tbl)) {
+ Ok(n) => Ok(n),
+ Err(_) => {
+ self.heap[0] = value;
+ self.arith_eval_by_metacall(0)
}
- &ArithmeticTerm::Interm(i) => Ok(mem::replace(
- &mut self.interms[i - 1],
- Number::Fixnum(Fixnum::build_with(0)),
- )),
- ArithmeticTerm::Number(n) => Ok(*n),
}
}
term_loc: usize,
) -> Result<Number, MachineStub> {
let stub_gen = || functor_stub(atom!("is"), 2);
+ let mut interms = vec![];
let mut iter =
stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, term_loc);
read_heap_cell!(value,
(HeapCellValueTag::Atom, (name, arity)) => {
if arity == 2 {
- let a2 = self.interms.pop().unwrap();
- let a1 = self.interms.pop().unwrap();
+ let a2 = interms.pop().unwrap();
+ let a1 = interms.pop().unwrap();
match name {
- atom!("+") => self.interms.push(drop_iter_on_err!(
+ atom!("+") => interms.push(drop_iter_on_err!(
self,
iter,
try_numeric_result!(add(a1, a2, &mut self.arena), stub_gen)
)),
- atom!("-") => self.interms.push(drop_iter_on_err!(
+ atom!("-") => interms.push(drop_iter_on_err!(
self,
iter,
try_numeric_result!(sub(a1, a2, &mut self.arena), stub_gen)
)),
- atom!("*") => self.interms.push(drop_iter_on_err!(
+ atom!("*") => interms.push(drop_iter_on_err!(
self,
iter,
try_numeric_result!(mul(a1, a2, &mut self.arena), stub_gen)
)),
- atom!("/") => self.interms.push(
+ atom!("/") => interms.push(
drop_iter_on_err!(self, iter, div(a1, a2))
),
- atom!("**") => self.interms.push(
+ atom!("**") => interms.push(
drop_iter_on_err!(self, iter, pow(a1, a2, atom!("is")))
),
- atom!("^") => self.interms.push(
+ atom!("^") => interms.push(
drop_iter_on_err!(self, iter, int_pow(a1, a2, &mut self.arena))
),
- atom!("max") => self.interms.push(
+ atom!("max") => interms.push(
drop_iter_on_err!(self, iter, max(a1, a2))
),
- atom!("min") => self.interms.push(
+ atom!("min") => interms.push(
drop_iter_on_err!(self, iter, min(a1, a2))
),
atom!("rdiv") => {
&mut self.arena
);
- self.interms.push(Number::Rational(result));
+ interms.push(Number::Rational(result));
}
- atom!("//") => self.interms.push(
+ atom!("//") => interms.push(
drop_iter_on_err!(self, iter, idiv(a1, a2, &mut self.arena))
),
- atom!("div") => self.interms.push(
+ atom!("div") => interms.push(
drop_iter_on_err!(self, iter, int_floor_div(a1, a2, &mut self.arena))
),
- atom!(">>") => self.interms.push(
+ atom!(">>") => interms.push(
drop_iter_on_err!(self, iter, shr(a1, a2, &mut self.arena))
),
- atom!("<<") => self.interms.push(
+ atom!("<<") => interms.push(
drop_iter_on_err!(self, iter, shl(a1, a2, &mut self.arena))
),
- atom!("/\\") => self.interms.push(
+ atom!("/\\") => interms.push(
drop_iter_on_err!(self, iter, and(a1, a2, &mut self.arena))
),
- atom!("\\/") => self.interms.push(
+ atom!("\\/") => interms.push(
drop_iter_on_err!(self, iter, or(a1, a2, &mut self.arena))
),
- atom!("xor") => self.interms.push(
+ atom!("xor") => interms.push(
drop_iter_on_err!(self, iter, xor(a1, a2, &mut self.arena))
),
- atom!("mod") => self.interms.push(
+ atom!("mod") => interms.push(
drop_iter_on_err!(self, iter, modulus(a1, a2, &mut self.arena))
),
- atom!("rem") => self.interms.push(
+ atom!("rem") => interms.push(
drop_iter_on_err!(self, iter, remainder(a1, a2, &mut self.arena))
),
- atom!("atan2") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("atan2") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, atan2(a1, a2))
))),
- atom!("gcd") => self.interms.push(
+ atom!("gcd") => interms.push(
drop_iter_on_err!(self, iter, gcd(a1, a2, &mut self.arena))
),
_ => {
continue;
} else if arity == 1 {
- let a1 = self.interms.pop().unwrap();
+ let a1 = interms.pop().unwrap();
match name {
- atom!("-") => self.interms.push(neg(a1, &mut self.arena)),
- atom!("+") => self.interms.push(a1),
- atom!("cos") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("-") => interms.push(neg(a1, &mut self.arena)),
+ atom!("+") => interms.push(a1),
+ atom!("cos") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, cos(a1))
))),
- atom!("sin") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("sin") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, sin(a1))
))),
- atom!("tan") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("tan") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, tan(a1))
))),
- atom!("float_fractional_part") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("float_fractional_part") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, float_fractional_part(a1))
))),
- atom!("float_integer_part") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("float_integer_part") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, float_integer_part(a1))
))),
- atom!("sqrt") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("sqrt") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, sqrt(a1))
))),
- atom!("log") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("log") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, log(a1))
))),
- atom!("exp") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("exp") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, exp(a1))
))),
- atom!("acos") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("acos") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, acos(a1))
))),
- atom!("asin") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("asin") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, asin(a1))
))),
- atom!("atan") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("atan") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, atan(a1))
))),
- atom!("abs") => self.interms.push(abs(a1, &mut self.arena)),
- atom!("float") => self.interms.push(Number::Float(OrderedFloat(
+ atom!("abs") => interms.push(abs(a1, &mut self.arena)),
+ atom!("float") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, float(a1))
))),
- atom!("truncate") => self.interms.push(truncate(a1, &mut self.arena)),
- atom!("round") => self.interms.push(drop_iter_on_err!(self, iter, round(a1, &mut self.arena))),
- atom!("ceiling") => self.interms.push(ceiling(a1, &mut self.arena)),
- atom!("floor") => self.interms.push(floor(a1, &mut self.arena)),
- atom!("\\") => self.interms.push(
+ atom!("truncate") => interms.push(truncate(a1, &mut self.arena)),
+ atom!("round") => interms.push(drop_iter_on_err!(self, iter, round(a1, &mut self.arena))),
+ atom!("ceiling") => interms.push(ceiling(a1, &mut self.arena)),
+ atom!("floor") => interms.push(floor(a1, &mut self.arena)),
+ atom!("\\") => interms.push(
drop_iter_on_err!(self, iter, bitwise_complement(a1, &mut self.arena))
),
- atom!("sign") => self.interms.push(a1.sign()),
+ atom!("sign") => interms.push(a1.sign()),
_ => {
let evaluable_stub = functor_stub(name, 1);
std::mem::drop(iter);
} else if arity == 0 {
match name {
atom!("pi") => {
- self.interms.push(Number::Float(OrderedFloat(f64::consts::PI)));
+ interms.push(Number::Float(OrderedFloat(f64::consts::PI)));
continue;
}
atom!("e") => {
- self.interms.push(Number::Float(OrderedFloat(f64::consts::E)));
+ interms.push(Number::Float(OrderedFloat(f64::consts::E)));
continue;
}
atom!("epsilon") => {
- self.interms.push(Number::Float(OrderedFloat(f64::EPSILON)));
+ interms.push(Number::Float(OrderedFloat(f64::EPSILON)));
continue;
}
_ => {
return Err(self.error_form(evaluable_error, stub));
}
(HeapCellValueTag::Fixnum, n) => {
- self.interms.push(Number::Fixnum(n));
+ interms.push(Number::Fixnum(n));
}
(HeapCellValueTag::F64Offset, offset) => {
let fl = self.arena.f64_tbl.get_entry(offset);
- self.interms.push(Number::Float(fl));
+ interms.push(Number::Float(fl));
}
(HeapCellValueTag::Cons, ptr) => {
match_untyped_arena_ptr!(ptr,
(ArenaHeaderTag::Integer, n) => {
- self.interms.push(Number::Integer(n));
+ interms.push(Number::Integer(n));
}
(ArenaHeaderTag::Rational, r) => {
- self.interms.push(Number::Rational(r));
+ interms.push(Number::Rational(r));
}
_ => {
std::mem::drop(iter);
)
}
- Ok(self.interms.pop().unwrap())
+ Ok(interms.pop().unwrap())
}
}
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
try_numeric_result!(add(n1, n2, &mut self.machine_st.arena), stub_gen)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Sub(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Mul(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
try_numeric_result!(mul(n1, n2, &mut self.machine_st.arena), stub_gen)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Max(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] =
- try_or_throw_gen!(&mut self.machine_st, max(n1, n2));
+ let value = try_or_throw_gen!(&mut self.machine_st, max(n1, n2));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Min(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] =
- try_or_throw_gen!(&mut self.machine_st, min(n1, n2));
+ let value = try_or_throw_gen!(&mut self.machine_st, min(n1, n2));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::IntPow(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
-
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
int_pow(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Gcd(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
gcd(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Pow(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] =
+ let value =
try_or_throw_gen!(&mut self.machine_st, pow(n1, n2, atom!("**")));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
self.machine_st.get_rational(a2, stub_gen)
);
- self.machine_st.interms[t - 1] = Number::Rational(arena_alloc!(
+ let value = Number::Rational(arena_alloc!(
try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)),
&mut self.machine_st.arena
));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::IntFloorDiv(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
int_floor_div(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::IDiv(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
idiv(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Abs(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = abs(n1, &mut self.machine_st.arena);
+ let value = abs(n1, &mut self.machine_st.arena);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Sign(ref a1, t) => {
let n = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
+ let value = n.sign();
- self.machine_st.interms[t - 1] = n.sign();
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Neg(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = neg(n1, &mut self.machine_st.arena);
+ let value = neg(n1, &mut self.machine_st.arena);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::BitwiseComplement(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
bitwise_complement(n1, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Div(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] =
- try_or_throw_gen!(&mut self.machine_st, div(n1, n2));
-
+ let value = try_or_throw_gen!(&mut self.machine_st, div(n1, n2));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Shr(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
shr(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Shl(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
shl(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Xor(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
xor(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::And(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
and(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Or(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
or(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Mod(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
modulus(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Rem(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
remainder(n1, n2, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Cos(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, cos(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ cos(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Sin(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, sin(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ sin(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Tan(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, tan(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ tan(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Sqrt(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, sqrt(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ sqrt(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Log(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, log(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ log(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Exp(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, exp(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ exp(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::ACos(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, acos(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ acos(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::ASin(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, asin(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ asin(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::ATan(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, atan(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ atan(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::ATan2(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, atan2(n1, n2)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ atan2(n1, n2)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Float(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, float(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ float(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Truncate(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = truncate(n1, &mut self.machine_st.arena);
+ let value = truncate(n1, &mut self.machine_st.arena);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Round(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = try_or_throw_gen!(
+ let value = try_or_throw_gen!(
&mut self.machine_st,
round(n1, &mut self.machine_st.arena)
);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Ceiling(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = ceiling(n1, &mut self.machine_st.arena);
+ let value = ceiling(n1, &mut self.machine_st.arena);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Floor(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = floor(n1, &mut self.machine_st.arena);
+ let value = floor(n1, &mut self.machine_st.arena);
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::FloatFractionalPart(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, float_fractional_part(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ float_fractional_part(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::FloatIntegerPart(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = Number::Float(OrderedFloat(
- try_or_throw_gen!(&mut self.machine_st, float_integer_part(n1)),
- ));
+ let value = Number::Float(OrderedFloat(try_or_throw_gen!(
+ &mut self.machine_st,
+ float_integer_part(n1)
+ )));
+ self.machine_st.registers[t] =
+ HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::Plus(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
- self.machine_st.interms[t - 1] = n1;
+ self.machine_st.registers[t] =
+ HeapCellValue::from((n1, &mut self.machine_st.arena));
self.machine_st.p += 1;
}
&Instruction::DynamicElse(..) => {