fix handling of global variables

This commit is contained in:
Sebastien Bourdeauducq 2024-10-08 18:58:13 +08:00
parent e31fba38e0
commit 17ce32d164
1 changed files with 45 additions and 41 deletions

View File

@ -121,48 +121,52 @@ fn handle_typevar_definition(
fn handle_assignment_pattern(
targets: &[nac3parser::ast::Expr],
value: &nac3parser::ast::Expr,
resolver: &(dyn nac3core::symbol_resolver::SymbolResolver + Send + Sync),
resolver: Arc<dyn nac3core::symbol_resolver::SymbolResolver + Send + Sync>,
internal_resolver: &ResolverInternal,
def_list: &[Arc<RwLock<toplevel::TopLevelDef>>],
unifier: &mut nac3core::typecheck::typedef::Unifier,
primitives: &type_inferencer::PrimitiveStore,
composer: &mut composer::TopLevelComposer,
) -> Result<(), String> {
if targets.len() == 1 {
match &targets[0].node {
let target = &targets[0];
match &target.node {
nac3parser::ast::ExprKind::Name { id, .. } => {
let def_list = composer.extract_def_list();
let unifier = &mut composer.unifier;
let primitives = &composer.primitives_ty;
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);
Ok(())
} else if let Ok(val) =
toplevel::helper::parse_parameter_default_value(value, resolver)
{
} else if let Ok(val) = toplevel::helper::parse_parameter_default_value(value, &*resolver) {
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(())
} else {
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
targets[0].node,
targets[0].location,
target.node,
target.location,
))
}
}
nac3parser::ast::ExprKind::List { elts, .. }
| nac3parser::ast::ExprKind::Tuple { elts, .. } => {
handle_assignment_pattern(
elts,
value,
resolver,
internal_resolver,
def_list,
unifier,
primitives,
)?;
handle_assignment_pattern(elts, value, resolver, internal_resolver, composer)?;
Ok(())
}
_ => Err(format!(
"assignment to {:?} is not supported at {}",
targets[0], targets[0].location
"assignment to {target:?} is not supported at {}",
target.location
)),
}
} else {
@ -174,11 +178,9 @@ fn handle_assignment_pattern(
handle_assignment_pattern(
std::slice::from_ref(tar),
val,
resolver,
resolver.clone(),
internal_resolver,
def_list,
unifier,
primitives,
composer,
)?;
}
Ok(())
@ -202,8 +204,9 @@ fn handle_assignment_pattern(
fn handle_global_var(
target: &nac3parser::ast::Expr,
value: Option<&nac3parser::ast::Expr>,
resolver: &(dyn nac3core::symbol_resolver::SymbolResolver + Send + Sync),
resolver: &Arc<dyn nac3core::symbol_resolver::SymbolResolver + Send + Sync>,
internal_resolver: &ResolverInternal,
composer: &mut composer::TopLevelComposer,
) -> Result<(), String> {
let nac3parser::ast::ExprKind::Name { id, .. } = target.node else {
return Err(format!(
@ -218,8 +221,18 @@ fn handle_global_var(
));
};
if let Ok(val) = toplevel::helper::parse_parameter_default_value(value, resolver) {
if let Ok(val) = toplevel::helper::parse_parameter_default_value(value, &**resolver) {
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(())
} else {
Err(format!(
@ -382,17 +395,12 @@ fn compile(code: &String, run_symbol: &String, output_filename: &Path) -> Result
for mut stmt in parser_result {
match stmt.node {
nac3parser::ast::StmtKind::Assign { targets, value, .. } => {
let def_list = composer.extract_def_list();
let unifier = &mut composer.unifier;
let primitives = &composer.primitives_ty;
handle_assignment_pattern(
&targets,
&value,
resolver.as_ref(),
resolver.clone(),
internal_resolver.as_ref(),
&def_list,
unifier,
primitives,
&mut composer,
)?;
}
nac3parser::ast::StmtKind::AnnAssign {
@ -403,14 +411,10 @@ fn compile(code: &String, run_symbol: &String, output_filename: &Path) -> Result
handle_global_var(
&target,
value.as_ref().map(Box::as_ref),
resolver.as_ref(),
&resolver,
internal_resolver.as_ref(),
&mut composer,
)?;
let (name, def_id, _) = composer
.register_top_level(stmt, Some(resolver.clone()), "__main__", true)
.unwrap();
internal_resolver.add_id_def(name, def_id);
}
_ => {
if let nac3parser::ast::StmtKind::FunctionDef { name, .. } = &mut stmt.node {