etk_asm/ops/
macros.rs

1use super::{AbstractOp, Expression, Imm};
2use std::convert::From;
3use std::fmt;
4
5/// Macro definition.
6#[derive(Debug, Clone, Eq, PartialEq)]
7pub enum MacroDefinition {
8    /// Instruction macro definition.
9    Instruction(InstructionMacroDefinition),
10
11    /// Expression macro definition.
12    Expression(ExpressionMacroDefinition),
13}
14
15impl MacroDefinition {
16    /// Returns the name of the defined macro.
17    pub fn name(&self) -> &String {
18        match self {
19            Self::Instruction(m) => &m.name,
20            Self::Expression(m) => &m.name,
21        }
22    }
23
24    /// Returns the specified parameters of the defined macro.
25    pub fn parameters(&self) -> &[String] {
26        match self {
27            Self::Instruction(m) => &m.parameters,
28            Self::Expression(m) => &m.parameters,
29        }
30    }
31
32    /// Unwraps an `ExpressionMacroDefinition` from a `MacroDefinition`.
33    pub fn unwrap_expression(&self) -> &ExpressionMacroDefinition {
34        match self {
35            Self::Instruction(_) => {
36                panic!("unwrapped expression macro, but found instruction macro")
37            }
38            Self::Expression(m) => m,
39        }
40    }
41}
42
43impl fmt::Display for MacroDefinition {
44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45        match self {
46            Self::Instruction(m) => write!(f, "%{}({})", m.name, m.parameters.join(", ")),
47            Self::Expression(m) => write!(f, "{}({})", m.name, m.parameters.join(", ")),
48        }
49    }
50}
51
52impl From<InstructionMacroDefinition> for MacroDefinition {
53    fn from(item: InstructionMacroDefinition) -> Self {
54        MacroDefinition::Instruction(item)
55    }
56}
57
58impl From<ExpressionMacroDefinition> for MacroDefinition {
59    fn from(item: ExpressionMacroDefinition) -> Self {
60        MacroDefinition::Expression(item)
61    }
62}
63
64/// Instruction macro definition op fields.
65#[derive(Debug, Default, Clone, Eq, PartialEq)]
66pub struct InstructionMacroDefinition {
67    /// The name that identifies the macro.
68    pub name: String,
69    /// The name identifiers for the macro's parameters.
70    pub parameters: Vec<String>,
71    /// The body of the macro.
72    pub contents: Vec<AbstractOp>,
73}
74
75/// Instruction macro invocation op.
76#[derive(Debug, Clone, Eq, PartialEq)]
77pub struct InstructionMacroInvocation {
78    /// The name of the macro being invoked.
79    pub name: String,
80    /// The parameters that are being passed into the invocation.
81    pub parameters: Vec<Expression>,
82}
83
84impl InstructionMacroInvocation {
85    /// Construct an instruction macro invocation with zero parameters.
86    pub fn with_zero_parameters(name: String) -> Self {
87        Self {
88            name,
89            parameters: vec![],
90        }
91    }
92}
93
94impl fmt::Display for InstructionMacroInvocation {
95    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96        write!(
97            f,
98            "%{}({})",
99            self.name,
100            self.parameters
101                .iter()
102                .map(Expression::to_string)
103                .collect::<Vec<String>>()
104                .join(", ")
105        )
106    }
107}
108
109/// Expression macro definition op fields.
110#[derive(Debug, Clone, Eq, PartialEq)]
111pub struct ExpressionMacroDefinition {
112    /// The name that identifies the macro.
113    pub name: String,
114    /// The name identifiers for the macro's parameters.
115    pub parameters: Vec<String>,
116    /// The body of the macro.
117    pub content: Imm,
118}
119
120/// Expression macro invocation imm.
121#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
122pub struct ExpressionMacroInvocation {
123    /// The name of the macro being invoked.
124    pub name: String,
125    /// The parameters that are being passed into the invocation.
126    pub parameters: Vec<Expression>,
127}
128
129impl fmt::Display for ExpressionMacroInvocation {
130    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131        write!(
132            f,
133            "{}({})",
134            self.name,
135            self.parameters
136                .iter()
137                .map(Expression::to_string)
138                .collect::<Vec<String>>()
139                .join(", ")
140        )
141    }
142}