Skip to content

Latest commit

 

History

History
134 lines (116 loc) · 3.16 KB

05-05-utilitarios.org

File metadata and controls

134 lines (116 loc) · 3.16 KB

Utilitários

Arquivo: axioms/utils.rs.

use gc::Gc;
use crate::core::Maj;
use crate::maj_list;
use crate::axioms::MajRawSym;

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

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
}

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
    })
}

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))
}

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 { "" })
    }
}

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
}