@@ -951,13 +951,11 @@ impl SymbolTableBuilder {
951
951
let table = self . tables . last_mut ( ) . unwrap ( ) ;
952
952
let location = Default :: default ( ) ;
953
953
954
- // Some checks:
955
- let containing = table. symbols . contains_key ( name) ;
956
- if containing {
954
+ // Some checks for the symbol that present on this scope level:
955
+ if let Some ( symbol) = table. symbols . get ( name) {
957
956
// Role already set..
958
957
match role {
959
958
SymbolUsage :: Global => {
960
- let symbol = table. symbols . get ( name) . unwrap ( ) ;
961
959
if let SymbolScope :: Global = symbol. scope {
962
960
// Ok
963
961
} else {
@@ -968,32 +966,53 @@ impl SymbolTableBuilder {
968
966
}
969
967
}
970
968
SymbolUsage :: Nonlocal => {
969
+ if symbol. is_parameter {
970
+ return Err ( SymbolTableError {
971
+ error : format ! ( "name '{}' is parameter and nonlocal" , name) ,
972
+ location,
973
+ } ) ;
974
+ }
975
+ if symbol. is_referenced {
976
+ return Err ( SymbolTableError {
977
+ error : format ! ( "name '{}' is used prior to nonlocal declaration" , name) ,
978
+ location,
979
+ } ) ;
980
+ }
981
+ if symbol. is_annotated {
982
+ return Err ( SymbolTableError {
983
+ error : format ! ( "annotated name '{}' can't be nonlocal" , name) ,
984
+ location,
985
+ } ) ;
986
+ }
987
+ if symbol. is_assigned {
988
+ return Err ( SymbolTableError {
989
+ error : format ! (
990
+ "name '{}' is assigned to before nonlocal declaration" ,
991
+ name
992
+ ) ,
993
+ location,
994
+ } ) ;
995
+ }
996
+ }
997
+ _ => {
998
+ // Ok?
999
+ }
1000
+ }
1001
+ } else {
1002
+ // The symbol does not present on this scope level.
1003
+ // Some checks to insert new symbol into symbol table:
1004
+ match role {
1005
+ SymbolUsage :: Nonlocal if scope_depth < 2 => {
971
1006
return Err ( SymbolTableError {
972
- error : format ! ( "name '{}' is used prior to nonlocal declaration " , name) ,
1007
+ error : format ! ( "cannot define nonlocal '{}' at top level. " , name) ,
973
1008
location,
974
1009
} )
975
1010
}
976
1011
_ => {
977
- // Ok?
1012
+ // Ok!
978
1013
}
979
1014
}
980
- }
981
-
982
- // Some more checks:
983
- match role {
984
- SymbolUsage :: Nonlocal if scope_depth < 2 => {
985
- return Err ( SymbolTableError {
986
- error : format ! ( "cannot define nonlocal '{}' at top level." , name) ,
987
- location,
988
- } )
989
- }
990
- _ => {
991
- // Ok!
992
- }
993
- }
994
-
995
- // Insert symbol when required:
996
- if !containing {
1015
+ // Insert symbol when required:
997
1016
let symbol = Symbol :: new ( name) ;
998
1017
table. symbols . insert ( name. to_owned ( ) , symbol) ;
999
1018
}
@@ -1002,14 +1021,7 @@ impl SymbolTableBuilder {
1002
1021
let symbol = table. symbols . get_mut ( name) . unwrap ( ) ;
1003
1022
match role {
1004
1023
SymbolUsage :: Nonlocal => {
1005
- if let SymbolScope :: Unknown = symbol. scope {
1006
- symbol. scope = SymbolScope :: Nonlocal ;
1007
- } else {
1008
- return Err ( SymbolTableError {
1009
- error : format ! ( "Symbol {} scope cannot be set to nonlocal, since its scope was already determined otherwise." , name) ,
1010
- location,
1011
- } ) ;
1012
- }
1024
+ symbol. scope = SymbolScope :: Nonlocal ;
1013
1025
}
1014
1026
SymbolUsage :: Imported => {
1015
1027
symbol. is_assigned = true ;
0 commit comments