forked from M-Labs/nac3
WIP: Partial implementation of dunder support
This commit is contained in:
parent
9e12ce442f
commit
c4373281c7
@ -10,10 +10,10 @@ class NameManglingTest:
|
||||
|
||||
def __init__(self):
|
||||
self.core = Core()
|
||||
self.__var1 = 42
|
||||
self.__var2__ = 10
|
||||
self.__ = 99
|
||||
|
||||
self.__var1 = 100
|
||||
self.__var2__ = 200
|
||||
self.__ = 300
|
||||
|
||||
@rpc
|
||||
def get_var1(self) -> int32:
|
||||
return self.__var1
|
||||
@ -28,10 +28,10 @@ class NameManglingTest:
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
assert self.get_var1() == 42
|
||||
assert self.get_var2() == 10
|
||||
assert self.get_var3() == 99
|
||||
|
||||
assert self.get_var1() == 100
|
||||
assert self.get_var2() == 200
|
||||
assert self.get_var3() == 300
|
||||
#assert self._NameManglingTest__var1 == 100
|
||||
|
||||
if __name__ == "__main__":
|
||||
NameManglingTest().run()
|
||||
NameManglingTest().run()
|
@ -630,15 +630,28 @@ impl Nac3 {
|
||||
|
||||
{
|
||||
let defs = top_level.definitions.read();
|
||||
for def in defs.iter() {
|
||||
println!("{:?}", def.read());
|
||||
}
|
||||
for (class_data, id, is_async) in &rpc_ids {
|
||||
let mut def = defs[id.0].write();
|
||||
match &mut *def {
|
||||
TopLevelDef::Function { codegen_callback, .. } => {
|
||||
*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();
|
||||
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 {
|
||||
println!("Method: {}", name);
|
||||
if name != method_name {
|
||||
continue;
|
||||
}
|
||||
|
@ -187,7 +187,8 @@ impl StaticValue for PythonValue {
|
||||
name: StrRef,
|
||||
ctx: &mut CodeGenContext<'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();
|
||||
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 mut mutable = true;
|
||||
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() {
|
||||
println!("Debug: Accessing TopLevelDef::Class with 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 {
|
||||
mutable = *is_mutable;
|
||||
println!("Debug: Match found for field `{}`. Mutable: {}", field_name.to_string(), is_mutable);
|
||||
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> {
|
||||
|
||||
println!(
|
||||
"Debug: Resolving field `{}` in get_class_name",
|
||||
field_id.to_string()
|
||||
);
|
||||
let field_to_val = self.field_to_val.read();
|
||||
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 {
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})?;
|
||||
|
||||
println!("Debug: Found class id: `{}` for field `{}`", class_id, field_id.to_string());
|
||||
let id_to_def = self.id_to_def.read();
|
||||
let def_id = id_to_def.get(&StrRef::from(class_id.to_string()))?;
|
||||
|
||||
@ -1540,15 +1583,21 @@ impl SymbolResolver for Resolver {
|
||||
) -> Option<ValueEnum<'ctx>> {
|
||||
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;
|
||||
|
||||
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 mangled_id: StrRef = format!("_{}{}", stripped_class_name, id).into();
|
||||
(mangled_id, true)
|
||||
} else {
|
||||
println!("Debug: Could not resolve class name for `{}`", id.to_string());
|
||||
(id, false)
|
||||
}
|
||||
} else {
|
||||
println!("Debug: Identifier `{}` is not a dunder variable", id.to_string());
|
||||
(id, false)
|
||||
};
|
||||
let sym_value = {
|
||||
@ -1586,11 +1635,20 @@ impl SymbolResolver for Resolver {
|
||||
}
|
||||
|
||||
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();
|
||||
id_to_def.get(&id).copied().ok_or_else(String::new)
|
||||
}
|
||||
.or_else(|_| {
|
||||
println!("Debug: Falling back to name_to_pyid for `{}`", id.to_string());
|
||||
let py_id = self
|
||||
.0
|
||||
.name_to_pyid
|
||||
@ -1601,6 +1659,13 @@ impl SymbolResolver for Resolver {
|
||||
"`{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);
|
||||
Ok(result)
|
||||
})
|
||||
|
@ -447,6 +447,10 @@ impl TopLevelComposer {
|
||||
}
|
||||
|
||||
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((
|
||||
RwLock::new(Self::make_top_level_variable_def(
|
||||
global_var_name,
|
||||
@ -1179,7 +1183,7 @@ impl TopLevelComposer {
|
||||
if let ExprKind::Name { id: attr, .. } = &target.node {
|
||||
if defined_fields.insert(attr.to_string()) {
|
||||
let dummy_field_type = unifier.get_dummy_var().ty;
|
||||
|
||||
let mutable = false;
|
||||
let annotation = match value {
|
||||
None => {
|
||||
// handle Kernel[T], KernelInvariant[T]
|
||||
@ -1243,6 +1247,10 @@ impl TopLevelComposer {
|
||||
annotation
|
||||
}
|
||||
};
|
||||
println!(
|
||||
"Class field registered: name=`{}`, type=`{:?}`, mutable=`{}`",
|
||||
attr, annotation, mutable
|
||||
);
|
||||
let parsed_annotation = parse_ast_to_type_annotation_kinds(
|
||||
class_resolver,
|
||||
temp_def_list,
|
||||
@ -1975,6 +1983,13 @@ impl TopLevelComposer {
|
||||
&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| {
|
||||
HashSet::from([e.at(Some(loc.unwrap())).to_display(unifier).to_string()])
|
||||
})?;
|
||||
|
Loading…
Reference in New Issue
Block a user