From 95d0c3c93c8064e8b7d3b74ec4a7680fada63b23 Mon Sep 17 00:00:00 2001 From: David Mak Date: Mon, 11 Dec 2023 12:11:41 +0800 Subject: [PATCH 1/4] artiq: Rename const_generic_dummy to const_generic_marker --- nac3artiq/src/lib.rs | 4 ++-- nac3artiq/src/symbol_resolver.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 59b3a91..61c3eca 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -75,7 +75,7 @@ pub struct PrimitivePythonId { list: u64, tuple: u64, typevar: u64, - const_generic_dummy: u64, + const_generic_marker: u64, none: u64, exception: u64, generic_alias: (u64, u64), @@ -871,7 +871,7 @@ impl Nac3 { .extract() .unwrap(), typevar: get_attr_id(typing_mod, "TypeVar"), - const_generic_dummy: id_fn + const_generic_marker: id_fn .call1(( builtins_mod.getattr("globals") .and_then(|v| v.call0()) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index bb5f6b0..3c50d4b 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -353,7 +353,7 @@ impl InnerResolver { for i in 0usize.. { if let Ok(constr) = constraints.get_item(i) { let constr_id: u64 = self.helper.id_fn.call1(py, (constr,))?.extract(py)?; - if constr_id == self.primitive_ids.const_generic_dummy { + if constr_id == self.primitive_ids.const_generic_marker { is_const_generic = true; continue } -- 2.44.1 From 5ffd06dd6129110065149ab7c4592bd79acd5f5b Mon Sep 17 00:00:00 2001 From: David Mak Date: Mon, 11 Dec 2023 12:18:53 +0800 Subject: [PATCH 2/4] core: Remove debugging statement --- nac3core/src/typecheck/typedef/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/nac3core/src/typecheck/typedef/mod.rs b/nac3core/src/typecheck/typedef/mod.rs index 1be280a..21d4fd2 100644 --- a/nac3core/src/typecheck/typedef/mod.rs +++ b/nac3core/src/typecheck/typedef/mod.rs @@ -746,7 +746,6 @@ impl Unifier { (TConstant { value: val1, ty: ty1, .. }, TConstant { value: val2, ty: ty2, .. }) => { if val1 != val2 { - eprintln!("VALUE MISMATCH: lhs={val1:?} rhs={val2:?} eq={}", val1 == val2); return self.incompatible_types(a, b) } self.unify_impl(*ty1, *ty2, false)?; -- 2.44.1 From d4c109b6ef5999b25dcd3f795df79c37fde9fff7 Mon Sep 17 00:00:00 2001 From: David Mak Date: Mon, 11 Dec 2023 12:33:43 +0800 Subject: [PATCH 3/4] core: Add missing generic constant concrete type --- nac3core/src/codegen/concrete_type.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/nac3core/src/codegen/concrete_type.rs b/nac3core/src/codegen/concrete_type.rs index 9181a1c..472f78e 100644 --- a/nac3core/src/codegen/concrete_type.rs +++ b/nac3core/src/codegen/concrete_type.rs @@ -60,6 +60,10 @@ pub enum ConcreteTypeEnum { ret: ConcreteType, vars: HashMap, }, + TConstant { + value: SymbolValue, + ty: ConcreteType, + }, } impl ConcreteTypeStore { @@ -198,7 +202,11 @@ impl ConcreteTypeStore { TypeEnum::TFunc(signature) => { self.from_signature(unifier, primitives, signature, cache) } - _ => unreachable!(), + TypeEnum::TConstant { value, ty, .. } => ConcreteTypeEnum::TConstant { + value: value.clone(), + ty: self.from_unifier_type(unifier, primitives, *ty, cache), + }, + _ => unreachable!("{:?}", ty_enum.get_type_name()), }; let index = if let Some(ConcreteType(index)) = cache.get(&ty).unwrap() { self.store[*index] = result; @@ -285,6 +293,11 @@ impl ConcreteTypeStore { .map(|(id, cty)| (*id, self.to_unifier_type(unifier, primitives, *cty, cache))) .collect::>(), }), + ConcreteTypeEnum::TConstant { value, ty } => TypeEnum::TConstant { + value: value.clone(), + ty: self.to_unifier_type(unifier, primitives, *ty, cache), + loc: None, + } }; let result = unifier.add_ty(result); if let Some(ty) = cache.get(&cty).unwrap() { -- 2.44.1 From beee3e1f7e68645e9b2dc6036577ab85b96e2cd1 Mon Sep 17 00:00:00 2001 From: David Mak Date: Mon, 11 Dec 2023 12:48:49 +0800 Subject: [PATCH 4/4] artiq: Pass artiq builtins to NAC3 constructor --- nac3artiq/demo/min_artiq.py | 8 ++++++- nac3artiq/src/lib.rs | 48 +++++-------------------------------- 2 files changed, 13 insertions(+), 43 deletions(-) diff --git a/nac3artiq/demo/min_artiq.py b/nac3artiq/demo/min_artiq.py index bd5a8ea..d471032 100644 --- a/nac3artiq/demo/min_artiq.py +++ b/nac3artiq/demo/min_artiq.py @@ -86,7 +86,13 @@ def ceil64(x): import device_db core_arguments = device_db.device_db["core"]["arguments"] -compiler = nac3artiq.NAC3(core_arguments["target"]) +artiq_builtins = { + "none": none, + "virtual": virtual, + "_ConstGenericMarker": _ConstGenericMarker, + "Option": Option, +} +compiler = nac3artiq.NAC3(core_arguments["target"], artiq_builtins) allow_registration = True # Delay NAC3 analysis until all referenced variables are supposed to exist on the CPython side. registered_functions = set() diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 61c3eca..ac6187e 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -776,7 +776,7 @@ fn add_exceptions( #[pymethods] impl Nac3 { #[new] - fn new(isa: &str, py: Python) -> PyResult { + fn new(isa: &str, artiq_builtins: &PyDict, py: Python) -> PyResult { let isa = match isa { "host" => Isa::Host, "rv32g" => Isa::RiscV32G, @@ -842,44 +842,18 @@ impl Nac3 { let typing_mod = PyModule::import(py, "typing").unwrap(); let types_mod = PyModule::import(py, "types").unwrap(); - let get_id = |x| id_fn.call1((x,)).unwrap().extract().unwrap(); + let get_id = |x: &PyAny| id_fn.call1((x,)).and_then(PyAny::extract).unwrap(); let get_attr_id = |obj: &PyModule, attr| id_fn.call1((obj.getattr(attr).unwrap(),)) .unwrap().extract().unwrap(); let primitive_ids = PrimitivePythonId { - virtual_id: get_id( - builtins_mod - .getattr("globals") - .unwrap() - .call0() - .unwrap() - .get_item("virtual") - .unwrap( - )), + virtual_id: get_id(artiq_builtins.get_item("virtual").ok().flatten().unwrap()), generic_alias: ( get_attr_id(typing_mod, "_GenericAlias"), get_attr_id(types_mod, "GenericAlias"), ), - none: id_fn - .call1((builtins_mod - .getattr("globals") - .unwrap() - .call0() - .unwrap() - .get_item("none") - .unwrap(),)) - .unwrap() - .extract() - .unwrap(), + none: get_id(artiq_builtins.get_item("none").ok().flatten().unwrap()), typevar: get_attr_id(typing_mod, "TypeVar"), - const_generic_marker: id_fn - .call1(( - builtins_mod.getattr("globals") - .and_then(|v| v.call0()) - .and_then(|v| v.get_item("_ConstGenericMarker")) - .unwrap(), - )) - .and_then(PyAny::extract) - .unwrap(), + const_generic_marker: get_id(artiq_builtins.get_item("_ConstGenericMarker").ok().flatten().unwrap()), int: get_attr_id(builtins_mod, "int"), int32: get_attr_id(numpy_mod, "int32"), int64: get_attr_id(numpy_mod, "int64"), @@ -891,17 +865,7 @@ impl Nac3 { list: get_attr_id(builtins_mod, "list"), tuple: get_attr_id(builtins_mod, "tuple"), exception: get_attr_id(builtins_mod, "Exception"), - option: id_fn - .call1((builtins_mod - .getattr("globals") - .unwrap() - .call0() - .unwrap() - .get_item("Option") - .unwrap(),)) - .unwrap() - .extract() - .unwrap(), + option: get_id(artiq_builtins.get_item("Option").ok().flatten().unwrap()), }; let working_directory = tempfile::Builder::new().prefix("nac3-").tempdir().unwrap(); -- 2.44.1