1pub type Loc = std::ops::Range<usize>;
3
4pub trait Locate {
6 fn loc(&self) -> Loc;
8}
9
10#[derive(Clone, Debug, PartialEq)]
12pub struct None {
13 pub loc: Loc,
14}
15
16impl None {
17 pub fn new(loc: Loc) -> Self {
19 Self { loc }
20 }
21}
22
23impl Locate for None {
24 fn loc(&self) -> Loc {
25 self.loc.clone()
26 }
27}
28
29#[derive(Clone, Debug, PartialEq)]
31pub struct Bool<'input> {
32 pub loc: Loc,
33 pub value: &'input str,
34}
35
36impl<'input> Bool<'input> {
37 pub fn new(loc: Loc, value: &'input str) -> Self {
39 Self { loc, value }
40 }
41}
42
43impl<'input> Locate for Bool<'input> {
44 fn loc(&self) -> Loc {
45 self.loc.clone()
46 }
47}
48
49#[derive(Clone, Copy, Debug, PartialEq)]
51pub enum NumKind {
52 Dec,
59
60 Hex,
68
69 Bin,
75
76 Oct,
82
83 Float,
91}
92
93#[derive(Clone, Debug, PartialEq)]
95pub struct Num<'input> {
96 pub loc: Loc,
97 pub kind: NumKind,
98 pub value: &'input str,
99}
100
101impl<'input> Num<'input> {
102 pub fn dec(loc: Loc, value: &'input str) -> Self {
104 Self { loc, kind: NumKind::Dec, value }
105 }
106
107 pub fn hex(loc: Loc, value: &'input str) -> Self {
109 Self { loc, kind: NumKind::Hex, value }
110 }
111
112 pub fn bin(loc: Loc, value: &'input str) -> Self {
114 Self { loc, kind: NumKind::Bin, value }
115 }
116
117 pub fn oct(loc: Loc, value: &'input str) -> Self {
119 Self { loc, kind: NumKind::Oct, value }
120 }
121
122 pub fn float(loc: Loc, value: &'input str) -> Self {
124 Self { loc, kind: NumKind::Float, value }
125 }
126}
127
128impl<'input> Locate for Num<'input> {
129 fn loc(&self) -> Loc {
130 self.loc.clone()
131 }
132}
133
134#[derive(Clone, Debug, PartialEq)]
136pub struct Ident<'input> {
137 pub loc: Loc,
138 pub value: &'input str,
139}
140
141impl<'input> Ident<'input> {
142 pub fn new(loc: Loc, value: &'input str) -> Self {
144 Self { loc, value }
145 }
146}
147
148impl<'input> Locate for Ident<'input> {
149 fn loc(&self) -> Loc {
150 self.loc.clone()
151 }
152}
153
154#[derive(Clone, Debug, PartialEq)]
156pub struct Atom<'input> {
157 pub loc: Loc,
158 pub value: &'input str,
159}
160
161impl<'input> Atom<'input> {
162 pub fn new(loc: Loc, value: &'input str) -> Self {
164 Self { loc, value }
165 }
166}
167
168impl<'input> Locate for Atom<'input> {
169 fn loc(&self) -> Loc {
170 self.loc.clone()
171 }
172}
173
174#[derive(Clone, Debug, PartialEq)]
176pub struct Str<'input> {
177 pub loc: Loc,
178 pub value: &'input str,
179}
180
181impl<'input> Str<'input> {
182 pub fn new(loc: Loc, value: &'input str) -> Self {
184 Self { loc, value }
185 }
186}
187
188impl<'input> Locate for Str<'input> {
189 fn loc(&self) -> Loc {
190 self.loc.clone()
191 }
192}
193
194#[derive(Clone, Copy, Debug, PartialEq)]
196pub enum BinaryOp {
197 ObjIdx,
203
204 StaticIdx,
210
211 ExprIdx,
217
218 Mul,
224
225 Div,
231
232 Mod,
238
239 Add,
245
246 Sub,
252
253 Shl,
259
260 Shr,
266
267 BitAnd,
273
274 BitXor,
280
281 BitOr,
287
288 Eq,
294
295 Neq,
301
302 Lt,
308
309 Gt,
315
316 LtEq,
324
325 GtEq,
333
334 And,
340
341 Or,
347}
348
349#[derive(Clone, Debug, PartialEq)]
351pub struct Binary<'input> {
352 pub loc: Loc,
353 pub op: BinaryOp,
354 pub left: Box<Expr<'input>>,
355 pub right: Box<Expr<'input>>,
356}
357
358impl<'input> Binary<'input> {
359 pub fn new(loc: Loc, op: BinaryOp, left: Box<Expr<'input>>, right: Box<Expr<'input>>) -> Self {
361 Self { loc, op, left, right }
362 }
363}
364
365impl<'input> Locate for Binary<'input> {
366 fn loc(&self) -> Loc {
367 self.loc.clone()
368 }
369}
370
371#[derive(Clone, Debug, PartialEq)]
373pub struct Call<'input> {
374 pub loc: Loc,
375 pub fun: Box<Expr<'input>>,
376 pub args: Vec<Expr<'input>>,
377}
378
379impl<'input> Call<'input> {
380 pub fn new(loc: Loc, fun: Box<Expr<'input>>, args: Vec<Expr<'input>>) -> Self {
382 Self { loc, fun, args }
383 }
384}
385
386impl<'input> Locate for Call<'input> {
387 fn loc(&self) -> Loc {
388 self.loc.clone()
389 }
390}
391
392#[derive(Clone, Copy, Debug, PartialEq)]
394pub enum UnaryOp {
395 Deref,
397
398 Cloned,
400
401 New,
403
404 Pos,
406
407 Neg,
409
410 Not,
412
413 BitNot,
415}
416
417#[derive(Clone, Debug, PartialEq)]
419pub struct Unary<'input> {
420 pub loc: Loc,
421 pub op: UnaryOp,
422 pub subject: Box<Expr<'input>>,
423}
424
425impl<'input> Unary<'input> {
426 pub fn new(loc: Loc, op: UnaryOp, subject: Box<Expr<'input>>) -> Self {
428 Self { loc, op, subject }
429 }
430}
431
432impl<'input> Locate for Unary<'input> {
433 fn loc(&self) -> Loc {
434 self.loc.clone()
435 }
436}
437
438#[derive(Clone, Copy, Debug, PartialEq)]
440pub enum AssignOp {
441 Assign,
442 AssignAdd,
443 AssignSub,
444 AssignMul,
445 AssignDiv,
446 AssignMod,
447 AssignBitOr,
448 AssignBitXor,
449 AssignShl,
450 AssignShr,
451}
452
453#[derive(Clone, Debug, PartialEq)]
455pub struct Assign<'input> {
456 pub loc: Loc,
457 pub op: AssignOp,
458 pub left: Box<Expr<'input>>,
459 pub right: Box<Expr<'input>>,
460}
461
462impl<'input> Assign<'input> {
463 pub fn new(loc: Loc, op: AssignOp, left: Box<Expr<'input>>, right: Box<Expr<'input>>) -> Self {
465 Self { loc, op, left, right }
466 }
467}
468
469impl<'input> Locate for Assign<'input> {
470 fn loc(&self) -> Loc {
471 self.loc.clone()
472 }
473}
474
475#[derive(Clone, Debug, PartialEq)]
477pub struct Block<'input> {
478 pub loc: Loc,
479 pub action: Vec<Expr<'input>>,
480}
481
482impl<'input> Block<'input> {
483 pub fn new(loc: Loc, action: Vec<Expr<'input>>) -> Self {
485 Self { loc, action }
486 }
487}
488
489impl<'input> Locate for Block<'input> {
490 fn loc(&self) -> Loc {
491 self.loc.clone()
492 }
493}
494
495#[derive(Clone, Debug, PartialEq)]
497pub struct ElseIf<'input> {
498 pub loc: Loc,
499 pub cond: Box<Expr<'input>>,
500 pub block: Block<'input>,
501}
502
503impl<'input> ElseIf<'input> {
504 pub fn new(loc: Loc, cond: Box<Expr<'input>>, block: Block<'input>) -> Self {
506 Self { loc, cond, block }
507 }
508}
509
510impl<'input> Locate for ElseIf<'input> {
511 fn loc(&self) -> Loc {
512 self.loc.clone()
513 }
514}
515
516#[derive(Clone, Debug, PartialEq)]
518pub struct Else<'input> {
519 pub loc: Loc,
520 pub block: Block<'input>,
521}
522
523impl<'input> Else<'input> {
524 pub fn new(loc: Loc, block: Block<'input>) -> Self {
526 Self { loc, block }
527 }
528}
529
530impl<'input> Locate for Else<'input> {
531 fn loc(&self) -> Loc {
532 self.loc.clone()
533 }
534}
535
536#[derive(Clone, Debug, PartialEq)]
538pub enum IfBranch<'input> {
539 ElseIf(ElseIf<'input>),
540 Else(Else<'input>),
541}
542
543impl<'input> Locate for IfBranch<'input> {
544 fn loc(&self) -> Loc {
545 match self {
546 Self::ElseIf(branch) => branch.loc(),
547 Self::Else(branch) => branch.loc(),
548 }
549 }
550}
551
552#[derive(Clone, Debug, PartialEq)]
554pub struct If<'input> {
555 pub loc: Loc,
556 pub cond: Box<Expr<'input>>,
557 pub block: Block<'input>,
558 pub branches: Vec<IfBranch<'input>>,
559}
560
561impl<'input> If<'input> {
562 pub fn new(loc: Loc, cond: Box<Expr<'input>>, block: Block<'input>, branches: Vec<IfBranch<'input>>) -> Self {
564 Self { loc, cond, block, branches }
565 }
566}
567
568impl<'input> Locate for If<'input> {
569 fn loc(&self) -> Loc {
570 self.loc.clone()
571 }
572}
573
574#[derive(Clone, Debug, PartialEq)]
576pub struct InlineFun<'input> {
577 pub loc: Loc,
578 pub args: Vec<Ident<'input>>,
579 pub block: Block<'input>,
580}
581
582impl<'input> InlineFun<'input> {
583 pub fn new(loc: Loc, args: Vec<Ident<'input>>, block: Block<'input>) -> Self {
585 Self { loc, args, block }
586 }
587}
588
589impl<'input> Locate for InlineFun<'input> {
590 fn loc(&self) -> Loc {
591 self.loc.clone()
592 }
593}
594
595#[derive(Clone, Debug, PartialEq)]
597pub struct Fun<'input> {
598 pub loc: Loc,
599 pub publ: bool,
600 pub name: Ident<'input>,
601 pub args: Vec<Ident<'input>>,
602 pub block: Block<'input>,
603}
604
605impl<'input> Fun<'input> {
606 pub fn new(loc: Loc, publ: bool, name: Ident<'input>, args: Vec<Ident<'input>>, block: Block<'input>) -> Self {
608 Self { loc, publ, name, args, block }
609 }
610}
611
612impl<'input> Locate for Fun<'input> {
613 fn loc(&self) -> Loc {
614 self.loc.clone()
615 }
616}
617
618#[derive(Clone, Debug, PartialEq)]
620pub struct ListLit<'input> {
621 pub loc: Loc,
622 pub items: Vec<Expr<'input>>,
623}
624
625impl<'input> ListLit<'input> {
626 pub fn new(loc: Loc, items: Vec<Expr<'input>>) -> Self {
628 Self { loc, items }
629 }
630}
631
632impl<'input> Locate for ListLit<'input> {
633 fn loc(&self) -> Loc {
634 self.loc.clone()
635 }
636}
637
638#[derive(Clone, Debug, PartialEq)]
640pub enum MapPair<'input> {
641 Local {
643 loc: Loc,
644 name: Ident<'input>,
645 },
646
647 Literal {
649 loc: Loc,
650 name: Ident<'input>,
651 value: Box<Expr<'input>>
652 },
653
654 Evaluated {
656 loc: Loc,
657 name: Box<Expr<'input>>,
658 value: Box<Expr<'input>>
659 },
660}
661
662impl<'input> MapPair<'input> {
663 pub fn local(loc: Loc, name: Ident<'input>) -> Self {
665 Self::Local { loc, name }
666 }
667
668 pub fn literal(loc: Loc, name: Ident<'input>, value: Box<Expr<'input>>) -> Self {
670 Self::Literal { loc, name, value }
671 }
672
673 pub fn evaluated(loc: Loc, name: Box<Expr<'input>>, value: Box<Expr<'input>>) -> Self {
675 Self::Evaluated { loc, name, value }
676 }
677}
678
679impl<'input> Locate for MapPair<'input> {
680 fn loc(&self) -> Loc {
681 match self {
682 Self::Local { loc, .. } => loc.clone(),
683 Self::Literal { loc, .. } => loc.clone(),
684 Self::Evaluated { loc, .. } => loc.clone(),
685 }
686 }
687}
688
689#[derive(Clone, Debug, PartialEq)]
691pub struct MapLit<'input> {
692 pub loc: Loc,
693 pub items: Vec<MapPair<'input>>,
694}
695
696impl<'input> MapLit<'input> {
697 pub fn new(loc: Loc, items: Vec<MapPair<'input>>) -> Self {
699 Self { loc, items }
700 }
701}
702
703impl<'input> Locate for MapLit<'input> {
704 fn loc(&self) -> Loc {
705 self.loc.clone()
706 }
707}
708
709#[derive(Clone, Debug, PartialEq)]
711pub struct StructProp<'input> {
712 pub loc: Loc,
713 pub publ: bool,
714 pub name: Ident<'input>,
715}
716
717impl<'input> StructProp<'input> {
718 pub fn new(loc: Loc, publ: bool, name: Ident<'input>) -> Self {
720 Self { loc, publ, name }
721 }
722}
723
724impl<'input> Locate for StructProp<'input> {
725 fn loc(&self) -> Loc {
726 self.loc.clone()
727 }
728}
729
730#[derive(Clone, Debug, PartialEq)]
732pub enum StructMember<'input> {
733 Prop(StructProp<'input>),
734 Fun(Fun<'input>),
735}
736
737impl<'input> Locate for StructMember<'input> {
738 fn loc(&self) -> Loc {
739 match self {
740 Self::Prop(member) => member.loc.clone(),
741 Self::Fun(member) => member.loc.clone(),
742 }
743 }
744}
745
746#[derive(Clone, Debug, PartialEq)]
748pub struct Struct<'input> {
749 pub loc: Loc,
750 pub publ: bool,
751 pub name: Ident<'input>,
752 pub members: Vec<StructMember<'input>>,
753}
754
755impl<'input> Struct<'input> {
756 pub fn new(loc: Loc, publ: bool, name: Ident<'input>, members: Vec<StructMember<'input>>) -> Self {
758 Self { loc, publ, name, members }
759 }
760}
761
762impl<'input> Locate for Struct<'input> {
763 fn loc(&self) -> Loc {
764 self.loc.clone()
765 }
766}
767
768#[derive(Clone, Debug, PartialEq)]
770pub enum VarDeco {
771 Mut {
772 loc: Loc,
773 },
774 Const {
775 loc: Loc,
776 }
777}
778
779impl VarDeco {
780 pub fn mut_(loc: Loc) -> Self {
782 Self::Mut { loc }
783 }
784
785 pub fn const_(loc: Loc) -> Self {
787 Self::Const { loc }
788 }
789}
790
791impl Locate for VarDeco {
792 fn loc(&self) -> Loc {
793 match self {
794 Self::Mut { loc } => loc.clone(),
795 Self::Const { loc } => loc.clone(),
796 }
797 }
798}
799
800#[derive(Clone, Debug, PartialEq)]
802pub enum PatternExpr<'input> {
803 Named(Ident<'input>, Expr<'input>),
804 Literal(Expr<'input>),
805 Evaluated(Expr<'input>),
806}
807
808#[derive(Clone, Debug, PartialEq)]
810pub struct VarPatternList<'input> {
811 pub loc: Loc,
812 pub pattern: Vec<PatternExpr<'input>>,
813}
814
815impl<'input> VarPatternList<'input> {
816 pub fn new(loc: Loc, pattern: Vec<PatternExpr<'input>>) -> Self {
818 Self { loc, pattern }
819 }
820}
821
822impl<'input> Locate for VarPatternList<'input> {
823 fn loc(&self) -> Loc {
824 self.loc.clone()
825 }
826}
827
828#[derive(Clone, Debug, PartialEq)]
830pub struct VarPatternMap<'input> {
831 pub loc: Loc,
832 pub pattern: Vec<PatternExpr<'input>>,
833}
834
835impl<'input> VarPatternMap<'input> {
836 pub fn new(loc: Loc, pattern: Vec<PatternExpr<'input>>) -> Self {
838 Self { loc, pattern }
839 }
840}
841
842impl<'input> Locate for VarPatternMap<'input> {
843 fn loc(&self) -> Loc {
844 self.loc.clone()
845 }
846}
847
848#[derive(Clone, Debug, PartialEq)]
850pub enum VarKind<'input> {
851 Named(Ident<'input>, Box<Option<Expr<'input>>>),
852 PatternList(VarPatternList<'input>, Box<Expr<'input>>),
853 PatternMap(VarPatternMap<'input>, Box<Expr<'input>>),
854}
855
856impl<'input> Locate for VarKind<'input> {
857 fn loc(&self) -> Loc {
858 match self {
859 VarKind::Named(kind, _) => kind.loc(),
860 VarKind::PatternList(kind, _) => kind.loc(),
861 VarKind::PatternMap(kind, _) => kind.loc(),
862 }
863 }
864}
865
866#[derive(Clone, Debug, PartialEq)]
868pub struct Var<'input> {
869 pub loc: Loc,
870 pub deco: VarDeco,
871 pub kind: VarKind<'input>,
872}
873
874impl<'input> Var<'input> {
875 pub fn named(loc: Loc, deco: VarDeco, name: Ident<'input>, value: Box<Option<Expr<'input>>>) -> Self {
877 Self { loc, deco, kind: VarKind::Named(name, value) }
878 }
879
880 pub fn pattern_list(loc: Loc, deco: VarDeco, pattern: VarPatternList<'input>, value: Box<Expr<'input>>) -> Self {
882 Self { loc, deco, kind: VarKind::PatternList(pattern, value) }
883 }
884
885 pub fn pattern_map(loc: Loc, deco: VarDeco, pattern: VarPatternMap<'input>, value: Box<Expr<'input>>) -> Self {
887 Self { loc, deco, kind: VarKind::PatternMap(pattern, value) }
888 }
889}
890
891impl<'input> Locate for Var<'input> {
892 fn loc(&self) -> Loc {
893 self.loc.clone()
894 }
895}
896
897#[derive(Clone, Debug, PartialEq)]
899pub struct While<'input> {
900 pub loc: Loc,
901 pub label: Option<Ident<'input>>,
902 pub cond: Box<Expr<'input>>,
903 pub block: Block<'input>,
904}
905
906impl<'input> While<'input> {
907 pub fn new(loc: Loc, label: Option<Ident<'input>>, cond: Box<Expr<'input>>, block: Block<'input>) -> Self {
909 Self { loc, label, cond, block }
910 }
911}
912
913impl<'input> Locate for While<'input> {
914 fn loc(&self) -> Loc {
915 self.loc.clone()
916 }
917}
918
919#[derive(Clone, Debug, PartialEq)]
921pub struct Break<'input> {
922 pub loc: Loc,
923 pub label: Option<Ident<'input>>,
924}
925
926impl<'input> Break<'input> {
927 pub fn new(loc: Loc, label: Option<Ident<'input>>) -> Self {
929 Self { loc, label }
930 }
931}
932
933impl<'input> Locate for Break<'input> {
934 fn loc(&self) -> Loc {
935 self.loc.clone()
936 }
937}
938
939#[derive(Clone, Debug, PartialEq)]
941pub struct Continue<'input> {
942 pub loc: Loc,
943 pub label: Option<Ident<'input>>,
944}
945
946impl<'input> Continue<'input> {
947 pub fn new(loc: Loc, label: Option<Ident<'input>>) -> Self {
949 Self { loc, label }
950 }
951}
952
953impl<'input> Locate for Continue<'input> {
954 fn loc(&self) -> Loc {
955 self.loc.clone()
956 }
957}
958
959#[derive(Clone, Debug, PartialEq)]
961pub struct Return<'input> {
962 pub loc: Loc,
963 pub value: Box<Option<Expr<'input>>>,
964}
965
966impl<'input> Return<'input> {
967 pub fn new(loc: Loc, value: Box<Option<Expr<'input>>>) -> Self {
969 Self { loc, value }
970 }
971}
972
973impl<'input> Locate for Return<'input> {
974 fn loc(&self) -> Loc {
975 self.loc.clone()
976 }
977}
978
979#[derive(Clone, Debug, PartialEq)]
981pub enum RangeOp<'input> {
982 Exclusive(Box<Option<Expr<'input>>>, Box<Option<Expr<'input>>>),
984
985 Inclusive(Box<Option<Expr<'input>>>, Box<Expr<'input>>),
987}
988
989#[derive(Clone, Debug, PartialEq)]
991pub struct Range<'input> {
992 pub loc: Loc,
993 pub op: RangeOp<'input>,
994}
995
996impl<'input> Range<'input> {
997 pub fn new(loc: Loc, op: RangeOp<'input>) -> Self {
999 Self { loc, op }
1000 }
1001}
1002
1003impl<'input> Locate for Range<'input> {
1004 fn loc(&self) -> Loc {
1005 self.loc.clone()
1006 }
1007}
1008
1009#[derive(Clone, Debug, PartialEq)]
1011pub enum Expr<'input> {
1012 None(None),
1013 Bool(Bool<'input>),
1014 Num(Num<'input>),
1015 Ident(Ident<'input>),
1016 Atom(Atom<'input>),
1017 Str(Str<'input>),
1018 Binary(Binary<'input>),
1019 Call(Call<'input>),
1020 Unary(Unary<'input>),
1021 Assign(Assign<'input>),
1022 If(If<'input>),
1023 InlineFun(InlineFun<'input>),
1024 Fun(Fun<'input>),
1025 Block(Block<'input>),
1026 ListLit(ListLit<'input>),
1027 MapLit(MapLit<'input>),
1028 Struct(Struct<'input>),
1029 Var(Var<'input>),
1030 While(While<'input>),
1031 Break(Break<'input>),
1032 Continue(Continue<'input>),
1033 Return(Return<'input>),
1034 Range(Range<'input>),
1035}
1036
1037impl<'input> Expr<'input> {
1038 #[inline]
1040 pub fn none(loc: Loc) -> Self {
1041 Self::None(None::new(loc))
1042 }
1043
1044 #[inline]
1046 pub fn bool(loc: Loc, value: &'input str) -> Self {
1047 Self::Bool(Bool::new(loc, value))
1048 }
1049
1050 #[inline]
1052 pub fn dec(loc: Loc, value: &'input str) -> Self {
1053 Self::Num(Num::dec(loc, value))
1054 }
1055
1056 #[inline]
1058 pub fn hex(loc: Loc, value: &'input str) -> Self {
1059 Self::Num(Num::hex(loc, value))
1060 }
1061
1062 #[inline]
1064 pub fn bin(loc: Loc, value: &'input str) -> Self {
1065 Self::Num(Num::bin(loc, value))
1066 }
1067
1068 #[inline]
1070 pub fn oct(loc: Loc, value: &'input str) -> Self {
1071 Self::Num(Num::oct(loc, value))
1072 }
1073
1074 #[inline]
1076 pub fn float(loc: Loc, value: &'input str) -> Self {
1077 Self::Num(Num::float(loc, value))
1078 }
1079
1080 #[inline]
1082 pub fn ident(loc: Loc, value: &'input str) -> Self {
1083 Self::Ident(Ident::new(loc, value))
1084 }
1085
1086 #[inline]
1088 pub fn atom(loc: Loc, value: &'input str) -> Self {
1089 Self::Ident(Ident::new(loc, value))
1090 }
1091
1092 #[inline]
1094 pub fn str(loc: Loc, value: &'input str) -> Self {
1095 Self::Str(Str::new(loc, value))
1096 }
1097
1098 #[inline]
1100 pub fn binary(loc: Loc, left: Self, op: BinaryOp, right: Self) -> Self {
1101 Self::Binary(Binary::new(loc, op, Box::new(left), Box::new(right)))
1102 }
1103
1104 #[inline]
1106 pub fn call(loc: Loc, fun: Self, args: Vec<Self>) -> Self {
1107 Self::Call(Call::new(loc, Box::new(fun), args))
1108 }
1109
1110 #[inline]
1112 pub fn unary(loc: Loc, op: UnaryOp, subject: Self) -> Self {
1113 Self::Unary(Unary::new(loc, op, Box::new(subject)))
1114 }
1115
1116 #[inline]
1118 pub fn assign(loc: Loc, left: Self, op: AssignOp, right: Self) -> Self {
1119 Self::Assign(Assign::new(loc, op, Box::new(left), Box::new(right)))
1120 }
1121
1122 #[inline]
1124 pub fn range_exclusive(loc: Loc, left: Option<Self>, right: Option<Self>) -> Self {
1125 Self::Range(Range::new(loc, RangeOp::Exclusive(Box::new(left), Box::new(right))))
1126 }
1127
1128 #[inline]
1130 pub fn range_inclusive(loc: Loc, left: Option<Self>, right: Self) -> Self {
1131 Self::Range(Range::new(loc, RangeOp::Inclusive(Box::new(left), Box::new(right))))
1132 }
1133}
1134
1135impl<'input> Locate for Expr<'input> {
1136 fn loc(&self) -> Loc {
1137 match self {
1138 Expr::None(expr) => expr.loc(),
1139 Expr::Bool(expr) => expr.loc(),
1140 Expr::Num(expr) => expr.loc(),
1141 Expr::Ident(expr) => expr.loc(),
1142 Expr::Atom(expr) => expr.loc(),
1143 Expr::Str(expr) => expr.loc(),
1144 Expr::Binary(expr) => expr.loc(),
1145 Expr::Call(expr) => expr.loc(),
1146 Expr::Unary(expr) => expr.loc(),
1147 Expr::Assign(expr) => expr.loc(),
1148 Expr::If(expr) => expr.loc(),
1149 Expr::InlineFun(expr) => expr.loc(),
1150 Expr::Fun(expr) => expr.loc(),
1151 Expr::Block(expr) => expr.loc(),
1152 Expr::ListLit(expr) => expr.loc(),
1153 Expr::MapLit(expr) => expr.loc(),
1154 Expr::Struct(expr) => expr.loc(),
1155 Expr::Var(expr) => expr.loc(),
1156 Expr::While(expr) => expr.loc(),
1157 Expr::Break(expr) => expr.loc(),
1158 Expr::Continue(expr) => expr.loc(),
1159 Expr::Return(expr) => expr.loc(),
1160 Expr::Range(expr) => expr.loc(),
1161 }
1162 }
1163}