73 lines
2.0 KiB
Rust
73 lines
2.0 KiB
Rust
|
use crate::{ast, eval, prims};
|
||
|
use std::rc::Rc;
|
||
|
|
||
|
#[derive(Clone)]
|
||
|
crate enum Value {
|
||
|
Num(f64),
|
||
|
Func(prims::Func),
|
||
|
Lambda(ast::Lambda),
|
||
|
Bool(bool),
|
||
|
/// Result of things that shouldnt have values, like (define x 3)
|
||
|
Trap,
|
||
|
}
|
||
|
|
||
|
impl PartialEq for Value {
|
||
|
fn eq(&self, other: &Self) -> bool {
|
||
|
use Value::*;
|
||
|
match (self, other) {
|
||
|
(Num(l), Num(r)) => l == r,
|
||
|
(Func(l), Func(r)) => *l as usize == *r as usize,
|
||
|
(Bool(l), Bool(r)) => l == r,
|
||
|
(Lambda(l), Lambda(r)) => Rc::ptr_eq(&l.0, &r.0) && Rc::ptr_eq(&l.1, &r.1),
|
||
|
|
||
|
(Num(_), _) => false,
|
||
|
(Func(_), _) => false,
|
||
|
(Bool(_), _) => false,
|
||
|
(Lambda(_), _) => false,
|
||
|
|
||
|
(Trap, _) => panic!("Trap value"),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl std::fmt::Debug for Value {
|
||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
match self {
|
||
|
Self::Num(n) => n.fmt(f),
|
||
|
Self::Func(_) => f.write_str("#<procedure>"),
|
||
|
Self::Lambda(_) => f.write_str("#<procedure>"),
|
||
|
Self::Bool(b) => f.write_str(if *b { "#t" } else { "#f" }),
|
||
|
Self::Trap => Ok(()),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Value {
|
||
|
crate fn as_num(&self) -> Result<f64, eval::RTError> {
|
||
|
if let Self::Num(n) = self {
|
||
|
Ok(*n)
|
||
|
} else {
|
||
|
Err(eval::RTError("Expected a number".to_owned()))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
crate fn as_func(&self) -> Result<eval::Callable, eval::RTError> {
|
||
|
match self {
|
||
|
Self::Func(f) => Ok(eval::Callable::Func(*f)),
|
||
|
Self::Lambda(l) => Ok(eval::Callable::Lambda(l)),
|
||
|
_ => Err(eval::RTError(format!(
|
||
|
"Expected a function, got {:?}",
|
||
|
self
|
||
|
))),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
crate fn as_bool(&self) -> Result<bool, eval::RTError> {
|
||
|
if let Self::Bool(b) = self {
|
||
|
Ok(*b)
|
||
|
} else {
|
||
|
Err(eval::RTError("Expected a bool".to_owned()))
|
||
|
}
|
||
|
}
|
||
|
}
|