pliron_derive/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) The pliron contributors
3
4mod derive_attr;
5mod derive_decontext;
6mod derive_entity;
7mod derive_format;
8mod derive_op;
9mod derive_type;
10mod interfaces;
11mod irfmt;
12mod verify_succ;
13
14use proc_macro::TokenStream;
15use syn::parse_quote;
16
17use derive_format::DeriveIRObject;
18
19/// A hash map with a fast, non-cryptographic hasher and deterministic iteration order.
20type IMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
21
22/// A hash set with a fast, non-cryptographic hasher and deterministic iteration order.
23type ISet<T> = indexmap::IndexSet<T, rustc_hash::FxBuildHasher>;
24
25/// `#[def_attribute(...)]`: Annotate a Rust struct as a new IR attribute.
26///
27/// *Note*: It is suggested to use the [pliron_attr] macro instead of using this macro directly.
28/// The documention here is useful though, because [pliron_attr]'s `name` field expands
29/// to this macro.
30///
31/// The argument to the macro is the fully qualified name of the attribute in the form of
32/// `"dialect.attribute_name"`.
33///
34/// The macro will leave the struct definition unchanged, but it will generate an implementation of
35/// the pliron::Attribute trait and implements other internal traits and types resources required
36/// to use the IR attribute.
37///
38/// **Note**: pre-requisite traits for `Attribute` must already be implemented.
39/// Additionaly, [Eq] and [Hash](core::hash::Hash) must be implemented by the type.
40///
41/// Usage:
42///
43/// ```
44/// use pliron::derive::{def_attribute, format_attribute, verify_succ};
45///
46/// #[verify_succ]
47/// #[def_attribute("my_dialect.attribute")]
48/// #[format_attribute]
49/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
50/// pub struct StringAttr(String);
51/// # use pliron::{printable::{State, Printable}, context::Context};
52/// ```
53#[proc_macro_attribute]
54pub fn def_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
55 to_token_stream(derive_attr::def_attribute(args, input))
56}
57
58/// `#[def_type(...)]`: Annotate a Rust struct as a new IR type.
59///
60/// *Note*: It is suggested to use the [pliron_type] macro instead of using this macro directly.
61/// The documention here is useful though, because [pliron_type]'s `name` field expands
62/// to this macro.
63///
64/// The argument to the macro is the fully qualified name of the type in the form of
65/// `"dialect.type_name"`.
66///
67/// The macro will leave the struct definition unchanged, but it will generate an implementation of
68/// the pliron::Type trait and implements other internal traits and types resources required
69/// to use the IR type.
70///
71/// **Note**: pre-requisite traits for `Type` must already be implemented.
72/// Additionaly, [Hash](core::hash::Hash) and [Eq] must be implemented by the rust type.
73///
74/// Usage:
75///
76/// ```
77/// use pliron::derive::{def_type, format_type, verify_succ};
78/// #[verify_succ]
79/// #[def_type("my_dialect.unit")]
80/// #[format_type]
81/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
82/// pub struct UnitType;
83/// ```
84#[proc_macro_attribute]
85pub fn def_type(args: TokenStream, input: TokenStream) -> TokenStream {
86 to_token_stream(derive_type::def_type(args, input))
87}
88
89/// Derive get methods for types that retrieve interned types.
90///
91/// *Note*: It is suggested to use the [pliron_type] macro instead of using this macro directly.
92/// The documention here is useful though, because [pliron_type]'s `generate_get` field
93/// expands to this macro.
94///
95/// This macro generates a `get` method that returns a uniqued instance of the type.
96/// For unit structs (no fields), it takes only a `Context` parameter.
97/// For structs with fields, it takes a `Context` parameter plus a parameter for each field.
98///
99/// ## Examples
100///
101/// ### Named fields struct:
102/// ```
103/// use pliron::derive::{def_type, derive_type_get, format_type, verify_succ};
104/// use pliron::context::Context;
105///
106/// #[verify_succ]
107/// #[def_type("my_dialect.vector_type")]
108/// #[format_type]
109/// #[derive_type_get] // Auto-generates get method
110/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
111/// pub struct VectorType {
112/// elem_ty: u32,
113/// num_elems: u32,
114/// }
115///
116/// // Usage of the auto-generated get method:
117/// # fn example(ctx: &Context) {
118/// let vector_type = VectorType::get(ctx, 42, 8); // get(ctx, elem_ty, num_elems)
119/// # }
120/// ```
121///
122/// ### Tuple struct:
123/// ```
124/// use pliron::derive::{def_type, derive_type_get, format_type, verify_succ};
125/// use pliron::context::Context;
126///
127/// #[verify_succ]
128/// #[def_type("my_dialect.tuple_type")]
129/// #[format_type]
130/// #[derive_type_get] // Auto-generates get method
131/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
132/// pub struct TupleType(u32, String, bool);
133///
134/// // Usage of the auto-generated get method:
135/// # fn example(ctx: &Context) {
136/// let tuple_type = TupleType::get(ctx, 42, "hello".to_string(), true); // get(ctx, field_0, field_1, field_2)
137/// # }
138/// ```
139///
140/// ### Unit struct:
141/// ```
142/// use pliron::derive::{def_type, derive_type_get, format_type, verify_succ};
143/// use pliron::context::Context;
144///
145/// #[verify_succ]
146/// #[def_type("my_dialect.unit_type")]
147/// #[format_type]
148/// #[derive_type_get] // Auto-generates get method
149/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
150/// pub struct UnitType;
151///
152/// // Usage of the auto-generated get method:
153/// # fn example(ctx: &Context) {
154/// let unit_type = UnitType::get(ctx); // get(ctx) - no additional parameters
155/// # }
156/// ```
157#[proc_macro_attribute]
158pub fn derive_type_get(args: TokenStream, input: TokenStream) -> TokenStream {
159 to_token_stream(derive_type::derive_type_get(args, input))
160}
161
162/// `#[verify_succ]`: Implement [Verify](../pliron/common_traits/trait.Verify.html)
163/// for a Rust struct or enum with a verifier that always succeeds.
164///
165/// This leaves the original item unchanged and adds:
166/// `impl Verify for T { fn verify(...) -> Result<()> { Ok(()) } }`.
167///
168/// Usage:
169///
170/// ```
171/// use pliron::derive::verify_succ;
172/// use pliron::{common_traits::Verify, context::Context};
173///
174/// #[verify_succ]
175/// struct AlwaysValid;
176///
177/// let ctx = Context::new();
178/// assert!(AlwaysValid.verify(&ctx).is_ok());
179/// ```
180#[proc_macro_attribute]
181pub fn verify_succ(args: TokenStream, input: TokenStream) -> TokenStream {
182 to_token_stream(verify_succ::verify_succ_impl(args.into(), input.into()))
183}
184
185/// `#[def_op(...)]`: Create a new IR operation.
186///
187/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
188/// The documention here is useful though, because [pliron_op]'s `name` field expands
189/// to this macro.
190///
191/// The argument to the macro is the fully qualified name of the operation in the form of
192/// `"dialect.op_name"`.
193///
194/// The macro assumes an empty struct and will add the `op: Ptr<Operation>` field used to access
195/// the underlying Operation in the context.
196///
197/// The macro will automatically derive the `Clone`, `Copy`, `Hash`, `PartialEq` and `Eq` traits
198/// for the new struct definition.
199///
200/// **Note**: pre-requisite traits for `Op` (Printable, Verify etc) must already be implemented
201///
202/// Usage:
203///
204/// ```
205/// use pliron::derive::{def_op, format_op, verify_succ};
206///
207/// #[verify_succ]
208/// #[def_op("my_dialect.op")]
209/// #[format_op]
210/// pub struct MyOp;
211/// ```
212/// The example will create a struct definition equivalent to:
213///
214/// ```
215/// #[derive(Clone, Copy, PartialEq, Eq, Hash)]
216/// pub struct MyOp {
217/// op: Ptr<Operation>,
218/// }
219/// # use pliron::{context::Ptr, operation::Operation};
220/// ```
221#[proc_macro_attribute]
222pub fn def_op(args: TokenStream, input: TokenStream) -> TokenStream {
223 to_token_stream(derive_op::def_op(args, input))
224}
225
226/// Derive getter and setters for operation attributes listed as arguments.
227///
228/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
229/// The documention here is useful though, because [pliron_op]'s `attributes` field
230/// expands to this macro.
231///
232/// The arguments are a comma separated list of attribute names
233/// (which must be an [Identifier](../pliron/identifier/struct.Identifier.html)),
234/// each of which may have an optional concrete Rust type specified,
235/// denoting the [Attribute](../pliron/attribute/trait.Attribute.html)'s concrete type.
236///
237/// ```
238/// # use pliron::derive::{def_op, derive_attr_get_set, format_op, verify_succ};
239/// // A test for the `derive_attr_get_set` macro.
240/// #[verify_succ]
241/// #[def_op("llvm.with_attrs")]
242/// #[format_op]
243/// #[derive_attr_get_set(name1_any_attr, name2_ty_attr : pliron::builtin::attributes::TypeAttr)]
244/// pub struct WithAttrsOp {}
245/// ```
246///
247/// This expands to add the following getter / setter items:
248/// ```Rust
249/// # use pliron::derive::{def_op, format_op, derive_attr_get_set};
250/// # use core::cell::Ref;
251/// # use pliron::dict_key;
252/// # use pliron::{attribute::AttrObj, context::Context};
253/// # use pliron::{builtin::attributes::TypeAttr};
254/// # use pliron::derive::verify_succ;
255/// # #[verify_succ]
256/// #[format_op]
257/// #[def_op("llvm.with_attrs")]
258/// pub struct WithAttrsOp {}
259/// dict_key!(ATTR_KEY_NAME1_ANY_ATTR, "name1_any_attr");
260/// dict_key!(ATTR_KEY_NAME2_TY_ATTR, "name2_ty_attr");
261/// impl WithAttrsOp {
262/// pub fn get_attr_name1_any_attr<'a>
263/// (&self, ctx: &'a Context)-> Option<Ref<'a, AttrObj>> { todo!() }
264/// pub fn set_attr_name1_any_attr(&self, ctx: &Context, value: AttrObj) { todo!() }
265/// pub fn get_attr_name2_ty_attr<'a>
266/// (&self, ctx: &'a Context) -> Option<Ref<'a, TypeAttr>> { todo!() }
267/// pub fn set_attr_name2_ty_attr(&self, ctx: &Context, value: TypeAttr) { todo!() }
268/// }
269/// ```
270#[proc_macro_attribute]
271pub fn derive_attr_get_set(args: TokenStream, input: TokenStream) -> TokenStream {
272 to_token_stream(derive_op::derive_attr_get_set(args, input))
273}
274
275/// Derive getter methods and / or operand type interfaces for operation operands.
276///
277/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
278/// The documention here is useful though, because [pliron_op]'s `operands` field expands
279/// to this macro.
280///
281/// The arguments are a comma-separated list where each entry is:
282/// - `name` or `name: Type` for a named operand getter `get_operand_<name>()`.
283/// - `_` or `_: Type` to skip getter generation for that position.
284///
285/// When `Type` is provided, this macro derives
286/// [OperandNOfType](../pliron/builtin/op_interfaces/trait.OperandNOfType.html)
287/// for the corresponding operand index.
288///
289/// The op is allowed to have more operands than those specified in the macro arguments.
290/// They just won't have getters or type interfaces generated for them.
291///
292/// ```
293/// use pliron::derive::{def_op, format_op, operands, verify_succ};
294/// use pliron::builtin::types::{IntegerType, UnitType};
295///
296/// #[verify_succ]
297/// #[def_op("dialect.with_operands")]
298/// #[format_op]
299/// #[operands(lhs: IntegerType, _, rhs, _: UnitType)]
300/// pub struct WithOperandsOp {}
301/// ```
302#[proc_macro_attribute]
303pub fn operands(args: TokenStream, input: TokenStream) -> TokenStream {
304 to_token_stream(derive_op::operands(args, input))
305}
306
307/// Derive getter methods and / or result type interfaces for operation results.
308///
309/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
310/// The documention here is useful though, because [pliron_op]'s `results` field expands
311/// to this macro.
312///
313/// The arguments are a comma-separated list where each entry is:
314/// - `name` or `name: Type` for a named result getter `get_result_<name>()`.
315/// - `_` or `_: Type` to skip getter generation for that position.
316///
317/// When `Type` is provided, this macro derives
318/// [ResultNOfType](../pliron/builtin/op_interfaces/trait.ResultNOfType.html)
319/// for the corresponding result index.
320///
321/// The op is allowed to have more results than those specified in the macro arguments.
322/// They just won't have getters or type interfaces generated for them.
323///
324/// ```
325/// use pliron::derive::{def_op, format_op, results, verify_succ};
326/// use pliron::builtin::types::{IntegerType, UnitType};
327///
328/// #[verify_succ]
329/// #[def_op("dialect.with_results")]
330/// #[format_op]
331/// #[results(out: IntegerType, _: UnitType)]
332/// pub struct WithResultsOp {}
333/// ```
334#[proc_macro_attribute]
335pub fn results(args: TokenStream, input: TokenStream) -> TokenStream {
336 to_token_stream(derive_op::results(args, input))
337}
338
339/// Derive [Printable](../pliron/printable/trait.Printable.html) and
340/// [Parsable](../pliron/parsable/trait.Parsable.html) for Rust types.
341/// Use this for types other than `Op`, `Type` and `Attribute`s.
342///
343/// A format string can be specified as an argument to the macro, to customize the syntax.
344/// Without a format string, the default syntax is used. For enums, no format string is allowed
345/// on the enum itself, but it is allowed on its variants.
346///
347/// Primarily, the following two are used to refer to fields in a struct or tuple:
348/// 1. A named variable `$name` specifies a named struct field.
349/// 2. An unnamed variable `$i` specifies the i'th field of a tuple struct.
350///
351/// Struct (or tuple) fields that are either [Option] or [Vec] (or an array) must to be specified
352/// using the `opt` and `vec` directives respectively (i.e., a format string is mandatory).
353///
354/// The `opt` directive takes one mandatory argument, a variable specifying the field name with
355/// type `Option`. It also supports optional `label` and `delimiters` directives:
356/// 1. `label($name)`: uses `name :` as a prefix for the optional value.
357/// 2. `delimiters(`open`, `close`)`: wraps the optional value with the given delimiters.
358///
359/// The `vec` directive takes two arguments, the first is a variable specifying the field name
360/// with type `Vec` (or array) and the second is another directive to specify a
361/// [ListSeparator](../pliron/printable/enum.ListSeparator.html).
362///
363/// The following directives are supported:
364/// 1. `NewLine`: takes no argument, and specifies a newline to be used as list separator.
365/// 2. ``CharNewline(`c`)``: takes a single character argument that will be followed by a newline.
366/// 3. ``Char(`c`)``: takes a single character argument that will be used as separator.
367/// 4. ``CharSpace(`c`)``: takes a single character argument that will be followed by a space.
368///
369/// Generic structs and enums are supported. The macro preserves generic parameters on the
370/// generated `Printable` and `Parsable` impls, but it does not synthesize trait bounds.
371/// Any generic field that is parsed or printed through the format must therefore carry explicit
372/// bounds on the type itself. In practice, this usually means a bound like
373/// `T: Printable + Parsable<Arg = (), Parsed = T>`.
374///
375/// Examples:
376/// 1. Derive for a struct, with no format string (default format):
377/// (Note that the field u64 has both `Printable` and `Parsable` implemented).
378/// ```
379/// use pliron::derive::format;
380/// #[format]
381/// struct IntWrapper {
382/// inner: u64,
383/// }
384/// ```
385/// 2. An example with a custom format string:
386/// ```
387/// use pliron::derive::format;
388/// #[format("`BubbleWrap` `[` $inner `]`")]
389/// struct IntWrapperCustom {
390/// inner: u64,
391/// }
392/// ```
393/// 3. An example for an enum (custom format strings are allowed for the variants only).
394/// ```
395/// use pliron::derive::format;
396/// use pliron::{builtin::types::IntegerType, r#type::TypedHandle};
397/// #[format]
398/// enum Enum {
399/// A(TypedHandle<IntegerType>),
400/// B {
401/// one: TypedHandle<IntegerType>,
402/// two: u64,
403/// },
404/// C,
405/// #[format("`<` $upper `/` $lower `>`")]
406/// Op {
407/// upper: u64,
408/// lower: u64,
409/// },
410/// }
411/// ```
412/// 4. An example with `Option` and `Vec` fields
413/// ```
414/// use pliron::derive::format;
415/// #[format("`<` opt($a) `;` vec($b, Char(`,`)) `>`")]
416/// struct OptAndVec {
417/// a: Option<u64>,
418/// b: Vec<u64>,
419///}
420/// ```
421/// 5. An example with a generic field and explicit bounds:
422/// ```
423/// use pliron::derive::format;
424/// use pliron::{parsable::Parsable, printable::Printable};
425///
426/// #[format]
427/// struct Wrapper<T>
428/// where
429/// T: Printable + Parsable<Arg = (), Parsed = T>,
430/// {
431/// value: T,
432/// }
433/// ```
434/// 6. An example with an optional field using `label` and `delimiters` in `opt`:
435/// ```
436/// use pliron::derive::format;
437/// #[format("`<` opt($a, label($value), delimiters(`(`, `)`)) `>`")]
438/// struct OptionalField {
439/// a: Option<u64>,
440/// }
441/// ```
442#[proc_macro_attribute]
443pub fn format(args: TokenStream, input: TokenStream) -> TokenStream {
444 to_token_stream(derive_format::derive(
445 args,
446 input,
447 DeriveIRObject::AnyOtherRustType,
448 ))
449}
450
451/// Derive [Printable](../pliron/printable/trait.Printable.html) and
452/// [Parsable](../pliron/parsable/trait.Parsable.html) for [Op](../pliron/op/trait.Op.html)s
453///
454/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
455/// The documention here is useful though, because [pliron_op]'s `format` field
456/// expands to this macro.
457///
458/// This derive only supports a syntax in which results appear before the opid:
459/// `res1, ... = opid ...`
460/// The format string specifies what comes after the opid.
461/// 1. A named variable `$name` specifies a named attribute of the operation.
462/// This cannot be combined with the [attr_dict](#attr_dict) directive.
463/// 2. An unnamed variable `$i` specifies `operands[i]`, except when inside some directives.
464/// This cannot be combined with the "operands" directive.
465/// 3. The "type" directive specifies that a type must be parsed. It takes one argument,
466/// which is an unnamed variable `$i` with `i` specifying `result[i]`. This cannot be
467/// combined with the "types" directive.
468/// 4. The "region" directive specifies that a region must be parsed. It takes one argument,
469/// which is an unnamed variable `$i` with `i` specifying `region[i]`. This cannot be
470/// combined with the "regions" directive.
471/// 5. The <a name="attr"></a> "attr" directive can be used to specify attribute on an `Op` when
472/// the attribute's rust type is fixed at compile time. It takes two mandatory and two optional
473/// arguments.
474///
475/// 1. The first operand is a named variable `$name` which is used as a key into the
476/// operation's attribute dictionary
477/// 2. The second is the concrete rust type of the attribute. This second argument can be a
478/// named variable `$name` (with `name` being in scope) or a literal string denoting the path
479/// to a rust type (e.g. `` `::pliron::builtin::attributes::IntegerAttr` ``).
480/// 3. Two additional optional arguments can be specified:
481/// * The "label" directive, with one argument, a named variable `$label`, which
482/// specifies the label to be used while printing / parsing the attribute.
483/// * The "delimiters" directive, which takes two literal arguments,
484/// specifying the opening and closing delimiters to be used while printing / parsing.
485///
486/// The advantage over specifying an attribute using the [attr](#attr) directive (as against
487/// just using a named variable) is that the attribute-id is not a part of the syntax
488/// here (because the type is statically known, allowing us to be able to parse it),
489/// thus allowing it to be more succinct. This cannot be combined with the [attr_dict](#attr_dict)
490/// directive.
491/// 6. The "succ" directive specifies an operation's successor. It takes one argument,
492/// which is an unnamed variable `$i` with `i` specifying `successor[i]`.
493/// 7. The "operands" directive specifies all the operands of an operation. It takes one argument
494/// which is a directive specifying the separator between operands. This cannot be combined
495/// with using unnamed variables `$i` to refer to operands.
496/// The following directives are supported:
497/// 1. `NewLine`: takes no argument, and specifies a newline to be used as list separator.
498/// 2. ``CharNewline(`c`)``: takes a single character argument that will be followed by a newline.
499/// 3. ``Char(`c`)``: takes a single character argument that will be used as separator.
500/// 4. ``CharSpace(`c`)``: takes a single character argument that will be followed by a space.
501/// 8. The "successors" directive specifies all the successors of an operation. It takes one argument
502/// which is a directive specifying the separator between successors. The separator directive is
503/// same as that for "operands" above. This cannot be combined with the "succ" directive.
504/// 9. The "regions" directive specifies all the regions of an operation. It takes one argument
505/// which is a directive specifying the separator between regions. The separator directive is same
506/// as that for "operands" above. This cannot be combined with the "region" directive.
507/// 10. The <a name="attr_dict"></a> "attr_dict" directive specifies an
508/// [AttributeDict](../pliron/attribute/struct.AttributeDict.html).
509/// It cannot be combined with any of [attr](#attr), [opt_attr](#opt_attr) directives or
510/// a named variable (`$name`).
511/// 11. The "types" directive specifies all the result types of an operation. It takes one argument
512/// which is a directive specifying the separator between result types. The separator directive is
513/// same as that for "operands" above. This cannot be combined with the "type" directive.
514/// 12. The "typesig" directive prints the full type signature of an operation as
515/// `(operand_types) -> (result_types)`. It takes no arguments. When parsing, the operand
516/// types are consumed and ignored; only the result types are used to build the operation.
517/// This cannot be combined with any of "type", "types", "opdtype" or "opdtypes" directives.
518/// 13. The "opdtype" directive specifies that an operand type should be printed. It takes one
519/// argument, which is an unnamed variable `$i` with `i` specifying `operands[i]`. This cannot
520/// be combined with the "opdtypes" or "typesig" directives. **Note**: Parsed operand types
521/// are ignored, and not validated against actual operand types.
522/// 14. The "opdtypes" directive specifies all the operand types of an operation. It takes one
523/// argument which is a directive specifying the separator between operand types. The separator
524/// directive is same as that for "operands" above. This cannot be combined with the "opdtype"
525/// or "typesig" directives. **Note**: Parsed operand types are ignored and not validated against
526/// actual operand types.
527/// 15. The <a name="opt_attr"></a> "opt_attr" directive specifies an optional attribute on an `Op`.
528/// It takes two or more arguments, which are same as those of the [attr](#attr) directive.
529/// This cannot be combined with the [attr_dict](#attr_dict) directive.
530///
531/// Examples:
532/// 1. Derive for a struct, with no format string (default format):
533/// ```
534/// use pliron::derive::{def_op, format_op, verify_succ};
535/// #[verify_succ]
536/// #[format_op]
537/// #[def_op("test.myop")]
538/// struct MyOp;
539/// ```
540/// 2. An example with a custom format string:
541/// ```
542/// use pliron::derive::{def_op, derive_op_interface_impl, format_op, verify_succ};
543/// use pliron::{op::Op, builtin::op_interfaces::{OneOpdInterface, OneResultInterface}};
544/// #[verify_succ]
545/// #[format_op("$0 `<` $attr `>` `:` type($0)")]
546/// #[def_op("test.one_result_one_operand")]
547/// #[derive_op_interface_impl(OneOpdInterface, OneResultInterface)]
548/// struct OneResultOneOperandOp;
549/// ```
550/// More examples can be seen in the tests for this macro in `pliron-derive/tests/format_op.rs`.
551#[proc_macro_attribute]
552pub fn format_op(args: TokenStream, input: TokenStream) -> TokenStream {
553 to_token_stream(derive_format::derive(args, input, DeriveIRObject::Op))
554}
555
556/// Derive [Printable](../pliron/printable/trait.Printable.html) and
557/// [Parsable](../pliron/parsable/trait.Parsable.html) for
558/// [Attribute](../pliron/attribute/trait.Attribute.html)s
559///
560/// *Note*: It is suggested to use the [pliron_attr] macro instead of using this macro directly.
561///
562/// Refer to [macro@format] for the syntax specification and examples.
563#[proc_macro_attribute]
564pub fn format_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
565 to_token_stream(derive_format::derive(
566 args,
567 input,
568 DeriveIRObject::Attribute,
569 ))
570}
571
572/// Derive [Printable](../pliron/printable/trait.Printable.html) and
573/// [Parsable](../pliron/parsable/trait.Parsable.html) for
574/// [Type](../pliron/type/trait.Type.html)s
575///
576/// *Note*: It is suggested to use the [pliron_type] macro instead of using this macro directly.
577///
578/// Refer to [macro@format] for the syntax specification and examples.
579#[proc_macro_attribute]
580pub fn format_type(args: TokenStream, input: TokenStream) -> TokenStream {
581 to_token_stream(derive_format::derive(args, input, DeriveIRObject::Type))
582}
583
584pub(crate) fn to_token_stream(res: syn::Result<proc_macro2::TokenStream>) -> TokenStream {
585 let tokens = match res {
586 Ok(tokens) => tokens,
587 Err(error) => {
588 let error = error.to_compile_error();
589 quote::quote!(
590 #error
591 )
592 }
593 };
594 TokenStream::from(tokens)
595}
596
597/// Declare an [Op](../pliron/op/trait.Op.html) interface, which can be implemented
598/// by any `Op`.
599///
600/// If the interface requires any other interface to be already implemented,
601/// they can be specified super-traits.
602///
603/// When an `Op` is verified, its interfaces are also automatically verified,
604/// with guarantee that a super-interface is verified before an interface itself is.
605///
606/// Example: Here `SameOperandsAndResultType` and `SymbolOpInterface` are super interfaces
607/// for the new interface `MyOpIntr`.
608/// ```
609/// # use pliron::builtin::op_interfaces::{SameOperandsAndResultType, SymbolOpInterface};
610/// # use pliron::derive::{op_interface};
611/// # use pliron::{op::Op, context::Context, result::Result};
612/// /// MyOpIntr is my first op interface.
613/// #[op_interface]
614/// trait MyOpIntr: SameOperandsAndResultType + SymbolOpInterface {
615/// fn verify(_op: &dyn Op, _ctx: &Context) -> Result<()>
616/// where Self: Sized,
617/// {
618/// Ok(())
619/// }
620/// }
621/// ```
622#[proc_macro_attribute]
623pub fn op_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
624 let supertrait = parse_quote! { ::pliron::op::Op };
625 let verifier_type = parse_quote! { ::pliron::op::OpInterfaceVerifier };
626 let target_marker_trait = parse_quote! { ::pliron::op::OpInterfaceMarker };
627
628 to_token_stream(interfaces::interface_define(
629 item,
630 supertrait,
631 verifier_type,
632 true,
633 target_marker_trait,
634 ))
635}
636
637/// Implement [Op](../pliron/op/trait.Op.html) Interface for an Op. The interface trait must define
638/// a `verify` function with type [OpInterfaceVerifier](../pliron/op/type.OpInterfaceVerifier.html)
639///
640/// Usage:
641/// ```
642/// # use pliron::derive::{def_op, format_op, op_interface, op_interface_impl, verify_succ};
643///
644/// #[verify_succ]
645/// #[def_op("dialect.name")]
646/// #[format_op]
647/// struct MyOp;
648///
649/// #[op_interface]
650/// pub trait MyOpInterface {
651/// fn gubbi(&self);
652/// fn verify(op: &dyn Op, ctx: &Context) -> Result<()>
653/// where Self: Sized,
654/// {
655/// Ok(())
656/// }
657/// }
658///
659/// #[op_interface_impl]
660/// impl MyOpInterface for MyOp {
661/// fn gubbi(&self) { println!("gubbi"); }
662/// }
663/// # use pliron::{
664/// # op::Op, context::Context, result::Result, common_traits::Verify
665/// # };
666/// ```
667#[proc_macro_attribute]
668pub fn op_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
669 let interface_verifiers_slice = parse_quote! { ::pliron::op::OP_INTERFACE_VERIFIERS };
670 let all_verifiers_fn_type = parse_quote! { ::pliron::op::OpInterfaceAllVerifiers };
671 to_token_stream(interfaces::interface_impl(
672 item.into(),
673 interface_verifiers_slice,
674 all_verifiers_fn_type,
675 interfaces::RegisterBoxedCast::Skip,
676 interfaces::ImplsMarkerTrait::Skip,
677 ))
678}
679
680/// `#[pliron_type(...)]`: Unified macro for defining IR types.
681///
682/// This macro provides a simplified, unified syntax for defining IR types by expanding
683/// into the existing type definition macros. It supports the following configuration options:
684///
685/// - `name = "dialect.type_name"`: The fully qualified name of the type (required).\
686/// Expands to [def_type].
687/// - `format = "format_string"`: Custom format string for printing/parsing (optional).\
688/// Expands to [format_type].
689/// - `verifier = "succ"`: Verifier implementation, currently only "succ" is supported (optional).\
690/// Expands to [macro@verify_succ].
691/// - `generate_get = true/false`: Whether to generate a get method for the type (optional, default: false).\
692/// Expands to [derive_type_get].
693///
694/// ## Examples
695///
696/// ### Basic type definition:
697/// ```
698/// use pliron::derive::pliron_type;
699///
700/// #[pliron_type(name = "test.unit_type", format, verifier = "succ")]
701/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
702/// pub struct UnitType;
703/// ```
704///
705/// ### Type with custom format:
706/// ```
707/// use pliron::derive::pliron_type;
708///
709/// #[pliron_type(
710/// name = "test.flags_type",
711/// format = "`type` `{` $flags `}`",
712/// verifier = "succ"
713/// )]
714/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
715/// struct FlagsType {
716/// flags: u32,
717/// }
718/// ```
719///
720/// ### Type with get method generation:
721/// ```
722/// use pliron::derive::pliron_type;
723///
724/// #[pliron_type(
725/// name = "test.vector_type",
726/// generate_get = true,
727/// format,
728/// verifier = "succ"
729/// )]
730/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
731/// struct VectorType {
732/// elem_ty: u32,
733/// num_elems: u32,
734/// }
735/// ```
736#[proc_macro_attribute]
737pub fn pliron_type(args: TokenStream, input: TokenStream) -> TokenStream {
738 to_token_stream(derive_entity::pliron_type(args, input))
739}
740
741/// `#[pliron_attr(...)]`: Unified macro for defining IR attributes.
742///
743/// This macro provides a simplified, unified syntax for defining IR attributes by expanding
744/// into the existing attribute definition macros. It supports the following configuration options:
745///
746/// - `name = "dialect.attribute_name"`: The fully qualified name of the attribute (required).\
747/// Expands to [def_attribute].
748/// - `format = "format_string"`: Custom format string for printing/parsing (optional).\
749/// Expands to [format_attribute].
750/// - `verifier = "succ"`: Verifier implementation, currently only "succ" is supported (optional).\
751/// Expands to [macro@verify_succ].
752///
753/// ## Examples
754///
755/// ### Basic attribute definition:
756/// ```
757/// use pliron::derive::pliron_attr;
758///
759/// #[pliron_attr(name = "test.string_attr", format, verifier = "succ")]
760/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
761/// struct StringAttr {
762/// value: String,
763/// }
764/// ```
765///
766/// ### Attribute with custom format:
767/// ```
768/// use pliron::derive::pliron_attr;
769///
770/// #[pliron_attr(
771/// name = "test.string_attr",
772/// format = "`attr` `(` $value `)`",
773/// verifier = "succ"
774/// )]
775/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
776/// struct StringAttr {
777/// value: String,
778/// }
779/// ```
780#[proc_macro_attribute]
781pub fn pliron_attr(args: TokenStream, input: TokenStream) -> TokenStream {
782 to_token_stream(derive_entity::pliron_attr(args, input))
783}
784
785/// `#[pliron_op(...)]`: Unified macro for defining IR operations.
786///
787/// This macro provides a simplified, unified syntax for defining IR operations by expanding
788/// into the existing operation definition macros. It supports the following configuration options:
789///
790/// - `name = "dialect.op_name"`: The fully qualified name of the operation (required).\
791/// Expands to [def_op].
792/// - `format = "format_string"`: Custom format string for printing/parsing (optional).\
793/// Expands to [format_op].
794/// - `interfaces = [Interface1, Interface2, ...]`: List of interfaces to implement (optional).\
795/// Expands to [derive_op_interface_impl].
796/// - `attributes = (attr_name: AttrType, ...)`: List of attributes with their types (optional).\
797/// Expands to [derive_attr_get_set], generating getter and setter methods.
798/// - `operands = (name, name: Type, _, _: Type, ...)`: List of operand specs (optional).\
799/// Expands to [operands].
800/// - `results = (name, name: Type, _, _: Type, ...)`: List of result specs (optional).\
801/// Expands to [results].
802/// - `verifier = "succ"`: Verifier implementation, currently only "succ" is supported (optional).\
803/// Expands to [macro@verify_succ].
804///
805/// ## Examples
806///
807/// ### Basic operation definition:
808/// ```
809/// use pliron::derive::pliron_op;
810///
811/// #[pliron_op(name = "test.my_op", format, verifier = "succ")]
812/// struct MyOp;
813/// ```
814///
815/// ### Operation with custom format and interfaces:
816/// ```
817/// use pliron::derive::pliron_op;
818/// use pliron::builtin::op_interfaces::NRegionsInterface;
819///
820/// #[pliron_op(
821/// name = "test.if_op",
822/// format = "`(`$0`)` region($0)",
823/// interfaces = [ NRegionsInterface<1> ],
824/// verifier = "succ"
825/// )]
826/// struct IfOp;
827/// ```
828///
829/// ### Operation with specified attributes:
830/// ```
831/// use pliron::derive::pliron_op;
832/// use pliron::builtin::attributes::{UnitAttr, IntegerAttr};
833///
834/// #[pliron_op(
835/// name = "dialect.test",
836/// format,
837/// attributes = (attr1: UnitAttr, attr2: IntegerAttr),
838/// verifier = "succ"
839/// )]
840/// struct CallOp;
841/// ```
842///
843/// ### Operation with specified operands:
844/// ```
845/// use pliron::derive::pliron_op;
846/// use pliron::builtin::types::{IntegerType, UnitType};
847///
848/// #[pliron_op(
849/// name = "dialect.with_operands",
850/// format,
851/// operands = (lhs: IntegerType, _, rhs, _: UnitType),
852/// verifier = "succ"
853/// )]
854/// struct WithOperandsOp;
855/// ```
856///
857/// ### Operation with specified results:
858/// ```
859/// use pliron::derive::pliron_op;
860/// use pliron::builtin::types::{IntegerType, UnitType};
861///
862/// #[pliron_op(
863/// name = "dialect.with_results",
864/// format,
865/// results = (out: IntegerType, _: UnitType),
866/// verifier = "succ"
867/// )]
868/// struct WithResultsOp;
869/// ```
870#[proc_macro_attribute]
871pub fn pliron_op(args: TokenStream, input: TokenStream) -> TokenStream {
872 to_token_stream(derive_entity::pliron_op(args, input))
873}
874
875/// Derive implementation of an [Op](../pliron/op/trait.Op.html) Interface for an Op.
876/// Note that an impl can be derived only for those interfaces that do not require any
877/// methods to be defined during the impl.
878///
879/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
880/// The documention here is useful though, because [pliron_op]'s `interfaces` field
881/// expands to this macro.
882///
883/// Usage:
884/// ```
885/// # use pliron::derive::{derive_op_interface_impl, format_op, op_interface, verify_succ};
886///
887/// #[verify_succ]
888/// #[def_op("dialect.name")]
889/// #[format_op]
890/// #[derive_op_interface_impl(MyOpInterface)]
891/// struct MyOp;
892///
893/// #[op_interface]
894/// pub trait MyOpInterface {
895/// fn gubbi(&self) { println!("gubbi"); }
896/// fn verify(op: &dyn Op, ctx: &Context) -> Result<()>
897/// where Self: Sized,
898/// {
899/// Ok(())
900/// }
901/// }
902/// # use pliron::derive::def_op;
903/// # use pliron::{
904/// # op::Op, context::Context, result::Result,
905/// # common_traits::Verify
906/// # };
907/// ```
908#[proc_macro_attribute]
909pub fn derive_op_interface_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
910 to_token_stream(interfaces::derive_op_interface_impl(attr, item))
911}
912
913/// Declare an [Attribute](../pliron/attribute/trait.Attribute.html) interface,
914/// which can be implemented by any `Attribute`.
915///
916/// If the interface requires any other interface to be already implemented,
917/// they can be specified super-traits.
918///
919/// When an `Attribute` is verified, its interfaces are also automatically verified,
920/// with guarantee that a super-interface is verified before an interface itself is.
921///
922/// Example: Here `Super1` and `Super2` are super interfaces for the interface `MyAttrIntr`.
923/// ```
924/// # use pliron::{attribute::Attribute, context::Context, result::Result};
925/// use pliron::derive::attr_interface;
926///
927/// #[attr_interface]
928/// trait Super1 {
929/// fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
930/// where
931/// Self: Sized,
932/// {
933/// Ok(())
934/// }
935/// }
936///
937/// #[attr_interface]
938/// trait Super2 {
939/// fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
940/// where
941/// Self: Sized,
942/// {
943/// Ok(())
944/// }
945/// }
946///
947/// // MyAttrIntr is my best attribute interface.
948/// #[attr_interface]
949/// trait MyAttrIntr: Super1 + Super2 {
950/// fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
951/// where
952/// Self: Sized,
953/// {
954/// Ok(())
955/// }
956/// }
957/// ```
958#[proc_macro_attribute]
959pub fn attr_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
960 let supertrait = parse_quote! { ::pliron::attribute::Attribute };
961 let verifier_type = parse_quote! { ::pliron::attribute::AttrInterfaceVerifier };
962 let target_marker_trait = parse_quote! { ::pliron::attribute::AttrInterfaceMarker };
963
964 let define = interfaces::interface_define(
965 item.clone(),
966 supertrait,
967 verifier_type,
968 true,
969 target_marker_trait,
970 );
971
972 // Implement common traits for `dyn Interface` that we already implement for `AttrObj`.
973 let obj_traits = interfaces::attr_interface_obj_traits(item);
974
975 to_token_stream(define.and_then(|mut output| {
976 output.extend(obj_traits?);
977 Ok(output)
978 }))
979}
980
981/// Implement [Attribute](../pliron/attribute/trait.Attribute.html) Interface for an Attribute.
982/// The interface trait must define a `verify` function with type
983/// [AttrInterfaceVerifier](../pliron/attribute/type.AttrInterfaceVerifier.html).
984///
985/// Usage:
986/// ```
987/// use pliron::derive::{attr_interface, attr_interface_impl, def_attribute, format_attribute, verify_succ};
988///
989/// #[verify_succ]
990/// #[def_attribute("dialect.name")]
991/// #[format_attribute]
992/// #[derive(PartialEq, Eq, Clone, Debug, Hash)]
993/// struct MyAttr { }
994///
995/// /// My first attribute interface.
996/// #[attr_interface]
997/// trait MyAttrInterface {
998/// fn monu(&self);
999/// fn verify(attr: &dyn Attribute, ctx: &Context) -> Result<()>
1000/// where Self: Sized,
1001/// {
1002/// Ok(())
1003/// }
1004/// }
1005///
1006/// #[attr_interface_impl]
1007/// impl MyAttrInterface for MyAttr
1008/// {
1009/// fn monu(&self) { println!("monu"); }
1010/// }
1011/// # use pliron::{
1012/// # printable::{self, Printable},
1013/// # context::Context, result::Result, common_traits::Verify,
1014/// # attribute::Attribute
1015/// # };
1016#[proc_macro_attribute]
1017pub fn attr_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
1018 let interface_verifiers_slice = parse_quote! { ::pliron::attribute::ATTR_INTERFACE_VERIFIERS };
1019 let all_verifiers_fn_type = parse_quote! { ::pliron::attribute::AttrInterfaceAllVerifiers };
1020 to_token_stream(interfaces::interface_impl(
1021 item.into(),
1022 interface_verifiers_slice,
1023 all_verifiers_fn_type,
1024 interfaces::RegisterBoxedCast::Register,
1025 interfaces::ImplsMarkerTrait::Skip,
1026 ))
1027}
1028
1029/// Declare a [Type](../pliron/type/trait.Type.html) interface,
1030/// which can be implemented by any `Type`.
1031///
1032/// If the interface requires any other interface to be already implemented,
1033/// they can be specified super-traits.
1034///
1035/// When an `Attribute` is verified, its interfaces are also automatically verified,
1036/// with guarantee that a super-interface is verified before an interface itself is.
1037///
1038/// Example: Here `Super1` and `Super2` are super interfaces for the interface `MyTypeIntr`.
1039/// ```
1040/// use pliron::derive::type_interface;
1041/// # use pliron::{r#type::Type, context::Context, result::Result};
1042/// #[type_interface]
1043/// trait Super1 {
1044/// fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
1045/// where
1046/// Self: Sized,
1047/// {
1048/// Ok(())
1049/// }
1050/// }
1051///
1052/// #[type_interface]
1053/// trait Super2 {
1054/// fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
1055/// where
1056/// Self: Sized,
1057/// {
1058/// Ok(())
1059/// }
1060/// }
1061///
1062/// #[type_interface]
1063/// // MyTypeIntr is my best type interface.
1064/// trait MyTypeIntr: Super1 + Super2 {
1065/// fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
1066/// where
1067/// Self: Sized,
1068/// {
1069/// Ok(())
1070/// }
1071/// }
1072/// ```
1073#[proc_macro_attribute]
1074pub fn type_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
1075 let supertrait = parse_quote! { ::pliron::r#type::Type };
1076 let verifier_type = parse_quote! { ::pliron::r#type::TypeInterfaceVerifier };
1077 let target_marker_trait = parse_quote! { ::pliron::r#type::TypeInterfaceMarker };
1078
1079 to_token_stream(interfaces::interface_define(
1080 item,
1081 supertrait,
1082 verifier_type,
1083 false,
1084 target_marker_trait,
1085 ))
1086}
1087
1088/// Implement [Type](../pliron/type/trait.Type.html) Interface for a Type.
1089/// The interface trait must define a `verify` function with type
1090/// [TypeInterfaceVerifier](../pliron/type/type.TypeInterfaceVerifier.html).
1091///
1092/// Usage:
1093/// ```
1094/// use pliron::derive::{def_type, format_type, type_interface, type_interface_impl, verify_succ};
1095///
1096/// #[verify_succ]
1097/// #[def_type("dialect.name")]
1098/// #[format_type]
1099/// #[derive(PartialEq, Eq, Clone, Debug, Hash)]
1100/// struct MyType { }
1101///
1102/// #[type_interface]
1103/// /// My first type interface.
1104/// trait MyTypeInterface {
1105/// fn monu(&self);
1106/// fn verify(r#type: &dyn Type, ctx: &Context) -> Result<()>
1107/// where Self: Sized,
1108/// {
1109/// Ok(())
1110/// }
1111/// }
1112///
1113/// #[type_interface_impl]
1114/// impl MyTypeInterface for MyType
1115/// {
1116/// fn monu(&self) { println!("monu"); }
1117/// }
1118/// # use pliron::{
1119/// # printable::{self, Printable},
1120/// # context::Context, result::Result, common_traits::Verify,
1121/// # r#type::Type
1122/// # };
1123#[proc_macro_attribute]
1124pub fn type_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
1125 let interface_verifiers_slice = parse_quote! { ::pliron::r#type::TYPE_INTERFACE_VERIFIERS };
1126 let all_verifiers_fn_type = parse_quote! { ::pliron::r#type::TypeInterfaceAllVerifiers };
1127 let impls_marker_trait = parse_quote! { ::pliron::r#type::TypeImplsInterface };
1128 to_token_stream(interfaces::interface_impl(
1129 item.into(),
1130 interface_verifiers_slice,
1131 all_verifiers_fn_type,
1132 interfaces::RegisterBoxedCast::Skip,
1133 interfaces::ImplsMarkerTrait::Implement(impls_marker_trait),
1134 ))
1135}
1136
1137/// Implement [StableHash](../pliron/irbuild/decontext/trait.StableHash.html)
1138/// for a struct or enum, assuming every field's type already implements it.
1139/// For an enum, the matched variant's discriminant is also mixed into the hash.
1140///
1141/// This also registers the impl with [type_to_trait!](../pliron/macro.type_to_trait.html).
1142///
1143/// Usage:
1144///
1145/// ```
1146/// use pliron::{derive::StableHash, r#type::TypeHandle};
1147///
1148/// #[derive(StableHash)]
1149/// struct MyAttr {
1150/// ty: TypeHandle,
1151/// val: u64,
1152/// }
1153/// ```
1154///
1155/// This fails to compile because `NotHashable` doesn't implement `StableHash`:
1156/// ```compile_fail
1157/// use pliron::derive::StableHash;
1158///
1159/// struct NotHashable;
1160///
1161/// #[derive(StableHash)]
1162/// struct MyAttr {
1163/// val: NotHashable,
1164/// }
1165/// ```
1166#[proc_macro_derive(StableHash)]
1167pub fn stable_hash(input: TokenStream) -> TokenStream {
1168 to_token_stream(derive_decontext::derive_stable_hash(input.into()))
1169}
1170
1171/// Implement [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html)
1172/// for a struct or enum, assuming every field's type already implements it. For an enum,
1173/// the matched variant is reconstructed with its (cloned) fields.
1174///
1175/// Usage:
1176///
1177/// ```
1178/// use pliron::{derive::CloneIntoContext, r#type::TypeHandle};
1179///
1180/// #[derive(CloneIntoContext)]
1181/// struct MyAttr {
1182/// ty: TypeHandle,
1183/// val: u64,
1184/// }
1185/// ```
1186///
1187/// A generic struct, with the field's bound written explicitly:
1188/// ```
1189/// use pliron::{
1190/// context::Context, derive::CloneIntoContext,
1191/// irbuild::decontext::CloneIntoContext as CloneIntoContextTrait,
1192/// };
1193///
1194/// #[derive(CloneIntoContext)]
1195/// struct Wrapper<T: CloneIntoContextTrait> {
1196/// inner: T,
1197/// }
1198///
1199/// let src_ctx = Context::new();
1200/// let mut dst_ctx = Context::new();
1201/// let cloned = Wrapper { inner: 42u64 }.clone_into_context(&src_ctx, &mut dst_ctx);
1202/// assert_eq!(cloned.inner, 42);
1203/// ```
1204///
1205/// This fails to compile because `NotCloneable` doesn't implement `CloneIntoContext`:
1206/// ```compile_fail
1207/// use pliron::derive::CloneIntoContext;
1208///
1209/// struct NotCloneable;
1210///
1211/// #[derive(CloneIntoContext)]
1212/// struct MyAttr {
1213/// val: NotCloneable,
1214/// }
1215/// ```
1216#[proc_macro_derive(CloneIntoContext)]
1217pub fn clone_into_context(input: TokenStream) -> TokenStream {
1218 to_token_stream(derive_decontext::derive_clone_into_context(input.into()))
1219}
1220
1221/// Implement [CloneAttributeIntoContext](../pliron/irbuild/decontext/trait.CloneAttributeIntoContext.html)
1222/// for an [Attribute](../pliron/attribute/trait.Attribute.html) by delegating to its own
1223/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) impl and boxing the result.
1224///
1225/// The type must already implement
1226/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) (e.g. via
1227/// [`#[derive(CloneIntoContext)]`](derive@CloneIntoContext),
1228/// or [`impl_clone_into_context_for_clone!`](../pliron/macro.impl_clone_into_context_for_clone.html)).
1229///
1230/// Usage:
1231///
1232/// ```
1233/// use pliron::{
1234/// attribute::AttrObj, context::Context,
1235/// derive::{CloneAttributeIntoContext, CloneIntoContext, pliron_attr},
1236/// irbuild::decontext::CloneIntoContext as _, printable::Printable,
1237/// };
1238///
1239/// #[pliron_attr(name = "test.point_attr", format = "`<` $x `>`", verifier = "succ")]
1240/// #[derive(Debug, Clone, PartialEq, Eq, Hash, CloneIntoContext, CloneAttributeIntoContext)]
1241/// struct PointAttr {
1242/// x: i32,
1243/// }
1244///
1245/// let src_ctx = Context::new();
1246/// let mut dst_ctx = Context::new();
1247/// let a: AttrObj = Box::new(PointAttr { x: 1 });
1248/// let a2 = a.clone_into_context(&src_ctx, &mut dst_ctx);
1249/// assert_eq!(a.disp(&src_ctx).to_string(), a2.disp(&dst_ctx).to_string());
1250/// ```
1251#[proc_macro_derive(CloneAttributeIntoContext)]
1252pub fn clone_attribute_into_context(input: TokenStream) -> TokenStream {
1253 to_token_stream(derive_decontext::derive_clone_attribute_into_context(
1254 input.into(),
1255 ))
1256}
1257
1258/// Implement [CloneTypeIntoContext](../pliron/irbuild/decontext/trait.CloneTypeIntoContext.html)
1259/// for a [Type](../pliron/type/trait.Type.html) by delegating to its own
1260/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) impl,
1261/// then re-interning the clone into `dst_ctx`.
1262///
1263/// The type must already implement
1264/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) (e.g. via
1265/// [`#[derive(CloneIntoContext)]`](derive@CloneIntoContext),
1266/// or [`impl_clone_into_context_for_clone!`](../pliron/macro.impl_clone_into_context_for_clone.html)).
1267///
1268/// Usage:
1269///
1270/// ```
1271/// use pliron::{
1272/// context::Context,
1273/// derive::{CloneIntoContext, CloneTypeIntoContext, pliron_type},
1274/// irbuild::decontext::CloneIntoContext as _, printable::Printable,
1275/// };
1276///
1277/// #[pliron_type(
1278/// name = "test.point_type",
1279/// format = "`<` $x `>`",
1280/// generate_get = true,
1281/// verifier = "succ"
1282/// )]
1283/// #[derive(Debug, Clone, PartialEq, Eq, Hash, CloneIntoContext, CloneTypeIntoContext)]
1284/// struct PointType {
1285/// x: i32,
1286/// }
1287///
1288/// let src_ctx = Context::new();
1289/// let mut dst_ctx = Context::new();
1290/// let p = PointType::get(&src_ctx, 1).to_handle();
1291/// let p2 = p.clone_into_context(&src_ctx, &mut dst_ctx);
1292/// assert_eq!(p.disp(&src_ctx).to_string(), p2.disp(&dst_ctx).to_string());
1293/// ```
1294#[proc_macro_derive(CloneTypeIntoContext)]
1295pub fn clone_type_into_context(input: TokenStream) -> TokenStream {
1296 to_token_stream(derive_decontext::derive_clone_type_into_context(
1297 input.into(),
1298 ))
1299}