1
1
// based on https://rust-unofficial.github.io/patterns/patterns/behavioural/visitor.html
2
+ // and https://github.com/rust-lang/rust/blob/5bc7b9ac8ace5312e1d2cdc2722715cf58d4f926/compiler/rustc_ast_ir/src/visit.rs
2
3
3
4
use crate :: ast:: * ;
4
5
6
+ macro_rules! visit {
7
+ ( $expr: expr) => {
8
+ $expr
9
+ } ;
10
+ }
11
+
5
12
macro_rules! visit_list {
6
- ( $visitor: ident, $method: ident, $list: expr) => {
7
- todo!( )
13
+ ( $visitor: ident, $method: ident, $list: expr $( , $( $extra_args: expr) , * ) ?) => {
14
+ for elem in $list {
15
+ visit!( $visitor. $method( elem $( , $( $extra_args) ,* ) ?) )
16
+ }
8
17
} ;
9
18
}
10
19
@@ -13,15 +22,175 @@ pub trait Visitor<'ast>: Sized {
13
22
walk_block ( self , & chunk. body )
14
23
}
15
24
25
+ fn visit_block ( & mut self , block : & ' ast Block ) {
26
+ walk_block ( self , block)
27
+ }
28
+
16
29
fn visit_statement ( & mut self , statement : & ' ast Statement ) {
17
30
walk_statement ( self , & statement)
18
31
}
32
+
33
+ fn visit_expression ( & mut self , expression : & ' ast Expression ) {
34
+ walk_expression ( self , & expression)
35
+ }
36
+
37
+ fn visit_number_literal ( & mut self , _: & ' ast NumberLiteral ) { }
38
+
39
+ fn visit_string_literal ( & mut self , _: & ' ast StringLiteral ) { }
40
+
41
+ fn visit_boolean_literal ( & mut self , _: & ' ast BooleanLiteral ) { }
42
+
43
+ fn visit_identifier ( & mut self , _: & ' ast Identifier ) { }
44
+
45
+ fn visit_function ( & mut self , func : & ' ast Function ) {
46
+ walk_function ( self , & func)
47
+ }
48
+
49
+ fn visit_function_signature ( & mut self , sign : & ' ast FunctionSignature ) {
50
+ walk_function_signature ( self , & sign)
51
+ }
52
+
53
+ fn visit_function_parameters ( & mut self , params : & ' ast FunctionParameters ) {
54
+ walk_function_parameters ( self , & params)
55
+ }
56
+
57
+ fn visit_function_parameter ( & mut self , param : & ' ast FunctionParameter ) {
58
+ walk_function_parameter ( self , & param)
59
+ }
60
+
61
+ fn visit_function_body ( & mut self , body : & ' ast FunctionBody ) {
62
+ walk_function_body ( self , & body)
63
+ }
64
+
65
+ fn visit_binding_pattern ( & mut self , pattern : & ' ast BindingPattern ) {
66
+ walk_binding_pattern ( self , & pattern)
67
+ }
68
+
69
+ fn visit_binding_identifier ( & mut self , pattern : & ' ast BindingIdentifier ) {
70
+ walk_binding_identifier ( self , & pattern)
71
+ }
72
+
73
+ fn visit_binding_rest ( & mut self , rest : & ' ast BindingRest ) {
74
+ walk_binding_rest ( self , & rest)
75
+ }
76
+
77
+ fn visit_type_annotation ( & mut self , annotation : & ' ast TypeAnnotation ) {
78
+ walk_type_annotation ( self , & annotation)
79
+ }
19
80
}
20
81
21
82
pub fn walk_block < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , block : & ' ast Block ) {
22
- visit_list ! ( visitor, visit_statement, block. statements)
83
+ visit_list ! ( visitor, visit_statement, & block. statements)
23
84
}
24
85
25
86
pub fn walk_statement < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , statement : & ' ast Statement ) {
26
- todo ! ( )
87
+ match statement {
88
+ Statement :: Empty ( _) => { } ,
89
+ Statement :: Expression ( expr) => visit ! ( visitor. visit_expression( expr) ) ,
90
+ _ => todo ! ( )
91
+ // Statement::VariableDeclaration(Box<VariableDeclaration>),
92
+ // Statement::FunctionDeclaration(Box<Function>),
93
+ // Statement::EnumDeclaration(Box<EnumDeclaration>),
94
+ // Statement::StructDeclaration(Box<StructDeclaration>),
95
+ // Statement::ImplStatement(Box<ImplStatement>),
96
+ }
27
97
}
98
+
99
+ pub fn walk_expression < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , expression : & ' ast Expression ) {
100
+ match expression {
101
+ Expression :: NumberLiteral ( lit) => visit ! ( visitor. visit_number_literal( lit) ) ,
102
+ Expression :: StringLiteral ( lit) => visit ! ( visitor. visit_string_literal( lit) ) ,
103
+ Expression :: BooleanLiteral ( lit) => visit ! ( visitor. visit_boolean_literal( lit) ) ,
104
+ Expression :: Identifier ( ident) => visit ! ( visitor. visit_identifier( ident) ) ,
105
+ Expression :: Function ( func) => visit ! ( visitor. visit_function( func) ) ,
106
+
107
+ // Expression::If(e),
108
+ // Expression::UnaryOperator(e),
109
+ // Expression::BinaryOperator(e),
110
+ // Expression::ArrayExpression(e),
111
+ // Expression::TupleExpression(e),
112
+ // Expression::ParenthesizedExpression(e),
113
+ // Expression::CallExpression(e),
114
+ // Expression::TableConstructionExpression(e),
115
+ // Expression::StructConstructionExpression(e),
116
+ _ => todo ! ( ) ,
117
+ }
118
+ }
119
+
120
+ pub fn walk_function < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , func : & ' ast Function ) {
121
+ visit ! ( visitor. visit_function_signature( & func. signature) ) ;
122
+ visit ! ( visitor. visit_function_body( & func. body) ) ;
123
+ }
124
+
125
+ pub fn walk_function_signature < ' ast , V : Visitor < ' ast > > (
126
+ visitor : & mut V ,
127
+ sign : & ' ast FunctionSignature ,
128
+ ) {
129
+ if let Some ( ident) = & sign. identifier {
130
+ visit ! ( visitor. visit_identifier( ident) ) ;
131
+ }
132
+ visit ! ( visitor. visit_function_parameters( & sign. params) ) ;
133
+ if let Some ( annotation) = & sign. return_type {
134
+ visit ! ( visitor. visit_type_annotation( annotation) ) ;
135
+ }
136
+ }
137
+
138
+ pub fn walk_function_parameters < ' ast , V : Visitor < ' ast > > (
139
+ visitor : & mut V ,
140
+ params : & ' ast FunctionParameters ,
141
+ ) {
142
+ for param in & params. items {
143
+ visit ! ( visitor. visit_function_parameter( param) )
144
+ }
145
+ if let Some ( rest) = & params. rest {
146
+ visit ! ( visitor. visit_binding_rest( rest) )
147
+ }
148
+ }
149
+
150
+ pub fn walk_function_parameter < ' ast , V : Visitor < ' ast > > (
151
+ visitor : & mut V ,
152
+ param : & ' ast FunctionParameter ,
153
+ ) {
154
+ visit ! ( visitor. visit_binding_pattern( & param. pattern) )
155
+ }
156
+
157
+ pub fn walk_function_body < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , body : & ' ast FunctionBody ) {
158
+ match body {
159
+ FunctionBody :: Block ( block) => visit ! ( visitor. visit_block( block) ) ,
160
+ FunctionBody :: Expression ( expr) => visit ! ( visitor. visit_expression( expr) ) ,
161
+ }
162
+ }
163
+
164
+ pub fn walk_binding_pattern < ' ast , V : Visitor < ' ast > > (
165
+ visitor : & mut V ,
166
+ pattern : & ' ast BindingPattern ,
167
+ ) {
168
+ match & pattern. kind {
169
+ BindingPatternKind :: Identifier ( patt) => {
170
+ visit ! ( visitor. visit_binding_identifier( patt) )
171
+ }
172
+ _ => todo ! ( ) ,
173
+ }
174
+ }
175
+
176
+ pub fn walk_binding_identifier < ' ast , V : Visitor < ' ast > > (
177
+ visitor : & mut V ,
178
+ pattern : & ' ast BindingIdentifier ,
179
+ ) {
180
+ visit ! ( visitor. visit_identifier( & pattern. identifier) )
181
+ }
182
+
183
+ pub fn walk_binding_rest < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , rest : & ' ast BindingRest ) {
184
+ visit ! ( visitor. visit_binding_identifier( & rest. binding) ) ;
185
+ if let Some ( annotation) = & rest. type_annotation {
186
+ visit ! ( visitor. visit_type_annotation( annotation) )
187
+ } ;
188
+ }
189
+
190
+ pub fn walk_type_annotation < ' ast , V : Visitor < ' ast > > (
191
+ visitor : & mut V ,
192
+ annotation : & ' ast TypeAnnotation ,
193
+ ) {
194
+ }
195
+
196
+ pub fn walk_template < ' ast , V : Visitor < ' ast > > ( visitor : & mut V , expression : & ' ast Expression ) { }
0 commit comments