1use crate::types::Token;
2
3use crate::types::ast::{
4 statement::Statement as Stat,
5 expression::Expression as Expr,
6 operators::Operator as Op,
7 value::Value,
8 line::Line,
9 program::Program
10};
11
12use crate::types::ParseErrorKind;
13use crate::types::ExprError;
14use crate::types::StatError;
15
16use crate::types::SlidingWindow;
17use crate::types::VecWindow;
18
19pub fn parse_program(window: &mut VecWindow<Token>) -> Result<Program, StatError>
20{
21 let mut line_vec: Vec<Line> = Vec::new();
22 let mut current_line: Vec<Stat> = Vec::new();
23
24 while window.remaining_length() > 0
25 {
26 if let Some(Token::Newline) = window.get_value(0)
27 {
28 window.move_view(1);
29
30 line_vec.push(Line(current_line.clone()));
31 if cfg!(debug_assertions) { println!("[Parser] Finished line:\n{:?}", current_line) }
32
33 current_line.clear();
34 continue;
35 }
36
37 match parse_statement(window)
38 {
39 Ok(stat) => {
40 if cfg!(debug_assertions) { println!("[Parser] Parsed statement: {:?}", stat) }
41 current_line.push(stat);
42 },
43
44 error => {
45 if cfg!(debug_assertions) {
46 println!("[Parser] Erroring out, line so far:\n{:?}", line_vec);
47 println!("[Parser] Erroring out, window state:\n{:?}", window.get_window(3));
48 }
49 error?;
50 }
51 }
52 }
53
54 if current_line.is_empty() == false
55 {
56 line_vec.push(Line(current_line.clone()));
57 }
58
59 Ok(Program(line_vec))
60}
61
62pub fn parse_line(window: &mut VecWindow<Token>) -> Result<Line, StatError>
63{
64 let mut stat_vec: Vec<Stat> = Vec::new();
65 while window.remaining_length() > 0
66 {
67 if let Some(Token::Newline) = window.get_value(0)
68 {
69 window.move_view(1);
70 if cfg!(debug_assertions) { println!("[Parser] Finished line:\n{:?}", stat_vec) }
71 break;
72 }
73
74 match parse_statement(window)
75 {
76 Ok(stat) => {
77 if cfg!(debug_assertions) { println!("[Parser] Parsed statement: {:?}", stat) }
78 stat_vec.push(stat);
79 }
80
81 error => {
82 if cfg!(debug_assertions) {
83 println!("[Parser] Erroring out, line so far:\n{:?}", stat_vec);
84 println!("[Parser] Erroring out, window state:\n{:?}", window.get_window(3));
85 }
86 error?;
87 }
88 }
89 }
90
91 Ok(Line(stat_vec))
92}
93
94fn parse_statement(window: &mut VecWindow<Token>) -> Result<Stat, StatError>
95{
96 let value_tuple = (window.get_value(0), window.get_value(1), window.get_value(2));
97 if cfg!(debug_assertions) { println!("[Parse Stat] Matching slice: {:?}", value_tuple) }
98
99 let statement = match value_tuple
100 {
101 (Some(Token::Comment(comment)), _, _) => {
102 let comment_string = comment.clone();
103 window.move_view(1);
104 Stat::Comment(comment_string)
105 }
106
107 (Some(Token::Goto), _, _) => {
108 window.move_view(1);
109 Stat::Goto(parse_expression(window)?)
110 },
111
112 (Some(Token::If), _, _) => {
113 window.move_view(1);
114 extend_if(window)?
115 },
116
117 (Some(ident @ Token::Identifier(_)), Some(Token::Plus), Some(Token::Equal)) => {
118 let value = Value::from(ident.clone());
119 window.move_view(3);
120 Stat::Assignment(value, Op::AddAssign, parse_expression(window)?)
121 },
122
123 (Some(ident @ Token::Identifier(_)), Some(Token::Minus), Some(Token::Equal)) => {
124 let value = Value::from(ident.clone());
125 window.move_view(3);
126 Stat::Assignment(value, Op::SubAssign, parse_expression(window)?)
127 },
128
129 (Some(ident @ Token::Identifier(_)), Some(Token::Star), Some(Token::Equal)) => {
130 let value = Value::from(ident.clone());
131 window.move_view(3);
132 Stat::Assignment(value, Op::MulAssign, parse_expression(window)?)
133 },
134
135 (Some(ident @ Token::Identifier(_)), Some(Token::Slash), Some(Token::Equal)) => {
136 let value = Value::from(ident.clone());
137 window.move_view(3);
138 Stat::Assignment(value, Op::DivAssign, parse_expression(window)?)
139 },
140
141 (Some(ident @ Token::Identifier(_)), Some(Token::Percent), Some(Token::Equal)) => {
142 let value = Value::from(ident.clone());
143 window.move_view(3);
144 Stat::Assignment(value, Op::ModAssign, parse_expression(window)?)
145 },
146
147 (Some(ident @ Token::Identifier(_)), Some(Token::Equal), Some(tok)) if *tok != Token::Equal => {
148 let value = Value::from(ident.clone());
149 window.move_view(2);
150 Stat::Assignment(value, Op::Assign, parse_expression(window)?)
151 },
152
153 _ => Stat::Expression(parse_expression(window)?)
154 };
155
156 Ok(statement)
157}
158
159fn extend_if(window: &mut VecWindow<Token>) -> Result<Stat, StatError>
160{
161 let condition = parse_expression(window)?;
162
163 if cfg!(debug_assertions) { println!("[Parse If] Condition: {:?}", condition) }
164
165 match window.get_value(0)
166 {
167 Some(Token::Then) => {
168 window.move_view(1);
169 },
170
171 tok => return Err(StatError::new(None,
172 ParseErrorKind::NoExtensionAvailable,
173 &format!("Can't find 'then' to extend if. Found: {:?}", tok)))
174 }
175
176 let mut body: Vec<Stat> = Vec::new();
177 let mut else_body: Vec<Stat> = Vec::new();
178 let mut parsing_else = false;
179 let mut hit_end = false;
180
181 while window.remaining_length() > 0
182 {
183 let value_tuple = (window.get_value(0), window.get_value(1));
184 let statement = match value_tuple
185 {
186 (Some(Token::Else), _) => {
187 if parsing_else
188 {
189 let error_stat = Stat::If(condition, body, Some(else_body));
190 return Err(StatError::new(Some(error_stat),
191 ParseErrorKind::RepeatedElseTokens,
192 "Found an else token after already finding one for this if!"))
193 }
194 window.move_view(1);
195 parsing_else = true;
196 continue
197 },
198 (Some(Token::End), _) => {
199 window.move_view(1);
200 hit_end = true;
201 break
202 },
203
204 _ => parse_statement(window)?
205 };
206
207 if parsing_else
208 {
209 else_body.push(statement)
210 }
211 else
212 {
213 body.push(statement)
214 }
215 }
216
217
218 let final_else = if else_body.is_empty() == false
219 {
220 Some(else_body)
221 }
222 else
223 {
224 None
225 };
226
227 let out_stat = Stat::If(condition, body, final_else);
228
229 if hit_end == false
230 {
231 return Err(StatError::new(Some(out_stat), ParseErrorKind::NoExtensionAvailable, "Didn't hit end while parsing if statement!"));
232 }
233
234 Ok(out_stat)
235}
236
237fn parse_expression(window: &mut VecWindow<Token>) -> Result<Box<Expr>, ExprError>
238{
239 Ok(Box::new(expr_and(window)?))
240}
241
242fn expr_and(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
243{
244 match expr_or(window)
245 {
246 Ok(expr) => {
248 match window.get_value(0)
249 {
250 Some(Token::And) => {
251 extend_and(expr, window)
252 },
253
254 _ => Ok(expr)
255 }
256 },
257 error @ Err(_) => {
259 error
260 },
261 }
262}
263
264fn extend_and(left: Expr, window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
265{
266 let op = match window.get_value(0)
267 {
268 Some(Token::And) => {
269 Op::And
270 },
271
272 _ => return Ok(left)
273 };
274
275 window.move_view(1);
276 match expr_or(window)
277 {
278 Ok(right) => {
279 let expr = Expr::BinaryOp(op, Box::new(left), Box::new(right));
281 extend_and(expr, window)
282 }
283
284 _ => Err(ExprError::new(Some(left), ParseErrorKind::NoExtensionAvailable, "Syntax error in parsing an and!"))
285 }
286}
287
288fn expr_or(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
289{
290 match expr_equality(window)
291 {
292 Ok(expr) => {
294 match window.get_value(0)
295 {
296 Some(Token::Or) => {
297 extend_or(expr, window)
298 },
299
300 _ => Ok(expr)
301 }
302 },
303 error @ Err(_) => {
305 error
306 },
307 }
308}
309
310fn extend_or(left: Expr, window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
311{
312 let op = match window.get_value(0)
313 {
314 Some(Token::Or) => {
315 Op::Or
316 },
317
318 _ => return Ok(left)
319 };
320
321 window.move_view(1);
322 match expr_equality(window)
323 {
324 Ok(right) => {
325 let expr = Expr::BinaryOp(op, Box::new(left), Box::new(right));
327 extend_or(expr, window)
328 }
329
330 _ => Err(ExprError::new(Some(left), ParseErrorKind::NoExtensionAvailable, "Syntax error in parsing an or!"))
331 }
332}
333
334fn expr_equality(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
335{
336 match expr_order(window)
337 {
338 Ok(expr) => {
340 let value_tuple = (window.get_value(0), window.get_value(1));
341 match value_tuple
342 {
343 (Some(Token::Equal), Some(Token::Equal)) |
344 (Some(Token::Exclam), Some(Token::Equal)) => {
345 extend_equality(expr, window)
346 },
347
348 _ => Ok(expr)
349 }
350 },
351 error @ Err(_) => {
353 error
354 },
355 }
356}
357
358fn extend_equality(left: Expr, window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
359{
360 let op = match (window.get_value(0), window.get_value(1))
361 {
362 (Some(Token::Equal), Some(Token::Equal)) => {
363 Op::Equal
364 },
365
366 (Some(Token::Exclam), Some(Token::Equal)) => {
367 Op::NotEqual
368 },
369
370 _ => return Ok(left)
371 };
372
373 window.move_view(2);
374 match expr_order(window)
375 {
376 Ok(right) => {
377 let expr = Expr::BinaryOp(op, Box::new(left), Box::new(right));
379 extend_equality(expr, window)
380 }
381
382 _ => Err(ExprError::new(Some(left), ParseErrorKind::NoExtensionAvailable, "Syntax error in parsing an equality!"))
383 }
384}
385
386fn expr_order(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
387{
388 match expr_additive(window)
389 {
390 Ok(expr) => {
392 let value_tuple = (window.get_value(0), window.get_value(1));
393 match value_tuple
394 {
395 (Some(Token::LAngleBrak), Some(Token::Equal)) |
396 (Some(Token::LAngleBrak), _) |
397 (Some(Token::RAngleBrak), Some(Token::Equal)) |
398 (Some(Token::RAngleBrak), _) => {
399 extend_order(expr, window)
400 },
401
402 _ => Ok(expr)
403 }
404 },
405 error @ Err(_) => {
407 error
408 },
409 }
410}
411
412fn extend_order(left: Expr, window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
413{
414 let op = match (window.get_value(0), window.get_value(1))
415 {
416 (Some(Token::LAngleBrak), Some(Token::Equal)) => {
417 window.move_view(2);
418 Op::LesserEq
419 },
420 (Some(Token::LAngleBrak), _) => {
421 window.move_view(1);
422 Op::Lesser
423 },
424
425 (Some(Token::RAngleBrak), Some(Token::Equal)) => {
426 window.move_view(2);
427 Op::GreaterEq
428 },
429 (Some(Token::RAngleBrak), _) => {
430 window.move_view(1);
431 Op::Greater
432 },
433
434 _ => return Ok(left)
435 };
436
437 match expr_additive(window)
438 {
439 Ok(right) => {
440 let expr = Expr::BinaryOp(op, Box::new(left), Box::new(right));
442 extend_order(expr, window)
443 }
444
445 _ => Err(ExprError::new(Some(left), ParseErrorKind::NoExtensionAvailable, "Syntax error in parsing an order!"))
446 }
447}
448
449fn expr_additive(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
450{
451 match expr_multiply(window)
452 {
453 Ok(expr) => {
455 match window.get_value(0)
456 {
457 Some(Token::Plus) |
458 Some(Token::Minus) => {
459 extend_additive(expr, window)
460 }
461
462 _ => Ok(expr)
463 }
464 },
465 error @ Err(_) => {
467 error
468 },
469 }
470}
471
472fn extend_additive(left: Expr, window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
473{
474 let op = match window.get_value(0)
475 {
476 Some(Token::Plus) => {
477 Op::Add
478 },
479
480 Some(Token::Minus) => {
481 Op::Sub
482 },
483
484 _ => return Ok(left)
485 };
486
487 window.move_view(1);
488 match expr_multiply(window)
489 {
490 Ok(right) => {
491 let expr = Expr::BinaryOp(op, Box::new(left), Box::new(right));
493 extend_additive(expr, window)
494 }
495
496 _ => Err(ExprError::new(Some(left), ParseErrorKind::NoExtensionAvailable, "Syntax error in parsing an additive!"))
497 }
498}
499
500fn expr_multiply(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
501{
502 match expr_exponent(window)
503 {
504 Ok(expr) => {
506 match window.get_value(0)
507 {
508 Some(Token::Slash) |
509 Some(Token::Star) |
510 Some(Token::Percent) => {
511 extend_multiply(expr, window)
512 },
513
514 _ => Ok(expr)
515 }
516 },
517 error @ Err(_) => {
519 error
520 },
521 }
522}
523
524fn extend_multiply(left: Expr, window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
525{
526 let op = match window.get_value(0)
527 {
528 Some(Token::Slash) => {
529 Op::Div
530 },
531
532 Some(Token::Star) => {
533 Op::Mul
534 },
535
536 Some(Token::Percent) => {
537 Op::Mod
538 },
539
540 _ => return Ok(left)
541 };
542
543 window.move_view(1);
544 match expr_exponent(window)
545 {
546 Ok(right) => {
547 let expr = Expr::BinaryOp(op, Box::new(left), Box::new(right));
549 extend_multiply(expr, window)
550 }
551
552 _ => Err(ExprError::new(Some(left), ParseErrorKind::NoExtensionAvailable, "Syntax error in parsing a multiply!"))
553 }
554}
555
556fn expr_exponent(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
558{
559 match expr_postfix(window)
560 {
561 Ok(expr) => {
563 match window.get_value(0)
564 {
565 Some(Token::Caret) => {
566 window.move_view(1);
567 let left = Box::new(expr);
568 let right = Box::new(expr_exponent(window)?);
569
570 Ok(Expr::BinaryOp(Op::Pow, left, right))
571 },
572 _ => Ok(expr)
573 }
574 },
575 error @ Err(_) => {
577 error
578 },
579 }
580}
581
582fn expr_postfix(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
583{
584 match expr_keyword(window)
585 {
586 Ok(expr) => Ok(extend_postfix(expr, window)),
588
589 error @ Err(_) => {
591 error
592 },
593 }
594}
595
596fn extend_postfix(expr: Expr, window: &mut VecWindow<Token>) -> Expr
597{
598 match (window.get_value(0), window.get_value(1))
599 {
600 (Some(Token::Exclam), Some(Token::Equal)) => expr,
601 (Some(Token::Exclam), _) => {
602 window.move_view(1);
603 extend_postfix(Expr::UnaryOp(Op::Fact, Box::new(expr)), window)
604 }
605 _ => expr
606 }
607}
608
609fn expr_keyword(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
610{
611 match expr_neg(window)
612 {
613 Err(ExprError { kind: ParseErrorKind::NoParseRuleMatch, .. }) => {
615 match window.get_value(0)
616 {
617 Some(Token::Abs) => {
618 window.move_view(1);
619 let operand = Box::new(expr_keyword(window)?);
620
621 Ok(Expr::UnaryOp(Op::Abs, operand))
622 },
623 Some(Token::Sqrt) => {
624 window.move_view(1);
625 let operand = Box::new(expr_keyword(window)?);
626
627 Ok(Expr::UnaryOp(Op::Sqrt, operand))
628 },
629 Some(Token::Sin) => {
630 window.move_view(1);
631 let operand = Box::new(expr_keyword(window)?);
632
633 Ok(Expr::UnaryOp(Op::Sin, operand))
634 },
635 Some(Token::Cos) => {
636 window.move_view(1);
637 let operand = Box::new(expr_keyword(window)?);
638
639 Ok(Expr::UnaryOp(Op::Cos, operand))
640 },
641 Some(Token::Tan) => {
642 window.move_view(1);
643 let operand = Box::new(expr_keyword(window)?);
644
645 Ok(Expr::UnaryOp(Op::Tan, operand))
646 },
647 Some(Token::Arcsin) => {
648 window.move_view(1);
649 let operand = Box::new(expr_keyword(window)?);
650
651 Ok(Expr::UnaryOp(Op::Arcsin, operand))
652 },
653 Some(Token::Arccos) => {
654 window.move_view(1);
655 let operand = Box::new(expr_keyword(window)?);
656
657 Ok(Expr::UnaryOp(Op::Arccos, operand))
658 },
659 Some(Token::Arctan) => {
660 window.move_view(1);
661 let operand = Box::new(expr_keyword(window)?);
662
663 Ok(Expr::UnaryOp(Op::Arctan, operand))
664 },
665 Some(Token::Not) => {
666 window.move_view(1);
667 let operand = Box::new(expr_keyword(window)?);
668
669 Ok(Expr::UnaryOp(Op::Not, operand))
670 },
671
672 _ => Err(ExprError::new(None,
673 ParseErrorKind::NoParseRuleMatch,
674 "In expr_keyword, can't find keyword operator after lower rule failed to match!"))
675 }
676 },
677 expr @ Ok(_) => {
679 expr
680 }
681 error @ Err(_) => {
683 error
684 },
685 }
686}
687
688fn expr_neg(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
689{
690 match expr_ident(window)
691 {
692 Err(ExprError { kind: ParseErrorKind::NoParseRuleMatch, .. }) => {
694 match window.get_value(0)
695 {
696 Some(Token::Minus) => {
697 window.move_view(1);
698 let operand = Box::new(expr_neg(window)?);
699
700 Ok(Expr::UnaryOp(Op::Negate, operand))
701 }
702
703 _ => {
704 Err(ExprError::new(None,
705 ParseErrorKind::NoParseRuleMatch,
706 "In expr_neg, can't find minus after lower rule failed to match!"))
707 }
708 }
709 },
710 expr @ Ok(_) => {
712 expr
713 }
714 error @ Err(_) => {
716 error
717 },
718 }
719}
720
721fn expr_ident(window: &mut VecWindow<Token>) -> Result<Expr, ExprError>
722{
723 let value_tuple = (window.get_value(0), window.get_value(1), window.get_value(2));
724 let expr = match value_tuple
725 {
726 (Some(ident @ Token::Identifier(_)), Some(Token::Plus), Some(Token::Plus)) => {
728 let value = Value::from(ident.clone());
729 window.move_view(3);
730
731 Expr::UnaryOp(Op::PostInc, Box::new(Expr::Value(value)))
732 },
733 (Some(ident @ Token::Identifier(_)), Some(Token::Minus), Some(Token::Minus)) => {
734 let value = Value::from(ident.clone());
735 window.move_view(3);
736
737 Expr::UnaryOp(Op::PostDec, Box::new(Expr::Value(value)))
738 },
739
740 (Some(Token::Plus), Some(Token::Plus), Some(ident @ Token::Identifier(_))) => {
742 let value = Value::from(ident.clone());
743 window.move_view(3);
744
745 Expr::UnaryOp(Op::PreInc, Box::new(Expr::Value(value)))
746 },
747 (Some(Token::Minus), Some(Token::Minus), Some(ident @ Token::Identifier(_))) => {
748 let value = Value::from(ident.clone());
749 window.move_view(3);
750
751 Expr::UnaryOp(Op::PreDec, Box::new(Expr::Value(value)))
752 },
753
754 _ => Expr::Value(parse_value(window)?)
756 };
757
758 Ok(expr)
759}
760
761
762fn parse_value(window: &mut VecWindow<Token>) -> Result<Value, ExprError>
763{
764 match window.get_value(0)
765 {
766 Some(tok @ Token::StringToken(_)) |
767 Some(tok @ Token::YololNum(_)) |
768 Some(tok @ Token::Identifier(_)) => {
769 let tok = tok.clone();
770 window.move_view(1);
771
772 Ok(Value::from(tok))
773 },
774
775 Some(Token::LParen) => {
776 window.move_view(1);
777 let output = parse_expression(window)?;
778
779 match window.get_value(0)
780 {
781 Some(Token::RParen) => {
782 window.move_view(1);
783 Ok(Value::Group(output))
784 },
785
786 _ => Err(ExprError::new(Some(*output), ParseErrorKind::UnbalancedParenthesis, "Saw LParen, parsed expr, found no RParen!"))
787 }
788 },
789
790 _ => Err(ExprError::new(None, ParseErrorKind::NoParseRuleMatch, "No match while parsing value!"))
791 }
792}
793
794