Skip to main content

pliron_derive/
lib.rs

1mod derive_attr;
2mod derive_format;
3mod derive_op;
4mod derive_type;
5mod interfaces;
6mod irfmt;
7
8use proc_macro::TokenStream;
9use quote::format_ident;
10use syn::parse_quote;
11
12use derive_format::DeriveIRObject;
13
14/// `#[def_attribute(...)]`: Annotate a Rust struct as a new IR attribute.
15///
16/// The argument to the macro is the fully qualified name of the attribute in the form of
17/// `"dialect.attribute_name"`.
18///
19/// The macro will leave the struct definition unchanged, but it will generate an implementation of
20/// the pliron::Attribute trait and implements other internal traits and types resources required
21/// to use the IR attribute.
22///
23/// **Note**: pre-requisite traits for `Attribute` must already be implemented.
24///         Additionaly, [Eq] and [Hash](core::hash::Hash) must be implemented by the type.
25///
26/// Usage:
27///
28/// ```
29/// use pliron::derive::{def_attribute, format_attribute};
30///
31/// #[def_attribute("my_dialect.attribute")]
32/// #[format_attribute]
33/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
34/// pub struct StringAttr(String);
35/// # use pliron::{impl_verify_succ, printable::{State, Printable}, context::Context};
36/// # impl_verify_succ!(StringAttr);
37/// ```
38#[proc_macro_attribute]
39pub fn def_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
40    to_token_stream(derive_attr::def_attribute(args, input))
41}
42
43/// `#[def_type(...)]`: Annotate a Rust struct as a new IR type.
44///
45/// The argument to the macro is the fully qualified name of the type in the form of
46/// `"dialect.type_name"`.
47///
48/// The macro will leave the struct definition unchanged, but it will generate an implementation of
49/// the pliron::Type trait and implements other internal traits and types resources required
50/// to use the IR type.
51///
52/// **Note**: pre-requisite traits for `Type` must already be implemented.
53///         Additionaly, [Hash](core::hash::Hash) and [Eq] must be implemented by the rust type.
54///
55/// Usage:
56///
57/// ```
58/// use pliron::derive::{def_type, format_type};
59/// #[def_type("my_dialect.unit")]
60/// #[format_type]
61/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
62/// pub struct UnitType;
63/// # use pliron::impl_verify_succ;
64/// # impl_verify_succ!(UnitType);
65/// ```
66#[proc_macro_attribute]
67pub fn def_type(args: TokenStream, input: TokenStream) -> TokenStream {
68    to_token_stream(derive_type::def_type(args, input))
69}
70
71/// Derive get methods for types that retrieve interned types.
72///
73/// This macro generates appropriate get methods based on the struct's fields:
74/// - For unit structs: generates a singleton `get(ctx: &Context)` method
75/// - For structs with fields (named or tuple): generates a `get(ctx: &mut Context, ...)` method
76///
77/// ## Examples
78///
79/// ### Named fields struct:
80/// ```
81/// use pliron::derive::{def_type, derive_type_get, format_type};
82/// use pliron::context::Context;
83///
84/// #[def_type("my_dialect.vector_type")]
85/// #[format_type]
86/// #[derive_type_get]  // Auto-generates get method
87/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
88/// pub struct VectorType {
89///     elem_ty: u32,
90///     num_elems: u32,
91/// }
92/// # use pliron::impl_verify_succ;
93/// # impl_verify_succ!(VectorType);
94///
95/// // Usage of the auto-generated get method:
96/// # fn example(ctx: &mut Context) {
97/// let vector_type = VectorType::get(ctx, 42, 8); // get(ctx, elem_ty, num_elems)
98/// # }
99/// ```
100///
101/// ### Tuple struct:
102/// ```
103/// use pliron::derive::{def_type, derive_type_get, format_type};
104/// use pliron::context::Context;
105///
106/// #[def_type("my_dialect.tuple_type")]
107/// #[format_type]
108/// #[derive_type_get]  // Auto-generates get method
109/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
110/// pub struct TupleType(u32, String, bool);
111/// # use pliron::impl_verify_succ;
112/// # impl_verify_succ!(TupleType);
113///
114/// // Usage of the auto-generated get method:
115/// # fn example(ctx: &mut Context) {
116/// let tuple_type = TupleType::get(ctx, 42, "hello".to_string(), true); // get(ctx, field_0, field_1, field_2)
117/// # }
118/// ```
119///
120/// ### Unit struct:
121/// ```
122/// use pliron::derive::{def_type, derive_type_get, format_type};
123/// use pliron::context::Context;
124///
125/// #[def_type("my_dialect.unit_type")]
126/// #[format_type]
127/// #[derive_type_get]  // Auto-generates singleton get method
128/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
129/// pub struct UnitType;
130/// # use pliron::impl_verify_succ;
131/// # impl_verify_succ!(UnitType);
132///
133/// // Usage of the auto-generated singleton get method:
134/// # fn example(ctx: &Context) {
135/// let unit_type = UnitType::get(ctx); // get(ctx) - no additional parameters
136/// # }
137/// ```
138#[proc_macro_attribute]
139pub fn derive_type_get(args: TokenStream, input: TokenStream) -> TokenStream {
140    to_token_stream(derive_type::derive_type_get(args, input))
141}
142
143/// `#[def_op(...)]`: Create a new IR operation.
144///
145/// The argument to the macro is the fully qualified name of the operation in the form of
146/// `"dialect.op_name"`.
147///
148/// The macro assumes an empty struct and will add the `op: Ptr<Operation>` field used to access
149/// the underlying Operation in the context.
150///
151/// The macro will automatically derive the `Clone`, `Copy`, `Hash`, `PartialEq` and `Eq` traits
152/// for the new struct definition.
153///
154/// **Note**: pre-requisite traits for `Op` (Printable, Verify etc) must already be implemented
155///
156/// Usage:
157///
158/// ```
159/// use pliron::derive::{format_op, def_op};
160/// use pliron::impl_verify_succ;
161///
162/// #[def_op("my_dialect.op")]
163/// #[format_op]
164/// pub struct MyOp;
165/// impl_verify_succ!(MyOp);
166/// ```
167/// The example will create a struct definition equivalent to:
168///
169/// ```
170/// #[derive(Clone, Copy, PartialEq, Eq, Hash)]
171/// pub struct MyOp {
172///   op: Ptr<Operation>,
173/// }
174/// # use pliron::{context::Ptr, operation::Operation};
175/// ```
176#[proc_macro_attribute]
177pub fn def_op(args: TokenStream, input: TokenStream) -> TokenStream {
178    to_token_stream(derive_op::def_op(args, input))
179}
180
181/// Derive getter and setters for operation attributes listed as arguments.
182/// The arguments are a comma separated list of attribute names
183/// (which must be an [Identifier](../pliron/identifier/struct.Identifier.html)),
184/// each of which may have an optional concrete Rust type specified,
185/// denoting the [Attribute](../pliron/attribute/trait.Attribute.html)'s concrete type.
186///
187/// ```
188/// # use pliron::derive::{def_op, derive_attr_get_set, format_op};
189/// # use pliron::impl_verify_succ;
190/// // A test for the `derive_attr_get_set` macro.
191/// #[def_op("llvm.with_attrs")]
192/// #[format_op]
193/// #[derive_attr_get_set(name1_any_attr, name2_ty_attr : pliron::builtin::attributes::TypeAttr)]
194/// pub struct WithAttrsOp {}
195/// # impl_verify_succ!(WithAttrsOp);
196/// ```
197///
198/// This expands to add the following getter / setter items:
199/// ```
200/// # use pliron::derive::{def_op, format_op, derive_attr_get_set};
201/// # use std::cell::Ref;
202/// # use pliron::{dict_key, impl_verify_succ};
203/// # use pliron::{attribute::AttrObj, context::Context};
204/// # use pliron::{builtin::attributes::TypeAttr};
205/// #[format_op]
206/// #[def_op("llvm.with_attrs")]
207/// pub struct WithAttrsOp {}
208/// dict_key!(ATTR_KEY_NAME1_ANY_ATTR, "name1_any_attr");
209/// dict_key!(ATTR_KEY_NAME2_TY_ATTR, "name2_ty_attr");
210/// impl WithAttrsOp {
211///   pub fn get_attr_name1_any_attr<'a>
212///     (&self, ctx: &'a Context)-> Option<Ref<'a, AttrObj>> { todo!() }
213///   pub fn set_attr_name1_any_attr(&self, ctx: &Context, value: AttrObj) { todo!() }
214///   pub fn get_attr_name2_ty_attr<'a>
215///     (&self, ctx: &'a Context) -> Option<Ref<'a, TypeAttr>> { todo!() }
216///   pub fn set_attr_name2_ty_attr(&self, ctx: &Context, value: TypeAttr) { todo!() }
217/// }
218/// # impl_verify_succ!(WithAttrsOp);
219/// ```
220#[proc_macro_attribute]
221pub fn derive_attr_get_set(args: TokenStream, input: TokenStream) -> TokenStream {
222    to_token_stream(derive_op::derive_attr_get_set(args, input))
223}
224
225/// Derive [Printable](../pliron/printable/trait.Printable.html) and
226/// [Parsable](../pliron/parsable/trait.Parsable.html) for Rust types.
227/// Use this is for types other than `Op`, `Type` and `Attribute`s.
228///   1. A named variable `$name` specifies a named struct field.
229///   2. An unnamed variable `$i` specifies the i'th field of a tuple struct.
230///
231/// Struct (or tuple) fields that are either [Option] or [Vec] must to be specified
232/// using the `opt` and `vec` directives respectively. The `opt` directive takes one argument,
233/// a variable specifying the field name with type `Option`. The `vec` directive takes two
234/// arguments, the first is a variable specifying the field name with type `Vec` and the second
235/// is another directive to specify a [ListSeparator](../pliron/printable/enum.ListSeparator.html).
236/// The following directives are supported:
237///   1. `NewLine`: takes no argument, and specifies a newline to be used as list separator.
238///   2. ``CharNewline(`c`)``: takes a single character argument that will be followed by a newline.
239///   3. ``Char(`c`)``: takes a single character argument that will be used as separator.
240///   4. ``CharSpace(`c`)``: takes a single character argument that will be followed by a space.
241///
242/// Examples:
243/// 1. Derive for a struct, with no format string (default format):
244///    (Note that the field u64 has both `Printable` and `Parsable` implemented).
245/// ```
246/// use pliron::derive::format;
247/// #[format]
248/// struct IntWrapper {
249///    inner: u64,
250/// }
251/// ```
252/// 2. An example with a custom format string:
253/// ```
254/// use pliron::derive::format;
255/// #[format("`BubbleWrap` `[` $inner `]`")]
256/// struct IntWrapperCustom {
257///   inner: u64,
258/// }
259/// ```
260/// 3. An example for an enum (custom format strings are allowed for the variants only).
261/// ```
262/// use pliron::derive::format;
263/// use pliron::{builtin::types::IntegerType, r#type::TypePtr};
264/// #[format]
265/// enum Enum {
266///     A(TypePtr<IntegerType>),
267///     B {
268///         one: TypePtr<IntegerType>,
269///         two: u64,
270///     },
271///     C,
272///     #[format("`<` $upper `/` $lower `>`")]
273///     Op {
274///         upper: u64,
275///         lower: u64,
276///     },
277/// }
278/// ```
279/// 4. An example with `Option` and `Vec` fields
280/// ```
281/// use pliron::derive::format;
282/// #[format("`<` opt($a) `;` vec($b, Char(`,`)) `>`")]
283/// struct OptAndVec {
284///    a: Option<u64>,
285///    b: Vec<u64>,
286///}
287/// ```
288#[proc_macro_attribute]
289pub fn format(args: TokenStream, input: TokenStream) -> TokenStream {
290    to_token_stream(derive_format::derive(
291        args,
292        input,
293        DeriveIRObject::AnyOtherRustType,
294    ))
295}
296
297/// Derive [Printable](../pliron/printable/trait.Printable.html) and
298/// [Parsable](../pliron/parsable/trait.Parsable.html) for [Op](../pliron/op/trait.Op.html)s
299/// This derive only supports a syntax in which results appear before the opid:
300///   `res1, ... = opid ...`
301/// The format string specifies what comes after the opid.
302///   1. A named variable `$name` specifies a named attribute of the operation.
303///      This cannot be combined with the [attr_dict](#attr_dict) directive.
304///   2. An unnamed variable `$i` specifies `operands[i]`, except when inside some directives.
305///      This cannot be combined with the "operands" directive.
306///   3. The "type" directive specifies that a type must be parsed. It takes one argument,
307///      which is an unnamed variable `$i` with `i` specifying `result[i]`. This cannot be
308///      combined with the "types" directive.
309///   4. The "region" directive specifies that a region must be parsed. It takes one argument,
310///      which is an unnamed variable `$i` with `i` specifying `region[i]`. This cannot be
311///      combined with the "regions" directive.
312///   5. The <a name="attr"></a> "attr" directive can be used to specify attribute on an `Op` when
313///      the attribute's rust type is fixed at compile time. It takes two mandatory and two optional
314///      arguments.
315///
316///      1. The first operand is a named variable `$name` which is used as a key into the
317///         operation's attribute dictionary
318///      2. The second is the concrete rust type of the attribute. This second argument can be a
319///         named variable `$name` (with `name` being in scope) or a literal string denoting the path
320///         to a rust type (e.g. `` `::pliron::builtin::attributes::IntegerAttr` ``).
321///      3. Two additional optional arguments can be specified:
322///         * The "label" directive, with one argument, a named variable `$label`, which
323///           specifies the label to be used while printing / parsing the attribute.
324///         * The "delimiter" directive, which takes two literal arguments,
325///           specifying the opening and closing delimiters to be used while printing / parsing.
326///
327///      The advantage over specifying an attribute using the [attr](#attr) directive (as against
328///      just using a named variable) is that the attribute-id is not a part of the syntax
329///      here (because the type is statically known, allowing us to be able to parse it),
330///      thus allowing it to be more succinct. This cannot be combined with the [attr_dict](#attr_dict)
331///      directive.
332///   6. The "succ" directive specifies an operation's successor. It takes one argument,
333///      which is an unnamed variable `$i` with `i` specifying `successor[i]`.
334///   7. The "operands" directive specifies all the operands of an operation. It takes one argument
335///      which is a directive specifying the separator between operands.
336///      The following directives are supported:
337///        1. `NewLine`: takes no argument, and specifies a newline to be used as list separator.
338///        2. ``CharNewline(`c`)``: takes a single character argument that will be followed by a newline.
339///        3. ``Char(`c`)``: takes a single character argument that will be used as separator.
340///        4. ``CharSpace(`c`)``: takes a single character argument that will be followed by a space.
341///   8. The "successors" directive specifies all the successors of an operation. It takes one argument
342///      which is a directive specifying the separator between successors. The separator directive is
343///      same as that for "operands" above. This cannot be combined with the "succ" directive.
344///   9. The "regions" directive specifies all the regions of an operation. It takes one argument
345///      which is a directive specifying the separator between regions. The separator directive is same
346///      as that for "operands" above. This cannot be combined with the "region" directive.
347///  10. The <a name="attr_dict"></a> "attr_dict" directive specifies an
348///      [AttributeDict](../pliron/attribute/struct.AttributeDict.html).
349///      It cannot be combined with any of [attr](#attr), [opt_attr](#opt_attr) directives or
350///      a named variable (`$name`).
351///  11. The "types" directive specifies all the result types of an operation. It takes one argument
352///      which is a directive specifying the separator between result types. The separator directive is
353///      same as that for "operands" above. This cannot be combined with the "type" directive.
354///  12. The <a name="opt_attr"></a> "opt_attr" directive specifies an optional attribute on an `Op`.
355///      It takes two or more arguments, which are same as those of the [attr](#attr) directive.
356///      This cannot be combined with the [attr_dict](#attr_dict) directive.
357///
358/// Examples:
359/// 1. Derive for a struct, with no format string (default format):
360/// ```
361/// use pliron::derive::{def_op, format_op};
362/// use pliron::impl_verify_succ;
363/// #[format_op]
364/// #[def_op("test.myop")]
365/// struct MyOp;
366/// impl_verify_succ!(MyOp);
367/// ```
368/// 2. An example with a custom format string:
369/// ```
370/// use pliron::derive::{def_op, format_op, derive_op_interface_impl};
371/// use pliron::impl_verify_succ;
372/// use pliron::{op::Op, builtin::op_interfaces::
373///     {OneOpdInterface, OneResultInterface, NOpdsInterface, NResultsInterface}};
374/// #[format_op("$0 `<` $attr `>` `:` type($0)")]
375/// #[def_op("test.one_result_one_operand")]
376/// #[derive_op_interface_impl
377///     (OneOpdInterface, OneResultInterface, NOpdsInterface<1>, NResultsInterface<1>)]
378/// struct OneResultOneOperandOp;
379/// impl_verify_succ!(OneResultOneOperandOp);
380/// ```
381/// More examples can be seen in the tests for this macro in `pliron-derive/tests/format_op.rs`.
382#[proc_macro_attribute]
383pub fn format_op(args: TokenStream, input: TokenStream) -> TokenStream {
384    to_token_stream(derive_format::derive(args, input, DeriveIRObject::Op))
385}
386
387/// Derive [Printable](../pliron/printable/trait.Printable.html) and
388/// [Parsable](../pliron/parsable/trait.Parsable.html) for
389/// [Attribute](../pliron/attribute/trait.Attribute.html)s
390///
391/// Refer to [macro@format] for the syntax specification and examples.
392#[proc_macro_attribute]
393pub fn format_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
394    to_token_stream(derive_format::derive(
395        args,
396        input,
397        DeriveIRObject::Attribute,
398    ))
399}
400/// Derive [Printable](../pliron/printable/trait.Printable.html) and
401/// [Parsable](../pliron/parsable/trait.Parsable.html) for
402/// [Type](../pliron/type/trait.Type.html)s
403///
404/// Refer to [macro@format] for the syntax specification and examples.
405#[proc_macro_attribute]
406pub fn format_type(args: TokenStream, input: TokenStream) -> TokenStream {
407    to_token_stream(derive_format::derive(args, input, DeriveIRObject::Type))
408}
409
410pub(crate) fn to_token_stream(res: syn::Result<proc_macro2::TokenStream>) -> TokenStream {
411    let tokens = match res {
412        Ok(tokens) => tokens,
413        Err(error) => {
414            let error = error.to_compile_error();
415            quote::quote!(
416                #error
417            )
418        }
419    };
420    TokenStream::from(tokens)
421}
422
423/// Declare an [Op](../pliron/op/trait.Op.html) interface, which can be implemented
424/// by any `Op`.
425///
426/// If the interface requires any other interface to be already implemented,
427/// they can be specified super-traits.
428///
429/// When an `Op` is verified, its interfaces are also automatically verified,
430/// with guarantee that a super-interface is verified before an interface itself is.
431///
432/// Example: Here `SameOperandsAndResultType` and `SymbolOpInterface` are super interfaces
433/// for the new interface `MyOpIntr`.
434/// ```
435/// # use pliron::builtin::op_interfaces::{SameOperandsAndResultType, SymbolOpInterface};
436/// # use pliron::derive::{op_interface};
437/// # use pliron::{op::Op, context::Context, result::Result};
438///   /// MyOpIntr is my first op interface.
439///   #[op_interface]
440///   trait MyOpIntr: SameOperandsAndResultType + SymbolOpInterface {
441///       fn verify(_op: &dyn Op, _ctx: &Context) -> Result<()>
442///       where Self: Sized,
443///       {
444///           Ok(())
445///       }
446///   }
447/// ```
448#[proc_macro_attribute]
449pub fn op_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
450    let supertrait = parse_quote! { ::pliron::op::Op };
451    let verifier_type = parse_quote! { ::pliron::op::OpInterfaceVerifier };
452
453    to_token_stream(interfaces::interface_define(
454        item,
455        supertrait,
456        verifier_type,
457        true,
458    ))
459}
460
461/// Implement [Op](../pliron/op/trait.Op.html) Interface for an Op. The interface trait must define
462/// a `verify` function with type [OpInterfaceVerifier](../pliron/op/type.OpInterfaceVerifier.html)
463///
464/// Usage:
465/// ```
466/// # use pliron::derive::{def_op, format_op, op_interface, op_interface_impl};
467///
468/// #[def_op("dialect.name")]
469/// #[format_op]
470/// struct MyOp;
471///
472/// #[op_interface]
473/// pub trait MyOpInterface {
474///     fn gubbi(&self);
475///     fn verify(op: &dyn Op, ctx: &Context) -> Result<()>
476///     where Self: Sized,
477///     {
478///         Ok(())
479///     }
480/// }
481///
482/// #[op_interface_impl]
483/// impl MyOpInterface for MyOp {
484///     fn gubbi(&self) { println!("gubbi"); }
485/// }
486/// # use pliron::{
487/// #     op::Op, context::Context, result::Result, common_traits::Verify
488/// # };
489/// # pliron::impl_verify_succ!(MyOp);
490/// ```
491#[proc_macro_attribute]
492pub fn op_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
493    let interface_verifiers_slice = parse_quote! { ::pliron::op::OP_INTERFACE_VERIFIERS };
494    let id = parse_quote! { ::pliron::op::OpId };
495    let get_id_static = format_ident!("{}", "get_opid_static");
496    let all_verifiers_fn_type = parse_quote! { ::pliron::op::OpInterfaceAllVerifiers };
497    to_token_stream(interfaces::interface_impl(
498        item,
499        interface_verifiers_slice,
500        id,
501        all_verifiers_fn_type,
502        get_id_static,
503    ))
504}
505
506/// Derive implementation of an [Op](../pliron/op/trait.Op.html) Interface for an Op.
507/// Note that an impl can be derived only for those interfaces that do not require any
508/// methods to be defined during the impl.
509///
510/// Usage:
511/// ```
512/// # use pliron::derive::{op_interface, format_op, derive_op_interface_impl};
513///
514/// #[def_op("dialect.name")]
515/// #[format_op]
516/// #[derive_op_interface_impl(MyOpInterface)]
517/// struct MyOp;
518///
519/// #[op_interface]
520/// pub trait MyOpInterface {
521///     fn gubbi(&self) { println!("gubbi"); }
522///     fn verify(op: &dyn Op, ctx: &Context) -> Result<()>
523///     where Self: Sized,
524///     {
525///         Ok(())
526///     }
527/// }
528/// # use pliron::derive::def_op;
529/// # use pliron::{
530/// #     op::Op, context::Context, result::Result,
531/// #     common_traits::Verify
532/// # };
533/// # pliron::impl_verify_succ!(MyOp);
534/// ```
535#[proc_macro_attribute]
536pub fn derive_op_interface_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
537    to_token_stream(interfaces::derive_op_interface_impl(attr, item))
538}
539
540/// Declare an [Attribute](../pliron/attribute/trait.Attribute.html) interface,
541/// which can be implemented by any `Attribute`.
542///
543/// If the interface requires any other interface to be already implemented,
544/// they can be specified super-traits.
545///
546/// When an `Attribute` is verified, its interfaces are also automatically verified,
547/// with guarantee that a super-interface is verified before an interface itself is.
548///
549/// Example: Here `Super1` and `Super2` are super interfaces for the interface `MyAttrIntr`.
550/// ```
551/// # use pliron::{attribute::Attribute, context::Context, result::Result};
552/// use pliron::derive::attr_interface;
553///
554/// #[attr_interface]
555/// trait Super1 {
556///     fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
557///     where
558///         Self: Sized,
559///     {
560///         Ok(())
561///     }
562/// }
563///
564/// #[attr_interface]
565/// trait Super2 {
566///     fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
567///     where
568///         Self: Sized,
569///     {
570///         Ok(())
571///     }
572/// }
573///
574/// // MyAttrIntr is my best attribute interface.
575/// #[attr_interface]
576/// trait MyAttrIntr: Super1 + Super2 {
577///     fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
578///     where
579///         Self: Sized,
580///     {
581///         Ok(())
582///     }
583/// }
584/// ```
585#[proc_macro_attribute]
586pub fn attr_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
587    let supertrait = parse_quote! { ::pliron::attribute::Attribute };
588    let verifier_type = parse_quote! { ::pliron::attribute::AttrInterfaceVerifier };
589
590    to_token_stream(interfaces::interface_define(
591        item,
592        supertrait,
593        verifier_type,
594        true,
595    ))
596}
597
598/// Implement [Attribute](../pliron/attribute/trait.Attribute.html) Interface for an Attribute.
599/// The interface trait must define a `verify` function with type
600/// [AttrInterfaceVerifier](../pliron/attribute/type.AttrInterfaceVerifier.html).
601///
602/// Usage:
603/// ```
604/// use pliron::derive::{attr_interface, attr_interface_impl, format_attribute};
605///
606/// #[def_attribute("dialect.name")]
607/// #[format_attribute]
608/// #[derive(PartialEq, Eq, Clone, Debug, Hash)]
609/// struct MyAttr { }
610///
611///     /// My first attribute interface.
612/// #[attr_interface]
613/// trait MyAttrInterface {
614///     fn monu(&self);
615///     fn verify(attr: &dyn Attribute, ctx: &Context) -> Result<()>
616///     where Self: Sized,
617///     {
618///          Ok(())
619///     }
620/// }
621///
622/// #[attr_interface_impl]
623/// impl MyAttrInterface for MyAttr
624/// {
625///     fn monu(&self) { println!("monu"); }
626/// }
627/// # use pliron::{
628/// #     printable::{self, Printable},
629/// #     context::Context, result::Result, common_traits::Verify,
630/// #     attribute::Attribute
631/// # };
632/// # use pliron::derive::def_attribute;
633/// #
634/// # pliron::impl_verify_succ!(MyAttr);
635#[proc_macro_attribute]
636pub fn attr_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
637    let interface_verifiers_slice = parse_quote! { ::pliron::attribute::ATTR_INTERFACE_VERIFIERS };
638    let id = parse_quote! { ::pliron::attribute::AttrId };
639    let get_id_static = format_ident!("{}", "get_attr_id_static");
640    let all_verifiers_fn_type = parse_quote! { ::pliron::attribute::AttrInterfaceAllVerifiers };
641    to_token_stream(interfaces::interface_impl(
642        item,
643        interface_verifiers_slice,
644        id,
645        all_verifiers_fn_type,
646        get_id_static,
647    ))
648}
649
650/// Declare a [Type](../pliron/type/trait.Type.html) interface,
651/// which can be implemented by any `Type`.
652///
653/// If the interface requires any other interface to be already implemented,
654/// they can be specified super-traits.
655///
656/// When an `Attribute` is verified, its interfaces are also automatically verified,
657/// with guarantee that a super-interface is verified before an interface itself is.
658///
659/// Example: Here `Super1` and `Super2` are super interfaces for the interface `MyTypeIntr`.
660/// ```
661/// use pliron::derive::type_interface;
662/// # use pliron::{r#type::Type, context::Context, result::Result};
663/// #[type_interface]
664/// trait Super1 {
665///     fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
666///     where
667///         Self: Sized,
668///     {
669///         Ok(())
670///     }
671/// }
672///
673/// #[type_interface]
674/// trait Super2 {
675///     fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
676///     where
677///         Self: Sized,
678///     {
679///         Ok(())
680///     }
681/// }
682///
683/// #[type_interface]
684/// // MyTypeIntr is my best type interface.
685/// trait MyTypeIntr: Super1 + Super2 {
686///     fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
687///     where
688///         Self: Sized,
689///     {
690///         Ok(())
691///     }
692/// }
693/// ```
694#[proc_macro_attribute]
695pub fn type_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
696    let supertrait = parse_quote! { ::pliron::r#type::Type };
697    let verifier_type = parse_quote! { ::pliron::r#type::TypeInterfaceVerifier };
698
699    to_token_stream(interfaces::interface_define(
700        item,
701        supertrait,
702        verifier_type,
703        false,
704    ))
705}
706
707/// Implement [Type](../pliron/type/trait.Type.html) Interface for a Type.
708/// The interface trait must define a `verify` function with type
709/// [TypeInterfaceVerifier](../pliron/type/type.TypeInterfaceVerifier.html).
710///
711/// Usage:
712/// ```
713/// use pliron::derive::{type_interface, type_interface_impl, format_type};
714///
715/// #[def_type("dialect.name")]
716/// #[format_type]
717/// #[derive(PartialEq, Eq, Clone, Debug, Hash)]
718/// struct MyType { }
719///
720/// #[type_interface]
721/// /// My first type interface.
722/// trait MyTypeInterface {
723///     fn monu(&self);
724///     fn verify(r#type: &dyn Type, ctx: &Context) -> Result<()>
725///     where Self: Sized,
726///     {
727///          Ok(())
728///     }
729/// }
730///
731/// #[type_interface_impl]
732/// impl MyTypeInterface for MyType
733/// {
734///     fn monu(&self) { println!("monu"); }
735/// }
736/// # use pliron::{
737/// #     printable::{self, Printable},
738/// #     context::Context, result::Result, common_traits::Verify,
739/// #     r#type::Type
740/// # };
741/// # use pliron::derive::def_type;
742/// #
743/// # pliron::impl_verify_succ!(MyType);
744#[proc_macro_attribute]
745pub fn type_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
746    let interface_verifiers_slice = parse_quote! { ::pliron::r#type::TYPE_INTERFACE_VERIFIERS };
747    let id = parse_quote! { ::pliron::r#type::TypeId };
748    let get_id_static = format_ident!("{}", "get_type_id_static");
749    let all_verifiers_fn_type = parse_quote! { ::pliron::r#type::TypeInterfaceAllVerifiers };
750    to_token_stream(interfaces::interface_impl(
751        item,
752        interface_verifiers_slice,
753        id,
754        all_verifiers_fn_type,
755        get_id_static,
756    ))
757}