1use std::fmt;
2use std::slice::Iter;
3
4use crate::ast::Elem::*;
5use crate::interner::{Interner, Name};
6use crate::lexer::position::{Position, Span};
7use crate::lexer::token::{FloatSuffix, IntBase, IntSuffix};
8
9pub mod dump;
10pub mod visit;
11
12#[derive(Clone, Debug)]
13pub struct Ast {
14 pub files: Vec<File>,
15}
16
17impl Ast {
18 pub fn new() -> Ast {
19 Ast { files: Vec::new() }
20 }
21
22 #[cfg(test)]
23 pub fn fct0(&self) -> &Function {
24 self.files.last().unwrap().elements[0]
25 .to_function()
26 .unwrap()
27 }
28
29 #[cfg(test)]
30 pub fn fct(&self, index: usize) -> &Function {
31 self.files.last().unwrap().elements[index]
32 .to_function()
33 .unwrap()
34 }
35
36 #[cfg(test)]
37 pub fn cls0(&self) -> &Class {
38 self.files.last().unwrap().elements[0].to_class().unwrap()
39 }
40
41 #[cfg(test)]
42 pub fn cls(&self, index: usize) -> &Class {
43 self.files.last().unwrap().elements[index]
44 .to_class()
45 .unwrap()
46 }
47
48 #[cfg(test)]
49 pub fn struct0(&self) -> &Struct {
50 self.files.last().unwrap().elements[0].to_struct().unwrap()
51 }
52
53 #[cfg(test)]
54 pub fn trai(&self, index: usize) -> &Trait {
55 self.files.last().unwrap().elements[index]
56 .to_trait()
57 .unwrap()
58 }
59
60 #[cfg(test)]
61 pub fn trait0(&self) -> &Trait {
62 self.files.last().unwrap().elements[0].to_trait().unwrap()
63 }
64
65 #[cfg(test)]
66 pub fn impl0(&self) -> &Impl {
67 self.files.last().unwrap().elements[0].to_impl().unwrap()
68 }
69
70 #[cfg(test)]
71 pub fn mod0(&self) -> &Module {
72 self.files.last().unwrap().elements[0].to_module().unwrap()
73 }
74
75 #[cfg(test)]
76 pub fn modu(&self, index: usize) -> &Module {
77 self.files.last().unwrap().elements[index]
78 .to_module()
79 .unwrap()
80 }
81
82 #[cfg(test)]
83 pub fn global0(&self) -> &Global {
84 self.files.last().unwrap().elements[0].to_global().unwrap()
85 }
86
87 #[cfg(test)]
88 pub fn const0(&self) -> &Const {
89 self.files.last().unwrap().elements[0].to_const().unwrap()
90 }
91}
92
93#[derive(Clone, Debug)]
94pub struct File {
95 pub path: String,
96 pub elements: Vec<Elem>,
97}
98
99#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
100pub struct NodeId(pub usize);
101
102impl fmt::Display for NodeId {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 write!(f, "#{}", self.0)
105 }
106}
107
108#[derive(Clone, Debug)]
109pub enum Elem {
110 ElemFunction(Function),
111 ElemClass(Class),
112 ElemStruct(Struct),
113 ElemTrait(Trait),
114 ElemImpl(Impl),
115 ElemModule(Module),
116 ElemGlobal(Global),
117 ElemConst(Const),
118 ElemEnum(Enum),
119}
120
121impl Elem {
122 pub fn id(&self) -> NodeId {
123 match self {
124 &ElemFunction(ref fct) => fct.id,
125 &ElemClass(ref class) => class.id,
126 &ElemStruct(ref s) => s.id,
127 &ElemTrait(ref t) => t.id,
128 &ElemImpl(ref i) => i.id,
129 &ElemModule(ref m) => m.id,
130 &ElemGlobal(ref g) => g.id,
131 &ElemConst(ref c) => c.id,
132 &ElemEnum(ref e) => e.id,
133 }
134 }
135
136 pub fn to_function(&self) -> Option<&Function> {
137 match self {
138 &ElemFunction(ref fct) => Some(fct),
139 _ => None,
140 }
141 }
142
143 pub fn to_class(&self) -> Option<&Class> {
144 match self {
145 &ElemClass(ref class) => Some(class),
146 _ => None,
147 }
148 }
149
150 pub fn to_struct(&self) -> Option<&Struct> {
151 match self {
152 &ElemStruct(ref struc) => Some(struc),
153 _ => None,
154 }
155 }
156
157 pub fn to_trait(&self) -> Option<&Trait> {
158 match self {
159 &ElemTrait(ref trai) => Some(trai),
160 _ => None,
161 }
162 }
163
164 pub fn to_impl(&self) -> Option<&Impl> {
165 match self {
166 &ElemImpl(ref ximpl) => Some(ximpl),
167 _ => None,
168 }
169 }
170
171 pub fn to_module(&self) -> Option<&Module> {
172 match self {
173 &ElemModule(ref module) => Some(module),
174 _ => None,
175 }
176 }
177
178 pub fn to_global(&self) -> Option<&Global> {
179 match self {
180 &ElemGlobal(ref global) => Some(global),
181 _ => None,
182 }
183 }
184
185 pub fn to_const(&self) -> Option<&Const> {
186 match self {
187 &ElemConst(ref konst) => Some(konst),
188 _ => None,
189 }
190 }
191}
192
193#[derive(Clone, Debug)]
194pub struct Global {
195 pub id: NodeId,
196 pub pos: Position,
197 pub span: Span,
198 pub name: Name,
199 pub reassignable: bool,
200 pub data_type: Type,
201 pub expr: Option<Box<Expr>>,
202}
203
204#[derive(Clone, Debug)]
205pub struct Const {
206 pub id: NodeId,
207 pub pos: Position,
208 pub span: Span,
209 pub name: Name,
210 pub data_type: Type,
211 pub expr: Box<Expr>,
212}
213
214#[derive(Clone, Debug)]
215pub struct Enum {
216 pub id: NodeId,
217 pub pos: Position,
218 pub span: Span,
219 pub name: Name,
220 pub values: Vec<Box<Expr>>,
221}
222
223#[derive(Clone, Debug)]
224pub struct Struct {
225 pub id: NodeId,
226 pub pos: Position,
227 pub span: Span,
228 pub name: Name,
229 pub fields: Vec<StructField>,
230}
231
232#[derive(Clone, Debug)]
233pub struct StructField {
234 pub id: NodeId,
235 pub name: Name,
236 pub pos: Position,
237 pub span: Span,
238 pub data_type: Type,
239}
240
241#[derive(Clone, Debug)]
242pub enum Type {
243 TypeSelf(TypeSelfType),
244 TypeBasic(TypeBasicType),
245 TypeTuple(TypeTupleType),
246 TypeLambda(TypeLambdaType),
247}
248
249#[derive(Clone, Debug)]
250pub struct TypeSelfType {
251 pub id: NodeId,
252 pub pos: Position,
253 pub span: Span,
254}
255
256#[derive(Clone, Debug)]
257pub struct TypeTupleType {
258 pub id: NodeId,
259 pub pos: Position,
260 pub span: Span,
261
262 pub subtypes: Vec<Box<Type>>,
263}
264
265#[derive(Clone, Debug)]
266pub struct TypeLambdaType {
267 pub id: NodeId,
268 pub pos: Position,
269 pub span: Span,
270
271 pub params: Vec<Box<Type>>,
272 pub ret: Box<Type>,
273}
274
275#[derive(Clone, Debug)]
276pub struct TypeBasicType {
277 pub id: NodeId,
278 pub pos: Position,
279 pub span: Span,
280
281 pub name: Name,
282 pub params: Vec<Box<Type>>,
283}
284
285impl Type {
286 pub fn create_self(id: NodeId, pos: Position, span: Span) -> Type {
287 Type::TypeSelf(TypeSelfType { id, pos, span })
288 }
289
290 pub fn create_basic(
291 id: NodeId,
292 pos: Position,
293 span: Span,
294 name: Name,
295 params: Vec<Box<Type>>,
296 ) -> Type {
297 Type::TypeBasic(TypeBasicType {
298 id,
299 pos,
300 span,
301 name,
302 params,
303 })
304 }
305
306 pub fn create_fct(
307 id: NodeId,
308 pos: Position,
309 span: Span,
310 params: Vec<Box<Type>>,
311 ret: Box<Type>,
312 ) -> Type {
313 Type::TypeLambda(TypeLambdaType {
314 id,
315 pos,
316 span,
317 params,
318 ret,
319 })
320 }
321
322 pub fn create_tuple(id: NodeId, pos: Position, span: Span, subtypes: Vec<Box<Type>>) -> Type {
323 Type::TypeTuple(TypeTupleType {
324 id,
325 pos,
326 span,
327 subtypes,
328 })
329 }
330
331 pub fn to_basic(&self) -> Option<&TypeBasicType> {
332 match *self {
333 Type::TypeBasic(ref val) => Some(val),
334 _ => None,
335 }
336 }
337
338 pub fn to_basic_without_type_params(&self) -> Option<Name> {
339 match *self {
340 Type::TypeBasic(ref basic) => {
341 if basic.params.len() == 0 {
342 Some(basic.name)
343 } else {
344 None
345 }
346 }
347
348 _ => None,
349 }
350 }
351
352 pub fn to_tuple(&self) -> Option<&TypeTupleType> {
353 match *self {
354 Type::TypeTuple(ref val) => Some(val),
355 _ => None,
356 }
357 }
358
359 pub fn to_fct(&self) -> Option<&TypeLambdaType> {
360 match *self {
361 Type::TypeLambda(ref val) => Some(val),
362 _ => None,
363 }
364 }
365
366 #[cfg(test)]
367 pub fn is_unit(&self) -> bool {
368 match self {
369 &Type::TypeTuple(ref val) if val.subtypes.len() == 0 => true,
370 _ => false,
371 }
372 }
373
374 pub fn to_string(&self, interner: &Interner) -> String {
375 match *self {
376 Type::TypeSelf(_) => "Self".into(),
377 Type::TypeBasic(ref val) => format!("{}", *interner.str(val.name)),
378
379 Type::TypeTuple(ref val) => {
380 let types: Vec<String> =
381 val.subtypes.iter().map(|t| t.to_string(interner)).collect();
382
383 format!("({})", types.join(", "))
384 }
385
386 Type::TypeLambda(ref val) => {
387 let types: Vec<String> = val.params.iter().map(|t| t.to_string(interner)).collect();
388 let ret = val.ret.to_string(interner);
389
390 format!("({}) -> {}", types.join(", "), ret)
391 }
392 }
393 }
394
395 pub fn pos(&self) -> Position {
396 match *self {
397 Type::TypeSelf(ref val) => val.pos,
398 Type::TypeBasic(ref val) => val.pos,
399 Type::TypeTuple(ref val) => val.pos,
400 Type::TypeLambda(ref val) => val.pos,
401 }
402 }
403
404 pub fn id(&self) -> NodeId {
405 match *self {
406 Type::TypeSelf(ref val) => val.id,
407 Type::TypeBasic(ref val) => val.id,
408 Type::TypeTuple(ref val) => val.id,
409 Type::TypeLambda(ref val) => val.id,
410 }
411 }
412}
413
414#[derive(Clone, Debug)]
415pub struct Impl {
416 pub id: NodeId,
417 pub pos: Position,
418 pub span: Span,
419
420 pub type_params: Option<Vec<TypeParam>>,
421 pub trait_type: Option<Type>,
422 pub class_type: Type,
423 pub methods: Vec<Function>,
424}
425
426#[derive(Clone, Debug)]
427pub struct Trait {
428 pub id: NodeId,
429 pub name: Name,
430 pub pos: Position,
431 pub span: Span,
432 pub methods: Vec<Function>,
433}
434
435#[derive(Clone, Debug)]
436pub struct Class {
437 pub id: NodeId,
438 pub name: Name,
439 pub pos: Position,
440 pub span: Span,
441 pub parent_class: Option<ParentClass>,
442 pub has_open: bool,
443 pub is_abstract: bool,
444 pub internal: bool,
445 pub has_constructor: bool,
446
447 pub constructor: Option<Function>,
448 pub fields: Vec<Field>,
449 pub methods: Vec<Function>,
450 pub initializers: Vec<Box<Stmt>>,
451 pub type_params: Option<Vec<TypeParam>>,
452}
453
454#[derive(Clone, Debug)]
455pub struct Module {
456 pub id: NodeId,
457 pub name: Name,
458 pub pos: Position,
459 pub parent_class: Option<ParentClass>,
460 pub internal: bool,
461 pub has_constructor: bool,
462
463 pub constructor: Option<Function>,
464 pub fields: Vec<Field>,
465 pub methods: Vec<Function>,
466 pub initializers: Vec<Box<Stmt>>,
467}
468
469#[derive(Clone, Debug)]
470pub struct TypeParam {
471 pub name: Name,
472 pub pos: Position,
473 pub span: Span,
474 pub bounds: Vec<Type>,
475}
476
477#[derive(Clone, Debug)]
478pub struct ConstructorParam {
479 pub name: Name,
480 pub pos: Position,
481 pub span: Span,
482 pub data_type: Type,
483 pub field: bool,
484 pub reassignable: bool,
485}
486
487#[derive(Clone, Debug)]
488pub struct ParentClass {
489 pub name: Name,
490 pub pos: Position,
491 pub span: Span,
492 pub type_params: Vec<Type>,
493 pub params: Vec<Box<Expr>>,
494}
495
496impl ParentClass {
497 pub fn new(
498 name: Name,
499 pos: Position,
500 span: Span,
501 type_params: Vec<Type>,
502 params: Vec<Box<Expr>>,
503 ) -> ParentClass {
504 ParentClass {
505 name,
506 pos,
507 span,
508 type_params,
509 params,
510 }
511 }
512}
513
514#[derive(Clone, Debug)]
515pub struct Field {
516 pub id: NodeId,
517 pub name: Name,
518 pub pos: Position,
519 pub span: Span,
520 pub data_type: Type,
521 pub primary_ctor: bool,
522 pub expr: Option<Box<Expr>>,
523 pub reassignable: bool,
524}
525
526#[derive(Clone, Debug)]
527pub struct Function {
528 pub id: NodeId,
529 pub name: Name,
530 pub pos: Position,
531 pub span: Span,
532 pub method: bool,
533 pub has_open: bool,
534 pub has_override: bool,
535 pub has_final: bool,
536 pub has_optimize: bool,
537 pub has_optimize_immediately: bool,
538 pub is_pub: bool,
539 pub is_static: bool,
540 pub is_abstract: bool,
541 pub is_test: bool,
542 pub use_cannon: bool,
543 pub internal: bool,
544 pub is_constructor: bool,
545
546 pub params: Vec<Param>,
547 pub throws: bool,
548
549 pub return_type: Option<Type>,
550 pub block: Option<Box<ExprBlockType>>,
551 pub type_params: Option<Vec<TypeParam>>,
552}
553
554impl Function {
555 pub fn block(&self) -> &ExprBlockType {
556 self.block.as_ref().unwrap()
557 }
558}
559
560#[derive(Clone, Debug)]
561pub struct Modifiers(Vec<ModifierElement>);
562
563impl Modifiers {
564 pub fn new() -> Modifiers {
565 Modifiers(Vec::new())
566 }
567
568 pub fn contains(&self, modifier: Modifier) -> bool {
569 self.0.iter().find(|el| el.value == modifier).is_some()
570 }
571
572 pub fn add(&mut self, modifier: Modifier, pos: Position, span: Span) {
573 self.0.push(ModifierElement {
574 value: modifier,
575 pos,
576 span,
577 });
578 }
579
580 pub fn iter(&self) -> Iter<ModifierElement> {
581 self.0.iter()
582 }
583}
584
585#[derive(Clone, Debug)]
586pub struct ModifierElement {
587 pub value: Modifier,
588 pub pos: Position,
589 pub span: Span,
590}
591
592#[derive(Copy, Clone, Debug, PartialEq, Eq)]
593pub enum Modifier {
594 Abstract,
595 Override,
596 Open,
597 Final,
598 Internal,
599 Optimize,
600 Pub,
601 Static,
602 Test,
603 Cannon,
604 OptimizeImmediately,
605}
606
607impl Modifier {
608 pub fn name(&self) -> &'static str {
609 match *self {
610 Modifier::Abstract => "abstract",
611 Modifier::Open => "open",
612 Modifier::Override => "override",
613 Modifier::Final => "final",
614 Modifier::Internal => "internal",
615 Modifier::Optimize => "optimize",
616 Modifier::Pub => "pub",
617 Modifier::Static => "static",
618 Modifier::Test => "test",
619 Modifier::Cannon => "cannon",
620 Modifier::OptimizeImmediately => "optimize_immediately",
621 }
622 }
623}
624
625#[derive(Clone, Debug)]
626pub struct Param {
627 pub id: NodeId,
628 pub idx: u32,
629 pub reassignable: bool,
630 pub name: Name,
631 pub pos: Position,
632 pub span: Span,
633 pub data_type: Type,
634}
635
636#[derive(Clone, Debug)]
637pub enum Stmt {
638 StmtVar(StmtVarType),
639 StmtWhile(StmtWhileType),
640 StmtLoop(StmtLoopType),
641 StmtExpr(StmtExprType),
642 StmtBreak(StmtBreakType),
643 StmtContinue(StmtContinueType),
644 StmtReturn(StmtReturnType),
645 StmtThrow(StmtThrowType),
646 StmtDefer(StmtDeferType),
647 StmtDo(StmtDoType),
648 StmtFor(StmtForType),
649}
650
651impl Stmt {
652 pub fn create_var(
653 id: NodeId,
654 pos: Position,
655 span: Span,
656 name: Name,
657 reassignable: bool,
658 data_type: Option<Type>,
659 expr: Option<Box<Expr>>,
660 ) -> Stmt {
661 Stmt::StmtVar(StmtVarType {
662 id,
663 pos,
664 span,
665
666 name,
667 reassignable,
668 data_type,
669 expr,
670 })
671 }
672
673 pub fn create_for(
674 id: NodeId,
675 pos: Position,
676 span: Span,
677 name: Name,
678 expr: Box<Expr>,
679 block: Box<Stmt>,
680 ) -> Stmt {
681 Stmt::StmtFor(StmtForType {
682 id,
683 pos,
684 span,
685
686 name,
687 expr,
688 block,
689 })
690 }
691
692 pub fn create_while(
693 id: NodeId,
694 pos: Position,
695 span: Span,
696 cond: Box<Expr>,
697 block: Box<Stmt>,
698 ) -> Stmt {
699 Stmt::StmtWhile(StmtWhileType {
700 id,
701 pos,
702 span,
703
704 cond,
705 block,
706 })
707 }
708
709 pub fn create_loop(id: NodeId, pos: Position, span: Span, block: Box<Stmt>) -> Stmt {
710 Stmt::StmtLoop(StmtLoopType {
711 id,
712 pos,
713 span,
714
715 block,
716 })
717 }
718
719 pub fn create_expr(id: NodeId, pos: Position, span: Span, expr: Box<Expr>) -> Stmt {
720 Stmt::StmtExpr(StmtExprType {
721 id,
722 pos,
723 span,
724
725 expr,
726 })
727 }
728
729 pub fn create_break(id: NodeId, pos: Position, span: Span) -> Stmt {
730 Stmt::StmtBreak(StmtBreakType { id, pos, span })
731 }
732
733 pub fn create_continue(id: NodeId, pos: Position, span: Span) -> Stmt {
734 Stmt::StmtContinue(StmtContinueType { id, pos, span })
735 }
736
737 pub fn create_return(id: NodeId, pos: Position, span: Span, expr: Option<Box<Expr>>) -> Stmt {
738 Stmt::StmtReturn(StmtReturnType {
739 id,
740 pos,
741 span,
742
743 expr,
744 })
745 }
746
747 pub fn create_throw(id: NodeId, pos: Position, span: Span, expr: Box<Expr>) -> Stmt {
748 Stmt::StmtThrow(StmtThrowType {
749 id,
750 pos,
751 span,
752
753 expr,
754 })
755 }
756
757 pub fn create_defer(id: NodeId, pos: Position, span: Span, expr: Box<Expr>) -> Stmt {
758 Stmt::StmtDefer(StmtDeferType {
759 id,
760 pos,
761 span,
762
763 expr,
764 })
765 }
766
767 pub fn create_do(
768 id: NodeId,
769 pos: Position,
770 span: Span,
771 do_block: Box<Stmt>,
772 catch_blocks: Vec<CatchBlock>,
773 finally_block: Option<FinallyBlock>,
774 ) -> Stmt {
775 Stmt::StmtDo(StmtDoType {
776 id,
777 pos,
778 span,
779
780 do_block,
781 catch_blocks,
782 finally_block,
783 })
784 }
785
786 pub fn id(&self) -> NodeId {
787 match *self {
788 Stmt::StmtVar(ref stmt) => stmt.id,
789 Stmt::StmtWhile(ref stmt) => stmt.id,
790 Stmt::StmtFor(ref stmt) => stmt.id,
791 Stmt::StmtLoop(ref stmt) => stmt.id,
792 Stmt::StmtExpr(ref stmt) => stmt.id,
793 Stmt::StmtBreak(ref stmt) => stmt.id,
794 Stmt::StmtContinue(ref stmt) => stmt.id,
795 Stmt::StmtReturn(ref stmt) => stmt.id,
796 Stmt::StmtThrow(ref stmt) => stmt.id,
797 Stmt::StmtDefer(ref stmt) => stmt.id,
798 Stmt::StmtDo(ref stmt) => stmt.id,
799 }
800 }
801
802 pub fn pos(&self) -> Position {
803 match *self {
804 Stmt::StmtVar(ref stmt) => stmt.pos,
805 Stmt::StmtWhile(ref stmt) => stmt.pos,
806 Stmt::StmtFor(ref stmt) => stmt.pos,
807 Stmt::StmtLoop(ref stmt) => stmt.pos,
808 Stmt::StmtExpr(ref stmt) => stmt.pos,
809 Stmt::StmtBreak(ref stmt) => stmt.pos,
810 Stmt::StmtContinue(ref stmt) => stmt.pos,
811 Stmt::StmtReturn(ref stmt) => stmt.pos,
812 Stmt::StmtThrow(ref stmt) => stmt.pos,
813 Stmt::StmtDefer(ref stmt) => stmt.pos,
814 Stmt::StmtDo(ref stmt) => stmt.pos,
815 }
816 }
817
818 pub fn span(&self) -> Span {
819 match *self {
820 Stmt::StmtVar(ref stmt) => stmt.span,
821 Stmt::StmtWhile(ref stmt) => stmt.span,
822 Stmt::StmtFor(ref stmt) => stmt.span,
823 Stmt::StmtLoop(ref stmt) => stmt.span,
824 Stmt::StmtExpr(ref stmt) => stmt.span,
825 Stmt::StmtBreak(ref stmt) => stmt.span,
826 Stmt::StmtContinue(ref stmt) => stmt.span,
827 Stmt::StmtReturn(ref stmt) => stmt.span,
828 Stmt::StmtThrow(ref stmt) => stmt.span,
829 Stmt::StmtDefer(ref stmt) => stmt.span,
830 Stmt::StmtDo(ref stmt) => stmt.span,
831 }
832 }
833
834 pub fn to_throw(&self) -> Option<&StmtThrowType> {
835 match *self {
836 Stmt::StmtThrow(ref val) => Some(val),
837 _ => None,
838 }
839 }
840
841 pub fn is_throw(&self) -> bool {
842 match *self {
843 Stmt::StmtThrow(_) => true,
844 _ => false,
845 }
846 }
847
848 pub fn to_defer(&self) -> Option<&StmtDeferType> {
849 match *self {
850 Stmt::StmtDefer(ref val) => Some(val),
851 _ => None,
852 }
853 }
854
855 pub fn is_defer(&self) -> bool {
856 match *self {
857 Stmt::StmtDefer(_) => true,
858 _ => false,
859 }
860 }
861
862 pub fn to_do(&self) -> Option<&StmtDoType> {
863 match *self {
864 Stmt::StmtDo(ref val) => Some(val),
865 _ => None,
866 }
867 }
868
869 pub fn is_try(&self) -> bool {
870 match *self {
871 Stmt::StmtDo(_) => true,
872 _ => false,
873 }
874 }
875
876 pub fn to_var(&self) -> Option<&StmtVarType> {
877 match *self {
878 Stmt::StmtVar(ref val) => Some(val),
879 _ => None,
880 }
881 }
882
883 pub fn is_var(&self) -> bool {
884 match *self {
885 Stmt::StmtVar(_) => true,
886 _ => false,
887 }
888 }
889
890 pub fn to_while(&self) -> Option<&StmtWhileType> {
891 match *self {
892 Stmt::StmtWhile(ref val) => Some(val),
893 _ => None,
894 }
895 }
896
897 pub fn is_while(&self) -> bool {
898 match *self {
899 Stmt::StmtWhile(_) => true,
900 _ => false,
901 }
902 }
903
904 pub fn to_for(&self) -> Option<&StmtForType> {
905 match *self {
906 Stmt::StmtFor(ref val) => Some(val),
907 _ => None,
908 }
909 }
910
911 pub fn is_for(&self) -> bool {
912 match *self {
913 Stmt::StmtFor(_) => true,
914 _ => false,
915 }
916 }
917
918 pub fn to_loop(&self) -> Option<&StmtLoopType> {
919 match *self {
920 Stmt::StmtLoop(ref val) => Some(val),
921 _ => None,
922 }
923 }
924
925 pub fn is_loop(&self) -> bool {
926 match *self {
927 Stmt::StmtLoop(_) => true,
928 _ => false,
929 }
930 }
931
932 pub fn to_expr(&self) -> Option<&StmtExprType> {
933 match *self {
934 Stmt::StmtExpr(ref val) => Some(val),
935 _ => None,
936 }
937 }
938
939 pub fn is_expr(&self) -> bool {
940 match *self {
941 Stmt::StmtExpr(_) => true,
942 _ => false,
943 }
944 }
945
946 pub fn to_return(&self) -> Option<&StmtReturnType> {
947 match *self {
948 Stmt::StmtReturn(ref val) => Some(val),
949 _ => None,
950 }
951 }
952
953 pub fn is_return(&self) -> bool {
954 match *self {
955 Stmt::StmtReturn(_) => true,
956 _ => false,
957 }
958 }
959
960 pub fn to_break(&self) -> Option<&StmtBreakType> {
961 match *self {
962 Stmt::StmtBreak(ref val) => Some(val),
963 _ => None,
964 }
965 }
966
967 pub fn is_break(&self) -> bool {
968 match *self {
969 Stmt::StmtBreak(_) => true,
970 _ => false,
971 }
972 }
973
974 pub fn to_continue(&self) -> Option<&StmtContinueType> {
975 match *self {
976 Stmt::StmtContinue(ref val) => Some(val),
977 _ => None,
978 }
979 }
980
981 pub fn is_continue(&self) -> bool {
982 match *self {
983 Stmt::StmtContinue(_) => true,
984 _ => false,
985 }
986 }
987}
988
989#[derive(Clone, Debug)]
990pub struct StmtVarType {
991 pub id: NodeId,
992 pub pos: Position,
993 pub span: Span,
994
995 pub name: Name,
996 pub reassignable: bool,
997
998 pub data_type: Option<Type>,
999 pub expr: Option<Box<Expr>>,
1000}
1001
1002#[derive(Clone, Debug)]
1003pub struct StmtForType {
1004 pub id: NodeId,
1005 pub pos: Position,
1006 pub span: Span,
1007
1008 pub name: Name,
1009 pub expr: Box<Expr>,
1010 pub block: Box<Stmt>,
1011}
1012
1013#[derive(Clone, Debug)]
1014pub struct StmtWhileType {
1015 pub id: NodeId,
1016 pub pos: Position,
1017 pub span: Span,
1018
1019 pub cond: Box<Expr>,
1020 pub block: Box<Stmt>,
1021}
1022
1023#[derive(Clone, Debug)]
1024pub struct StmtLoopType {
1025 pub id: NodeId,
1026 pub pos: Position,
1027 pub span: Span,
1028
1029 pub block: Box<Stmt>,
1030}
1031
1032#[derive(Clone, Debug)]
1033pub struct StmtExprType {
1034 pub id: NodeId,
1035 pub pos: Position,
1036 pub span: Span,
1037
1038 pub expr: Box<Expr>,
1039}
1040
1041#[derive(Clone, Debug)]
1042pub struct StmtReturnType {
1043 pub id: NodeId,
1044 pub pos: Position,
1045 pub span: Span,
1046
1047 pub expr: Option<Box<Expr>>,
1048}
1049
1050#[derive(Clone, Debug)]
1051pub struct StmtBreakType {
1052 pub id: NodeId,
1053 pub pos: Position,
1054 pub span: Span,
1055}
1056
1057#[derive(Clone, Debug)]
1058pub struct StmtContinueType {
1059 pub id: NodeId,
1060 pub pos: Position,
1061 pub span: Span,
1062}
1063
1064#[derive(Clone, Debug)]
1065pub struct StmtThrowType {
1066 pub id: NodeId,
1067 pub pos: Position,
1068 pub span: Span,
1069
1070 pub expr: Box<Expr>,
1071}
1072
1073#[derive(Clone, Debug)]
1074pub struct StmtDeferType {
1075 pub id: NodeId,
1076 pub pos: Position,
1077 pub span: Span,
1078
1079 pub expr: Box<Expr>,
1080}
1081
1082#[derive(Clone, Debug)]
1083pub struct StmtDoType {
1084 pub id: NodeId,
1085 pub pos: Position,
1086 pub span: Span,
1087
1088 pub do_block: Box<Stmt>,
1089 pub catch_blocks: Vec<CatchBlock>,
1090 pub finally_block: Option<FinallyBlock>,
1091}
1092
1093#[derive(Clone, Debug)]
1094pub struct CatchBlock {
1095 pub id: NodeId,
1096 pub name: Name,
1097 pub pos: Position,
1098 pub span: Span,
1099
1100 pub data_type: Type,
1101 pub block: Box<Stmt>,
1102}
1103
1104impl CatchBlock {
1105 pub fn new(
1106 id: NodeId,
1107 name: Name,
1108 pos: Position,
1109 span: Span,
1110 data_type: Type,
1111 block: Box<Stmt>,
1112 ) -> CatchBlock {
1113 CatchBlock {
1114 id,
1115 name,
1116 pos,
1117 span,
1118
1119 data_type,
1120 block,
1121 }
1122 }
1123}
1124
1125#[derive(Clone, Debug)]
1126pub struct FinallyBlock {
1127 pub block: Box<Stmt>,
1128}
1129
1130impl FinallyBlock {
1131 pub fn new(block: Box<Stmt>) -> FinallyBlock {
1132 FinallyBlock { block }
1133 }
1134}
1135
1136#[derive(PartialEq, Eq, Debug, Copy, Clone)]
1137pub enum UnOp {
1138 Plus,
1139 Neg,
1140 Not,
1141}
1142
1143impl UnOp {
1144 pub fn as_str(&self) -> &'static str {
1145 match *self {
1146 UnOp::Plus => "+",
1147 UnOp::Neg => "-",
1148 UnOp::Not => "!",
1149 }
1150 }
1151}
1152
1153#[derive(PartialEq, Eq, Debug, Copy, Clone)]
1154pub enum CmpOp {
1155 Eq,
1156 Ne,
1157 Lt,
1158 Le,
1159 Gt,
1160 Ge,
1161 Is,
1162 IsNot,
1163}
1164
1165impl CmpOp {
1166 pub fn as_str(&self) -> &'static str {
1167 match *self {
1168 CmpOp::Eq => "==",
1169 CmpOp::Ne => "!=",
1170 CmpOp::Lt => "<",
1171 CmpOp::Le => "<=",
1172 CmpOp::Gt => ">",
1173 CmpOp::Ge => ">=",
1174 CmpOp::Is => "===",
1175 CmpOp::IsNot => "!==",
1176 }
1177 }
1178}
1179
1180#[derive(PartialEq, Eq, Debug, Copy, Clone)]
1181pub enum BinOp {
1182 Assign,
1183 Add,
1184 Sub,
1185 Mul,
1186 Div,
1187 Mod,
1188 Cmp(CmpOp),
1189 Or,
1190 And,
1191 BitOr,
1192 BitAnd,
1193 BitXor,
1194 ShiftL,
1195 ArithShiftR,
1196 LogicalShiftR,
1197}
1198
1199impl BinOp {
1200 pub fn as_str(&self) -> &'static str {
1201 match *self {
1202 BinOp::Assign => "=",
1203 BinOp::Add => "+",
1204 BinOp::Sub => "-",
1205 BinOp::Mul => "*",
1206 BinOp::Div => "/",
1207 BinOp::Mod => "%",
1208 BinOp::Cmp(op) => op.as_str(),
1209 BinOp::Or => "||",
1210 BinOp::And => "&&",
1211 BinOp::BitOr => "|",
1212 BinOp::BitAnd => "&",
1213 BinOp::BitXor => "^",
1214 BinOp::ShiftL => "<<",
1215 BinOp::ArithShiftR => ">>",
1216 BinOp::LogicalShiftR => ">>>",
1217 }
1218 }
1219
1220 pub fn is_any_assign(&self) -> bool {
1221 match *self {
1222 BinOp::Assign => true,
1223 _ => false,
1224 }
1225 }
1226
1227 pub fn is_compare(&self) -> bool {
1228 match *self {
1229 BinOp::Cmp(cmp) if cmp != CmpOp::Is && cmp != CmpOp::IsNot => true,
1230 _ => false,
1231 }
1232 }
1233}
1234
1235#[derive(Clone, Debug)]
1236pub enum Expr {
1237 ExprUn(ExprUnType),
1238 ExprBin(ExprBinType),
1239 ExprLitChar(ExprLitCharType),
1240 ExprLitInt(ExprLitIntType),
1241 ExprLitFloat(ExprLitFloatType),
1242 ExprLitStr(ExprLitStrType),
1243 ExprTemplate(ExprTemplateType),
1244 ExprLitBool(ExprLitBoolType),
1245 ExprIdent(ExprIdentType),
1246 ExprCall(ExprCallType),
1247 ExprTypeParam(ExprTypeParamType),
1248 ExprPath(ExprPathType),
1249 ExprDelegation(ExprDelegationType),
1250 ExprDot(ExprDotType),
1251 ExprSelf(ExprSelfType),
1252 ExprSuper(ExprSuperType),
1253 ExprNil(ExprNilType),
1254 ExprConv(ExprConvType),
1255 ExprTry(ExprTryType),
1256 ExprLambda(ExprLambdaType),
1257 ExprBlock(ExprBlockType),
1258 ExprIf(ExprIfType),
1259 ExprTuple(ExprTupleType),
1260}
1261
1262impl Expr {
1263 pub fn create_block(
1264 id: NodeId,
1265 pos: Position,
1266 span: Span,
1267 stmts: Vec<Box<Stmt>>,
1268 expr: Option<Box<Expr>>,
1269 ) -> Expr {
1270 Expr::ExprBlock(ExprBlockType {
1271 id,
1272 pos,
1273 span,
1274
1275 stmts,
1276 expr,
1277 })
1278 }
1279
1280 pub fn create_if(
1281 id: NodeId,
1282 pos: Position,
1283 span: Span,
1284 cond: Box<Expr>,
1285 then_block: Box<Expr>,
1286 else_block: Option<Box<Expr>>,
1287 ) -> Expr {
1288 Expr::ExprIf(ExprIfType {
1289 id,
1290 pos,
1291 span,
1292
1293 cond,
1294 then_block,
1295 else_block,
1296 })
1297 }
1298
1299 pub fn create_un(id: NodeId, pos: Position, span: Span, op: UnOp, opnd: Box<Expr>) -> Expr {
1300 Expr::ExprUn(ExprUnType {
1301 id,
1302 pos,
1303 span,
1304
1305 op,
1306 opnd,
1307 })
1308 }
1309
1310 pub fn create_try(
1311 id: NodeId,
1312 pos: Position,
1313 span: Span,
1314 expr: Box<Expr>,
1315 mode: TryMode,
1316 ) -> Expr {
1317 Expr::ExprTry(ExprTryType {
1318 id,
1319 pos,
1320 span,
1321
1322 expr,
1323 mode,
1324 })
1325 }
1326
1327 pub fn create_bin(
1328 id: NodeId,
1329 pos: Position,
1330 span: Span,
1331 op: BinOp,
1332 lhs: Box<Expr>,
1333 rhs: Box<Expr>,
1334 ) -> Expr {
1335 Expr::ExprBin(ExprBinType {
1336 id,
1337 pos,
1338 span,
1339
1340 op,
1341 lhs,
1342 rhs,
1343 })
1344 }
1345
1346 pub fn create_conv(
1347 id: NodeId,
1348 pos: Position,
1349 span: Span,
1350 object: Box<Expr>,
1351 data_type: Box<Type>,
1352 is: bool,
1353 ) -> Expr {
1354 Expr::ExprConv(ExprConvType {
1355 id,
1356 pos,
1357 span,
1358
1359 object,
1360 data_type,
1361 is,
1362 })
1363 }
1364
1365 pub fn create_lit_char(id: NodeId, pos: Position, span: Span, value: char) -> Expr {
1366 Expr::ExprLitChar(ExprLitCharType {
1367 id,
1368 pos,
1369 span,
1370
1371 value,
1372 })
1373 }
1374
1375 pub fn create_lit_int(
1376 id: NodeId,
1377 pos: Position,
1378 span: Span,
1379 value: u64,
1380 base: IntBase,
1381 suffix: IntSuffix,
1382 ) -> Expr {
1383 Expr::ExprLitInt(ExprLitIntType {
1384 id,
1385 pos,
1386 span,
1387
1388 value,
1389 base,
1390 suffix,
1391 })
1392 }
1393
1394 pub fn create_lit_float(
1395 id: NodeId,
1396 pos: Position,
1397 span: Span,
1398 value: f64,
1399 suffix: FloatSuffix,
1400 ) -> Expr {
1401 Expr::ExprLitFloat(ExprLitFloatType {
1402 id,
1403 pos,
1404 span,
1405 value,
1406 suffix,
1407 })
1408 }
1409
1410 pub fn create_lit_str(id: NodeId, pos: Position, span: Span, value: String) -> Expr {
1411 Expr::ExprLitStr(ExprLitStrType {
1412 id,
1413 pos,
1414 span,
1415
1416 value,
1417 })
1418 }
1419
1420 pub fn create_template(id: NodeId, pos: Position, span: Span, parts: Vec<Box<Expr>>) -> Expr {
1421 Expr::ExprTemplate(ExprTemplateType {
1422 id,
1423 pos,
1424 span,
1425
1426 parts,
1427 })
1428 }
1429
1430 pub fn create_lit_bool(id: NodeId, pos: Position, span: Span, value: bool) -> Expr {
1431 Expr::ExprLitBool(ExprLitBoolType {
1432 id,
1433 pos,
1434 span,
1435
1436 value,
1437 })
1438 }
1439
1440 pub fn create_this(id: NodeId, pos: Position, span: Span) -> Expr {
1441 Expr::ExprSelf(ExprSelfType { id, pos, span })
1442 }
1443
1444 pub fn create_super(id: NodeId, pos: Position, span: Span) -> Expr {
1445 Expr::ExprSuper(ExprSuperType { id, pos, span })
1446 }
1447
1448 pub fn create_nil(id: NodeId, pos: Position, span: Span) -> Expr {
1449 Expr::ExprNil(ExprNilType { id, pos, span })
1450 }
1451
1452 pub fn create_ident(
1453 id: NodeId,
1454 pos: Position,
1455 span: Span,
1456 name: Name,
1457 type_params: Option<Vec<Type>>,
1458 ) -> Expr {
1459 Expr::ExprIdent(ExprIdentType {
1460 id,
1461 pos,
1462 span,
1463
1464 name,
1465 type_params,
1466 })
1467 }
1468
1469 pub fn create_call(
1470 id: NodeId,
1471 pos: Position,
1472 span: Span,
1473 callee: Box<Expr>,
1474 args: Vec<Box<Expr>>,
1475 ) -> Expr {
1476 Expr::ExprCall(ExprCallType {
1477 id,
1478 pos,
1479 span,
1480
1481 callee,
1482 args,
1483 })
1484 }
1485
1486 pub fn create_type_param(
1487 id: NodeId,
1488 pos: Position,
1489 span: Span,
1490 callee: Box<Expr>,
1491 args: Vec<Type>,
1492 ) -> Expr {
1493 Expr::ExprTypeParam(ExprTypeParamType {
1494 id,
1495 pos,
1496 span,
1497
1498 callee,
1499 args,
1500 })
1501 }
1502
1503 pub fn create_path(
1504 id: NodeId,
1505 pos: Position,
1506 span: Span,
1507 lhs: Box<Expr>,
1508 rhs: Box<Expr>,
1509 ) -> Expr {
1510 Expr::ExprPath(ExprPathType {
1511 id,
1512 pos,
1513 span,
1514
1515 lhs,
1516 rhs,
1517 })
1518 }
1519
1520 pub fn create_delegation(id: NodeId, pos: Position, span: Span, args: Vec<Box<Expr>>) -> Expr {
1521 Expr::ExprDelegation(ExprDelegationType {
1522 id,
1523 pos,
1524 span,
1525
1526 args,
1527 })
1528 }
1529
1530 pub fn create_dot(
1531 id: NodeId,
1532 pos: Position,
1533 span: Span,
1534 lhs: Box<Expr>,
1535 rhs: Box<Expr>,
1536 ) -> Expr {
1537 Expr::ExprDot(ExprDotType {
1538 id,
1539 pos,
1540 span,
1541
1542 lhs,
1543 rhs,
1544 })
1545 }
1546
1547 pub fn create_lambda(
1548 id: NodeId,
1549 pos: Position,
1550 span: Span,
1551 params: Vec<Param>,
1552 ret: Option<Box<Type>>,
1553 block: Box<Stmt>,
1554 ) -> Expr {
1555 Expr::ExprLambda(ExprLambdaType {
1556 id,
1557 pos,
1558 span,
1559
1560 params,
1561 ret,
1562 block,
1563 })
1564 }
1565
1566 pub fn create_tuple(id: NodeId, pos: Position, span: Span, values: Vec<Box<Expr>>) -> Expr {
1567 Expr::ExprTuple(ExprTupleType {
1568 id,
1569 pos,
1570 span,
1571 values,
1572 })
1573 }
1574
1575 pub fn to_un(&self) -> Option<&ExprUnType> {
1576 match *self {
1577 Expr::ExprUn(ref val) => Some(val),
1578 _ => None,
1579 }
1580 }
1581
1582 pub fn is_un(&self) -> bool {
1583 match *self {
1584 Expr::ExprUn(_) => true,
1585 _ => false,
1586 }
1587 }
1588
1589 pub fn to_bin(&self) -> Option<&ExprBinType> {
1590 match *self {
1591 Expr::ExprBin(ref val) => Some(val),
1592 _ => None,
1593 }
1594 }
1595
1596 pub fn is_bin(&self) -> bool {
1597 match *self {
1598 Expr::ExprBin(_) => true,
1599 _ => false,
1600 }
1601 }
1602
1603 pub fn to_ident(&self) -> Option<&ExprIdentType> {
1604 match *self {
1605 Expr::ExprIdent(ref val) => Some(val),
1606 _ => None,
1607 }
1608 }
1609
1610 pub fn is_ident(&self) -> bool {
1611 match *self {
1612 Expr::ExprIdent(_) => true,
1613 _ => false,
1614 }
1615 }
1616
1617 pub fn to_call(&self) -> Option<&ExprCallType> {
1618 match *self {
1619 Expr::ExprCall(ref val) => Some(val),
1620 _ => None,
1621 }
1622 }
1623
1624 pub fn is_call(&self) -> bool {
1625 match *self {
1626 Expr::ExprCall(_) => true,
1627 _ => false,
1628 }
1629 }
1630
1631 pub fn to_path(&self) -> Option<&ExprPathType> {
1632 match *self {
1633 Expr::ExprPath(ref val) => Some(val),
1634 _ => None,
1635 }
1636 }
1637
1638 pub fn is_path(&self) -> bool {
1639 match *self {
1640 Expr::ExprPath(_) => true,
1641 _ => false,
1642 }
1643 }
1644
1645 pub fn to_type_param(&self) -> Option<&ExprTypeParamType> {
1646 match *self {
1647 Expr::ExprTypeParam(ref val) => Some(val),
1648 _ => None,
1649 }
1650 }
1651
1652 pub fn is_type_param(&self) -> bool {
1653 match *self {
1654 Expr::ExprTypeParam(_) => true,
1655 _ => false,
1656 }
1657 }
1658
1659 pub fn to_lit_char(&self) -> Option<&ExprLitCharType> {
1660 match *self {
1661 Expr::ExprLitChar(ref val) => Some(val),
1662 _ => None,
1663 }
1664 }
1665
1666 pub fn is_lit_char(&self) -> bool {
1667 match *self {
1668 Expr::ExprLitChar(_) => true,
1669 _ => false,
1670 }
1671 }
1672
1673 pub fn to_lit_int(&self) -> Option<&ExprLitIntType> {
1674 match *self {
1675 Expr::ExprLitInt(ref val) => Some(val),
1676 _ => None,
1677 }
1678 }
1679
1680 pub fn is_lit_int(&self) -> bool {
1681 match *self {
1682 Expr::ExprLitInt(_) => true,
1683 _ => false,
1684 }
1685 }
1686
1687 pub fn to_template(&self) -> Option<&ExprTemplateType> {
1688 match *self {
1689 Expr::ExprTemplate(ref val) => Some(val),
1690 _ => None,
1691 }
1692 }
1693
1694 pub fn is_template(&self) -> bool {
1695 match *self {
1696 Expr::ExprTemplate(_) => true,
1697 _ => false,
1698 }
1699 }
1700
1701 pub fn to_lit_float(&self) -> Option<&ExprLitFloatType> {
1702 match *self {
1703 Expr::ExprLitFloat(ref val) => Some(val),
1704 _ => None,
1705 }
1706 }
1707
1708 pub fn is_lit_float(&self) -> bool {
1709 match *self {
1710 Expr::ExprLitFloat(_) => true,
1711 _ => false,
1712 }
1713 }
1714
1715 pub fn to_lit_str(&self) -> Option<&ExprLitStrType> {
1716 match *self {
1717 Expr::ExprLitStr(ref val) => Some(val),
1718 _ => None,
1719 }
1720 }
1721
1722 pub fn is_lit_str(&self) -> bool {
1723 match *self {
1724 Expr::ExprLitStr(_) => true,
1725 _ => false,
1726 }
1727 }
1728
1729 pub fn to_lit_bool(&self) -> Option<&ExprLitBoolType> {
1730 match *self {
1731 Expr::ExprLitBool(ref val) => Some(val),
1732 _ => None,
1733 }
1734 }
1735
1736 pub fn is_lit_bool(&self) -> bool {
1737 match *self {
1738 Expr::ExprLitBool(_) => true,
1739 _ => false,
1740 }
1741 }
1742
1743 pub fn is_lit_true(&self) -> bool {
1744 match *self {
1745 Expr::ExprLitBool(ref lit) if lit.value => true,
1746 _ => false,
1747 }
1748 }
1749
1750 pub fn to_dot(&self) -> Option<&ExprDotType> {
1751 match *self {
1752 Expr::ExprDot(ref val) => Some(val),
1753 _ => None,
1754 }
1755 }
1756
1757 pub fn is_dot(&self) -> bool {
1758 match *self {
1759 Expr::ExprDot(_) => true,
1760 _ => false,
1761 }
1762 }
1763
1764 pub fn to_delegation(&self) -> Option<&ExprDelegationType> {
1765 match *self {
1766 Expr::ExprDelegation(ref val) => Some(val),
1767 _ => None,
1768 }
1769 }
1770
1771 pub fn is_delegation(&self) -> bool {
1772 match *self {
1773 Expr::ExprDelegation(_) => true,
1774 _ => false,
1775 }
1776 }
1777
1778 pub fn is_this(&self) -> bool {
1779 match *self {
1780 Expr::ExprSelf(_) => true,
1781 _ => false,
1782 }
1783 }
1784
1785 pub fn is_super(&self) -> bool {
1786 match *self {
1787 Expr::ExprSuper(_) => true,
1788 _ => false,
1789 }
1790 }
1791
1792 pub fn to_super(&self) -> Option<&ExprSuperType> {
1793 match *self {
1794 Expr::ExprSuper(ref val) => Some(val),
1795 _ => None,
1796 }
1797 }
1798
1799 pub fn is_nil(&self) -> bool {
1800 match *self {
1801 Expr::ExprNil(_) => true,
1802 _ => false,
1803 }
1804 }
1805
1806 pub fn to_conv(&self) -> Option<&ExprConvType> {
1807 match *self {
1808 Expr::ExprConv(ref val) => Some(val),
1809 _ => None,
1810 }
1811 }
1812
1813 pub fn is_conv(&self) -> bool {
1814 match *self {
1815 Expr::ExprConv(_) => true,
1816 _ => false,
1817 }
1818 }
1819
1820 pub fn to_try(&self) -> Option<&ExprTryType> {
1821 match *self {
1822 Expr::ExprTry(ref val) => Some(val),
1823 _ => None,
1824 }
1825 }
1826
1827 pub fn is_try(&self) -> bool {
1828 match *self {
1829 Expr::ExprTry(_) => true,
1830 _ => false,
1831 }
1832 }
1833
1834 pub fn to_lambda(&self) -> Option<&ExprLambdaType> {
1835 match *self {
1836 Expr::ExprLambda(ref val) => Some(val),
1837 _ => None,
1838 }
1839 }
1840
1841 pub fn is_lambda(&self) -> bool {
1842 match self {
1843 &Expr::ExprLambda(_) => true,
1844 _ => false,
1845 }
1846 }
1847
1848 pub fn to_tuple(&self) -> Option<&ExprTupleType> {
1849 match *self {
1850 Expr::ExprTuple(ref val) => Some(val),
1851 _ => None,
1852 }
1853 }
1854
1855 pub fn is_tuple(&self) -> bool {
1856 match *self {
1857 Expr::ExprTuple(_) => true,
1858 _ => false,
1859 }
1860 }
1861
1862 pub fn to_block(&self) -> Option<&ExprBlockType> {
1863 match *self {
1864 Expr::ExprBlock(ref val) => Some(val),
1865 _ => None,
1866 }
1867 }
1868
1869 pub fn is_block(&self) -> bool {
1870 match self {
1871 &Expr::ExprBlock(_) => true,
1872 _ => false,
1873 }
1874 }
1875
1876 pub fn to_if(&self) -> Option<&ExprIfType> {
1877 match *self {
1878 Expr::ExprIf(ref val) => Some(val),
1879 _ => None,
1880 }
1881 }
1882
1883 pub fn is_if(&self) -> bool {
1884 match *self {
1885 Expr::ExprIf(_) => true,
1886 _ => false,
1887 }
1888 }
1889
1890 pub fn needs_semicolon(&self) -> bool {
1891 match self {
1892 &Expr::ExprBlock(_) => false,
1893 &Expr::ExprIf(_) => false,
1894 _ => true,
1895 }
1896 }
1897
1898 pub fn pos(&self) -> Position {
1899 match *self {
1900 Expr::ExprUn(ref val) => val.pos,
1901 Expr::ExprBin(ref val) => val.pos,
1902 Expr::ExprLitChar(ref val) => val.pos,
1903 Expr::ExprLitInt(ref val) => val.pos,
1904 Expr::ExprLitFloat(ref val) => val.pos,
1905 Expr::ExprLitStr(ref val) => val.pos,
1906 Expr::ExprTemplate(ref val) => val.pos,
1907 Expr::ExprLitBool(ref val) => val.pos,
1908 Expr::ExprIdent(ref val) => val.pos,
1909 Expr::ExprCall(ref val) => val.pos,
1910 Expr::ExprTypeParam(ref val) => val.pos,
1911 Expr::ExprPath(ref val) => val.pos,
1912 Expr::ExprDelegation(ref val) => val.pos,
1913 Expr::ExprDot(ref val) => val.pos,
1914 Expr::ExprSelf(ref val) => val.pos,
1915 Expr::ExprSuper(ref val) => val.pos,
1916 Expr::ExprNil(ref val) => val.pos,
1917 Expr::ExprConv(ref val) => val.pos,
1918 Expr::ExprTry(ref val) => val.pos,
1919 Expr::ExprLambda(ref val) => val.pos,
1920 Expr::ExprBlock(ref val) => val.pos,
1921 Expr::ExprIf(ref val) => val.pos,
1922 Expr::ExprTuple(ref val) => val.pos,
1923 }
1924 }
1925
1926 pub fn span(&self) -> Span {
1927 match *self {
1928 Expr::ExprUn(ref val) => val.span,
1929 Expr::ExprBin(ref val) => val.span,
1930 Expr::ExprLitChar(ref val) => val.span,
1931 Expr::ExprLitInt(ref val) => val.span,
1932 Expr::ExprLitFloat(ref val) => val.span,
1933 Expr::ExprLitStr(ref val) => val.span,
1934 Expr::ExprTemplate(ref val) => val.span,
1935 Expr::ExprLitBool(ref val) => val.span,
1936 Expr::ExprIdent(ref val) => val.span,
1937 Expr::ExprCall(ref val) => val.span,
1938 Expr::ExprTypeParam(ref val) => val.span,
1939 Expr::ExprPath(ref val) => val.span,
1940 Expr::ExprDelegation(ref val) => val.span,
1941 Expr::ExprDot(ref val) => val.span,
1942 Expr::ExprSelf(ref val) => val.span,
1943 Expr::ExprSuper(ref val) => val.span,
1944 Expr::ExprNil(ref val) => val.span,
1945 Expr::ExprConv(ref val) => val.span,
1946 Expr::ExprTry(ref val) => val.span,
1947 Expr::ExprLambda(ref val) => val.span,
1948 Expr::ExprBlock(ref val) => val.span,
1949 Expr::ExprIf(ref val) => val.span,
1950 Expr::ExprTuple(ref val) => val.span,
1951 }
1952 }
1953
1954 pub fn id(&self) -> NodeId {
1955 match *self {
1956 Expr::ExprUn(ref val) => val.id,
1957 Expr::ExprBin(ref val) => val.id,
1958 Expr::ExprLitChar(ref val) => val.id,
1959 Expr::ExprLitInt(ref val) => val.id,
1960 Expr::ExprLitFloat(ref val) => val.id,
1961 Expr::ExprLitStr(ref val) => val.id,
1962 Expr::ExprTemplate(ref val) => val.id,
1963 Expr::ExprLitBool(ref val) => val.id,
1964 Expr::ExprIdent(ref val) => val.id,
1965 Expr::ExprCall(ref val) => val.id,
1966 Expr::ExprTypeParam(ref val) => val.id,
1967 Expr::ExprPath(ref val) => val.id,
1968 Expr::ExprDelegation(ref val) => val.id,
1969 Expr::ExprDot(ref val) => val.id,
1970 Expr::ExprSelf(ref val) => val.id,
1971 Expr::ExprSuper(ref val) => val.id,
1972 Expr::ExprNil(ref val) => val.id,
1973 Expr::ExprConv(ref val) => val.id,
1974 Expr::ExprTry(ref val) => val.id,
1975 Expr::ExprLambda(ref val) => val.id,
1976 Expr::ExprBlock(ref val) => val.id,
1977 Expr::ExprIf(ref val) => val.id,
1978 Expr::ExprTuple(ref val) => val.id,
1979 }
1980 }
1981}
1982
1983#[derive(Clone, Debug)]
1984pub struct ExprIfType {
1985 pub id: NodeId,
1986 pub pos: Position,
1987 pub span: Span,
1988
1989 pub cond: Box<Expr>,
1990 pub then_block: Box<Expr>,
1991 pub else_block: Option<Box<Expr>>,
1992}
1993
1994#[derive(Clone, Debug)]
1995pub struct ExprTupleType {
1996 pub id: NodeId,
1997 pub pos: Position,
1998 pub span: Span,
1999
2000 pub values: Vec<Box<Expr>>,
2001}
2002
2003#[derive(Clone, Debug)]
2004pub struct ExprConvType {
2005 pub id: NodeId,
2006 pub pos: Position,
2007 pub span: Span,
2008
2009 pub object: Box<Expr>,
2010 pub is: bool,
2011 pub data_type: Box<Type>,
2012}
2013
2014#[derive(Clone, Debug)]
2015pub struct ExprTryType {
2016 pub id: NodeId,
2017 pub pos: Position,
2018 pub span: Span,
2019
2020 pub expr: Box<Expr>,
2021 pub mode: TryMode,
2022}
2023
2024#[derive(Clone, Debug)]
2025pub enum TryMode {
2026 Normal,
2027 Else(Box<Expr>),
2028 Opt,
2029 Force,
2030}
2031
2032impl TryMode {
2033 pub fn is_normal(&self) -> bool {
2034 match self {
2035 &TryMode::Normal => true,
2036 _ => false,
2037 }
2038 }
2039
2040 pub fn is_else(&self) -> bool {
2041 match self {
2042 &TryMode::Else(_) => true,
2043 _ => false,
2044 }
2045 }
2046
2047 pub fn is_force(&self) -> bool {
2048 match self {
2049 &TryMode::Force => true,
2050 _ => false,
2051 }
2052 }
2053
2054 pub fn is_opt(&self) -> bool {
2055 match self {
2056 &TryMode::Opt => true,
2057 _ => false,
2058 }
2059 }
2060}
2061
2062#[derive(Clone, Debug)]
2063pub struct ExprDelegationType {
2064 pub id: NodeId,
2065 pub pos: Position,
2066 pub span: Span,
2067
2068 pub args: Vec<Box<Expr>>,
2069}
2070
2071#[derive(Clone, Debug)]
2072pub struct ExprUnType {
2073 pub id: NodeId,
2074 pub pos: Position,
2075 pub span: Span,
2076
2077 pub op: UnOp,
2078 pub opnd: Box<Expr>,
2079}
2080
2081#[derive(Clone, Debug)]
2082pub struct ExprBinType {
2083 pub id: NodeId,
2084 pub pos: Position,
2085 pub span: Span,
2086
2087 pub op: BinOp,
2088 pub lhs: Box<Expr>,
2089 pub rhs: Box<Expr>,
2090}
2091
2092#[derive(Clone, Debug)]
2093pub struct ExprLitCharType {
2094 pub id: NodeId,
2095 pub pos: Position,
2096 pub span: Span,
2097
2098 pub value: char,
2099}
2100
2101#[derive(Clone, Debug)]
2102pub struct ExprLitIntType {
2103 pub id: NodeId,
2104 pub pos: Position,
2105 pub span: Span,
2106
2107 pub value: u64,
2108 pub base: IntBase,
2109 pub suffix: IntSuffix,
2110}
2111
2112#[derive(Clone, Debug)]
2113pub struct ExprLitFloatType {
2114 pub id: NodeId,
2115 pub pos: Position,
2116 pub span: Span,
2117
2118 pub value: f64,
2119 pub suffix: FloatSuffix,
2120}
2121
2122#[derive(Clone, Debug)]
2123pub struct ExprLitStrType {
2124 pub id: NodeId,
2125 pub pos: Position,
2126 pub span: Span,
2127
2128 pub value: String,
2129}
2130
2131#[derive(Clone, Debug)]
2132pub struct ExprTemplateType {
2133 pub id: NodeId,
2134 pub pos: Position,
2135 pub span: Span,
2136
2137 pub parts: Vec<Box<Expr>>,
2138}
2139
2140#[derive(Clone, Debug)]
2141pub struct ExprLitBoolType {
2142 pub id: NodeId,
2143 pub pos: Position,
2144 pub span: Span,
2145
2146 pub value: bool,
2147}
2148
2149#[derive(Clone, Debug)]
2150pub struct ExprBlockType {
2151 pub id: NodeId,
2152 pub pos: Position,
2153 pub span: Span,
2154
2155 pub stmts: Vec<Box<Stmt>>,
2156 pub expr: Option<Box<Expr>>,
2157}
2158
2159#[derive(Clone, Debug)]
2160pub struct ExprSuperType {
2161 pub id: NodeId,
2162 pub pos: Position,
2163 pub span: Span,
2164}
2165
2166#[derive(Clone, Debug)]
2167pub struct ExprSelfType {
2168 pub id: NodeId,
2169 pub pos: Position,
2170 pub span: Span,
2171}
2172
2173#[derive(Clone, Debug)]
2174pub struct ExprNilType {
2175 pub id: NodeId,
2176 pub pos: Position,
2177 pub span: Span,
2178}
2179
2180#[derive(Clone, Debug)]
2181pub struct ExprIdentType {
2182 pub id: NodeId,
2183 pub pos: Position,
2184 pub span: Span,
2185
2186 pub name: Name,
2187 pub type_params: Option<Vec<Type>>,
2188}
2189
2190#[derive(Clone, Debug)]
2191pub struct ExprLambdaType {
2192 pub id: NodeId,
2193 pub pos: Position,
2194 pub span: Span,
2195
2196 pub params: Vec<Param>,
2197 pub ret: Option<Box<Type>>,
2198 pub block: Box<Stmt>,
2199}
2200
2201#[derive(Clone, Debug)]
2202pub struct ExprCallType {
2203 pub id: NodeId,
2204 pub pos: Position,
2205 pub span: Span,
2206
2207 pub callee: Box<Expr>,
2208 pub args: Vec<Box<Expr>>,
2209}
2210
2211impl ExprCallType {
2212 pub fn object(&self) -> Option<&Expr> {
2213 if let Some(type_param) = self.callee.to_type_param() {
2214 if let Some(dot) = type_param.callee.to_dot() {
2215 Some(&dot.lhs)
2216 } else {
2217 None
2218 }
2219 } else if let Some(dot) = self.callee.to_dot() {
2220 Some(&dot.lhs)
2221 } else {
2222 None
2223 }
2224 }
2225}
2226
2227#[derive(Clone, Debug)]
2228pub struct ExprTypeParamType {
2229 pub id: NodeId,
2230 pub pos: Position,
2231 pub span: Span,
2232
2233 pub callee: Box<Expr>,
2234 pub args: Vec<Type>,
2235}
2236
2237#[derive(Clone, Debug)]
2238pub struct ExprPathType {
2239 pub id: NodeId,
2240 pub pos: Position,
2241 pub span: Span,
2242
2243 pub lhs: Box<Expr>,
2244 pub rhs: Box<Expr>,
2245}
2246
2247#[derive(Clone, Debug)]
2248pub struct ExprDotType {
2249 pub id: NodeId,
2250 pub pos: Position,
2251 pub span: Span,
2252
2253 pub lhs: Box<Expr>,
2254 pub rhs: Box<Expr>,
2255}