use miette::{miette, Result}; use std::{num::ParseIntError, rc::Rc}; #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Expression { pub expr: String, pub value: Value, } impl From<&str> for Expression { fn from(value: &str) -> Self { Self { expr: value.to_string(), value: Value::String(value.to_string()), } } } pub type LispArgs = Vec; #[derive(Default, Debug, Clone, Eq, PartialEq, PartialOrd, Ord)] pub enum Value { List(Vec), String(String), Number(i64), #[default] Nil, Function(fn(LispArgs) -> Result, Rc), True, Symbol(Symbol), Keyword(Keyword), } impl Value { fn parse(str: &str) -> Self { match str { "a" => Self::Symbol(Symbol::from(str)), _ => Self::Nil, } } pub fn func(f: fn(LispArgs) -> Result) -> Self { Self::Function(f, Rc::new(Self::Nil)) } pub fn apply(&self, args: LispArgs) -> Result { match self { Self::Function(f, _) => f(args), _ => Err(miette!("No function here, shouldn't call apply")), } } pub fn is_list(&self) -> bool { match self { Self::List(_) => true, _ => false, } } } impl From> for Value { fn from(values: Vec) -> Self { Value::List(values) } } impl From<&str> for Value { fn from(s: &str) -> Self { let s = s.to_string(); if let Ok(parse_result) = s.parse::() { Value::Number(parse_result) } else if let Some(s) = s.strip_prefix(":") { Value::Keyword(Keyword(s.to_string())) } else if s == "t".to_owned() { Value::True } else if s.starts_with(r#"""#) { Value::String(s.replace('"', "")) } else if s == "nil".to_owned() { Value::Nil } else { Value::Symbol(Symbol(s)) } } } impl From for Value { fn from(str: String) -> Self { Self::from(str.as_str()) } } impl From<&String> for Value { fn from(str: &String) -> Self { Self::from(str.as_str()) } } impl From for Value { fn from(num: i64) -> Self { Self::Number(num) } } impl From<&i64> for Value { fn from(num: &i64) -> Self { Self::Number(*num) } } impl From for String { fn from(value: Value) -> Self { match value { Value::String(str) => str, Value::Symbol(Symbol(str)) => str, Value::Keyword(Keyword(str)) => str, _ => String::default(), } } } impl From<&Value> for String { fn from(value: &Value) -> Self { match value { Value::String(str) => str.clone(), Value::Symbol(Symbol(str)) => { dbg!(str); str.clone() } Value::Keyword(Keyword(str)) => str.clone(), _ => String::default(), } } } impl From for i32 { fn from(value: Value) -> Self { match value { Value::Number(num) => num as i32, _ => 0, } } } impl From for i64 { fn from(value: Value) -> Self { match value { Value::Number(num) => num, _ => 0, } } } impl From<&Value> for i32 { fn from(value: &Value) -> Self { match value { Value::Number(num) => *num as i32, _ => 0, } } } impl From<&Value> for i64 { fn from(value: &Value) -> Self { match value { Value::Number(num) => *num, _ => 0, } } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Symbol(pub String); impl From<&str> for Symbol { fn from(s: &str) -> Self { Symbol(String::from(s)) } } impl std::fmt::Display for Symbol { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&self.0, f) } } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Keyword(pub String); impl From<&str> for Keyword { fn from(s: &str) -> Self { Keyword(String::from(s)) } } impl std::fmt::Display for Keyword { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&self.0, f) } }