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 next.as_rule() == Rule::identifier {
24 let id = Identifier::parse(next)?;
25 if named
26 .insert(
27 id.clone(),
28 TypeAnnotation::parse(
29 inner.next().expect("Identifier or type expected"),
30 )?
31 .ty(),
32 )
33 .is_some()
34 {
35 return Err(ParseError::DuplicateTupleIdentifier(id));
36 }
37 } else {
38 let ty = TypeAnnotation::parse(next)?.ty();
39 if !unnamed.insert(ty.clone()) {
40 return Err(ParseError::DuplicateTupleType(Refer::new(
41 ty,
42 pair.clone().into(),
43 )));
44 }
45 }
46
47 Ok::<(), ParseError>(())
48 })?;
49
50 Ok(Self { named, unnamed })
51 }
52 }
53 }
54}
55
56impl Parse for MatrixType {
57 fn parse(pair: Pair) -> ParseResult<Self> {
58 Parser::ensure_rule(&pair, Rule::matrix_type);
59
60 let mut m: Option<usize> = None;
61 let mut n: Option<usize> = None;
62
63 for p in pair.inner() {
64 match p.as_rule() {
65 Rule::int => match m {
66 None => m = Some(p.as_str().parse().expect("Valid integer")),
67 Some(_) => n = Some(p.as_str().parse().expect("Valid integer")),
68 },
69 _ => unreachable!(),
70 }
71 }
72
73 let m = m.expect("M");
74
75 Ok(Self {
76 rows: m,
77 columns: n.unwrap_or(m),
78 })
79 }
80}
81
82#[test]
83fn array_type() {
84 use crate::parser::{Parser, Rule};
85 use crate::ty::Ty;
86
87 let type_annotation =
88 Parser::parse_rule::<TypeAnnotation>(Rule::r#type, "[Integer]", 0).expect("test error");
89 assert_eq!(type_annotation.ty().to_string(), "[Integer]");
90 assert_eq!(type_annotation.ty(), Type::Array(Box::new(Type::Integer)));
91}
92
93#[test]
94fn matrix_type() {
95 use crate::parser::*;
96 use crate::ty::Ty;
97
98 let type_annotation =
99 Parser::parse_rule::<TypeAnnotation>(Rule::r#type, "Matrix4x3", 0).expect("test error");
100 assert_eq!(type_annotation.ty().to_string(), "Matrix4x3");
101 assert_eq!(
102 type_annotation.ty(),
103 Type::Matrix(MatrixType {
104 rows: 4,
105 columns: 3,
106 })
107 );
108}