Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Change TypeParam::USize to TypeParam::BoundedNat and use in int extensions #445

Merged
merged 14 commits into from
Aug 24, 2023
6 changes: 3 additions & 3 deletions specification/hugr.md
Original file line number Diff line number Diff line change
Expand Up @@ -907,17 +907,17 @@ The declaration of the `params` uses a language that is a distinct, simplified
form of the [Type System](#type-system) - writing terminals that appear in the YAML in quotes,
the value of each member of `params` is given by the following production:
```
TypeParam ::= "Type"("Any"|"Copy"|"Eq") | "USize" | "Extensions" | "List"(TypeParam) | "Tuple"([TypeParam]) | Opaque
TypeParam ::= "Type"("Any"|"Copy"|"Eq") | "BoundedUSize(u64)" | "Extensions" | "List"(TypeParam) | "Tuple"([TypeParam]) | Opaque

Opaque ::= string<[TypeArgs]>

TypeArgs ::= Type(Type) | USize(u64) | Extensions | List([TypeArg]) | Tuple([TypeArg])
TypeArgs ::= Type(Type) | BoundedUSize(u64) | Extensions | List([TypeArg]) | Tuple([TypeArg])

Type ::= Name<[TypeArg]>
```
(We write `[Foo]` to indicate a list of Foo's; and omit `<>` where the contents is the empty list).

To use an OpDef as an Op, or a TypeDef as a type, the user must provide a type argument for each type param in the def: a type in the appropriate class, a constant usize, a set of extensions, a list or tuple of arguments.
To use an OpDef as an Op, or a TypeDef as a type, the user must provide a type argument for each type param in the def: a type in the appropriate class, a bounded usize, a set of extensions, a list or tuple of arguments.

**Implementation note** Reading this format into Rust is made easy by `serde` and
[serde\_yaml](https://github.com/dtolnay/serde-yaml) (see the
Expand Down
4 changes: 2 additions & 2 deletions src/extension/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ lazy_static! {
prelude
.add_type(
SmolStr::new_inline("array"),
vec![TypeParam::Type(TypeBound::Any), TypeParam::USize],
vec![TypeParam::Type(TypeBound::Any), TypeParam::max_nat()],
"array".into(),
TypeDefBound::FromParams(vec![0]),
)
Expand Down Expand Up @@ -68,7 +68,7 @@ pub(crate) const BOOL_T: Type = Type::new_simple_predicate(2);
pub fn new_array(typ: Type, size: u64) -> Type {
let array_def = PRELUDE.get_type("array").unwrap();
let custom_t = array_def
.instantiate_concrete(vec![TypeArg::Type(typ), TypeArg::USize(size)])
.instantiate_concrete(vec![TypeArg::Type(typ), TypeArg::BoundedNat(size)])
.unwrap();
Type::new_extension(custom_t)
}
Expand Down
7 changes: 6 additions & 1 deletion src/ops/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,12 @@ mod test {

#[test]
fn test_yaml_const() {
let typ_int = CustomType::new("mytype", vec![TypeArg::USize(8)], "myrsrc", TypeBound::Eq);
let typ_int = CustomType::new(
"mytype",
vec![TypeArg::BoundedNat(8)],
"myrsrc",
TypeBound::Eq,
);
let val: Value = CustomSerialized::new(typ_int.clone(), YamlValue::Number(6.into())).into();
let classic_t = Type::new_extension(typ_int.clone());
assert_matches!(classic_t.least_upper_bound(), TypeBound::Eq);
Expand Down
23 changes: 9 additions & 14 deletions src/std_extensions/arithmetic/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,23 @@ use smol_str::SmolStr;
use crate::{
extension::{ExtensionSet, SignatureError},
type_row,
types::{
type_param::{TypeArg, TypeParam},
Type, TypeRow,
},
types::{type_param::TypeArg, Type, TypeRow},
utils::collect_array,
Extension,
};

use super::float_types::FLOAT64_TYPE;
use super::int_types::{get_width, int_type};
use super::int_types::int_type;
use super::{float_types::FLOAT64_TYPE, int_types::LOG_WIDTH_TYPE_PARAM};

/// The extension identifier.
pub const EXTENSION_ID: SmolStr = SmolStr::new_inline("arithmetic.conversions");

fn ftoi_sig(arg_values: &[TypeArg]) -> Result<(TypeRow, TypeRow, ExtensionSet), SignatureError> {
let [arg] = collect_array(arg_values);
let n: u8 = get_width(arg)?;
Ok((
type_row![FLOAT64_TYPE],
vec![Type::new_sum(vec![
int_type(n),
int_type(arg.clone()),
crate::extension::prelude::ERROR_TYPE,
])]
.into(),
Expand All @@ -37,9 +33,8 @@ fn ftoi_sig(arg_values: &[TypeArg]) -> Result<(TypeRow, TypeRow, ExtensionSet),

fn itof_sig(arg_values: &[TypeArg]) -> Result<(TypeRow, TypeRow, ExtensionSet), SignatureError> {
let [arg] = collect_array(arg_values);
let n: u8 = get_width(arg)?;
Ok((
vec![int_type(n)].into(),
vec![int_type(arg.clone())].into(),
type_row![FLOAT64_TYPE],
ExtensionSet::default(),
))
Expand All @@ -59,31 +54,31 @@ pub fn extension() -> Extension {
.add_op_custom_sig_simple(
"trunc_u".into(),
"float to unsigned int".to_owned(),
vec![TypeParam::USize],
vec![LOG_WIDTH_TYPE_PARAM],
ftoi_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"trunc_s".into(),
"float to signed int".to_owned(),
vec![TypeParam::USize],
vec![LOG_WIDTH_TYPE_PARAM],
ftoi_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"convert_u".into(),
"unsigned int to float".to_owned(),
vec![TypeParam::USize],
vec![LOG_WIDTH_TYPE_PARAM],
itof_sig,
)
.unwrap();
extension
.add_op_custom_sig_simple(
"convert_s".into(),
"signed int to float".to_owned(),
vec![TypeParam::USize],
vec![LOG_WIDTH_TYPE_PARAM],
itof_sig,
)
.unwrap();
Expand Down
Loading