Browse Source

cranelift/isle: add Binding::MakeSome for partial constructors (#8761)

pull/8794/head
Michael McLoughlin 5 months ago
committed by GitHub
parent
commit
9f29c6e926
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      cranelift/isle/isle/src/codegen.rs
  2. 11
      cranelift/isle/isle/src/sema.rs
  3. 11
      cranelift/isle/isle/src/trie_again.rs

11
cranelift/isle/isle/src/codegen.rs

@ -639,8 +639,7 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
)?;
write!(ctx.out, "{}", &ctx.indent)?;
match ret_kind {
ReturnKind::Plain => write!(ctx.out, "return ")?,
ReturnKind::Option => write!(ctx.out, "return Some(")?,
ReturnKind::Plain | ReturnKind::Option => write!(ctx.out, "return ")?,
ReturnKind::Iterator => write!(ctx.out, "returns.extend(Some(")?,
}
self.emit_expr(ctx, result)?;
@ -648,8 +647,7 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
write!(ctx.out, ".clone()")?;
}
match ret_kind {
ReturnKind::Plain => writeln!(ctx.out, ";")?,
ReturnKind::Option => writeln!(ctx.out, ");")?,
ReturnKind::Plain | ReturnKind::Option => writeln!(ctx.out, ";")?,
ReturnKind::Iterator => {
writeln!(ctx.out, "));")?;
writeln!(
@ -753,6 +751,11 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
Ok(())
}
&Binding::MakeSome { inner } => {
write!(ctx.out, "Some(")?;
self.emit_expr(ctx, inner)?;
write!(ctx.out, ")")
}
&Binding::MatchSome { source } => {
self.emit_expr(ctx, source)?;
write!(ctx.out, "?")

11
cranelift/isle/isle/src/sema.rs

@ -339,6 +339,17 @@ impl Term {
matches!(self.kind, TermKind::EnumVariant { .. })
}
/// Is this term partial?
pub fn is_partial(&self) -> bool {
matches!(
self.kind,
TermKind::Decl {
flags: TermFlags { partial: true, .. },
..
}
)
}
/// Does this term have a constructor?
pub fn has_constructor(&self) -> bool {
matches!(

11
cranelift/isle/isle/src/trie_again.rs

@ -111,6 +111,11 @@ pub enum Binding {
/// get the field names.
field: TupleIndex,
},
/// The result of constructing an Option::Some variant.
MakeSome {
/// Contained expression.
inner: BindingId,
},
/// Pattern-match one of the previous bindings against `Option::Some` and produce a new binding
/// from its contents. There must be a corresponding [Constraint::Some] for each `source` that
/// appears in a `MatchSome` binding. (This currently only happens with external extractors.)
@ -250,6 +255,7 @@ impl Binding {
Binding::Iterator { source } => std::slice::from_ref(source),
Binding::MakeVariant { fields, .. } => &fields[..],
Binding::MatchVariant { source, .. } => std::slice::from_ref(source),
Binding::MakeSome { inner } => std::slice::from_ref(inner),
Binding::MatchSome { source } => std::slice::from_ref(source),
Binding::MatchTuple { source, .. } => std::slice::from_ref(source),
}
@ -384,6 +390,11 @@ impl RuleSetBuilder {
self.current_rule.pos = rule.pos;
self.current_rule.prio = rule.prio;
self.current_rule.result = rule.visit(self, termenv);
if termenv.terms[rule.root_term.index()].is_partial() {
self.current_rule.result = self.dedup_binding(Binding::MakeSome {
inner: self.current_rule.result,
});
}
self.normalize_equivalence_classes();
let rule = std::mem::take(&mut self.current_rule);

Loading…
Cancel
Save