1use std::{
2 fmt::{self, Debug, Formatter},
3 ops::ControlFlow,
4};
5
6use crate::source::Span;
7
8use super::origin;
9
10pub trait Node {
11 const TRANSPARENT: bool = false;
12
13 fn accept<'a, V: Visit>(&'a self, visit: &'a mut V) -> ControlFlow<V::Break>;
14
15 fn trans<'a, V: Visit>(&'a self, visit: &'a mut V) -> ControlFlow<V::Break> {
16 if Self::TRANSPARENT {
17 self.accept(visit)
18 } else {
19 visit.node(self)
20 }
21 }
22
23 fn span(&self) -> Span {
24 let mut visit = SpanVisit(Span::INVALID);
25 let _ = self.accept(&mut visit);
26 visit.0
27 }
28
29 fn kind(&self) -> NodeKind;
30}
31
32struct SpanVisit(Span);
33
34impl Visit for SpanVisit {
35 type Break = ();
36
37 fn node<T: Node + ?Sized>(&mut self, node: &T) -> ControlFlow<Self::Break> {
38 self.0 = self.0 | node.span();
39 ControlFlow::Continue(())
40 }
41
42 fn token(
43 &mut self,
44 _leaf: Token,
45 span: Span,
46 _origin: Option<origin::Id>,
47 ) -> ControlFlow<Self::Break> {
48 self.0 = self.0 | span;
49 ControlFlow::Continue(())
50 }
51}
52
53#[derive(Copy, Clone, Debug)]
55pub enum Token {
56 Comment,
58 Constant,
60 Delim,
62 Escape,
64 Field,
66 Key,
68 ModuleName,
70 ModuleItem,
72 Keyword,
74 Literal,
76 Number,
78 Operator,
80 StringDelim,
82 Variable,
84 Sigil,
86}
87
88pub trait Visit {
89 type Break;
90
91 fn node<T: Node + ?Sized>(&mut self, node: &T) -> ControlFlow<Self::Break>;
92 fn token(
93 &mut self,
94 token: Token,
95 span: Span,
96 origin: Option<origin::Id>,
97 ) -> ControlFlow<Self::Break>;
98}
99
100#[derive(Clone, Copy, PartialEq, Eq, Debug)]
102pub enum NodeKind {
103 Literal,
104 Ident,
105 I64,
106 VerbatimI64,
107 F64,
108 VerbatimF64,
109 Bool,
110 Nil,
111 Sym,
112 Concat,
113 Escape,
114 BinConcat,
115 EscapeByte,
116 Group,
117 Unary,
118 Binary,
119 Call,
120 Lambda,
121 Field,
122 Index,
123 Array,
124 Dict,
125 Error,
126 Assign,
127 Bind,
128 Break,
129 Class,
130 Continue,
131 Def,
132 For,
133 If,
134 Import,
135 Let,
136 Return,
137 Throw,
138 Try,
139 While,
140 NlGuard,
141 Param,
142 Block,
143 Function,
144 ImportItem,
145 Branch,
146 Catch,
147 Expand,
148 Pair,
149 Body,
150 Pattern,
151 Key,
152}
153
154impl fmt::Display for NodeKind {
155 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
156 Debug::fmt(self, f)
157 }
158}