conlang: Add Tuple-Struct Patterns
- Patterns are no longer parsed with the highest precedence - Function calls with just a path and a tuple of args can now be transformed into a Pattern
This commit is contained in:
@@ -424,6 +424,7 @@ pub enum Pattern {
|
||||
Tuple(Vec<Pattern>),
|
||||
Array(Vec<Pattern>),
|
||||
Struct(Path, Vec<(Sym, Option<Pattern>)>),
|
||||
TupleStruct(Path, Vec<Pattern>),
|
||||
}
|
||||
|
||||
/// A `match` expression: `match` `{` ([MatchArm] `,`)* [MatchArm]? `}`
|
||||
|
||||
@@ -487,6 +487,10 @@ mod display {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Pattern::TupleStruct(path, items) => {
|
||||
write!(f, "{path}")?;
|
||||
separate(items, ", ")(f.delimit(INLINE_PARENS))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -884,8 +888,19 @@ mod convert {
|
||||
.map(|e| Pattern::try_from(e.kind))
|
||||
.collect::<Result<_, _>>()?,
|
||||
),
|
||||
// ExprKind::Index(index) => todo!(),
|
||||
// ExprKind::Member(member) => todo!(),
|
||||
ExprKind::Binary(Binary { kind: BinaryKind::Call, parts }) => {
|
||||
let (ExprKind::Path(path), args) = *parts else {
|
||||
return Err(parts.0);
|
||||
};
|
||||
match args {
|
||||
ExprKind::Empty | ExprKind::Tuple(_) => {}
|
||||
_ => return Err(args),
|
||||
}
|
||||
let Pattern::Tuple(args) = Pattern::try_from(args)? else {
|
||||
unreachable!("Arguments should be convertible to pattern!")
|
||||
};
|
||||
Pattern::TupleStruct(path, args)
|
||||
}
|
||||
ExprKind::Structor(Structor { to, init }) => {
|
||||
let fields = init
|
||||
.into_iter()
|
||||
|
||||
@@ -267,6 +267,13 @@ pub trait Fold {
|
||||
.map(|(name, bind)| (name, bind.map(|p| self.fold_pattern(p))))
|
||||
.collect(),
|
||||
),
|
||||
Pattern::TupleStruct(path, items) => Pattern::TupleStruct(
|
||||
self.fold_path(path),
|
||||
items
|
||||
.into_iter()
|
||||
.map(|bind| self.fold_pattern(bind))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -234,6 +234,10 @@ pub trait Visit<'a>: Sized {
|
||||
});
|
||||
});
|
||||
}
|
||||
Pattern::TupleStruct(path, items) => {
|
||||
self.visit_path(path);
|
||||
items.iter().for_each(|bind| self.visit_pattern(bind));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user