From 0cbea962b22accd58e46bf9a8118036556a6c27b Mon Sep 17 00:00:00 2001 From: mwojcik Date: Fri, 25 Oct 2024 17:46:57 +0800 Subject: [PATCH] subkernels: get destination from decorator --- nac3artiq/src/lib.rs | 57 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index ea624c20..86b24a96 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -501,9 +501,22 @@ impl Nac3 { .iter() .any(|decorator| decorator_id_string(decorator) == Some("subkernel".to_string())) { - store_fun.call1(py, (def_id.0.into_py(py), module.getattr(py, name.to_string().as_str()).unwrap())).unwrap(); - let dest = decorator_list.SOMETHING; - subkernel_rpc_ids.push((None, def_id, dest)); + if let Constant::Int(destination) = decorator_get_destination(decorator) { + if destination < 0 || destination > 255 { + return Err(CompileError::new_err(format!( + "compilation failed\n----------\nSubkernel destination must be between 0 and 255 (at {})", + stmt.location + ))); + } + subkernel_ids.push((None, def_id, destination)); + } else { + return Err(CompileError::new_err(format!( + "compilation failed\n----------\nDestination must be provided for subkernels (at {})", + stmt.location + ))); + } + // store_fun.call1(py, (def_id.0.into_py(py), module.getattr(py, name.to_string().as_str()).unwrap())).unwrap(); + } } StmtKind::ClassDef { name, body, .. } => { @@ -527,14 +540,28 @@ impl Nac3 { } rpc_ids.push((Some((class_obj.clone(), *name)), def_id, is_async)); } else if decorator_list.iter().any(|decorator| matches!(decorator.node, ExprKind::Name { id, .. } if id == "subkernel".into())) { - if name == &"__init__".into() { + if let Constant::Int(destination) = decorator_get_destination(decorator) { + if name == &"__init__".into() { + return Err(CompileError::new_err(format!( + "compilation failed\n----------\nThe constructor of class {} should not be decorated with subkernel decorator (at {})", + class_name, stmt.location + ))); + } + if destination < 0 || destination > 255 { + return Err(CompileError::new_err(format!( + "compilation failed\n----------\nSubkernel destination must be between 0 and 255 (at {})", + stmt.location + ))); + } + subkernel_ids.push((Some((class_obj.clone(), *name)), def_id, destination)); + } else { return Err(CompileError::new_err(format!( - "compilation failed\n----------\nThe constructor of class {} should not be decorated with subkernel decorator (at {})", - class_name, stmt.location + "compilation failed\n----------\nDestination must be provided for subkernels (at {})", + stmt.location ))); } - let dest = decorator_list.iter(). // figure out what's in the decorator list - subkernel_ids.push((Some((class_obj.clone(), *name)), def_id, dest)); + + } } } @@ -922,6 +949,20 @@ fn decorator_get_flags(decorator: &Located) -> Vec { flags } +fn decorator_get_destination(decorator: &Located) -> Option { + if let ExprKind::Call { keywords, .. } = &decorator.node { + for keyword in keywords { + if keyword.node.arg != Some("destination".into()) { + continue; + } + if let ExprKind::Constant { value, .. } = &keyword.node.value.node { + return Some(value.clone()); + } + } + } + None +} + fn link_with_lld(elf_filename: String, obj_filename: String) -> PyResult<()> { let linker_args = vec![ "-shared".to_string(),