2024-12-15 22:54:40 +00:00
|
|
|
use crate::compiler::Chunk;
|
|
|
|
use crate::parser::Ast;
|
|
|
|
use crate::spans::Spanned;
|
|
|
|
use imbl::{HashMap, Vector};
|
2024-11-08 01:41:38 +00:00
|
|
|
use std::cell::RefCell;
|
2024-11-01 03:53:48 +00:00
|
|
|
use std::rc::Rc;
|
2024-10-31 20:59:26 +00:00
|
|
|
|
2024-12-15 22:54:40 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct LFn {
|
|
|
|
pub name: &'static str,
|
|
|
|
pub body: Vec<Spanned<Ast>>,
|
|
|
|
pub doc: Option<&'static str>,
|
|
|
|
pub enclosing: Vec<(usize, Value)>,
|
2024-12-13 00:01:51 +00:00
|
|
|
pub has_run: bool,
|
|
|
|
pub input: &'static str,
|
|
|
|
pub src: &'static str,
|
2024-10-31 20:59:26 +00:00
|
|
|
}
|
|
|
|
|
2024-12-15 22:54:40 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub enum Value {
|
2024-10-31 20:59:26 +00:00
|
|
|
Nil,
|
2024-12-16 04:28:57 +00:00
|
|
|
True,
|
|
|
|
False,
|
2024-12-23 00:07:42 +00:00
|
|
|
Keyword(usize),
|
2024-12-15 22:54:40 +00:00
|
|
|
Interned(usize),
|
|
|
|
FnDecl(usize),
|
|
|
|
String(Rc<String>),
|
2024-10-31 20:59:26 +00:00
|
|
|
Number(f64),
|
2024-12-16 04:28:57 +00:00
|
|
|
Tuple(Rc<Vec<Value>>),
|
2024-12-15 22:54:40 +00:00
|
|
|
List(Box<Vector<Value>>),
|
2024-12-16 04:28:57 +00:00
|
|
|
Dict(Box<HashMap<usize, Value>>),
|
2024-12-23 00:07:42 +00:00
|
|
|
Box(Rc<RefCell<Value>>),
|
2024-12-15 22:54:40 +00:00
|
|
|
Fn(Rc<RefCell<LFn>>),
|
2024-11-01 03:53:48 +00:00
|
|
|
}
|
|
|
|
|
2024-12-18 06:28:23 +00:00
|
|
|
impl std::fmt::Display for Value {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
use Value::*;
|
|
|
|
match self {
|
|
|
|
Nil => write!(f, "nil"),
|
|
|
|
True => write!(f, "true"),
|
|
|
|
False => write!(f, "false"),
|
|
|
|
Keyword(idx) => write!(f, ":{idx}"),
|
|
|
|
Interned(idx) => write!(f, "\"@{idx}\""),
|
|
|
|
Number(n) => write!(f, "{n}"),
|
2024-12-23 00:07:42 +00:00
|
|
|
Tuple(members) => write!(
|
|
|
|
f,
|
|
|
|
"({})",
|
|
|
|
members
|
|
|
|
.iter()
|
|
|
|
.map(|x| x.to_string())
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(", ")
|
|
|
|
),
|
|
|
|
List(members) => write!(
|
|
|
|
f,
|
|
|
|
"[{}]",
|
|
|
|
members
|
|
|
|
.iter()
|
|
|
|
.map(|x| x.to_string())
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(", ")
|
|
|
|
),
|
|
|
|
Dict(members) => write!(
|
|
|
|
f,
|
|
|
|
"#{{{}}}",
|
|
|
|
members
|
|
|
|
.iter()
|
|
|
|
.map(|(k, v)| format!("{k} {v}"))
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(", ")
|
|
|
|
),
|
|
|
|
Box(value) => write!(f, "box {}", value.as_ref().borrow()),
|
2024-12-18 06:28:23 +00:00
|
|
|
_ => todo!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-15 22:54:40 +00:00
|
|
|
impl Value {
|
2024-12-16 04:28:57 +00:00
|
|
|
pub fn show(&self, ctx: &Chunk) -> String {
|
2024-12-15 22:54:40 +00:00
|
|
|
use Value::*;
|
|
|
|
match &self {
|
2024-12-16 04:28:57 +00:00
|
|
|
Nil => "nil".to_string(),
|
|
|
|
True => "true".to_string(),
|
|
|
|
False => "false".to_string(),
|
|
|
|
Number(n) => format!("{n}"),
|
|
|
|
Interned(i) => {
|
|
|
|
let str_str = ctx.strings[*i];
|
|
|
|
format!("\"{str_str}\"")
|
|
|
|
}
|
|
|
|
Keyword(i) => {
|
|
|
|
let kw_str = ctx.keywords[*i];
|
|
|
|
format!(":{kw_str}")
|
|
|
|
}
|
|
|
|
Tuple(t) => {
|
|
|
|
let members = t.iter().map(|e| e.show(ctx)).collect::<Vec<_>>().join(", ");
|
|
|
|
format!("({members})")
|
|
|
|
}
|
|
|
|
List(l) => {
|
|
|
|
let members = l.iter().map(|e| e.show(ctx)).collect::<Vec<_>>().join(", ");
|
|
|
|
format!("[{members}]")
|
|
|
|
}
|
|
|
|
Dict(d) => {
|
|
|
|
let members = d
|
|
|
|
.iter()
|
|
|
|
.map(|(k, v)| {
|
|
|
|
let key_show = Value::Keyword(*k).show(ctx);
|
|
|
|
let value_show = v.show(ctx);
|
|
|
|
format!("{key_show} {value_show}")
|
|
|
|
})
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(", ");
|
|
|
|
format!("#{{{members}}}")
|
|
|
|
}
|
|
|
|
String(s) => s.as_ref().clone(),
|
2024-12-23 00:07:42 +00:00
|
|
|
Box(x) => format!("box {{ {} }}", x.as_ref().borrow().show(ctx)),
|
2024-12-16 04:28:57 +00:00
|
|
|
_ => todo!(),
|
2024-12-05 00:07:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|