finx 0.1.0

A fast, lightweight embeddable scripting language
Documentation
#[cfg(test)]
mod tests {
    use logos::Logos;
    use finx::lexer::Token;

    #[test]
    fn test_lexer() {
        let source = r#"
            let a = 1;
            let b = "hello";
            fn add(x, y) {
                if x > y {
                    return x;
                }
                return y;
            }
            if true == false {
                print("oops");
            }
        "#;

        let lexer = Token::lexer(source);
        let tokens: Vec<Token> = lexer
            .map(|token_result| token_result.unwrap_or(Token::Error))
            .collect();

        assert_eq!(
            tokens,
            vec![
                Token::Let,
                Token::Identifier("a".to_string()),
                Token::Assign,
                Token::NumberLiteral(1.0),
                Token::Semicolon,
                Token::Let,
                Token::Identifier("b".to_string()),
                Token::Assign,
                Token::StringLiteral("hello".to_string()),
                Token::Semicolon,
                Token::Fn,
                Token::Identifier("add".to_string()),
                Token::LParen,
                Token::Identifier("x".to_string()),
                Token::Comma,
                Token::Identifier("y".to_string()),
                Token::RParen,
                Token::LBrace,
                Token::If,
                Token::Identifier("x".to_string()),
                Token::Gt,
                Token::Identifier("y".to_string()),
                Token::LBrace,
                Token::Return,
                Token::Identifier("x".to_string()),
                Token::Semicolon,
                Token::RBrace,
                Token::Return,
                Token::Identifier("y".to_string()),
                Token::Semicolon,
                Token::RBrace,
                Token::If,
                Token::True,
                Token::EqEq,
                Token::False,
                Token::LBrace,
                Token::Identifier("print".to_string()),
                Token::LParen,
                Token::StringLiteral("oops".to_string()),
                Token::RParen,
                Token::Semicolon,
                Token::RBrace,
            ]
        );
    }

    #[test]
    fn test_simple_if() {
        let source = r#"
            if 1 == 1 {
                print("yes");
            } if a {
                print("a exists and is not null");
            }
        "#;
        let lexer = Token::lexer(source);
        let tokens: Vec<Token> = lexer
            .map(|token_result| token_result.unwrap_or(Token::Error))
            .collect();

        assert_eq!(
            tokens,
            vec![
                Token::If,
                Token::NumberLiteral(1.0),
                Token::EqEq,
                Token::NumberLiteral(1.0),
                Token::LBrace,
                Token::Identifier("print".to_string()),
                Token::LParen,
                Token::StringLiteral("yes".to_string()),
                Token::RParen,
                Token::Semicolon,
                Token::RBrace,
                Token::If,
                Token::Identifier("a".to_string()),
                Token::LBrace,
                Token::Identifier("print".to_string()),
                Token::LParen,
                Token::StringLiteral("a exists and is not null".to_string()),
                Token::RParen,
                Token::Semicolon,
                Token::RBrace,
            ]
        );
    }

    #[test]
    fn test_lexer_skips_comments() {
        let source = r#"let a = 1; // this is a comment
        let b = 2; /* 
        block comment 
        let d = 4;
        */ let c = 3;"#;

        let lexer = Token::lexer(source);
        let tokens: Vec<Token> = lexer
            .map(|token_result| token_result.unwrap_or(Token::Error))
            .collect();

        assert_eq!(
            tokens,
            vec![
                Token::Let,
                Token::Identifier("a".to_string()),
                Token::Assign,
                Token::NumberLiteral(1.0),
                Token::Semicolon,
                Token::Let,
                Token::Identifier("b".to_string()),
                Token::Assign,
                Token::NumberLiteral(2.0),
                Token::Semicolon,
                Token::Let,
                Token::Identifier("c".to_string()),
                Token::Assign,
                Token::NumberLiteral(3.0),
                Token::Semicolon,
            ]
        );
    }
}