[meta] Refactor instruction predicates to distinguish format and type checks;
Also add the instruction format name in format predicates, since they're going to be used when generating encodings.
This commit is contained in:
@@ -449,6 +449,7 @@ impl Apply {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pred = pred.and(InstructionPredicate::new_is_field_equal(
|
pred = pred.and(InstructionPredicate::new_is_field_equal(
|
||||||
|
iform.name,
|
||||||
&format_field,
|
&format_field,
|
||||||
arg.to_rust_code(var_pool),
|
arg.to_rust_code(var_pool),
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -551,12 +551,39 @@ fn verify_ctrl_typevar(
|
|||||||
Ok(other_typevars)
|
Ok(other_typevars)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A basic node in an instruction predicate: either an atom, or an AND of two conditions.
|
pub enum FormatPredicateKind {
|
||||||
pub enum InstructionPredicateNode {
|
/// Is the field member equal to the expected value (stored here)?
|
||||||
/// Is the field member (first member) equal to the actual argument (which name is the second
|
IsEqual(String),
|
||||||
/// field)?
|
}
|
||||||
IsFieldEqual(String, String),
|
|
||||||
|
|
||||||
|
pub struct FormatPredicateNode {
|
||||||
|
_format_name: &'static str,
|
||||||
|
field_name: &'static str,
|
||||||
|
kind: FormatPredicateKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatPredicateNode {
|
||||||
|
fn new(
|
||||||
|
_format_name: &'static str,
|
||||||
|
field_name: &'static str,
|
||||||
|
kind: FormatPredicateKind,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
_format_name,
|
||||||
|
field_name,
|
||||||
|
kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn rust_predicate(&self) -> String {
|
||||||
|
match &self.kind {
|
||||||
|
FormatPredicateKind::IsEqual(arg) => {
|
||||||
|
format!("crate::predicates::is_equal({}, {})", self.field_name, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum TypePredicateNode {
|
||||||
/// Is the value argument (at the index designated by the first member) the same type as the
|
/// Is the value argument (at the index designated by the first member) the same type as the
|
||||||
/// type name (second member)?
|
/// type name (second member)?
|
||||||
TypeVarCheck(usize, String),
|
TypeVarCheck(usize, String),
|
||||||
@@ -564,6 +591,27 @@ pub enum InstructionPredicateNode {
|
|||||||
/// Is the controlling type variable the same type as the one designated by the type name
|
/// Is the controlling type variable the same type as the one designated by the type name
|
||||||
/// (only member)?
|
/// (only member)?
|
||||||
CtrlTypeVarCheck(String),
|
CtrlTypeVarCheck(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypePredicateNode {
|
||||||
|
fn rust_predicate(&self) -> String {
|
||||||
|
match self {
|
||||||
|
TypePredicateNode::TypeVarCheck(index, value_type_name) => format!(
|
||||||
|
"func.dfg.value_type(args[{}]) == {}",
|
||||||
|
index, value_type_name
|
||||||
|
),
|
||||||
|
TypePredicateNode::CtrlTypeVarCheck(value_type_name) => {
|
||||||
|
format!("func.dfg.ctrl_typevar(inst) == {}", value_type_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A basic node in an instruction predicate: either an atom, or an AND of two conditions.
|
||||||
|
pub enum InstructionPredicateNode {
|
||||||
|
FormatPredicate(FormatPredicateNode),
|
||||||
|
|
||||||
|
TypePredicate(TypePredicateNode),
|
||||||
|
|
||||||
/// A combination of two other predicates.
|
/// A combination of two other predicates.
|
||||||
And(Vec<InstructionPredicateNode>),
|
And(Vec<InstructionPredicateNode>),
|
||||||
@@ -572,17 +620,8 @@ pub enum InstructionPredicateNode {
|
|||||||
impl InstructionPredicateNode {
|
impl InstructionPredicateNode {
|
||||||
fn rust_predicate(&self) -> String {
|
fn rust_predicate(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
InstructionPredicateNode::IsFieldEqual(field_name, arg) => {
|
InstructionPredicateNode::FormatPredicate(node) => node.rust_predicate(),
|
||||||
let new_args = vec![field_name.clone(), arg.clone()];
|
InstructionPredicateNode::TypePredicate(node) => node.rust_predicate(),
|
||||||
format!("crate::predicates::is_equal({})", new_args.join(", "))
|
|
||||||
}
|
|
||||||
InstructionPredicateNode::TypeVarCheck(index, value_type_name) => format!(
|
|
||||||
"func.dfg.value_type(args[{}]) == {}",
|
|
||||||
index, value_type_name
|
|
||||||
),
|
|
||||||
InstructionPredicateNode::CtrlTypeVarCheck(value_type_name) => {
|
|
||||||
format!("func.dfg.ctrl_typevar(inst) == {}", value_type_name)
|
|
||||||
}
|
|
||||||
InstructionPredicateNode::And(nodes) => nodes
|
InstructionPredicateNode::And(nodes) => nodes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.rust_predicate())
|
.map(|x| x.rust_predicate())
|
||||||
@@ -614,18 +653,28 @@ impl InstructionPredicate {
|
|||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
InstructionPredicateNode::TypeVarCheck(index, value_type.rust_name())
|
InstructionPredicateNode::TypePredicate(TypePredicateNode::TypeVarCheck(
|
||||||
|
index,
|
||||||
|
value_type.rust_name(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_is_field_equal(
|
pub fn new_is_field_equal(
|
||||||
|
format_name: &'static str,
|
||||||
format_field: &FormatField,
|
format_field: &FormatField,
|
||||||
imm_value: String,
|
imm_value: String,
|
||||||
) -> InstructionPredicateNode {
|
) -> InstructionPredicateNode {
|
||||||
InstructionPredicateNode::IsFieldEqual(format_field.member.into(), imm_value)
|
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
|
||||||
|
format_name,
|
||||||
|
format_field.member,
|
||||||
|
FormatPredicateKind::IsEqual(imm_value),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_ctrl_typevar_check(value_type: &ValueType) -> InstructionPredicateNode {
|
pub fn new_ctrl_typevar_check(value_type: &ValueType) -> InstructionPredicateNode {
|
||||||
InstructionPredicateNode::CtrlTypeVarCheck(value_type.rust_name())
|
InstructionPredicateNode::TypePredicate(TypePredicateNode::CtrlTypeVarCheck(
|
||||||
|
value_type.rust_name(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn and(mut self, new_node: InstructionPredicateNode) -> Self {
|
pub fn and(mut self, new_node: InstructionPredicateNode) -> Self {
|
||||||
|
|||||||
Reference in New Issue
Block a user