ralix 0.2.0

A simple, type-safe, tree walking interpreter
use crate::{Parser, ParserResult, Statement, Token, parser::expressions::Precedence};

impl Parser<'_> {
    pub fn parse_expression_statement(&mut self) -> ParserResult<Statement> {
        let expr = self.parse_expression(Precedence::Lowest)?;

        // Convert to assignment statement
        if self.is_peek_token(Token::Assign) {
            return self.parse_assignment_statement(expr);
        }

        Ok(Statement::Expression(expr))
    }
}

#[cfg(test)]
mod tests {
    use std::path::Path;

    use crate::{Expression, Lexer, Literal, Parser, Statement, SymbolTable};

    #[test]
    fn test_parse_expression_statement() {
        let tests = ["3", "3.14159", "true", "false", "'c'", r#" "hello world" "#];
        let expected = [
            Statement::Expression(Expression::Integer(3)),
            Statement::Expression(Expression::Float(
                #[allow(clippy::approx_constant)]
                3.14159,
            )),
            Statement::Expression(Expression::Boolean(true)),
            Statement::Expression(Expression::Boolean(false)),
            Statement::Expression(Expression::Char('c')),
            Statement::Expression(Expression::String(Literal::from("hello world"))),
        ];

        for (test, expected) in tests.into_iter().zip(expected) {
            let lexer = Lexer::new(test);
            let mut symbol_table = SymbolTable::default();
            let wd = Path::new(".");
            let mut parser = Parser::new(lexer, &mut symbol_table, wd);

            let result = parser
                .parse_expression_statement()
                .unwrap_or_else(|err| panic!("{err}"));

            assert_eq!(format!("{result}"), format!("{expected}"))
        }
    }
}