microcad_lang/parse/
type.rs1use crate::{parse::*, parser::*, src_ref::*, ty::*};
5
6impl Parse for Type {
7 fn parse(pair: Pair) -> ParseResult<Self> {
8 Parser::ensure_rule(&pair, Rule::r#type);
9 let inner = pair.inner().next().expect("Expected type");
10
11 match inner.as_rule() {
12 Rule::array_type => Ok(Type::Array(Box::new(Type::parse(
13 inner.inner().next().expect("Type"),
14 )?))),
15 Rule::tuple_type => Ok(Type::Tuple(TupleType::parse(inner)?.into())),
16 Rule::matrix_type => Ok(Type::Matrix(MatrixType::parse(inner)?)),
17 Rule::quantity_type => Ok(Type::Quantity(QuantityType::parse(inner)?)),
18 Rule::base_type => match inner.as_str() {
19 "Integer" => Ok(Type::Integer),
21 "Bool" => Ok(Type::Bool),
22 "String" => Ok(Type::String),
23 _ => Err(ParseError::UnknownType(inner.to_string())),
24 },
25 _ => Err(ParseError::UnknownType(inner.to_string())),
26 }
27 }
28}
29
30impl Parse for QuantityType {
31 fn parse(pair: Pair) -> ParseResult<Self> {
32 Parser::ensure_rule(&pair, Rule::quantity_type);
33 Ok(match pair.as_str() {
34 "Scalar" => QuantityType::Scalar,
35 "Length" => QuantityType::Length,
36 "Area" => QuantityType::Area,
37 "Angle" => QuantityType::Angle,
38 "Volume" => QuantityType::Volume,
39 "Weight" => QuantityType::Weight,
40 "Density" => QuantityType::Density,
41 _ => unreachable!("Expected type, found {:?}", pair.as_str()),
42 })
43 }
44}
45
46impl Parse for TypeAnnotation {
47 fn parse(pair: Pair) -> ParseResult<Self> {
48 Ok(Self(Refer::new(Type::parse(pair.clone())?, pair.into())))
49 }
50}
51
52#[test]
53fn named_tuple_type() {
54 use crate::parser::*;
55 use crate::ty::Ty;
56
57 let type_annotation =
58 Parser::parse_rule::<TypeAnnotation>(Rule::r#type, "(x: Integer, y: String)", 0)
59 .expect("test error");
60 assert_eq!(type_annotation.ty().to_string(), "(x: Integer, y: String)");
61 assert_eq!(
62 type_annotation.ty(),
63 Type::Tuple(
64 TupleType {
65 named: [("x", Type::Integer), ("y", Type::String)]
66 .into_iter()
67 .map(|(id, ty)| (id.into(), ty))
68 .collect(),
69 ..Default::default()
70 }
71 .into()
72 )
73 );
74}