1use crate::{
2 Lexer, Program,
3 ast::{Action, Item, Statement},
4 token::{Token, TokenKind},
5};
6
7#[derive(Debug)]
8pub struct Parser<'a> {
9 lexer: Lexer<'a>,
10 current_token: Token<'a>,
11 peek_token: Token<'a>,
12}
13
14impl<'a> Parser<'a> {
15 pub fn new(mut lexer: Lexer<'a>) -> Self {
16 let current_token = lexer.next_token();
17 let peek_token = lexer.next_token();
18
19 Parser {
20 lexer,
21 current_token,
22 peek_token,
23 }
24 }
25
26 fn next_token(&mut self) {
27 self.current_token = self.peek_token.clone();
28 self.peek_token = self.lexer.next_token();
29 }
30
31 fn is_eof(&self) -> bool {
32 self.current_token.kind == TokenKind::Eof
33 }
34
35 fn parse_next_item(&mut self) -> Option<Item<'a>> {
36 match &self.current_token.kind {
37 TokenKind::Eof => None,
38 TokenKind::LeftCurlyBrace => Some(self.parse_action()),
39 _ => panic!(
40 "parse_next_item not yet implemented, found token: {:?}",
41 self.current_token
42 ),
43 }
44 }
45
46 fn parse_action(&mut self) -> Item<'a> {
47 self.next_token(); let mut statements = Vec::new();
50 if self.current_token.kind == TokenKind::Print {
51 statements.push(Statement::Print(vec![]));
52 }
53
54 while self.current_token.kind != TokenKind::RightCurlyBrace
55 && self.current_token.kind != TokenKind::Eof
56 {
57 self.next_token();
58 }
59
60 Item::PatternAction {
61 pattern: None,
62 action: Some(Action { statements }),
63 }
64 }
65
66 pub fn parse_program(&mut self) -> Program<'_> {
67 let mut program = Program::new();
68
69 while !self.is_eof() {
70 match self.parse_next_item() {
71 Some(item) => program.add_item(item),
72 None => {}
73 }
74 self.next_token();
75 }
76
77 program
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn create_parser() {
87 let parser = Parser::new(Lexer::new("42 == 42"));
88
89 assert_eq!(parser.current_token.literal, "42");
90 assert_eq!(parser.peek_token.literal, "==");
91 }
92
93 #[test]
94 fn parse_empty_program() {
95 let mut parser = Parser::new(Lexer::new(""));
96
97 let program = parser.parse_program();
98
99 assert_eq!(program.len(), 0);
100 }
101
102 #[test]
103 fn parse_action_without_pattern() {
104 let mut parser = Parser::new(Lexer::new("{ print }"));
105
106 let program = parser.parse_program();
107
108 assert_eq!(program.len(), 1);
109 assert_eq!("{ print }", program.to_string());
110 }
111}