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:
parent
5d2c714bc1
commit
697d139cfd
@ -424,6 +424,7 @@ pub enum Pattern {
|
|||||||
Tuple(Vec<Pattern>),
|
Tuple(Vec<Pattern>),
|
||||||
Array(Vec<Pattern>),
|
Array(Vec<Pattern>),
|
||||||
Struct(Path, Vec<(Sym, Option<Pattern>)>),
|
Struct(Path, Vec<(Sym, Option<Pattern>)>),
|
||||||
|
TupleStruct(Path, Vec<Pattern>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `match` expression: `match` `{` ([MatchArm] `,`)* [MatchArm]? `}`
|
/// A `match` expression: `match` `{` ([MatchArm] `,`)* [MatchArm]? `}`
|
||||||
|
@ -487,6 +487,10 @@ mod display {
|
|||||||
}
|
}
|
||||||
Ok(())
|
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))
|
.map(|e| Pattern::try_from(e.kind))
|
||||||
.collect::<Result<_, _>>()?,
|
.collect::<Result<_, _>>()?,
|
||||||
),
|
),
|
||||||
// ExprKind::Index(index) => todo!(),
|
ExprKind::Binary(Binary { kind: BinaryKind::Call, parts }) => {
|
||||||
// ExprKind::Member(member) => todo!(),
|
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 }) => {
|
ExprKind::Structor(Structor { to, init }) => {
|
||||||
let fields = init
|
let fields = init
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -267,6 +267,13 @@ pub trait Fold {
|
|||||||
.map(|(name, bind)| (name, bind.map(|p| self.fold_pattern(p))))
|
.map(|(name, bind)| (name, bind.map(|p| self.fold_pattern(p))))
|
||||||
.collect(),
|
.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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,10 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Pattern::TupleStruct(path, items) => {
|
||||||
|
self.visit_path(path);
|
||||||
|
items.iter().for_each(|bind| self.visit_pattern(bind));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,6 +320,9 @@ mod assignment {
|
|||||||
None => set.push(name),
|
None => set.push(name),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Pattern::TupleStruct(_path, items) => {
|
||||||
|
items.iter().for_each(|pat| patvars(set, pat));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut set = Vec::new();
|
let mut set = Vec::new();
|
||||||
|
@ -1080,7 +1080,7 @@ impl Parse<'_> for Return {
|
|||||||
|
|
||||||
impl Parse<'_> for Pattern {
|
impl Parse<'_> for Pattern {
|
||||||
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
||||||
let value = prec::exprkind(p, prec::Precedence::Highest.level())?;
|
let value = prec::exprkind(p, prec::Precedence::Pattern.level())?;
|
||||||
Pattern::try_from(value)
|
Pattern::try_from(value)
|
||||||
.map_err(|_| p.error(ExpectedParsing { want: Parsing::Pattern }, Parsing::Pattern))
|
.map_err(|_| p.error(ExpectedParsing { want: Parsing::Pattern }, Parsing::Pattern))
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,8 @@ pub enum Precedence {
|
|||||||
Index,
|
Index,
|
||||||
Cast,
|
Cast,
|
||||||
Member, // left-associative
|
Member, // left-associative
|
||||||
|
Pattern,
|
||||||
Call,
|
Call,
|
||||||
Highest,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Precedence {
|
impl Precedence {
|
||||||
|
@ -438,13 +438,20 @@ pub mod yamlify {
|
|||||||
Pattern::Struct(path, items) => {
|
Pattern::Struct(path, items) => {
|
||||||
{
|
{
|
||||||
let mut y = y.key("Struct");
|
let mut y = y.key("Struct");
|
||||||
y.pair("name", path);
|
y.yaml(path);
|
||||||
for (name, item) in items {
|
for (name, item) in items {
|
||||||
y.pair(name, item);
|
y.pair(name, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y
|
y
|
||||||
}
|
}
|
||||||
|
Pattern::TupleStruct(path, items) => {
|
||||||
|
{
|
||||||
|
let mut y = y.key("TupleStruct");
|
||||||
|
y.yaml(path).list(items);
|
||||||
|
}
|
||||||
|
y
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user