199 lines
4.4 KiB
Rust
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)
|
|
}
|
|
}
|