72 lines
2.0 KiB
Rust
72 lines
2.0 KiB
Rust
|
use crate::parser::*;
|
||
|
use crate::spans::*;
|
||
|
use imbl::*;
|
||
|
use std::fmt;
|
||
|
|
||
|
#[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>>,
|
||
|
}
|
||
|
|
||
|
#[derive(Clone, Debug, PartialEq)]
|
||
|
pub enum Value<'src> {
|
||
|
Nil,
|
||
|
Boolean(bool),
|
||
|
Number(f64),
|
||
|
Keyword(&'src str),
|
||
|
String(&'src str),
|
||
|
Tuple(Vec<Self>), // on the heap for now
|
||
|
List(Vector<Self>), // ref-counted, immutable, persistent
|
||
|
Dict(HashMap<&'src str, Self>), // ref-counted, immutable, persistent
|
||
|
Fn(&'src Fn<'src>),
|
||
|
// 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
|
||
|
}
|
||
|
|
||
|
impl<'src> fmt::Display for Value<'src> {
|
||
|
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),
|
||
|
Value::Fn(fun) => write!(f, "fn {}", fun.name),
|
||
|
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),
|
||
|
}
|
||
|
}
|
||
|
}
|