Utilitários
Table of Contents
Arquivo: axioms/utils.rs
.
use gc::Gc; use crate::core::Maj; use crate::maj_list; use crate::axioms::MajRawSym;
1. Constantes para aumento de Call Stack
pub const STACK_RED_ZONE: usize = 100 * 1024; // 100KB pub const STACK_PER_RECURSION: usize = 9 * 1024 * 1024; // 9MB
2. Máximo divisor comum
pub fn gcd(a: i64, b: i64) -> i64 { let mut a = a; let mut b = b; while b != 0 { let ratio = a % b; a = b; b = ratio; } a }
3. Simplificação de frações
pub fn simplify_frac_raw(numer: i64, denom: i64) -> (i64, i64) { if denom == 0 { // Division by zero is illegal and, if it came // to this part of the program, we should panic panic!("Division by zero on fraction simplification"); } let gcd = gcd(numer, denom); let (mut numer, mut denom) = (numer / gcd, denom / gcd); if (denom < 0) && (numer > 0) { numer *= -1; denom *= -1; } (numer, denom) }
pub fn simplify_frac(x: Gc<Maj>) -> Result<Gc<Maj>, Gc<Maj>> { use crate::axioms::predicates::maj_fractionp; use crate::axioms::primitives::{ maj_numer, maj_denom, maj_err, }; if !maj_fractionp(x.clone()).to_bool() { Err(maj_err(Maj::string("{} is not a fraction"), maj_list!(x))) } else { let numer = maj_numer(x.clone()).to_integer().unwrap(); let denom = maj_denom(x.clone()).to_integer().unwrap(); if denom == 0 { Err(maj_err(Maj::string("Division by zero"), Maj::nil())) } else { let (numer, denom) = simplify_frac_raw(numer, denom); Ok(Maj::fraction(numer, denom)) } } }
pub fn simplify_frac_coerce(x: Gc<Maj>) -> Result<Gc<Maj>, Gc<Maj>> { use crate::axioms::primitives::{maj_numer, maj_denom }; let frac = simplify_frac(x)?; Ok(if maj_denom(frac.clone()).to_integer().unwrap() == 1 { maj_numer(frac) } else { frac }) }
4. Criação de símbolos a partir de símbolos crus
pub fn sym_from_raw(raw: MajRawSym) -> Gc<Maj> { Gc::new(Maj::Sym(raw as u64)) }
5. Truncagem de formatação
pub fn truncate_format(text: String, max: usize) -> String { if max < 4 || text.len() <= max { text } else { let slice = &text[..(max - 4)]; let should_close = slice.chars().nth(0).unwrap() == '('; format!("{}{}{}", slice, "...", if should_close { ")" } else { "" }) } }
6. Impressão apropriada de pontos flutuantes
pub fn format_raw_float(num: f64) -> String { let mut buffer = format!("{}", num); if buffer.find('.').is_none() { buffer.push('.'); buffer.push('0'); } buffer }