forked from M-Labs/nac3
[core] Add support for global statements
This commit is contained in:
parent
9fdbe9695d
commit
e60e8e837f
@ -1828,6 +1828,37 @@ pub fn gen_stmt<G: CodeGenerator>(
|
||||
stmt.location,
|
||||
);
|
||||
}
|
||||
StmtKind::Global { names, .. } => {
|
||||
let registered_globals = ctx
|
||||
.top_level
|
||||
.definitions
|
||||
.read()
|
||||
.iter()
|
||||
.filter_map(|def| {
|
||||
if let TopLevelDef::Variable { simple_name, ty, .. } = &*def.read() {
|
||||
Some((*simple_name, *ty))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
for id in names {
|
||||
let Some((_, ty)) = registered_globals.iter().find(|(name, _)| name == id) else {
|
||||
return Err(format!("{id} is not a global at {}", stmt.location));
|
||||
};
|
||||
|
||||
let resolver = ctx.resolver.clone();
|
||||
let ptr = resolver
|
||||
.get_symbol_value(*id, ctx, generator)
|
||||
.map(|val| val.to_basic_value_enum(ctx, generator, *ty))
|
||||
.transpose()?
|
||||
.map(BasicValueEnum::into_pointer_value)
|
||||
.unwrap();
|
||||
|
||||
ctx.var_assignment.insert(*id, (ptr, None, 0));
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Ok(())
|
||||
|
@ -365,6 +365,40 @@ impl<'a> Inferencer<'a> {
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
StmtKind::Global { names, .. } => {
|
||||
for id in names {
|
||||
if let Some(id_info) = defined_identifiers.get(id) {
|
||||
if !id_info.is_global {
|
||||
return Err(HashSet::from([format!(
|
||||
"name '{id}' is assigned to before global declaration at {}",
|
||||
stmt.location,
|
||||
)]));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
match self.function_data.resolver.get_symbol_type(
|
||||
self.unifier,
|
||||
&self.top_level.definitions.read(),
|
||||
self.primitives,
|
||||
*id,
|
||||
) {
|
||||
Ok(_) => {
|
||||
self.defined_identifiers
|
||||
.insert(*id, IdentifierInfo { is_global: true });
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HashSet::from([format!(
|
||||
"type error at identifier `{}` ({}) at {}",
|
||||
id, e, stmt.location
|
||||
)]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
// break, raise, etc.
|
||||
_ => Ok(false),
|
||||
}
|
||||
|
@ -394,6 +394,7 @@ impl<'a> Fold<()> for Inferencer<'a> {
|
||||
| ast::StmtKind::Continue { .. }
|
||||
| ast::StmtKind::Expr { .. }
|
||||
| ast::StmtKind::For { .. }
|
||||
| ast::StmtKind::Global { .. }
|
||||
| ast::StmtKind::Pass { .. }
|
||||
| ast::StmtKind::Try { .. } => {}
|
||||
ast::StmtKind::If { test, .. } | ast::StmtKind::While { test, .. } => {
|
||||
|
Loading…
Reference in New Issue
Block a user