microcad_lang/parse/
type.rs1use crate::{parse::*, parser::*, ty::*};
5use microcad_lang_base::SrcRef;
6use microcad_syntax::ast;
7use std::str::FromStr;
8
9impl Type {
10 fn parse_str(ty: &str, src_ref: SrcRef) -> ParseResult<Self> {
11 if let Some(dimensions) = ty.strip_prefix("Matrix") {
12 let (x, y) = dimensions
13 .split_once('x')
14 .unwrap_or((dimensions, dimensions));
15 let x = usize::from_str(x).map_err(|_| {
16 ParseError::InvalidMatrixType(Refer::new(ty.to_string(), src_ref.clone()))
17 })?;
18 let y = usize::from_str(y).map_err(|_| {
19 ParseError::InvalidMatrixType(Refer::new(ty.to_string(), src_ref.clone()))
20 })?;
21 return Ok(Type::Matrix(MatrixType::new(x, y)));
22 }
23
24 match ty {
25 "Color" => Ok(Type::Tuple(Box::new(TupleType::new_color()))),
26 "Vec2" => Ok(Type::Tuple(Box::new(TupleType::new_vec2()))),
27 "Vec3" => Ok(Type::Tuple(Box::new(TupleType::new_vec3()))),
28 "Size2" => Ok(Type::Tuple(Box::new(TupleType::new_size2()))),
29 "Integer" => Ok(Type::Integer),
30 "Bool" => Ok(Type::Bool),
31 "String" => Ok(Type::String),
32 "Scalar" => Ok(Type::Quantity(QuantityType::Scalar)),
33 "Length" => Ok(Type::Quantity(QuantityType::Length)),
34 "Area" => Ok(Type::Quantity(QuantityType::Area)),
35 "Angle" => Ok(Type::Quantity(QuantityType::Angle)),
36 "Volume" => Ok(Type::Quantity(QuantityType::Volume)),
37 "Weight" => Ok(Type::Quantity(QuantityType::Weight)),
38 "Density" => Ok(Type::Quantity(QuantityType::Density)),
39 "Model" => Ok(Type::Model),
40 _ => Err(ParseError::UnknownType(Refer::new(ty.to_string(), src_ref))),
41 }
42 }
43}
44
45impl FromAst for Type {
46 type AstNode = ast::Type;
47
48 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
49 Ok(match node {
50 ast::Type::Single(ty) => {
51 Type::parse_str(ty.name.as_str(), context.src_ref(&node.span()))?
52 }
53 ast::Type::Array(ty) => Type::Array(Box::new(Type::from_ast(&ty.inner, context)?)),
54 ast::Type::Tuple(ty) => Type::Tuple(Box::new(TupleType::from_ast(ty, context)?)),
55 })
56 }
57}
58
59impl FromAst for TypeAnnotation {
60 type AstNode = ast::Type;
61
62 fn from_ast(node: &Self::AstNode, context: &ParseContext) -> Result<Self, ParseError> {
63 Ok(TypeAnnotation(Refer::new(
64 Type::from_ast(node, context)?,
65 context.src_ref(&node.span()),
66 )))
67 }
68}