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(Refer::new(
24 inner.to_string(),
25 pair.into(),
26 ))),
27 },
28 _ => Err(ParseError::UnknownType(Refer::new(
29 inner.to_string(),
30 pair.into(),
31 ))),
32 }
33 }
34}
35
36impl Parse for QuantityType {
37 fn parse(pair: Pair) -> ParseResult<Self> {
38 Parser::ensure_rule(&pair, Rule::quantity_type);
39 Ok(match pair.as_str() {
40 "Scalar" => QuantityType::Scalar,
41 "Length" => QuantityType::Length,
42 "Area" => QuantityType::Area,
43 "Angle" => QuantityType::Angle,
44 "Volume" => QuantityType::Volume,
45 "Weight" => QuantityType::Weight,
46 "Density" => QuantityType::Density,
47 _ => unreachable!("Expected type, found {:?}", pair.as_str()),
48 })
49 }
50}
51
52impl Parse for TypeAnnotation {
53 fn parse(pair: Pair) -> ParseResult<Self> {
54 Ok(Self(Refer::new(Type::parse(pair.clone())?, pair.into())))
55 }
56}
57
58#[test]
59fn named_tuple_type() {
60 use crate::parser::*;
61 use crate::ty::Ty;
62
63 let type_annotation =
64 Parser::parse_rule::<TypeAnnotation>(Rule::r#type, "(x: Integer, y: String)", 0)
65 .expect("test error");
66 assert_eq!(type_annotation.ty().to_string(), "(x: Integer, y: String)");
67 assert_eq!(
68 type_annotation.ty(),
69 Type::Tuple(
70 TupleType {
71 named: [("x", Type::Integer), ("y", Type::String)]
72 .into_iter()
73 .map(|(id, ty)| (id.into(), ty))
74 .collect(),
75 ..Default::default()
76 }
77 .into()
78 )
79 );
80}