1use crate::lexer::token::LiteralValue;
2use crate::lexer::token::TokenType::{Eof, LeftParen, RightParen};
3use crate::lexer::token::{Token, TokenType};
4use crate::parser::ast::Break as BreakStatement;
5use crate::parser::ast::Continue as ContinueStatement;
6use crate::parser::ast::Import as ImportStatement;
7use crate::parser::ast::Return as ReturnValue;
8use crate::parser::ast::*;
9use miette::{miette, LabeledSpan, NamedSource, Report, SourceSpan};
10use std::sync::Arc;
11
12use crate::lexer::token::TokenType::*;
13use crate::parser::ast::If as IfStmt;
14
15pub struct Parser {
16 tokens: Vec<Token>,
17 source: Arc<str>,
18 named_source: NamedSource<Arc<str>>,
19 current: usize,
20 in_function_scope: bool,
21 _warnings: Vec<Report>,
22 in_loop_scope: bool,
23}
24
25impl Parser {
26 pub(crate) fn new(tokens: Vec<Token>, source: Arc<str>, file_name: &str) -> Self {
27 Self {
28 tokens,
29 source: source.clone(),
30 in_function_scope: false,
31 in_loop_scope: false,
32 named_source: NamedSource::new(file_name, source),
33 current: 0,
34 _warnings: vec![],
35 }
36 }
37
38 pub(crate) fn parse(&mut self) -> Result<Ast, Vec<Report>> {
39 let mut statements = vec![];
40 let mut reports = vec![];
41
42 while !self.is_at_end() {
43 if self.match_token(&SoftSemi) {
44 continue;
45 }
46
47 match self.declaration() {
48 Ok(stmt) => statements.push(stmt),
49 Err(report) => {
50 let report = report;
51 reports.push(report);
52 self.synchronize();
53 }
54 }
55 }
56
57 if !reports.is_empty() {
58 return Err(reports);
59 }
60
61 Ok(Ast {
62 source: self.source.clone(),
63 program: statements,
64 })
65 }
66}
67
68impl Parser {
70 fn declaration(&mut self) -> miette::Result<Stmt> {
71 if self.match_tokens(&[Export, Procedure]) {
74 return self.procedure();
75 }
76 self.statement()
77 }
78
79 fn procedure(&mut self) -> miette::Result<Stmt> {
80 let export_or_procedure = self.previous().clone();
81
82 let (proc_token, exported) = if export_or_procedure.token_type == Export {
83 let proc_token = self
84 .consume(&Procedure, |token| {
85 let labels = vec![
86 LabeledSpan::at(token.span(), "expected keyword 'PROCEDURE' here"),
87 LabeledSpan::at(token.span(), "'EXPORT' cannot exist alone"),
88 ];
89
90 miette!(
91 labels = labels,
92 code = "standalone_export",
93 help = "you can only export a procedure from a module",
94 "expected 'PROCEDURE' following 'EXPORT' found {}",
95 token.lexeme,
96 )
97 })?
98 .clone();
99
100 (proc_token, true)
101 } else {
102 (export_or_procedure, false)
103 };
104
105 let name_token = self
106 .consume(&Identifier, |token| {
107 let labels = vec![
108 LabeledSpan::at(proc_token.span(), "this procedure requires a name"),
109 LabeledSpan::at(token.span(), "name goes here"),
110 ];
111
112 miette!(
113 labels = labels,
114 code = "unnamed_procedure",
115 help = "name the PROCEDURE with an IDENT",
116 "expected `IDENT` found `{}`",
117 token.lexeme
118 )
119 })?
120 .clone();
121
122 let name = name_token.lexeme.clone();
125
126 let _lp_token = self
127 .consume(&LeftParen, |token| {
128 let labels = vec![
129 LabeledSpan::at(token.span(), "expected a `(`"),
130 LabeledSpan::at(
131 name_token.span(),
132 format!("{} requires `(..)` argument list", name_token.lexeme),
133 ),
134 ];
135 miette!(
136 labels = labels,
137 code = "missing_lp",
138 help = "a PROCEDURE requires a argument list in `()` after its name",
139 "expected `(` found `{}`",
140 token.lexeme
141 )
142 })?
143 .clone();
144
145 let mut params = vec![];
146 if !self.check(&RightParen) {
147 loop {
148 if params.len() > 255 {
149 let _peeked = self.peek();
150 return Err(miette! {
151 "todo: params cannot exceed 255, why the f**k do you need so many?"
152 });
153 }
154
155 let token = self
157 .consume(&Identifier, |_token| miette!("hello"))?
158 .clone();
159
160 params.push(Variable {
161 ident: token.lexeme.clone(),
162 token,
163 });
164
165 if !self.match_token(&Comma) {
166 break;
167 }
168 }
169 }
170
171 let _rp_token = self
172 .consume(&RightParen, |token| {
173 let labels = vec![LabeledSpan::at(token.span(), "expected a `)`")];
174
175 miette!(
176 labels = labels,
177 code = "missing_rp",
178 help = "mismatched `(`, it seems you missed a `)`.",
179 "expected `)`, found `{}`",
180 token.lexeme
181 )
182 })?
183 .clone();
184
185 let function_scope_state_cache = self.in_function_scope;
187 self.in_function_scope = true;
188
189 let body = self.statement()?;
191 self.in_function_scope = function_scope_state_cache;
193
194 Ok(Stmt::ProcDeclaration(Arc::new(ProcDeclaration {
195 name,
196 params,
197 body,
198 exported,
199 proc_token,
200 name_token,
201 })))
202 }
203
204 fn statement(&mut self) -> miette::Result<Stmt> {
205 if self.match_token(&Import) {
207 let import_token = self.previous().clone();
208 return self.import_statement(import_token);
209 }
210
211 if self.match_token(&If) {
213 let if_token = self.previous().clone();
214 return self.if_statement(if_token);
215 }
216
217 if self.match_token(&Repeat) {
219 let repeat_token = self.previous().clone();
220
221 let cache_loop_state = self.in_loop_scope;
223 self.in_loop_scope = true;
224
225 let result = if self.check(&Until) {
227 self.repeat_until(repeat_token)
228 } else {
229 self.repeat_times(repeat_token)
230 };
231
232 self.in_loop_scope = cache_loop_state;
234
235 return result;
237 }
238
239 if self.match_token(&For) {
240 let for_token = self.previous().clone();
241
242 let cache_loop_state = self.in_loop_scope;
244 self.in_loop_scope = true;
245
246 let result = self.for_each(for_token);
248
249 self.in_loop_scope = cache_loop_state;
251
252 return result
253 }
254
255 if self.match_token(&LeftBrace) {
257 let lb_token = self.previous().clone();
258
259 return self.block(lb_token);
260 }
261
262 if self.match_token(&Continue) {
263 let cont_token = self.previous().clone();
264 return self.continue_statement(cont_token);
265 }
266
267 if self.match_token(&Break) {
268 let brk_token = self.previous().clone();
269 return self.break_statement(brk_token);
270 }
271
272 if self.match_token(&Return) {
273 let return_token = self.previous().clone();
274 return self.return_statement(return_token);
275 }
276
277 self.expression_statement()
278 }
279
280 fn block(&mut self, lb_token: Token) -> miette::Result<Stmt> {
281 let mut statements = vec![];
282
283 while !self.check(&LeftBrace) && !self.is_at_end() {
284 if self.match_token(&SoftSemi) {
286 continue;
287 }
288
289 if self.check(&RightBrace) {
291 break;
292 }
293
294 statements.push(self.declaration()?);
295 }
296
297 let rb_token = self
298 .consume(&RightBrace, |_token| {
299 let labels = vec![LabeledSpan::at(
300 lb_token.span(),
301 "this delimiter requires a closing `}`",
302 )];
303 miette!(
306 labels = labels,
307 code = "missing_rb",
308 help = "mismatched `{`, it seems you missed a `}`",
309 "this block has an unclosed delimiter"
310 )
311 })?
312 .clone();
313
314 Ok(Stmt::Block(
315 Block {
316 lb_token,
317 statements,
318 rb_token,
319 }
320 .into(),
321 ))
322 }
323
324 fn break_statement(&mut self, break_token: Token) -> miette::Result<Stmt> {
325 if !self.in_loop_scope {
326 return Err(miette! {
328 "BREAK can only be called in a loop"
329 });
330 }
331
332 Ok(Stmt::Break(Arc::new(BreakStatement { token: break_token })))
333 }
334
335 fn continue_statement(&mut self, continue_token: Token) -> miette::Result<Stmt> {
336 if !self.in_loop_scope {
337 return Err(miette! {
339 "CONTINUE can only be called in a loop",
340 });
341 }
342
343 Ok(Stmt::Continue(Arc::new(ContinueStatement {
344 token: continue_token,
345 })))
346 }
347
348 fn return_statement(&mut self, return_token: Token) -> miette::Result<Stmt> {
349 if !self.in_function_scope {
350 return Err(miette! {
352 "RETURN can only be called in a PROCEDURE"
353 });
354 }
355
356 let maybe_value = if !self.match_token(&SoftSemi) {
357 Some(self.expression()?)
358 } else {
359 None
360 };
361
362 if maybe_value.is_some() {
363 self.consume(&SoftSemi, |_token| {
364 miette! {
365 "todo: expected semicolon after return statement"
366 }
367 })?;
368 }
369
370 Ok(Stmt::Return(Arc::new(ReturnValue {
371 token: return_token,
372 data: maybe_value,
373 })))
374 }
375
376 fn import_statement(&mut self, import_token: Token) -> miette::Result<Stmt> {
377 let only_functions = if self.match_token(&LeftBracket) {
379 let lbracket = self.previous().clone();
381
382 let mut specific_functions: Vec<Token> = vec![];
383 loop {
384 const MAX_SPECIFIC_FUNCTIONS: usize = 63;
388 if specific_functions.len() >= MAX_SPECIFIC_FUNCTIONS {
389 let correct_span =
390 lbracket.span_until_token(specific_functions.last().unwrap());
391 let labels = vec![LabeledSpan::at(
392 correct_span,
393 "just import the entire module",
394 )];
395 let _s = 2.0;
396
397 return Err(miette!(
398 labels = labels,
399 help = "what the freak dude. are you okay?",
400 "cannot have more than {} specific imports",
401 MAX_SPECIFIC_FUNCTIONS
402 ));
403 }
404
405 let specific_function = self.consume(&StringLiteral, |found| {
406 miette!("expected a specific function instead found {}", found)
407 })?;
408
409 specific_functions.push(specific_function.clone());
410
411 if !self.match_token(&Comma) {
413 break;
414 }
415 }
416
417 println!("debug: specific functions: {:?}", specific_functions);
418
419 let _rbracket = self.consume(&RightBracket, |_found| {
421 miette! {
422 ""
423 }
424 })?;
425
426 Some(specific_functions)
427 } else if self.match_token(&StringLiteral) {
428 let one_specific_function = self.previous().clone();
430 Some(vec![one_specific_function])
431 } else {
432 None
433 };
434
435 let maybe_from_token =
436 if only_functions.is_some() {
437 Some(self.consume(&From, |found| miette! {
438 "(todo) Expected from following specific imports, found {}", found.lexeme
439 })?.clone())
440 } else {
441 None
442 };
443
444 let mod_token = self
445 .consume(&Mod, |_token| {
446 miette! {
447 "todo: expected a mod token following import. could also be a specific function" }
449 })?
450 .clone();
451
452 let module_name = self
453 .consume(&StringLiteral, |_token| {
454 miette! {
455 "todo: expected a string literal specifying the type of import"
456 }
457 })?
458 .clone();
459
460 self.consume(&SoftSemi, |_token| {
461 miette! {
462 "todo: expected a semicolon following import statement"
463 }
464 })?;
465
466 Ok(Stmt::Import(Arc::new(ImportStatement {
467 import_token,
468 mod_token,
469 maybe_from_token,
470
471 only_functions,
472 module_name,
473 })))
474 }
475
476 fn if_statement(&mut self, if_token: Token) -> miette::Result<Stmt> {
477 let _lp_token = self
479 .consume(&LeftParen, |token| {
480 let labels = vec![
482 LabeledSpan::at(token.span(), "expected a `(`"),
483 LabeledSpan::at(if_token.span(), "IF requires `(..)` condition"),
484 ];
485
486 miette!(
487 labels = labels,
488 code = "missing_lp",
489 help = "an IF statement requires a condition in `()` after the `IF` keyword",
490 "expected `(` found `{}`",
491 token.lexeme
492 )
493 })?
494 .clone();
495
496 let condition = self.expression()?;
497
498 let _rp_token = self
499 .consume(&RightParen, |token| {
500 let labels = vec![LabeledSpan::at(token.span(), "expected a `)`")];
502
503 miette!(
504 labels = labels,
505 code = "missing_rp",
506 help = "mismatched `(`, it seems you missed a `)`.",
507 "expected `)`, found `{}`",
508 token.lexeme
509 )
510 })?
511 .clone();
512
513 let then_branch = self.statement()?;
514
515 let (else_branch, else_token) = if self.match_token(&Else) {
516 let else_token = self.previous().clone();
518 let else_branch = self.statement()?;
519
520 (Some(else_branch), Some(else_token))
521 } else {
522 (None, None)
523 };
524
525 Ok(Stmt::If(Arc::new(IfStmt {
526 condition,
527 then_branch,
528 else_branch,
529 if_token,
530 else_token,
531 })))
532 }
533
534 fn repeat_times(&mut self, repeat_token: Token) -> miette::Result<Stmt> {
535 self.confirm(&Repeat)?;
537
538 let count = self.expression()?;
540
541 let count_token = self.previous().clone();
542
543 let times_token = self.consume(&Times, |token| {
544 let labels = vec![
547 LabeledSpan::at(token.span(), "expected a `TIMES`"),
548 ];
549
550 miette!(
551 labels = labels,
552 code = "missing_times",
553 help = "a REPEAT block requires a `TIMES` keyword after the number of times to repeat",
554 "expected `TIMES` found `{}`", token.lexeme
555 )
556 })?.clone();
557
558 let body = self.statement()?;
559
560 Ok(Stmt::RepeatTimes(
561 RepeatTimes {
562 count,
563 body,
564 repeat_token,
565 times_token,
566 count_token,
567 }
568 .into(),
569 ))
570 }
571
572 fn repeat_until(&mut self, repeat_token: Token) -> miette::Result<Stmt> {
573 self.confirm(&Repeat)?;
575
576 let until_token = self
577 .consume(&Until, |_token| {
578 miette!("how tf do i trigger this")
595 })?
596 .clone();
597
598 let _lp_token = self.consume(&LeftParen, |token| {
599 let labels = vec![
601 LabeledSpan::at(token.span(), "expected a `(`"),
602 LabeledSpan::at(until_token.span(), "REPEAT UNTIL requires `(..)` condition")
603 ];
604
605 miette!(
606 labels = labels,
607 code = "missing_lp",
608 help = "a REPEAT UNTIL block requires a condition in `()` after the `UNTIL` keyword",
609 "expected `(` found `{}`", token.lexeme
610 )
611 })?.clone();
612
613 let condition = self.expression()?;
614
615 let _rp_token = self
616 .consume(&RightParen, |token| {
617 let labels = vec![LabeledSpan::at(token.span(), "expected a `)`")];
619
620 miette!(
621 labels = labels,
622 code = "missing_rp",
623 help = "mismatched `(`, it seems you missed a `)`.",
624 "expected `)`, found `{}`",
625 token.lexeme
626 )
627 })?
628 .clone();
629
630 let body = self.statement()?;
631
632 Ok(Stmt::RepeatUntil(
633 RepeatUntil {
634 condition,
635 body,
636 repeat_token,
637 until_token,
638 }
639 .into(),
640 ))
641 }
642
643 fn for_each(&mut self, for_token: Token) -> miette::Result<Stmt> {
644 self.confirm(&For)?;
645
646 let each_token = self
647 .consume(&Each, |token| {
648 let labels = vec![LabeledSpan::at(token.span(), "expected an `EACH`")];
651
652 miette!(
653 labels = labels,
654 code = "missing_each",
655 help = "a FOR block requires an `EACH` keyword after the `FOR` keyword",
656 "expected `EACH` found `{}`",
657 token.lexeme
658 )
659 })?
660 .clone();
661
662 let item_token = self
663 .consume(&Identifier, |token| {
664 let labels = vec![
667 LabeledSpan::at(each_token.span(), "expected an identifier after `EACH`"),
668 LabeledSpan::at(token.span(), "identifier goes here"),
669 ];
670
671 miette!(
672 labels = labels,
673 code = "missing_ident",
674 help = "a FOR EACH block requires an identifier after the `EACH` keyword",
675 "expected `IDENTIFIER` found `{}`",
676 token.lexeme
677 )
678 })?
679 .clone();
680 let item = Variable {
682 ident: item_token.lexeme.to_string(),
683 token: item_token.clone(),
684 };
685
686 let in_token = self
688 .consume(&In, |token| {
689 let labels = vec![
691 LabeledSpan::at(item_token.span(), "expected an `IN` after identifier"),
692 LabeledSpan::at(token.span(), "`IN` goes here"),
693 ];
694
695 miette!(
696 labels = labels,
697 code = "missing_in",
698 help = "a FOR EACH block requires an `IN` keyword after the identifier",
699 "expected `IN` found `{}`",
700 token.lexeme
701 )
702 })?
703 .clone();
704
705 let list = self.expression()?;
706
707 let list_token = self.previous().clone();
708
709 let body = self.statement()?;
710
711 Ok(Stmt::ForEach(
712 ForEach {
713 item,
714 list,
715 body,
716 item_token,
717 for_token,
718 each_token,
719 in_token,
720 list_token,
721 }
722 .into(),
723 ))
724 }
725
726 fn expression_statement(&mut self) -> miette::Result<Stmt> {
727 let expr = self.expression()?;
728 if self.is_at_end() {
729 return Ok(Stmt::Expr(Arc::new(expr)));
730 }
731
732 if self.check(&RightBrace) {
733 return Ok(Stmt::Expr(Arc::new(expr)));
734 }
735
736 self.consume(&SoftSemi, |token| {
737 let labels = vec![LabeledSpan::at(
739 token.span(),
740 "missing End Of Line indicator",
741 )];
742 miette!(
743 labels = labels,
744 code = "missing_eol",
745 help = "try manually placing a semicolon",
746 "expected `End Of Line` found `{}`",
747 token.lexeme
748 )
749 })?;
750 Ok(Stmt::Expr(Arc::new(expr)))
751 }
752
753 pub(crate) fn expression(&mut self) -> miette::Result<Expr> {
754 self.assignment()
755 }
756
757 fn assignment(&mut self) -> miette::Result<Expr> {
758 let expr = self.or()?;
759 let expr_token = self.previous().clone();
760
761 if self.match_token(&Arrow) {
762 let arrow_token = self.previous().clone();
763 let value = self.assignment()?; match expr {
766 Expr::Variable(ref variable) => Ok(Expr::Assign(
767 Assignment {
768 target: variable.clone(),
769 value,
770 ident_token: variable.token.clone(),
771 arrow_token,
772 }
773 .into(),
774 )),
775
776 Expr::Access(ref access) => Ok(Expr::Set(
778 Set {
779 target: Expr::Access(
780 Access {
781 list: access.list.clone(),
782 list_token: access.list_token.clone(),
783 key: access.key.clone(),
784 brackets: access.brackets.clone(),
785 }
786 .into(),
787 ),
788 list: access.list.clone(),
789 idx: access.key.clone(),
790 value,
791 list_token: access.list_token.clone(),
792 brackets: access.brackets.clone(),
793 arrow_token,
794 }
795 .into(),
796 )),
797
798 _ => {
804 let labels = vec![
805 LabeledSpan::at(arrow_token.span(), "expected an assignment target"),
806 LabeledSpan::at(expr_token.span(), "target goes here"),
807 ];
808
809 Err(miette!(
810 labels = labels,
811 code = "invalid_assignment_target",
812 help = "an assignment target must be a variable or an access expression (array[index] type)",
813 "expected an assignment target found {}", expr
814 ).with_source_code(self.named_source.clone()))
815 }
816 }
817 } else {
818 Ok(expr)
819 }
820 }
821
822 fn or(&mut self) -> miette::Result<Expr> {
824 let mut expr = self.and()?;
825
826 while self.match_token(&Or) {
827 let token = self.previous().clone();
829
830 let right = self.and()?;
831 expr = Expr::Logical(Arc::new(Logical {
832 left: expr,
833 operator: LogicalOp::Or,
834 right,
835
836 token,
837 }))
838 }
839
840 Ok(expr)
841 }
842
843 fn and(&mut self) -> miette::Result<Expr> {
845 let mut expr = self.equality()?;
846
847 while self.match_token(&And) {
848 let token = self.previous().clone();
850
851 let right = self.and()?;
852 expr = Expr::Logical(Arc::new(Logical {
853 left: expr,
854 operator: LogicalOp::And,
855 right,
856
857 token,
858 }))
859 }
860
861 Ok(expr)
862 }
863
864 fn equality(&mut self) -> miette::Result<Expr> {
865 let mut expr = self.comparison()?;
866
867 while self.match_tokens(&[BangEqual, EqualEqual]) {
868 let token = self.previous().clone();
870 let right = self.comparison()?;
871 let operator = token.to_binary_op()?;
872 let left = expr;
873 expr = Expr::Binary(
874 Binary {
875 left,
876 operator,
877 right,
878 token,
879 }
880 .into(),
881 )
882 }
883
884 Ok(expr)
885 }
886
887 fn comparison(&mut self) -> miette::Result<Expr> {
888 let mut expr = self.addition()?;
889
890 while self.match_tokens(&[Greater, GreaterEqual, Less, LessEqual]) {
891 let token = self.previous().clone();
893 let right = self.addition()?;
894 let operator = token.to_binary_op()?;
895 let left = expr;
896 expr = Expr::Binary(
897 Binary {
898 left,
899 operator,
900 right,
901 token,
902 }
903 .into(),
904 )
905 }
906
907 Ok(expr)
908 }
909
910 fn addition(&mut self) -> miette::Result<Expr> {
911 let mut expr = self.multiplication()?;
912
913 while self.match_tokens(&[Plus, Minus]) {
914 let token = self.previous().clone();
916 let right = self.multiplication()?;
917 let operator = token.to_binary_op()?;
918 let left = expr;
919 expr = Expr::Binary(
920 Binary {
921 left,
922 operator,
923 right,
924 token,
925 }
926 .into(),
927 )
928 }
929
930 Ok(expr)
931 }
932
933 fn multiplication(&mut self) -> miette::Result<Expr> {
934 let mut expr = self.unary()?;
935
936 while self.match_tokens(&[Star, Slash, Mod]) {
937 let token = self.previous().clone();
939 let right = self.unary()?;
940 let operator = token.to_binary_op()?;
941 let left = expr;
942 expr = Expr::Binary(
943 Binary {
944 left,
945 operator,
946 right,
947 token,
948 }
949 .into(),
950 )
951 }
952
953 Ok(expr)
954 }
955
956 fn unary(&mut self) -> miette::Result<Expr> {
957 if self.match_tokens(&[Not, Minus]) {
958 let token = self.previous().clone();
959 let right = self.unary()?;
960 let operator = token.to_unary_op()?;
961
962 let expr = Expr::Unary(
963 Unary {
964 operator,
965 right,
966 token,
967 }
968 .into(),
969 );
970
971 Ok(expr)
972 } else {
973 self.access()
974 }
975 }
976
977 fn access(&mut self) -> miette::Result<Expr> {
978 let mut expr = self.primary()?;
979 let expr_token = self.previous().clone();
980
981 loop {
982 if self.match_token(&LeftBracket) {
983 let lb_token = self.previous().clone();
984
985 let index = self.expression()?;
986 let rb_token = self.consume(&RightBracket, |token| {
987 let labels = vec![
988 LabeledSpan::at(token.span(), "requires closing `]`")
991 ];
992
993 miette!(
994 labels = labels,
995 code = "missing_rbracket",
996 help = "when indexing an array you must have a closing `]` bracket following the expression",
997 "expected ']' found {}", token.lexeme
998 )
999 })?.clone();
1000
1001 expr = Expr::Access(Arc::new(Access {
1002 list: expr,
1003 list_token: expr_token.clone(),
1004 key: index,
1005 brackets: (lb_token, rb_token),
1006 }));
1007 } else {
1008 break;
1009 }
1010 }
1011
1012 Ok(expr)
1013 }
1014
1015 fn primary(&mut self) -> miette::Result<Expr> {
1017 if self.match_token(&True) {
1019 let token = self.previous().clone();
1020 return Ok(Expr::Literal(Arc::new(ExprLiteral {
1021 value: Literal::True,
1022 token,
1023 })));
1024 }
1025 if self.match_token(&False) {
1027 let token = self.previous().clone();
1028 return Ok(Expr::Literal(Arc::new(ExprLiteral {
1029 value: Literal::False,
1030 token,
1031 })));
1032 }
1033 if self.match_token(&Null) {
1035 let token = self.previous().clone();
1036 return Ok(Expr::Literal(Arc::new(ExprLiteral {
1037 value: Literal::Null,
1038 token,
1039 })));
1040 }
1041 if self.match_token(&StringLiteral) {
1043 let token = self.previous().clone();
1044
1045 let literal = token
1047 .literal
1048 .clone()
1049 .miette_expect(|| miette!("internal parser error. could not find literal"));
1050
1051 let LiteralValue::String(literal) = literal else {
1053 let report = miette!("internal parser error literal is not a string");
1054 panic!("{:?}", report)
1055 };
1056
1057 return Ok(Expr::Literal(
1058 ExprLiteral {
1059 value: Literal::String(literal),
1060 token,
1061 }
1062 .into(),
1063 ));
1064 }
1065
1066 if self.match_token(&Number) {
1068 let token = self.previous().clone();
1069
1070 let literal = token
1072 .literal
1073 .clone()
1074 .miette_expect(|| miette!("internal parser error. could not find literal"));
1075
1076 let LiteralValue::Number(literal) = literal else {
1078 let report = miette!("internal parser error literal is not a number");
1079 panic!("{:?}", report)
1080 };
1081
1082 return Ok(Expr::Literal(
1083 ExprLiteral {
1084 value: Literal::Number(literal),
1085 token,
1086 }
1087 .into(),
1088 ));
1089 }
1090 if self.match_token(&Identifier) {
1094 let token = self.previous().clone();
1095 let ident = token.lexeme.clone();
1099
1100 if self.match_token(&LeftParen) {
1103 let lp_token = self.previous().clone();
1104
1105 let mut arguments = vec![];
1106 let mut arguments_tokens = vec![lp_token.clone()];
1107 if !self.check(&RightParen) {
1108 loop {
1109 if arguments.len() >= 255 {
1110 let report = miette!(
1113 "todo: max args for function call exceeded"
1115 );
1116 return Err(report);
1117 }
1118
1119 let expr = self.expression()?;
1120 arguments.push(expr);
1121 arguments_tokens.push(self.peek().clone());
1122
1123 if !self.match_token(&Comma) {
1125 break;
1126 }
1127 }
1128 }
1129
1130 let rp_token = self
1131 .consume(&RightParen, |token| {
1132 let labels = vec![LabeledSpan::at(token.span(), "expected a `)`")];
1135
1136 miette!(
1137 labels = labels,
1138 code = "missing_rp",
1139 help = "mismatched `(`, it seems you missed a `)`.",
1140 "expected `)`, found `{}`",
1141 token.lexeme
1142 )
1143 })?
1144 .clone();
1145
1146 let arguments_spans: Vec<SourceSpan> = arguments_tokens
1147 .windows(2)
1148 .map(|tok| tok[0].span_until_token(&tok[1]))
1149 .collect();
1150
1151 return Ok(Expr::ProcCall(Arc::new(ProcCall {
1152 ident,
1153 arguments,
1154 arguments_spans,
1155 token,
1156 parens: (lp_token, rp_token),
1157 })));
1158 }
1159
1160 return Ok(Expr::Variable(Arc::new(Variable { ident, token })));
1162 }
1163
1164 if self.match_token(&LeftParen) {
1166 let lp_token = self.previous().clone();
1167 let expr = self.expression()?;
1168
1169 let rp_token = self.consume(&RightParen, |token| {
1170 let labels = vec![LabeledSpan::at(token.span(), "expected a `(`")];
1173
1174 miette!(
1175 labels = labels,
1176 code = "missing_lp",
1177 help = "mismatched `)`, it seems you missed a `(`.",
1178 "expected `(` found `{}`",
1179 token.lexeme
1180 )
1181 })?;
1182
1183 return Ok(Expr::Grouping(Arc::new(Grouping {
1184 expr,
1185 parens: (lp_token.clone(), rp_token.clone()),
1186 })));
1187 }
1188
1189 if self.match_token(&LeftBracket) {
1191 let lb_token = self.previous().clone();
1192
1193 let mut items = vec![];
1194 if !self.check(&RightBracket) {
1195 loop {
1196 let expr = self.expression()?;
1197 items.push(expr);
1198
1199 if !self.match_token(&Comma) {
1201 break;
1202 }
1203 }
1204 }
1205
1206 let rb_token = self.consume(&RightBracket, |token| {
1207 let labels = vec![LabeledSpan::at(token.span(), "expected a `]`")];
1210
1211 miette!(
1212 labels = labels,
1213 code = "missing_rb",
1214 help = "mismatched `[`, it seems you missed a `]`.",
1215 "expected `]`, found `{}`",
1216 token.lexeme
1217 )
1218 })?;
1219
1220 return Ok(Expr::List(Arc::new(List {
1221 items,
1222 brackets: (lb_token, rb_token.clone()),
1223 })));
1224 }
1225
1226 let cspan = self.previous().span_to(self.peek().span());
1227 let labels = vec![
1228 LabeledSpan::at(self.peek().span(), "primary expected here"),
1229 ];
1231 let report = miette!(
1233 labels = labels,
1234 help = "a primary is made up of the following set:\n\
1235 [expression | ident | literal | list]",
1236 "expected primary, instead found {}\n",
1237 self.peek()
1238 )
1239 .with_source_code(self.named_source.clone());
1240 Err(report)
1242 }
1243}
1244impl Parser {
1246 fn synchronize(&mut self) {
1249 self.advance();
1250
1251 while !self.is_at_end() {
1252 match self.peek().token_type {
1257 Procedure | Repeat | For | If | Return | Continue | Break | Import | Export => {
1258 return
1259 }
1260 _ => (),
1261 }
1262
1263 self.advance();
1264 }
1265 }
1266
1267 fn consume(
1282 &mut self,
1283 token_type: &TokenType,
1284 report: impl FnOnce(&Token) -> Report,
1285 ) -> miette::Result<&Token> {
1286 let next_token = self.peek().clone();
1287 if next_token.token_type() == token_type {
1288 self.advance();
1289 let token = self.previous();
1290 Ok(token)
1291 } else {
1292 Err(report(&next_token).with_source_code(self.named_source.clone()))
1293 }
1294 }
1295
1296 fn take_semis(&mut self) {
1301 while self.check(&SoftSemi) {
1302 self.advance();
1303 }
1304 }
1305
1306 fn check(&self, typ: &TokenType) -> bool {
1317 if self.is_at_end() {
1318 return false;
1319 }
1320
1321 self.peek().token_type() == typ
1322 }
1323
1324 fn confirm(&self, typ: &TokenType) -> miette::Result<()> {
1339 let previous = self.previous();
1340
1341 if &previous.token_type != typ {
1342 return Err(miette!(
1343 "Expected previous token to be {:?}, but found {:?}.",
1344 typ,
1345 previous.token_type
1346 ));
1347 }
1348
1349 Ok(())
1350 }
1351
1352 fn match_token(&mut self, token_type: &TokenType) -> bool {
1363 if self.check(token_type) {
1364 self.advance();
1365 return true;
1366 }
1367 false
1368 }
1369
1370 fn match_tokens(&mut self, types: &[TokenType]) -> bool {
1381 for ty in types {
1382 if self.match_token(ty) {
1383 return true;
1384 }
1385 }
1386 false
1387 }
1388
1389 fn advance(&mut self) -> &Token {
1397 if !self.is_at_end() {
1398 self.current += 1;
1399 }
1400
1401 self.previous()
1402 }
1403
1404 fn peek(&self) -> &Token {
1414 self.tokens
1415 .get(self.current)
1416 .expect("Internal error: attempted to peek token when there is no token to peek.")
1417 }
1418
1419 fn previous(&self) -> &Token {
1429 if self.current == 0 {
1430 panic!("Internal error: there is no previous token.");
1431 }
1432
1433 self.tokens
1434 .get(self.current - 1)
1435 .expect("Internal error: failed to retrieve previous token.")
1436 }
1437
1438 fn is_at_end(&self) -> bool {
1445 self.peek().token_type == Eof
1446 }
1447}
1448
1449pub(super) mod warning {
1450 use crate::parser::Parser;
1451 use miette::Report;
1452
1453 impl Parser {
1454 pub(super) fn warning(&mut self, report: Report) {
1455 self._warnings
1456 .push(report.with_source_code(self.named_source.clone()))
1457 }
1458 }
1459}
1460
1461trait ExpectMiette<T> {
1462 fn miette_expect(self, report_handler: fn() -> Report) -> T;
1463}
1464
1465impl<T, E> ExpectMiette<T> for Result<T, E> {
1466 fn miette_expect(self, report_handler: fn() -> Report) -> T {
1467 match self {
1468 Ok(t) => t,
1469 Err(_) => {
1470 let _report = report_handler();
1471 panic!()
1472 }
1473 }
1474 }
1475}
1476
1477impl<T> ExpectMiette<T> for Option<T> {
1478 fn miette_expect(self, report_handler: fn() -> Report) -> T {
1479 match self {
1480 Some(t) => t,
1481 None => {
1482 let _report = report_handler();
1483 panic!()
1484 }
1485 }
1486 }
1487}