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