crisp/src/types.rs
2024-12-05 17:25:16 -06:00

199 lines
4.4 KiB
Rust

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<Value>;
#[derive(Default, Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub enum Value {
List(Vec<Value>),
String(String),
Number(i64),
#[default]
Nil,
Function(fn(LispArgs) -> Result<Value>, Rc<Value>),
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<Value>) -> Self {
Self::Function(f, Rc::new(Self::Nil))
}
pub fn apply(&self, args: LispArgs) -> Result<Value> {
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<Vec<Value>> for Value {
fn from(values: Vec<Value>) -> 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::<i64>() {
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<String> 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<i64> 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<Value> 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<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,
}
}
}
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)
}
}