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}