[meta] Introduce the InstructionGroupBuilder;

This follows the rest of the code base data structures, where we have a
mutable data structure builder; once the data structure is constructed,
it's immutable.

This also makes the definition of instructions easier, and it paves the
way for defining immediate variants.
This commit is contained in:
Benjamin Bouvier
2019-04-30 18:33:01 +02:00
parent feb90e376a
commit d9277f249b
7 changed files with 251 additions and 382 deletions

View File

@@ -12,6 +12,40 @@ use std::ops;
use std::rc::Rc;
use std::slice;
pub struct InstructionGroupBuilder<'format_reg> {
_name: &'static str,
_doc: &'static str,
format_registry: &'format_reg FormatRegistry,
instructions: Vec<Instruction>,
}
impl<'format_reg> InstructionGroupBuilder<'format_reg> {
pub fn new(
name: &'static str,
doc: &'static str,
format_registry: &'format_reg FormatRegistry,
) -> Self {
Self {
_name: name,
_doc: doc,
format_registry,
instructions: Vec::new(),
}
}
pub fn push(&mut self, builder: InstructionBuilder) {
self.instructions.push(builder.finish(self.format_registry));
}
pub fn finish(self) -> InstructionGroup {
InstructionGroup {
_name: self._name,
_doc: self._doc,
instructions: self.instructions,
}
}
}
/// Every instruction must belong to exactly one instruction group. A given
/// target architecture can support instructions from multiple groups, and it
/// does not necessarily support all instructions in a group.
@@ -22,18 +56,6 @@ pub struct InstructionGroup {
}
impl InstructionGroup {
pub fn new(name: &'static str, doc: &'static str) -> Self {
Self {
_name: name,
_doc: doc,
instructions: Vec::new(),
}
}
pub fn push(&mut self, inst: Instruction) {
self.instructions.push(inst);
}
pub fn iter(&self) -> slice::Iter<Instruction> {
self.instructions.iter()
}
@@ -278,7 +300,7 @@ impl InstructionBuilder {
self
}
pub fn finish(self, format_registry: &FormatRegistry) -> Instruction {
fn finish(self, format_registry: &FormatRegistry) -> Instruction {
let operands_in = self.operands_in.unwrap_or_else(Vec::new);
let operands_out = self.operands_out.unwrap_or_else(Vec::new);