[fine] Implement the wildcard pattern

This commit is contained in:
John Doty 2024-02-04 19:36:47 -08:00
parent e0721d09fc
commit 65ec2d4cca
5 changed files with 104 additions and 25 deletions

View file

@ -857,11 +857,21 @@ impl<'a> Semantics<'a> {
// parse error, don't make more trouble.
return Environment::error();
};
self.environment_of_pattern(parent, pattern)
// The left hand side of the `is` expression is used for wildcard types.
let Some(lhs) = tree.nth_tree(0) else {
return Environment::error();
};
self.environment_of_pattern(parent, pattern, lhs)
}
// NOTE: THIS IS CALLED DIRECTLY, NOT VIA `environment_of` TO AVOID CYCLES.
fn environment_of_pattern(&self, parent: EnvironmentRef, tree: &Tree) -> EnvironmentRef {
fn environment_of_pattern(
&self,
parent: EnvironmentRef,
tree: &Tree,
value_expr: TreeRef,
) -> EnvironmentRef {
assert_eq!(tree.kind, TreeKind::Pattern);
let Some(binding) = tree.child_tree_of_kind(self.syntax_tree, TreeKind::VariableBinding)
@ -872,15 +882,30 @@ impl<'a> Semantics<'a> {
let Some(variable) = binding.nth_token(0) else {
return Environment::error();
};
let Some(type_expr) = tree.child_of_kind(self.syntax_tree, TreeKind::TypeExpression) else {
return Environment::error();
let is_wildcard = tree
.child_of_kind(self.syntax_tree, TreeKind::WildcardPattern)
.is_some();
let variable_decl = if is_wildcard {
// If the variable is bound to a wildcard then treat the value
// expression as the declaration for the purpose of determining
// type.
value_expr
} else {
// Otherwise the binding is to the type expression which must
// match for the variable to have a value.
let Some(type_expr) = tree.child_of_kind(self.syntax_tree, TreeKind::TypeExpression)
else {
return Environment::error();
};
type_expr
};
// TODO: This binding should be un-assignable! Don't assign to this!
// (UNLESS VERY SPECIFIC CIRCUMSTANCES; WHICH ARE COMPLEX)
let mut env = Environment::new(Some(parent), Location::Local);
env.insert(variable, type_expr);
env.insert(variable, variable_decl);
EnvironmentRef::new(env)
}
@ -1927,6 +1952,7 @@ pub fn check(s: &Semantics) {
TreeKind::IsExpression => check_is_expression(s, tree),
TreeKind::VariableBinding => check_variable_binding(s, tree),
TreeKind::Pattern => check_pattern(s, tree),
TreeKind::WildcardPattern => {}
TreeKind::MatchArm => {}
TreeKind::MatchBody => {}