(and ...) combinator in patterns
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
- `and` combinator in input.
|
|
||||||
- inputs to external extractors? "polarity" of args?
|
- inputs to external extractors? "polarity" of args?
|
||||||
- "extractor macros" rather than full rule reversal? (rule ...) and (pattern ...)?
|
- "extractor macros" rather than full rule reversal? (rule ...) and (pattern ...)?
|
||||||
- Document semantics carefully, especially wrt extractors.
|
- 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> },
|
Term { sym: Ident, args: Vec<Pattern> },
|
||||||
/// An operator that matches anything.
|
/// An operator that matches anything.
|
||||||
Wildcard,
|
Wildcard,
|
||||||
|
/// N sub-patterns that must all match.
|
||||||
|
And { subpats: Vec<Pattern> },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An expression: the right-hand side of a rule.
|
/// 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) => {
|
&Pattern::Wildcard(_ty) => {
|
||||||
// Nothing!
|
// Nothing!
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -305,13 +305,23 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
} else if self.is_lparen() {
|
} else if self.is_lparen() {
|
||||||
self.lparen()?;
|
self.lparen()?;
|
||||||
let sym = self.parse_ident()?;
|
if self.is_sym_str("and") {
|
||||||
let mut args = vec![];
|
self.symbol()?;
|
||||||
while !self.is_rparen() {
|
let mut subpats = vec![];
|
||||||
args.push(self.parse_pattern()?);
|
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() {
|
||||||
|
args.push(self.parse_pattern()?);
|
||||||
|
}
|
||||||
|
self.rparen()?;
|
||||||
|
Ok(Pattern::Term { sym, args })
|
||||||
}
|
}
|
||||||
self.rparen()?;
|
|
||||||
Ok(Pattern::Term { sym, args })
|
|
||||||
} else {
|
} else {
|
||||||
Err(self.error(pos.unwrap(), "Unexpected pattern".into()))
|
Err(self.error(pos.unwrap(), "Unexpected pattern".into()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ pub enum Pattern {
|
|||||||
ConstInt(TypeId, i64),
|
ConstInt(TypeId, i64),
|
||||||
Term(TypeId, TermId, Vec<Pattern>),
|
Term(TypeId, TermId, Vec<Pattern>),
|
||||||
Wildcard(TypeId),
|
Wildcard(TypeId),
|
||||||
|
And(TypeId, Vec<Pattern>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
@@ -141,6 +142,7 @@ impl Pattern {
|
|||||||
&Self::ConstInt(t, ..) => t,
|
&Self::ConstInt(t, ..) => t,
|
||||||
&Self::Term(t, ..) => t,
|
&Self::Term(t, ..) => t,
|
||||||
&Self::Wildcard(t, ..) => t,
|
&Self::Wildcard(t, ..) => t,
|
||||||
|
&Self::And(t, ..) => t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,11 +295,13 @@ impl TypeEnv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct Bindings {
|
struct Bindings {
|
||||||
next_var: usize,
|
next_var: usize,
|
||||||
vars: Vec<BoundVar>,
|
vars: Vec<BoundVar>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct BoundVar {
|
struct BoundVar {
|
||||||
name: Sym,
|
name: Sym,
|
||||||
id: VarId,
|
id: VarId,
|
||||||
@@ -548,6 +552,21 @@ impl TermEnv {
|
|||||||
})?;
|
})?;
|
||||||
Ok((Pattern::Wildcard(ty), ty))
|
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 {
|
&ast::Pattern::BindPattern {
|
||||||
ref var,
|
ref var,
|
||||||
ref subpat,
|
ref subpat,
|
||||||
|
|||||||
Reference in New Issue
Block a user