diff --git a/src/parser/plugins/validate_type.rs b/src/parser/plugins/validate_type.rs index 21855b8..139c9b9 100644 --- a/src/parser/plugins/validate_type.rs +++ b/src/parser/plugins/validate_type.rs @@ -1,7 +1,7 @@ use crate::{ error::AiScriptError, parser::{node as cst, visit::Visitor}, - r#type::get_type_by_source, + r#type::Type, }; #[derive(Debug, PartialEq, Clone)] @@ -17,7 +17,7 @@ impl Visitor for TypeValidator { .. }) = &statement { - get_type_by_source(var_type.clone())?; + Type::try_from(var_type.clone())?; }; Ok(statement) } @@ -31,7 +31,7 @@ impl Visitor for TypeValidator { .. }) = &expression { - get_type_by_source(ret_type.clone())?; + Type::try_from(ret_type.clone())?; }; Ok(expression) } diff --git a/src/type.rs b/src/type.rs index defe4de..78d1670 100644 --- a/src/type.rs +++ b/src/type.rs @@ -3,9 +3,9 @@ use std::fmt::Display; use crate::{error::AiScriptSyntaxError, node as ast}; pub enum Type { - Simple(TSimple), - Generic(TGeneric), - Fn(TFn), + Simple, + Generic, + Fn, } impl Display for ast::NamedTypeSource { @@ -42,32 +42,28 @@ impl Display for ast::TypeSource { } } -pub fn get_type_by_source(type_source: ast::TypeSource) -> Result { - match type_source { - ast::TypeSource::NamedTypeSource(type_source) => match type_source.name.as_str() { - "null" | "bool" | "num" | "str" | "any" | "void" => Ok(Type::Simple(TSimple { - name: type_source.name, - })), - "arr" | "obj" => Ok(Type::Generic(TGeneric { - name: type_source.name, - inners: vec![type_source.inner.map_or_else( - || { - Ok(Type::Simple(TSimple { - name: "any".to_string(), - })) - }, - |inner| get_type_by_source(*inner), - )?], - })), - _ => Err(AiScriptSyntaxError::UnknownType(type_source.to_string())), - }, - ast::TypeSource::FnTypeSource(type_source) => Ok(Type::Fn(TFn { - args: type_source - .args - .into_iter() - .map(get_type_by_source) - .collect::, AiScriptSyntaxError>>()?, - result: get_type_by_source(*type_source.result)?.into(), - })), +impl TryFrom for Type { + type Error = AiScriptSyntaxError; + + fn try_from(value: ast::TypeSource) -> Result { + match value { + ast::TypeSource::NamedTypeSource(type_source) => match type_source.name.as_str() { + "null" | "bool" | "num" | "str" | "any" | "void" => Ok(Type::Simple), + "arr" | "obj" => { + if let Some(inner) = type_source.inner { + Type::try_from(*inner)?; + } + Ok(Type::Generic) + } + _ => Err(AiScriptSyntaxError::UnknownType(type_source.to_string())), + }, + ast::TypeSource::FnTypeSource(ast::FnTypeSource { args, result, .. }) => { + for arg in args { + Type::try_from(arg)?; + } + Type::try_from(*result)?; + Ok(Type::Fn) + } + } } }