microcad_lang/parse/
lang_type.rs1use crate::{parse::*, parser::*, syntax::*, ty::*};
5
6impl Parse for TupleType {
7 fn parse(pair: Pair) -> ParseResult<Self> {
8 use crate::ty::Ty;
9 Parser::ensure_rule(&pair, Rule::tuple_type);
10
11 match pair.as_str() {
12 "Color" => Ok(TupleType::new_color()),
13 "Vec2" => Ok(TupleType::new_vec2()),
14 "Vec3" => Ok(TupleType::new_vec3()),
15 "Size2" => Ok(TupleType::new_size2()),
16 _ => {
17 let mut named = std::collections::HashMap::new();
18 let mut unnamed = std::collections::HashSet::new();
19
20 pair.inner().try_for_each(|pair| {
21 let mut inner = pair.inner();
22 let next = inner.next().expect("Identifier or type expected");
23 if let Ok(id) = Identifier::parse(next.clone()) {
24 if named
25 .insert(
26 id.clone(),
27 TypeAnnotation::parse(
28 inner.next().expect("Identifier or type expected"),
29 )?
30 .ty(),
31 )
32 .is_some()
33 {
34 return Err(ParseError::DuplicateTupleIdentifier(id));
35 }
36 } else {
37 let ty = TypeAnnotation::parse(next)?.ty();
38 if !unnamed.insert(ty.clone()) {
39 return Err(ParseError::DuplicateTupleType(ty));
40 }
41 }
42
43 Ok::<(), ParseError>(())
44 })?;
45
46 Ok(Self { named, unnamed })
47 }
48 }
49 }
50}
51
52impl Parse for MatrixType {
53 fn parse(pair: Pair) -> ParseResult<Self> {
54 Parser::ensure_rule(&pair, Rule::matrix_type);
55
56 let mut m: Option<usize> = None;
57 let mut n: Option<usize> = None;
58
59 for p in pair.inner() {
60 match p.as_rule() {
61 Rule::int => match m {
62 None => m = Some(p.as_str().parse().expect("Valid integer")),
63 Some(_) => n = Some(p.as_str().parse().expect("Valid integer")),
64 },
65 _ => unreachable!(),
66 }
67 }
68
69 let m = m.expect("M");
70
71 Ok(Self {
72 rows: m,
73 columns: n.unwrap_or(m),
74 })
75 }
76}
77
78#[test]
79fn array_type() {
80 use crate::parser::{Parser, Rule};
81 use crate::ty::Ty;
82
83 let type_annotation =
84 Parser::parse_rule::<TypeAnnotation>(Rule::r#type, "[Integer]", 0).expect("test error");
85 assert_eq!(type_annotation.ty().to_string(), "[Integer]");
86 assert_eq!(type_annotation.ty(), Type::Array(Box::new(Type::Integer)));
87}
88
89#[test]
90fn matrix_type() {
91 use crate::parser::*;
92 use crate::ty::Ty;
93
94 let type_annotation =
95 Parser::parse_rule::<TypeAnnotation>(Rule::r#type, "Matrix4x3", 0).expect("test error");
96 assert_eq!(type_annotation.ty().to_string(), "Matrix4x3");
97 assert_eq!(
98 type_annotation.ty(),
99 Type::Matrix(MatrixType {
100 rows: 4,
101 columns: 3,
102 })
103 );
104}