1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use smallvec::SmallVec;
use crate::syntax::token::Token;
pub enum Identifier<'a> {
Unqual(Token<'a>),
Qual(SmallVec<[Token<'a>; 2]>)
}
#[cfg(test)]
impl<'a> std::fmt::Debug for Identifier<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Identifier::Unqual(token) => write!(f, "{}", token.get_str_value()),
Identifier::Qual(tokens) => {
for i in 0..tokens.len() - 1 {
write!(f, "{} :: ", tokens[i].get_str_value())?;
}
write!(f, "{}", tokens[tokens.len() - 1])
}
}
}
}
#[cfg(test)]
pub fn assert_ident_unqual(ident: &Identifier<'_>, expected: &str) {
use crate::syntax::token::TokenInner;
if let Identifier::Unqual(token ) = ident {
if let TokenInner::Ident(actual) = token.token_inner {
assert_eq!(actual, expected);
} else {
panic!("incorrect token content")
}
} else {
panic!("should be an unqualified identifier")
}
}
#[cfg(test)]
pub fn assert_ident_qual(ident: &Identifier<'_>, expected: &[&str]) {
if let Identifier::Qual(tokens) = ident {
tokens.iter()
.map(Token::get_str_value)
.zip(expected.iter())
.for_each(|(got, expected): (&str, &&str)| assert_eq!(got, *expected));
} else {
panic!("should be a qualified identifier")
}
}
#[cfg(test)]
mod test {
use std::cell::RefCell;
use crate::diag::DiagContext;
use crate::parse::parser::Parser;
use crate::syntax::id::{Identifier, assert_ident_unqual, assert_ident_qual};
#[test]
fn test_parse_unqual_ident() {
let source: &str = "ablahblahblah";
let diag: RefCell<DiagContext> = RefCell::new(DiagContext::new());
let mut parser: Parser = Parser::new(0, source, &diag);
let ident: Identifier = parser.parse_ident().unwrap();
assert!(!diag.borrow().has_diag());
dbg!(&ident);
assert_ident_unqual(&ident, "ablahblahblah");
}
#[test]
fn test_parse_qual_ident() {
let source: &str = "ablah::blah::blahblah";
let diag: RefCell<DiagContext> = RefCell::new(DiagContext::new());
let mut parser: Parser = Parser::new(0, source, &diag);
let ident: Identifier = parser.parse_ident().unwrap();
assert!(!diag.borrow().has_diag());
dbg!(&ident);
assert_ident_qual(&ident, &["ablah", "blah", "blahblah"]);
}
}