71 lines
2.0 KiB
Rust
71 lines
2.0 KiB
Rust
use std::{fmt::Display, rc::Rc};
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum Type {
|
|
Any,
|
|
Number,
|
|
String,
|
|
Boolean,
|
|
Nil,
|
|
Function(FunctionType),
|
|
Struct(Rc<StructType>),
|
|
Unresolved(String),
|
|
}
|
|
|
|
impl Display for Type {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Type::Any => write!(f, "any"),
|
|
Type::Number => write!(f, "number"),
|
|
Type::String => write!(f, "string"),
|
|
Type::Boolean => write!(f, "boolean"),
|
|
Type::Nil => write!(f, "nil"),
|
|
Type::Function(fun) => write!(f, "{}", fun),
|
|
Type::Struct(struct_) => write!(f, "{}", struct_),
|
|
Type::Unresolved(name) => write!(f, "{}", name),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub struct FunctionType {
|
|
pub params: Vec<(String, Box<Type>)>,
|
|
pub return_type: Box<Type>,
|
|
}
|
|
|
|
impl Display for FunctionType {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let rendered_params = self
|
|
.params
|
|
.iter()
|
|
.map(|(name, ty)| format!("{}: {}", name, ty))
|
|
.collect::<Vec<_>>()
|
|
.join(", ");
|
|
write!(f, "fn({}) -> {}", rendered_params, self.return_type)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub struct StructType {
|
|
pub fields: Vec<(String, Box<Type>)>,
|
|
pub methods: Vec<(String, FunctionType)>,
|
|
}
|
|
|
|
impl Display for StructType {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let rendered_field = self
|
|
.fields
|
|
.iter()
|
|
.map(|(name, ty)| format!("{}: {}", name, ty))
|
|
.collect::<Vec<_>>()
|
|
.join(", ");
|
|
let rendered_method = self
|
|
.methods
|
|
.iter()
|
|
.map(|(name, ty)| format!("{}: {}", name, ty))
|
|
.collect::<Vec<_>>()
|
|
.join(", ");
|
|
write!(f, "struct {{ {}, {} }}", rendered_field, rendered_method)
|
|
}
|
|
}
|