forked from M-Labs/nac3
[core] typecheck/type_inferencer: Differentiate global symbols
Required for analyzing use of global symbols before global declaration.
This commit is contained in:
parent
1a197c67f6
commit
51bf126a32
@ -10,7 +10,7 @@ use nac3parser::ast::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
type_inferencer::{IdentifierInfo, Inferencer},
|
||||
type_inferencer::{DeclarationSource, IdentifierInfo, Inferencer},
|
||||
typedef::{Type, TypeEnum},
|
||||
};
|
||||
use crate::toplevel::helper::PrimDef;
|
||||
@ -368,7 +368,7 @@ impl<'a> Inferencer<'a> {
|
||||
StmtKind::Global { names, .. } => {
|
||||
for id in names {
|
||||
if let Some(id_info) = defined_identifiers.get(id) {
|
||||
if !id_info.is_global {
|
||||
if id_info.source == DeclarationSource::Local {
|
||||
return Err(HashSet::from([format!(
|
||||
"name '{id}' is assigned to before global declaration at {}",
|
||||
stmt.location,
|
||||
@ -385,8 +385,12 @@ impl<'a> Inferencer<'a> {
|
||||
*id,
|
||||
) {
|
||||
Ok(_) => {
|
||||
self.defined_identifiers
|
||||
.insert(*id, IdentifierInfo { is_global: true });
|
||||
self.defined_identifiers.insert(
|
||||
*id,
|
||||
IdentifierInfo {
|
||||
source: DeclarationSource::Global { is_explicit: Some(true) },
|
||||
},
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HashSet::from([format!(
|
||||
|
@ -88,11 +88,31 @@ impl PrimitiveStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// The location where an identifier declaration refers to.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum DeclarationSource {
|
||||
/// Local scope.
|
||||
Local,
|
||||
|
||||
/// Global scope.
|
||||
Global {
|
||||
/// Whether the identifier is declared by the use of `global` statement. This field is
|
||||
/// [`None`] if the identifier does not refer to a variable.
|
||||
is_explicit: Option<bool>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Information regarding a defined identifier.
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct IdentifierInfo {
|
||||
/// Whether this identifier refers to a global variable.
|
||||
pub is_global: bool,
|
||||
pub source: DeclarationSource,
|
||||
}
|
||||
|
||||
impl Default for IdentifierInfo {
|
||||
fn default() -> Self {
|
||||
IdentifierInfo { source: DeclarationSource::Local }
|
||||
}
|
||||
}
|
||||
|
||||
impl IdentifierInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user