brainterpreter 0.1.1

An interpreter for a Bauble toy programming language
Documentation
//! Parser

use std::iter::Peekable;

use thiserror::Error;

use crate::ast::Program;
use crate::lexer::token::Token;
use crate::lexer::SourceToken;
use crate::source::Position;

mod advance;
mod expression;
mod statement;

#[derive(Debug)]
pub struct Parser<T>
where
    T: Iterator<Item = SourceToken>,
{
    tokens: Peekable<T>,
}

#[derive(Debug, Clone, PartialEq, Error)]
pub enum ParsingError {
    #[error("error during parsing at {0}")]
    Unknown(Position),
    #[error("unexpected token `{0}` at {1}")]
    UnexpectedToken(Token, Position),
    #[error("{position}: expected `{expected}` but found `{actual}`")]
    MissingToken {
        position: Position,
        expected: Token,
        actual: Token,
    },
    #[error("missing operand at {0}")]
    MissingOperand(Position),
    #[error("unknown operation at {0}")]
    UnknownOperation(Position),
    #[error("missing closing parentheses at {0}")]
    MissingClosingParentheses(Position),
    #[error("attempting to call uncallable object {0}")]
    InvalidCall(Position),
    #[error("attempting to assign to non-assignable object {0}")]
    InvalidAssignment(Position),
}

impl<T> Parser<T>
where
    T: Iterator<Item = SourceToken>,
{
    pub fn new(tokens: T) -> Self {
        Parser {
            tokens: tokens.peekable(),
        }
    }

    pub fn parse_program(&mut self) -> Result<Program, ParsingError> {
        let mut program = Program::default();
        while self.tokens.peek().is_some() {
            program.add_statement(self.statement()?);
        }
        Ok(program)
    }
}