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,
|
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!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -365,6 +365,40 @@ impl<'a> Inferencer<'a> {
|
||||||
}
|
}
|
||||||
Ok(true)
|
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.
|
// break, raise, etc.
|
||||||
_ => Ok(false),
|
_ => Ok(false),
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,6 +394,7 @@ impl<'a> Fold<()> for Inferencer<'a> {
|
||||||
| ast::StmtKind::Continue { .. }
|
| ast::StmtKind::Continue { .. }
|
||||||
| ast::StmtKind::Expr { .. }
|
| ast::StmtKind::Expr { .. }
|
||||||
| ast::StmtKind::For { .. }
|
| ast::StmtKind::For { .. }
|
||||||
|
| ast::StmtKind::Global { .. }
|
||||||
| ast::StmtKind::Pass { .. }
|
| ast::StmtKind::Pass { .. }
|
||||||
| ast::StmtKind::Try { .. } => {}
|
| ast::StmtKind::Try { .. } => {}
|
||||||
ast::StmtKind::If { test, .. } | ast::StmtKind::While { test, .. } => {
|
ast::StmtKind::If { test, .. } | ast::StmtKind::While { test, .. } => {
|
||||||
|
|
Loading…
Reference in New Issue