blanket_script/parser/
statement.rs

1use nom::{
2    bytes::complete::tag,
3    sequence::{delimited, pair, terminated},
4    Parser,
5};
6
7use crate::parser::{
8    expression::{parse_expression, parse_identifier},
9    ws1,
10};
11
12use super::{ws0, Expression, ParseResult};
13
14#[derive(Debug, Eq, PartialEq, Clone)]
15pub enum Statement {
16    LetStatement {
17        identifier: String,
18        expression: Expression,
19    },
20}
21
22fn parse_let_statement(input: &str) -> ParseResult<Statement> {
23    pair(
24        delimited(tag("let"), ws1(parse_identifier), tag("=")),
25        terminated(ws0(parse_expression), tag(";")),
26    )
27    .map(|(identifier, expression)| Statement::LetStatement {
28        identifier,
29        expression,
30    })
31    .parse(input)
32}
33
34pub(crate) fn parse_statement(input: &str) -> ParseResult<Statement> {
35    parse_let_statement(input)
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use crate::parser::*;
42
43    macro_rules! assert_parse {
44        ($input:expr, $expected:expr) => {
45            let (rest, result) = parse_statement($input).unwrap();
46            assert_eq!(rest, "");
47            assert_eq!(result, $expected);
48        };
49    }
50
51    #[test]
52    fn test_parse_let_statement() {
53        assert_parse!(
54            "let x = 42;",
55            Statement::LetStatement {
56                identifier: "x".into(),
57                expression: Expression::Number("42".into())
58            }
59        );
60        assert_parse!(
61            "let foo = 42n;",
62            Statement::LetStatement {
63                identifier: "foo".into(),
64                expression: Expression::BigInt("42".into())
65            }
66        );
67        assert_parse!(
68            "let bar = \"hello\";",
69            Statement::LetStatement {
70                identifier: "bar".into(),
71                expression: Expression::String(StringLiteral {
72                    value: "hello".into(),
73                    interpolations: vec![]
74                })
75            }
76        );
77        assert_parse!(
78            "let baz = bar;",
79            Statement::LetStatement {
80                identifier: "baz".into(),
81                expression: Expression::Identifier("bar".into())
82            }
83        );
84    }
85}