Merge pull request #1050 from pmoura/add_float_integer_part_and_float_fractional_part_standard_functions

WIP: Add float_integer_part/1 and float_fractional_part/1 standard arithmetic functions
This commit is contained in:
Mark Thom
2023-07-22 13:48:16 -06:00
committed by GitHub
4 changed files with 47 additions and 0 deletions

View File

@@ -743,6 +743,10 @@ enum InstructionTemplate {
Ceiling(ArithmeticTerm, usize),
#[strum_discriminants(strum(props(Arity = "1", Name = "floor")))]
Floor(ArithmeticTerm, usize),
#[strum_discriminants(strum(props(Arity = "1", Name = "float_fractional_part")))]
FloatFractionalPart(ArithmeticTerm, usize),
#[strum_discriminants(strum(props(Arity = "1", Name = "float_integer_part")))]
FloatIntegerPart(ArithmeticTerm, usize),
#[strum_discriminants(strum(props(Arity = "1", Name = "neg")))]
Neg(ArithmeticTerm, usize),
#[strum_discriminants(strum(props(Arity = "1", Name = "plus")))]
@@ -1463,6 +1467,12 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::Floor(ref at, t) => {
arith_instr_unary_functor(h, atom!("floor"), arena, at, t)
}
&Instruction::FloatFractionalPart(ref at, t) => {
arith_instr_unary_functor(h, atom!("float_fractional_part"), arena, at, t)
}
&Instruction::FloatIntegerPart(ref at, t) => {
arith_instr_unary_functor(h, atom!("float_integer_part"), arena, at, t)
}
&Instruction::Neg(ref at, t) => arith_instr_unary_functor(
h,
atom!("-"),

View File

@@ -212,6 +212,8 @@ impl<'a> ArithmeticEvaluator<'a> {
atom!("round") => Ok(Instruction::Round(a1, t)),
atom!("ceiling") => Ok(Instruction::Ceiling(a1, t)),
atom!("floor") => Ok(Instruction::Floor(a1, t)),
atom!("float_integer_part") => Ok(Instruction::FloatIntegerPart(a1, t)),
atom!("float_fractional_part") => Ok(Instruction::FloatFractionalPart(a1, t)),
atom!("sign") => Ok(Instruction::Sign(a1, t)),
atom!("\\") => Ok(Instruction::BitwiseComplement(a1, t)),
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 1)),

View File

@@ -1053,6 +1053,16 @@ pub(crate) fn log10(n1: Number) -> Result<f64, MachineStubGen> {
unary_float_fn_template(n1, |f| f.log(10f64))
}
#[inline]
pub(crate) fn float_fractional_part(n1: Number) -> Result<f64, MachineStubGen> {
unary_float_fn_template(n1, |f| f.fract())
}
#[inline]
pub(crate) fn float_integer_part(n1: Number) -> Result<f64, MachineStubGen> {
unary_float_fn_template(n1, |f| f.trunc())
}
#[inline]
pub(crate) fn sqrt(n1: Number) -> Result<f64, MachineStubGen> {
if n1.is_negative() {
@@ -1072,6 +1082,7 @@ pub(crate) fn floor(n1: Number, arena: &mut Arena) -> Number {
rnd_i(&n1, arena)
}
#[inline]
pub(crate) fn ceiling(n1: Number, arena: &mut Arena) -> Number {
let n1 = neg(n1, arena);
@@ -1323,6 +1334,12 @@ impl MachineState {
atom!("log10") => self.interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, log10(a1))
))),
atom!("float_fractional_part") => self.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(
drop_iter_on_err!(self, iter, float_integer_part(a1))
))),
atom!("sqrt") => self.interms.push(Number::Float(OrderedFloat(
drop_iter_on_err!(self, iter, sqrt(a1))
))),

View File

@@ -1028,6 +1028,24 @@ impl Machine {
self.machine_st.interms[t - 1] = floor(n1, &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))
));
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))
));
self.machine_st.p += 1;
}
&Instruction::Plus(ref a1, t) => {
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(a1));