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