fixed pattern matching

This commit is contained in:
pca006132 2021-07-27 14:39:53 +08:00
parent 5f0490cd84
commit e15473d2c9
2 changed files with 18 additions and 7 deletions

View File

@ -8,19 +8,23 @@ impl<'a> Inferencer<'a> {
&mut self, &mut self,
pattern: &Expr<Option<Type>>, pattern: &Expr<Option<Type>>,
defined_identifiers: &mut Vec<String>, defined_identifiers: &mut Vec<String>,
) { ) -> Result<(), String> {
match &pattern.node { match &pattern.node {
ExprKind::Name { id, .. } => { ExprKind::Name { id, .. } => {
if !defined_identifiers.contains(id) { if !defined_identifiers.contains(id) {
defined_identifiers.push(id.clone()); defined_identifiers.push(id.clone());
} }
Ok(())
} }
ExprKind::Tuple { elts, .. } => { ExprKind::Tuple { elts, .. } => {
for elt in elts.iter() { for elt in elts.iter() {
self.check_pattern(elt, defined_identifiers); self.check_pattern(elt, defined_identifiers)?;
} }
Ok(())
}
_ => {
self.check_expr(pattern, defined_identifiers)
} }
_ => unimplemented!(),
} }
} }
@ -106,7 +110,7 @@ impl<'a> Inferencer<'a> {
} = &generators[0]; } = &generators[0];
self.check_expr(iter, defined_identifiers)?; self.check_expr(iter, defined_identifiers)?;
let mut defined_identifiers = defined_identifiers.to_vec(); let mut defined_identifiers = defined_identifiers.to_vec();
self.check_pattern(target, &mut defined_identifiers); self.check_pattern(target, &mut defined_identifiers)?;
for term in once(elt.as_ref()).chain(ifs.iter()) { for term in once(elt.as_ref()).chain(ifs.iter()) {
self.check_expr(term, &defined_identifiers)?; self.check_expr(term, &defined_identifiers)?;
} }
@ -151,7 +155,7 @@ impl<'a> Inferencer<'a> {
self.check_stmt(stmt, defined_identifiers)?; self.check_stmt(stmt, defined_identifiers)?;
} }
let mut defined_identifiers = defined_identifiers.clone(); let mut defined_identifiers = defined_identifiers.clone();
self.check_pattern(target, &mut defined_identifiers); self.check_pattern(target, &mut defined_identifiers)?;
for stmt in body.iter() { for stmt in body.iter() {
self.check_stmt(stmt, &mut defined_identifiers)?; self.check_stmt(stmt, &mut defined_identifiers)?;
} }
@ -185,14 +189,14 @@ impl<'a> Inferencer<'a> {
StmtKind::Assign { targets, value, .. } => { StmtKind::Assign { targets, value, .. } => {
self.check_expr(value, defined_identifiers)?; self.check_expr(value, defined_identifiers)?;
for target in targets { for target in targets {
self.check_pattern(target, defined_identifiers); self.check_pattern(target, defined_identifiers)?;
} }
Ok(false) Ok(false)
} }
StmtKind::AnnAssign { target, value, .. } => { StmtKind::AnnAssign { target, value, .. } => {
if let Some(value) = value { if let Some(value) = value {
self.check_expr(value, defined_identifiers)?; self.check_expr(value, defined_identifiers)?;
self.check_pattern(target, defined_identifiers); self.check_pattern(target, defined_identifiers)?;
} }
Ok(false) Ok(false)
} }

View File

@ -222,6 +222,13 @@ impl TestEnvironment {
[("a", "virtual[Bar]"), ("b", "int32")].iter().cloned().collect(), [("a", "virtual[Bar]"), ("b", "int32")].iter().cloned().collect(),
&[("Bar", "Bar"), ("Bar2", "Bar")] &[("Bar", "Bar"), ("Bar2", "Bar")]
; "virtual test")] ; "virtual test")]
#[test_case(indoc! {"
a = [virtual(Bar(), Bar), virtual(Bar2())]
b = [x.b() for x in a]
"},
[("a", "list[virtual[Bar]]"), ("b", "list[int32]")].iter().cloned().collect(),
&[("Bar", "Bar"), ("Bar2", "Bar")]
; "virtual list test")]
fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &str)]) { fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &str)]) {
println!("source:\n{}", source); println!("source:\n{}", source);
let mut env = TestEnvironment::new(); let mut env = TestEnvironment::new();