use crate::lexer::{Span, Token, TokenType};
use super::error::ParseError;
#[derive(Debug, Clone, PartialEq)]
pub enum TypeKind {
Primitive(PrimitiveType),
Named(String, Vec<TypeNode>),
TraitObject(Box<TypeNode>),
Function {
params: Vec<TypeNode>,
returns: Box<TypeNode>,
},
Reference(Box<TypeNode>),
List(Box<TypeNode>),
Map(Box<TypeNode>, Box<TypeNode>),
Set(Box<TypeNode>),
Tuple(Box<TypeNode>, Box<TypeNode>),
Auto,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TypeNode {
pub kind: TypeKind,
pub span: Span,
}
impl super::Spanned for TypeNode {
fn span(&self) -> &Span {
&self.span
}
}
impl From<PrimitiveType> for TypeNode {
fn from(prim: PrimitiveType) -> Self {
TypeNode {
kind: TypeKind::Primitive(prim),
span: Span::new(0, 0),
}
}
}
impl From<&str> for TypeNode {
fn from(s: &str) -> Self {
TypeNode {
kind: TypeKind::Named(s.to_string(), Vec::new()),
span: Span::new(0, 0),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PrimitiveType {
Int,
Float,
Bool,
Char,
Str,
Void,
Auto,
}
impl PrimitiveType {
pub fn parse(token: Token) -> Result<PrimitiveType, ParseError> {
match token.token_type {
TokenType::Id(value) => match value.as_str() {
"int" => Ok(PrimitiveType::Int),
"float" => Ok(PrimitiveType::Float),
"bool" => Ok(PrimitiveType::Bool),
"char" => Ok(PrimitiveType::Char),
"string" => Ok(PrimitiveType::Str),
"void" => Ok(PrimitiveType::Void),
"auto" => Ok(PrimitiveType::Auto),
_ => Err(ParseError::new(
format!("Unknown primitive type: {}", value),
token.span,
)),
},
_ => Err(ParseError::new(
format!("Expected an identifier, found {:?}", token.token_type),
token.span,
)),
}
}
}