WIP: Partial implementation of dunder support

This commit is contained in:
Siddhangana 2025-01-31 11:52:20 +08:00
parent 9e12ce442f
commit c4373281c7
4 changed files with 107 additions and 14 deletions

View File

@ -10,9 +10,9 @@ class NameManglingTest:
def __init__(self): def __init__(self):
self.core = Core() self.core = Core()
self.__var1 = 42 self.__var1 = 100
self.__var2__ = 10 self.__var2__ = 200
self.__ = 99 self.__ = 300
@rpc @rpc
def get_var1(self) -> int32: def get_var1(self) -> int32:
@ -28,10 +28,10 @@ class NameManglingTest:
@kernel @kernel
def run(self): def run(self):
assert self.get_var1() == 42 assert self.get_var1() == 100
assert self.get_var2() == 10 assert self.get_var2() == 200
assert self.get_var3() == 99 assert self.get_var3() == 300
#assert self._NameManglingTest__var1 == 100
if __name__ == "__main__": if __name__ == "__main__":
NameManglingTest().run() NameManglingTest().run()

View File

@ -630,15 +630,28 @@ impl Nac3 {
{ {
let defs = top_level.definitions.read(); let defs = top_level.definitions.read();
for def in defs.iter() {
println!("{:?}", def.read());
}
for (class_data, id, is_async) in &rpc_ids { for (class_data, id, is_async) in &rpc_ids {
let mut def = defs[id.0].write(); let mut def = defs[id.0].write();
match &mut *def { match &mut *def {
TopLevelDef::Function { codegen_callback, .. } => { TopLevelDef::Function { codegen_callback, .. } => {
*codegen_callback = Some(rpc_codegen_callback(*is_async)); *codegen_callback = Some(rpc_codegen_callback(*is_async));
} }
TopLevelDef::Class { methods, .. } => { TopLevelDef::Class { methods, fields, .. } => {
let (class_def, method_name) = class_data.as_ref().unwrap(); let (class_def, method_name) = class_data.as_ref().unwrap();
println!("Class definition for: {:?}", class_def);
println!("Fields in the class:");
for (field_name, field_type, mutable) in fields {
println!(
"Field name: {}, Field type: {:?}, Mutable: {}",
field_name, field_type, mutable
);
}
println!("Methods in the class:");
for (name, _, id) in &*methods { for (name, _, id) in &*methods {
println!("Method: {}", name);
if name != method_name { if name != method_name {
continue; continue;
} }

View File

@ -188,6 +188,7 @@ impl StaticValue for PythonValue {
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
) -> Option<ValueEnum<'ctx>> { ) -> Option<ValueEnum<'ctx>> {
{ {
println!("Debug: Entered `get_field` with name `{}` and ID `{}`", name.to_string(), self.id);
let field_to_val = self.resolver.field_to_val.read(); let field_to_val = self.resolver.field_to_val.read();
field_to_val.get(&(self.id, name)).cloned() field_to_val.get(&(self.id, name)).cloned()
} }
@ -209,10 +210,20 @@ impl StaticValue for PythonValue {
let def_id = { *self.resolver.pyid_to_def.read().get(&ty_id).unwrap() }; let def_id = { *self.resolver.pyid_to_def.read().get(&ty_id).unwrap() };
let mut mutable = true; let mut mutable = true;
let defs = ctx.top_level.definitions.read(); let defs = ctx.top_level.definitions.read();
println!("Debug: defs length: {}", defs.len());
println!("Debug: def_id index: {}", def_id.0);
if let TopLevelDef::Class { fields, .. } = &*defs[def_id.0].read() { if let TopLevelDef::Class { fields, .. } = &*defs[def_id.0].read() {
println!("Debug: Accessing TopLevelDef::Class with fields:");
for (field_name, _, is_mutable) in fields { for (field_name, _, is_mutable) in fields {
println!(
"Debug: Field `{}`, Mutable: {}, Comparing with `{}`",
field_name.to_string(),
is_mutable,
name.to_string()
);
if field_name == &name { if field_name == &name {
mutable = *is_mutable; mutable = *is_mutable;
println!("Debug: Match found for field `{}`. Mutable: {}", field_name.to_string(), is_mutable);
break; break;
} }
} }
@ -946,18 +957,50 @@ impl InnerResolver {
} }
} }
} }
pub fn debug_dump_field_to_val(&self) {
let field_to_val = self.field_to_val.read(); // Access the field_to_val map
println!("Debug: Dumping `field_to_val`...");
for ((id, name), handle) in field_to_val.iter() {
println!(" Field Name: {}, ID: {}, Handle: {:?}", name.to_string(), id, handle);
}
}
pub fn debug_dump_id_to_def(&self) {
let id_to_def = self.id_to_def.read(); // Access the id_to_def map
println!("Debug: Dumping `id_to_def`...");
for (name, def_id) in id_to_def.iter() {
println!(" Identifier: {}, DefinitionId: {:?}", name.to_string(), def_id);
}
}
pub fn debug_dump_id_to_pyval(&self) {
let id_to_pyval = self.id_to_pyval.read(); // Access the id_to_pyval map
println!("Debug: Dumping `id_to_pyval`...");
for (name, (id, obj)) in id_to_pyval.iter() {
println!(" Identifier: {}, ID: {}, PyObject: {:?}", name.to_string(), id, obj);
}
}
pub fn get_class_name(&self, field_id: StrRef, defs: &[Arc<RwLock<TopLevelDef>>]) -> Option<String> { pub fn get_class_name(&self, field_id: StrRef, defs: &[Arc<RwLock<TopLevelDef>>]) -> Option<String> {
println!(
"Debug: Resolving field `{}` in get_class_name",
field_id.to_string()
);
let field_to_val = self.field_to_val.read(); let field_to_val = self.field_to_val.read();
let class_id = field_to_val.iter().find_map(|(&(id, ref name), _)| { let class_id = field_to_val.iter().find_map(|(&(id, ref name), _)| {
println!(
"Debug: Checking field name `{}` with id `{}`",
name.to_string(),
id
);
if *name == field_id { if *name == field_id {
Some(id) Some(id)
} else { } else {
None None
} }
})?; })?;
println!("Debug: Found class id: `{}` for field `{}`", class_id, field_id.to_string());
let id_to_def = self.id_to_def.read(); let id_to_def = self.id_to_def.read();
let def_id = id_to_def.get(&StrRef::from(class_id.to_string()))?; let def_id = id_to_def.get(&StrRef::from(class_id.to_string()))?;
@ -1540,15 +1583,21 @@ impl SymbolResolver for Resolver {
) -> Option<ValueEnum<'ctx>> { ) -> Option<ValueEnum<'ctx>> {
let (resolved_id, _is_dunder) = if id.to_string().starts_with("__") && !id.to_string().ends_with("__") && !id.to_string().contains('.') { let (resolved_id, _is_dunder) = if id.to_string().starts_with("__") && !id.to_string().ends_with("__") && !id.to_string().contains('.') {
let inner_resolver = &self.0; let inner_resolver = &self.0;
if let Some(class_name) = inner_resolver.get_class_name(id, &ctx.top_level.definitions.read()) { if let Some(class_name) = inner_resolver.get_class_name(id, &ctx.top_level.definitions.read()) {
println!(
"Debug: Mangling dunder variable `{}` with class `{}`",
id.to_string(),
class_name
);
let stripped_class_name = class_name.trim_start_matches('_'); let stripped_class_name = class_name.trim_start_matches('_');
let mangled_id: StrRef = format!("_{}{}", stripped_class_name, id).into(); let mangled_id: StrRef = format!("_{}{}", stripped_class_name, id).into();
(mangled_id, true) (mangled_id, true)
} else { } else {
println!("Debug: Could not resolve class name for `{}`", id.to_string());
(id, false) (id, false)
} }
} else { } else {
println!("Debug: Identifier `{}` is not a dunder variable", id.to_string());
(id, false) (id, false)
}; };
let sym_value = { let sym_value = {
@ -1586,11 +1635,20 @@ impl SymbolResolver for Resolver {
} }
fn get_identifier_def(&self, id: StrRef) -> Result<DefinitionId, HashSet<String>> { fn get_identifier_def(&self, id: StrRef) -> Result<DefinitionId, HashSet<String>> {
println!("Debug: Resolving identifier `{}`", id.to_string());
println!("Debug: Dumping resolver state before reading `id_to_def`:");
self.0.debug_dump_field_to_val();
self.0.debug_dump_id_to_def();
self.0.debug_dump_id_to_pyval();
{ {
let id_to_def = self.0.id_to_def.read(); let id_to_def = self.0.id_to_def.read();
id_to_def.get(&id).copied().ok_or_else(String::new) id_to_def.get(&id).copied().ok_or_else(String::new)
} }
.or_else(|_| { .or_else(|_| {
println!("Debug: Falling back to name_to_pyid for `{}`", id.to_string());
let py_id = self let py_id = self
.0 .0
.name_to_pyid .name_to_pyid
@ -1601,6 +1659,13 @@ impl SymbolResolver for Resolver {
"`{id}` is not registered with NAC3 (@nac3 decorator missing?)" "`{id}` is not registered with NAC3 (@nac3 decorator missing?)"
)]) )])
})?; })?;
println!("Debug: Dumping resolver state after resolving `{}`:", id.to_string());
self.0.debug_dump_field_to_val();
self.0.debug_dump_id_to_def();
self.0.debug_dump_id_to_pyval();
println!("Debug: Found in pyid_to_def -> {:?}", result);
self.0.id_to_def.write().insert(id, result); self.0.id_to_def.write().insert(id, result);
Ok(result) Ok(result)
}) })

View File

@ -447,6 +447,10 @@ impl TopLevelComposer {
} }
let ty_to_be_unified = self.unifier.get_dummy_var().ty; let ty_to_be_unified = self.unifier.get_dummy_var().ty;
println!(
"Registering field: name=`{}` in module=`{}` with annotation=`{:?}` at location=`{:?}`",
name, mod_path, annotation, location
);
self.definition_ast_list.push(( self.definition_ast_list.push((
RwLock::new(Self::make_top_level_variable_def( RwLock::new(Self::make_top_level_variable_def(
global_var_name, global_var_name,
@ -1179,7 +1183,7 @@ impl TopLevelComposer {
if let ExprKind::Name { id: attr, .. } = &target.node { if let ExprKind::Name { id: attr, .. } = &target.node {
if defined_fields.insert(attr.to_string()) { if defined_fields.insert(attr.to_string()) {
let dummy_field_type = unifier.get_dummy_var().ty; let dummy_field_type = unifier.get_dummy_var().ty;
let mutable = false;
let annotation = match value { let annotation = match value {
None => { None => {
// handle Kernel[T], KernelInvariant[T] // handle Kernel[T], KernelInvariant[T]
@ -1243,6 +1247,10 @@ impl TopLevelComposer {
annotation annotation
} }
}; };
println!(
"Class field registered: name=`{}`, type=`{:?}`, mutable=`{}`",
attr, annotation, mutable
);
let parsed_annotation = parse_ast_to_type_annotation_kinds( let parsed_annotation = parse_ast_to_type_annotation_kinds(
class_resolver, class_resolver,
temp_def_list, temp_def_list,
@ -1975,6 +1983,13 @@ impl TopLevelComposer {
&mut None, &mut None,
)?; )?;
let variable_name = match &*variable_def.read() {
TopLevelDef::Class { name, .. } => name.clone(),
TopLevelDef::Function { simple_name, .. } => simple_name.clone(),
TopLevelDef::Variable { simple_name, .. } => simple_name.clone(),
};
println!("Variable name: {}", variable_name);
unifier.unify(*dummy_ty, ty_from_ty_annotation).map_err(|e| { unifier.unify(*dummy_ty, ty_from_ty_annotation).map_err(|e| {
HashSet::from([e.at(Some(loc.unwrap())).to_display(unifier).to_string()]) HashSet::from([e.at(Some(loc.unwrap())).to_display(unifier).to_string()])
})?; })?;