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