Amo/src/ir/value.rs

63 lines
1.4 KiB
Rust

use core::fmt;
use std::{collections::LinkedList, mem::discriminant};
use super::{expr::Expr, Identifier, evaluation::EvaluateError};
#[derive(Clone, Debug)]
pub enum Value {
Int(usize),
String(String),
Function(Vec<Identifier>, LinkedList<Expr>),
Structural(usize, Vec<Value>),
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Int(v) => write!(f, "{}", v),
Self::String(val) => write!(f, "\"{val}\""),
Self::Function(args, exprs) => write!(f,
"function({}):{}",
args.into_iter()
.map(|a| a.to_string())
.collect::<Vec<_>>()
.join(", "),
exprs.into_iter()
.map(|e| format!("\n\t{e}"))
.collect::<String>(),
),
Self::Structural(_, _) => todo!(),
}
}
}
impl TryInto<usize> for Value {
type Error = EvaluateError;
fn try_into(self) -> Result<usize, EvaluateError> {
if let Value::Int(v) = self {
Ok(v)
} else {
Err(EvaluateError::TypeMismatch(
discriminant(&Value::Int(0)),
discriminant(&self),
))
}
}
}
impl TryInto<bool> for Value {
type Error = EvaluateError;
fn try_into(self) -> Result<bool, EvaluateError> {
if let Value::Int(v) = self {
Ok(v != 0)
} else {
Err(EvaluateError::TypeMismatch(
discriminant(&Value::Int(0)),
discriminant(&self),
))
}
}
}