[fine] Implement the wildcard pattern
This commit is contained in:
parent
e0721d09fc
commit
65ec2d4cca
5 changed files with 104 additions and 25 deletions
|
|
@ -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 => {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue