blanket-script 0.0.2

BlanketScript is a simple script language inspired by Rust that transpiles to JavaScript.
Documentation
use nom::{
    bytes::complete::tag,
    sequence::{delimited, pair, terminated},
    Parser,
};

use crate::parser::{
    expression::{parse_expression, parse_identifier},
    ws1,
};

use super::{ws0, Expression, ParseResult};

#[derive(Debug, Eq, PartialEq, Clone)]
pub enum Statement {
    LetStatement {
        identifier: String,
        expression: Expression,
    },
}

fn parse_let_statement(input: &str) -> ParseResult<Statement> {
    pair(
        delimited(tag("let"), ws1(parse_identifier), tag("=")),
        terminated(ws0(parse_expression), tag(";")),
    )
    .map(|(identifier, expression)| Statement::LetStatement {
        identifier,
        expression,
    })
    .parse(input)
}

pub(crate) fn parse_statement(input: &str) -> ParseResult<Statement> {
    parse_let_statement(input)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::parser::*;

    macro_rules! assert_parse {
        ($input:expr, $expected:expr) => {
            let (rest, result) = parse_statement($input).unwrap();
            assert_eq!(rest, "");
            assert_eq!(result, $expected);
        };
    }

    #[test]
    fn test_parse_let_statement() {
        assert_parse!(
            "let x = 42;",
            Statement::LetStatement {
                identifier: "x".into(),
                expression: Expression::Number("42".into())
            }
        );
        assert_parse!(
            "let foo = 42n;",
            Statement::LetStatement {
                identifier: "foo".into(),
                expression: Expression::BigInt("42".into())
            }
        );
        assert_parse!(
            "let bar = \"hello\";",
            Statement::LetStatement {
                identifier: "bar".into(),
                expression: Expression::String(StringLiteral {
                    value: "hello".into(),
                    interpolations: vec![]
                })
            }
        );
        assert_parse!(
            "let baz = bar;",
            Statement::LetStatement {
                identifier: "baz".into(),
                expression: Expression::Identifier("bar".into())
            }
        );
    }
}