Skip to main content

melior_macro/dialect/operation/
operand.rs

1use super::{OperationElement, OperationField, VariadicKind};
2use crate::dialect::{
3    error::Error,
4    r#type::Type as ElementType,
5    utility::{generate_iterator_type, generate_result_type, sanitize_snake_case_identifier},
6};
7use proc_macro2::{Ident, TokenStream};
8use quote::{format_ident, quote};
9use syn::{parse_quote, Type};
10
11#[derive(Debug)]
12pub struct Operand<'a> {
13    name: &'a str,
14    singular_identifier: Ident,
15    r#type: ElementType,
16    variadic_kind: VariadicKind,
17}
18
19impl<'a> Operand<'a> {
20    pub fn new(
21        name: &'a str,
22        r#type: ElementType,
23        variadic_kind: VariadicKind,
24    ) -> Result<Self, Error> {
25        Ok(Self {
26            name,
27            singular_identifier: sanitize_snake_case_identifier(name)?,
28            r#type,
29            variadic_kind,
30        })
31    }
32}
33
34impl OperationField for Operand<'_> {
35    fn name(&self) -> &str {
36        self.name
37    }
38
39    fn singular_identifier(&self) -> &Ident {
40        &self.singular_identifier
41    }
42
43    fn plural_kind_identifier(&self) -> Ident {
44        format_ident!("operands")
45    }
46
47    fn parameter_type(&self) -> Type {
48        let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>);
49
50        if self.r#type.is_variadic() {
51            parse_quote! { &[#r#type] }
52        } else {
53            r#type
54        }
55    }
56
57    fn return_type(&self) -> Type {
58        let r#type: Type = parse_quote!(::melior::ir::Value<'c, '_>);
59
60        if !self.r#type.is_variadic() {
61            generate_result_type(r#type)
62        } else if self.variadic_kind == VariadicKind::AttributeSized {
63            generate_result_type(generate_iterator_type(r#type))
64        } else {
65            generate_iterator_type(r#type)
66        }
67    }
68
69    fn is_optional(&self) -> bool {
70        self.r#type.is_optional()
71    }
72
73    fn add_arguments(&self, name: &Ident) -> TokenStream {
74        if self.r#type.is_variadic() {
75            quote! { #name }
76        } else {
77            quote! { &[#name] }
78        }
79    }
80}
81
82impl OperationElement for Operand<'_> {
83    fn is_variadic(&self) -> bool {
84        self.r#type.is_variadic()
85    }
86
87    fn variadic_kind(&self) -> &VariadicKind {
88        &self.variadic_kind
89    }
90}