1use crate::lexer::Token;
4use crate::{ast::*, ParseError, ParseResult};
5use logos::{Logos, Span};
6
7pub fn preprocess_tokens(input: &str) -> Vec<(Token, Span)> {
9 let mut tokens = Vec::new();
10 let mut lexer = Token::lexer(input);
11 let mut indent_stack = vec![0];
12 let mut at_line_start = true;
13 let mut current_line_indent;
14 let mut pending_tokens = Vec::new();
15
16 while let Some(result) = lexer.next() {
18 if let Ok(token) = result {
19 let span = lexer.span();
20 pending_tokens.push((token, span));
21 }
22 }
23
24 let mut i = 0;
26 let mut paren_depth: usize = 0; let mut in_function_signature = false; while i < pending_tokens.len() {
30 let (token, span) = pending_tokens[i].clone();
31
32 match &token {
33 Token::Newline => {
34 tokens.push((token, span));
35 at_line_start = true;
36 i += 1;
37 }
38 _ => {
39 if at_line_start && paren_depth == 0 && !in_function_signature {
42 let line_start = input[..span.start].rfind('\n').map(|p| p + 1).unwrap_or(0);
44 let indent_str = &input[line_start..span.start];
45 current_line_indent = indent_str.chars().filter(|&c| c == ' ').count();
46
47 if matches!(token, Token::Newline) {
49 tokens.push((token, span));
50 i += 1;
51 continue;
52 }
53
54 let prev_indent = *indent_stack.last().unwrap();
56
57 if current_line_indent > prev_indent {
58 tokens.push((Token::Indent, span.start..span.start));
60 indent_stack.push(current_line_indent);
61 } else if current_line_indent < prev_indent {
62 while let Some(&stack_indent) = indent_stack.last() {
64 if stack_indent <= current_line_indent {
65 break;
66 }
67 tokens.push((Token::Dedent, span.start..span.start));
68 indent_stack.pop();
69 }
70
71 if indent_stack.last() != Some(¤t_line_indent) {
73 if let Some(&last_indent) = indent_stack.last() {
75 if current_line_indent > last_indent {
76 tokens.push((Token::Indent, span.start..span.start));
77 indent_stack.push(current_line_indent);
78 }
79 }
80 }
81 }
82
83 at_line_start = false;
84 }
85
86 match &token {
88 Token::LeftParen | Token::LeftBracket | Token::LeftBrace => {
89 paren_depth += 1;
90 }
91 Token::RightParen | Token::RightBracket | Token::RightBrace => {
92 paren_depth = paren_depth.saturating_sub(1);
93 }
94 _ => {}
95 }
96
97 if matches!(token, Token::Def) {
99 in_function_signature = true;
100 } else if matches!(token, Token::Colon) && in_function_signature && paren_depth == 0
101 {
102 in_function_signature = false;
103 }
104
105 tokens.push((token, span));
106 i += 1;
107 }
108 }
109 }
110
111 while indent_stack.len() > 1 {
113 tokens.push((Token::Dedent, input.len()..input.len()));
114 indent_stack.pop();
115 }
116
117 tokens
118}
119
120type ParsedArguments = (Vec<Expression>, Vec<(String, Expression)>);
122
123pub struct Parser<'a> {
124 tokens: Vec<(Token, Span)>,
125 current: usize,
126 current_line: usize,
127 #[allow(dead_code)]
128 errors: Vec<ParseError>,
129 #[allow(dead_code)]
130 error_recovery: bool,
131 source: &'a str,
132}
133
134impl<'a> Parser<'a> {
135 pub fn new(input: &'a str) -> Self {
136 let tokens = preprocess_tokens(input);
137
138 Self {
139 tokens,
140 current: 0,
141 current_line: 1,
142 errors: vec![],
143 error_recovery: true, source: input,
145 }
146 }
147
148 pub fn parse(&mut self) -> ParseResult<GlyphModule> {
149 self.skip_whitespace();
151
152 let program_decorator = self.parse_program_decorator()?;
154
155 self.skip_whitespace();
157
158 let mut imports = vec![];
160 while self.is_at_import() {
161 imports.push(self.parse_import()?);
162 self.skip_whitespace();
163 }
164
165 let mut statements = vec![];
167 while !self.is_at_end() {
168 self.skip_whitespace();
169 if self.is_at_end() {
170 break;
171 }
172 statements.push(self.parse_statement()?);
173 }
174
175 Ok(GlyphModule {
176 program: program_decorator,
177 imports,
178 statements,
179 })
180 }
181
182 fn current_token(&self) -> Option<&Token> {
183 if self.current < self.tokens.len() {
184 Some(&self.tokens[self.current].0)
185 } else {
186 None
187 }
188 }
189
190 fn current_span(&self) -> Span {
191 if self.current < self.tokens.len() {
192 self.tokens[self.current].1.clone()
193 } else {
194 self.source.len()..self.source.len()
195 }
196 }
197
198 fn peek_token(&self) -> Option<&Token> {
199 if self.current + 1 < self.tokens.len() {
200 Some(&self.tokens[self.current + 1].0)
201 } else {
202 None
203 }
204 }
205
206 fn is_at_end(&self) -> bool {
207 self.current >= self.tokens.len()
208 }
209
210 fn advance(&mut self) {
211 if !self.is_at_end() {
212 if let Some(Token::Newline) = self.current_token() {
213 self.current_line += 1;
214 }
215 self.current += 1;
216 }
217 }
218
219 fn expect(&mut self, expected: Token) -> ParseResult<()> {
220 if self.current_token() == Some(&expected) {
221 self.advance();
222 Ok(())
223 } else {
224 Err(ParseError::UnexpectedToken(format!(
225 "Expected {:?}, found {:?} at line {}",
226 expected,
227 self.current_token(),
228 self.current_line
229 )))
230 }
231 }
232
233 fn skip_whitespace(&mut self) {
234 while matches!(self.current_token(), Some(Token::Newline)) {
235 self.advance();
236 }
237 }
238
239 fn is_at_import(&self) -> bool {
240 matches!(
241 self.current_token(),
242 Some(Token::Import) | Some(Token::From)
243 )
244 }
245
246 fn get_source_text(&self, span: &Span) -> String {
247 self.source[span.clone()].to_string()
248 }
249
250 fn parse_program_decorator(&mut self) -> ParseResult<ProgramDecorator> {
251 self.expect(Token::At)?;
253
254 if !matches!(self.current_token(), Some(Token::Identifier)) {
256 return Err(ParseError::SyntaxError {
257 line: self.current_line,
258 message: "Expected 'program' after @".to_string(),
259 });
260 }
261
262 let ident_text = self.get_source_text(&self.current_span());
263 if ident_text != "program" {
264 return Err(ParseError::SyntaxError {
265 line: self.current_line,
266 message: format!("Expected 'program', found '{ident_text}'"),
267 });
268 }
269 self.advance();
270
271 self.expect(Token::LeftParen)?;
272
273 let mut name = String::new();
274 let mut version = "0.1.0".to_string();
275 let mut requires = vec![];
276
277 while !matches!(self.current_token(), Some(Token::RightParen)) {
279 if !matches!(self.current_token(), Some(Token::Identifier)) {
281 return Err(ParseError::SyntaxError {
282 line: self.current_line,
283 message: "Expected keyword argument".to_string(),
284 });
285 }
286
287 let key = self.get_source_text(&self.current_span());
288 self.advance();
289
290 self.expect(Token::Equal)?;
291
292 match key.as_str() {
293 "name" => {
294 if let Some(Token::String) = &self.current_token() {
295 name = self.get_source_text(&self.current_span());
296 name = name
298 .trim_start_matches('"')
299 .trim_end_matches('"')
300 .trim_start_matches('\'')
301 .trim_end_matches('\'')
302 .to_string();
303 self.advance();
304 } else {
305 return Err(ParseError::SyntaxError {
306 line: self.current_line,
307 message: "Expected string for 'name'".to_string(),
308 });
309 }
310 }
311 "version" => {
312 if let Some(Token::String) = &self.current_token() {
313 version = self.get_source_text(&self.current_span());
314 version = version
315 .trim_start_matches('"')
316 .trim_end_matches('"')
317 .trim_start_matches('\'')
318 .trim_end_matches('\'')
319 .to_string();
320 self.advance();
321 }
322 }
323 "requires" => {
324 requires = self.parse_string_list()?;
325 }
326 _ => {
327 return Err(ParseError::SyntaxError {
328 line: self.current_line,
329 message: format!("Unknown program parameter: {key}"),
330 });
331 }
332 }
333
334 if matches!(self.current_token(), Some(Token::Comma)) {
335 self.advance();
336 }
337 }
338
339 self.expect(Token::RightParen)?;
340 self.skip_whitespace();
341
342 if name.is_empty() {
343 return Err(ParseError::MissingProgramField {
344 field: "name".to_string(),
345 });
346 }
347
348 Ok(ProgramDecorator {
349 name,
350 version,
351 requires,
352 })
353 }
354
355 fn parse_string_list(&mut self) -> ParseResult<Vec<String>> {
356 self.expect(Token::LeftBracket)?;
357
358 let mut items = vec![];
359
360 while !matches!(self.current_token(), Some(Token::RightBracket)) {
361 if let Some(Token::String) = &self.current_token() {
362 let mut item = self.get_source_text(&self.current_span());
363 item = item
364 .trim_start_matches('"')
365 .trim_end_matches('"')
366 .trim_start_matches('\'')
367 .trim_end_matches('\'')
368 .to_string();
369 items.push(item);
370 self.advance();
371
372 if matches!(self.current_token(), Some(Token::Comma)) {
373 self.advance();
374 }
375 } else {
376 return Err(ParseError::SyntaxError {
377 line: self.current_line,
378 message: "Expected string in list".to_string(),
379 });
380 }
381 }
382
383 self.expect(Token::RightBracket)?;
384 Ok(items)
385 }
386
387 fn parse_import(&mut self) -> ParseResult<Import> {
388 match self.current_token() {
389 Some(Token::Import) => {
390 self.advance();
391 if let Some(Token::Identifier) = &self.current_token() {
392 let name = self.get_source_text(&self.current_span());
393 self.advance();
394 self.skip_whitespace();
395 Ok(Import::Module { name })
396 } else {
397 Err(ParseError::SyntaxError {
398 line: self.current_line,
399 message: "Expected module name after 'import'".to_string(),
400 })
401 }
402 }
403 Some(Token::From) => {
404 self.advance();
405
406 if !matches!(self.current_token(), Some(Token::Identifier)) {
407 return Err(ParseError::SyntaxError {
408 line: self.current_line,
409 message: "Expected module name after 'from'".to_string(),
410 });
411 }
412
413 let module = self.get_source_text(&self.current_span());
414 self.advance();
415
416 self.expect(Token::Import)?;
417
418 let mut items = vec![];
419
420 loop {
421 if let Some(Token::Identifier) = &self.current_token() {
422 items.push(self.get_source_text(&self.current_span()));
423 self.advance();
424
425 if matches!(self.current_token(), Some(Token::Comma)) {
426 self.advance();
427 } else {
428 break;
429 }
430 } else {
431 return Err(ParseError::SyntaxError {
432 line: self.current_line,
433 message: "Expected identifier in import list".to_string(),
434 });
435 }
436 }
437
438 self.skip_whitespace();
439 Ok(Import::FromImport { module, items })
440 }
441 _ => Err(ParseError::UnexpectedToken(format!(
442 "Expected 'import' or 'from', found {:?}",
443 self.current_token()
444 ))),
445 }
446 }
447
448 fn parse_statement(&mut self) -> ParseResult<Statement> {
449 match self.current_token() {
450 Some(Token::Def) => Ok(Statement::FunctionDef(self.parse_function()?)),
451 Some(Token::If) => Ok(Statement::If(self.parse_if_statement()?)),
452 Some(Token::Match) => Ok(Statement::Match(self.parse_match_statement()?)),
453 Some(Token::While) => self.parse_while_statement(),
454 Some(Token::For) => self.parse_for_statement(),
455 Some(Token::Break) => {
456 self.advance();
457 self.skip_whitespace();
458 Ok(Statement::Break)
459 }
460 Some(Token::Continue) => {
461 self.advance();
462 self.skip_whitespace();
463 Ok(Statement::Continue)
464 }
465 Some(Token::Return) => {
466 self.advance();
467 let expr = if matches!(self.current_token(), Some(Token::Newline)) {
468 None
469 } else {
470 Some(self.parse_expression()?)
471 };
472 self.skip_whitespace();
473 Ok(Statement::Return(expr))
474 }
475 Some(Token::Let) => {
476 self.advance();
477
478 if !matches!(self.current_token(), Some(Token::Identifier)) {
479 return Err(ParseError::SyntaxError {
480 line: self.current_line,
481 message: "Expected identifier after 'let'".to_string(),
482 });
483 }
484
485 let name = self.get_source_text(&self.current_span());
486 self.advance();
487
488 let type_hint = if matches!(self.current_token(), Some(Token::Colon)) {
489 self.advance();
490 Some(self.parse_type()?)
491 } else {
492 None
493 };
494
495 self.expect(Token::Equal)?;
496 let value = self.parse_expression()?;
497 self.skip_whitespace();
498
499 Ok(Statement::Let {
500 name,
501 value,
502 type_hint,
503 })
504 }
505 Some(Token::Pass) => {
506 self.advance();
507 self.skip_whitespace();
508 Ok(Statement::Expression(Expression::Literal(Literal::Unit)))
509 }
510 Some(Token::Identifier) => {
511 let checkpoint = self.current;
513 let name = self.get_source_text(&self.current_span());
514 self.advance();
515
516 if matches!(self.current_token(), Some(Token::Equal)) {
517 self.advance();
518 let value = self.parse_expression()?;
519 self.skip_whitespace();
520 Ok(Statement::Assignment {
521 target: name,
522 value,
523 })
524 } else {
525 self.current = checkpoint;
527 let expr = self.parse_expression()?;
528 self.skip_whitespace();
529 Ok(Statement::Expression(expr))
530 }
531 }
532 _ => {
533 let expr = self.parse_expression()?;
535 self.skip_whitespace();
536 Ok(Statement::Expression(expr))
537 }
538 }
539 }
540
541 fn parse_function(&mut self) -> ParseResult<Function> {
542 self.expect(Token::Def)?;
543
544 if !matches!(self.current_token(), Some(Token::Identifier)) {
545 return Err(ParseError::SyntaxError {
546 line: self.current_line,
547 message: "Expected function name".to_string(),
548 });
549 }
550
551 let name = self.get_source_text(&self.current_span());
552 self.advance();
553
554 self.expect(Token::LeftParen)?;
555
556 let mut params = vec![];
557 while !matches!(self.current_token(), Some(Token::RightParen)) {
558 while matches!(self.current_token(), Some(Token::Newline)) {
560 self.advance();
561 }
562
563 if matches!(self.current_token(), Some(Token::RightParen)) {
564 break;
565 }
566
567 params.push(self.parse_parameter()?);
568
569 if matches!(self.current_token(), Some(Token::Comma)) {
570 self.advance();
571 while matches!(self.current_token(), Some(Token::Newline)) {
573 self.advance();
574 }
575 }
576 }
577
578 self.expect(Token::RightParen)?;
579
580 let return_type = if matches!(self.current_token(), Some(Token::Arrow)) {
581 self.advance();
582 Some(self.parse_type()?)
583 } else {
584 None
585 };
586
587 self.expect(Token::Colon)?;
588
589 if matches!(self.current_token(), Some(Token::Newline)) {
591 self.advance();
592 }
593
594 self.expect(Token::Indent)?;
595 let mut body = vec![];
596
597 while !matches!(self.current_token(), Some(Token::Dedent)) {
598 body.push(self.parse_statement()?);
599 }
600
601 self.expect(Token::Dedent)?;
602
603 Ok(Function {
604 name,
605 params,
606 return_type,
607 body,
608 is_async: false, })
610 }
611
612 fn parse_parameter(&mut self) -> ParseResult<Parameter> {
613 if !matches!(self.current_token(), Some(Token::Identifier)) {
614 return Err(ParseError::SyntaxError {
615 line: self.current_line,
616 message: "Expected parameter name".to_string(),
617 });
618 }
619
620 let name = self.get_source_text(&self.current_span());
621 self.advance();
622
623 let type_hint = if matches!(self.current_token(), Some(Token::Colon)) {
624 self.advance();
625 Some(self.parse_type()?)
626 } else {
627 None
628 };
629
630 let default = if matches!(self.current_token(), Some(Token::Equal)) {
631 self.advance();
632 Some(self.parse_expression()?)
633 } else {
634 None
635 };
636
637 Ok(Parameter {
638 name,
639 type_hint,
640 default,
641 })
642 }
643
644 fn parse_type(&mut self) -> ParseResult<Type> {
645 if !matches!(self.current_token(), Some(Token::Identifier)) {
646 return Err(ParseError::SyntaxError {
647 line: self.current_line,
648 message: "Expected type name".to_string(),
649 });
650 }
651
652 let type_name = self.get_source_text(&self.current_span());
653 self.advance();
654
655 match type_name.as_str() {
656 "list" => {
657 if matches!(self.current_token(), Some(Token::LeftBracket)) {
658 self.advance();
659 let inner = Box::new(self.parse_type()?);
660 self.expect(Token::RightBracket)?;
661 Ok(Type::List(inner))
662 } else {
663 Ok(Type::Named("list".to_string()))
664 }
665 }
666 "dict" => {
667 if matches!(self.current_token(), Some(Token::LeftBracket)) {
668 self.advance();
669 let key = Box::new(self.parse_type()?);
670 self.expect(Token::Comma)?;
671 let value = Box::new(self.parse_type()?);
672 self.expect(Token::RightBracket)?;
673 Ok(Type::Dict { key, value })
674 } else {
675 Ok(Type::Named("dict".to_string()))
676 }
677 }
678 "optional" => {
679 self.expect(Token::LeftBracket)?;
680 let inner = Box::new(self.parse_type()?);
681 self.expect(Token::RightBracket)?;
682 Ok(Type::Optional(inner))
683 }
684 "promise" => {
685 self.expect(Token::LeftBracket)?;
686 let inner = Box::new(self.parse_type()?);
687 self.expect(Token::RightBracket)?;
688 Ok(Type::Promise(inner))
689 }
690 "result" => {
691 self.expect(Token::LeftBracket)?;
692 let ok = Box::new(self.parse_type()?);
693 self.expect(Token::Comma)?;
694 let err = Box::new(self.parse_type()?);
695 self.expect(Token::RightBracket)?;
696 Ok(Type::Result { ok, err })
697 }
698 _ => Ok(Type::Named(type_name)),
699 }
700 }
701
702 fn parse_if_statement(&mut self) -> ParseResult<IfStatement> {
703 self.expect(Token::If)?;
704
705 let condition = self.parse_expression()?;
706 self.expect(Token::Colon)?;
707
708 if matches!(self.current_token(), Some(Token::Newline)) {
710 self.advance();
711 }
712
713 self.expect(Token::Indent)?;
714 let mut then_body = vec![];
715
716 while !matches!(self.current_token(), Some(Token::Dedent)) {
717 then_body.push(self.parse_statement()?);
718 }
719
720 self.expect(Token::Dedent)?;
721
722 let mut elif_clauses = vec![];
724 while matches!(self.current_token(), Some(Token::Elif)) {
725 self.advance();
726 let elif_condition = self.parse_expression()?;
727 self.expect(Token::Colon)?;
728
729 if matches!(self.current_token(), Some(Token::Newline)) {
730 self.advance();
731 }
732
733 self.expect(Token::Indent)?;
734 let mut elif_body = vec![];
735
736 while !matches!(self.current_token(), Some(Token::Dedent)) {
737 elif_body.push(self.parse_statement()?);
738 }
739
740 self.expect(Token::Dedent)?;
741
742 elif_clauses.push(ElifClause {
743 condition: elif_condition,
744 body: elif_body,
745 });
746 }
747
748 let else_body = if matches!(self.current_token(), Some(Token::Else)) {
750 self.advance();
751 self.expect(Token::Colon)?;
752
753 if matches!(self.current_token(), Some(Token::Newline)) {
754 self.advance();
755 }
756
757 self.expect(Token::Indent)?;
758 let mut else_stmts = vec![];
759
760 while !matches!(self.current_token(), Some(Token::Dedent)) {
761 else_stmts.push(self.parse_statement()?);
762 }
763
764 self.expect(Token::Dedent)?;
765
766 Some(else_stmts)
767 } else {
768 None
769 };
770
771 Ok(IfStatement {
772 condition,
773 then_body,
774 elif_clauses,
775 else_body,
776 })
777 }
778
779 fn parse_match_statement(&mut self) -> ParseResult<MatchStatement> {
780 self.expect(Token::Match)?;
781
782 let subject = self.parse_expression()?;
783 self.expect(Token::Colon)?;
784
785 if matches!(self.current_token(), Some(Token::Newline)) {
787 self.advance();
788 }
789
790 self.expect(Token::Indent)?;
791 let mut cases = vec![];
792
793 while !matches!(self.current_token(), Some(Token::Dedent)) {
794 cases.push(self.parse_case_clause()?);
795 }
796
797 self.expect(Token::Dedent)?;
798
799 Ok(MatchStatement { subject, cases })
800 }
801
802 fn parse_case_clause(&mut self) -> ParseResult<CaseClause> {
803 self.expect(Token::Case)?;
804
805 let pattern = self.parse_pattern()?;
806 self.expect(Token::Colon)?;
807
808 if matches!(self.current_token(), Some(Token::Newline)) {
810 self.advance();
811 }
812
813 self.expect(Token::Indent)?;
814 let mut body = vec![];
815
816 while !matches!(self.current_token(), Some(Token::Dedent)) {
817 body.push(self.parse_statement()?);
818 }
819
820 self.expect(Token::Dedent)?;
821
822 Ok(CaseClause { pattern, body })
823 }
824
825 fn parse_pattern(&mut self) -> ParseResult<Pattern> {
826 match self.current_token() {
827 Some(Token::Identifier) => {
828 let name = self.get_source_text(&self.current_span());
829 self.advance();
830
831 if name == "_" {
832 Ok(Pattern::Wildcard)
833 } else if matches!(self.current_token(), Some(Token::LeftParen)) {
834 self.advance();
836 let mut args = vec![];
837
838 while !matches!(self.current_token(), Some(Token::RightParen)) {
839 args.push(self.parse_pattern()?);
840
841 if matches!(self.current_token(), Some(Token::Comma)) {
842 self.advance();
843 }
844 }
845
846 self.expect(Token::RightParen)?;
847 Ok(Pattern::Constructor { name, args })
848 } else {
849 Ok(Pattern::Variable(name))
850 }
851 }
852 Some(Token::Int) => {
853 let value = self
854 .get_source_text(&self.current_span())
855 .parse::<i64>()
856 .map_err(|_| ParseError::SyntaxError {
857 line: self.current_line,
858 message: "Invalid integer".to_string(),
859 })?;
860 self.advance();
861 Ok(Pattern::Literal(Literal::Int(value)))
862 }
863 Some(Token::Float) => {
864 let value = self
865 .get_source_text(&self.current_span())
866 .parse::<f64>()
867 .map_err(|_| ParseError::SyntaxError {
868 line: self.current_line,
869 message: "Invalid float".to_string(),
870 })?;
871 self.advance();
872 Ok(Pattern::Literal(Literal::Float(value)))
873 }
874 Some(Token::String) => {
875 let mut value = self.get_source_text(&self.current_span());
876 value = value
877 .trim_start_matches('"')
878 .trim_end_matches('"')
879 .trim_start_matches('\'')
880 .trim_end_matches('\'')
881 .to_string();
882 self.advance();
883 Ok(Pattern::Literal(Literal::String(value)))
884 }
885 Some(Token::True) => {
886 self.advance();
887 Ok(Pattern::Literal(Literal::Bool(true)))
888 }
889 Some(Token::False) => {
890 self.advance();
891 Ok(Pattern::Literal(Literal::Bool(false)))
892 }
893 Some(Token::None) => {
894 self.advance();
895 Ok(Pattern::Literal(Literal::Unit))
896 }
897 _ => Err(ParseError::SyntaxError {
898 line: self.current_line,
899 message: "Expected pattern".to_string(),
900 }),
901 }
902 }
903
904 fn parse_while_statement(&mut self) -> ParseResult<Statement> {
905 self.expect(Token::While)?;
906
907 let condition = self.parse_expression()?;
908 self.expect(Token::Colon)?;
909
910 if matches!(self.current_token(), Some(Token::Newline)) {
912 self.advance();
913 }
914
915 self.expect(Token::Indent)?;
916 let mut body = vec![];
917
918 while !matches!(self.current_token(), Some(Token::Dedent)) {
919 body.push(self.parse_statement()?);
920 }
921
922 self.expect(Token::Dedent)?;
923
924 Ok(Statement::While { condition, body })
925 }
926
927 fn parse_for_statement(&mut self) -> ParseResult<Statement> {
928 self.expect(Token::For)?;
929
930 if !matches!(self.current_token(), Some(Token::Identifier)) {
931 return Err(ParseError::SyntaxError {
932 line: self.current_line,
933 message: "Expected identifier after 'for'".to_string(),
934 });
935 }
936
937 let variable = self.get_source_text(&self.current_span());
938 self.advance();
939
940 self.expect(Token::In)?;
941
942 let iterable = self.parse_expression()?;
943 self.expect(Token::Colon)?;
944
945 if matches!(self.current_token(), Some(Token::Newline)) {
947 self.advance();
948 }
949
950 self.expect(Token::Indent)?;
951 let mut body = vec![];
952
953 while !matches!(self.current_token(), Some(Token::Dedent)) {
954 body.push(self.parse_statement()?);
955 }
956
957 self.expect(Token::Dedent)?;
958
959 Ok(Statement::For {
960 variable,
961 iterable,
962 body,
963 })
964 }
965
966 fn parse_expression(&mut self) -> ParseResult<Expression> {
967 self.parse_or_expr()
968 }
969
970 fn parse_or_expr(&mut self) -> ParseResult<Expression> {
971 let mut left = self.parse_and_expr()?;
972
973 while matches!(self.current_token(), Some(Token::Or)) {
974 self.advance();
975 let right = self.parse_and_expr()?;
976 left = Expression::BinaryOp {
977 left: Box::new(left),
978 op: BinaryOperator::Or,
979 right: Box::new(right),
980 };
981 }
982
983 Ok(left)
984 }
985
986 fn parse_and_expr(&mut self) -> ParseResult<Expression> {
987 let mut left = self.parse_not_expr()?;
988
989 while matches!(self.current_token(), Some(Token::And)) {
990 self.advance();
991 let right = self.parse_not_expr()?;
992 left = Expression::BinaryOp {
993 left: Box::new(left),
994 op: BinaryOperator::And,
995 right: Box::new(right),
996 };
997 }
998
999 Ok(left)
1000 }
1001
1002 fn parse_not_expr(&mut self) -> ParseResult<Expression> {
1003 if matches!(self.current_token(), Some(Token::Not)) {
1004 self.advance();
1005 let operand = self.parse_not_expr()?;
1006 Ok(Expression::UnaryOp {
1007 op: UnaryOperator::Not,
1008 operand: Box::new(operand),
1009 })
1010 } else {
1011 self.parse_comparison()
1012 }
1013 }
1014
1015 fn parse_comparison(&mut self) -> ParseResult<Expression> {
1016 let mut left = self.parse_additive()?;
1017
1018 loop {
1019 let op = match &self.current_token() {
1020 Some(Token::Less) => BinaryOperator::Less,
1021 Some(Token::Greater) => BinaryOperator::Greater,
1022 Some(Token::LessEqual) => BinaryOperator::LessEqual,
1023 Some(Token::GreaterEqual) => BinaryOperator::GreaterEqual,
1024 Some(Token::EqualEqual) => BinaryOperator::Equal,
1025 Some(Token::NotEqual) => BinaryOperator::NotEqual,
1026 _ => break,
1027 };
1028
1029 self.advance();
1030 let right = self.parse_additive()?;
1031 left = Expression::BinaryOp {
1032 left: Box::new(left),
1033 op,
1034 right: Box::new(right),
1035 };
1036 }
1037
1038 Ok(left)
1039 }
1040
1041 fn parse_additive(&mut self) -> ParseResult<Expression> {
1042 let mut left = self.parse_multiplicative()?;
1043
1044 loop {
1045 let op = match &self.current_token() {
1046 Some(Token::Plus) => BinaryOperator::Add,
1047 Some(Token::Minus) => BinaryOperator::Subtract,
1048 _ => break,
1049 };
1050
1051 self.advance();
1052 let right = self.parse_multiplicative()?;
1053 left = Expression::BinaryOp {
1054 left: Box::new(left),
1055 op,
1056 right: Box::new(right),
1057 };
1058 }
1059
1060 Ok(left)
1061 }
1062
1063 fn parse_multiplicative(&mut self) -> ParseResult<Expression> {
1064 let mut left = self.parse_power()?;
1065
1066 loop {
1067 let op = match &self.current_token() {
1068 Some(Token::Star) => BinaryOperator::Multiply,
1069 Some(Token::Slash) => BinaryOperator::Divide,
1070 Some(Token::Percent) => BinaryOperator::Modulo,
1071 _ => break,
1072 };
1073
1074 self.advance();
1075 let right = self.parse_power()?;
1076 left = Expression::BinaryOp {
1077 left: Box::new(left),
1078 op,
1079 right: Box::new(right),
1080 };
1081 }
1082
1083 Ok(left)
1084 }
1085
1086 fn parse_power(&mut self) -> ParseResult<Expression> {
1087 let mut left = self.parse_unary()?;
1088
1089 if matches!(self.current_token(), Some(Token::StarStar)) {
1090 self.advance();
1091 let right = self.parse_power()?; left = Expression::BinaryOp {
1093 left: Box::new(left),
1094 op: BinaryOperator::Power,
1095 right: Box::new(right),
1096 };
1097 }
1098
1099 Ok(left)
1100 }
1101
1102 fn parse_unary(&mut self) -> ParseResult<Expression> {
1103 match &self.current_token() {
1104 Some(Token::Minus) => {
1105 self.advance();
1106 let operand = self.parse_unary()?;
1107 Ok(Expression::UnaryOp {
1108 op: UnaryOperator::Negate,
1109 operand: Box::new(operand),
1110 })
1111 }
1112 _ => self.parse_postfix(),
1113 }
1114 }
1115
1116 fn parse_postfix(&mut self) -> ParseResult<Expression> {
1117 let mut expr = self.parse_atom()?;
1118
1119 loop {
1120 match self.current_token() {
1121 Some(Token::LeftParen) => {
1122 self.advance();
1124 let (args, kwargs) = self.parse_arguments()?;
1125 self.expect(Token::RightParen)?;
1126
1127 expr = Expression::Call {
1128 func: Box::new(expr),
1129 args,
1130 kwargs,
1131 };
1132 }
1133 Some(Token::Dot) => {
1134 self.advance();
1136
1137 if !matches!(self.current_token(), Some(Token::Identifier)) {
1138 return Err(ParseError::SyntaxError {
1139 line: self.current_line,
1140 message: "Expected attribute name after '.'".to_string(),
1141 });
1142 }
1143
1144 let attr = self.get_source_text(&self.current_span());
1145 self.advance();
1146
1147 expr = Expression::Attribute {
1148 value: Box::new(expr),
1149 attr,
1150 };
1151 }
1152 Some(Token::LeftBracket) => {
1153 self.advance();
1155 let _index = self.parse_expression()?;
1156 self.expect(Token::RightBracket)?;
1157 }
1159 _ => break,
1160 }
1161 }
1162
1163 if matches!(self.current_token(), Some(Token::Await)) {
1165 self.advance();
1166 expr = Expression::Await(Box::new(expr));
1167 }
1168
1169 Ok(expr)
1170 }
1171
1172 fn parse_atom(&mut self) -> ParseResult<Expression> {
1173 match self.current_token() {
1174 Some(Token::Int) => {
1175 let value = self
1176 .get_source_text(&self.current_span())
1177 .parse::<i64>()
1178 .map_err(|_| ParseError::SyntaxError {
1179 line: self.current_line,
1180 message: "Invalid integer".to_string(),
1181 })?;
1182 self.advance();
1183 Ok(Expression::Literal(Literal::Int(value)))
1184 }
1185 Some(Token::Float) => {
1186 let value = self
1187 .get_source_text(&self.current_span())
1188 .parse::<f64>()
1189 .map_err(|_| ParseError::SyntaxError {
1190 line: self.current_line,
1191 message: "Invalid float".to_string(),
1192 })?;
1193 self.advance();
1194 Ok(Expression::Literal(Literal::Float(value)))
1195 }
1196 Some(Token::String) => {
1197 let mut value = self.get_source_text(&self.current_span());
1198 value = value
1199 .trim_start_matches('"')
1200 .trim_end_matches('"')
1201 .trim_start_matches('\'')
1202 .trim_end_matches('\'')
1203 .to_string();
1204 self.advance();
1205 Ok(Expression::Literal(Literal::String(value)))
1206 }
1207 Some(Token::FString) => {
1208 let mut value = self.get_source_text(&self.current_span());
1209 if value.starts_with("f\"") || value.starts_with("f'") {
1211 value = value[2..value.len() - 1].to_string();
1212 }
1213 self.advance();
1214 Ok(Expression::Literal(Literal::String(value)))
1217 }
1218 Some(Token::True) => {
1219 self.advance();
1220 Ok(Expression::Literal(Literal::Bool(true)))
1221 }
1222 Some(Token::False) => {
1223 self.advance();
1224 Ok(Expression::Literal(Literal::Bool(false)))
1225 }
1226 Some(Token::None) => {
1227 self.advance();
1228 Ok(Expression::Literal(Literal::Unit))
1229 }
1230 Some(Token::Identifier) => {
1231 let name = self.get_source_text(&self.current_span());
1232 self.advance();
1233 Ok(Expression::Identifier(name))
1234 }
1235 Some(Token::LeftParen) => {
1236 self.advance();
1237 let expr = self.parse_expression()?;
1238 self.expect(Token::RightParen)?;
1239 Ok(expr)
1240 }
1241 Some(Token::LeftBracket) => {
1242 self.advance();
1243 let mut elements = vec![];
1244
1245 while !matches!(self.current_token(), Some(Token::RightBracket)) {
1246 elements.push(self.parse_expression()?);
1247
1248 if matches!(self.current_token(), Some(Token::Comma)) {
1249 self.advance();
1250 }
1251 }
1252
1253 self.expect(Token::RightBracket)?;
1254 Ok(Expression::List(elements))
1255 }
1256 Some(Token::LeftBrace) => {
1257 self.advance();
1258 let mut pairs = vec![];
1259
1260 while !matches!(self.current_token(), Some(Token::RightBrace)) {
1261 let key = self.parse_expression()?;
1262 self.expect(Token::Colon)?;
1263 let value = self.parse_expression()?;
1264 pairs.push((key, value));
1265
1266 if matches!(self.current_token(), Some(Token::Comma)) {
1267 self.advance();
1268 }
1269 }
1270
1271 self.expect(Token::RightBrace)?;
1272 Ok(Expression::Dict(pairs))
1273 }
1274 _ => Err(ParseError::UnexpectedToken(format!(
1275 "Expected expression, found {:?}",
1276 self.current_token()
1277 ))),
1278 }
1279 }
1280
1281 fn parse_arguments(&mut self) -> ParseResult<ParsedArguments> {
1282 let mut args = vec![];
1283 let mut kwargs = vec![];
1284 let mut parsing_kwargs = false;
1285
1286 while !matches!(self.current_token(), Some(Token::RightParen)) {
1287 if matches!(self.current_token(), Some(Token::Identifier))
1289 && matches!(self.peek_token(), Some(Token::Equal))
1290 {
1291 parsing_kwargs = true;
1292 let key = self.get_source_text(&self.current_span());
1293 self.advance(); self.advance(); let value = self.parse_expression()?;
1296 kwargs.push((key, value));
1297 } else if parsing_kwargs {
1298 return Err(ParseError::SyntaxError {
1299 line: self.current_line,
1300 message: "Positional argument after keyword argument".to_string(),
1301 });
1302 } else {
1303 args.push(self.parse_expression()?);
1304 }
1305
1306 if matches!(self.current_token(), Some(Token::Comma)) {
1307 self.advance();
1308 }
1309 }
1310
1311 Ok((args, kwargs))
1312 }
1313}
1314
1315pub fn parse_glyph(source: &str) -> ParseResult<GlyphModule> {
1317 let mut parser = Parser::new(source);
1318 parser.parse()
1319}