1
1
use std:: collections:: HashMap ;
2
2
3
3
use fuse_ast:: {
4
- Atom , BinaryOperator , BinaryOperatorKind , BindingPatternKind , CallExpression , Chunk ,
5
- Expression , Function , Identifier , VariableDeclaration ,
4
+ Atom , BindingPatternKind , Chunk , Function , Identifier , MemberExpression , MemberExpressionLHS ,
5
+ MemberExpressionRHS , VariableDeclaration ,
6
6
} ;
7
7
use fuse_common:: ReferenceType ;
8
8
use fuse_visitor:: {
9
- walk_binary_operator_mut , walk_call_expression_mut , walk_function_mut ,
10
- walk_variable_declaration_mut , ScopeVisitor , VisitorMut ,
9
+ walk_function_mut , walk_member_expression_mut , walk_variable_declaration_mut , ScopeVisitor ,
10
+ VisitorMut ,
11
11
} ;
12
12
13
13
#[ derive( Debug , PartialEq , Clone , Copy ) ]
@@ -31,9 +31,9 @@ impl PartialEq<ReferenceType> for ScopeId {
31
31
}
32
32
}
33
33
34
- struct IdentifierMap ( HashMap < Atom , ReferenceType > ) ;
34
+ struct IdentDeclMap ( HashMap < Atom , ReferenceType > ) ;
35
35
36
- impl IdentifierMap {
36
+ impl IdentDeclMap {
37
37
fn new ( ) -> Self {
38
38
Self ( HashMap :: new ( ) )
39
39
}
@@ -54,30 +54,31 @@ enum ReferenceKind {
54
54
55
55
struct ScopeTree {
56
56
current : ScopeId ,
57
- identifier_maps : Vec < IdentifierMap > ,
57
+ ident_decl_maps : Vec < IdentDeclMap > ,
58
58
/// Maps between `ReferenceId` and `ReferenceKind`
59
59
reference_kinds : Vec < ReferenceKind > ,
60
60
parent_ids : Vec < ScopeId > ,
61
61
}
62
62
63
+ /// Tree operations for `ScopeTree`
63
64
impl ScopeTree {
64
65
fn root_scope ( ) -> Self {
65
66
Self {
66
67
current : ScopeId ( 0 ) ,
67
68
parent_ids : vec ! [ ScopeId ( 0 ) ] ,
68
- identifier_maps : vec ! [ IdentifierMap :: new( ) ] ,
69
+ ident_decl_maps : vec ! [ IdentDeclMap :: new( ) ] ,
69
70
reference_kinds : Vec :: new ( ) ,
70
71
}
71
72
}
72
73
73
74
fn push_stack ( & mut self ) -> ScopeId {
74
- self . identifier_maps . push ( IdentifierMap :: new ( ) ) ;
75
+ self . ident_decl_maps . push ( IdentDeclMap :: new ( ) ) ;
75
76
self . parent_ids . push ( self . current ) ;
76
77
77
78
// length of all arrays should be same.
78
- debug_assert ! ( self . identifier_maps . len( ) == self . parent_ids. len( ) ) ;
79
+ debug_assert ! ( self . ident_decl_maps . len( ) == self . parent_ids. len( ) ) ;
79
80
80
- self . current = ScopeId ( self . identifier_maps . len ( ) - 1 ) ;
81
+ self . current = ScopeId ( self . ident_decl_maps . len ( ) - 1 ) ;
81
82
self . current
82
83
}
83
84
@@ -90,13 +91,32 @@ impl ScopeTree {
90
91
self . current = self . parent ( ) ;
91
92
}
92
93
94
+ fn parent ( & self ) -> ScopeId {
95
+ assert_ne ! (
96
+ self . current, 0 ,
97
+ "Attempt to access the root scope's parent."
98
+ ) ;
99
+ self . parent_ids [ self . current . as_index ( ) ]
100
+ }
101
+
102
+ fn parent_of ( & self , children_id : ScopeId ) -> ScopeId {
103
+ assert_ne ! (
104
+ self . current, 0 ,
105
+ "Attempt to access the root scope's parent."
106
+ ) ;
107
+ self . parent_ids [ children_id. as_index ( ) ]
108
+ }
109
+ }
110
+
111
+ /// Identifier operations for `ScopeTree`
112
+ impl ScopeTree {
93
113
/// Get an identifier reference from current scope or its parents.
94
114
/// This function is implemented using loops instead of recursion.
95
- fn identifier_reference ( & mut self , atom : & Atom ) -> Option < ReferenceType > {
115
+ fn scope_identifier_reference ( & mut self , atom : & Atom ) -> Option < ReferenceType > {
96
116
let mut scope_id = self . current ;
97
117
let mut reference;
98
118
loop {
99
- reference = self . identifier_maps [ scope_id. as_index ( ) ] . get ( atom) ;
119
+ reference = self . ident_decl_maps [ scope_id. as_index ( ) ] . get ( atom) ;
100
120
101
121
if reference. is_some ( ) || scope_id. is_root ( ) {
102
122
break ;
@@ -109,29 +129,20 @@ impl ScopeTree {
109
129
110
130
/// Set a `ReferenceType` for the given identifier's `Atom` in the current scope.
111
131
/// Would return the last `ReferenceType` if we are shadowing it.
112
- fn set_identifier_reference (
132
+ fn set_scope_identifier_reference (
113
133
& mut self ,
114
134
atom : Atom ,
115
135
ref_id : ReferenceType ,
116
- ref_kind : ReferenceKind ,
117
136
) -> Option < ReferenceType > {
118
- self . identifier_maps [ self . current . as_index ( ) ] . insert ( atom, ref_id)
119
- }
120
-
121
- fn parent ( & self ) -> ScopeId {
122
- assert_ne ! (
123
- self . current, 0 ,
124
- "Attempt to access the root scope's parent."
125
- ) ;
126
- self . parent_ids [ self . current . as_index ( ) ]
137
+ self . ident_decl_maps [ self . current . as_index ( ) ] . insert ( atom, ref_id)
127
138
}
128
139
129
- fn parent_of ( & self , children_id : ScopeId ) -> ScopeId {
130
- assert_ne ! (
131
- self . current , 0 ,
132
- "Attempt to access the root scope's parent."
133
- ) ;
134
- self . parent_ids [ children_id . as_index ( ) ]
140
+ fn member_identifier_reference (
141
+ & mut self ,
142
+ atom : Atom ,
143
+ ref_id : ReferenceType ,
144
+ ) -> Option < ReferenceType > {
145
+ self . ident_decl_maps [ self . current . as_index ( ) ] . insert ( atom , ref_id )
135
146
}
136
147
}
137
148
@@ -159,23 +170,29 @@ impl<'ast> Semantic<'ast> {
159
170
160
171
fn declare_identifier ( & mut self , ident : & Identifier ) {
161
172
self . last_reference += 1 ;
162
- self . scope . set_identifier_reference (
163
- ident. name . clone ( ) ,
164
- self . last_reference ,
165
- ReferenceKind :: Scope ,
166
- ) ;
173
+ self . scope
174
+ . set_scope_identifier_reference ( ident. name . clone ( ) , self . last_reference ) ;
167
175
ident. reference . set ( Some ( self . last_reference ) )
168
176
}
169
177
170
178
fn reference_scope_identifier ( & mut self , ident : & Identifier ) {
171
- let reference = self . scope . identifier_reference ( & ident. name ) ;
179
+ let reference = self . scope . scope_identifier_reference ( & ident. name ) ;
172
180
ident. reference . set ( reference)
173
181
}
174
182
175
- fn reference_member_identifier ( & mut self , ident : & Identifier , sup : Option < & Identifier > ) {
176
- let reference = self . scope . identifier_reference ( & ident. name ) ;
183
+ fn resolve_member_identifier ( & mut self , ident : & Identifier , sup : Option < & Identifier > ) {
184
+ let Some ( sup) = sup else {
185
+ return self . declare_member_identifier ( ident, None ) ;
186
+ } ;
187
+ let reference = self . scope . scope_identifier_reference ( & ident. name ) ;
188
+ ident. reference . set ( reference) ;
189
+ // todo!()
190
+ }
191
+
192
+ fn declare_member_identifier ( & mut self , ident : & Identifier , sup : Option < & Identifier > ) {
193
+ let reference = self . scope . scope_identifier_reference ( & ident. name ) ;
177
194
ident. reference . set ( reference) ;
178
- todo ! ( )
195
+ // todo!()
179
196
}
180
197
}
181
198
@@ -205,33 +222,20 @@ impl<'ast> VisitorMut<'ast> for Semantic<'ast> {
205
222
walk_function_mut ( self , decl)
206
223
}
207
224
208
- fn visit_binary_operator_mut ( & mut self , op : & ' ast mut BinaryOperator ) {
209
- match & op. kind {
210
- BinaryOperatorKind :: Member ( _) => {
211
- println ! ( "{:?}" , op) ;
212
- let rhs = match & op. rhs {
213
- Expression :: Identifier ( rhs) => rhs,
214
- Expression :: BinaryOperator ( op) => match & * * op {
215
- BinaryOperator {
216
- kind : BinaryOperatorKind :: Member ( ..) ,
217
- lhs : Expression :: Identifier ( lhs) ,
218
- ..
219
- } => lhs,
220
- BinaryOperator {
221
- kind : BinaryOperatorKind :: Member ( ..) ,
222
- lhs : Expression :: ParenthesizedExpression ( expr) ,
223
- ..
224
- } => todo ! ( ) ,
225
- _ => {
226
- todo ! ( )
227
- }
228
- } ,
229
- _ => panic ! ( "Right hand side of a member(.) operator should be an identifier" ) ,
230
- } ;
225
+ fn visit_member_expression_mut ( & mut self , member : & ' ast mut MemberExpression ) {
226
+ let lhs = member. lhs . as_ref ( ) ;
227
+ let rhs = member. rhs . as_ref ( ) ;
228
+ let sup = match lhs {
229
+ MemberExpressionLHS :: Identifier ( ident) => {
230
+ self . reference_scope_identifier ( ident) ;
231
+ Some ( ident)
231
232
}
232
- _ => { }
233
+ _ => None ,
234
+ } ;
235
+ if let MemberExpressionRHS :: Identifier ( ident) = rhs {
236
+ self . resolve_member_identifier ( ident, sup)
233
237
}
234
- walk_binary_operator_mut ( self , op )
238
+ walk_member_expression_mut ( self , member )
235
239
}
236
240
}
237
241
0 commit comments