rudus/src/value.rs

277 lines
8.3 KiB
Rust
Raw Normal View History

use crate::base::BaseFn;
2024-12-15 22:54:40 +00:00
use crate::compiler::Chunk;
use crate::parser::Ast;
use crate::spans::Spanned;
use imbl::{HashMap, Vector};
2025-06-04 21:53:38 +00:00
use std::cell::RefCell;
use std::rc::Rc;
2024-10-31 20:59:26 +00:00
2025-06-04 21:53:38 +00:00
// #[derive(Clone, Debug, PartialEq)]
// pub struct Defined {
// pub name: &'static str,
// pub doc: Option<&'static str>,
// // pub enclosing: Vec<(usize, Value)>,
// // pub has_run: bool,
// // pub input: &'static str,
// // pub src: &'static str,
// pub chunks: Vec<(u8, Chunk)>,
// pub closed: Vec<Value>,
// }
// impl Defined {
// pub fn close(&mut self, val: Value) {
// self.closed.push(val);
// }
// }
2024-12-15 22:54:40 +00:00
#[derive(Clone, Debug, PartialEq)]
2025-06-04 21:53:38 +00:00
pub enum LFn {
Declared {
name: &'static str,
},
Defined {
name: &'static str,
doc: Option<&'static str>,
chunks: Vec<(u8, Chunk)>,
closed: RefCell<Vec<Value>>,
},
2024-12-24 17:35:44 +00:00
}
impl LFn {
2025-06-04 21:53:38 +00:00
pub fn close(&self, value: Value) {
match self {
LFn::Declared { .. } => unreachable!(),
LFn::Defined { closed, .. } => {
closed.borrow_mut().push(value);
}
}
}
pub fn doc(&self) -> Value {
match self {
LFn::Declared { name } => {
Value::String(Rc::new(format!("fn {name}: undefined function")))
}
LFn::Defined {
name,
doc: Some(doc),
..
} => Value::String(Rc::new(format!("fn {name}\n{doc}"))),
LFn::Defined { name, .. } => {
Value::String(Rc::new(format!("fn {name}: no documentation")))
}
}
}
pub fn name(&self) -> &'static str {
match self {
LFn::Declared { name } | LFn::Defined { name, .. } => name,
}
}
pub fn chunk(&self, arity: u8) -> &Chunk {
match self {
LFn::Declared { .. } => unreachable!(),
LFn::Defined { chunks, .. } => &chunks.iter().find(|(a, _)| *a == arity).unwrap().1,
}
}
pub fn upvalue(&self, idx: u8) -> Value {
match self {
LFn::Declared { .. } => unreachable!(),
LFn::Defined { closed, .. } => closed.borrow()[idx as usize].clone(),
}
2024-12-24 17:35:44 +00:00
}
2024-10-31 20:59:26 +00:00
}
#[derive(Clone, Debug)]
2024-12-15 22:54:40 +00:00
pub enum Value {
2025-05-26 13:16:47 +00:00
Nothing,
2024-10-31 20:59:26 +00:00
Nil,
2024-12-16 04:28:57 +00:00
True,
False,
Keyword(&'static str),
Interned(&'static str),
2024-12-15 22:54:40 +00:00
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>>),
Dict(Box<HashMap<&'static str, Value>>),
2024-12-23 00:07:42 +00:00
Box(Rc<RefCell<Value>>),
2025-06-04 21:53:38 +00:00
Fn(Rc<LFn>),
BaseFn(BaseFn),
}
impl PartialEq for Value {
fn eq(&self, other: &Value) -> bool {
use Value::*;
match (self, other) {
(Nothing, Nothing) | (Nil, Nil) | (True, True) | (False, False) => true,
(Keyword(str1), Keyword(str2)) | (Interned(str1), Interned(str2)) => str1 == str2,
(String(x), String(y)) => x == y,
(String(x), Interned(y)) => x.as_ref() == y,
(Interned(x), String(y)) => x == y.as_ref(),
(Number(x), Number(y)) => x == y,
(Tuple(x), Tuple(y)) => x == y,
(List(x), List(y)) => x == y,
(Dict(x), Dict(y)) => x == y,
(Box(x), Box(y)) => std::ptr::eq(x.as_ref().as_ptr(), y.as_ref().as_ptr()),
(Fn(x), Fn(y)) => x == y,
(BaseFn(x), BaseFn(y)) => std::ptr::eq(x, y),
_ => false,
}
}
}
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 {
2025-05-26 13:16:47 +00:00
Nothing => write!(f, "_"),
2024-12-18 06:28:23 +00:00
Nil => write!(f, "nil"),
True => write!(f, "true"),
False => write!(f, "false"),
Keyword(str) => write!(f, ":{str}"),
Interned(str) => write!(f, "\"{str}\""),
2025-05-30 15:44:32 +00:00
String(str) => write!(f, "\"{str}\""),
2024-12-18 06:28:23 +00:00
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()),
2025-06-04 21:53:38 +00:00
Fn(lfn) => write!(f, "fn {}", lfn.name()),
BaseFn(_) => write!(f, "base fn"),
2024-12-18 06:28:23 +00:00
}
}
}
2024-12-15 22:54:40 +00:00
impl Value {
pub fn show(&self) -> 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(str) => format!("\"{str}\""),
2025-05-30 15:44:32 +00:00
String(str) => {
let str_str = str.to_string();
format!("\"{str_str}\"")
}
Keyword(str) => format!(":{str}"),
2024-12-16 04:28:57 +00:00
Tuple(t) => {
let members = t.iter().map(|e| e.show()).collect::<Vec<_>>().join(", ");
2024-12-16 04:28:57 +00:00
format!("({members})")
}
List(l) => {
let members = l.iter().map(|e| e.show()).collect::<Vec<_>>().join(", ");
2024-12-16 04:28:57 +00:00
format!("[{members}]")
}
Dict(d) => {
let members = d
.iter()
.map(|(k, v)| {
let key_show = Value::Keyword(k).show();
let value_show = v.show();
2024-12-16 04:28:57 +00:00
format!("{key_show} {value_show}")
})
.collect::<Vec<_>>()
.join(", ");
format!("#{{{members}}}")
}
Box(x) => format!("box {{ {} }}", x.as_ref().borrow().show()),
2025-06-04 21:53:38 +00:00
Fn(lfn) => format!("fn {}", lfn.name()),
BaseFn(_) => "base fn".to_string(),
Nothing => unreachable!(),
2024-12-05 00:07:03 +00:00
}
}
pub fn stringify(&self) -> String {
2025-05-30 15:44:32 +00:00
use Value::*;
match &self {
Nil => "nil".to_string(),
True => "true".to_string(),
False => "false".to_string(),
Number(n) => format!("{n}"),
Interned(str) => str.to_string(),
Keyword(str) => str.to_string(),
2025-05-30 15:44:32 +00:00
Tuple(t) => {
let members = t
.iter()
.map(|e| e.stringify())
2025-05-30 15:44:32 +00:00
.collect::<Vec<_>>()
.join(", ");
members.to_string()
}
List(l) => {
let members = l
.iter()
.map(|e| e.stringify())
2025-05-30 15:44:32 +00:00
.collect::<Vec<_>>()
.join(", ");
members.to_string()
}
Dict(d) => {
let members = d
.iter()
.map(|(k, v)| {
let key_show = Value::Keyword(k).stringify();
let value_show = v.stringify();
2025-05-30 15:44:32 +00:00
format!("{key_show} {value_show}")
})
.collect::<Vec<_>>()
.join(", ");
members.to_string()
}
String(s) => s.as_ref().clone(),
Box(x) => x.as_ref().borrow().stringify(),
2025-06-04 21:53:38 +00:00
Fn(lfn) => format!("fn {}", lfn.name()),
2025-05-30 15:44:32 +00:00
_ => todo!(),
}
}
pub fn type_of(&self) -> &'static str {
use Value::*;
match self {
2025-05-26 13:16:47 +00:00
Nothing => unreachable!(),
Nil => "nil",
True => "bool",
False => "bool",
Keyword(..) => "keyword",
Interned(..) => "string",
String(..) => "string",
Number(..) => "number",
Tuple(..) => "tuple",
List(..) => "list",
Dict(..) => "dict",
Box(..) => "box",
Fn(..) => "fn",
BaseFn(..) => "fn",
}
}
2024-12-05 00:07:03 +00:00
}