lust/parser/
mod.rs

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}