clause guard with discard is now handled
This commit is contained in:
parent
0846fe2d5f
commit
1e35281650
|
@ -813,38 +813,44 @@ 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 {
|
||||||
|
ir_stack.clause(
|
||||||
|
subject_type.clone(),
|
||||||
|
subject_name,
|
||||||
|
*clause_properties.is_complex_clause(),
|
||||||
|
clause_pattern_stack,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let mut condition_stack = ir_stack.empty_with_scope();
|
||||||
|
|
||||||
|
condition_stack.integer(0.to_string());
|
||||||
|
|
||||||
|
condition_stack.merge_child(clause_pattern_stack);
|
||||||
|
|
||||||
|
ir_stack.clause(
|
||||||
|
subject_type.clone(),
|
||||||
|
subject_name,
|
||||||
|
*clause_properties.is_complex_clause(),
|
||||||
|
condition_stack,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ir_stack.clause(
|
ir_stack.clause(
|
||||||
subject_type.clone(),
|
subject_type.clone(),
|
||||||
subject_name,
|
subject_name,
|
||||||
*clause_properties.is_complex_clause(),
|
*clause_properties.is_complex_clause(),
|
||||||
clause_pattern_stack,
|
clause_pattern_stack,
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
let mut condition_stack = ir_stack.empty_with_scope();
|
|
||||||
|
|
||||||
condition_stack.integer(0.to_string());
|
|
||||||
|
|
||||||
condition_stack.merge_child(clause_pattern_stack);
|
|
||||||
|
|
||||||
ir_stack.clause(
|
|
||||||
subject_type.clone(),
|
|
||||||
subject_name,
|
|
||||||
*clause_properties.is_complex_clause(),
|
|
||||||
condition_stack,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ir_stack.clause(
|
|
||||||
subject_type.clone(),
|
|
||||||
subject_name,
|
|
||||||
*clause_properties.is_complex_clause(),
|
|
||||||
clause_pattern_stack,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClauseProperties::ListClause {
|
ClauseProperties::ListClause {
|
||||||
|
|
|
@ -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,27 +310,44 @@ 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() {
|
||||||
Pattern::Var { name, .. } => {
|
match &sorted_clauses[sorted_clauses.len() - 1].pattern {
|
||||||
assign_plug_in_name = Some(name);
|
Pattern::Var { name, .. } => {
|
||||||
sorted_clauses[sorted_clauses.len() - 1].clone().then
|
assign_plug_in_name = Some(name);
|
||||||
}
|
sorted_clauses[sorted_clauses.len() - 1].clone().then
|
||||||
Pattern::Discard { .. } => sorted_clauses[sorted_clauses.len() - 1].clone().then,
|
|
||||||
_ => {
|
|
||||||
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,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
Pattern::Discard { .. } => sorted_clauses[sorted_clauses.len() - 1].clone().then,
|
||||||
|
_ => {
|
||||||
|
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,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -379,33 +400,34 @@ 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
|
||||||
match &clause.pattern {
|
if clause.guard.is_none() {
|
||||||
Pattern::Var { .. } => {
|
match &clause.pattern {
|
||||||
last_clause_index = index + 1;
|
Pattern::Var { .. } => {
|
||||||
last_clause_set = true;
|
|
||||||
}
|
|
||||||
Pattern::Discard { .. } => {
|
|
||||||
last_clause_index = index + 1;
|
|
||||||
last_clause_set = true;
|
|
||||||
}
|
|
||||||
Pattern::List {
|
|
||||||
elements,
|
|
||||||
tail: Some(tail),
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
let mut elements = elements.clone();
|
|
||||||
elements.push(*tail.clone());
|
|
||||||
if elements
|
|
||||||
.iter()
|
|
||||||
.all(|element| matches!(element, Pattern::Var { .. } | Pattern::Discard { .. }))
|
|
||||||
&& !last_clause_set
|
|
||||||
&& !elements.is_empty()
|
|
||||||
{
|
|
||||||
last_clause_index = index + 1;
|
last_clause_index = index + 1;
|
||||||
last_clause_set = true;
|
last_clause_set = true;
|
||||||
}
|
}
|
||||||
|
Pattern::Discard { .. } => {
|
||||||
|
last_clause_index = index + 1;
|
||||||
|
last_clause_set = true;
|
||||||
|
}
|
||||||
|
Pattern::List {
|
||||||
|
elements,
|
||||||
|
tail: Some(tail),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let mut elements = elements.clone();
|
||||||
|
elements.push(*tail.clone());
|
||||||
|
if elements.iter().all(|element| {
|
||||||
|
matches!(element, Pattern::Var { .. } | Pattern::Discard { .. })
|
||||||
|
}) && !last_clause_set
|
||||||
|
&& !elements.is_empty()
|
||||||
|
{
|
||||||
|
last_clause_index = index + 1;
|
||||||
|
last_clause_set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
Loading…
Reference in New Issue