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( fn handle_assignment_pattern(
targets: &[nac3parser::ast::Expr], targets: &[nac3parser::ast::Expr],
value: &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, internal_resolver: &ResolverInternal,
def_list: &[Arc<RwLock<toplevel::TopLevelDef>>], composer: &mut composer::TopLevelComposer,
unifier: &mut nac3core::typecheck::typedef::Unifier,
primitives: &type_inferencer::PrimitiveStore,
) -> Result<(), String> { ) -> Result<(), String> {
if targets.len() == 1 { if targets.len() == 1 {
match &targets[0].node { let target = &targets[0];
match &target.node {
nac3parser::ast::ExprKind::Name { id, .. } => { 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) = 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) = } else if let Ok(val) = toplevel::helper::parse_parameter_default_value(value, &*resolver) {
toplevel::helper::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,
)) ))
} }
} }
nac3parser::ast::ExprKind::List { elts, .. } nac3parser::ast::ExprKind::List { elts, .. }
| nac3parser::ast::ExprKind::Tuple { elts, .. } => { | nac3parser::ast::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 {:?} is not supported at {}", "assignment to {target:?} is not supported at {}",
targets[0], targets[0].location target.location
)), )),
} }
} else { } else {
@ -174,11 +178,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(())
@ -202,8 +204,9 @@ fn handle_assignment_pattern(
fn handle_global_var( fn handle_global_var(
target: &nac3parser::ast::Expr, target: &nac3parser::ast::Expr,
value: Option<&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, internal_resolver: &ResolverInternal,
composer: &mut composer::TopLevelComposer,
) -> Result<(), String> { ) -> Result<(), String> {
let nac3parser::ast::ExprKind::Name { id, .. } = target.node else { let nac3parser::ast::ExprKind::Name { id, .. } = target.node else {
return Err(format!( 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); 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!( Err(format!(
@ -382,17 +395,12 @@ fn compile(code: &String, run_symbol: &String, output_filename: &Path) -> Result
for mut stmt in parser_result { for mut stmt in parser_result {
match stmt.node { match stmt.node {
nac3parser::ast::StmtKind::Assign { targets, value, .. } => { 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( 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,
)?; )?;
} }
nac3parser::ast::StmtKind::AnnAssign { nac3parser::ast::StmtKind::AnnAssign {
@ -403,14 +411,10 @@ fn compile(code: &String, run_symbol: &String, output_filename: &Path) -> Result
handle_global_var( handle_global_var(
&target, &target,
value.as_ref().map(Box::as_ref), value.as_ref().map(Box::as_ref),
resolver.as_ref(), &resolver,
internal_resolver.as_ref(), 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 { if let nac3parser::ast::StmtKind::FunctionDef { name, .. } = &mut stmt.node {