forked from M-Labs/nac3
[standalone] Add support for registering globals without type decl
This commit is contained in:
parent
65a12d9ab3
commit
56c845aac4
|
@ -382,6 +382,19 @@ impl TopLevelComposer {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::StmtKind::Assign { .. } => {
|
||||||
|
// Assignment statements can assign to (and therefore create) more than one
|
||||||
|
// variable, but this function only allows returning one set of symbol information.
|
||||||
|
// We want to avoid changing this to return a `Vec` of symbol info, as this would
|
||||||
|
// require `iter().next().unwrap()` on every variable created from a non-Assign
|
||||||
|
// statement.
|
||||||
|
//
|
||||||
|
// Make callers use `register_top_level_var` instead, as it provides more
|
||||||
|
// fine-grained control over which symbols to register, while also simplifying the
|
||||||
|
// usage of this function.
|
||||||
|
panic!("Registration of top-level Assign statements must use TopLevelComposer::register_top_level_var (at {})", ast.location);
|
||||||
|
}
|
||||||
|
|
||||||
ast::StmtKind::AnnAssign { target, annotation, .. } => {
|
ast::StmtKind::AnnAssign { target, annotation, .. } => {
|
||||||
let ExprKind::Name { id: name, .. } = target.node else {
|
let ExprKind::Name { id: name, .. } = target.node else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
|
|
|
@ -174,46 +174,49 @@ fn handle_typevar_definition(
|
||||||
fn handle_assignment_pattern(
|
fn handle_assignment_pattern(
|
||||||
targets: &[Expr],
|
targets: &[Expr],
|
||||||
value: &Expr,
|
value: &Expr,
|
||||||
resolver: &(dyn SymbolResolver + Send + Sync),
|
resolver: Arc<dyn SymbolResolver + Send + Sync>,
|
||||||
internal_resolver: &ResolverInternal,
|
internal_resolver: &ResolverInternal,
|
||||||
def_list: &[Arc<RwLock<TopLevelDef>>],
|
composer: &mut TopLevelComposer,
|
||||||
unifier: &mut Unifier,
|
|
||||||
primitives: &PrimitiveStore,
|
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if targets.len() == 1 {
|
if targets.len() == 1 {
|
||||||
match &targets[0].node {
|
let target = &targets[0];
|
||||||
|
|
||||||
|
match &target.node {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
|
let def_list = composer.extract_def_list();
|
||||||
|
let unifier = &mut composer.unifier;
|
||||||
|
let primitives = &composer.primitives_ty;
|
||||||
|
|
||||||
if let Ok(var) =
|
if let Ok(var) =
|
||||||
handle_typevar_definition(value, resolver, def_list, unifier, primitives)
|
handle_typevar_definition(value, &*resolver, &def_list, unifier, primitives)
|
||||||
{
|
{
|
||||||
internal_resolver.add_id_type(*id, var);
|
internal_resolver.add_id_type(*id, var);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if let Ok(val) = parse_parameter_default_value(value, resolver) {
|
} else if let Ok(val) = parse_parameter_default_value(value, &*resolver) {
|
||||||
internal_resolver.add_module_global(*id, val);
|
internal_resolver.add_module_global(*id, val);
|
||||||
|
let (name, def_id, _) = composer
|
||||||
|
.register_top_level_var(
|
||||||
|
*id,
|
||||||
|
None,
|
||||||
|
Some(resolver.clone()),
|
||||||
|
"__main__",
|
||||||
|
target.location,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
internal_resolver.add_id_def(name, def_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
|
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
|
||||||
targets[0].node,
|
target.node,
|
||||||
targets[0].location,
|
target.location,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
|
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
|
||||||
handle_assignment_pattern(
|
handle_assignment_pattern(elts, value, resolver, internal_resolver, composer)?;
|
||||||
elts,
|
|
||||||
value,
|
|
||||||
resolver,
|
|
||||||
internal_resolver,
|
|
||||||
def_list,
|
|
||||||
unifier,
|
|
||||||
primitives,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(format!(
|
_ => Err(format!("assignment to {target:?} is not supported at {}", target.location)),
|
||||||
"assignment to {:?} is not supported at {}",
|
|
||||||
targets[0], targets[0].location
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match &value.node {
|
match &value.node {
|
||||||
|
@ -223,11 +226,9 @@ fn handle_assignment_pattern(
|
||||||
handle_assignment_pattern(
|
handle_assignment_pattern(
|
||||||
std::slice::from_ref(tar),
|
std::slice::from_ref(tar),
|
||||||
val,
|
val,
|
||||||
resolver,
|
resolver.clone(),
|
||||||
internal_resolver,
|
internal_resolver,
|
||||||
def_list,
|
composer,
|
||||||
unifier,
|
|
||||||
primitives,
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -360,17 +361,12 @@ fn main() {
|
||||||
for stmt in parser_result {
|
for stmt in parser_result {
|
||||||
match &stmt.node {
|
match &stmt.node {
|
||||||
StmtKind::Assign { targets, value, .. } => {
|
StmtKind::Assign { targets, value, .. } => {
|
||||||
let def_list = composer.extract_def_list();
|
|
||||||
let unifier = &mut composer.unifier;
|
|
||||||
let primitives = &composer.primitives_ty;
|
|
||||||
if let Err(err) = handle_assignment_pattern(
|
if let Err(err) = handle_assignment_pattern(
|
||||||
targets,
|
targets,
|
||||||
value,
|
value,
|
||||||
resolver.as_ref(),
|
resolver.clone(),
|
||||||
internal_resolver.as_ref(),
|
internal_resolver.as_ref(),
|
||||||
&def_list,
|
&mut composer,
|
||||||
unifier,
|
|
||||||
primitives,
|
|
||||||
) {
|
) {
|
||||||
panic!("{err}");
|
panic!("{err}");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue