Skip to main content

mysz_core/parse/
parser.rs

1use crate::lex::lexing::{Token, TokenType};
2use crate::parse::parsing::{
3    BinaryOp, Expr, ExprKind, Identifier, Literal, Parameter, ParserError, ParserErrorType,
4    Program, Stmt, Type, UnaryOp,
5};
6use crate::utils::location::Location;
7use crate::utils::toident::to_ident;
8
9pub struct Parser {
10    pub tokens: Vec<Token>,
11    pub token_idx: usize,
12    pub ast: Program,
13    pub parser_errs: Vec<ParserError>,
14    pub generic_params: Vec<String>,
15}
16
17impl Parser {
18    pub fn new(tokens: Vec<Token>) -> Self {
19        Self {
20            tokens,
21            token_idx: 0,
22            ast: Program {
23                statements: Vec::new(),
24            },
25            parser_errs: Vec::new(),
26            generic_params: Vec::new(),
27        }
28    }
29
30    fn eof(&self) -> bool {
31        self.token_idx >= self.tokens.len()
32    }
33
34    fn current(&self) -> Option<&Token> {
35        self.tokens.get(self.token_idx)
36    }
37
38    fn throw(&mut self, etype: ParserErrorType, message: String, location: Location) -> Token {
39        self.parser_errs.push(ParserError {
40            etype,
41            message,
42            location: location.clone(),
43        });
44
45        Token {
46            ttype: TokenType::Niltoken,
47            location,
48            value: "ERROR".to_string(),
49        }
50    }
51
52    fn advance(&mut self) {
53        if self.token_idx < self.tokens.len() {
54            self.token_idx += 1;
55        }
56    }
57
58    fn get_token(&self) -> Option<&Token> {
59        self.current()
60    }
61
62    fn expect(&mut self, ttype: TokenType) -> Option<Token> {
63        let tk = self.get_token()?.clone();
64
65        if tk.ttype == ttype {
66            self.advance();
67            Some(tk)
68        } else {
69            self.throw(
70                ParserErrorType::UnexpectedTokenTypeError,
71                format!(
72                    "Expected {:?}, found {:?} '{:?}'",
73                    ttype, tk.ttype, tk.value
74                ),
75                tk.location,
76            );
77            None
78        }
79    }
80
81    pub fn parse(&mut self) {
82        let mut statements = Vec::new();
83
84        while !self.eof() {
85            if let Some(stmt) = self.parse_statement(true) {
86                statements.push(stmt);
87            } else {
88                self.advance();
89            }
90        }
91
92        self.ast = Program { statements };
93    }
94
95    fn parse_generic_params(&mut self) -> Vec<String> {
96        let mut params = Vec::new();
97        if matches!(
98            self.get_token().map(|t| &t.ttype),
99            Some(TokenType::LessThan)
100        ) {
101            self.advance(); // consume '<'
102            while let Some(tk) = self.expect(TokenType::Identifier) {
103                params.push(tk.value);
104                if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Comma)) {
105                    self.advance();
106                } else {
107                    break;
108                }
109            }
110            self.expect(TokenType::GreaterThan);
111        }
112        params
113    }
114
115    fn parse_generic_args(&mut self) -> Vec<Type> {
116        let mut args = Vec::new();
117        if matches!(
118            self.get_token().map(|t| &t.ttype),
119            Some(TokenType::LessThan)
120        ) {
121            self.advance(); // consume '<'
122            while let Some(ty) = self.parse_type() {
123                args.push(ty);
124
125                if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Comma)) {
126                    self.advance();
127                } else {
128                    break;
129                }
130            }
131            self.expect(TokenType::GreaterThan);
132        }
133        args
134    }
135
136    fn parse_type(&mut self) -> Option<Type> {
137        let tk = self.get_token()?.clone();
138
139        match tk.ttype {
140            TokenType::LBracket => {
141                self.advance();
142                let element_type = self.parse_type()?;
143                self.expect(TokenType::SemiColon)?;
144
145                let size_tk = self.expect(TokenType::IntLiteral)?;
146                let size = size_tk.value.parse::<usize>().unwrap();
147                self.expect(TokenType::RBracket)?;
148
149                Some(Type::Array {
150                    element_type: Box::new(element_type),
151                    size,
152                })
153            }
154
155            TokenType::Identifier => match tk.value.as_str() {
156                "int" => {
157                    self.advance();
158                    Some(Type::Int)
159                }
160                "uint" => {
161                    self.advance();
162                    Some(Type::UInt)
163                }
164                "i8" => {
165                    self.advance();
166                    Some(Type::Int8)
167                }
168                "u8" => {
169                    self.advance();
170                    Some(Type::UInt8)
171                }
172                "bool" => {
173                    self.advance();
174                    Some(Type::Bool)
175                }
176                "str" => {
177                    self.advance();
178                    Some(Type::Str)
179                }
180                "void" => {
181                    self.advance();
182                    Some(Type::Void)
183                }
184                "ptr" => {
185                    self.advance();
186                    self.expect(TokenType::LessThan)?;
187                    let inner = self.parse_type()?;
188                    self.expect(TokenType::GreaterThan)?;
189                    Some(Type::Ptr(Box::new(inner)))
190                }
191                "any" => {
192                    self.advance();
193                    Some(Type::Any)
194                }
195                "char" => {
196                    self.advance();
197                    Some(Type::Char)
198                }
199                other => {
200                    let name = other.to_string();
201                    self.advance();
202
203                    if self.generic_params.contains(&name) {
204                        Some(Type::GenericParam(name))
205                    } else if matches!(
206                        self.get_token().map(|t| &t.ttype),
207                        Some(TokenType::LessThan)
208                    ) {
209                        let args = self.parse_generic_args();
210                        Some(Type::GenericInstance { name, args })
211                    } else {
212                        Some(Type::Struct(name))
213                    }
214                }
215            },
216            _ => {
217                self.throw(
218                    ParserErrorType::UnexpectedTokenTypeError,
219                    format!("Expected type metadata, found {:?}", tk.ttype),
220                    tk.location,
221                );
222                None
223            }
224        }
225    }
226
227    fn parse_block(&mut self) -> Vec<Stmt> {
228        let mut statements = Vec::new();
229
230        while !self.eof() && !matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::RBrace))
231        {
232            if let Some(stmt) = self.parse_statement(true) {
233                statements.push(stmt);
234            } else {
235                self.advance();
236            }
237        }
238
239        self.expect(TokenType::RBrace);
240        statements
241    }
242
243    fn parse_statement(&mut self, semi_colon: bool) -> Option<Stmt> {
244        let tk = self.get_token()?.clone();
245
246        let stmt = match tk.ttype {
247            TokenType::VarKeyword => self.parse_assignment(),
248            TokenType::StructKeyword => self.parse_struct(),
249            TokenType::IfKeyword => self.parse_if(),
250            TokenType::WhileKeyword => self.parse_while(),
251            TokenType::ConstKeyword => self.parse_const(),
252            TokenType::FnKeyword => self.parse_function(),
253            TokenType::ForKeyword => self.parse_for(),
254            TokenType::ReturnKeyword => self.parse_return(),
255            TokenType::BreakKeyword => self.parse_break(),
256            TokenType::UseKeyword => self.parse_import(),
257            TokenType::ExternKeyword => self.parse_extern(),
258            TokenType::Identifier | TokenType::LParen | TokenType::Star | TokenType::Ampersand => {
259                self.parse_assignment_expression()
260            }
261
262            _ => self.parse_expr().map(Stmt::Expr),
263        };
264
265        if semi_colon && self.expect(TokenType::SemiColon).is_none() {
266            self.throw(
267                ParserErrorType::MalformedStatementError,
268                "Statement did not finish with semicolon ';'".to_string(),
269                tk.location,
270            );
271        }
272        stmt
273    }
274
275    fn parse_assignment_expression(&mut self) -> Option<Stmt> {
276        let lhs = self.parse_expr()?;
277
278        if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Assign)) {
279            self.advance();
280            let rhs = self.parse_expr()?;
281
282            if self.is_valid_lvalue(&lhs) {
283                return Some(Stmt::DerefReassignment {
284                    target: lhs,
285                    expr: rhs,
286                });
287            }
288        }
289
290        Some(Stmt::Expr(lhs))
291    }
292
293    fn is_valid_lvalue(&self, expr: &Expr) -> bool {
294        match &expr.kind {
295            ExprKind::Identifier(_) => true,
296            ExprKind::Field { base, .. } => self.is_valid_lvalue(base),
297            ExprKind::Index { base, .. } => self.is_valid_lvalue(base),
298            ExprKind::Unary {
299                op: UnaryOp::Deref,
300                expr: inner,
301            } => self.is_valid_lvalue(inner),
302            _ => false,
303        }
304    }
305
306    fn parse_import(&mut self) -> Option<Stmt> {
307        let use_tok = self.get_token().cloned()?;
308        self.advance();
309        let mut path = Vec::new();
310
311        loop {
312            let ident = match self.get_token().map(|t| &t.ttype) {
313                Some(TokenType::Identifier) => {
314                    let token = self.get_token().cloned()?;
315                    self.advance();
316                    token.value
317                }
318                other => {
319                    self.throw(
320                        ParserErrorType::UnexpectedTokenTypeError,
321                        format!("Expected identifier in use path, found {:?}", other),
322                        use_tok.location.clone(),
323                    );
324                    return None;
325                }
326            };
327            path.push(ident);
328
329            match self.get_token().map(|t| &t.ttype) {
330                Some(TokenType::DoubleColon) => {
331                    self.advance();
332                }
333                Some(TokenType::SemiColon) => {
334                    break;
335                }
336                other => {
337                    self.throw(
338                        ParserErrorType::UnexpectedTokenTypeError,
339                        format!("Expected '::' or ';', found {:?}", other),
340                        use_tok.location.clone(),
341                    );
342                    return None;
343                }
344            }
345        }
346
347        Some(Stmt::Use { path })
348    }
349
350    fn parse_extern(&mut self) -> Option<Stmt> {
351        self.advance(); // consume 'extern'
352        self.expect(TokenType::FnKeyword)?;
353
354        let ident = self.expect(TokenType::Identifier)?;
355
356        let generic_params = self.parse_generic_params();
357
358        for param in &generic_params {
359            self.generic_params.push(param.clone());
360        }
361
362        self.expect(TokenType::LParen)?;
363        let params = self.parse_params(TokenType::RParen);
364
365        let rttype = if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Colon)) {
366            self.advance();
367            self.parse_type()
368        } else {
369            None
370        };
371
372        for _ in &generic_params {
373            self.generic_params.pop();
374        }
375
376        Some(Stmt::Extern {
377            name: to_ident(Some(ident))?,
378            rttype,
379            generic_params,
380            params,
381        })
382    }
383
384    fn parse_params(&mut self, ending: TokenType) -> Vec<Parameter> {
385        let mut params = Vec::new();
386
387        if self.get_token().map(|t| &t.ttype) == Some(&ending) {
388            self.advance();
389            return params;
390        }
391
392        loop {
393            let name = match self
394                .get_token()
395                .cloned()
396                .and_then(|token| to_ident(Some(token)))
397            {
398                Some(ident) => {
399                    self.advance();
400                    ident
401                }
402                other => {
403                    self.throw(
404                        ParserErrorType::UnexpectedTokenTypeError,
405                        format!("Expected parameter name, found {:?}", other),
406                        self.get_token().unwrap().location.clone(),
407                    );
408                    break;
409                }
410            };
411
412            let ptype = if self.get_token().map(|t| &t.ttype) == Some(&TokenType::Colon) {
413                self.advance();
414                self.parse_type()
415            } else {
416                None
417            };
418
419            params.push(Parameter { name, ptype });
420
421            match self.get_token().map(|t| &t.ttype) {
422                Some(TokenType::Comma) => {
423                    self.advance();
424                }
425                Some(ttype) if ttype == &ending => {
426                    self.advance();
427                    break;
428                }
429                other => {
430                    self.throw(
431                        ParserErrorType::UnexpectedTokenTypeError,
432                        format!("Expected ',' or {:?}, found {:?}", ending, other),
433                        self.get_token().unwrap().location.clone(),
434                    );
435                    break;
436                }
437            }
438        }
439
440        params
441    }
442
443    fn parse_args(&mut self) -> Vec<Expr> {
444        let mut args = Vec::new();
445
446        if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::RParen)) {
447            self.advance();
448            return args;
449        }
450
451        while let Some(expr) = self.parse_expr() {
452            args.push(expr);
453
454            match self.get_token().map(|t| &t.ttype) {
455                Some(TokenType::Comma) => {
456                    self.advance();
457                }
458                Some(TokenType::RParen) => {
459                    self.advance();
460                    break;
461                }
462                other => {
463                    self.throw(
464                        ParserErrorType::UnexpectedTokenTypeError,
465                        format!("Expected ',' or ')', found {:?}", other),
466                        self.get_token().unwrap().location.clone(),
467                    );
468                    break;
469                }
470            }
471        }
472
473        args
474    }
475
476    fn parse_function(&mut self) -> Option<Stmt> {
477        self.advance();
478
479        let public = match self.get_token()?.ttype {
480            TokenType::PubKeyword => {
481                self.advance();
482                true
483            }
484            _ => false,
485        };
486
487        let ident = self.expect(TokenType::Identifier)?;
488
489        let generic_params = self.parse_generic_params();
490
491        for param in &generic_params {
492            self.generic_params.push(param.clone());
493        }
494
495        self.expect(TokenType::LParen)?;
496        let params = self.parse_params(TokenType::RParen);
497
498        let mut rttype = None;
499        if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Colon)) {
500            self.advance();
501            rttype = self.parse_type();
502        }
503
504        self.expect(TokenType::LBrace)?;
505        let body = self.parse_block();
506
507        for _ in &generic_params {
508            self.generic_params.pop();
509        }
510
511        Some(Stmt::Function {
512            name: Identifier {
513                value: ident.value,
514                location: ident.location,
515            },
516            public,
517            rttype,
518            generic_params,
519            params,
520            body,
521        })
522    }
523
524    fn parse_break(&mut self) -> Option<Stmt> {
525        let tk = self.get_token()?.clone();
526        self.advance();
527
528        Some(Stmt::Break {
529            location: tk.location,
530        })
531    }
532
533    fn parse_return(&mut self) -> Option<Stmt> {
534        let tk = self.get_token()?.clone();
535        self.advance();
536
537        let expr = match self.get_token().map(|t| &t.ttype) {
538            Some(TokenType::SemiColon | TokenType::RBrace) => None,
539            _ => Some(self.parse_expr()?),
540        };
541
542        Some(Stmt::Return {
543            value: expr,
544            span: tk.location,
545        })
546    }
547
548    fn parse_const(&mut self) -> Option<Stmt> {
549        self.advance();
550
551        let ident = self.expect(TokenType::Identifier)?;
552        let ident_loc = ident.location.clone();
553
554        let mut vtype = None;
555        if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Colon)) {
556            self.advance();
557            vtype = self.parse_type();
558        }
559
560        self.expect(TokenType::Assign)?;
561
562        let expr = self.parse_expr()?;
563
564        Some(Stmt::Constant {
565            name: Identifier {
566                value: ident.value,
567                location: ident_loc,
568            },
569            vtype,
570            expr,
571        })
572    }
573
574    fn parse_assignment(&mut self) -> Option<Stmt> {
575        self.advance();
576
577        let ident = self.expect(TokenType::Identifier)?;
578        let ident_loc = ident.location.clone();
579
580        let mut vtype = None;
581
582        if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Colon)) {
583            self.advance();
584            vtype = self.parse_type();
585        }
586
587        let value = if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Assign)) {
588            self.advance();
589            Some(self.parse_expr()?)
590        } else {
591            None
592        };
593
594        Some(Stmt::Assignment {
595            ident: Identifier {
596                value: ident.value,
597                location: ident_loc,
598            },
599            vtype,
600            expr: value,
601        })
602    }
603
604    fn parse_for(&mut self) -> Option<Stmt> {
605        self.advance();
606
607        self.expect(TokenType::LParen)?;
608        let init = self.parse_statement(false)?;
609        self.expect(TokenType::SemiColon)?;
610        let cond = self.parse_expr()?;
611        self.expect(TokenType::SemiColon)?;
612        let step = self.parse_statement(false)?;
613        self.expect(TokenType::RParen)?;
614
615        self.expect(TokenType::LBrace)?;
616        let body = self.parse_block();
617
618        Some(Stmt::For {
619            init: Box::new(init),
620            cond,
621            step: Box::new(step),
622            body,
623        })
624    }
625
626    fn parse_while(&mut self) -> Option<Stmt> {
627        self.advance();
628
629        self.expect(TokenType::LParen)?;
630        let cond = self.parse_expr()?;
631        self.expect(TokenType::RParen)?;
632
633        self.expect(TokenType::LBrace)?;
634        let body = self.parse_block();
635
636        Some(Stmt::While { cond, body })
637    }
638
639    fn parse_struct(&mut self) -> Option<Stmt> {
640        self.advance();
641
642        let ident = self.expect(TokenType::Identifier)?;
643
644        let generic_params = self.parse_generic_params();
645
646        for param in &generic_params {
647            self.generic_params.push(param.clone());
648        }
649
650        self.expect(TokenType::LBrace)?;
651        let mut fields = Vec::new();
652
653        while !self.eof() && !matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::RBrace))
654        {
655            let name = to_ident(self.get_token().cloned())?;
656            self.advance();
657            self.expect(TokenType::Colon)?;
658
659            let ptype = self.parse_type();
660            fields.push(Parameter { name, ptype });
661
662            if matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::Comma)) {
663                self.advance();
664            } else if !matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::RBrace)) {
665                self.throw(
666                    ParserErrorType::UnexpectedTokenTypeError,
667                    "Expected ',' or '}' after struct field".to_string(),
668                    self.get_token().unwrap().location.clone(),
669                );
670                return None;
671            }
672        }
673
674        self.expect(TokenType::RBrace)?;
675
676        for _ in &generic_params {
677            self.generic_params.pop();
678        }
679
680        Some(Stmt::Struct {
681            name: to_ident(Some(ident))?,
682            generic_params,
683            fields,
684        })
685    }
686
687    fn parse_if(&mut self) -> Option<Stmt> {
688        self.advance();
689
690        self.expect(TokenType::LParen)?;
691        let cond = self.parse_expr()?;
692        self.expect(TokenType::RParen)?;
693
694        self.expect(TokenType::LBrace)?;
695        let body = self.parse_block();
696
697        let mut elseif_branches = Vec::new();
698
699        while matches!(
700            self.get_token().map(|t| &t.ttype),
701            Some(TokenType::ElseIfKeyword)
702        ) {
703            self.advance();
704
705            self.expect(TokenType::LParen)?;
706            let elseif_cond = self.parse_expr()?;
707            self.expect(TokenType::RParen)?;
708
709            self.expect(TokenType::LBrace)?;
710            let elseif_body = self.parse_block();
711
712            elseif_branches.push((elseif_cond, elseif_body));
713        }
714
715        let else_branch = if matches!(
716            self.get_token().map(|t| &t.ttype),
717            Some(TokenType::ElseKeyword)
718        ) {
719            self.advance();
720            self.expect(TokenType::LBrace);
721            Some(self.parse_block())
722        } else {
723            None
724        };
725
726        Some(Stmt::If {
727            cond,
728            then_branch: body,
729            else_if_branches: elseif_branches,
730            else_branch,
731        })
732    }
733
734    fn parse_array_literal(&mut self) -> Option<Expr> {
735        let open_bracket = self.get_token()?.clone();
736        self.advance();
737
738        let mut elements = Vec::new();
739
740        if matches!(
741            self.get_token().map(|t| &t.ttype),
742            Some(TokenType::RBracket)
743        ) {
744            self.advance();
745            return Some(Expr {
746                kind: ExprKind::Literal(Literal::Arr { elements }),
747                span: open_bracket.location,
748            });
749        }
750
751        loop {
752            let expr = self.parse_expr()?;
753            elements.push(expr);
754
755            match self.get_token().map(|t| &t.ttype) {
756                Some(TokenType::Comma) => {
757                    self.advance();
758                }
759                Some(TokenType::RBracket) => {
760                    self.advance();
761                    break;
762                }
763                other => {
764                    self.throw(
765                        ParserErrorType::UnexpectedTokenTypeError,
766                        format!("Expected ',' or ']', found {:?}", other),
767                        self.get_token().unwrap().location.clone(),
768                    );
769                    return None;
770                }
771            }
772        }
773
774        Some(Expr {
775            kind: ExprKind::Literal(Literal::Arr { elements }),
776            span: open_bracket.location,
777        })
778    }
779
780    fn parse_expr(&mut self) -> Option<Expr> {
781        if let Some(TokenType::RParen | TokenType::RBrace | TokenType::SemiColon) = self.get_token().map(|t| &t.ttype) {
782            return None;
783        }
784        self.parse_andor()
785    }
786
787    fn parse_andor(&mut self) -> Option<Expr> {
788        let mut left = self.parse_equality()?;
789
790        while matches!(
791            self.get_token().map(|t| t.ttype.clone()),
792            Some(TokenType::And | TokenType::Or)
793        ) {
794            let op_token = self.get_token()?.clone();
795            self.advance();
796
797            let op = match op_token.ttype {
798                TokenType::And => BinaryOp::And,
799                TokenType::Or => BinaryOp::Or,
800                _ => unreachable!(),
801            };
802
803            let right = self.parse_equality()?;
804            left = Expr {
805                kind: ExprKind::Binary {
806                    left: Box::new(left),
807                    op,
808                    right: Box::new(right),
809                },
810                span: op_token.location,
811            };
812        }
813
814        Some(left)
815    }
816
817    fn parse_equality(&mut self) -> Option<Expr> {
818        let mut left = self.parse_comparison()?;
819
820        while matches!(
821            self.get_token().map(|t| t.ttype.clone()),
822            Some(TokenType::Equals | TokenType::NotEquals)
823        ) {
824            let op_token = self.get_token()?.clone();
825            self.advance();
826
827            let op = match op_token.ttype {
828                TokenType::Equals => BinaryOp::Eq,
829                TokenType::NotEquals => BinaryOp::NEq,
830
831                _ => unreachable!(),
832            };
833
834            let right = self.parse_comparison()?;
835
836            left = Expr {
837                kind: ExprKind::Binary {
838                    left: Box::new(left),
839                    op,
840                    right: Box::new(right),
841                },
842                span: op_token.location,
843            };
844        }
845
846        Some(left)
847    }
848
849    fn parse_comparison(&mut self) -> Option<Expr> {
850        let mut left = self.parse_addsub()?;
851
852        while matches!(
853            self.get_token().map(|t| t.ttype.clone()),
854            Some(
855                TokenType::LessThan
856                    | TokenType::LessThanEquals
857                    | TokenType::GreaterThan
858                    | TokenType::GreaterThanEquals
859            )
860        ) {
861            let op_token = self.get_token()?.clone();
862            self.advance();
863
864            let op = match op_token.ttype {
865                TokenType::LessThan => BinaryOp::Lt,
866                TokenType::LessThanEquals => BinaryOp::LtE,
867                TokenType::GreaterThan => BinaryOp::Gt,
868                TokenType::GreaterThanEquals => BinaryOp::GtE,
869                _ => unreachable!(),
870            };
871
872            let right = self.parse_addsub()?;
873
874            left = Expr {
875                kind: ExprKind::Binary {
876                    left: Box::new(left),
877                    op,
878                    right: Box::new(right),
879                },
880                span: op_token.location,
881            };
882        }
883
884        Some(left)
885    }
886
887    fn parse_addsub(&mut self) -> Option<Expr> {
888        let mut left = self.parse_muldiv()?;
889
890        while matches!(
891            self.get_token().map(|t| t.ttype.clone()),
892            Some(TokenType::Add | TokenType::Minus)
893        ) {
894            let op_token = self.get_token()?.clone();
895
896            let op = match op_token.ttype {
897                TokenType::Add => BinaryOp::Add,
898                TokenType::Minus => BinaryOp::Sub,
899                _ => unreachable!(),
900            };
901
902            self.advance();
903            let right = self.parse_muldiv()?;
904            let span = left.span.clone();
905
906            left = Expr {
907                kind: ExprKind::Binary {
908                    left: Box::new(left),
909                    op,
910                    right: Box::new(right),
911                },
912                span,
913            };
914        }
915
916        Some(left)
917    }
918
919    fn parse_muldiv(&mut self) -> Option<Expr> {
920        let mut left = self.parse_cast()?;
921
922        while matches!(
923            self.get_token().map(|t| t.ttype.clone()),
924            Some(TokenType::Multiply | TokenType::Divide | TokenType::Modulo)
925        ) {
926            let op_token = self.get_token()?.clone();
927
928            let op = match op_token.ttype {
929                TokenType::Multiply => BinaryOp::Mul,
930                TokenType::Divide => BinaryOp::Div,
931                TokenType::Modulo => BinaryOp::Mod,
932                _ => unreachable!(),
933            };
934
935            self.advance();
936            let right = self.parse_cast()?;
937            let span = left.span.clone();
938
939            left = Expr {
940                kind: ExprKind::Binary {
941                    left: Box::new(left),
942                    op,
943                    right: Box::new(right),
944                },
945                span,
946            };
947        }
948
949        Some(left)
950    }
951
952    fn parse_cast(&mut self) -> Option<Expr> {
953        let mut left = self.parse_unary()?;
954
955        while matches!(
956            self.get_token().map(|t| t.ttype.clone()),
957            Some(TokenType::AsKeyword)
958        ) {
959            self.advance();
960            let right = self.parse_type()?;
961            let span = left.span.clone();
962
963            left = Expr {
964                kind: ExprKind::Cast {
965                    left: Box::new(left),
966                    right,
967                },
968                span,
969            }
970        }
971
972        Some(left)
973    }
974
975    fn parse_unary(&mut self) -> Option<Expr> {
976        let tk = self.get_token()?.clone();
977
978        match tk.ttype {
979            TokenType::Add => {
980                self.advance();
981                let expr = self.parse_unary()?;
982                Some(Expr {
983                    kind: ExprKind::Unary {
984                        op: UnaryOp::Positive,
985                        expr: Box::new(expr),
986                    },
987                    span: tk.location,
988                })
989            }
990            TokenType::Minus => {
991                self.advance();
992                let expr = self.parse_unary()?;
993                Some(Expr {
994                    kind: ExprKind::Unary {
995                        op: UnaryOp::Negative,
996                        expr: Box::new(expr),
997                    },
998                    span: tk.location,
999                })
1000            }
1001            TokenType::Ampersand => {
1002                self.advance();
1003                let expr = self.parse_unary()?;
1004                Some(Expr {
1005                    kind: ExprKind::Unary {
1006                        op: UnaryOp::AddressOf,
1007                        expr: Box::new(expr),
1008                    },
1009                    span: tk.location,
1010                })
1011            }
1012            TokenType::Star => {
1013                self.advance();
1014                let expr = self.parse_unary()?;
1015                Some(Expr {
1016                    kind: ExprKind::Unary {
1017                        op: UnaryOp::Deref,
1018                        expr: Box::new(expr),
1019                    },
1020                    span: tk.location,
1021                })
1022            }
1023            TokenType::Not => {
1024                self.advance();
1025                let expr = self.parse_unary()?;
1026                Some(Expr {
1027                    kind: ExprKind::Unary {
1028                        op: UnaryOp::Not,
1029                        expr: Box::new(expr),
1030                    },
1031                    span: tk.location,
1032                })
1033            }
1034            _ => self.parse_postfix(),
1035        }
1036    }
1037
1038    fn parse_postfix(&mut self) -> Option<Expr> {
1039        let mut expr = self.parse_primary()?;
1040
1041        loop {
1042            match self.get_token().map(|t| &t.ttype) {
1043                Some(TokenType::LBracket) => {
1044                    self.advance();
1045                    let index_expr = self.parse_expr()?;
1046                    let close_tk = self.expect(TokenType::RBracket)?;
1047                    expr = Expr {
1048                        kind: ExprKind::Index {
1049                            base: Box::new(expr),
1050                            index: Box::new(index_expr),
1051                        },
1052                        span: close_tk.location,
1053                    };
1054                }
1055                Some(TokenType::Period) => {
1056                    self.advance();
1057                    let field_tk = self.expect(TokenType::Identifier)?;
1058                    let loc = field_tk.location.clone();
1059                    expr = Expr {
1060                        kind: ExprKind::Field {
1061                            base: Box::new(expr),
1062                            field: field_tk.value,
1063                        },
1064                        span: loc,
1065                    };
1066                }
1067                Some(TokenType::LParen) => {
1068                    if let ExprKind::Identifier(name) = &expr.kind {
1069                        let callee_loc = expr.span.clone();
1070                        self.advance();
1071                        let args = self.parse_args();
1072                        expr = Expr {
1073                            kind: ExprKind::Call {
1074                                callee: Identifier {
1075                                    value: name.clone(),
1076                                    location: callee_loc.clone(),
1077                                },
1078                                generic_args: Vec::new(),
1079                                args,
1080                            },
1081                            span: callee_loc,
1082                        };
1083                    } else {
1084                        self.throw(
1085                            ParserErrorType::UnexpectedTokenTypeError,
1086                            "Expected function name before parenthesis".to_string(),
1087                            self.get_token().unwrap().location.clone(),
1088                        );
1089                        return None;
1090                    }
1091                }
1092                Some(TokenType::LBrace) => {
1093                    if let ExprKind::Identifier(name) = &expr.kind {
1094                        self.advance();
1095                        let mut fields = Vec::new();
1096                        if !matches!(self.get_token().map(|t| &t.ttype), Some(TokenType::RBrace)) {
1097                            loop {
1098                                let field_name = self.expect(TokenType::Identifier)?.value;
1099                                self.expect(TokenType::Colon)?;
1100                                let value_expr = self.parse_expr()?;
1101                                fields.push((field_name, value_expr));
1102                                match self.get_token().map(|t| &t.ttype) {
1103                                    Some(TokenType::Comma) => self.advance(),
1104                                    Some(TokenType::RBrace) => break,
1105                                    _ => {
1106                                        self.throw(
1107                                            ParserErrorType::UnexpectedTokenTypeError,
1108                                            "Expected ',' or '}' in struct initializer".to_string(),
1109                                            self.get_token().unwrap().location.clone(),
1110                                        );
1111                                        return None;
1112                                    }
1113                                }
1114                            }
1115                        }
1116                        self.expect(TokenType::RBrace)?;
1117                        expr = Expr {
1118                            kind: ExprKind::StructLiteral {
1119                                struct_name: name.clone(),
1120                                generic_args: Vec::new(),
1121                                fields,
1122                            },
1123                            span: expr.span.clone(),
1124                        };
1125                    } else {
1126                        self.throw(
1127                            ParserErrorType::UnexpectedTokenTypeError,
1128                            "Expected struct name before '{'".to_string(),
1129                            self.get_token().unwrap().location.clone(),
1130                        );
1131                        return None;
1132                    }
1133                }
1134                Some(TokenType::DoubleColon) => {
1135                    self.advance(); // consume '::'
1136                    let generic_args = self.parse_generic_args();
1137
1138                    // Determine what follows: '(' or '{'
1139                    match self.get_token().map(|t| &t.ttype) {
1140                        Some(TokenType::LParen) => {
1141                            // Generic function call
1142                            self.advance(); // consume '('
1143                            let args = self.parse_args();
1144                            if let ExprKind::Identifier(name) = &expr.kind {
1145                                let callee_loc = expr.span.clone();
1146                                expr = Expr {
1147                                    kind: ExprKind::Call {
1148                                        callee: Identifier {
1149                                            value: name.clone(),
1150                                            location: callee_loc.clone(),
1151                                        },
1152                                        generic_args,
1153                                        args,
1154                                    },
1155                                    span: callee_loc,
1156                                };
1157                            } else {
1158                                self.throw(
1159                                    ParserErrorType::UnexpectedTokenTypeError,
1160                                    "Cannot apply generic arguments to non-identifier expression"
1161                                        .to_string(),
1162                                    expr.span.clone(),
1163                                );
1164                                return None;
1165                            }
1166                        }
1167                        Some(TokenType::LBrace) => {
1168                            // Generic struct literal
1169                            self.advance(); // consume '{'
1170                            let mut fields = Vec::new();
1171                            if !matches!(
1172                                self.get_token().map(|t| &t.ttype),
1173                                Some(TokenType::RBrace)
1174                            ) {
1175                                loop {
1176                                    let field_name = self.expect(TokenType::Identifier)?.value;
1177                                    self.expect(TokenType::Colon)?;
1178                                    let value_expr = self.parse_expr()?;
1179                                    fields.push((field_name, value_expr));
1180                                    match self.get_token().map(|t| &t.ttype) {
1181                                        Some(TokenType::Comma) => self.advance(),
1182                                        Some(TokenType::RBrace) => break,
1183                                        _ => {
1184                                            self.throw(
1185                                                ParserErrorType::UnexpectedTokenTypeError,
1186                                                "Expected ',' or '}' in struct initializer"
1187                                                    .to_string(),
1188                                                self.get_token().unwrap().location.clone(),
1189                                            );
1190                                            return None;
1191                                        }
1192                                    }
1193                                }
1194                            }
1195                            self.expect(TokenType::RBrace)?;
1196                            if let ExprKind::Identifier(name) = &expr.kind {
1197                                expr = Expr {
1198                                    kind: ExprKind::StructLiteral {
1199                                        struct_name: name.clone(),
1200                                        generic_args,
1201                                        fields,
1202                                    },
1203                                    span: expr.span.clone(),
1204                                };
1205                            } else {
1206                                self.throw(
1207                    ParserErrorType::UnexpectedTokenTypeError,
1208                    "Cannot apply generic arguments to non-identifier for struct literal".to_string(),
1209                    expr.span.clone(),
1210                );
1211                                return None;
1212                            }
1213                        }
1214                        _ => {
1215                            self.throw(
1216                                ParserErrorType::UnexpectedTokenTypeError,
1217                                format!(
1218                                    "Expected '(' or '{{' after generic arguments, found {:?}",
1219                                    self.get_token()
1220                                ),
1221                                self.get_token().unwrap().location.clone(),
1222                            );
1223                            return None;
1224                        }
1225                    }
1226                }
1227
1228                _ => break,
1229            }
1230        }
1231        Some(expr)
1232    }
1233
1234    fn parse_primary(&mut self) -> Option<Expr> {
1235        let tk = self.get_token()?.clone();
1236
1237        match tk.ttype {
1238            TokenType::IntLiteral => {
1239                self.advance();
1240                let value = tk.value.parse::<i64>().unwrap();
1241                Some(Expr {
1242                    kind: ExprKind::Literal(Literal::Int(value)),
1243                    span: tk.location,
1244                })
1245            }
1246
1247            TokenType::True => {
1248                self.advance();
1249                let value = true;
1250                Some(Expr {
1251                    kind: ExprKind::Literal(Literal::Bool(value)),
1252                    span: tk.location,
1253                })
1254            }
1255            TokenType::False => {
1256                self.advance();
1257                let value = false;
1258                Some(Expr {
1259                    kind: ExprKind::Literal(Literal::Bool(value)),
1260                    span: tk.location,
1261                })
1262            }
1263
1264            TokenType::StringLiteral => {
1265                self.advance();
1266                Some(Expr {
1267                    kind: ExprKind::Literal(Literal::String(tk.value)),
1268                    span: tk.location,
1269                })
1270            }
1271            TokenType::CharLiteral => {
1272                self.advance();
1273                let value = tk.value.chars().next().unwrap();
1274                Some(Expr {
1275                    kind: ExprKind::Literal(Literal::Char(value)),
1276                    span: tk.location,
1277                })
1278            }
1279            TokenType::SizeOfKeyword => {
1280                let start_tk = self.get_token().cloned()?;
1281                self.advance(); // consume 'sizeof'
1282
1283                self.expect(TokenType::LParen)?;
1284                let target_type = self.parse_type()?;
1285                self.expect(TokenType::RParen)?;
1286
1287                Some(Expr {
1288                    kind: ExprKind::Sizeof { ty: target_type },
1289                    span: start_tk.location,
1290                })
1291            }
1292            TokenType::Identifier => {
1293                let id_tk = self.get_token()?.clone();
1294                self.advance();
1295                Some(Expr {
1296                    kind: ExprKind::Identifier(id_tk.value),
1297                    span: id_tk.location,
1298                })
1299            }
1300            TokenType::LBracket => self.parse_array_literal(),
1301
1302            TokenType::LParen => {
1303                self.advance();
1304                let expr = self.parse_expr()?;
1305                self.expect(TokenType::RParen)?;
1306                Some(expr)
1307            }
1308
1309            _ => {
1310                self.throw(
1311                    ParserErrorType::UnexpectedTokenTypeError,
1312                    format!("Unexpected token in expression: {:?}", tk.ttype),
1313                    self.get_token().unwrap().location.clone(),
1314                );
1315                None
1316            }
1317        }
1318    }
1319}