1
0
forked from M-Labs/nac3

Add string registration in NAC

This commit is contained in:
ram 2025-01-10 06:22:53 +00:00
parent 37886fcfe3
commit 3d087160ca
2 changed files with 85 additions and 51 deletions

View File

@ -378,6 +378,18 @@ impl Nac3 {
py: Python, py: Python,
link_fn: &dyn Fn(&Module) -> PyResult<T>, link_fn: &dyn Fn(&Module) -> PyResult<T>,
) -> PyResult<T> { ) -> PyResult<T> {
// Pre-register string arguments in string store
Python::with_gil(|py| {
let mut string_store = self.string_store.write();
for arg in &args {
if let Ok(s) = arg.extract::<String>() {
if !string_store.contains_key(&s) {
string_store.insert(s.clone(), i32::try_from(string_store.len()).unwrap());
}
}
}
});
let size_t = self.isa.get_size_type(); let size_t = self.isa.get_size_type();
let (mut composer, mut builtins_def, mut builtins_ty) = TopLevelComposer::new( let (mut composer, mut builtins_def, mut builtins_ty) = TopLevelComposer::new(
self.builtins.clone(), self.builtins.clone(),
@ -993,55 +1005,64 @@ impl Nac3 {
Isa::CortexA9 | Isa::Host => &timeline::EXTERN_TIME_FNS, Isa::CortexA9 | Isa::Host => &timeline::EXTERN_TIME_FNS,
}; };
let (primitive, _) = TopLevelComposer::make_primitives(isa.get_size_type()); let (primitive, _) = TopLevelComposer::make_primitives(isa.get_size_type());
let builtins = vec![ let builtins = {
( let mut b = vec![
"now_mu".into(), (
FunSignature { args: vec![], ret: primitive.int64, vars: VarMap::new() }, "now_mu".into(),
Arc::new(GenCall::new(Box::new(move |ctx, _, _, _, _| { FunSignature { args: vec![], ret: primitive.int64, vars: VarMap::new() },
Ok(Some(time_fns.emit_now_mu(ctx))) Arc::new(GenCall::new(Box::new(move |ctx, _, _, _, _| {
}))), Ok(Some(time_fns.emit_now_mu(ctx)))
), }))),
( ),
"at_mu".into(), (
FunSignature { "at_mu".into(),
args: vec![FuncArg { FunSignature {
name: "t".into(), args: vec![FuncArg {
ty: primitive.int64, name: "t".into(),
default_value: None, ty: primitive.int64,
is_vararg: false, default_value: None,
}], is_vararg: false,
ret: primitive.none, }],
vars: VarMap::new(), ret: primitive.none,
}, vars: VarMap::new(),
Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| { },
let arg_ty = fun.0.args[0].ty; Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| {
let arg = let arg_ty = fun.0.args[0].ty;
args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap(); let arg =
time_fns.emit_at_mu(ctx, arg); args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap();
Ok(None) time_fns.emit_at_mu(ctx, arg);
}))), Ok(None)
), }))),
( ),
"delay_mu".into(), (
FunSignature { "delay_mu".into(),
args: vec![FuncArg { FunSignature {
name: "dt".into(), args: vec![FuncArg {
ty: primitive.int64, name: "dt".into(),
default_value: None, ty: primitive.int64,
is_vararg: false, default_value: None,
}], is_vararg: false,
ret: primitive.none, }],
vars: VarMap::new(), ret: primitive.none,
}, vars: VarMap::new(),
Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| { },
let arg_ty = fun.0.args[0].ty; Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| {
let arg = let arg_ty = fun.0.args[0].ty;
args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap(); let arg =
time_fns.emit_delay_mu(ctx, arg); args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap();
Ok(None) time_fns.emit_delay_mu(ctx, arg);
}))), Ok(None)
), }))),
]; ),
];
b.push((
"str".into(),
FunSignature { args: vec![], ret: primitive.str, vars: VarMap::new() },
Arc::new(GenCall::new(Box::new(|_, _, _, _, _| Ok(None)))),
));
b
};
let builtins_mod = PyModule::import(py, "builtins").unwrap(); let builtins_mod = PyModule::import(py, "builtins").unwrap();
let id_fn = builtins_mod.getattr("id").unwrap(); let id_fn = builtins_mod.getattr("id").unwrap();
@ -1086,6 +1107,7 @@ impl Nac3 {
fs::write(working_directory.path().join("kernel.ld"), include_bytes!("kernel.ld")).unwrap(); fs::write(working_directory.path().join("kernel.ld"), include_bytes!("kernel.ld")).unwrap();
let mut string_store: HashMap<String, i32> = HashMap::default(); let mut string_store: HashMap<String, i32> = HashMap::default();
string_store.insert(String::new(), 0);
// Keep this list of exceptions in sync with `EXCEPTION_ID_LOOKUP` in `artiq::firmware::ksupport::eh_artiq` // Keep this list of exceptions in sync with `EXCEPTION_ID_LOOKUP` in `artiq::firmware::ksupport::eh_artiq`
// The exceptions declared here must be defined in `artiq.coredevice.exceptions` // The exceptions declared here must be defined in `artiq.coredevice.exceptions`

View File

@ -679,6 +679,11 @@ impl InnerResolver {
return Ok(Ok(ty)); return Ok(Ok(ty));
} }
// Early check for string type
if let Ok(_s) = obj.extract::<String>() {
return Ok(Ok(primitives.str));
}
let (extracted_ty, inst_check) = match self.get_pyty_obj_type( let (extracted_ty, inst_check) = match self.get_pyty_obj_type(
py, py,
{ {
@ -686,6 +691,7 @@ impl InnerResolver {
self.primitive_ids.typevar, self.primitive_ids.typevar,
self.primitive_ids.generic_alias.0, self.primitive_ids.generic_alias.0,
self.primitive_ids.generic_alias.1, self.primitive_ids.generic_alias.1,
self.primitive_ids.string, // Add string type to the check
] ]
.contains(&self.helper.id_fn.call1(py, (ty.clone(),))?.extract::<u64>(py)?) .contains(&self.helper.id_fn.call1(py, (ty.clone(),))?.extract::<u64>(py)?)
{ {
@ -943,9 +949,16 @@ impl InnerResolver {
|_| Ok(Err(format!("{obj} is not in the range of float64"))), |_| Ok(Err(format!("{obj} is not in the range of float64"))),
|_| Ok(Ok(extracted_ty)), |_| Ok(Ok(extracted_ty)),
) )
} else if let Ok(s) = obj.extract::<String>() {
if unifier.unioned(extracted_ty, primitives.str) {
Ok(Ok(primitives.str))
} else {
Ok(Err(format!("expected str, got {s}")))
}
} else { } else {
Ok(Ok(extracted_ty)) Ok(Ok(extracted_ty))
} }
}
} }
} }
} }
@ -988,7 +1001,7 @@ impl InnerResolver {
} else if ty_id == self.primitive_ids.string || ty_id == self.primitive_ids.np_str_ { } else if ty_id == self.primitive_ids.string || ty_id == self.primitive_ids.np_str_ {
let val: String = obj.extract().unwrap(); let val: String = obj.extract().unwrap();
self.id_to_primitive.write().insert(id, PrimitiveValue::Str(val.clone())); self.id_to_primitive.write().insert(id, PrimitiveValue::Str(val.clone()));
Ok(Some(ctx.gen_string(generator, val).into())) return Ok(Some(ctx.gen_string(generator, val).into()));
} else if ty_id == self.primitive_ids.float || ty_id == self.primitive_ids.float64 { } else if ty_id == self.primitive_ids.float || ty_id == self.primitive_ids.float64 {
let val: f64 = obj.extract().unwrap(); let val: f64 = obj.extract().unwrap();
self.id_to_primitive.write().insert(id, PrimitiveValue::F64(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::F64(val));
@ -1480,7 +1493,6 @@ impl InnerResolver {
Err("only primitives values, option and tuple can be default parameter value".into()) Err("only primitives values, option and tuple can be default parameter value".into())
}) })
} }
}
impl SymbolResolver for Resolver { impl SymbolResolver for Resolver {
fn get_default_param_value(&self, expr: &ast::Expr) -> Option<SymbolValue> { fn get_default_param_value(&self, expr: &ast::Expr) -> Option<SymbolValue> {