Resolver - Report an error if a symbol isn't used
This commit is contained in:
parent
670b50e8cd
commit
34991d4b4b
1 changed files with 21 additions and 3 deletions
|
@ -40,8 +40,9 @@ enum SymKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// General information about a symbol.
|
/// General information about a symbol.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug)]
|
||||||
struct SymInfo {
|
struct SymInfo {
|
||||||
|
decl: Token,
|
||||||
kind: SymKind,
|
kind: SymKind,
|
||||||
state: SymState,
|
state: SymState,
|
||||||
}
|
}
|
||||||
|
@ -64,11 +65,27 @@ impl ResolverState {
|
||||||
F: FnOnce(&mut Self) -> ResolverResult,
|
F: FnOnce(&mut Self) -> ResolverResult,
|
||||||
{
|
{
|
||||||
self.scopes.push(HashMap::new());
|
self.scopes.push(HashMap::new());
|
||||||
let result = f(self);
|
let result = f(self).and_then(|_| self.check_unused());
|
||||||
self.scopes.pop();
|
self.scopes.pop();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check for unused symbols in the scope. If an unused symbol is found and
|
||||||
|
/// its name does not begin with an underscore, generate an error.
|
||||||
|
fn check_unused(&self) -> ResolverResult {
|
||||||
|
self.scopes[self.scopes.len() - 1]
|
||||||
|
.values()
|
||||||
|
.filter(|v| v.state != SymState::Used)
|
||||||
|
.filter(|v| !v.decl.lexeme.starts_with("_"))
|
||||||
|
.nth(0)
|
||||||
|
.map_or(Ok(()), |v| {
|
||||||
|
self.error(
|
||||||
|
&v.decl,
|
||||||
|
"unused symbol; prefix its name with '_' to avoid this error",
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to declare a symbol. If the scope already contains a declaration
|
/// Try to declare a symbol. If the scope already contains a declaration
|
||||||
/// for the same name, return an error.
|
/// for the same name, return an error.
|
||||||
fn declare(&mut self, name: &Token, kind: SymKind) -> ResolverResult {
|
fn declare(&mut self, name: &Token, kind: SymKind) -> ResolverResult {
|
||||||
|
@ -85,6 +102,7 @@ impl ResolverState {
|
||||||
scope.insert(
|
scope.insert(
|
||||||
name.lexeme.clone(),
|
name.lexeme.clone(),
|
||||||
SymInfo {
|
SymInfo {
|
||||||
|
decl: name.clone(),
|
||||||
kind,
|
kind,
|
||||||
state: SymState::Declared,
|
state: SymState::Declared,
|
||||||
},
|
},
|
||||||
|
@ -160,7 +178,7 @@ impl ResolverState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return an error.
|
/// Return an error.
|
||||||
fn error(&mut self, name: &Token, message: &str) -> ResolverResult {
|
fn error(&self, name: &Token, message: &str) -> ResolverResult {
|
||||||
Err(SloxError::with_token(
|
Err(SloxError::with_token(
|
||||||
ErrorKind::Parse,
|
ErrorKind::Parse,
|
||||||
name,
|
name,
|
||||||
|
|
Loading…
Reference in a new issue