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:
2025-02-22 01:37:08 -06:00
parent 5d2c714bc1
commit 697d139cfd
9 changed files with 46 additions and 5 deletions

View File

@@ -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]? `}`

View File

@@ -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()

View File

@@ -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(),
),
}
}

View File

@@ -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));
}
}
}