1mod expr_parser;
2mod item_parser;
3mod stmt_parser;
4mod type_parser;
5use crate::{
6 ast::{Item, ItemKind, Span},
7 error::{LustError, Result},
8 lexer::{Token, TokenKind},
9};
10use alloc::{
11 format,
12 string::{String, ToString},
13 vec::Vec,
14};
15pub struct Parser {
16 tokens: Vec<Token>,
17 current: usize,
18}
19
20impl Parser {
21 pub fn new(tokens: Vec<Token>) -> Self {
22 Self { tokens, current: 0 }
23 }
24
25 pub fn parse(&mut self) -> Result<Vec<Item>> {
26 let mut items = Vec::new();
27 while !self.is_at_end() {
28 if self.is_item_start() {
29 items.push(self.parse_item()?);
30 } else {
31 let start_token = self.current_token().clone();
32 let mut stmts = Vec::new();
33 while !self.is_at_end() && !self.is_item_start() {
34 stmts.push(self.parse_stmt()?);
35 }
36
37 if !stmts.is_empty() {
38 let end_token = if self.current > 0 {
39 self.tokens[self.current - 1].clone()
40 } else {
41 self.current_token().clone()
42 };
43 items.push(Item::new(
44 ItemKind::Script(stmts),
45 self.make_span(&start_token, &end_token),
46 ));
47 } else {
48 break;
49 }
50 }
51 }
52
53 Ok(items)
54 }
55
56 fn is_item_start(&self) -> bool {
57 match self.peek_kind() {
58 TokenKind::Function
59 | TokenKind::Struct
60 | TokenKind::Enum
61 | TokenKind::Trait
62 | TokenKind::Impl
63 | TokenKind::Type
64 | TokenKind::Const
65 | TokenKind::Static
66 | TokenKind::Use
67 | TokenKind::Module
68 | TokenKind::Extern => true,
69 TokenKind::Pub => self.peek_ahead(1).map_or(false, |t| {
70 matches!(
71 t.kind,
72 TokenKind::Function
73 | TokenKind::Struct
74 | TokenKind::Enum
75 | TokenKind::Trait
76 | TokenKind::Impl
77 | TokenKind::Type
78 | TokenKind::Const
79 | TokenKind::Static
80 | TokenKind::Use
81 | TokenKind::Module
82 | TokenKind::Extern
83 )
84 }),
85 _ => false,
86 }
87 }
88
89 fn current_token(&self) -> &Token {
90 &self.tokens[self.current]
91 }
92
93 fn peek_kind(&self) -> TokenKind {
94 self.current_token().kind.clone()
95 }
96
97 fn peek_ahead(&self, n: usize) -> Option<&Token> {
98 self.tokens.get(self.current + n)
99 }
100
101 fn advance(&mut self) -> &Token {
102 if !self.is_at_end() {
103 self.current += 1;
104 }
105
106 &self.tokens[self.current - 1]
107 }
108
109 fn is_at_end(&self) -> bool {
110 self.peek_kind() == TokenKind::Eof
111 }
112
113 fn check(&self, kind: TokenKind) -> bool {
114 if self.is_at_end() {
115 return false;
116 }
117
118 self.peek_kind() == kind
119 }
120
121 fn match_token(&mut self, kinds: &[TokenKind]) -> bool {
122 for kind in kinds {
123 if self.check(kind.clone()) {
124 self.advance();
125 return true;
126 }
127 }
128
129 false
130 }
131
132 fn consume(&mut self, kind: TokenKind, message: &str) -> Result<&Token> {
133 if self.check(kind) {
134 Ok(self.advance())
135 } else {
136 let token = self.current_token();
137 Err(LustError::ParserError {
138 line: token.line,
139 column: token.column,
140 message: format!("{} (got {:?}, expected {:?})", message, token.kind, kind),
141 module: None,
142 })
143 }
144 }
145
146 fn expect_identifier(&mut self) -> Result<String> {
147 let token = self.consume(TokenKind::Identifier, "Expected identifier")?;
148 Ok(token.lexeme.clone())
149 }
150
151 fn make_span(&self, start_token: &Token, end_token: &Token) -> Span {
152 Span::new(
153 start_token.line,
154 start_token.column,
155 end_token.line,
156 end_token.column,
157 )
158 }
159
160 fn error(&self, message: &str) -> LustError {
161 let token = self.current_token();
162 LustError::ParserError {
163 line: token.line,
164 column: token.column,
165 message: message.to_string(),
166 module: None,
167 }
168 }
169
170 #[allow(dead_code)]
171 fn synchronize(&mut self) {
172 self.advance();
173 while !self.is_at_end() {
174 match self.peek_kind() {
175 TokenKind::Function
176 | TokenKind::Local
177 | TokenKind::If
178 | TokenKind::While
179 | TokenKind::For
180 | TokenKind::Return
181 | TokenKind::Struct
182 | TokenKind::Enum
183 | TokenKind::Trait
184 | TokenKind::Impl => return,
185 _ => {}
186 }
187
188 self.advance();
189 }
190 }
191}