Merge pull request #351 from aiken-lang/acceptance-test-054-pattern-match-on-list

Add new acceptance test scenario: 056
This commit is contained in:
Matthias Benkort 2023-02-16 10:01:56 +01:00 committed by GitHub
commit ec6baf3a6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 8 deletions

View File

@ -764,12 +764,12 @@ impl<'a> CodeGenerator<'a> {
current_index, current_index,
.. ..
} => { } => {
let current_clause_index = let (current_clause_index, has_tail) =
if let Pattern::List { elements, .. } = &clause.pattern[0] { if let Pattern::List { elements, tail, .. } = &clause.pattern[0] {
elements.len() (elements.len(), tail.is_some())
} else if let Pattern::Assign { pattern, .. } = &clause.pattern[0] { } else if let Pattern::Assign { pattern, .. } = &clause.pattern[0] {
if let Pattern::List { elements, .. } = pattern.as_ref() { if let Pattern::List { elements, tail, .. } = pattern.as_ref() {
elements.len() (elements.len(), tail.is_some())
} else { } else {
unreachable!("{:#?}", pattern) unreachable!("{:#?}", pattern)
} }
@ -820,7 +820,9 @@ impl<'a> CodeGenerator<'a> {
} }
}; };
if current_clause_index as i64 == prev_index { let minus_tail = if has_tail { 1 } else { 0 };
if current_clause_index as i64 - minus_tail == prev_index {
ir_stack.push(Air::WrapClause { scope }); ir_stack.push(Air::WrapClause { scope });
} else { } else {
ir_stack.push(Air::ListClause { ir_stack.push(Air::ListClause {
@ -1121,7 +1123,9 @@ impl<'a> CodeGenerator<'a> {
Pattern::Var { name, .. } => { Pattern::Var { name, .. } => {
tail_name = name.clone(); tail_name = name.clone();
} }
Pattern::Discard { .. } => {} Pattern::Discard { .. } => {
tail_name = "_".to_string();
}
_ => unreachable!("Patterns in tail of list should not allow this"), _ => unreachable!("Patterns in tail of list should not allow this"),
} }
} }
@ -1149,11 +1153,17 @@ impl<'a> CodeGenerator<'a> {
format!("__tail_{}", elements.len() - 2) format!("__tail_{}", elements.len() - 2)
}; };
let tail = if &tail_name == "_" {
None
} else {
Some((tail_var, tail_name))
};
pattern_vec.push(Air::ListExpose { pattern_vec.push(Air::ListExpose {
scope, scope,
tipo: tipo.clone().into(), tipo: tipo.clone().into(),
tail_head_names, tail_head_names,
tail: Some((tail_var, tail_name)), tail,
}); });
} else if !elements.is_empty() { } else if !elements.is_empty() {
pattern_vec.push(Air::ListExpose { pattern_vec.push(Air::ListExpose {

View File

@ -0,0 +1,5 @@
# This file was generated by Aiken
# You typically do not need to edit this file
requirements = []
packages = []

View File

@ -0,0 +1,3 @@
name = "aiken-lang/acceptance_test_056"
version = "0.0.0"
dependencies = []

View File

@ -0,0 +1,24 @@
// Could possibly be forbidden by the parser instead if we have no intent to support that.
pub fn choice(self: List<Option<a>>) -> Option<a> {
when self is {
[] -> None
[Some(_) as result, ..] -> result
[None, ..others] -> choice(others)
}
}
test choice_1() {
choice([Some(14), Some(42)]) == Some(14)
}
test choice_2() {
choice([]) == None
}
test choice_3() {
choice([None]) == None
}
test choice_4() {
choice([None, Some(42)]) == Some(42)
}

View File

@ -0,0 +1,23 @@
pub fn choice(self: List<Option<a>>) -> Option<a> {
when self is {
[] -> None
[Some(x), ..] -> Some(x)
[None, ..others] -> choice(others)
}
}
test choice_1() {
choice([Some(14), Some(42)]) == Some(14)
}
test choice_2() {
choice([]) == None
}
test choice_3() {
choice([None]) == None
}
test choice_4() {
choice([None, Some(42)]) == Some(42)
}

View File

@ -0,0 +1,23 @@
pub fn choice(self: List<Option<a>>) -> Option<a> {
when self is {
[] -> None
[None, ..others] -> choice(others)
[result, ..] -> result
}
}
test choice_1() {
choice([Some(14), Some(42)]) == Some(14)
}
test choice_2() {
choice([]) == None
}
test choice_3() {
choice([None]) == None
}
test choice_4() {
choice([None, Some(42)]) == Some(42)
}