From 72cdba82f57e34c3ff16345187378bda843008d8 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 15 Sep 2025 21:58:38 -0700 Subject: [PATCH] implement unify_ginteger to address FIXME in skip_max_list_cycle --- src/machine/machine_state_impl.rs | 5 +++++ src/machine/system_calls.rs | 8 +++----- src/machine/unify.rs | 7 +++++++ src/parser/ast.rs | 16 ++++++++++++++++ src/parser/lexer.rs | 26 ++++++-------------------- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 2ef605bf..2432c702 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -278,6 +278,11 @@ impl MachineState { unifier.unify_fixnum(n1, value); } + pub fn unify_ginteger(&mut self, n1: GInteger, value: HeapCellValue) { + let mut unifier = DefaultUnifier::from(self); + unifier.unify_ginteger(n1, value); + } + pub fn unify_big_int(&mut self, n1: TypedArenaPtr, value: HeapCellValue) { let mut unifier = DefaultUnifier::from(self); unifier.unify_big_integer(n1, value); diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 320c0d92..a2a8576b 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -744,11 +744,9 @@ impl MachineState { } let target_n = self.store(self.deref(self.registers[1])); - self.unify_fixnum( - /* FIXME this is not safe */ - unsafe { Fixnum::build_with_unchecked(brent_st.num_steps() as i64) }, - target_n, - ); + let num_steps = fixnum!(GInteger, brent_st.num_steps() as i64, &mut self.arena); + + self.unify_ginteger(num_steps, target_n); if !self.fail { unify!(self, self.registers[4], self.heap[prev_hare]); diff --git a/src/machine/unify.rs b/src/machine/unify.rs index fdc430ee..e1f73eae 100644 --- a/src/machine/unify.rs +++ b/src/machine/unify.rs @@ -150,6 +150,13 @@ pub(crate) trait Unifier: DerefMut { ); } + fn unify_ginteger(&mut self, n: GInteger, value: HeapCellValue) { + match n { + GInteger::Integer(integer) => self.unify_big_int(integer, value), + GInteger::Fixnum(fixnum) => self.unify_fixnum(fixnum, value), + } + } + fn unify_atom(&mut self, atom: Atom, value: HeapCellValue) { read_heap_cell!(value, (HeapCellValueTag::Atom, (name, arity)) => { diff --git a/src/parser/ast.rs b/src/parser/ast.rs index c2a1e7f8..9effb51e 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -241,6 +241,22 @@ macro_rules! is_fy { }; } +#[derive(Debug)] +pub enum GInteger { + Integer(TypedArenaPtr), + Fixnum(Fixnum), +} + +impl GInteger { + #[inline] + pub fn to_literal(self) -> Literal { + match self { + GInteger::Integer(integer) => Literal::Integer(integer), + GInteger::Fixnum(fixnum) => Literal::Fixnum(fixnum), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RegType { Perm(usize), diff --git a/src/parser/lexer.rs b/src/parser/lexer.rs index e1cf3b90..bfc3fb8f 100644 --- a/src/parser/lexer.rs +++ b/src/parser/lexer.rs @@ -1,4 +1,3 @@ -use crate::arena::*; use crate::atom_table::*; pub use crate::machine::machine_state::*; use crate::offset_table::*; @@ -67,7 +66,7 @@ impl NumberToken { fn to_token(self) -> Option { match self { NumberToken::Float(offset, fl) => Some(Token::Literal(Literal::F64(offset, fl))), - NumberToken::Integer(GInteger::BigInt(n)) => Some(Token::Literal(Literal::Integer(n))), + NumberToken::Integer(GInteger::Integer(n)) => Some(Token::Literal(Literal::Integer(n))), NumberToken::Integer(GInteger::Fixnum(n)) => Some(Token::Literal(Literal::Fixnum(n))), NumberToken::Partial(_) => None, } @@ -89,22 +88,6 @@ macro_rules! try_nt { }}; } -#[derive(Debug)] -enum GInteger { - BigInt(TypedArenaPtr), - Fixnum(Fixnum), -} - -impl GInteger { - #[inline] - fn to_literal(self) -> Literal { - match self { - GInteger::BigInt(integer) => Literal::Integer(integer), - GInteger::Fixnum(fixnum) => Literal::Fixnum(fixnum), - } - } -} - pub(crate) struct Lexer<'a, R> { pub(crate) reader: R, pub(crate) machine_st: &'a mut MachineState, @@ -716,12 +699,15 @@ impl<'a, R: CharRead> Lexer<'a, R> { Fixnum::build_with_checked(n) .map(GInteger::Fixnum) .unwrap_or_else(|_| { - GInteger::BigInt(arena_alloc!(Integer::from(n), &mut self.machine_st.arena)) + GInteger::Integer(arena_alloc!( + Integer::from(n), + &mut self.machine_st.arena + )) }) }) .or_else(|_| { Integer::from_str_radix(token, radix) - .map(|n| GInteger::BigInt(arena_alloc!(n, &mut self.machine_st.arena))) + .map(|n| GInteger::Integer(arena_alloc!(n, &mut self.machine_st.arena))) .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) }) } -- 2.54.0