dice_rust/
parser.rs

1use crate::ast::{BinaryOperator, Expression, Program, Statement};
2use crate::error::{ParseError, Position, Span};
3use crate::lexer::{Lexer, Token, TokenKind};
4
5pub struct Parser {
6    tokens: Vec<Token>,
7    current: usize,
8}
9
10impl Parser {
11    pub fn new(source: &str) -> Result<Self, ParseError> {
12        let tokens = Lexer::new(source).lex()?;
13        Ok(Self { tokens, current: 0 })
14    }
15
16    fn current_token(&self) -> Token {
17        self.tokens
18            .get(self.current)
19            .cloned()
20            .unwrap_or_else(|| Token::new(TokenKind::Eof, Span::single(Position::new(1, 1, 0))))
21    }
22
23    fn is_at_end(&self) -> bool {
24        matches!(self.current_token().kind, TokenKind::Eof)
25    }
26
27    fn advance(&mut self) -> Token {
28        if !self.is_at_end() {
29            self.current += 1;
30        }
31        self.tokens
32            .get(self.current - 1)
33            .cloned()
34            .unwrap_or_else(|| Token::new(TokenKind::Eof, Span::single(Position::new(1, 1, 0))))
35    }
36
37    fn token_to_binary_operator(&self, token: &TokenKind) -> Option<BinaryOperator> {
38        match token {
39            TokenKind::Dice => Some(BinaryOperator::Dice),
40            _ => None,
41        }
42    }
43
44    pub fn parse(&mut self) -> Result<Program, ParseError> {
45        let mut program = Program::new();
46
47        let stmt = self.parse_statement()?;
48        program.statement = Some(stmt);
49
50        if !self.is_at_end() {
51            return Err(ParseError::unexpected_end_of_input());
52        }
53
54        Ok(program)
55    }
56
57    fn parse_statement(&mut self) -> Result<Statement, ParseError> {
58        match &self.current_token().kind {
59            TokenKind::U32(_) => self.parse_expression_statement(),
60            _ => Err(ParseError::syntax_error(
61                self.current_token().span.clone(),
62                "Expected a statement".to_string(),
63            )),
64        }
65    }
66
67    fn parse_expression_statement(&mut self) -> Result<Statement, ParseError> {
68        let start_span = self.current_token().span.clone();
69        let count = if let TokenKind::U32(count) = &self.current_token().kind {
70            *count
71        } else {
72            return Err(ParseError::unexpected_token(
73                self.current_token().span.clone(),
74                "u32",
75                format!("{:?}", self.current_token().kind),
76            ));
77        };
78        self.advance();
79        let operator_token = self.advance();
80        self.token_to_binary_operator(&operator_token.kind);
81        let faces = if let TokenKind::U32(faces) = &self.current_token().kind {
82            *faces
83        } else {
84            return Err(ParseError::unexpected_token(
85                self.current_token().span.clone(),
86                "u32",
87                format!("{:?}", self.current_token().kind),
88            ));
89        };
90        self.advance();
91        let end_span = self.current_token().span.clone();
92
93        Ok(Statement::expr_stmt(
94            Expression::dice(count, faces, Span::new(start_span.start, end_span.end)),
95            Span::new(start_span.start, end_span.end),
96        ))
97    }
98}