diff --git a/compiler/cl-interpret/src/convalue.rs b/compiler/cl-interpret/src/convalue.rs index 2aec994..bb8796f 100644 --- a/compiler/cl-interpret/src/convalue.rs +++ b/compiler/cl-interpret/src/convalue.rs @@ -31,20 +31,23 @@ pub enum ConValue { /// A reference Ref(Rc), /// 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)>), + Struct(Box<(Sym, HashMap)>), + /// An entire namespace + Module(Box>>), /// A callable thing Function(Rc), /// A built-in function BuiltIn(&'static dyn BuiltIn), } + impl ConValue { /// Gets whether the current value is true or false pub fn truthy(&self) -> IResult { @@ -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 { 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()) } diff --git a/compiler/cl-interpret/src/interpret.rs b/compiler/cl-interpret/src/interpret.rs index 6b3edf4..8ada42c 100644 --- a/compiler/cl-interpret/src/interpret.rs +++ b/compiler/cl-interpret/src/interpret.rs @@ -67,11 +67,21 @@ impl Interpret for Static { impl Interpret for Module { fn interpret(&self, env: &mut Environment) -> IResult { 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 {