(and ...) combinator in patterns
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
- `and` combinator in input.
|
||||
- inputs to external extractors? "polarity" of args?
|
||||
- "extractor macros" rather than full rule reversal? (rule ...) and (pattern ...)?
|
||||
- Document semantics carefully, especially wrt extractors.
|
||||
|
||||
17
cranelift/isle/isle_examples/test4.isle
Normal file
17
cranelift/isle/isle_examples/test4.isle
Normal file
@@ -0,0 +1,17 @@
|
||||
(type u32 (primitive u32))
|
||||
(type A (enum (A1 (x u32))))
|
||||
|
||||
(decl Ext1 (u32) A)
|
||||
(decl Ext2 (u32) A)
|
||||
(extractor Ext1 ext1)
|
||||
(extractor Ext2 ext2)
|
||||
|
||||
(decl Lower (A) A)
|
||||
|
||||
(rule
|
||||
(Lower
|
||||
(and
|
||||
a
|
||||
(Ext1 x)
|
||||
(Ext2 =x)))
|
||||
a)
|
||||
@@ -83,6 +83,8 @@ pub enum Pattern {
|
||||
Term { sym: Ident, args: Vec<Pattern> },
|
||||
/// An operator that matches anything.
|
||||
Wildcard,
|
||||
/// N sub-patterns that must all match.
|
||||
And { subpats: Vec<Pattern> },
|
||||
}
|
||||
|
||||
/// An expression: the right-hand side of a rule.
|
||||
|
||||
@@ -253,6 +253,13 @@ impl PatternSequence {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Pattern::And(_ty, ref children) => {
|
||||
let input = input.unwrap();
|
||||
for child in children {
|
||||
self.gen_pattern(Some(input), typeenv, termenv, child, vars);
|
||||
}
|
||||
None
|
||||
}
|
||||
&Pattern::Wildcard(_ty) => {
|
||||
// Nothing!
|
||||
None
|
||||
|
||||
@@ -305,6 +305,15 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
} else if self.is_lparen() {
|
||||
self.lparen()?;
|
||||
if self.is_sym_str("and") {
|
||||
self.symbol()?;
|
||||
let mut subpats = vec![];
|
||||
while !self.is_rparen() {
|
||||
subpats.push(self.parse_pattern()?);
|
||||
}
|
||||
self.rparen()?;
|
||||
Ok(Pattern::And { subpats })
|
||||
} else {
|
||||
let sym = self.parse_ident()?;
|
||||
let mut args = vec![];
|
||||
while !self.is_rparen() {
|
||||
@@ -312,6 +321,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
self.rparen()?;
|
||||
Ok(Pattern::Term { sym, args })
|
||||
}
|
||||
} else {
|
||||
Err(self.error(pos.unwrap(), "Unexpected pattern".into()))
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ pub enum Pattern {
|
||||
ConstInt(TypeId, i64),
|
||||
Term(TypeId, TermId, Vec<Pattern>),
|
||||
Wildcard(TypeId),
|
||||
And(TypeId, Vec<Pattern>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -141,6 +142,7 @@ impl Pattern {
|
||||
&Self::ConstInt(t, ..) => t,
|
||||
&Self::Term(t, ..) => t,
|
||||
&Self::Wildcard(t, ..) => t,
|
||||
&Self::And(t, ..) => t,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,11 +295,13 @@ impl TypeEnv {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Bindings {
|
||||
next_var: usize,
|
||||
vars: Vec<BoundVar>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct BoundVar {
|
||||
name: Sym,
|
||||
id: VarId,
|
||||
@@ -548,6 +552,21 @@ impl TermEnv {
|
||||
})?;
|
||||
Ok((Pattern::Wildcard(ty), ty))
|
||||
}
|
||||
&ast::Pattern::And { ref subpats } => {
|
||||
let mut expected_ty = expected_ty;
|
||||
let mut children = vec![];
|
||||
for subpat in subpats {
|
||||
let (subpat, ty) =
|
||||
self.translate_pattern(tyenv, pos, &*subpat, expected_ty, bindings)?;
|
||||
expected_ty = expected_ty.or(Some(ty));
|
||||
children.push(subpat);
|
||||
}
|
||||
if expected_ty.is_none() {
|
||||
return Err(tyenv.error(pos, "No type for (and ...) form.".to_string()));
|
||||
}
|
||||
let ty = expected_ty.unwrap();
|
||||
Ok((Pattern::And(ty, children), ty))
|
||||
}
|
||||
&ast::Pattern::BindPattern {
|
||||
ref var,
|
||||
ref subpat,
|
||||
|
||||
Reference in New Issue
Block a user