mechylang/parser/expressions/
identifier.rs

1use std::fmt;
2use std::fmt::{Display, Formatter};
3use std::rc::Rc;
4use serde::Serialize;
5use crate::parser::{Parser, Error, Result};
6use crate::{trace, TokenKind, Span};
7use crate::parser::error::Location;
8
9#[derive(Debug, Clone, PartialEq, Serialize)]
10pub struct Identifier {
11    pub span: Span,
12    pub value: Rc<str>,
13}
14
15impl Display for Identifier {
16    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
17        write!(f, "{}", self.value)
18    }
19}
20
21impl From<Identifier> for Rc<str> {
22    fn from(ident: Identifier) -> Self {
23        ident.value
24    }
25}
26impl Parser<'_> {
27
28     pub(super) fn parse_identifier(&mut self) -> Result<Identifier> {
29         let _trace = trace!("parse_identifier");
30
31         let literal = match self.cur_token.kind {
32             TokenKind::Identifier(ref literal) => literal.clone(),
33             _ => {
34                 return Err(Error::UnexpectedToken {
35                     span: self.cur_token.span.clone(),
36                     expected: vec![TokenKind::Identifier(String::new())],
37                     found: self.cur_token.kind.clone(),
38                     location: Some(Location::Expression),
39                 })
40             }
41         };
42
43         Ok(Identifier {
44             span: self.cur_token.span.clone(),
45             value: literal.into(),
46         })
47     }
48 }
49
50#[cfg(test)]
51mod tests {
52    use crate::parser::expressions::Expression;
53    use crate::parser::tests::parse;
54    use crate::parser::statements::Statement;
55
56    #[test]
57    fn test_identifier_expression() {
58        let input = "foobar;";
59
60        let statements = parse(input).unwrap();
61
62        let stmt = &statements[0];
63
64        match stmt {
65            Statement::Expression(ref expr) => {
66                match expr.expression {
67                    Expression::Identifier(ref ident) => {
68                        assert_eq!(ident.value, "foobar".into());
69                    }
70                    _ => panic!("expected identifier expression"),
71                };
72            }
73            _ => panic!("expected expression statement"),
74        };
75    }
76}