dora_parser/
ast.rs

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}