1use std::fmt::{Display, Formatter, Write as _};
2use std::mem;
3use crate::lexer::CodePosition;
4use crate::parser::ast::AST;
5use crate::parser::ParsingError;
6
7#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
8pub enum OperatorType {
9 All,
10 General,
11 Math,
12 Condition,
13}
14
15impl OperatorType {
16 pub fn is_compatible_with(&self, operator_type: OperatorType) -> bool {
17 *self == OperatorType::All || operator_type == OperatorType::General || *self == operator_type
18 }
19}
20
21impl Display for OperatorType {
22 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
23 f.write_str(match self {
24 OperatorType::All => "ALL",
25 OperatorType::General => "GENERAL",
26 OperatorType::Math => "MATH",
27 OperatorType::Condition => "CONDITION",
28 })
29 }
30}
31
32#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
33pub enum Operator {
34 Non,
36 Len,
37 DeepCopy,
38 Concat,
39 Spaceship,
40 Elvis,
41 NullCoalescing,
42 InlineIf,
43
44 MathNon,
46 Pow,
47 Pos,
48 Inv,
49 BitwiseNot,
50 Inc,
51 Dec,
52 Mul,
53 Div,
54 TruncDiv,
55 FloorDiv,
56 CeilDiv,
57 Mod,
58 Add,
59 Sub,
60 Lshift,
61 Rshift,
62 Rzshift,
63 BitwiseAnd,
64 BitwiseXor,
65 BitwiseOr,
66
67 ConditionalNon,
69 Not,
70 InstanceOf,
71 Equals,
72 NotEquals,
73 Matches,
74 NotMatches,
75 StrictEquals,
76 StrictNotEquals,
77 LessThan,
78 GreaterThan,
79 LessThanOrEquals,
80 GreaterThanOrEquals,
81 And,
82 Or,
83
84 Comma,
87 GetItem,
88 OptionalGetItem,
89 Slice,
90 OptionalSlice,
91 MemberAccess,
92 MemberAccessThis,
94 OptionalMemberAccess,
95 MemberAccessPointer,
96}
97
98impl Operator {
99 pub fn symbol(&self) -> &'static str {
100 match self {
101 Operator::Non => "",
103 Operator::Len => "@",
104 Operator::DeepCopy => "^",
105 Operator::Concat => "|||",
106 Operator::Spaceship => "<=>",
107 Operator::Elvis => "?:",
108 Operator::NullCoalescing => "??",
109 Operator::InlineIf => "?...:",
110
111 Operator::MathNon => "",
113 Operator::Pow => "**",
114 Operator::Pos => "+",
115 Operator::Inv => "-",
116 Operator::BitwiseNot => "~",
117 Operator::Inc => "+|",
118 Operator::Dec => "-|",
119 Operator::Mul => "*",
120 Operator::Div => "/",
121 Operator::TruncDiv => "~/",
122 Operator::FloorDiv => "//",
123 Operator::CeilDiv => "^/",
124 Operator::Mod => "%",
125 Operator::Add => "+",
126 Operator::Sub => "-",
127 Operator::Lshift => "<<",
128 Operator::Rshift => ">>",
129 Operator::Rzshift => ">>>",
130 Operator::BitwiseAnd => "&",
131 Operator::BitwiseXor => "^",
132 Operator::BitwiseOr => "|",
133
134 Operator::ConditionalNon => "",
136 Operator::Not => "!",
137 Operator::InstanceOf => "~~",
138 Operator::Equals => "==",
139 Operator::NotEquals => "!=",
140 Operator::Matches => "=~",
141 Operator::NotMatches => "!=~",
142 Operator::StrictEquals => "===",
143 Operator::StrictNotEquals => "!==",
144 Operator::LessThan => "<",
145 Operator::GreaterThan => ">",
146 Operator::LessThanOrEquals => "<=",
147 Operator::GreaterThanOrEquals => ">=",
148 Operator::And => "&&",
149 Operator::Or => "||",
150
151 Operator::Comma => ",",
153 Operator::GetItem => "[...]",
154 Operator::OptionalGetItem => "?.[...]",
155 Operator::Slice => "[...:...]",
156 Operator::OptionalSlice => "?.[...:...]",
157 Operator::MemberAccess => "::",
158 Operator::MemberAccessThis => "::",
159 Operator::OptionalMemberAccess => "?::",
160 Operator::MemberAccessPointer => "->",
161 }
162 }
163
164 pub fn arity(&self) -> usize {
165 match self {
166 Operator::Non => 1,
168 Operator::Len => 1,
169 Operator::DeepCopy => 1,
170 Operator::Concat => 2,
171 Operator::Spaceship => 2,
172 Operator::Elvis => 2,
173 Operator::NullCoalescing => 2,
174 Operator::InlineIf => 3,
175
176 Operator::MathNon => 1,
178 Operator::Pow => 2,
179 Operator::Pos => 1,
180 Operator::Inv => 1,
181 Operator::BitwiseNot => 1,
182 Operator::Inc => 1,
183 Operator::Dec => 1,
184 Operator::Mul => 2,
185 Operator::Div => 2,
186 Operator::TruncDiv => 2,
187 Operator::FloorDiv => 2,
188 Operator::CeilDiv => 2,
189 Operator::Mod => 2,
190 Operator::Add => 2,
191 Operator::Sub => 2,
192 Operator::Lshift => 2,
193 Operator::Rshift => 2,
194 Operator::Rzshift => 2,
195 Operator::BitwiseAnd => 2,
196 Operator::BitwiseXor => 2,
197 Operator::BitwiseOr => 2,
198
199 Operator::ConditionalNon => 1,
201 Operator::Not => 1,
202 Operator::InstanceOf => 2,
203 Operator::Equals => 2,
204 Operator::NotEquals => 2,
205 Operator::Matches => 2,
206 Operator::NotMatches => 2,
207 Operator::StrictEquals => 2,
208 Operator::StrictNotEquals => 2,
209 Operator::LessThan => 2,
210 Operator::GreaterThan => 2,
211 Operator::LessThanOrEquals => 2,
212 Operator::GreaterThanOrEquals => 2,
213 Operator::And => 2,
214 Operator::Or => 2,
215
216 Operator::Comma => 2,
218 Operator::GetItem => 2,
219 Operator::OptionalGetItem => 2,
220 Operator::Slice => 3,
221 Operator::OptionalSlice => 3,
222 Operator::MemberAccess => 2,
223 Operator::MemberAccessThis => 1,
224 Operator::OptionalMemberAccess => 2,
225 Operator::MemberAccessPointer => 2,
226 }
227 }
228
229 pub fn is_unary(&self) -> bool {
230 self.arity() == 1
231 }
232
233 pub fn is_binary(&self) -> bool {
234 self.arity() == 2
235 }
236
237 pub fn is_ternary(&self) -> bool {
238 self.arity() == 3
239 }
240
241 pub fn precedence(&self) -> isize {
242 match self {
243 Operator::Non => -1,
245 Operator::Len => 1,
246 Operator::DeepCopy => 1,
247 Operator::Concat => 5,
248 Operator::Spaceship => 10,
249 Operator::Elvis => 13,
250 Operator::NullCoalescing => 13,
251 Operator::InlineIf => 14,
252
253 Operator::MathNon => -1,
255 Operator::Pow => 2,
256 Operator::Pos => 3,
257 Operator::Inv => 3,
258 Operator::BitwiseNot => 3,
259 Operator::Inc => 3,
260 Operator::Dec => 3,
261 Operator::Mul => 4,
262 Operator::Div => 4,
263 Operator::TruncDiv => 4,
264 Operator::FloorDiv => 4,
265 Operator::CeilDiv => 4,
266 Operator::Mod => 4,
267 Operator::Add => 5,
268 Operator::Sub => 5,
269 Operator::Lshift => 6,
270 Operator::Rshift => 6,
271 Operator::Rzshift => 6,
272 Operator::BitwiseAnd => 7,
273 Operator::BitwiseXor => 8,
274 Operator::BitwiseOr => 9,
275
276 Operator::ConditionalNon => -1,
278 Operator::Not => 3,
279 Operator::InstanceOf => 10,
280 Operator::Equals => 10,
281 Operator::NotEquals => 10,
282 Operator::Matches => 10,
283 Operator::NotMatches => 10,
284 Operator::StrictEquals => 10,
285 Operator::StrictNotEquals => 10,
286 Operator::LessThan => 10,
287 Operator::GreaterThan => 10,
288 Operator::LessThanOrEquals => 10,
289 Operator::GreaterThanOrEquals => 10,
290 Operator::And => 11,
291 Operator::Or => 12,
292
293 Operator::Comma => 15,
295 Operator::GetItem => 0,
296 Operator::OptionalGetItem => 0,
297 Operator::Slice => 0,
298 Operator::OptionalSlice => 0,
299 Operator::MemberAccess => 0,
300 Operator::MemberAccessThis => 0,
301 Operator::OptionalMemberAccess => 0,
302 Operator::MemberAccessPointer => 0,
303 }
304 }
305
306 pub fn lazy_evaluation(&self) -> bool {
307 matches!(
308 self,
309
310 Operator::Elvis |
312 Operator::NullCoalescing |
313 Operator::InlineIf |
314
315 Operator::And |
317 Operator::Or |
318
319 Operator::MemberAccess |
321 Operator::MemberAccessThis |
322 Operator::OptionalMemberAccess |
323 Operator::MemberAccessPointer
324 )
325 }
326
327 pub fn operator_type(&self) -> OperatorType {
328 match self {
329 Operator::Non |
331 Operator::Len |
332 Operator::DeepCopy |
333 Operator::Concat |
334 Operator::Spaceship |
335 Operator::Elvis |
336 Operator::NullCoalescing |
337 Operator::InlineIf => OperatorType::General,
338
339 Operator::MathNon |
341 Operator::Pow |
342 Operator::Pos |
343 Operator::Inv |
344 Operator::BitwiseNot |
345 Operator::Inc |
346 Operator::Dec |
347 Operator::Mul |
348 Operator::Div |
349 Operator::TruncDiv |
350 Operator::FloorDiv |
351 Operator::CeilDiv |
352 Operator::Mod |
353 Operator::Add |
354 Operator::Sub |
355 Operator::Lshift |
356 Operator::Rshift |
357 Operator::Rzshift |
358 Operator::BitwiseAnd |
359 Operator::BitwiseXor |
360 Operator::BitwiseOr => OperatorType::Math,
361
362 Operator::ConditionalNon |
364 Operator::Not |
365 Operator::InstanceOf |
366 Operator::Equals |
367 Operator::NotEquals |
368 Operator::Matches |
369 Operator::NotMatches |
370 Operator::StrictEquals |
371 Operator::StrictNotEquals |
372 Operator::LessThan |
373 Operator::GreaterThan |
374 Operator::LessThanOrEquals |
375 Operator::GreaterThanOrEquals |
376 Operator::And |
377 Operator::Or => OperatorType::Condition,
378
379 Operator::Comma |
381 Operator::GetItem |
382 Operator::OptionalGetItem |
383 Operator::Slice |
384 Operator::OptionalSlice |
385 Operator::MemberAccess |
386 Operator::MemberAccessThis |
387 Operator::OptionalMemberAccess |
388 Operator::MemberAccessPointer => OperatorType::All,
389 }
390 }
391}
392
393impl Display for Operator {
394 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
395 f.write_str(match self {
396 Operator::Non => "NON",
398 Operator::Len => "LEN",
399 Operator::DeepCopy => "DEEP_COPY",
400 Operator::Concat => "CONCAT",
401 Operator::Spaceship => "SPACESHIP",
402 Operator::Elvis => "ELVIS",
403 Operator::NullCoalescing => "NULL_COALESCING",
404 Operator::InlineIf => "INLINE_IF",
405
406 Operator::MathNon => "MATH_NON",
408 Operator::Pow => "POW",
409 Operator::Pos => "POS",
410 Operator::Inv => "INV",
411 Operator::BitwiseNot => "BITWISE_NOT",
412 Operator::Inc => "INC",
413 Operator::Dec => "DEC",
414 Operator::Mul => "MUL",
415 Operator::Div => "DIV",
416 Operator::TruncDiv => "TRUNC_DIV",
417 Operator::FloorDiv => "FLOOR_DIV",
418 Operator::CeilDiv => "CEIL_DIV",
419 Operator::Mod => "MOD",
420 Operator::Add => "ADD",
421 Operator::Sub => "SUB",
422 Operator::Lshift => "LSHIFT",
423 Operator::Rshift => "RSHIFT",
424 Operator::Rzshift => "RZSHIFT",
425 Operator::BitwiseAnd => "BITWISE_AND",
426 Operator::BitwiseXor => "BITWISE_XOR",
427 Operator::BitwiseOr => "BITWISE_OR",
428
429 Operator::ConditionalNon => "CONDITIONAL_NON",
431 Operator::Not => "NOT",
432 Operator::InstanceOf => "INSTANCE_OF",
433 Operator::Equals => "EQUALS",
434 Operator::NotEquals => "NOT_EQUALS",
435 Operator::Matches => "MATCHES",
436 Operator::NotMatches => "NOT_MATCHES",
437 Operator::StrictEquals => "STRICT_EQUALS",
438 Operator::StrictNotEquals => "STRICT_NOT_EQUALS",
439 Operator::LessThan => "LESS_THAN",
440 Operator::GreaterThan => "GREATER_THAN",
441 Operator::LessThanOrEquals => "LESS_THAN_OR_EQUALS",
442 Operator::GreaterThanOrEquals => "GREATER_THAN_OR_EQUALS",
443 Operator::And => "AND",
444 Operator::Or => "OR",
445
446 Operator::Comma => "COMMA",
448 Operator::GetItem => "GET_ITEM",
449 Operator::OptionalGetItem => "OPTIONAL_GET_ITEM",
450 Operator::Slice => "SLICE",
451 Operator::OptionalSlice => "OPTIONAL_SLICE",
452 Operator::MemberAccess => "MEMBER_ACCESS",
453 Operator::MemberAccessThis => "MEMBER_ACCESS_THIS",
454 Operator::OptionalMemberAccess => "OPTIONAL_MEMBER_ACCESS",
455 Operator::MemberAccessPointer => "MEMBER_ACCESS_POINTER",
456 })
457 }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461pub struct FunctionDefinition {
462 function_name: Option<Box<str>>,
463 overloaded: bool,
464 combinator: bool,
465 doc_comment: Option<Box<str>>,
466 return_value_type_constraint: Option<Box<str>>,
467 function_body: AST,
468}
469
470impl FunctionDefinition {
471 pub fn new(function_name: Option<Box<str>>, overloaded: bool, combinator: bool, doc_comment: Option<Box<str>>, return_value_type_constraint: Option<Box<str>>, function_body: AST) -> Self {
472 Self { function_name, overloaded, combinator, doc_comment, return_value_type_constraint, function_body }
473 }
474
475 pub fn function_name(&self) -> Option<&str> {
476 self.function_name.as_deref()
477 }
478
479 pub fn overloaded(&self) -> bool {
480 self.overloaded
481 }
482
483 pub fn combinator(&self) -> bool {
484 self.combinator
485 }
486
487 pub fn doc_comment(&self) -> Option<&str> {
488 self.doc_comment.as_deref()
489 }
490
491 pub fn return_value_type_constraint(&self) -> Option<&str> {
492 self.return_value_type_constraint.as_deref()
493 }
494
495 pub fn function_body(&self) -> &AST {
496 &self.function_body
497 }
498}
499
500#[derive(Debug, Clone, PartialEq)]
501pub struct StructMember {
502 name: Box<str>,
503 type_constraint: Option<Box<str>>,
504}
505
506impl StructMember {
507 pub fn new(name: Box<str>, type_constraint: Option<Box<str>>) -> Self {
508 Self { name, type_constraint }
509 }
510
511 pub fn name(&self) -> &str {
512 &self.name
513 }
514
515 pub fn type_constraint(&self) -> Option<&str> {
516 self.type_constraint.as_deref()
517 }
518}
519
520#[derive(Debug, Clone, PartialEq)]
521pub struct StructDefinition {
522 struct_name: Option<Box<str>>,
523
524 members: Vec<StructMember>,
525}
526
527impl StructDefinition {
528 pub fn new(struct_name: Option<Box<str>>, members: Vec<StructMember>) -> Self {
529 Self { struct_name, members }
530 }
531
532 pub fn struct_name(&self) -> Option<&str> {
533 self.struct_name.as_deref()
534 }
535
536 pub fn members(&self) -> &[StructMember] {
537 &self.members
538 }
539}
540
541#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
542pub enum Visibility {
543 Private,
544 Protected,
545 Public,
546}
547
548impl Visibility {
549 pub fn from_symbol(symbol: u8) -> Option<Visibility> {
550 match symbol {
551 b'-' => Some(Visibility::Private),
552 b'~' => Some(Visibility::Protected),
553 b'+' => Some(Visibility::Public),
554
555 _ => None,
556 }
557 }
558
559 pub fn from_keyword(keyword: &str) -> Option<Visibility> {
560 match keyword {
561 "private" => Some(Visibility::Private),
562 "protected" => Some(Visibility::Protected),
563 "public" => Some(Visibility::Public),
564
565 _ => None,
566 }
567 }
568
569 pub fn symbol(&self) -> &'static str {
570 match self {
571 Visibility::Private => "-",
572 Visibility::Protected => "~",
573 Visibility::Public => "+",
574 }
575 }
576}
577
578#[derive(Debug, Clone, PartialEq)]
579pub struct ClassMember {
580 name: Box<str>,
581 type_constraint: Option<Box<str>>,
582 value: Option<Node>,
583 final_flag: bool,
584 visibility: Visibility,
585}
586
587impl ClassMember {
588 pub fn new(name: Box<str>, type_constraint: Option<Box<str>>, value: Option<Node>, final_flag: bool, visibility: Visibility) -> Self {
589 Self { name, type_constraint, value, final_flag, visibility }
590 }
591
592 pub fn name(&self) -> &str {
593 &self.name
594 }
595
596 pub fn type_constraint(&self) -> Option<&str> {
597 self.type_constraint.as_deref()
598 }
599
600 pub fn value(&self) -> Option<&Node> {
601 self.value.as_ref()
602 }
603
604 pub fn final_flag(&self) -> bool {
605 self.final_flag
606 }
607
608 pub fn visibility(&self) -> Visibility {
609 self.visibility
610 }
611}
612
613#[derive(Debug, Clone, PartialEq)]
614pub struct Method {
615 name: Box<str>,
616 body: Node,
617 override_flag: bool,
618 visibility: Visibility,
619}
620
621impl Method {
622 pub fn new(name: Box<str>, definition: Node, override_flag: bool, visibility: Visibility) -> Self {
623 Self { name, body: definition, override_flag, visibility }
624 }
625
626 pub fn name(&self) -> &str {
627 &self.name
628 }
629
630 pub fn body(&self) -> &Node {
631 &self.body
632 }
633
634 pub fn override_flag(&self) -> bool {
635 self.override_flag
636 }
637
638 pub fn visibility(&self) -> Visibility {
639 self.visibility
640 }
641}
642
643#[derive(Debug, Clone, PartialEq)]
644pub struct Constructor {
645 body: Node,
646 visibility: Visibility,
647}
648
649impl Constructor {
650 pub fn new(definition: Node, visibility: Visibility) -> Self {
651 Self { body: definition, visibility }
652 }
653
654 pub fn body(&self) -> &Node {
655 &self.body
656 }
657
658 pub fn visibility(&self) -> Visibility {
659 self.visibility
660 }
661}
662
663#[derive(Debug, Clone, PartialEq)]
664pub struct ClassDefinition {
665 class_name: Option<Box<str>>,
666
667 static_members: Vec<ClassMember>,
668
669 members: Vec<ClassMember>,
670
671 methods: Vec<Method>,
673
674 constructors: Vec<Constructor>,
675
676 parent_classes: Vec<Node>,
678}
679
680impl ClassDefinition {
681 pub fn new(
682 class_name: Option<Box<str>>,
683 static_members: Vec<ClassMember>,
684 members: Vec<ClassMember>,
685 methods: Vec<Method>,
686 constructors: Vec<Constructor>,
687 parent_classes: Vec<Node>,
688 ) -> Self {
689 if members.iter().any(|member| member.value.is_some()) {
690 panic!("Non-static class members can not have a default value");
691 }
692
693 Self {
694 class_name,
695 static_members,
696 members,
697 methods,
698 constructors,
699 parent_classes,
700 }
701 }
702
703 pub fn class_name(&self) -> Option<&str> {
704 self.class_name.as_deref()
705 }
706
707 pub fn static_members(&self) -> &[ClassMember] {
708 &self.static_members
709 }
710
711 pub fn members(&self) -> &[ClassMember] {
712 &self.members
713 }
714
715 pub fn methods(&self) -> &[Method] {
716 &self.methods
717 }
718
719 pub fn constructors(&self) -> &[Constructor] {
720 &self.constructors
721 }
722
723 pub fn parent_classes(&self) -> &[Node] {
724 &self.parent_classes
725 }
726}
727
728#[derive(Debug, Clone, PartialEq)]
729pub struct OperationExpression {
730 left_side_operand: Option<Box<Node>>,
731 middle_operand: Option<Box<Node>>,
732 right_side_operand: Option<Box<Node>>,
733 operator: Operator,
734 operator_type: OperatorType,
735}
736
737impl OperationExpression {
738 pub fn new(
739 left_side_operand: Option<Box<Node>>,
740 middle_operand: Option<Box<Node>>,
741 right_side_operand: Option<Box<Node>>,
742 operator: Operator,
743 operator_type: OperatorType,
744 ) -> Self {
745 let arity = operator.arity();
746 if matches!(
747 arity,
748
749 1 if left_side_operand.is_none() || middle_operand.is_some() || right_side_operand.is_some(),
750 ) {
751 panic!("Invalid operand count for unary operator");
752 }
753
754 if matches!(
755 arity,
756
757 2 if left_side_operand.is_none() || middle_operand.is_some() || right_side_operand.is_none(),
758 ) {
759 panic!("Invalid operand count for binary operator");
760 }
761
762 if matches!(
763 arity,
764
765 3 if left_side_operand.is_none() || middle_operand.is_none() || right_side_operand.is_none(),
766 ) {
767 panic!("Invalid operand count for ternary operator");
768 }
769
770 if !operator.operator_type().is_compatible_with(operator_type) {
771 panic!("Node type is not compatible with the operator");
772 }
773
774 Self {
775 left_side_operand,
776 middle_operand,
777 right_side_operand,
778 operator,
779 operator_type,
780 }
781 }
782
783 pub fn left_side_operand(&self) -> Option<&Node> {
784 self.left_side_operand.as_deref()
785 }
786
787 pub fn middle_operand(&self) -> Option<&Node> {
788 self.middle_operand.as_deref()
789 }
790
791 pub fn right_side_operand(&self) -> Option<&Node> {
792 self.right_side_operand.as_deref()
793 }
794
795 pub fn operator(&self) -> Operator {
796 self.operator
797 }
798
799 pub fn operator_type(&self) -> OperatorType {
800 self.operator.operator_type()
801 }
802}
803
804#[derive(Debug, Clone, PartialEq)]
805pub struct ConditionalNode {
806 node: Node,
807}
808
809impl ConditionalNode {
810 pub fn new(node: Node) -> Self {
811 if !matches!(node.node_data, NodeData::Condition{..}) {
812 panic!("Node type is not compatible with this node");
813 }
814
815 Self { node }
816 }
817
818 pub fn node(&self) -> &Node {
819 &self.node
820 }
821}
822
823#[derive(Debug, Clone, PartialEq)]
824pub enum NodeData {
825 List,
826
827 ParsingError {
828 error: ParsingError,
829 message: Box<str>,
830 },
831
832 Assignment,
833
834 EscapeSequence(char),
835 UnicodeEscapeSequence(Box<str>),
836
837 UnprocessedVariableName(Box<str>),
838 VariableName {
839 variable_name: Box<str>,
840 type_constraint: Option<Box<str>>,
841 },
842
843 ArgumentSeparator(Box<str>),
844
845 FunctionCall(Box<str>),
846 FunctionCallPreviousNodeValue {
847 leading_whitespace: Box<str>,
848 trailing_whitespace: Box<str>,
849 },
850
851 FunctionDefinition(Box<FunctionDefinition>),
852
853 IfStatementPartIf {
854 if_body: AST,
855 condition: Box<ConditionalNode>,
856 },
857 IfStatementPartElse(AST),
858 IfStatement,
859
860 LoopStatementPartLoop(AST),
861 LoopStatementPartWhile {
862 loop_body: AST,
863 condition: Box<ConditionalNode>,
864 },
865 LoopStatementPartUntil {
866 loop_body: AST,
867 condition: Box<ConditionalNode>,
868 },
869 LoopStatementPartRepeat {
870 loop_body: AST,
871 var_pointer_node: Box<Node>,
872 repeat_count_node: Box<Node>,
873 },
874 LoopStatementPartForEach {
875 loop_body: AST,
876 var_pointer_node: Box<Node>,
877 composite_or_text_node: Box<Node>,
878 },
879 LoopStatementPartElse(AST),
880 LoopStatement,
881
882 TryStatementPartTry(AST),
883 TryStatementPartSoftTry(AST),
884 TryStatementPartNonTry(AST),
885 TryStatementPartCatch {
886 try_body: AST,
887 errors: Option<Vec<Node>>,
888 },
889 TryStatementPartElse(AST),
890 TryStatementPartFinally(AST),
891 TryStatement,
892
893 ContinueBreakStatement {
894 number_node: Option<Box<Node>>,
895 continue_node: bool,
896 },
897
898 Operation(OperationExpression),
899 Math(OperationExpression),
900 Condition(OperationExpression),
901
902 Return,
903 Throw,
904
905 IntValue(i32),
906 LongValue(i64),
907 FloatValue(f32),
908 DoubleValue(f64),
909 CharValue(char),
910 TextValue(Box<str>),
911 NullValue,
912 VoidValue,
913 ArrayValue,
914
915 StructDefinition(Box<StructDefinition>),
916
917 ClassDefinition(Box<ClassDefinition>),
918}
919
920#[derive(Debug, Clone)]
921pub struct Node {
922 pos: CodePosition,
923 child_nodes: Vec<Node>,
924 node_data: NodeData,
925}
926
927impl Node {
928 pub fn new_list_node(child_nodes: Vec<Node>) -> Node {
929 let pos = if child_nodes.is_empty() {
930 CodePosition::EMPTY
931 }else {
932 child_nodes.first().unwrap().pos().combine(&child_nodes.last().unwrap().pos())
933 };
934
935 Self {
936 pos,
937 child_nodes,
938 node_data: NodeData::List,
939 }
940 }
941
942 pub fn new_parsing_error_node(pos: CodePosition, error: ParsingError, message: impl Into<Box<str>>) -> Node {
943 Self {
944 pos,
945 child_nodes: Default::default(),
946 node_data: NodeData::ParsingError {
947 error,
948 message: message.into(),
949 },
950 }
951 }
952
953 pub fn new_assignment_node(lvalue: Node, rvalue: Node) -> Node {
954 let pos = lvalue.pos.combine(&rvalue.pos);
955
956 let child_nodes = vec![lvalue, rvalue];
957
958 Self {
959 pos,
960 child_nodes,
961 node_data: NodeData::Assignment,
962 }
963 }
964
965 pub fn new_escape_sequence_node(pos: CodePosition, char: char) -> Node {
966 Self {
967 pos,
968 child_nodes: Default::default(),
969 node_data: NodeData::EscapeSequence(char),
970 }
971 }
972
973 pub fn new_unicode_escape_sequence_node(pos: CodePosition, hex_codepoint: impl Into<Box<str>>) -> Node {
974 Self {
975 pos,
976 child_nodes: Default::default(),
977 node_data: NodeData::UnicodeEscapeSequence(hex_codepoint.into()),
978 }
979 }
980
981 pub fn new_unprocessed_variable_name_node(pos: CodePosition, variable_name: impl Into<Box<str>>) -> Node {
982 Self {
983 pos,
984 child_nodes: Default::default(),
985 node_data: NodeData::UnprocessedVariableName(variable_name.into()),
986 }
987 }
988
989 pub fn new_variable_name_node(pos: CodePosition, variable_name: impl Into<Box<str>>, type_constraint: Option<Box<str>>) -> Node {
990 Self {
991 pos,
992 child_nodes: Default::default(),
993 node_data: NodeData::VariableName {
994 variable_name: variable_name.into(),
995 type_constraint,
996 },
997 }
998 }
999
1000 pub fn new_argument_separator_node(pos: CodePosition, original_text: impl Into<Box<str>>) -> Node {
1001 Self {
1002 pos,
1003 child_nodes: Default::default(),
1004 node_data: NodeData::ArgumentSeparator(original_text.into()),
1005 }
1006 }
1007
1008 pub fn new_function_call_node(pos: CodePosition, argument_list: Vec<Node>, function_name: impl Into<Box<str>>) -> Node {
1009 Self {
1010 pos,
1011 child_nodes: argument_list,
1012 node_data: NodeData::FunctionCall(function_name.into()),
1013 }
1014 }
1015
1016 pub fn new_function_call_previous_node_value_node(
1017 pos: CodePosition,
1018 leading_whitespace: impl Into<Box<str>>,
1019 trailing_whitespace: impl Into<Box<str>>,
1020 argument_list: Vec<Node>,
1021 ) -> Node {
1022 Self {
1023 pos,
1024 child_nodes: argument_list,
1025 node_data: NodeData::FunctionCallPreviousNodeValue {
1026 leading_whitespace: leading_whitespace.into(),
1027 trailing_whitespace: trailing_whitespace.into(),
1028 },
1029 }
1030 }
1031
1032 pub fn new_function_definition_node(pos: CodePosition, function_definition: FunctionDefinition, parameter_list: Vec<Node>) -> Node {
1033 Self {
1034 pos,
1035 child_nodes: parameter_list,
1036 node_data: NodeData::FunctionDefinition(Box::new(function_definition)),
1037 }
1038 }
1039
1040 pub fn new_if_statement_part_if_node(pos: CodePosition, if_body: AST, condition: ConditionalNode) -> Node {
1041 Self {
1042 pos,
1043 child_nodes: Default::default(),
1044 node_data: NodeData::IfStatementPartIf {
1045 if_body,
1046 condition: Box::new(condition),
1047 },
1048 }
1049 }
1050
1051 pub fn new_if_statement_part_else_node(pos: CodePosition, if_body: AST) -> Node {
1052 Self {
1053 pos,
1054 child_nodes: Default::default(),
1055 node_data: NodeData::IfStatementPartElse(if_body),
1056 }
1057 }
1058
1059 pub fn new_if_statement_node(pos: CodePosition, nodes: Vec<Node>) -> Node {
1060 if nodes.iter().any(|node| {
1061 !matches!(node.node_data, NodeData::IfStatementPartIf{..}) &&
1062 !matches!(node.node_data, NodeData::IfStatementPartElse(..))
1063 }) {
1064 panic!("Node type is not compatible with this node");
1065 }
1066
1067 Self {
1068 pos,
1069 child_nodes: nodes,
1070 node_data: NodeData::IfStatement,
1071 }
1072 }
1073
1074 pub fn new_loop_statement_part_loop_node(pos: CodePosition, loop_body: AST) -> Node {
1075 Self {
1076 pos,
1077 child_nodes: Default::default(),
1078 node_data: NodeData::LoopStatementPartLoop(loop_body),
1079 }
1080 }
1081
1082 pub fn new_loop_statement_part_while_node(pos: CodePosition, loop_body: AST, condition: ConditionalNode) -> Node {
1083 Self {
1084 pos,
1085 child_nodes: Default::default(),
1086 node_data: NodeData::LoopStatementPartWhile {
1087 loop_body,
1088 condition: Box::new(condition),
1089 },
1090 }
1091 }
1092
1093 pub fn new_loop_statement_part_until_node(pos: CodePosition, loop_body: AST, condition: ConditionalNode) -> Node {
1094 Self {
1095 pos,
1096 child_nodes: Default::default(),
1097 node_data: NodeData::LoopStatementPartUntil {
1098 loop_body,
1099 condition: Box::new(condition),
1100 },
1101 }
1102 }
1103
1104 pub fn new_loop_statement_part_repeat_node(pos: CodePosition, loop_body: AST, var_pointer_node: Node, repeat_count_node: Node) -> Node {
1105 Self {
1106 pos,
1107 child_nodes: Default::default(),
1108 node_data: NodeData::LoopStatementPartRepeat {
1109 loop_body,
1110 var_pointer_node: Box::new(var_pointer_node),
1111 repeat_count_node: Box::new(repeat_count_node),
1112 },
1113 }
1114 }
1115
1116 pub fn new_loop_statement_part_for_each_node(pos: CodePosition, loop_body: AST, var_pointer_node: Node, composite_or_text_node: Node) -> Node {
1117 Self {
1118 pos,
1119 child_nodes: Default::default(),
1120 node_data: NodeData::LoopStatementPartForEach {
1121 loop_body,
1122 var_pointer_node: Box::new(var_pointer_node),
1123 composite_or_text_node: Box::new(composite_or_text_node),
1124 },
1125 }
1126 }
1127
1128 pub fn new_loop_statement_part_else_node(pos: CodePosition, loop_body: AST) -> Node {
1129 Self {
1130 pos,
1131 child_nodes: Default::default(),
1132 node_data: NodeData::LoopStatementPartElse(loop_body),
1133 }
1134 }
1135
1136 pub fn new_loop_statement_node(pos: CodePosition, nodes: Vec<Node>) -> Node {
1137 if nodes.iter().any(|node| {
1138 !matches!(node.node_data, NodeData::LoopStatementPartLoop(..)) &&
1139 !matches!(node.node_data, NodeData::LoopStatementPartWhile{..}) &&
1140 !matches!(node.node_data, NodeData::LoopStatementPartUntil{..}) &&
1141 !matches!(node.node_data, NodeData::LoopStatementPartRepeat{..}) &&
1142 !matches!(node.node_data, NodeData::LoopStatementPartForEach{..}) &&
1143 !matches!(node.node_data, NodeData::LoopStatementPartElse(..))
1144 }) {
1145 panic!("Node type is not compatible with this node");
1146 }
1147
1148 Self {
1149 pos,
1150 child_nodes: nodes,
1151 node_data: NodeData::LoopStatement,
1152 }
1153 }
1154
1155 pub fn new_continue_break_statement_node(pos: CodePosition, number_node: Option<Box<Node>>, continue_node: bool) -> Node {
1156 Self {
1157 pos,
1158 child_nodes: Default::default(),
1159 node_data: NodeData::ContinueBreakStatement {
1160 number_node,
1161 continue_node,
1162 },
1163 }
1164 }
1165
1166 pub fn new_try_statement_part_try_node(pos: CodePosition, try_body: AST) -> Node {
1167 Self {
1168 pos,
1169 child_nodes: Default::default(),
1170 node_data: NodeData::TryStatementPartTry(try_body),
1171 }
1172 }
1173
1174 pub fn new_try_statement_part_soft_try_node(pos: CodePosition, try_body: AST) -> Node {
1175 Self {
1176 pos,
1177 child_nodes: Default::default(),
1178 node_data: NodeData::TryStatementPartSoftTry(try_body),
1179 }
1180 }
1181
1182 pub fn new_try_statement_part_non_try_node(pos: CodePosition, try_body: AST) -> Node {
1183 Self {
1184 pos,
1185 child_nodes: Default::default(),
1186 node_data: NodeData::TryStatementPartNonTry(try_body),
1187 }
1188 }
1189
1190 pub fn new_try_statement_part_catch_node(pos: CodePosition, try_body: AST, errors: Option<Vec<Node>>) -> Node {
1191 Self {
1192 pos,
1193 child_nodes: Default::default(),
1194 node_data: NodeData::TryStatementPartCatch {
1195 try_body,
1196 errors,
1197 },
1198 }
1199 }
1200
1201 pub fn new_try_statement_part_else_node(pos: CodePosition, try_body: AST) -> Node {
1202 Self {
1203 pos,
1204 child_nodes: Default::default(),
1205 node_data: NodeData::TryStatementPartElse(try_body),
1206 }
1207 }
1208
1209 pub fn new_try_statement_part_finally_node(pos: CodePosition, try_body: AST) -> Node {
1210 Self {
1211 pos,
1212 child_nodes: Default::default(),
1213 node_data: NodeData::TryStatementPartFinally(try_body),
1214 }
1215 }
1216
1217 pub fn new_try_statement_node(pos: CodePosition, nodes: Vec<Node>) -> Node {
1218 if nodes.iter().any(|node| {
1219 !matches!(node.node_data, NodeData::TryStatementPartTry(..)) &&
1220 !matches!(node.node_data, NodeData::TryStatementPartSoftTry{..}) &&
1221 !matches!(node.node_data, NodeData::TryStatementPartNonTry{..}) &&
1222 !matches!(node.node_data, NodeData::TryStatementPartCatch{..}) &&
1223 !matches!(node.node_data, NodeData::TryStatementPartElse(..)) &&
1224 !matches!(node.node_data, NodeData::TryStatementPartFinally(..))
1225 }) {
1226 panic!("Node type is not compatible with this node");
1227 }
1228
1229 Self {
1230 pos,
1231 child_nodes: nodes,
1232 node_data: NodeData::TryStatement,
1233 }
1234 }
1235
1236 pub fn new_operation_statement_node(
1237 pos: CodePosition,
1238 operation_expression: OperationExpression,
1239 ) -> Node {
1240 Self {
1241 pos,
1242 child_nodes: Default::default(),
1243 node_data: match operation_expression.operator_type {
1244 OperatorType::All | OperatorType::General => NodeData::Operation(operation_expression),
1245 OperatorType::Math => NodeData::Math(operation_expression),
1246 OperatorType::Condition => NodeData::Condition(operation_expression),
1247 },
1248 }
1249 }
1250
1251 pub fn new_return_statement_node(pos: CodePosition, return_value: Option<Node>) -> Node {
1252 Self {
1253 pos,
1254 child_nodes: match return_value {
1255 Some(return_value) => vec![return_value],
1256 None => vec![],
1257 },
1258 node_data: NodeData::Return,
1259 }
1260 }
1261
1262 pub fn new_throw_statement_node(pos: CodePosition, throw_value: Node, message_value: Option<Node>) -> Node {
1263 Self {
1264 pos,
1265 child_nodes: match message_value {
1266 Some(message_value) => vec![throw_value, message_value],
1267 None => vec![throw_value],
1268 },
1269 node_data: NodeData::Throw,
1270 }
1271 }
1272
1273 pub fn new_int_value_node(pos: CodePosition, value: i32) -> Node {
1274 Self {
1275 pos,
1276 child_nodes: Default::default(),
1277 node_data: NodeData::IntValue(value),
1278 }
1279 }
1280
1281 pub fn new_long_value_node(pos: CodePosition, value: i64) -> Node {
1282 Self {
1283 pos,
1284 child_nodes: Default::default(),
1285 node_data: NodeData::LongValue(value),
1286 }
1287 }
1288
1289 pub fn new_float_value_node(pos: CodePosition, value: f32) -> Node {
1290 Self {
1291 pos,
1292 child_nodes: Default::default(),
1293 node_data: NodeData::FloatValue(value),
1294 }
1295 }
1296
1297 pub fn new_double_value_node(pos: CodePosition, value: f64) -> Node {
1298 Self {
1299 pos,
1300 child_nodes: Default::default(),
1301 node_data: NodeData::DoubleValue(value),
1302 }
1303 }
1304
1305 pub fn new_char_value_node(pos: CodePosition, value: char) -> Node {
1306 Self {
1307 pos,
1308 child_nodes: Default::default(),
1309 node_data: NodeData::CharValue(value),
1310 }
1311 }
1312
1313 pub fn new_text_value_node(pos: CodePosition, value: impl Into<Box<str>>) -> Node {
1314 Self {
1315 pos,
1316 child_nodes: Default::default(),
1317 node_data: NodeData::TextValue(value.into()),
1318 }
1319 }
1320
1321 pub fn new_null_value_node(pos: CodePosition) -> Node {
1322 Self {
1323 pos,
1324 child_nodes: Default::default(),
1325 node_data: NodeData::NullValue,
1326 }
1327 }
1328
1329 pub fn new_void_value_node(pos: CodePosition) -> Node {
1330 Self {
1331 pos,
1332 child_nodes: Default::default(),
1333 node_data: NodeData::VoidValue,
1334 }
1335 }
1336
1337 pub fn new_array_value_node(pos: CodePosition, child_nodes: Vec<Node>) -> Node {
1338 Self {
1339 pos,
1340 child_nodes,
1341 node_data: NodeData::ArrayValue,
1342 }
1343 }
1344
1345 pub fn new_struct_definition_node(pos: CodePosition, struct_definition: StructDefinition) -> Node {
1346 Self {
1347 pos,
1348 child_nodes: Default::default(),
1349 node_data: NodeData::StructDefinition(Box::new(struct_definition)),
1350 }
1351 }
1352
1353 pub fn new_class_definition_node(pos: CodePosition, class_definition: ClassDefinition) -> Node {
1354 Self {
1355 pos,
1356 child_nodes: Default::default(),
1357 node_data: NodeData::ClassDefinition(Box::new(class_definition)),
1358 }
1359 }
1360
1361 pub fn pos(&self) -> CodePosition {
1362 self.pos
1363 }
1364
1365 pub fn child_nodes(&self) -> &[Node] {
1366 &self.child_nodes
1367 }
1368
1369 pub fn node_data(&self) -> &NodeData {
1370 &self.node_data
1371 }
1372
1373 pub fn operator(&self) -> Option<Operator> {
1374 match &self.node_data {
1375 NodeData::Operation(operation_expression) |
1376 NodeData::Math(operation_expression) |
1377 NodeData::Condition(operation_expression) =>
1378 Some(operation_expression.operator),
1379
1380 _ => None,
1381 }
1382 }
1383
1384 pub fn left_side_operand(&self) -> Option<&Node> {
1385 match &self.node_data {
1386 NodeData::Operation(operation_expression) |
1387 NodeData::Math(operation_expression) |
1388 NodeData::Condition(operation_expression) =>
1389 operation_expression.left_side_operand.as_deref(),
1390
1391 _ => None,
1392 }
1393 }
1394
1395 pub fn into_left_side_operand(self) -> Option<Node> {
1396 match self.node_data {
1397 NodeData::Operation(operation_expression) |
1398 NodeData::Math(operation_expression) |
1399 NodeData::Condition(operation_expression) =>
1400 operation_expression.left_side_operand.map(|node| *node),
1401
1402 _ => None,
1403 }
1404 }
1405
1406 pub fn middle_operand(&self) -> Option<&Node> {
1407 match &self.node_data {
1408 NodeData::Operation(operation_expression) |
1409 NodeData::Math(operation_expression) |
1410 NodeData::Condition(operation_expression) =>
1411 operation_expression.middle_operand.as_deref(),
1412
1413 _ => None,
1414 }
1415 }
1416
1417 pub fn into_middle_operand(self) -> Option<Node> {
1418 match self.node_data {
1419 NodeData::Operation(operation_expression) |
1420 NodeData::Math(operation_expression) |
1421 NodeData::Condition(operation_expression) =>
1422 operation_expression.middle_operand.map(|node| *node),
1423
1424 _ => None,
1425 }
1426 }
1427
1428 pub fn right_side_operand(&self) -> Option<&Node> {
1429 match &self.node_data {
1430 NodeData::Operation(operation_expression) |
1431 NodeData::Math(operation_expression) |
1432 NodeData::Condition(operation_expression) =>
1433 operation_expression.right_side_operand.as_deref(),
1434
1435 _ => None,
1436 }
1437 }
1438
1439 pub fn into_right_side_operand(self) -> Option<Node> {
1440 match self.node_data {
1441 NodeData::Operation(operation_expression) |
1442 NodeData::Math(operation_expression) |
1443 NodeData::Condition(operation_expression) =>
1444 operation_expression.right_side_operand.map(|node| *node),
1445
1446 _ => None,
1447 }
1448 }
1449
1450 pub fn operands(&self) -> (Option<&Node>, Option<&Node>, Option<&Node>) {
1451 match &self.node_data {
1452 NodeData::Operation(operation_expression) |
1453 NodeData::Math(operation_expression) |
1454 NodeData::Condition(operation_expression) =>
1455 (
1456 operation_expression.left_side_operand.as_deref(),
1457 operation_expression.middle_operand.as_deref(),
1458 operation_expression.right_side_operand.as_deref(),
1459 ),
1460
1461 _ => (None, None, None),
1462 }
1463 }
1464
1465 pub fn into_operands(self) -> (Option<Node>, Option<Node>, Option<Node>) {
1466 match self.node_data {
1467 NodeData::Operation(operation_expression) |
1468 NodeData::Math(operation_expression) |
1469 NodeData::Condition(operation_expression) =>
1470 (
1471 operation_expression.left_side_operand.map(|node| *node),
1472 operation_expression.middle_operand.map(|node| *node),
1473 operation_expression.right_side_operand.map(|node| *node),
1474 ),
1475
1476 _ => (None, None, None),
1477 }
1478 }
1479
1480 fn try_evaluate_escape_sequence(char: char) -> Option<String> {
1481 match char {
1482 '0' => Some("\0".to_string()),
1483 'n' => Some("\n".to_string()),
1484 'r' => Some("\r".to_string()),
1485 'f' => Some("\u{000C}".to_string()),
1486 's' => Some(" ".to_string()),
1487 'e' => Some(String::new()),
1488 'E' => Some("\u{001B}".to_string()),
1489 'b' => Some("\u{0008}".to_string()),
1490 't' => Some("\t".to_string()),
1491
1492 '$' | '&' | '#' | ',' | '.' | '(' | ')' | '[' | ']' | '{' | '}' | '=' | '<' | '>' |
1493 '+' | '-' | '/' | '*' | '%' | '|' | '~' | '^' | '?' | ':' | '@' | '\u{25b2}' |
1494 '\u{25bc}' | '\"' | '\\' => Some(char.to_string()),
1495
1496 _ => None,
1497 }
1498 }
1499
1500 pub(super) fn optimize_nodes(nodes: &mut Vec<Node>) {
1501 let mut i = 0;
1502 while i < nodes.len() {
1503 nodes[i].optimize_node();
1504
1505 let mut builder = None;
1506 if let NodeData::EscapeSequence(char) = nodes[i].node_data() {
1507 builder = Self::try_evaluate_escape_sequence(*char);
1508 }else if let NodeData::TextValue(str) = nodes[i].node_data() {
1509 builder = Some(str.to_string());
1510 }else if let NodeData::CharValue(char) = nodes[i].node_data() {
1511 builder = Some(char.to_string());
1512 }
1513
1514 if let Some(mut builder) = builder {
1515 let mut pos = nodes[i].pos();
1516
1517 let mut changed = false;
1518 let index = i + 1;
1519 while index < nodes.len() {
1520 match nodes[index].node_data() {
1521 NodeData::EscapeSequence(char) => {
1522 if let Some(str) = Self::try_evaluate_escape_sequence(*char) {
1523 changed = true;
1524
1525 builder += &str;
1526 pos = pos.combine(&nodes[index].pos());
1527
1528 nodes.remove(index);
1529 continue;
1530 }
1531
1532 break;
1533 },
1534
1535 NodeData::TextValue(str) => {
1536 changed = true;
1537
1538 builder += str;
1539 pos = pos.combine(&nodes[index].pos());
1540
1541 nodes.remove(index);
1542 continue;
1543 },
1544
1545 NodeData::CharValue(char) => {
1546 changed = true;
1547
1548 builder += &char.to_string();
1549 pos = pos.combine(&nodes[index].pos());
1550
1551 nodes.remove(index);
1552 continue;
1553 },
1554
1555 _ => break,
1556 }
1557 }
1558
1559 if changed {
1560 nodes[i] = Node::new_text_value_node(pos, builder);
1561 }
1562 }
1563
1564 i += 1;
1565 }
1566 }
1567
1568 pub(super) fn optimize_node(&mut self) {
1569 if matches!(self.node_data, NodeData::List | NodeData::FunctionCall(..) |
1570 NodeData::FunctionCallPreviousNodeValue { .. } | NodeData::IfStatement |
1571 NodeData::LoopStatement | NodeData::TryStatement) {
1572 Self::optimize_nodes(&mut self.child_nodes);
1573 }else {
1574 for node in &mut self.child_nodes {
1575 node.optimize_node();
1576 }
1577 }
1578
1579 match &mut self.node_data {
1580 NodeData::List if self.child_nodes.len() == 1 => {
1581 let _ = mem::replace(self, self.child_nodes[0].clone());
1582 },
1583
1584 NodeData::FunctionDefinition(function_definition) => {
1585 function_definition.function_body.optimize_ast();
1586 },
1587
1588 NodeData::IfStatementPartIf { if_body, condition } => {
1589 if_body.optimize_ast();
1590
1591 Self::optimize_node(&mut condition.node);
1592 },
1593
1594 NodeData::IfStatementPartElse(if_body) => {
1595 if_body.optimize_ast();
1596 },
1597
1598 NodeData::LoopStatementPartLoop(loop_body) |
1599 NodeData::LoopStatementPartElse(loop_body) => {
1600 loop_body.optimize_ast();
1601 },
1602
1603 NodeData::LoopStatementPartWhile { loop_body, condition } |
1604 NodeData::LoopStatementPartUntil { loop_body, condition } => {
1605 loop_body.optimize_ast();
1606
1607 Self::optimize_node(&mut condition.node);
1608 },
1609
1610 NodeData::LoopStatementPartRepeat {
1611 loop_body,
1612 var_pointer_node,
1613 repeat_count_node,
1614 } => {
1615 loop_body.optimize_ast();
1616
1617 Self::optimize_node(var_pointer_node);
1618 Self::optimize_node(repeat_count_node);
1619 },
1620
1621 NodeData::LoopStatementPartForEach {
1622 loop_body,
1623 var_pointer_node,
1624 composite_or_text_node,
1625 } => {
1626 loop_body.optimize_ast();
1627
1628 Self::optimize_node(var_pointer_node);
1629 Self::optimize_node(composite_or_text_node);
1630 },
1631
1632 NodeData::TryStatementPartTry(try_body) |
1633 NodeData::TryStatementPartSoftTry(try_body) |
1634 NodeData::TryStatementPartNonTry(try_body) |
1635 NodeData::TryStatementPartElse(try_body) |
1636 NodeData::TryStatementPartFinally(try_body) => {
1637 try_body.optimize_ast();
1638 },
1639
1640 NodeData::TryStatementPartCatch { try_body, errors } => {
1641 try_body.optimize_ast();
1642
1643 if let Some(errors) = errors {
1644 Self::optimize_nodes(errors);
1645 }
1646 },
1647
1648 NodeData::ContinueBreakStatement { number_node: Some(number_node), .. } => {
1649 Self::optimize_node(number_node);
1650 },
1651
1652 NodeData::Operation(operation_expression) |
1653 NodeData::Math(operation_expression) |
1654 NodeData::Condition(operation_expression) => {
1655 if let Some(node) = &mut operation_expression.left_side_operand {
1656 Self::optimize_node(node);
1657 }
1658
1659 if let Some(node) = &mut operation_expression.middle_operand {
1660 Self::optimize_node(node);
1661 }
1662
1663 if let Some(node) = &mut operation_expression.right_side_operand {
1664 Self::optimize_node(node);
1665 }
1666
1667 if matches!(operation_expression.operator(), Operator::Non | Operator::MathNon |
1668 Operator::ConditionalNon) {
1669 let mut inner_non_value = None;
1670
1671 if let Some(node) = operation_expression.left_side_operand.as_deref()
1672 && let
1673 NodeData::Operation(inner_operation_expression) |
1674 NodeData::Math(inner_operation_expression) |
1675 NodeData::Condition(inner_operation_expression) = &node.node_data
1676 && (matches!(inner_operation_expression.operator(), Operator::Non) ||
1677 mem::discriminant(&operation_expression.operator) ==
1678 mem::discriminant(&inner_operation_expression.operator)) {
1679 inner_non_value.clone_from(&inner_operation_expression.left_side_operand);
1680 }
1681
1682 if inner_non_value.is_some() {
1683 operation_expression.left_side_operand = inner_non_value;
1684 }
1685 }
1686 },
1687
1688 NodeData::ClassDefinition(class_definition) => {
1689 for member in &mut class_definition.static_members {
1690 if let Some(value) = &mut member.value {
1691 Self::optimize_node(value);
1692 }
1693 }
1694
1695 for member in &mut class_definition.members {
1696 if let Some(value) = &mut member.value {
1697 Self::optimize_node(value);
1698 }
1699 }
1700
1701 for method in &mut class_definition.methods {
1702 Self::optimize_node(&mut method.body);
1703 }
1704
1705 for constructor in &mut class_definition.constructors {
1706 Self::optimize_node(&mut constructor.body);
1707 }
1708 },
1709
1710 _ => {},
1711 }
1712 }
1713}
1714
1715impl PartialEq for Node {
1716 fn eq(&self, other: &Self) -> bool {
1717 self.child_nodes == other.child_nodes && self.node_data == other.node_data
1718 }
1719}
1720
1721impl Display for Node {
1722 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1723 let mut builder = String::new();
1724
1725 match &self.node_data {
1726 NodeData::List => {
1727 let _ = write!(builder, "ListNode: Position: {}", self.pos.to_compact_string());
1728 builder += ", Children: {\n";
1729 for node in self.child_nodes.iter() {
1730 for token in node.to_string().split("\n") {
1731 let _ = writeln!(builder, "\t{token}");
1732 }
1733 }
1734 builder += "}";
1735 },
1736
1737 NodeData::ParsingError { error, message } => {
1738 let _ = write!(builder, "ParsingErrorNode: Position: {}", self.pos.to_compact_string());
1739 let _ = write!(builder, ", Error: \"{error}\"");
1740 let _ = write!(builder, ", Message: \"{message}\"");
1741 },
1742
1743 NodeData::Assignment => {
1744 let _ = write!(builder, "AssignmentNode: Position: {}", self.pos.to_compact_string());
1745 builder += ", lvalue: {\n";
1746 for token in format!("{}", self.child_nodes[0]).split("\n") {
1747 let _ = writeln!(builder, "\t{token}");
1748 }
1749 builder += "}, rvalue: {\n";
1750 for token in format!("{}", self.child_nodes[1]).split("\n") {
1751 let _ = writeln!(builder, "\t{token}");
1752 }
1753 builder += "}";
1754 },
1755
1756 NodeData::EscapeSequence(char) => {
1757 let _ = write!(builder, "EscapeSequenceNode: Position: {}", self.pos.to_compact_string());
1758 let _ = write!(builder, ", Char: \"{char}\"");
1759 },
1760
1761 NodeData::UnicodeEscapeSequence(hex_code_point) => {
1762 let _ = write!(builder, "UnicodeEscapeSequenceNode: Position: {}", self.pos.to_compact_string());
1763 let _ = write!(builder, ", hexCodePoint: \"{hex_code_point}\"");
1764 },
1765
1766 NodeData::UnprocessedVariableName(variable_name) => {
1767 let _ = write!(builder, "UnprocessedVariableNameNode: Position: {}", self.pos.to_compact_string());
1768 let _ = write!(builder, ", Variable Name: \"{variable_name}\"");
1769 },
1770
1771 NodeData::VariableName { variable_name, type_constraint } => {
1772 let _ = write!(builder, "VariableNameNode: Position: {}", self.pos.to_compact_string());
1773 let _ = write!(builder, ", Variable Name: \"{variable_name}\"");
1774 let _ = write!(builder, ", TypeConstraint: \"{}\"", type_constraint.as_deref().unwrap_or("null"));
1775 },
1776
1777 NodeData::ArgumentSeparator(original_text) => {
1778 let _ = write!(builder, "ArgumentSeparatorNode: Position: {}", self.pos.to_compact_string());
1779 let _ = write!(builder, ", OriginalText: \"{original_text}\"");
1780 },
1781
1782 NodeData::FunctionCall(function_name) => {
1783 let _ = write!(builder, "FunctionCallNode: Position: {}", self.pos.to_compact_string());
1784 let _ = write!(builder, ", FunctionName: \"{function_name}\"");
1785 builder += ", ParameterList: {\n";
1786 for node in self.child_nodes.iter() {
1787 for token in node.to_string().split("\n") {
1788 let _ = writeln!(builder, "\t{token}");
1789 }
1790 }
1791 builder += "}";
1792 },
1793
1794 NodeData::FunctionCallPreviousNodeValue { leading_whitespace, trailing_whitespace } => {
1795 let _ = write!(builder, "FunctionCallNode: Position: {}", self.pos.to_compact_string());
1796 builder += ", ArgumentList: {\n";
1797 for node in self.child_nodes.iter() {
1798 for token in node.to_string().split("\n") {
1799 let _ = writeln!(builder, "\t{token}");
1800 }
1801 }
1802 let _ = write!(builder, "}}, LeadingWhitespace: \"{leading_whitespace}\"");
1803 let _ = write!(builder, ", TrailingWhitespace: \"{trailing_whitespace}\"");
1804 },
1805
1806 NodeData::FunctionDefinition(function_definition) => {
1807 let _ = write!(builder, "FunctionDefinitionNode: Position: {}", self.pos.to_compact_string());
1808 let _ = write!(builder, ", FunctionName: \"{}\"", function_definition.function_name.as_deref().unwrap_or("null"));
1809 let _ = write!(builder, ", Overloaded: \"{}\"", function_definition.overloaded);
1810 let _ = write!(builder, ", Combinator: \"{}\"", function_definition.combinator);
1811 let _ = write!(builder, ", Doc Comment: \"{}\"", function_definition.doc_comment.as_deref().unwrap_or("null"));
1812 builder += ", ParameterList: {\n";
1813 for node in self.child_nodes.iter() {
1814 for token in node.to_string().split("\n") {
1815 let _ = writeln!(builder, "\t{token}");
1816 }
1817 }
1818 let _ = write!(builder,
1819 "}}, ReturnValueTypeConstraint: \"{}\"",
1820 function_definition.return_value_type_constraint.as_deref().unwrap_or("null"),
1821 );
1822 builder += ", FunctionBody: {\n";
1823 for token in function_definition.function_body.to_string().split("\n") {
1824 let _ = writeln!(builder, "\t{token}");
1825 }
1826 builder += "}";
1827 },
1828
1829 NodeData::IfStatementPartIf { if_body, condition } => {
1830 let _ = write!(builder, "IfStatementPartIfNode: Position: {}", self.pos.to_compact_string());
1831 builder += ", Condition: {\n";
1832 for token in condition.node.to_string().split("\n") {
1833 let _ = writeln!(builder, "\t{token}");
1834 }
1835 builder += "}, IfBody: {\n";
1836 for token in if_body.to_string().split("\n") {
1837 let _ = writeln!(builder, "\t{token}");
1838 }
1839 builder += "}";
1840 },
1841
1842 NodeData::IfStatementPartElse(if_body) => {
1843 let _ = write!(builder, "IfStatementPartElseNode: Position: {}", self.pos.to_compact_string());
1844 builder += ", IfBody: {\n";
1845 for token in if_body.to_string().split("\n") {
1846 let _ = writeln!(builder, "\t{token}");
1847 }
1848 builder += "}";
1849 },
1850
1851 NodeData::IfStatement => {
1852 let _ = write!(builder, "IfStatementNode: Position: {}", self.pos.to_compact_string());
1853 builder += ", Children: {\n";
1854 for node in self.child_nodes.iter() {
1855 for token in node.to_string().split("\n") {
1856 let _ = writeln!(builder, "\t{token}");
1857 }
1858 }
1859 builder += "}";
1860 },
1861
1862 NodeData::LoopStatementPartLoop(loop_body) => {
1863 let _ = write!(builder, "LoopStatementPartLoopNode: Position: {}", self.pos.to_compact_string());
1864 builder += ", LoopBody: {\n";
1865 for token in loop_body.to_string().split("\n") {
1866 let _ = writeln!(builder, "\t{token}");
1867 }
1868 builder += "}";
1869 },
1870
1871 NodeData::LoopStatementPartWhile { loop_body, condition } => {
1872 let _ = write!(builder, "LoopStatementPartWhileNode: Position: {}", self.pos.to_compact_string());
1873 builder += ", Condition: {\n";
1874 for token in condition.node.to_string().split("\n") {
1875 let _ = writeln!(builder, "\t{token}");
1876 }
1877 builder += "}, LoopBody: {\n";
1878 for token in loop_body.to_string().split("\n") {
1879 let _ = writeln!(builder, "\t{token}");
1880 }
1881 builder += "}";
1882 },
1883
1884 NodeData::LoopStatementPartUntil { loop_body, condition } => {
1885 let _ = write!(builder, "LoopStatementPartUntilNode: Position: {}", self.pos.to_compact_string());
1886 builder += ", Condition: {\n";
1887 for token in condition.node.to_string().split("\n") {
1888 let _ = writeln!(builder, "\t{token}");
1889 }
1890 builder += "}, LoopBody: {\n";
1891 for token in loop_body.to_string().split("\n") {
1892 let _ = writeln!(builder, "\t{token}");
1893 }
1894 builder += "}";
1895 },
1896
1897 NodeData::LoopStatementPartRepeat {
1898 loop_body,
1899 var_pointer_node,
1900 repeat_count_node,
1901 } => {
1902 let _ = write!(builder, "LoopStatementPartRepeatNode: Position: {}", self.pos.to_compact_string());
1903 builder += ", varPointer: {\n";
1904 for token in var_pointer_node.to_string().split("\n") {
1905 let _ = writeln!(builder, "\t{token}");
1906 }
1907 builder += "}, repeatCount: {\n";
1908 for token in repeat_count_node.to_string().split("\n") {
1909 let _ = writeln!(builder, "\t{token}");
1910 }
1911 builder += "}, LoopBody: {\n";
1912 for token in loop_body.to_string().split("\n") {
1913 let _ = writeln!(builder, "\t{token}");
1914 }
1915 builder += "}";
1916 },
1917
1918 NodeData::LoopStatementPartForEach {
1919 loop_body,
1920 var_pointer_node,
1921 composite_or_text_node,
1922 } => {
1923 let _ = write!(builder, "LoopStatementPartForEachNode: Position: {}", self.pos.to_compact_string());
1924 builder += ", Condition: {\n";
1925 for token in var_pointer_node.to_string().split("\n") {
1926 let _ = writeln!(builder, "\t{token}");
1927 }
1928 builder += "}, compositeOrTextNode: {\n";
1929 for token in composite_or_text_node.to_string().split("\n") {
1930 let _ = writeln!(builder, "\t{token}");
1931 }
1932 builder += "}, LoopBody: {\n";
1933 for token in loop_body.to_string().split("\n") {
1934 let _ = writeln!(builder, "\t{token}");
1935 }
1936 builder += "}";
1937 },
1938
1939 NodeData::LoopStatementPartElse(loop_body) => {
1940 let _ = write!(builder, "LoopStatementPartElseNode: Position: {}", self.pos.to_compact_string());
1941 builder += ", LoopBody: {\n";
1942 for token in loop_body.to_string().split("\n") {
1943 let _ = writeln!(builder, "\t{token}");
1944 }
1945 builder += "}";
1946 },
1947
1948 NodeData::LoopStatement => {
1949 let _ = write!(builder, "LoopStatementNode: Position: {}", self.pos.to_compact_string());
1950 builder += ", Children: {\n";
1951 for node in self.child_nodes.iter() {
1952 for token in node.to_string().split("\n") {
1953 let _ = writeln!(builder, "\t{token}");
1954 }
1955 }
1956 builder += "}";
1957 },
1958
1959 NodeData::TryStatementPartTry(try_body) => {
1960 let _ = write!(builder, "TryStatementPartTryNode: Position: {}", self.pos.to_compact_string());
1961 builder += ", TryBody: {\n";
1962 for token in try_body.to_string().split("\n") {
1963 let _ = writeln!(builder, "\t{token}");
1964 }
1965 builder += "}";
1966 },
1967
1968 NodeData::TryStatementPartSoftTry(try_body) => {
1969 let _ = write!(builder, "TryStatementPartSoftTryNode: Position: {}", self.pos.to_compact_string());
1970 builder += ", TryBody: {\n";
1971 for token in try_body.to_string().split("\n") {
1972 let _ = writeln!(builder, "\t{token}");
1973 }
1974 builder += "}";
1975 },
1976
1977 NodeData::TryStatementPartNonTry(try_body) => {
1978 let _ = write!(builder, "TryStatementPartNonTryNode: Position: {}", self.pos.to_compact_string());
1979 builder += ", TryBody: {\n";
1980 for token in try_body.to_string().split("\n") {
1981 let _ = writeln!(builder, "\t{token}");
1982 }
1983 builder += "}";
1984 },
1985
1986 NodeData::TryStatementPartCatch { try_body, errors } => {
1987 let _ = write!(builder, "TryStatementPartCatchNode: Position: {}", self.pos.to_compact_string());
1988 builder += ", Errors: {\n";
1989 if let Some(errors) = errors {
1990 for node in errors.iter() {
1991 for token in node.to_string().split("\n") {
1992 let _ = writeln!(builder, "\t{token}");
1993 }
1994 }
1995 }else {
1996 builder += "\tnull\n";
1997 }
1998 builder += "}, TryBody: {\n";
1999 for token in try_body.to_string().split("\n") {
2000 let _ = writeln!(builder, "\t{token}");
2001 }
2002 builder += "}";
2003 },
2004
2005 NodeData::TryStatementPartElse(try_body) => {
2006 let _ = write!(builder, "TryStatementPartElseNode: Position: {}", self.pos.to_compact_string());
2007 builder += ", TryBody: {\n";
2008 for token in try_body.to_string().split("\n") {
2009 let _ = writeln!(builder, "\t{token}");
2010 }
2011 builder += "}";
2012 },
2013
2014 NodeData::TryStatementPartFinally(try_body) => {
2015 let _ = write!(builder, "TryStatementPartFinallyNode: Position: {}", self.pos.to_compact_string());
2016 builder += ", TryBody: {\n";
2017 for token in try_body.to_string().split("\n") {
2018 let _ = writeln!(builder, "\t{token}");
2019 }
2020 builder += "}";
2021 },
2022
2023 NodeData::TryStatement => {
2024 let _ = write!(builder, "TryStatementNode: Position: {}", self.pos.to_compact_string());
2025 builder += ", Children: {\n";
2026 for node in self.child_nodes.iter() {
2027 for token in node.to_string().split("\n") {
2028 let _ = writeln!(builder, "\t{token}");
2029 }
2030 }
2031 builder += "}";
2032 },
2033
2034 NodeData::ContinueBreakStatement { number_node, continue_node } => {
2035 let _ = write!(builder, "LoopStatementContinueBreakStatementNode: Position: {}", self.pos.to_compact_string());
2036 builder += ", numberNode: {\n";
2037 if let Some(number_node) = number_node {
2038 for token in number_node.to_string().split("\n") {
2039 let _ = writeln!(builder, "\t{token}");
2040 }
2041 }else {
2042 builder += "\tnull\n";
2043 }
2044 let _ = write!(builder, "}}, continueNode: \"{}\"", continue_node);
2045 },
2046
2047 NodeData::Operation(operation_expression) |
2048 NodeData::Math(operation_expression) |
2049 NodeData::Condition(operation_expression) => {
2050 let _ = write!(builder, "OperationNode: Position: {}", self.pos.to_compact_string());
2051 let _ = write!(builder, ", NodeType: \"{}\"", operation_expression.operator_type);
2052 let _ = write!(builder, ", Operator: \"{}\"", operation_expression.operator);
2053 let _ = write!(builder, ", OperatorType: \"{}\"", operation_expression.operator.operator_type());
2054 builder += ", Operands: {\n";
2055 for node in operation_expression.left_side_operand.iter().
2056 chain(operation_expression.middle_operand.iter()).
2057 chain(operation_expression.right_side_operand.iter()) {
2058 for token in node.to_string().split("\n") {
2059 let _ = writeln!(builder, "\t{token}");
2060 }
2061 }
2062 builder += "}";
2063 },
2064
2065 NodeData::Return => {
2066 let _ = write!(builder, "ReturnNode: Position: {}", self.pos.to_compact_string());
2067 builder += ", Children: {\n";
2068 for node in self.child_nodes.iter() {
2069 for token in node.to_string().split("\n") {
2070 let _ = writeln!(builder, "\t{token}");
2071 }
2072 }
2073 builder += "}";
2074 },
2075
2076 NodeData::Throw => {
2077 let _ = write!(builder, "ThrowNode: Position: {}", self.pos.to_compact_string());
2078 builder += ", ThrowValue: {\n";
2079 for token in self.child_nodes[0].to_string().split("\n") {
2080 let _ = writeln!(builder, "\t{token}");
2081 }
2082 builder += "}, Message: ";
2083 if let Some(message) = self.child_nodes.get(1) {
2084 builder += "{\n";
2085 for token in message.to_string().split("\n") {
2086 let _ = writeln!(builder, "\t{token}");
2087 }
2088 builder += "}";
2089 }else {
2090 builder += "null";
2091 }
2092 },
2093
2094 NodeData::IntValue(value) => {
2095 let _ = write!(builder, "IntValueNode: Position: {}", self.pos.to_compact_string());
2096 let _ = write!(builder, ", Value: \"{value}\"");
2097 },
2098
2099 NodeData::LongValue(value) => {
2100 let _ = write!(builder, "LongValueNode: Position: {}", self.pos.to_compact_string());
2101 let _ = write!(builder, ", Value: \"{value}\"");
2102 },
2103
2104 NodeData::FloatValue(value) => {
2105 let _ = write!(builder, "FloatValueNode: Position: {}", self.pos.to_compact_string());
2106 let _ = write!(builder, ", Value: \"{value}\"");
2107 },
2108
2109 NodeData::DoubleValue(value) => {
2110 let _ = write!(builder, "DoubleValueNode: Position: {}", self.pos.to_compact_string());
2111 let _ = write!(builder, ", Value: \"{value}\"");
2112 },
2113
2114 NodeData::CharValue(value) => {
2115 let _ = write!(builder, "CharValueNode: Position: {}", self.pos.to_compact_string());
2116 let _ = write!(builder, ", Value: \"{value}\"");
2117 },
2118
2119 NodeData::TextValue(value) => {
2120 let _ = write!(builder, "TextValueNode: Position: {}", self.pos.to_compact_string());
2121 let _ = write!(builder, ", Value: \"{value}\"");
2122 },
2123
2124 NodeData::NullValue => {
2125 let _ = write!(builder, "NullValueNode: Position: {}", self.pos.to_compact_string());
2126 },
2127
2128 NodeData::VoidValue => {
2129 let _ = write!(builder, "VoidValueNode: Position: {}", self.pos.to_compact_string());
2130 },
2131
2132 NodeData::ArrayValue => {
2133 let _ = write!(builder, "ArrayNode: Position: {}", self.pos.to_compact_string());
2134 builder += ", Elements: {\n";
2135 for node in self.child_nodes.iter() {
2136 for token in node.to_string().split("\n") {
2137 let _ = writeln!(builder, "\t{token}");
2138 }
2139 }
2140 builder += "}";
2141 },
2142
2143 NodeData::StructDefinition(struct_definition) => {
2144 let _ = write!(builder, "StructDefinitionNode: Position: {}", self.pos.to_compact_string());
2145 let _ = write!(builder, ", StructName: \"{}\"", struct_definition.struct_name.as_deref().unwrap_or("null"));
2146 builder += ", Members{TypeConstraints}: {\n";
2147 for member in struct_definition.members.iter() {
2148 let _ = write!(builder, "\t{}", member.name);
2149 if let Some(type_constraint) = &member.type_constraint {
2150 let _ = write!(builder, "{{{type_constraint}}}");
2151 }
2152 builder += "\n";
2153 }
2154 builder += "}";
2155 },
2156
2157 NodeData::ClassDefinition(class_definition) => {
2158 let _ = write!(builder, "ClassDefinitionNode: Position: {}", self.pos.to_compact_string());
2159 let _ = write!(builder, ", ClassName: \"{}\"", class_definition.class_name.as_deref().unwrap_or("null"));
2160 builder += ", StaticMembers{TypeConstraints} = <value>: {\n";
2161 for member in class_definition.static_members.iter() {
2162 let _ = write!(builder, "\t{}{}{}", member.visibility.symbol(), if member.final_flag {
2163 "final:"
2164 } else {
2165 ""
2166 }, member.name);
2167 if let Some(type_constraint) = &member.type_constraint {
2168 let _ = write!(builder, "{{{type_constraint}}}");
2169 }
2170 if let Some(value) = &member.value {
2171 builder += "= {\n";
2172 for token in value.to_string().split("\n") {
2173 let _ = writeln!(builder, "\t\t{token}");
2174 }
2175 builder += "\t}";
2176 }
2177 builder += "\n";
2178 }
2179 builder += "}, Members{TypeConstraints}: {\n";
2180 for member in class_definition.members.iter() {
2181 let _ = write!(builder, "\t{}{}{}", member.visibility.symbol(), if member.final_flag {
2182 "final:"
2183 } else {
2184 ""
2185 }, member.name);
2186 if let Some(type_constraint) = &member.type_constraint {
2187 let _ = write!(builder, "{{{type_constraint}}}");
2188 }
2189 builder += "\n";
2190 }
2191 builder += "}, MethodName = <definition>: {\n";
2192 for method in class_definition.methods.iter() {
2193 let _ = writeln!(builder, "\t{}{}{} = {{", method.visibility.symbol(), if method.override_flag {
2194 "override:"
2195 } else {
2196 ""
2197 }, method.name);
2198 for token in method.body.to_string().split("\n") {
2199 let _ = writeln!(builder, "\t\t{token}");
2200 }
2201 builder += "\t}\n";
2202 }
2203 builder += "}, Constructors: {\n";
2204 for constructor in class_definition.constructors.iter() {
2205 let _ = writeln!(builder, "\t{}construct = {{", constructor.visibility.symbol());
2206 for token in constructor.body.to_string().split("\n") {
2207 let _ = writeln!(builder, "\t\t{token}");
2208 }
2209 builder += "\t}\n";
2210 }
2211 builder += "}, ParentClasses: {\n";
2212 for node in class_definition.parent_classes.iter() {
2213 for token in node.to_string().split("\n") {
2214 let _ = writeln!(builder, "\t{token}");
2215 }
2216 }
2217 builder += "}";
2218 },
2219 }
2220
2221 f.write_str(builder.as_str())
2222 }
2223}