Skip to content

Commit fa1e311

Browse files
ss2165cqc-alec
andauthored
feat: Change TypeParam::USize to TypeParam::BoundedNat and use in int extensions (#445)
Closes #437 BREAKING CHANGE: `USize` type param and type arg changed to `BoundedNat` with optional maximum. For previous behaviour use `TypeParam::max_nat()` --------- Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com>
1 parent a43d046 commit fa1e311

File tree

10 files changed

+214
-175
lines changed

10 files changed

+214
-175
lines changed

specification/hugr.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -907,17 +907,17 @@ The declaration of the `params` uses a language that is a distinct, simplified
907907
form of the [Type System](#type-system) - writing terminals that appear in the YAML in quotes,
908908
the value of each member of `params` is given by the following production:
909909
```
910-
TypeParam ::= "Type"("Any"|"Copy"|"Eq") | "USize" | "Extensions" | "List"(TypeParam) | "Tuple"([TypeParam]) | Opaque
910+
TypeParam ::= "Type"("Any"|"Copy"|"Eq") | "BoundedUSize(u64)" | "Extensions" | "List"(TypeParam) | "Tuple"([TypeParam]) | Opaque
911911
912912
Opaque ::= string<[TypeArgs]>
913913
914-
TypeArgs ::= Type(Type) | USize(u64) | Extensions | List([TypeArg]) | Tuple([TypeArg])
914+
TypeArgs ::= Type(Type) | BoundedUSize(u64) | Extensions | List([TypeArg]) | Tuple([TypeArg])
915915
916916
Type ::= Name<[TypeArg]>
917917
```
918918
(We write `[Foo]` to indicate a list of Foo's; and omit `<>` where the contents is the empty list).
919919

920-
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.
920+
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.
921921

922922
**Implementation note** Reading this format into Rust is made easy by `serde` and
923923
[serde\_yaml](https://github.com/dtolnay/serde-yaml) (see the

src/extension/prelude.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ lazy_static! {
3030
prelude
3131
.add_type(
3232
SmolStr::new_inline("array"),
33-
vec![TypeParam::Type(TypeBound::Any), TypeParam::USize],
33+
vec![TypeParam::Type(TypeBound::Any), TypeParam::max_nat()],
3434
"array".into(),
3535
TypeDefBound::FromParams(vec![0]),
3636
)
@@ -68,7 +68,7 @@ pub(crate) const BOOL_T: Type = Type::new_simple_predicate(2);
6868
pub fn new_array(typ: Type, size: u64) -> Type {
6969
let array_def = PRELUDE.get_type("array").unwrap();
7070
let custom_t = array_def
71-
.instantiate_concrete(vec![TypeArg::Type(typ), TypeArg::USize(size)])
71+
.instantiate_concrete(vec![TypeArg::Type(typ), TypeArg::BoundedNat(size)])
7272
.unwrap();
7373
Type::new_extension(custom_t)
7474
}

src/ops/constant.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,12 @@ mod test {
199199

200200
#[test]
201201
fn test_yaml_const() {
202-
let typ_int = CustomType::new("mytype", vec![TypeArg::USize(8)], "myrsrc", TypeBound::Eq);
202+
let typ_int = CustomType::new(
203+
"mytype",
204+
vec![TypeArg::BoundedNat(8)],
205+
"myrsrc",
206+
TypeBound::Eq,
207+
);
203208
let val: Value = CustomSerialized::new(typ_int.clone(), YamlValue::Number(6.into())).into();
204209
let classic_t = Type::new_extension(typ_int.clone());
205210
assert_matches!(classic_t.least_upper_bound(), TypeBound::Eq);

src/std_extensions/arithmetic/conversions.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,23 @@ use smol_str::SmolStr;
77
use crate::{
88
extension::{ExtensionSet, SignatureError},
99
type_row,
10-
types::{
11-
type_param::{TypeArg, TypeParam},
12-
Type, TypeRow,
13-
},
10+
types::{type_param::TypeArg, Type, TypeRow},
1411
utils::collect_array,
1512
Extension,
1613
};
1714

18-
use super::float_types::FLOAT64_TYPE;
19-
use super::int_types::{get_width, int_type};
15+
use super::int_types::int_type;
16+
use super::{float_types::FLOAT64_TYPE, int_types::LOG_WIDTH_TYPE_PARAM};
2017

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

2421
fn ftoi_sig(arg_values: &[TypeArg]) -> Result<(TypeRow, TypeRow, ExtensionSet), SignatureError> {
2522
let [arg] = collect_array(arg_values);
26-
let n: u8 = get_width(arg)?;
2723
Ok((
2824
type_row![FLOAT64_TYPE],
2925
vec![Type::new_sum(vec![
30-
int_type(n),
26+
int_type(arg.clone()),
3127
crate::extension::prelude::ERROR_TYPE,
3228
])]
3329
.into(),
@@ -37,9 +33,8 @@ fn ftoi_sig(arg_values: &[TypeArg]) -> Result<(TypeRow, TypeRow, ExtensionSet),
3733

3834
fn itof_sig(arg_values: &[TypeArg]) -> Result<(TypeRow, TypeRow, ExtensionSet), SignatureError> {
3935
let [arg] = collect_array(arg_values);
40-
let n: u8 = get_width(arg)?;
4136
Ok((
42-
vec![int_type(n)].into(),
37+
vec![int_type(arg.clone())].into(),
4338
type_row![FLOAT64_TYPE],
4439
ExtensionSet::default(),
4540
))
@@ -59,31 +54,31 @@ pub fn extension() -> Extension {
5954
.add_op_custom_sig_simple(
6055
"trunc_u".into(),
6156
"float to unsigned int".to_owned(),
62-
vec![TypeParam::USize],
57+
vec![LOG_WIDTH_TYPE_PARAM],
6358
ftoi_sig,
6459
)
6560
.unwrap();
6661
extension
6762
.add_op_custom_sig_simple(
6863
"trunc_s".into(),
6964
"float to signed int".to_owned(),
70-
vec![TypeParam::USize],
65+
vec![LOG_WIDTH_TYPE_PARAM],
7166
ftoi_sig,
7267
)
7368
.unwrap();
7469
extension
7570
.add_op_custom_sig_simple(
7671
"convert_u".into(),
7772
"unsigned int to float".to_owned(),
78-
vec![TypeParam::USize],
73+
vec![LOG_WIDTH_TYPE_PARAM],
7974
itof_sig,
8075
)
8176
.unwrap();
8277
extension
8378
.add_op_custom_sig_simple(
8479
"convert_s".into(),
8580
"signed int to float".to_owned(),
86-
vec![TypeParam::USize],
81+
vec![LOG_WIDTH_TYPE_PARAM],
8782
itof_sig,
8883
)
8984
.unwrap();

0 commit comments

Comments
 (0)