I would like to implement a dialect where quantities (i.e., physical units) are encoded in the type system. For now, the dialect should encode simply unit kinds as part of a quantity type and provide ops to work with quantities.
Ideally, I’m imagining something like this:
%0 = qty.constant 12.0 : !qty.qty<f64, seconds>
taking inspiration from arith.constant, complex.constant and similar dialects.
But I haven’t really found the right way forward. What is the recommended approach for doing this? My current approach is the following:
def QuantityType : TypeDef<Qty_Dialect, "Quantity"> {
let mnemonic = "qty";
let summary = "a value with a physical unit";
let parameters = (ins
"Type":$elementType,
"UnitKind":$unit
);
let assemblyFormat = "`<` $elementType `,` $unit `>`";
}
def Qty_ConstantOp : QtyOp<"constant", [ConstantLike, Pure]> {
let summary = "quantity constant";
let arguments = (ins TypedAttrInterface:$value);
let results = (outs QuantityType:$result);
let assemblyFormat = "attr-dict $value `:` type($result)";
}
I imagined that this allows the syntax seen above, but I couldn’t get it to work. The syntax from above gives me floating point value not valid for specified type. I have also tried other approaches with custom attributes or trying to replace type($result) with type($input) -> type($result), all with similar errors.
What are best practices here? Is a custom assembly printer/parser needed? Does the type have to have some property to allow implicit conversion from f64?