rudus/src/value.rs

108 lines
3.1 KiB
Rust
Raw Normal View History

2024-10-31 20:59:26 +00:00
use crate::parser::*;
use imbl::*;
use std::cell::RefCell;
2024-10-31 20:59:26 +00:00
use std::fmt;
use std::rc::Rc;
2024-10-31 20:59:26 +00:00
#[derive(Clone, Debug, PartialEq)]
pub struct Fn<'src> {
2024-11-11 01:12:19 +00:00
pub name: &'src str,
pub body: &'src Vec<MatchClause<'src>>,
2024-10-31 20:59:26 +00:00
}
#[derive(Debug, PartialEq)]
2024-11-06 22:37:57 +00:00
pub enum Value<'src> {
2024-10-31 20:59:26 +00:00
Nil,
2024-11-11 01:12:19 +00:00
Placeholder,
2024-10-31 20:59:26 +00:00
Boolean(bool),
Number(f64),
2024-11-06 22:37:57 +00:00
Keyword(&'src str),
String(&'src str),
// on the heap for now
Tuple(Rc<Vec<Self>>),
2024-11-11 01:12:19 +00:00
Args(Rc<Vec<Self>>),
// ref-counted, immutable, persistent
2024-11-09 19:10:08 +00:00
List(Vector<Self>),
// ref-counted, immutable, persistent
2024-11-09 19:10:08 +00:00
Dict(HashMap<&'src str, Self>),
Box(&'src str, Rc<RefCell<Self>>),
2024-11-11 01:12:19 +00:00
Fn(Rc<Fn<'src>>),
2024-10-31 20:59:26 +00:00
// Set(HashSet<Self>),
// Sets are hard
// Sets require Eq
// Eq is not implemented on f64, because NaNs
// We could use ordered_float::NotNan
// Let's defer that
// We're not really using sets in Ludus
// Other things we're not implementing yet:
// pkgs, nses, tests
}
2024-11-06 22:37:57 +00:00
impl<'src> Clone for Value<'src> {
fn clone(&self) -> Value<'src> {
match self {
Value::Nil => Value::Nil,
Value::Boolean(b) => Value::Boolean(b.clone()),
Value::String(s) => Value::String(s),
Value::Keyword(s) => Value::Keyword(s),
Value::Number(n) => Value::Number(n.clone()),
Value::Tuple(t) => Value::Tuple(t.clone()),
2024-11-11 01:12:19 +00:00
Value::Args(a) => Value::Args(a.clone()),
Value::Fn(f) => Value::Fn(f.clone()),
Value::List(l) => Value::List(l.clone()),
Value::Dict(d) => Value::Dict(d.clone()),
Value::Box(name, b) => Value::Box(name, b.clone()),
2024-11-11 01:12:19 +00:00
Value::Placeholder => Value::Placeholder,
}
}
}
2024-11-06 22:37:57 +00:00
impl<'src> fmt::Display for Value<'src> {
2024-10-31 20:59:26 +00:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Value::Nil => write!(f, "nil"),
Value::Boolean(b) => write!(f, "{}", b),
Value::Number(n) => write!(f, "{}", n),
Value::Keyword(k) => write!(f, ":{}", k),
Value::String(s) => write!(f, "\"{}\"", s),
2024-11-11 01:12:19 +00:00
Value::Fn(fun) => write!(f, "fn {}", fun.name),
Value::Tuple(t) | Value::Args(t) => write!(
2024-10-31 20:59:26 +00:00
f,
"({})",
t.iter()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(", ")
),
Value::List(l) => write!(
f,
"[{}]",
l.iter()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(", ")
),
2024-11-11 01:12:19 +00:00
Value::Dict(d) => write!(
f,
"#{{{}}}",
d.iter()
.map(|(k, v)| format!(":{k} {v}"))
.collect::<Vec<_>>()
.join(", ")
),
2024-11-09 19:10:08 +00:00
Value::Box(name, b) => todo!(),
2024-11-11 01:12:19 +00:00
Value::Placeholder => write!(f, "_"),
2024-10-31 20:59:26 +00:00
}
}
}
2024-11-06 22:37:57 +00:00
impl<'src> Value<'src> {
pub fn bool(&self) -> bool {
match self {
Value::Nil | Value::Boolean(false) => false,
_ => true,
}
}
}