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}