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