simple-vm 0.1.1

A simple bytecode VM with a custom compiler
Documentation
#[derive(Debug)]
pub enum Expr {
    Number(i64),
    BinaryOp(Box<Expr>, BinaryOpKind, Box<Expr>),
    Variable(String),
}

#[derive(Debug)]
pub enum BinaryOpKind {
    Add,
    Sub,
    Mul,
    Div,
    Equals,
    LessThan,
    GreaterThan,
}

#[derive(Debug)]
pub enum Statement {
    Let(String, Expr),
    Assign(String, Expr),
    If(Expr, Vec<Statement>, Vec<Statement>),
    While(Expr, Vec<Statement>),
    Print(Expr),
}

pub struct Parser {
    lexer: Lexer,
    current_token: Option<Token>,
}

impl Parser {
    pub fn new(input: &str) -> Self {
        let mut lexer = Lexer::new(input);
        let current_token = lexer.next_token();
        Parser {
            lexer,
            current_token,
        }
    }

    fn advance(&mut self) {
        self.current_token = self.lexer.next_token();
    }

    fn expect(&mut self, expected: Token) -> Result<(), String> {
        if self.current_token == Some(expected.clone()) {
            self.advance();
            Ok(())
        } else {
            Err(format!("Expected {:?}, got {:?}", expected, self.current_token))
        }
    }

    pub fn parse_program(&mut self) -> Result<Vec<Statement>, String> {
        let mut statements = Vec::new();
        while self.current_token.is_some() {
            statements.push(self.parse_statement()?);
        }
        Ok(statements)
    }

    fn parse_statement(&mut self) -> Result<Statement, String> {
        match &self.current_token {
            Some(Token::Let) => {
                self.advance();
                if let Some(Token::Identifier(name)) = self.current_token.clone() {
                    self.advance();
                    self.expect(Token::Equals)?;
                    let expr = self.parse_expression()?;
                    self.expect(Token::Semicolon)?;
                    Ok(Statement::Let(name, expr))
                } else {
                    Err("Expected identifier after 'let'".to_string())
                }
            },
            Some(Token::If) => {
                self.advance();
                let condition = self.parse_expression()?;
                let then_block = self.parse_block()?;
                let else_block = if self.current_token == Some(Token::Else) {
                    self.advance();
                    self.parse_block()?
                } else {
                    Vec::new()
                };
                Ok(Statement::If(condition, then_block, else_block))
            },
            Some(Token::While) => {
                self.advance();
                let condition = self.parse_expression()?;
                let block = self.parse_block()?;
                Ok(Statement::While(condition, block))
            },
            Some(Token::Print) => {
                self.advance();
                let expr = self.parse_expression()?;
                self.expect(Token::Semicolon)?;
                Ok(Statement::Print(expr))
            },
            Some(Token::Identifier(name)) => {
                let name = name.clone();
                self.advance();
                self.expect(Token::Equals)?;
                let expr = self.parse_expression()?;
                self.expect(Token::Semicolon)?;
                Ok(Statement::Assign(name, expr))
            },
            _ => Err("Expected statement".to_string()),
        }
    }

    fn parse_block(&mut self) -> Result<Vec<Statement>, String> {
        let mut statements = Vec::new();
        
        match &self.current_token {
            Some(Token::LParen) => {
                self.advance();
                while self.current_token.is_some() && self.current_token != Some(Token::RParen) {
                    statements.push(self.parse_statement()?);
                }
                self.expect(Token::RParen)?;
            }
            _ => {
                statements.push(self.parse_statement()?);
            }
        }
        
        Ok(statements)
    }

    fn parse_expression(&mut self) -> Result<Expr, String> {
        self.parse_comparison()
    }

    fn parse_comparison(&mut self) -> Result<Expr, String> {
        let mut expr = self.parse_additive()?;

        while let Some(token) = &self.current_token {
            let op = match token {
                Token::DoubleEquals => BinaryOpKind::Equals,
                Token::LessThan => BinaryOpKind::LessThan,
                Token::GreaterThan => BinaryOpKind::GreaterThan,
                _ => break,
            };
            self.advance();
            let right = self.parse_additive()?;
            expr = Expr::BinaryOp(Box::new(expr), op, Box::new(right));
        }

        Ok(expr)
    }

    fn parse_additive(&mut self) -> Result<Expr, String> {
        let mut expr = self.parse_multiplicative()?;

        while let Some(token) = &self.current_token {
            let op = match token {
                Token::Plus => BinaryOpKind::Add,
                Token::Minus => BinaryOpKind::Sub,
                _ => break,
            };
            self.advance();
            let right = self.parse_multiplicative()?;
            expr = Expr::BinaryOp(Box::new(expr), op, Box::new(right));
        }

        Ok(expr)
    }

    fn parse_multiplicative(&mut self) -> Result<Expr, String> {
        let mut expr = self.parse_primary()?;

        while let Some(token) = &self.current_token {
            let op = match token {
                Token::Star => BinaryOpKind::Mul,
                Token::Slash => BinaryOpKind::Div,
                _ => break,
            };
            self.advance();
            let right = self.parse_primary()?;
            expr = Expr::BinaryOp(Box::new(expr), op, Box::new(right));
        }

        Ok(expr)
    }

    fn parse_primary(&mut self) -> Result<Expr, String> {
        match &self.current_token {
            Some(Token::Number(n)) => {
                let n = *n;
                self.advance();
                Ok(Expr::Number(n))
            }
            Some(Token::Identifier(name)) => {
                let name = name.clone();
                self.advance();
                Ok(Expr::Variable(name))
            }
            Some(Token::LParen) => {
                self.advance();
                let expr = self.parse_expression()?;
                self.expect(Token::RParen)?;
                Ok(expr)
            }
            _ => Err("Expected expression".to_string()),
        }
    }
}