From f2e044e5b8db6fefdd9bd19c812e88e3e1731b5c Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 24 Nov 2025 22:19:09 -0800 Subject: [PATCH] remove interms field from MachineState --- build/instructions_template.rs | 4 +- src/arithmetic.rs | 80 ++++------ src/codegen.rs | 13 +- src/machine/arithmetic_ops.rs | 133 ++++++++--------- src/machine/dispatch.rs | 233 +++++++++++++++++++++--------- src/machine/machine_state.rs | 2 - src/machine/machine_state_impl.rs | 1 - src/macros.rs | 6 - 8 files changed, 259 insertions(+), 213 deletions(-) diff --git a/build/instructions_template.rs b/build/instructions_template.rs index 6b5ba80e..674892d3 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -951,8 +951,8 @@ fn generate_instruction_preface() -> TokenStream { fn into_functor(self, arena: &mut Arena) -> MachineStub { match self { ArithmeticTerm::Reg(r) => reg_type_into_functor(r), - ArithmeticTerm::Interm(i) => { - functor!(atom!("intermediate"), [fixnum(i)]) + ArithmeticTerm::IntermReg(i) => { + functor!(atom!("x"), [fixnum(i)]) } ArithmeticTerm::Number(n) => { functor!(atom!("number"), [number(n, arena)]) diff --git a/src/arithmetic.rs b/src/arithmetic.rs index 76d5318e..9a70962f 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -22,7 +22,7 @@ use num_order::NumOrd; 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; @@ -31,21 +31,11 @@ use std::vec::Vec; #[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()) @@ -57,7 +47,7 @@ pub(crate) struct ArithInstructionIterator<'a> { state_stack: Vec>, } -pub(crate) type ArithCont = (CodeDeque, Option); +pub(crate) type ArithCont = (CodeDeque, ArithmeticTerm); impl<'a> ArithInstructionIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { @@ -90,7 +80,7 @@ impl<'a> ArithInstructionIterator<'a> { #[derive(Debug)] pub(crate) enum ArithTermRef<'a> { Literal(Literal), - Op(Atom, usize), // name, arity. + Op(Level, &'a Cell, Atom, usize), // name, arity. Var(Level, &'a Cell, VarPtr), } @@ -105,7 +95,7 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { 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, @@ -139,7 +129,6 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { pub(crate) struct ArithmeticEvaluator<'a> { marker: &'a mut DebrayAllocator, interm: Vec, - interm_c: usize, } pub(crate) trait ArithmeticTermIter<'a> { @@ -180,11 +169,10 @@ fn push_literal(interm: &mut Vec, c: &Literal) -> Result<(), Ari } 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, } } @@ -252,56 +240,37 @@ impl<'a> ArithmeticEvaluator<'a> { } } - 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 { 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), @@ -346,13 +315,20 @@ impl<'a> ArithmeticEvaluator<'a> { 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::(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())) } } diff --git a/src/codegen.rs b/src/codegen.rs index 02b8d99b..69a0d3b5 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -560,20 +560,17 @@ impl CodeGenerator { &InlinedClauseType::CompareNumber(mut cmp) => { 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(..)) { 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 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) } InlinedClauseType::IsAtom(..) => match &terms[0] { @@ -787,11 +784,10 @@ impl CodeGenerator { fn compile_arith_expr( &mut self, term: &Term, - target_int: usize, term_loc: GenContext, arg: usize, ) -> Result { - 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) } @@ -804,7 +800,7 @@ impl CodeGenerator { ) -> Result<(), CompilationError> { macro_rules! compile_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()); 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); Ok(()) } diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index c0c3f2bb..84105a38 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -21,7 +21,6 @@ use ordered_float::{Float, OrderedFloat}; use std::cmp; use std::convert::TryFrom; use std::f64; -use std::mem; macro_rules! try_numeric_result { ($e: expr, $stub_gen: expr) => { @@ -1120,23 +1119,18 @@ pub(crate) fn bitwise_complement(n1: Number, arena: &mut Arena) -> Result Result { - 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), } } @@ -1158,6 +1152,7 @@ impl MachineState { term_loc: usize, ) -> Result { let stub_gen = || functor_stub(atom!("is"), 2); + let mut interms = vec![]; let mut iter = stackful_post_order_iter::(&mut self.heap, &mut self.stack, term_loc); @@ -1194,38 +1189,38 @@ impl MachineState { 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") => { @@ -1246,39 +1241,39 @@ impl MachineState { &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)) ), _ => { @@ -1294,56 +1289,56 @@ impl MachineState { 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); @@ -1362,15 +1357,15 @@ impl MachineState { } 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; } _ => { @@ -1386,19 +1381,19 @@ impl MachineState { 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); @@ -1429,7 +1424,7 @@ impl MachineState { ) } - Ok(self.interms.pop().unwrap()) + Ok(interms.pop().unwrap()) } } diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index fc13d825..fb1c5d12 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -630,11 +630,13 @@ impl Machine { 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) => { @@ -643,11 +645,13 @@ impl Machine { 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) => { @@ -656,59 +660,68 @@ impl Machine { 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; } @@ -724,299 +737,375 @@ impl Machine { 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(..) => { diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index ca88a6ea..eaca8ee8 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -85,7 +85,6 @@ pub struct MachineState { pub(super) ball: Ball, pub(super) ball_stack: Vec, // save current ball before jumping via, e.g., verify_attr interrupt. pub(super) lifted_heap: Heap, - pub(super) interms: Vec, // intermediate numbers. // locations of cleaners, cut points, the previous scc_block. for setup_call_cleanup/3. pub(super) cont_pts: Vec<(HeapCellValue, usize, usize)>, pub(super) cwil: CWIL, @@ -124,7 +123,6 @@ impl fmt::Debug for MachineState { .field("ball", &self.ball) .field("ball_stack", &self.ball_stack) .field("lifted_heap", &self.lifted_heap) - .field("interms", &self.interms) .field("flags", &self.flags) .field("cc", &self.cc) .field("global_clock", &self.global_clock) diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 04fd143f..67d9ca76 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -57,7 +57,6 @@ impl MachineState { ball: Ball::new(), ball_stack: vec![], lifted_heap: Heap::new(), - interms: vec![Number::default(); 256], cont_pts: Vec::with_capacity(256), cwil: CWIL::new(), flags: MachineFlags::default(), diff --git a/src/macros.rs b/src/macros.rs index 0bf7b6af..83706ba4 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -369,12 +369,6 @@ macro_rules! compare_number_instr { }}; } -macro_rules! interm { - ($n: expr) => { - ArithmeticTerm::Interm($n) - }; -} - macro_rules! ar_reg { ($r: expr) => { ArithmeticTerm::Reg($r) -- 2.54.0