remove interms field from MachineState

This commit is contained in:
Mark Thom
2025-11-24 22:19:09 -08:00
parent e4d9692535
commit f2e044e5b8
8 changed files with 258 additions and 212 deletions

View File

@@ -951,8 +951,8 @@ fn generate_instruction_preface() -> TokenStream {
fn into_functor(self, arena: &mut Arena) -> MachineStub { fn into_functor(self, arena: &mut Arena) -> MachineStub {
match self { match self {
ArithmeticTerm::Reg(r) => reg_type_into_functor(r), ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
ArithmeticTerm::Interm(i) => { ArithmeticTerm::IntermReg(i) => {
functor!(atom!("intermediate"), [fixnum(i)]) functor!(atom!("x"), [fixnum(i)])
} }
ArithmeticTerm::Number(n) => { ArithmeticTerm::Number(n) => {
functor!(atom!("number"), [number(n, arena)]) functor!(atom!("number"), [number(n, arena)])

View File

@@ -22,7 +22,7 @@ use num_order::NumOrd;
use ordered_float::{Float, OrderedFloat}; use ordered_float::{Float, OrderedFloat};
use std::cell::Cell; use std::cell::Cell;
use std::cmp::{max, min, Ordering}; use std::cmp::Ordering;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::f64; use std::f64;
use std::num::FpCategory; use std::num::FpCategory;
@@ -31,21 +31,11 @@ use std::vec::Vec;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ArithmeticTerm { pub enum ArithmeticTerm {
IntermReg(usize),
Reg(RegType), Reg(RegType),
Interm(usize),
Number(Number), 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 { impl Default for ArithmeticTerm {
fn default() -> Self { fn default() -> Self {
ArithmeticTerm::Number(Number::default()) ArithmeticTerm::Number(Number::default())
@@ -57,7 +47,7 @@ pub(crate) struct ArithInstructionIterator<'a> {
state_stack: Vec<TermIterState<'a>>, state_stack: Vec<TermIterState<'a>>,
} }
pub(crate) type ArithCont = (CodeDeque, Option<ArithmeticTerm>); pub(crate) type ArithCont = (CodeDeque, ArithmeticTerm);
impl<'a> ArithInstructionIterator<'a> { impl<'a> ArithInstructionIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) { fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
@@ -90,7 +80,7 @@ impl<'a> ArithInstructionIterator<'a> {
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum ArithTermRef<'a> { pub(crate) enum ArithTermRef<'a> {
Literal(Literal), Literal(Literal),
Op(Atom, usize), // name, arity. Op(Level, &'a Cell<RegType>, Atom, usize), // name, arity.
Var(Level, &'a Cell<VarReg>, VarPtr), Var(Level, &'a Cell<VarReg>, VarPtr),
} }
@@ -105,7 +95,7 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
let arity = subterms.len(); let arity = subterms.len();
if child_num == arity { if child_num == arity {
return Some(Ok(ArithTermRef::Op(name, arity))); return Some(Ok(ArithTermRef::Op(lvl, cell, name, arity)));
} else { } else {
self.state_stack.push(TermIterState::Clause( self.state_stack.push(TermIterState::Clause(
lvl, lvl,
@@ -139,7 +129,6 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
pub(crate) struct ArithmeticEvaluator<'a> { pub(crate) struct ArithmeticEvaluator<'a> {
marker: &'a mut DebrayAllocator, marker: &'a mut DebrayAllocator,
interm: Vec<ArithmeticTerm>, interm: Vec<ArithmeticTerm>,
interm_c: usize,
} }
pub(crate) trait ArithmeticTermIter<'a> { pub(crate) trait ArithmeticTermIter<'a> {
@@ -180,11 +169,10 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
} }
impl<'a> ArithmeticEvaluator<'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 { ArithmeticEvaluator {
marker, marker,
interm: Vec::new(), interm: Vec::new(),
interm_c: target_int,
} }
} }
@@ -252,56 +240,37 @@ impl<'a> ArithmeticEvaluator<'a> {
} }
} }
fn incr_interm(&mut self) -> usize { fn try_add_to_free_list(&mut self, a1: ArithmeticTerm) {
let temp = self.interm_c; if let ArithmeticTerm::IntermReg(t) = a1 {
self.marker.add_reg_to_free_list(RegType::Temp(t));
self.interm.push(ArithmeticTerm::Interm(temp)); }
self.interm_c += 1;
temp
} }
fn instr_from_clause( fn instr_from_clause(
&mut self, &mut self,
name: Atom, name: Atom,
arity: usize, arity: usize,
arg: usize,
) -> Result<Instruction, ArithmeticError> { ) -> Result<Instruction, ArithmeticError> {
match arity { match arity {
1 => { 1 => {
let a1 = self.interm.pop().unwrap(); let a1 = self.interm.pop().unwrap();
let ninterm = if a1.interm_or(0) == 0 { self.interm.push(ArithmeticTerm::IntermReg(arg));
self.incr_interm() self.try_add_to_free_list(a1);
} else {
self.interm.push(a1);
a1.interm_or(0)
};
self.get_unary_instr(name, a1, ninterm) self.get_unary_instr(name, a1, arg)
} }
2 => { 2 => {
let a2 = self.interm.pop().unwrap(); let a2 = self.interm.pop().unwrap();
let a1 = self.interm.pop().unwrap(); let a1 = self.interm.pop().unwrap();
let min_interm = min(a1.interm_or(0), a2.interm_or(0)); self.interm.push(ArithmeticTerm::IntermReg(arg));
let ninterm = if min_interm == 0 { self.try_add_to_free_list(a1);
let max_interm = max(a1.interm_or(0), a2.interm_or(0)); self.try_add_to_free_list(a2);
if max_interm == 0 { self.get_binary_instr(name, a1, a2, arg)
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.get_binary_instr(name, a1, a2, ninterm)
} }
_ => Err(ArithmeticError::NonEvaluableFunctor( _ => Err(ArithmeticError::NonEvaluableFunctor(
Literal::Atom(name), Literal::Atom(name),
@@ -346,13 +315,20 @@ impl<'a> ArithmeticEvaluator<'a> {
self.interm.push(ArithmeticTerm::Reg(r)); self.interm.push(ArithmeticTerm::Reg(r));
} }
ArithTermRef::Op(name, arity) => { ArithTermRef::Op(lvl, cell, name, arity) => {
code.push_back(self.instr_from_clause(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()))
} }
} }

View File

@@ -560,20 +560,17 @@ impl CodeGenerator {
&InlinedClauseType::CompareNumber(mut cmp) => { &InlinedClauseType::CompareNumber(mut cmp) => {
self.marker.reset_arg(2); self.marker.reset_arg(2);
let (mut lcode, at_1) = self.compile_arith_expr(&terms[0], 1, term_loc, 1)?; let (mut lcode, at_1) = self.compile_arith_expr(&terms[0], term_loc, 1)?;
if !matches!(terms[0], Term::Var(..)) { if !matches!(terms[0], Term::Var(..)) {
self.marker.advance_arg(); self.marker.advance_arg();
} }
let (mut rcode, at_2) = self.compile_arith_expr(&terms[1], 2, term_loc, 2)?; let (mut rcode, at_2) = self.compile_arith_expr(&terms[1], term_loc, 2)?;
code.append(&mut lcode); code.append(&mut lcode);
code.append(&mut rcode); code.append(&mut rcode);
let at_1 = at_1.unwrap_or(interm!(1));
let at_2 = at_2.unwrap_or(interm!(2));
compare_number_instr!(cmp, at_1, at_2) compare_number_instr!(cmp, at_1, at_2)
} }
InlinedClauseType::IsAtom(..) => match &terms[0] { InlinedClauseType::IsAtom(..) => match &terms[0] {
@@ -787,11 +784,10 @@ impl CodeGenerator {
fn compile_arith_expr( fn compile_arith_expr(
&mut self, &mut self,
term: &Term, term: &Term,
target_int: usize,
term_loc: GenContext, term_loc: GenContext,
arg: usize, arg: usize,
) -> Result<ArithCont, ArithmeticError> { ) -> Result<ArithCont, ArithmeticError> {
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int); let mut evaluator = ArithmeticEvaluator::new(&mut self.marker);
evaluator.compile_is(term, term_loc, arg) evaluator.compile_is(term, term_loc, arg)
} }
@@ -804,7 +800,7 @@ impl CodeGenerator {
) -> Result<(), CompilationError> { ) -> Result<(), CompilationError> {
macro_rules! compile_expr { macro_rules! compile_expr {
($self:expr, $terms:expr, $term_loc:expr, $code:expr) => {{ ($self:expr, $terms:expr, $term_loc:expr, $code:expr) => {{
let (acode, at) = $self.compile_arith_expr($terms, 1, $term_loc, 2)?; let (acode, at) = $self.compile_arith_expr($terms, $term_loc, 2)?;
$code.extend(acode.into_iter()); $code.extend(acode.into_iter());
at at
}}; }};
@@ -877,7 +873,6 @@ impl CodeGenerator {
} }
}; };
let at = at.unwrap_or(interm!(1));
self.add_call(code, instr!("is", temp_v!(1), at), call_policy); self.add_call(code, instr!("is", temp_v!(1), at), call_policy);
Ok(()) Ok(())
} }

View File

@@ -21,7 +21,6 @@ use ordered_float::{Float, OrderedFloat};
use std::cmp; use std::cmp;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::f64; use std::f64;
use std::mem;
macro_rules! try_numeric_result { macro_rules! try_numeric_result {
($e: expr, $stub_gen: expr) => { ($e: expr, $stub_gen: expr) => {
@@ -1120,23 +1119,18 @@ pub(crate) fn bitwise_complement(n1: Number, arena: &mut Arena) -> Result<Number
impl MachineState { impl MachineState {
#[inline] #[inline]
pub fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> { pub fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
match at { let value = match at {
&ArithmeticTerm::Reg(r) => { &ArithmeticTerm::Reg(r) => self.store(self.deref(self[r])),
let value = 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)) { match Number::try_from((value, &self.arena.f64_tbl)) {
Ok(n) => Ok(n), Ok(n) => Ok(n),
Err(_) => { Err(_) => {
self.heap[0] = value; self.heap[0] = value;
self.arith_eval_by_metacall(0) 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),
} }
} }
@@ -1158,6 +1152,7 @@ impl MachineState {
term_loc: usize, term_loc: usize,
) -> Result<Number, MachineStub> { ) -> Result<Number, MachineStub> {
let stub_gen = || functor_stub(atom!("is"), 2); let stub_gen = || functor_stub(atom!("is"), 2);
let mut interms = vec![];
let mut iter = let mut iter =
stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, term_loc); stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, term_loc);
@@ -1194,38 +1189,38 @@ impl MachineState {
read_heap_cell!(value, read_heap_cell!(value,
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
if arity == 2 { if arity == 2 {
let a2 = self.interms.pop().unwrap(); let a2 = interms.pop().unwrap();
let a1 = self.interms.pop().unwrap(); let a1 = interms.pop().unwrap();
match name { match name {
atom!("+") => self.interms.push(drop_iter_on_err!( atom!("+") => interms.push(drop_iter_on_err!(
self, self,
iter, iter,
try_numeric_result!(add(a1, a2, &mut self.arena), stub_gen) 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, self,
iter, iter,
try_numeric_result!(sub(a1, a2, &mut self.arena), stub_gen) 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, self,
iter, iter,
try_numeric_result!(mul(a1, a2, &mut self.arena), stub_gen) 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)) 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"))) 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)) 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)) 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)) drop_iter_on_err!(self, iter, min(a1, a2))
), ),
atom!("rdiv") => { atom!("rdiv") => {
@@ -1246,39 +1241,39 @@ impl MachineState {
&mut self.arena &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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) drop_iter_on_err!(self, iter, gcd(a1, a2, &mut self.arena))
), ),
_ => { _ => {
@@ -1294,56 +1289,56 @@ impl MachineState {
continue; continue;
} else if arity == 1 { } else if arity == 1 {
let a1 = self.interms.pop().unwrap(); let a1 = interms.pop().unwrap();
match name { match name {
atom!("-") => self.interms.push(neg(a1, &mut self.arena)), atom!("-") => interms.push(neg(a1, &mut self.arena)),
atom!("+") => self.interms.push(a1), atom!("+") => interms.push(a1),
atom!("cos") => self.interms.push(Number::Float(OrderedFloat( atom!("cos") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, cos(a1)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) drop_iter_on_err!(self, iter, atan(a1))
))), ))),
atom!("abs") => self.interms.push(abs(a1, &mut self.arena)), atom!("abs") => interms.push(abs(a1, &mut self.arena)),
atom!("float") => self.interms.push(Number::Float(OrderedFloat( atom!("float") => interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, float(a1)) drop_iter_on_err!(self, iter, float(a1))
))), ))),
atom!("truncate") => self.interms.push(truncate(a1, &mut self.arena)), atom!("truncate") => interms.push(truncate(a1, &mut self.arena)),
atom!("round") => self.interms.push(drop_iter_on_err!(self, iter, round(a1, &mut self.arena))), atom!("round") => interms.push(drop_iter_on_err!(self, iter, round(a1, &mut self.arena))),
atom!("ceiling") => self.interms.push(ceiling(a1, &mut self.arena)), atom!("ceiling") => interms.push(ceiling(a1, &mut self.arena)),
atom!("floor") => self.interms.push(floor(a1, &mut self.arena)), atom!("floor") => interms.push(floor(a1, &mut self.arena)),
atom!("\\") => self.interms.push( atom!("\\") => interms.push(
drop_iter_on_err!(self, iter, bitwise_complement(a1, &mut self.arena)) 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); let evaluable_stub = functor_stub(name, 1);
std::mem::drop(iter); std::mem::drop(iter);
@@ -1362,15 +1357,15 @@ impl MachineState {
} else if arity == 0 { } else if arity == 0 {
match name { match name {
atom!("pi") => { atom!("pi") => {
self.interms.push(Number::Float(OrderedFloat(f64::consts::PI))); interms.push(Number::Float(OrderedFloat(f64::consts::PI)));
continue; continue;
} }
atom!("e") => { atom!("e") => {
self.interms.push(Number::Float(OrderedFloat(f64::consts::E))); interms.push(Number::Float(OrderedFloat(f64::consts::E)));
continue; continue;
} }
atom!("epsilon") => { atom!("epsilon") => {
self.interms.push(Number::Float(OrderedFloat(f64::EPSILON))); interms.push(Number::Float(OrderedFloat(f64::EPSILON)));
continue; continue;
} }
_ => { _ => {
@@ -1386,19 +1381,19 @@ impl MachineState {
return Err(self.error_form(evaluable_error, stub)); return Err(self.error_form(evaluable_error, stub));
} }
(HeapCellValueTag::Fixnum, n) => { (HeapCellValueTag::Fixnum, n) => {
self.interms.push(Number::Fixnum(n)); interms.push(Number::Fixnum(n));
} }
(HeapCellValueTag::F64Offset, offset) => { (HeapCellValueTag::F64Offset, offset) => {
let fl = self.arena.f64_tbl.get_entry(offset); let fl = self.arena.f64_tbl.get_entry(offset);
self.interms.push(Number::Float(fl)); interms.push(Number::Float(fl));
} }
(HeapCellValueTag::Cons, ptr) => { (HeapCellValueTag::Cons, ptr) => {
match_untyped_arena_ptr!(ptr, match_untyped_arena_ptr!(ptr,
(ArenaHeaderTag::Integer, n) => { (ArenaHeaderTag::Integer, n) => {
self.interms.push(Number::Integer(n)); interms.push(Number::Integer(n));
} }
(ArenaHeaderTag::Rational, r) => { (ArenaHeaderTag::Rational, r) => {
self.interms.push(Number::Rational(r)); interms.push(Number::Rational(r));
} }
_ => { _ => {
std::mem::drop(iter); std::mem::drop(iter);
@@ -1429,7 +1424,7 @@ impl MachineState {
) )
} }
Ok(self.interms.pop().unwrap()) Ok(interms.pop().unwrap())
} }
} }

View File

@@ -630,11 +630,13 @@ impl Machine {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
try_numeric_result!(add(n1, n2, &mut self.machine_st.arena), stub_gen) 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; self.machine_st.p += 1;
} }
&Instruction::Sub(ref a1, ref a2, t) => { &Instruction::Sub(ref a1, ref a2, t) => {
@@ -643,11 +645,13 @@ impl Machine {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
try_numeric_result!(sub(n1, n2, &mut self.machine_st.arena), stub_gen) 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; self.machine_st.p += 1;
} }
&Instruction::Mul(ref a1, ref a2, t) => { &Instruction::Mul(ref a1, ref a2, t) => {
@@ -656,59 +660,68 @@ impl Machine {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
try_numeric_result!(mul(n1, n2, &mut self.machine_st.arena), stub_gen) 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; self.machine_st.p += 1;
} }
&Instruction::Max(ref a1, ref a2, t) => { &Instruction::Max(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, max(n1, n2));
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; self.machine_st.p += 1;
} }
&Instruction::Min(ref a1, ref a2, t) => { &Instruction::Min(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, min(n1, n2));
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; self.machine_st.p += 1;
} }
&Instruction::IntPow(ref a1, ref a2, t) => { &Instruction::IntPow(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
let value = try_or_throw_gen!(
self.machine_st.interms[t - 1] = try_or_throw_gen!(
&mut self.machine_st, &mut self.machine_st,
int_pow(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Gcd(ref a1, ref a2, t) => { &Instruction::Gcd(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
gcd(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Pow(ref a1, ref a2, t) => { &Instruction::Pow(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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!("**"))); 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.p += 1;
} }
@@ -724,299 +737,375 @@ impl Machine {
self.machine_st.get_rational(a2, stub_gen) 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)), try_or_throw_gen!(&mut self.machine_st, rdiv(r1, r2)),
&mut self.machine_st.arena &mut self.machine_st.arena
)); ));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::IntFloorDiv(ref a1, ref a2, t) => { &Instruction::IntFloorDiv(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
int_floor_div(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::IDiv(ref a1, ref a2, t) => { &Instruction::IDiv(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
idiv(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Abs(ref a1, t) => { &Instruction::Abs(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::Sign(ref a1, t) => { &Instruction::Sign(ref a1, t) => {
let n = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::Neg(ref a1, t) => { &Instruction::Neg(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::BitwiseComplement(ref a1, t) => { &Instruction::BitwiseComplement(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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, &mut self.machine_st,
bitwise_complement(n1, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Div(ref a1, ref a2, t) => { &Instruction::Div(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, div(n1, n2));
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; self.machine_st.p += 1;
} }
&Instruction::Shr(ref a1, ref a2, t) => { &Instruction::Shr(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
shr(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Shl(ref a1, ref a2, t) => { &Instruction::Shl(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
shl(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Xor(ref a1, ref a2, t) => { &Instruction::Xor(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
xor(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::And(ref a1, ref a2, t) => { &Instruction::And(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
and(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Or(ref a1, ref a2, t) => { &Instruction::Or(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
or(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Mod(ref a1, ref a2, t) => { &Instruction::Mod(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
modulus(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Rem(ref a1, ref a2, t) => { &Instruction::Rem(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); 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, &mut self.machine_st,
remainder(n1, n2, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Cos(ref a1, t) => { &Instruction::Cos(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, cos(n1)), &mut self.machine_st,
)); cos(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::Sin(ref a1, t) => { &Instruction::Sin(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, sin(n1)), &mut self.machine_st,
)); sin(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::Tan(ref a1, t) => { &Instruction::Tan(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, tan(n1)), &mut self.machine_st,
)); tan(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::Sqrt(ref a1, t) => { &Instruction::Sqrt(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, sqrt(n1)), &mut self.machine_st,
)); sqrt(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::Log(ref a1, t) => { &Instruction::Log(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, log(n1)), &mut self.machine_st,
)); log(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::Exp(ref a1, t) => { &Instruction::Exp(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, exp(n1)), &mut self.machine_st,
)); exp(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::ACos(ref a1, t) => { &Instruction::ACos(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, acos(n1)), &mut self.machine_st,
)); acos(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::ASin(ref a1, t) => { &Instruction::ASin(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, asin(n1)), &mut self.machine_st,
)); asin(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::ATan(ref a1, t) => { &Instruction::ATan(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, atan(n1)), &mut self.machine_st,
)); atan(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::ATan2(ref a1, ref a2, t) => { &Instruction::ATan2(ref a1, ref a2, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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)); let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(a2));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, atan2(n1, n2)), &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; self.machine_st.p += 1;
} }
&Instruction::Float(ref a1, t) => { &Instruction::Float(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, float(n1)), &mut self.machine_st,
)); float(n1)
)));
self.machine_st.registers[t] =
HeapCellValue::from((value, &mut self.machine_st.arena));
self.machine_st.p += 1; self.machine_st.p += 1;
} }
&Instruction::Truncate(ref a1, t) => { &Instruction::Truncate(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::Round(ref a1, t) => { &Instruction::Round(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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, &mut self.machine_st,
round(n1, &mut self.machine_st.arena) 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; self.machine_st.p += 1;
} }
&Instruction::Ceiling(ref a1, t) => { &Instruction::Ceiling(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::Floor(ref a1, t) => { &Instruction::Floor(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::FloatFractionalPart(ref a1, t) => { &Instruction::FloatFractionalPart(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, float_fractional_part(n1)), &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; self.machine_st.p += 1;
} }
&Instruction::FloatIntegerPart(ref a1, t) => { &Instruction::FloatIntegerPart(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));
self.machine_st.interms[t - 1] = Number::Float(OrderedFloat( let value = Number::Float(OrderedFloat(try_or_throw_gen!(
try_or_throw_gen!(&mut self.machine_st, float_integer_part(n1)), &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; self.machine_st.p += 1;
} }
&Instruction::Plus(ref a1, t) => { &Instruction::Plus(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1)); 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; self.machine_st.p += 1;
} }
&Instruction::DynamicElse(..) => { &Instruction::DynamicElse(..) => {

View File

@@ -85,7 +85,6 @@ pub struct MachineState {
pub(super) ball: Ball, pub(super) ball: Ball,
pub(super) ball_stack: Vec<Ball>, // save current ball before jumping via, e.g., verify_attr interrupt. pub(super) ball_stack: Vec<Ball>, // save current ball before jumping via, e.g., verify_attr interrupt.
pub(super) lifted_heap: Heap, pub(super) lifted_heap: Heap,
pub(super) interms: Vec<Number>, // intermediate numbers.
// locations of cleaners, cut points, the previous scc_block. for setup_call_cleanup/3. // locations of cleaners, cut points, the previous scc_block. for setup_call_cleanup/3.
pub(super) cont_pts: Vec<(HeapCellValue, usize, usize)>, pub(super) cont_pts: Vec<(HeapCellValue, usize, usize)>,
pub(super) cwil: CWIL, pub(super) cwil: CWIL,
@@ -124,7 +123,6 @@ impl fmt::Debug for MachineState {
.field("ball", &self.ball) .field("ball", &self.ball)
.field("ball_stack", &self.ball_stack) .field("ball_stack", &self.ball_stack)
.field("lifted_heap", &self.lifted_heap) .field("lifted_heap", &self.lifted_heap)
.field("interms", &self.interms)
.field("flags", &self.flags) .field("flags", &self.flags)
.field("cc", &self.cc) .field("cc", &self.cc)
.field("global_clock", &self.global_clock) .field("global_clock", &self.global_clock)

View File

@@ -57,7 +57,6 @@ impl MachineState {
ball: Ball::new(), ball: Ball::new(),
ball_stack: vec![], ball_stack: vec![],
lifted_heap: Heap::new(), lifted_heap: Heap::new(),
interms: vec![Number::default(); 256],
cont_pts: Vec::with_capacity(256), cont_pts: Vec::with_capacity(256),
cwil: CWIL::new(), cwil: CWIL::new(),
flags: MachineFlags::default(), flags: MachineFlags::default(),

View File

@@ -369,12 +369,6 @@ macro_rules! compare_number_instr {
}}; }};
} }
macro_rules! interm {
($n: expr) => {
ArithmeticTerm::Interm($n)
};
}
macro_rules! ar_reg { macro_rules! ar_reg {
($r: expr) => { ($r: expr) => {
ArithmeticTerm::Reg($r) ArithmeticTerm::Reg($r)