fix: List clauses were destructuring the next element unnecessarily

feat: finish nested constructor clauses
This commit is contained in:
microproofs 2023-07-02 13:17:14 -04:00 committed by Kasey
parent f6e163d16d
commit c025073056
2 changed files with 128 additions and 68 deletions

View File

@ -122,6 +122,47 @@ impl ClauseProperties {
}
}
}
pub fn init_inner(
t: &Arc<Type>,
constr_var: String,
subject_name: String,
final_clause: bool,
) -> Self {
if t.is_list() {
ClauseProperties {
clause_var_name: constr_var,
complex_clause: false,
original_subject_name: subject_name,
final_clause,
needs_constr_var: false,
specific_clause: SpecificClause::ListClause {
current_index: 0,
defined_tails: vec![],
},
}
} else if t.is_tuple() {
ClauseProperties {
clause_var_name: constr_var,
complex_clause: false,
original_subject_name: subject_name,
needs_constr_var: false,
final_clause,
specific_clause: SpecificClause::TupleClause {
defined_tuple_indices: IndexSet::new(),
},
}
} else {
ClauseProperties {
clause_var_name: constr_var,
complex_clause: false,
original_subject_name: subject_name,
needs_constr_var: false,
final_clause,
specific_clause: SpecificClause::ConstrClause,
}
}
}
}
pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> {

View File

@ -1256,11 +1256,10 @@ impl<'a> CodeGenerator<'a> {
};
let next_tail_name = {
let next_clause = if rest_clauses.is_empty() {
&final_clause
if rest_clauses.is_empty() {
None
} else {
&rest_clauses[0]
};
let next_clause = &rest_clauses[0];
let next_elements_len = match &next_clause.pattern {
Pattern::List { elements, .. } => elements.len(),
_ => 0,
@ -1269,13 +1268,14 @@ impl<'a> CodeGenerator<'a> {
if (*current_index as usize) < next_elements_len {
Some(format!(
"tail_index_{}_span_{}_{}",
*current_index,
*current_index + 1,
next_clause.pattern.location().start,
next_clause.pattern.location().end
))
} else {
None
}
}
};
let mut use_wrap_clause = false;
@ -1384,8 +1384,6 @@ impl<'a> CodeGenerator<'a> {
let ClauseProperties {
specific_clause: SpecificClause::ListClause { defined_tails, .. },
complex_clause,
original_subject_name: _,
final_clause: _,
..
} = props
else { unreachable!() };
@ -1415,10 +1413,11 @@ impl<'a> CodeGenerator<'a> {
),
};
let mut elem_props = ClauseProperties::init(
let mut elem_props = ClauseProperties::init_inner(
list_elem_type,
elem_name.clone(),
elem_name.clone(),
props.final_clause,
);
let statement =
@ -1457,14 +1456,12 @@ impl<'a> CodeGenerator<'a> {
),
};
let mut elem_props = ClauseProperties {
clause_var_name: elem_name.clone(),
complex_clause: false,
needs_constr_var: false,
original_subject_name: elem_name.clone(),
final_clause: props.final_clause,
specific_clause: props.specific_clause.clone(),
};
let mut elem_props = ClauseProperties::init_inner(
subject_tipo,
elem_name.clone(),
elem_name.clone(),
props.final_clause,
);
let statement =
self.nested_clause_condition(elem, subject_tipo, &mut elem_props);
@ -1557,14 +1554,12 @@ impl<'a> CodeGenerator<'a> {
)
});
let mut field_props = ClauseProperties {
clause_var_name: field_name.clone(),
complex_clause: false,
needs_constr_var: false,
original_subject_name: field_name.clone(),
final_clause: props.final_clause,
specific_clause: props.specific_clause.clone(),
};
let mut field_props = ClauseProperties::init_inner(
arg_type,
field_name.clone(),
field_name.clone(),
props.final_clause,
);
let statement = self.nested_clause_condition(
&arg.value,
@ -1614,38 +1609,62 @@ impl<'a> CodeGenerator<'a> {
subject_tipo: &Arc<Type>,
props: &mut ClauseProperties,
) -> AirTree {
if props.final_clause {
props.complex_clause = false;
let (_, assign) = self.clause_pattern(pattern, subject_tipo, props);
assign
} else {
match pattern {
Pattern::Int { value, .. } => {
props.complex_clause = true;
AirTree::clause_guard(&props.original_subject_name, AirTree::int(value), int())
}
Pattern::Var { name, .. } => AirTree::let_assignment(
name,
AirTree::local_var(&props.clause_var_name, subject_tipo.clone()),
),
Pattern::Assign {
Pattern::Assign { name, pattern, .. } => AirTree::UnhoistedSequence(vec![
AirTree::let_assignment(
name,
location,
pattern,
} => {
todo!();
}
Pattern::Discard { name, location } => todo!(),
AirTree::local_var(&props.clause_var_name, subject_tipo.clone()),
),
self.nested_clause_condition(pattern, subject_tipo, props),
]),
Pattern::Discard { .. } => AirTree::no_op(),
Pattern::List {
location,
elements,
tail,
} => todo!(),
} => {
todo!();
}
Pattern::Constructor {
is_record,
location,
name,
arguments,
module,
constructor,
with_spread,
tipo,
} => todo!(),
name: constr_name, ..
} => {
props.complex_clause = true;
if subject_tipo.is_bool() {
AirTree::clause_guard(
&props.original_subject_name,
AirTree::bool(constr_name == "True"),
bool(),
)
} else if subject_tipo.is_void() {
todo!()
} else {
let (cond, assign) = self.clause_pattern(pattern, subject_tipo, props);
AirTree::UnhoistedSequence(vec![
AirTree::clause_guard(
&props.original_subject_name,
cond,
subject_tipo.clone(),
),
assign,
])
}
}
Pattern::Tuple { location, elems } => todo!(),
}
}
}
}