clause guard with discard is now handled

This commit is contained in:
Kasey White 2023-04-10 02:12:40 -04:00 committed by KtorZ
parent 0846fe2d5f
commit 1e35281650
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
2 changed files with 96 additions and 68 deletions

View File

@ -813,8 +813,13 @@ impl<'a> CodeGenerator<'a> {
clause_properties, clause_properties,
); );
let data_type = if clause.pattern.is_var() || clause.pattern.is_discard() {
builder::lookup_data_type_by_tipo(self.data_types.clone(), subject_type); ir_stack.wrap_clause(clause_pattern_stack);
} else {
let data_type = builder::lookup_data_type_by_tipo(
self.data_types.clone(),
subject_type,
);
if let Some(data_type) = data_type { if let Some(data_type) = data_type {
if data_type.constructors.len() > 1 { if data_type.constructors.len() > 1 {
@ -847,6 +852,7 @@ impl<'a> CodeGenerator<'a> {
); );
} }
} }
}
ClauseProperties::ListClause { ClauseProperties::ListClause {
original_subject_name, original_subject_name,
current_index, current_index,

View File

@ -286,7 +286,11 @@ pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
// TODO: how shall tails be weighted? Since any clause after will not run // TODO: how shall tails be weighted? Since any clause after will not run
sorted_clauses.sort_by(|clause1, clause2| { sorted_clauses.sort_by(|clause1, clause2| {
let clause1_len = match &clause1.pattern { let clause1_len = match &clause1.pattern {
Pattern::List { elements, tail, .. } => elements.len() + usize::from(tail.is_some()), Pattern::List { elements, tail, .. } => {
elements.len() * 3
+ usize::from(tail.is_some())
+ usize::from(clause1.guard.is_some())
}
_ => 10000000, _ => 10000000,
}; };
let clause2_len = match &clause2.pattern { let clause2_len = match &clause2.pattern {
@ -306,7 +310,8 @@ pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
// If we have a catch all, use that. Otherwise use todo which will result in error // If we have a catch all, use that. Otherwise use todo which will result in error
// TODO: fill in todo label with description // TODO: fill in todo label with description
let plug_in_then = match &sorted_clauses[sorted_clauses.len() - 1].pattern { let plug_in_then = if sorted_clauses[sorted_clauses.len() - 1].guard.is_none() {
match &sorted_clauses[sorted_clauses.len() - 1].pattern {
Pattern::Var { name, .. } => { Pattern::Var { name, .. } => {
assign_plug_in_name = Some(name); assign_plug_in_name = Some(name);
sorted_clauses[sorted_clauses.len() - 1].clone().then sorted_clauses[sorted_clauses.len() - 1].clone().then
@ -328,6 +333,22 @@ pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
}), }),
} }
} }
}
} else {
let tipo = sorted_clauses[sorted_clauses.len() - 1].then.tipo();
TypedExpr::Trace {
location: Span::empty(),
tipo: tipo.clone(),
text: Box::new(TypedExpr::String {
location: Span::empty(),
tipo: crate::builtins::string(),
value: "Clause not filled".to_string(),
}),
then: Box::new(TypedExpr::ErrorTerm {
location: Span::empty(),
tipo,
}),
}
}; };
for (index, clause) in sorted_clauses.iter().enumerate() { for (index, clause) in sorted_clauses.iter().enumerate() {
@ -379,6 +400,7 @@ pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
} }
// if we have a pattern with no clause guards and a tail then no lists will get past here to other clauses // if we have a pattern with no clause guards and a tail then no lists will get past here to other clauses
if clause.guard.is_none() {
match &clause.pattern { match &clause.pattern {
Pattern::Var { .. } => { Pattern::Var { .. } => {
last_clause_index = index + 1; last_clause_index = index + 1;
@ -395,10 +417,9 @@ pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
} => { } => {
let mut elements = elements.clone(); let mut elements = elements.clone();
elements.push(*tail.clone()); elements.push(*tail.clone());
if elements if elements.iter().all(|element| {
.iter() matches!(element, Pattern::Var { .. } | Pattern::Discard { .. })
.all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. })) }) && !last_clause_set
&& !last_clause_set
&& !elements.is_empty() && !elements.is_empty()
{ {
last_clause_index = index + 1; last_clause_index = index + 1;
@ -407,6 +428,7 @@ pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
} }
_ => {} _ => {}
} }
}
// If the last condition doesn't have a catch all or tail then add a catch all with a todo // If the last condition doesn't have a catch all or tail then add a catch all with a todo
if index == sorted_clauses.len() - 1 { if index == sorted_clauses.len() - 1 {