1use crate::tokens::{Token, TokenType};
2use crate::types::{FloatType, IntType};
3use rslua_traits::Comments;
4
5#[derive(Clone, PartialEq, Debug)]
6pub enum UnOp {
7 Minus(Token),
8 BNot(Token),
9 Not(Token),
10 Len(Token),
11 None,
12}
13
14impl Comments for UnOp {
15 fn get_comments(&self) -> Vec<&str> {
16 match self {
17 UnOp::Minus(token) => token.get_comments(),
18 UnOp::BNot(token) => token.get_comments(),
19 UnOp::Not(token) => token.get_comments(),
20 UnOp::Len(token) => token.get_comments(),
21 UnOp::None => vec![],
22 }
23 }
24}
25
26impl UnOp {
27 pub fn from_token(token: Token) -> UnOp {
28 match token.t {
29 TokenType::Minus => UnOp::Minus(token),
30 TokenType::BXor => UnOp::BNot(token),
31 TokenType::Not => UnOp::Not(token),
32 TokenType::Len => UnOp::Len(token),
33 _ => UnOp::None,
34 }
35 }
36 pub fn priority(&self) -> u8 {
37 12
38 }
39}
40
41#[derive(Clone, PartialEq, Debug)]
42pub enum BinOp {
43 Add(Token),
44 Minus(Token),
45 Mul(Token),
46 Mod(Token),
47 Pow(Token),
48 Div(Token),
49 IDiv(Token),
50 BAnd(Token),
51 BOr(Token),
52 BXor(Token),
53 Shl(Token),
54 Shr(Token),
55 Concat(Token),
56 Ne(Token),
57 Eq(Token),
58 Lt(Token),
59 Le(Token),
60 Gt(Token),
61 Ge(Token),
62 And(Token),
63 Or(Token),
64 None,
65}
66
67pub struct BinOpPriority {
68 pub left: u8,
69 pub right: u8,
70}
71
72impl BinOp {
73 pub fn from_token(token: Token) -> BinOp {
74 match token.t {
75 TokenType::Add => BinOp::Add(token),
76 TokenType::Minus => BinOp::Minus(token),
77 TokenType::Mul => BinOp::Mul(token),
78 TokenType::Mod => BinOp::Mod(token),
79 TokenType::Pow => BinOp::Pow(token),
80 TokenType::Div => BinOp::Div(token),
81 TokenType::IDiv => BinOp::IDiv(token),
82 TokenType::BAnd => BinOp::BAnd(token),
83 TokenType::BOr => BinOp::BOr(token),
84 TokenType::BXor => BinOp::BXor(token),
85 TokenType::Shl => BinOp::Shl(token),
86 TokenType::Shr => BinOp::Shr(token),
87 TokenType::Concat => BinOp::Concat(token),
88 TokenType::Ne => BinOp::Ne(token),
89 TokenType::Eq => BinOp::Eq(token),
90 TokenType::Lt => BinOp::Lt(token),
91 TokenType::Le => BinOp::Le(token),
92 TokenType::Gt => BinOp::Gt(token),
93 TokenType::Ge => BinOp::Ge(token),
94 TokenType::And => BinOp::And(token),
95 TokenType::Or => BinOp::Or(token),
96 _ => BinOp::None,
97 }
98 }
99
100 pub fn priority(&self) -> BinOpPriority {
101 match self {
102 BinOp::Or(_) => BinOpPriority { left: 1, right: 1 },
103 BinOp::And(_) => BinOpPriority { left: 2, right: 2 },
104 BinOp::Eq(_)
105 | BinOp::Ne(_)
106 | BinOp::Lt(_)
107 | BinOp::Gt(_)
108 | BinOp::Le(_)
109 | BinOp::Ge(_) => BinOpPriority { left: 3, right: 3 },
110 BinOp::BOr(_) => BinOpPriority { left: 4, right: 4 },
111 BinOp::BXor(_) => BinOpPriority { left: 5, right: 5 },
112 BinOp::BAnd(_) => BinOpPriority { left: 6, right: 6 },
113 BinOp::Shl(_) | BinOp::Shr(_) => BinOpPriority { left: 7, right: 7 },
114 BinOp::Concat(_) => BinOpPriority { left: 9, right: 8 },
115 BinOp::Add(_) | BinOp::Minus(_) => BinOpPriority {
116 left: 10,
117 right: 10,
118 },
119 BinOp::Mul(_) | BinOp::Mod(_) | BinOp::Div(_) | BinOp::IDiv(_) => BinOpPriority {
120 left: 11,
121 right: 11,
122 },
123 BinOp::Pow(_) => BinOpPriority {
124 left: 14,
125 right: 13,
126 },
127 _ => unreachable!(),
128 }
129 }
130
131 pub fn is_comp(&self) -> bool {
132 matches!(
133 self,
134 BinOp::Le(_) | BinOp::Ge(_) | BinOp::Ne(_) | BinOp::Eq(_) | BinOp::Lt(_) | BinOp::Gt(_)
135 )
136 }
137}
138
139impl Comments for BinOp {
140 fn get_comments(&self) -> Vec<&str> {
141 match self {
143 BinOp::Add(token) => token.get_comments(),
144 BinOp::Minus(token) => token.get_comments(),
145 BinOp::Mul(token) => token.get_comments(),
146 BinOp::Mod(token) => token.get_comments(),
147 BinOp::Pow(token) => token.get_comments(),
148 BinOp::Div(token) => token.get_comments(),
149 BinOp::IDiv(token) => token.get_comments(),
150 BinOp::BAnd(token) => token.get_comments(),
151 BinOp::BOr(token) => token.get_comments(),
152 BinOp::BXor(token) => token.get_comments(),
153 BinOp::Shl(token) => token.get_comments(),
154 BinOp::Shr(token) => token.get_comments(),
155 BinOp::Concat(token) => token.get_comments(),
156 BinOp::Ne(token) => token.get_comments(),
157 BinOp::Eq(token) => token.get_comments(),
158 BinOp::Lt(token) => token.get_comments(),
159 BinOp::Le(token) => token.get_comments(),
160 BinOp::Gt(token) => token.get_comments(),
161 BinOp::Ge(token) => token.get_comments(),
162 BinOp::And(token) => token.get_comments(),
163 BinOp::Or(token) => token.get_comments(),
164 _ => unreachable!(),
165 }
166 }
167}
168
169#[derive(PartialEq, Clone, Debug)]
170pub enum Expr {
171 Nil(Token),
172 True(Token),
173 False(Token),
174 VarArg(Token),
175 Float(FloatExpr),
176 Int(IntExpr),
177 String(StringExpr),
178 Name(StringExpr),
179 ParenExpr(Box<Expr>),
180 FuncBody(FuncBody),
181 Table(Table),
182 BinExpr(BinExpr),
183 UnExpr(UnExpr),
184 SuffixedExpr(SuffixedExpr),
185}
186
187impl Expr {
188 pub fn to_assignable(self) -> Assignable {
189 match self {
190 Expr::Name(s) => Assignable::Name(s),
191 Expr::SuffixedExpr(s) => Assignable::SuffixedExpr(s),
192 _ => unreachable!(),
193 }
194 }
195
196 pub fn unwrap_as_int(&self) -> IntType {
197 match &self {
198 Expr::Int(expr) => expr.value(),
199 _ => unreachable!(),
200 }
201 }
202
203 pub fn unwrap_as_float(&self) -> FloatType {
204 match &self {
205 Expr::Float(expr) => expr.value(),
206 _ => unreachable!(),
207 }
208 }
209
210 pub fn unwrap_as_string(&self) -> String {
211 match &self {
212 Expr::String(expr) => expr.value(),
213 _ => unreachable!(),
214 }
215 }
216
217 pub fn unwrap_as_name(&self) -> &StringExpr {
218 match &self {
219 Expr::Name(expr) => expr,
220 _ => unreachable!(),
221 }
222 }
223}
224
225impl Comments for Expr {
226 fn get_comments(&self) -> Vec<&str> {
227 match &self {
228 Expr::Nil(token) => token.get_comments(),
229 Expr::True(token) => token.get_comments(),
230 Expr::False(token) => token.get_comments(),
231 Expr::VarArg(token) => token.get_comments(),
232 Expr::Float(expr) => expr.get_comments(),
233 Expr::Int(expr) => expr.get_comments(),
234 Expr::String(expr) => expr.get_comments(),
235 Expr::Name(expr) => expr.get_comments(),
236 Expr::ParenExpr(expr) => expr.get_comments(),
237 Expr::FuncBody(expr) => expr.get_comments(),
238 Expr::Table(expr) => expr.get_comments(),
239 Expr::BinExpr(expr) => expr.get_comments(),
240 Expr::UnExpr(expr) => expr.get_comments(),
241 Expr::SuffixedExpr(expr) => expr.get_comments(),
242 }
243 }
244}
245
246#[derive(PartialEq, Clone, Debug)]
247pub enum Assignable {
248 Name(StringExpr),
249 SuffixedExpr(SuffixedExpr),
250}
251
252impl Assignable {
253 pub fn unwrap_as_name(&self) -> &StringExpr {
254 match &self {
255 Assignable::Name(name) => name,
256 _ => unreachable!(),
257 }
258 }
259 pub fn unwrap_as_suffix(&self) -> &SuffixedExpr {
260 match &self {
261 Assignable::SuffixedExpr(suffix) => suffix,
262 _ => unreachable!(),
263 }
264 }
265}
266
267impl Comments for Assignable {
268 fn get_comments(&self) -> Vec<&str> {
269 match &self {
270 Assignable::Name(name) => name.get_comments(),
271 Assignable::SuffixedExpr(suffix) => suffix.get_comments(),
272 }
273 }
274}
275
276#[derive(PartialEq, Clone, Debug)]
277pub struct FloatExpr {
278 pub token: Token,
279}
280
281impl FloatExpr {
282 pub fn value(&self) -> FloatType {
283 self.token.get_float()
284 }
285}
286
287impl Comments for FloatExpr {
288 fn get_comments(&self) -> Vec<&str> {
289 self.token.get_comments()
290 }
291}
292
293#[derive(PartialEq, Clone, Debug)]
294pub struct IntExpr {
295 pub token: Token,
296}
297
298impl IntExpr {
299 pub fn value(&self) -> IntType {
300 self.token.get_int()
301 }
302}
303
304impl Comments for IntExpr {
305 fn get_comments(&self) -> Vec<&str> {
306 self.token.get_comments()
307 }
308}
309
310#[derive(PartialEq, Clone, Debug)]
311pub struct StringExpr {
312 pub token: Token,
313}
314
315impl StringExpr {
316 pub fn value(&self) -> String {
317 self.token.get_string()
318 }
319}
320
321impl Comments for StringExpr {
322 fn get_comments(&self) -> Vec<&str> {
323 self.token.get_comments()
324 }
325}
326
327#[derive(PartialEq, Clone, Debug)]
328pub struct SuffixedExpr {
329 pub primary: Box<Expr>,
330 pub suffixes: Vec<Suffix>,
331}
332
333impl Comments for SuffixedExpr {
334 fn get_comments(&self) -> Vec<&str> {
335 self.primary.get_comments()
336 }
337}
338
339#[derive(Clone, PartialEq, Debug)]
340pub enum Suffix {
341 Attr(Token, StringExpr),
343 Index(Token, Expr, Token),
345 Method(Token, StringExpr),
347 FuncArgs(FuncArgs),
348}
349
350impl Suffix {
351 pub fn unwrap_as_func_args(&self) -> &FuncArgs {
352 match &self {
353 Suffix::FuncArgs(args) => args,
354 _ => unreachable!(),
355 }
356 }
357}
358
359impl Comments for Suffix {
360 fn get_comments(&self) -> Vec<&str> {
361 match &self {
362 Suffix::Attr(token, _) => token.get_comments(),
363 Suffix::Index(token, _, _) => token.get_comments(),
364 Suffix::Method(token, _) => token.get_comments(),
365 Suffix::FuncArgs(args) => args.get_comments(),
366 }
367 }
368}
369
370#[derive(Clone, PartialEq, Debug)]
371pub enum FuncArgs {
372 Exprs(Token, ExprList, Token),
374 Table(Table),
375 String(StringExpr),
376}
377
378impl Comments for FuncArgs {
379 fn get_comments(&self) -> Vec<&str> {
380 match &self {
381 FuncArgs::Exprs(token, _, _) => token.get_comments(),
382 FuncArgs::Table(table) => table.get_comments(),
383 FuncArgs::String(string) => string.get_comments(),
384 }
385 }
386}
387
388#[derive(Default, Clone, PartialEq, Debug)]
389pub struct ExprList {
390 pub exprs: Vec<Expr>,
391 pub commas: Vec<Token>,
392}
393
394impl Comments for ExprList {
395 fn get_comments(&self) -> Vec<&str> {
396 if let Some(expr) = self.exprs.first() {
397 expr.get_comments()
398 } else {
399 Vec::new()
400 }
401 }
402 fn has_comments(&self) -> bool {
403 self.exprs.iter().any(|expr| expr.has_comments())
404 }
405}
406
407#[derive(Clone, PartialEq, Debug)]
408pub struct Table {
409 pub lb: Token,
410 pub fields: Vec<Field>,
411 pub rb: Token,
412}
413
414impl Comments for Table {
415 fn get_comments(&self) -> Vec<&str> {
416 self.lb.get_comments()
417 }
418}
419
420#[derive(Clone, PartialEq, Debug)]
421pub enum Field {
422 RecField(RecField),
423 ListField(ListField),
424}
425
426impl Field {
427 pub fn unwrap_as_list_field(&self) -> &ListField {
428 match &self {
429 Field::ListField(field) => field,
430 _ => unreachable!(),
431 }
432 }
433 pub fn unwrap_as_rec_field(&self) -> &RecField {
434 match &self {
435 Field::RecField(field) => field,
436 _ => unreachable!(),
437 }
438 }
439}
440
441impl Comments for Field {
442 fn get_comments(&self) -> Vec<&str> {
443 match &self {
444 Field::RecField(field) => field.get_comments(),
445 Field::ListField(field) => field.get_comments(),
446 }
447 }
448}
449
450#[derive(Clone, PartialEq, Debug)]
451pub struct RecField {
452 pub key: FieldKey,
453 pub equal: Token,
454 pub value: Expr,
455 pub sep: Option<Token>,
456}
457
458impl Comments for RecField {
459 fn get_comments(&self) -> Vec<&str> {
460 self.key.get_comments()
461 }
462}
463
464#[derive(Clone, PartialEq, Debug)]
465pub struct ListField {
466 pub value: Expr,
467 pub sep: Option<Token>,
468}
469
470impl Comments for ListField {
471 fn get_comments(&self) -> Vec<&str> {
472 self.value.get_comments()
473 }
474}
475
476#[derive(Clone, PartialEq, Debug)]
477pub enum FieldKey {
478 Name(StringExpr),
479 Expr(Token, Expr, Token),
481}
482
483impl FieldKey {
484 pub fn unwrap_as_name(&self) -> &StringExpr {
485 match &self {
486 FieldKey::Name(name) => name,
487 _ => unreachable!(),
488 }
489 }
490 pub fn unwrap_as_expr(&self) -> &Expr {
491 match &self {
492 FieldKey::Expr(_, expr, _) => expr,
493 _ => unreachable!(),
494 }
495 }
496}
497
498impl Comments for FieldKey {
499 fn get_comments(&self) -> Vec<&str> {
500 match &self {
501 FieldKey::Name(name) => name.get_comments(),
502 FieldKey::Expr(token, ..) => token.get_comments(),
503 }
504 }
505}
506
507#[derive(Clone, PartialEq, Debug)]
508pub struct UnExpr {
509 pub op: UnOp,
510 pub expr: Box<Expr>,
511}
512
513impl Comments for UnExpr {
514 fn get_comments(&self) -> Vec<&str> {
515 self.op.get_comments()
516 }
517}
518
519#[derive(Clone, PartialEq, Debug)]
520pub struct BinExpr {
521 pub left: Box<Expr>,
522 pub op: BinOp,
523 pub right: Box<Expr>,
524}
525
526impl Comments for BinExpr {
527 fn get_comments(&self) -> Vec<&str> {
528 self.left.get_comments()
529 }
530}
531
532#[derive(Clone, PartialEq, Debug)]
533pub struct IfStat {
534 pub cond_blocks: Vec<CondBlock>,
535 pub else_: Option<Token>,
536 pub else_block: Option<Block>,
537 pub end: Token,
538}
539
540impl Comments for IfStat {
541 fn get_comments(&self) -> Vec<&str> {
542 if let Some(cond) = self.cond_blocks.first() {
543 cond.get_comments()
544 } else {
545 unreachable!("IfStat should have at least one cond block")
546 }
547 }
548}
549
550#[derive(Clone, PartialEq, Debug)]
551pub struct CondBlock {
552 pub if_: Token,
553 pub cond: Expr,
554 pub then: Token,
555 pub block: Block,
556}
557
558impl Comments for CondBlock {
559 fn get_comments(&self) -> Vec<&str> {
560 self.if_.get_comments()
561 }
562}
563
564#[derive(Clone, PartialEq, Debug)]
565pub struct WhileStat {
566 pub while_: Token,
567 pub cond: Expr,
568 pub do_: Token,
569 pub block: Block,
570 pub end: Token,
571}
572
573impl Comments for WhileStat {
574 fn get_comments(&self) -> Vec<&str> {
575 self.while_.get_comments()
576 }
577}
578
579#[derive(Clone, PartialEq, Debug)]
580pub struct DoBlock {
581 pub do_: Token,
582 pub block: Block,
583 pub end: Token,
584}
585
586impl Comments for DoBlock {
587 fn get_comments(&self) -> Vec<&str> {
588 self.do_.get_comments()
589 }
590}
591
592#[derive(Clone, PartialEq, Debug)]
593pub enum ForStat {
594 ForNum(ForNum),
595 ForList(ForList),
596}
597
598impl Comments for ForStat {
599 fn get_comments(&self) -> Vec<&str> {
600 match &self {
601 ForStat::ForNum(stat) => stat.get_comments(),
602 ForStat::ForList(stat) => stat.get_comments(),
603 }
604 }
605}
606
607#[derive(Clone, PartialEq, Debug)]
608pub struct ForNum {
609 pub for_: Token,
610 pub var: StringExpr,
611 pub equal: Token,
612 pub init: Expr,
613 pub init_comma: Token,
614 pub limit: Expr,
615 pub limit_comma: Option<Token>,
616 pub step: Option<Expr>,
617 pub do_: Token,
618 pub body: Block,
619 pub end: Token,
620}
621
622impl Comments for ForNum {
623 fn get_comments(&self) -> Vec<&str> {
624 self.for_.get_comments()
625 }
626}
627
628#[derive(Clone, PartialEq, Debug)]
629pub struct ForList {
630 pub for_: Token,
631 pub vars: VarList,
632 pub in_: Token,
633 pub exprs: ExprList,
634 pub do_: Token,
635 pub body: Block,
636 pub end: Token,
637}
638
639impl Comments for ForList {
640 fn get_comments(&self) -> Vec<&str> {
641 self.for_.get_comments()
642 }
643}
644
645#[derive(Clone, PartialEq, Debug)]
646pub struct VarList {
647 pub vars: Vec<StringExpr>,
648 pub delimiters: Vec<Token>,
649}
650
651impl Comments for VarList {
652 fn get_comments(&self) -> Vec<&str> {
653 if let Some(var) = self.vars.first() {
654 var.get_comments()
655 } else {
656 unreachable!("VarList should have at least one var")
657 }
658 }
659}
660
661#[derive(Clone, PartialEq, Debug)]
662pub struct RepeatStat {
663 pub repeat: Token,
664 pub block: Block,
665 pub until: Token,
666 pub cond: Expr,
667}
668
669impl Comments for RepeatStat {
670 fn get_comments(&self) -> Vec<&str> {
671 self.repeat.get_comments()
672 }
673}
674
675#[derive(Clone, PartialEq, Debug)]
676pub enum FuncType {
677 Global,
678 Local(Token),
679}
680
681#[derive(Clone, PartialEq, Debug)]
682pub struct FuncStat {
683 pub func_type: FuncType,
684 pub function: Token,
685 pub func_name: FuncName,
686 pub body: FuncBody,
687}
688
689impl Comments for FuncStat {
690 fn get_comments(&self) -> Vec<&str> {
691 match &self.func_type {
692 FuncType::Global => self.function.get_comments(),
693 FuncType::Local(token) => token.get_comments(),
694 }
695 }
696}
697
698#[derive(Clone, PartialEq, Debug)]
699pub struct FuncName {
700 pub fields: VarList,
702 pub method: Option<(Token, StringExpr)>,
704}
705
706impl Comments for FuncName {
707 fn get_comments(&self) -> Vec<&str> {
708 if let Some(field) = self.fields.vars.first() {
709 field.get_comments()
710 } else {
711 unreachable!("FuncName should have at least one field")
712 }
713 }
714}
715
716#[derive(Clone, PartialEq, Debug)]
717pub struct FuncBody {
718 pub lp: Token,
719 pub params: ParamList,
720 pub rp: Token,
721 pub block: Block,
722 pub end: Token,
723}
724
725impl Comments for FuncBody {
726 fn get_comments(&self) -> Vec<&str> {
727 self.lp.get_comments()
728 }
729}
730
731#[derive(Clone, PartialEq, Debug)]
732pub struct ParamList {
733 pub params: Vec<Param>,
734 pub commas: Vec<Token>,
735}
736
737#[derive(Clone, PartialEq, Debug)]
738pub enum Param {
739 VarArg(Token),
740 Name(StringExpr),
741}
742
743impl Param {
744 pub fn unwrap_as_name(&self) -> String {
745 match self {
746 Param::Name(expr) => expr.value(),
747 _ => unreachable!(),
748 }
749 }
750}
751
752impl Comments for Param {
753 fn get_comments(&self) -> Vec<&str> {
754 match &self {
755 Param::VarArg(token) => token.get_comments(),
756 Param::Name(expr) => expr.get_comments(),
757 }
758 }
759}
760
761#[derive(Clone, PartialEq, Debug)]
762pub struct LocalStat {
763 pub local: Token,
764 pub names: VarList,
765 pub equal: Option<Token>,
766 pub exprs: Option<ExprList>,
767}
768
769impl Comments for LocalStat {
770 fn get_comments(&self) -> Vec<&str> {
771 self.local.get_comments()
772 }
773}
774
775#[derive(Clone, PartialEq, Debug)]
776pub struct LabelStat {
777 pub ldc: Token,
778 pub label: StringExpr,
779 pub rdc: Token,
780}
781
782impl Comments for LabelStat {
783 fn get_comments(&self) -> Vec<&str> {
784 self.ldc.get_comments()
785 }
786}
787
788#[derive(Clone, PartialEq, Debug)]
789pub struct RetStat {
790 pub return_: Token,
791 pub exprs: Option<ExprList>,
792 pub semi: Option<Token>,
793}
794
795impl Comments for RetStat {
796 fn get_comments(&self) -> Vec<&str> {
797 self.return_.get_comments()
798 }
799}
800
801#[derive(Clone, PartialEq, Debug)]
802pub struct BreakStat {
803 pub token: Token,
804}
805
806impl Comments for BreakStat {
807 fn get_comments(&self) -> Vec<&str> {
808 self.token.get_comments()
809 }
810}
811
812#[derive(Clone, PartialEq, Debug)]
813pub struct GotoStat {
814 pub goto: Token,
815 pub label: StringExpr,
816}
817
818impl Comments for GotoStat {
819 fn get_comments(&self) -> Vec<&str> {
820 self.goto.get_comments()
821 }
822}
823
824#[derive(Clone, PartialEq, Debug)]
825pub struct AssignStat {
826 pub left: AssignableList,
827 pub equal: Token,
828 pub right: ExprList,
829}
830
831impl Comments for AssignStat {
832 fn get_comments(&self) -> Vec<&str> {
833 if let Some(assignable) = self.left.assignables.first() {
834 assignable.get_comments()
835 } else {
836 unreachable!("AssignStat should have at least one assignable")
837 }
838 }
839}
840
841#[derive(Clone, PartialEq, Debug)]
842pub struct AssignableList {
843 pub assignables: Vec<Assignable>,
844 pub commas: Vec<Token>,
845}
846
847#[derive(Clone, PartialEq, Debug)]
848pub struct CallStat {
849 pub call: Assignable,
850}
851
852impl Comments for CallStat {
853 fn get_comments(&self) -> Vec<&str> {
854 self.call.get_comments()
855 }
856}
857
858#[derive(Clone, PartialEq, Debug)]
859pub enum Stat {
860 IfStat(IfStat),
861 WhileStat(WhileStat),
862 DoBlock(DoBlock),
863 ForStat(ForStat),
864 RepeatStat(RepeatStat),
865 FuncStat(FuncStat),
866 LocalStat(LocalStat),
867 LabelStat(LabelStat),
868 RetStat(RetStat),
869 BreakStat(BreakStat),
870 GotoStat(GotoStat),
871 AssignStat(AssignStat),
872 CallStat(CallStat),
873}
874
875impl Comments for Stat {
876 fn get_comments(&self) -> Vec<&str> {
877 match self {
878 Stat::IfStat(stat) => stat.get_comments(),
879 Stat::WhileStat(stat) => stat.get_comments(),
880 Stat::DoBlock(stat) => stat.get_comments(),
881 Stat::ForStat(stat) => stat.get_comments(),
882 Stat::RepeatStat(stat) => stat.get_comments(),
883 Stat::FuncStat(stat) => stat.get_comments(),
884 Stat::LocalStat(stat) => stat.get_comments(),
885 Stat::LabelStat(stat) => stat.get_comments(),
886 Stat::RetStat(stat) => stat.get_comments(),
887 Stat::BreakStat(stat) => stat.get_comments(),
888 Stat::GotoStat(stat) => stat.get_comments(),
889 Stat::AssignStat(stat) => stat.get_comments(),
890 Stat::CallStat(stat) => stat.get_comments(),
891 }
892 }
893}
894
895#[derive(Clone, PartialEq, Debug)]
896pub struct Block {
897 pub stats: Vec<Stat>,
898}
899
900impl Comments for Block {
901 fn get_comments(&self) -> Vec<&str> {
902 if let Some(stat) = self.stats.first() {
903 stat.get_comments()
904 } else {
905 Vec::new()
906 }
907 }
908}