Skip to main content

coda_runtime/frontend/
parser.rs

1use crate::{
2    frontend::token::{Token, TokenKind},
3    runtime::ast::*,
4};
5
6pub fn parse(tokens: Vec<Token>) -> Result<Vec<Stmt>, String> {
7    let mut parser = Parser::new(tokens);
8
9    parser.parse()
10}
11
12struct Parser {
13    tokens: Vec<Token>,
14    current: usize,
15}
16
17impl Parser {
18    #[inline(always)]
19    fn new(tokens: Vec<Token>) -> Self {
20        Self { tokens, current: 0 }
21    }
22
23    fn parse(&mut self) -> Result<Vec<Stmt>, String> {
24        let mut statements = Vec::new();
25
26        while !self.is_at_end() {
27            statements.push(self.statement()?);
28        }
29
30        Ok(statements)
31    }
32
33    fn statement(&mut self) -> Result<Stmt, String> {
34        let mut is_exported = false;
35
36        if self.match_kind(&[TokenKind::Export]) {
37            is_exported = true;
38        }
39
40        if self.match_kind(&[TokenKind::Let]) {
41            return self.let_statement(false, is_exported);
42        }
43
44        if self.match_kind(&[TokenKind::Const]) {
45            return self.let_statement(true, is_exported);
46        }
47
48        if self.match_kind(&[TokenKind::Fn]) {
49            return self.fn_statement(is_exported);
50        }
51
52        if self.match_kind(&[TokenKind::Import]) {
53            return self.import_statement();
54        }
55
56        if self.match_kind(&[TokenKind::If]) {
57            return self.if_statement();
58        }
59        
60        if self.match_kind(&[TokenKind::While]) {
61            return self.while_statement();
62        }
63        
64        if self.match_kind(&[TokenKind::Return]) {
65            return self.return_statement();
66        }
67        
68        if self.match_kind(&[TokenKind::LBrace]) {
69            return Ok(Stmt::Block(self.block()?));
70        }
71
72        let expr = self.expression()?;
73        
74        Ok(Stmt::Expr(expr))
75    }
76
77    fn import_statement(&mut self) -> Result<Stmt, String> {
78        let token = self.advance().clone();
79
80        match token.kind {
81            TokenKind::String(s) => Ok(Stmt::Import(s)),
82
83            TokenKind::Identifier(id) => {
84                let mut full_path = id;
85
86                while self.match_kind(&[TokenKind::Dot]) {
87                    match self.advance().kind.clone() {
88                        TokenKind::Identifier(next_id) => full_path.push_str(&format!(".{}", next_id)),
89                        
90                        _ => return Err("expected identifier after '.'".into()),
91                    }
92                }
93
94                Ok(Stmt::Import(full_path))
95            }
96
97            _ => Err("expected module path or string after import".into()),
98        }
99    }
100
101    fn block(&mut self) -> Result<Vec<Stmt>, String> {
102        let mut statements = Vec::new();
103
104        while !self.check(&TokenKind::RBrace) && !self.is_at_end() {
105            statements.push(self.statement()?);
106        }
107
108        self.consume(TokenKind::RBrace, "expected '}' after block")?;
109
110        Ok(statements)
111    }
112
113    fn while_statement(&mut self) -> Result<Stmt, String> {
114        let condition = self.expression()?;
115
116        self.consume(TokenKind::LBrace, "expected '{' after condition")?;
117
118        let body = self.block()?;
119
120        Ok(Stmt::While { condition, body })
121    }
122
123    fn return_statement(&mut self) -> Result<Stmt, String> {
124        if self.check(&TokenKind::RBrace) {
125            return Ok(Stmt::Return(None));
126        }
127
128        let value = self.expression()?;
129
130        Ok(Stmt::Return(Some(value)))
131    }
132
133    fn let_statement(&mut self, is_const: bool, is_exported: bool) -> Result<Stmt, String> {
134        let name = match self.advance().kind.clone() {
135            TokenKind::Identifier(s) => s,
136            
137            _ => return Err("expected identifier".into()),
138        };
139
140        self.consume(TokenKind::Equal, "expected '=' after variable name")?;
141
142        let value = self.expression()?;
143
144        Ok(Stmt::Let { name, value, is_const, is_exported })
145    }
146
147    fn fn_statement(&mut self, is_exported: bool) -> Result<Stmt, String> {
148        let name = match self.advance().kind.clone() {
149            TokenKind::Identifier(s) => s,
150            
151            _ => return Err("expected function name".into()),
152        };
153
154        self.consume(TokenKind::LParen, "expected '(' after function name")?;
155        
156        let mut params = Vec::new();
157
158        if !self.check(&TokenKind::RParen) {
159            loop {
160                match self.advance().kind.clone() {
161                    TokenKind::Identifier(s) => params.push(s),
162                    
163                    _ => return Err("expected parameter name".into()),
164                }
165                
166                if !self.match_kind(&[TokenKind::Comma]) {
167                    break;
168                }
169            }
170        }
171
172        self.consume(TokenKind::RParen, "expected ')' after parameters")?;
173        self.consume(TokenKind::LBrace, "expected '{' before function body")?;
174        
175        let body = self.block()?;
176
177        Ok(Stmt::Function { name, params, body, is_exported })
178    }
179
180    fn if_statement(&mut self) -> Result<Stmt, String> {
181        let condition = self.expression()?;
182
183        self.consume(TokenKind::LBrace, "expected '{' after condition")?;
184        
185        let then_branch = self.block()?;
186
187        let else_branch = if self.match_kind(&[TokenKind::Else]) {
188            self.consume(TokenKind::LBrace, "expected '{' after else")?;
189            
190            Some(self.block()?)
191        } else {
192            None
193        };
194
195        Ok(Stmt::If { condition, then_branch, else_branch })
196    }
197
198    fn expression(&mut self) -> Result<Expr, String> {
199        self.assignment()
200    }
201
202    fn equality(&mut self) -> Result<Expr, String> {
203        let mut expr = self.comparison()?;
204
205        while self.match_kind(&[TokenKind::EqualEqual, TokenKind::BangEqual]) {
206            let operator = self.previous().kind.clone();
207            let right = self.comparison()?;
208
209            expr = Expr::Binary {
210                left: Box::new(expr),
211                operator,
212                right: Box::new(right),
213            };
214        }
215
216        Ok(expr)
217    }
218
219    fn comparison(&mut self) -> Result<Expr, String> {
220        let mut expr = self.term()?;
221
222        while self.match_kind(&[TokenKind::Greater, TokenKind::GreaterEqual, TokenKind::Less, TokenKind::LessEqual]) {
223            let operator = self.previous().kind.clone();
224            let right = self.term()?;
225
226            expr = Expr::Binary {
227                left: Box::new(expr),
228                operator,
229                right: Box::new(right),
230            };
231        }
232
233        Ok(expr)
234    }
235
236    fn term(&mut self) -> Result<Expr, String> {
237        let mut expr = self.factor()?;
238
239        while self.match_kind(&[TokenKind::Plus, TokenKind::Minus]) {
240            let operator = self.previous().kind.clone();
241            let right = self.factor()?;
242            
243            expr = Expr::Binary {
244                left: Box::new(expr),
245                operator,
246                right: Box::new(right),
247            };
248        }
249
250        Ok(expr)
251    }
252
253    fn factor(&mut self) -> Result<Expr, String> {
254        let mut expr = self.unary()?;
255
256        while self.match_kind(&[TokenKind::Star, TokenKind::Slash]) {
257            let operator = self.previous().kind.clone();
258            let right = self.unary()?;
259            
260            expr = Expr::Binary {
261                left: Box::new(expr),
262                operator,
263                right: Box::new(right),
264            };
265        }
266
267        Ok(expr)
268    }
269
270    fn unary(&mut self) -> Result<Expr, String> {
271        self.call()
272    }
273
274    fn call(&mut self) -> Result<Expr, String> {
275        let mut expr = self.primary()?;
276
277        loop {
278            if self.match_kind(&[TokenKind::LParen]) {
279                let mut args = Vec::new();
280
281                if !self.check(&TokenKind::RParen) {
282                    loop {
283                        args.push(self.expression()?);
284                        if !self.match_kind(&[TokenKind::Comma]) {
285                            break;
286                        }
287                    }
288                }
289
290                self.consume(TokenKind::RParen, "expected ')' after arguments")?;
291
292                expr = Expr::Call { callee: Box::new(expr), args };
293            } else {
294                break;
295            }
296        }
297
298        Ok(expr)
299    }
300
301    fn primary(&mut self) -> Result<Expr, String> {
302        let token = self.advance().clone();
303
304        match token.kind {
305            TokenKind::Number(n) => Ok(Expr::Literal(ValueLiteral::Number(n))),
306            TokenKind::String(s) => Ok(Expr::Literal(ValueLiteral::String(s))),
307            TokenKind::True => Ok(Expr::Literal(ValueLiteral::Bool(true))),
308            TokenKind::False => Ok(Expr::Literal(ValueLiteral::Bool(false))),
309            TokenKind::Null => Ok(Expr::Literal(ValueLiteral::Null)),
310            TokenKind::Identifier(s) => Ok(Expr::Variable(s)),
311
312            TokenKind::Fn => {
313                let name = if let TokenKind::Identifier(_) = self.peek().kind {
314                    if let TokenKind::Identifier(s) = self.advance().kind.clone() { s } else { "".to_string() }
315                } else {
316                    "".to_string()
317                };
318
319                self.consume(TokenKind::LParen, "expected '(' after function name")?;
320                
321                let mut params = Vec::new();
322
323                if !self.check(&TokenKind::RParen) {
324                    loop {
325                        match self.advance().kind.clone() {
326                            TokenKind::Identifier(s) => params.push(s),
327                            _ => return Err("expected parameter name".into()),
328                        }
329                        if !self.match_kind(&[TokenKind::Comma]) {
330                            break;
331                        }
332                    }
333                }
334
335                self.consume(TokenKind::RParen, "expected ')' after parameters")?;
336                self.consume(TokenKind::LBrace, "expected '{' before function body")?;
337                let body = self.block()?;
338
339                Ok(Expr::Function { name, params, body })
340            }
341
342            TokenKind::LParen => {
343                let expr = self.expression()?;
344
345                self.consume(TokenKind::RParen, "expected ')'")?;
346
347                Ok(expr)
348            }
349
350            TokenKind::LBracket => {
351                let mut elements = Vec::new();
352
353                if !self.check(&TokenKind::RBracket) {
354                    loop {
355                        elements.push(self.expression()?);
356
357                        if !self.match_kind(&[TokenKind::Comma]) {
358                            break;
359                        }
360                    }
361                }
362
363                self.consume(TokenKind::RBracket, "expected ']'")?;
364
365                Ok(Expr::Array(elements))
366            }
367            _ => Err("unexpected token".into()),
368        }
369    }
370
371    fn assignment(&mut self) -> Result<Expr, String> {
372        let expr = self.equality()?;
373
374        if self.match_kind(&[TokenKind::Equal]) {
375            let value = self.assignment()?;
376
377            if let Expr::Variable(name) = expr {
378                return Ok(Expr::Assign { name, value: Box::new(value) });
379            }
380
381            return Err("Invalid assignment target".into());
382        }
383
384        // compound assignments
385        let compound_map = [
386            (TokenKind::PlusEqual, TokenKind::Plus),
387            (TokenKind::MinusEqual, TokenKind::Minus),
388            (TokenKind::StarEqual, TokenKind::Star),
389            (TokenKind::SlashEqual, TokenKind::Slash),
390        ];
391
392        for (compound, operator) in compound_map {
393            if self.match_kind(&[compound]) {
394                let value = self.assignment()?;
395
396                if let Expr::Variable(name) = expr.clone() {
397                    return Ok(Expr::Assign {
398                        name: name.clone(),
399                        value: Box::new(Expr::Binary {
400                            left: Box::new(Expr::Variable(name)),
401                            operator,
402                            right: Box::new(value),
403                        }),
404                    });
405                } else {
406                    return Err("Invalid assignment target".into());
407                }
408            }
409        }
410
411        Ok(expr)
412    }
413
414    // utils
415    #[inline(always)]
416    fn match_kind(&mut self, kinds: &[TokenKind]) -> bool {
417        for kind in kinds {
418            if self.check(kind) {
419                self.advance();
420                return true;
421            }
422        }
423        false
424    }
425
426    #[inline(always)]
427    fn check(&self, kind: &TokenKind) -> bool {
428        if self.is_at_end() {
429            return false;
430        }
431
432        std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
433    }
434
435    #[inline(always)]
436    fn consume(&mut self, kind: TokenKind, msg: &str) -> Result<(), String> {
437        if self.check(&kind) {
438            self.advance();
439
440            Ok(())
441        } else {
442            Err(msg.into())
443        }
444    }
445
446    #[inline(always)]
447    fn advance(&mut self) -> &Token {
448        if !self.is_at_end() {
449            self.current += 1;
450        }
451
452        self.previous()
453    }
454
455    #[inline(always)]
456    fn previous(&self) -> &Token {
457        &self.tokens[self.current - 1]
458    }
459
460    #[inline(always)]
461    fn peek(&self) -> &Token {
462        &self.tokens[self.current]
463    }
464
465    #[inline(always)]
466    fn is_at_end(&self) -> bool {
467        matches!(self.peek().kind, TokenKind::EOF)
468    }
469}