cl-interpret: Make ConValues act like value types
(Aside from the fact that they're smothered in heap allocations)
This commit is contained in:
parent
01871bf455
commit
485afb7843
@ -31,20 +31,23 @@ pub enum ConValue {
|
||||
/// A reference
|
||||
Ref(Rc<ConValue>),
|
||||
/// An Array
|
||||
Array(Rc<[ConValue]>),
|
||||
Array(Box<[ConValue]>),
|
||||
/// A tuple
|
||||
Tuple(Rc<[ConValue]>),
|
||||
Tuple(Box<[ConValue]>),
|
||||
/// An exclusive range
|
||||
RangeExc(Integer, Integer),
|
||||
/// An inclusive range
|
||||
RangeInc(Integer, Integer),
|
||||
/// A value of a product type
|
||||
Struct(Rc<(Sym, HashMap<Sym, ConValue>)>),
|
||||
Struct(Box<(Sym, HashMap<Sym, ConValue>)>),
|
||||
/// An entire namespace
|
||||
Module(Box<HashMap<Sym, Option<ConValue>>>),
|
||||
/// A callable thing
|
||||
Function(Rc<Function>),
|
||||
/// A built-in function
|
||||
BuiltIn(&'static dyn BuiltIn),
|
||||
}
|
||||
|
||||
impl ConValue {
|
||||
/// Gets whether the current value is true or false
|
||||
pub fn truthy(&self) -> IResult<bool> {
|
||||
@ -57,7 +60,7 @@ impl ConValue {
|
||||
let (Self::Int(a), Self::Int(b)) = (self, other) else {
|
||||
Err(Error::TypeError)?
|
||||
};
|
||||
Ok(Self::RangeExc(a, b.saturating_sub(1)))
|
||||
Ok(Self::RangeExc(a, b))
|
||||
}
|
||||
pub fn range_inc(self, other: Self) -> IResult<Self> {
|
||||
let (Self::Int(a), Self::Int(b)) = (self, other) else {
|
||||
@ -304,6 +307,18 @@ impl std::fmt::Display for ConValue {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
ConValue::Module(module) => {
|
||||
use std::fmt::Write;
|
||||
let mut f = f.delimit_with("{", "\n}");
|
||||
for (k, v) in module.iter() {
|
||||
write!(f, "\n{k}: ")?;
|
||||
match v {
|
||||
Some(v) => write!(f, "{v},"),
|
||||
None => write!(f, "_,"),
|
||||
}?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
ConValue::Function(func) => {
|
||||
write!(f, "{}", func.decl())
|
||||
}
|
||||
|
@ -67,11 +67,21 @@ impl Interpret for Static {
|
||||
impl Interpret for Module {
|
||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||
let Self { name, kind } = self;
|
||||
// TODO: Enter this module's namespace
|
||||
match kind {
|
||||
env.push_frame(Interned::to_ref(name), Default::default());
|
||||
let out = match kind {
|
||||
ModuleKind::Inline(file) => file.interpret(env),
|
||||
ModuleKind::Outline => Err(Error::Outlined(*name)),
|
||||
}
|
||||
ModuleKind::Outline => {
|
||||
eprintln!("{}", Error::Outlined(*name));
|
||||
Ok(ConValue::Empty)
|
||||
}
|
||||
};
|
||||
|
||||
let frame = env
|
||||
.pop_frame()
|
||||
.expect("Environment frames must be balanced");
|
||||
env.insert(*name, Some(ConValue::Module(frame.into())));
|
||||
|
||||
out
|
||||
}
|
||||
}
|
||||
impl Interpret for Function {
|
||||
|
Loading…
x
Reference in New Issue
Block a user