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 if self.check(TokenKind::Identifier) || self.check(TokenKind::Type) {
148 let token = self.advance().clone();
149 Ok(token.lexeme.clone())
150 } else {
151 let token = self.current_token().clone();
152 Err(LustError::ParserError {
153 line: token.line,
154 column: token.column,
155 message: format!(
156 "Expected identifier (got {:?}, expected Identifier)",
157 token.kind
158 ),
159 module: None,
160 })
161 }
162 }
163
164 fn make_span(&self, start_token: &Token, end_token: &Token) -> Span {
165 Span::new(
166 start_token.line,
167 start_token.column,
168 end_token.line,
169 end_token.column,
170 )
171 }
172
173 fn error(&self, message: &str) -> LustError {
174 let token = self.current_token();
175 LustError::ParserError {
176 line: token.line,
177 column: token.column,
178 message: message.to_string(),
179 module: None,
180 }
181 }
182
183 #[allow(dead_code)]
184 fn synchronize(&mut self) {
185 self.advance();
186 while !self.is_at_end() {
187 match self.peek_kind() {
188 TokenKind::Function
189 | TokenKind::Local
190 | TokenKind::If
191 | TokenKind::While
192 | TokenKind::For
193 | TokenKind::Return
194 | TokenKind::Struct
195 | TokenKind::Enum
196 | TokenKind::Trait
197 | TokenKind::Impl => return,
198 _ => {}
199 }
200
201 self.advance();
202 }
203 }
204}