2024-10-31 20:59:26 +00:00
|
|
|
use crate::parser::*;
|
|
|
|
use crate::spans::*;
|
|
|
|
use imbl::*;
|
|
|
|
use std::fmt;
|
2024-11-01 03:53:48 +00:00
|
|
|
use std::rc::Rc;
|
2024-10-31 20:59:26 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct Clause<'src> {
|
|
|
|
patt: Pattern<'src>,
|
|
|
|
span: Span,
|
|
|
|
body: Ast<'src>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct Fn<'src> {
|
|
|
|
name: &'src str,
|
|
|
|
span: Span,
|
|
|
|
body: Vec<Clause<'src>>,
|
|
|
|
}
|
|
|
|
|
2024-11-01 03:53:48 +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,
|
|
|
|
Boolean(bool),
|
|
|
|
Number(f64),
|
2024-11-06 22:37:57 +00:00
|
|
|
Keyword(&'src str),
|
|
|
|
String(&'src str),
|
2024-11-01 03:53:48 +00:00
|
|
|
// on the heap for now
|
|
|
|
Tuple(Rc<Vec<Self>>),
|
|
|
|
// ref-counted, immutable, persistent
|
|
|
|
List(Rc<Vector<Self>>),
|
|
|
|
// ref-counted, immutable, persistent
|
2024-11-06 22:37:57 +00:00
|
|
|
Dict(Rc<HashMap<&'src str, Self>>),
|
2024-11-01 03:53:48 +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> {
|
2024-11-01 03:53:48 +00:00
|
|
|
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()),
|
|
|
|
Value::List(l) => Value::List(l.clone()),
|
|
|
|
Value::Dict(d) => Value::Dict(d.clone()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-01 03:53:48 +00:00
|
|
|
// Value::Fn(fun) => write!(f, "fn {}", fun.name),
|
2024-10-31 20:59:26 +00:00
|
|
|
Value::Tuple(t) => write!(
|
|
|
|
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(", ")
|
|
|
|
),
|
|
|
|
Value::Dict(d) => write!(f, "#{{{:?}}}", d),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-11-01 03:53:48 +00:00
|
|
|
|
2024-11-06 22:37:57 +00:00
|
|
|
impl<'src> Value<'src> {
|
2024-11-01 03:53:48 +00:00
|
|
|
pub fn bool(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Value::Nil | Value::Boolean(false) => false,
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|