[meta] Delegate finding the default value to OperandKind instead of its builder.
This applies both to the default_member value (which is now determined at runtime, instead of pre-computed) and the rust_type value (which is determined in the Operand's ctor, instead of the builder).
This commit is contained in:
@@ -95,7 +95,7 @@ impl EncodingBuilder {
|
|||||||
&inst.inst.format,
|
&inst.inst.format,
|
||||||
immediate_operand
|
immediate_operand
|
||||||
.kind
|
.kind
|
||||||
.default_member
|
.default_member()
|
||||||
.expect("Immediates must always have a default member name set."),
|
.expect("Immediates must always have a default member name set."),
|
||||||
immediate_value.to_string(),
|
immediate_value.to_string(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ impl InstructionFormatBuilder {
|
|||||||
pub fn imm(mut self, operand_kind: &OperandKind) -> Self {
|
pub fn imm(mut self, operand_kind: &OperandKind) -> Self {
|
||||||
let field = FormatField {
|
let field = FormatField {
|
||||||
kind: operand_kind.clone(),
|
kind: operand_kind.clone(),
|
||||||
member: operand_kind.default_member.unwrap(),
|
member: operand_kind.default_member().unwrap(),
|
||||||
};
|
};
|
||||||
self.imm_fields.push(field);
|
self.imm_fields.push(field);
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -111,18 +111,55 @@ pub(crate) enum OperandKindFields {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct OperandKind {
|
pub(crate) struct OperandKind {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
|
doc: Option<&'static str>,
|
||||||
doc: Option<String>,
|
default_member: Option<&'static str>,
|
||||||
|
|
||||||
pub default_member: Option<&'static str>,
|
|
||||||
|
|
||||||
/// The camel-cased name of an operand kind is also the Rust type used to represent it.
|
/// The camel-cased name of an operand kind is also the Rust type used to represent it.
|
||||||
pub rust_type: String,
|
pub rust_type: String,
|
||||||
|
|
||||||
pub fields: OperandKindFields,
|
pub fields: OperandKindFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OperandKind {
|
impl OperandKind {
|
||||||
|
fn new(
|
||||||
|
name: &'static str,
|
||||||
|
doc: Option<&'static str>,
|
||||||
|
default_member: Option<&'static str>,
|
||||||
|
rust_type: Option<&'static str>,
|
||||||
|
fields: OperandKindFields,
|
||||||
|
) -> Self {
|
||||||
|
// Compute the default rust_type value, if it wasn't provided.
|
||||||
|
let rust_type = match rust_type {
|
||||||
|
Some(rust_type) => rust_type.to_string(),
|
||||||
|
None => match &fields {
|
||||||
|
OperandKindFields::ImmEnum(_) | OperandKindFields::ImmValue => {
|
||||||
|
format!("ir::immediates::{}", camel_case(name))
|
||||||
|
}
|
||||||
|
OperandKindFields::VariableArgs => "&[Value]".to_string(),
|
||||||
|
OperandKindFields::TypeVar(_) | OperandKindFields::EntityRef => {
|
||||||
|
format!("ir::{}", camel_case(name))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
doc,
|
||||||
|
default_member,
|
||||||
|
rust_type,
|
||||||
|
fields,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Name of this OperandKind in the format's member field.
|
||||||
|
pub fn default_member(&self) -> Option<&'static str> {
|
||||||
|
if let Some(member) = &self.default_member {
|
||||||
|
return Some(member);
|
||||||
|
}
|
||||||
|
match &self.fields {
|
||||||
|
OperandKindFields::ImmEnum(_) | OperandKindFields::ImmValue => Some("imm"),
|
||||||
|
OperandKindFields::TypeVar(_) | OperandKindFields::EntityRef => Some(self.name),
|
||||||
|
OperandKindFields::VariableArgs => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn doc(&self) -> Option<&str> {
|
fn doc(&self) -> Option<&str> {
|
||||||
if let Some(doc) = &self.doc {
|
if let Some(doc) = &self.doc {
|
||||||
return Some(doc);
|
return Some(doc);
|
||||||
@@ -146,16 +183,22 @@ impl OperandKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<OperandKind> for &TypeVar {
|
||||||
|
fn into(self) -> OperandKind {
|
||||||
|
OperandKindBuilder::new("value", OperandKindFields::TypeVar(self.into())).build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Into<OperandKind> for &OperandKind {
|
||||||
|
fn into(self) -> OperandKind {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct OperandKindBuilder {
|
pub(crate) struct OperandKindBuilder {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
|
doc: Option<&'static str>,
|
||||||
doc: Option<String>,
|
|
||||||
|
|
||||||
default_member: Option<&'static str>,
|
default_member: Option<&'static str>,
|
||||||
|
rust_type: Option<&'static str>,
|
||||||
/// The camel-cased name of an operand kind is also the Rust type used to represent it.
|
|
||||||
rust_type: Option<String>,
|
|
||||||
|
|
||||||
fields: OperandKindFields,
|
fields: OperandKindFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +212,6 @@ impl OperandKindBuilder {
|
|||||||
fields,
|
fields,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_imm(name: &'static str) -> Self {
|
pub fn new_imm(name: &'static str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
@@ -179,7 +221,6 @@ impl OperandKindBuilder {
|
|||||||
fields: OperandKindFields::ImmValue,
|
fields: OperandKindFields::ImmValue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_enum(name: &'static str, values: EnumValues) -> Self {
|
pub fn new_enum(name: &'static str, values: EnumValues) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
@@ -189,10 +230,9 @@ impl OperandKindBuilder {
|
|||||||
fields: OperandKindFields::ImmEnum(values),
|
fields: OperandKindFields::ImmEnum(values),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn doc(mut self, doc: &'static str) -> Self {
|
pub fn doc(mut self, doc: &'static str) -> Self {
|
||||||
assert!(self.doc.is_none());
|
assert!(self.doc.is_none());
|
||||||
self.doc = Some(doc.to_string());
|
self.doc = Some(doc);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn default_member(mut self, default_member: &'static str) -> Self {
|
pub fn default_member(mut self, default_member: &'static str) -> Self {
|
||||||
@@ -202,50 +242,16 @@ impl OperandKindBuilder {
|
|||||||
}
|
}
|
||||||
pub fn rust_type(mut self, rust_type: &'static str) -> Self {
|
pub fn rust_type(mut self, rust_type: &'static str) -> Self {
|
||||||
assert!(self.rust_type.is_none());
|
assert!(self.rust_type.is_none());
|
||||||
self.rust_type = Some(rust_type.to_string());
|
self.rust_type = Some(rust_type);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> OperandKind {
|
pub fn build(self) -> OperandKind {
|
||||||
let default_member = match self.default_member {
|
OperandKind::new(
|
||||||
Some(default_member) => Some(default_member),
|
self.name,
|
||||||
None => match &self.fields {
|
self.doc,
|
||||||
OperandKindFields::ImmEnum(_) | OperandKindFields::ImmValue => Some("imm"),
|
self.default_member,
|
||||||
OperandKindFields::TypeVar(_) | OperandKindFields::EntityRef => Some(self.name),
|
self.rust_type,
|
||||||
OperandKindFields::VariableArgs => None,
|
self.fields,
|
||||||
},
|
)
|
||||||
};
|
|
||||||
|
|
||||||
let rust_type = match self.rust_type {
|
|
||||||
Some(rust_type) => rust_type.to_string(),
|
|
||||||
None => match &self.fields {
|
|
||||||
OperandKindFields::ImmEnum(_) | OperandKindFields::ImmValue => {
|
|
||||||
format!("ir::immediates::{}", camel_case(self.name))
|
|
||||||
}
|
|
||||||
OperandKindFields::VariableArgs => "&[Value]".to_string(),
|
|
||||||
OperandKindFields::TypeVar(_) | OperandKindFields::EntityRef => {
|
|
||||||
format!("ir::{}", camel_case(self.name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
OperandKind {
|
|
||||||
name: self.name,
|
|
||||||
doc: self.doc,
|
|
||||||
default_member,
|
|
||||||
rust_type,
|
|
||||||
fields: self.fields,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<OperandKind> for &TypeVar {
|
|
||||||
fn into(self) -> OperandKind {
|
|
||||||
OperandKindBuilder::new("value", OperandKindFields::TypeVar(self.into())).build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Into<OperandKind> for &OperandKind {
|
|
||||||
fn into(self) -> OperandKind {
|
|
||||||
self.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user