@@ -127,16 +127,18 @@ export class Resolver implements StmtNS.Visitor<void>, ExprNS.Visitor<void> {
127
127
ast : Stmt ;
128
128
// change the environment to be suite scope as in python
129
129
environment : Environment | null ;
130
+ functionScope : Environment | null ;
130
131
constructor ( source : string , ast : Stmt ) {
131
132
this . source = source ;
132
133
this . ast = ast ;
133
134
// The global environment
134
135
this . environment = new Environment ( source , null , new Map ( [
135
136
[ "range" , new Token ( TokenType . NAME , "range" , 0 , 0 , 0 ) ] ,
136
- [ "display " , new Token ( TokenType . NAME , "display " , 0 , 0 , 0 ) ] ,
137
+ [ "print " , new Token ( TokenType . NAME , "print " , 0 , 0 , 0 ) ] ,
137
138
[ "stringify" , new Token ( TokenType . NAME , "stringify" , 0 , 0 , 0 ) ] ,
138
139
// @TODO add all the source pre-declared names here
139
140
] ) ) ;
141
+ this . functionScope = null ;
140
142
}
141
143
resolve ( stmt : Stmt [ ] | Stmt | Expr [ ] | Expr | null ) {
142
144
if ( stmt === null ) {
@@ -163,6 +165,27 @@ export class Resolver implements StmtNS.Visitor<void>, ExprNS.Visitor<void> {
163
165
return res . length === 0 ? null : res ;
164
166
}
165
167
168
+ functionVarConstraint ( identifier : Token ) : void {
169
+ if ( this . functionScope == null ) {
170
+ return ;
171
+ }
172
+ let curr = this . environment ;
173
+ while ( curr !== this . functionScope ) {
174
+ if ( curr !== null && curr . names . has ( identifier . lexeme ) ) {
175
+ const token = curr . names . get ( identifier . lexeme ) ;
176
+ if ( token === undefined ) {
177
+ throw new Error ( "placeholder error" )
178
+ }
179
+ throw new ResolverErrors . NameReassignmentError ( identifier . line , identifier . col ,
180
+ this . source ,
181
+ identifier . indexInSource ,
182
+ identifier . indexInSource + identifier . lexeme . length ,
183
+ token ) ;
184
+ }
185
+ curr = curr ?. enclosing ?? null ;
186
+ }
187
+ }
188
+
166
189
//// STATEMENTS
167
190
visitFileInputStmt ( stmt : StmtNS . FileInput ) : void {
168
191
// Create a new environment.
@@ -175,8 +198,7 @@ export class Resolver implements StmtNS.Visitor<void>, ExprNS.Visitor<void> {
175
198
}
176
199
177
200
visitIndentCreation ( stmt : StmtNS . Indent ) : void {
178
- // Create a new environment.
179
- const oldEnv = this . environment ;
201
+ // Create a new environment
180
202
this . environment = new Environment ( this . source , this . environment , new Map ( ) ) ;
181
203
}
182
204
@@ -190,19 +212,20 @@ export class Resolver implements StmtNS.Visitor<void>, ExprNS.Visitor<void> {
190
212
visitFunctionDefStmt ( stmt : StmtNS . FunctionDef ) {
191
213
this . environment ?. declareName ( stmt . name ) ;
192
214
this . environment ?. functions . add ( stmt . name . lexeme ) ;
193
- // // Create a new environment.
215
+ // Create a new environment.
194
216
// const oldEnv = this.environment;
195
- // // Assign the parameters to the new environment.
196
- // const newEnv = new Map(
197
- // stmt.parameters.map(param => [param.lexeme, param])
198
- // );
199
- // this.environment = new Environment(this.source, this.environment, newEnv);
200
- const params = new Map (
217
+ // Assign the parameters to the new environment.
218
+ const newEnv = new Map (
201
219
stmt . parameters . map ( param => [ param . lexeme , param ] )
202
220
) ;
203
- if ( this . environment !== null ) {
204
- this . environment . names = params ;
205
- }
221
+ this . environment = new Environment ( this . source , this . environment , newEnv ) ;
222
+ // const params = new Map(
223
+ // stmt.parameters.map(param => [param.lexeme, param])
224
+ // );
225
+ // if (this.environment !== null) {
226
+ // this.environment.names = params;
227
+ // }
228
+ this . functionScope = this . environment ;
206
229
this . resolve ( stmt . body ) ;
207
230
// Grab identifiers from that new environment. That are NOT functions.
208
231
// stmt.varDecls = this.varDeclNames(this.environment.names)
@@ -213,11 +236,13 @@ export class Resolver implements StmtNS.Visitor<void>, ExprNS.Visitor<void> {
213
236
visitAnnAssignStmt ( stmt : StmtNS . AnnAssign ) : void {
214
237
this . resolve ( stmt . ann ) ;
215
238
this . resolve ( stmt . value ) ;
239
+ this . functionVarConstraint ( stmt . name ) ;
216
240
this . environment ?. declareName ( stmt . name ) ;
217
241
}
218
242
219
243
visitAssignStmt ( stmt : StmtNS . Assign ) : void {
220
244
this . resolve ( stmt . value ) ;
245
+ this . functionVarConstraint ( stmt . name ) ;
221
246
this . environment ?. declareName ( stmt . name ) ;
222
247
}
223
248
0 commit comments