lust/parser/
mod.rs

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}