mirror of
https://github.com/teo3300/rust-mal.git
synced 2026-01-12 01:05:32 +01:00
Fixing division
Previously was returning error on - (/ 0 n) with error: attempting division by zero
This commit is contained in:
26
src/env.rs
26
src/env.rs
@ -57,7 +57,7 @@ pub fn env_get(env: &Env, sym: &str) -> MalRet {
|
||||
|
||||
pub fn env_binds(outer: Env, binds: &MalType, exprs: &[MalType]) -> Result<Env, MalErr> {
|
||||
let env = env_new(Some(outer));
|
||||
let binds = binds.if_vec()?;
|
||||
let binds = binds.if_list()?;
|
||||
let binl = binds.len();
|
||||
let expl = exprs.len();
|
||||
if binl < expl {
|
||||
@ -150,13 +150,25 @@ pub fn call_func(func: &MalType, args: &[MalType]) -> CallRet {
|
||||
}
|
||||
|
||||
pub fn any_zero(list: &[MalType]) -> Result<&[MalType], MalErr> {
|
||||
if list
|
||||
.iter()
|
||||
.any(|x| matches!(x, M::Num(v) if v.exact_zero()))
|
||||
{
|
||||
return Err(MalErr::unrecoverable("Attempting division by 0"));
|
||||
match list.len() {
|
||||
1 => {
|
||||
if list[0].if_number()?.get_num() == 0 {
|
||||
Err(MalErr::unrecoverable("Attempting division by 0"))
|
||||
} else {
|
||||
Ok(list)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if list[1..list.len()]
|
||||
.iter()
|
||||
.any(|x| matches!(x, M::Num(v) if v.exact_zero()))
|
||||
{
|
||||
Err(MalErr::unrecoverable("Attempting division by 0"))
|
||||
} else {
|
||||
Ok(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
pub fn arithmetic_op(set: isize, f: fn(Frac, Frac) -> Frac, args: &[MalType]) -> MalRet {
|
||||
|
||||
@ -75,7 +75,7 @@ fn let_star_form(list: &[MalType], env: Env) -> Result<(MalType, Env), MalErr> {
|
||||
let inner_env = env_new(Some(env.clone()));
|
||||
// change the inner environment
|
||||
let (car, cdr) = car_cdr(list)?;
|
||||
let list = car.if_vec()?;
|
||||
let list = car.if_list()?;
|
||||
if list.len() % 2 != 0 {
|
||||
return Err(MalErr::unrecoverable(
|
||||
"let* form, number of arguments must be even",
|
||||
@ -114,7 +114,7 @@ fn if_form(list: &[MalType], env: Env) -> MalRet {
|
||||
|
||||
fn fn_star_form(list: &[MalType], env: Env) -> MalRet {
|
||||
let (binds, exprs) = car_cdr(list)?;
|
||||
binds.if_vec()?;
|
||||
binds.if_list()?;
|
||||
Ok(M::MalFun {
|
||||
// eval: eval_ast,
|
||||
params: Rc::new(binds.clone()),
|
||||
|
||||
@ -192,9 +192,9 @@ impl MalType {
|
||||
|
||||
pub fn if_list(&self) -> Result<&[MalType], MalErr> {
|
||||
match self {
|
||||
Self::List(list) => Ok(list),
|
||||
Self::List(list) | Self::Vector(list) => Ok(list),
|
||||
_ => Err(MalErr::unrecoverable(
|
||||
format!("{:?} is not a list", prt(self)).as_str(),
|
||||
format!("{:?} is not an iterable", prt(self)).as_str(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user