chore: another checkpoint

fix: guard clause to properly check condition
This commit is contained in:
microproofs 2023-07-01 15:35:37 -04:00 committed by Kasey
parent f94c8213b6
commit 023be88bf6
1 changed files with 97 additions and 56 deletions

View File

@ -16,7 +16,7 @@ use crate::{
AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction, AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction,
TypedValidator, TypedValidator,
}, },
builtins::{int, void}, builtins::{bool, int, void},
expr::TypedExpr, expr::TypedExpr,
gen_uplc::{ gen_uplc::{
air::Air, air::Air,
@ -243,7 +243,24 @@ impl<'a> CodeGenerator<'a> {
AirTree::call(self.build(fun.as_ref()), tipo.clone(), func_args) AirTree::call(self.build(fun.as_ref()), tipo.clone(), func_args)
} }
} }
_ => unreachable!("IS THIS REACHABLE? Well you reached it with {:#?}", body), _ => {
let Some(fun_arg_types) = fun.tipo().arg_types() else {unreachable!("Expected a function type with arguments")};
let func_args = args
.iter()
.zip(fun_arg_types)
.map(|(arg, arg_tipo)| {
let mut arg_val = self.build(&arg.value);
if arg_tipo.is_data() && !arg.value.tipo().is_data() {
arg_val = AirTree::wrap_data(arg_val, arg.value.tipo())
}
arg_val
})
.collect_vec();
AirTree::call(self.build(fun.as_ref()), tipo.clone(), func_args)
}
}, },
TypedExpr::BinOp { TypedExpr::BinOp {
name, name,
@ -1120,10 +1137,17 @@ impl<'a> CodeGenerator<'a> {
clause.location.start, clause.location.end clause.location.start, clause.location.end
); );
let clause_guard_assign = let clause_guard_assign = AirTree::let_assignment(
AirTree::let_assignment(clause_guard_name, builder::handle_clause_guard(guard)); &clause_guard_name,
builder::handle_clause_guard(guard),
);
clause_then = clause_guard_assign.hoist_over(clause_then); clause_then = clause_guard_assign.hoist_over(AirTree::clause_guard(
clause_guard_name,
AirTree::bool(true),
bool(),
clause_then,
));
} }
match &mut props.specific_clause { match &mut props.specific_clause {
@ -1207,7 +1231,12 @@ impl<'a> CodeGenerator<'a> {
}; };
let next_tail_name = { let next_tail_name = {
let next_elements_len = match &rest_clauses[0].pattern { let next_clause = if rest_clauses.is_empty() {
&final_clause
} else {
&rest_clauses[0]
};
let next_elements_len = match &next_clause.pattern {
Pattern::List { elements, .. } => elements.len(), Pattern::List { elements, .. } => elements.len(),
_ => 0, _ => 0,
}; };
@ -1216,17 +1245,21 @@ impl<'a> CodeGenerator<'a> {
Some(format!( Some(format!(
"tail_index_{}_span_{}_{}", "tail_index_{}_span_{}_{}",
*current_index, *current_index,
rest_clauses[0].pattern.location().start, next_clause.pattern.location().start,
rest_clauses[0].pattern.location().end next_clause.pattern.location().end
)) ))
} else { } else {
None None
} }
}; };
let mut use_wrap_clause = false;
if elements.len() > *current_index as usize { if elements.len() > *current_index as usize {
*current_index += 1; *current_index += 1;
defined_tails.push(tail_name.clone()); defined_tails.push(tail_name.clone());
} else if next_tail_name.is_none() {
use_wrap_clause = true;
} }
let mut next_clause_props = ClauseProperties { let mut next_clause_props = ClauseProperties {
@ -1248,21 +1281,31 @@ impl<'a> CodeGenerator<'a> {
let complex_clause = props.complex_clause; let complex_clause = props.complex_clause;
AirTree::list_clause( if use_wrap_clause {
tail_name, AirTree::wrap_clause(
subject_tipo.clone(), clause_assign_hoisted,
clause_assign_hoisted, self.handle_each_clause(
self.handle_each_clause( rest_clauses,
clauses, final_clause,
final_clause, subject_tipo,
subject_tipo, &mut next_clause_props,
&mut next_clause_props, ),
), )
next_tail_name, } else {
complex_clause, AirTree::list_clause(
); tail_name,
subject_tipo.clone(),
todo!(); clause_assign_hoisted,
self.handle_each_clause(
rest_clauses,
final_clause,
subject_tipo,
&mut next_clause_props,
),
next_tail_name,
complex_clause,
)
}
} }
SpecificClause::TupleClause { .. } => todo!(), SpecificClause::TupleClause { .. } => todo!(),
} }
@ -1328,10 +1371,12 @@ impl<'a> CodeGenerator<'a> {
.get(0) .get(0)
.unwrap_or_else(|| unreachable!("No list element type?")); .unwrap_or_else(|| unreachable!("No list element type?"));
let defined_tails = defined_tails.clone();
let elems = elements let elems = elements
.iter() .iter()
.enumerate() .enumerate()
.zip(defined_tails.clone()) .zip(defined_tails.iter())
.map(|((index, elem), tail)| { .map(|((index, elem), tail)| {
let elem_name = match elem { let elem_name = match elem {
Pattern::Var { name, .. } => name.to_string(), Pattern::Var { name, .. } => name.to_string(),
@ -1371,41 +1416,37 @@ impl<'a> CodeGenerator<'a> {
let mut list_tail = None; let mut list_tail = None;
tail.iter() tail.iter().for_each(|elem| {
.zip( let tail = defined_tails
defined_tails .last()
.clone() .unwrap_or_else(|| panic!("WHERE IS ME TAIL???"));
.get(defined_tails.clone().len() - 1) let elem_name = match elem.as_ref() {
.iter(), Pattern::Var { name, .. } => name.to_string(),
) Pattern::Assign { name, .. } => name.to_string(),
.for_each(|(elem, tail)| { Pattern::Discard { .. } => "_".to_string(),
let elem_name = match elem.as_ref() { _ => format!(
Pattern::Var { name, .. } => name.to_string(), "tail_span_{}_{}",
Pattern::Assign { name, .. } => name.to_string(), elem.location().start,
Pattern::Discard { .. } => "_".to_string(), elem.location().end
_ => format!( ),
"tail_span_{}_{}", };
elem.location().start,
elem.location().end
),
};
let mut elem_props = ClauseProperties { let mut elem_props = ClauseProperties {
clause_var_name: elem_name.clone(), clause_var_name: elem_name.clone(),
complex_clause: false, complex_clause: false,
needs_constr_var: false, needs_constr_var: false,
original_subject_name: elem_name.clone(), original_subject_name: elem_name.clone(),
final_clause: props.final_clause, final_clause: props.final_clause,
specific_clause: props.specific_clause.clone(), specific_clause: props.specific_clause.clone(),
}; };
let statement = let statement =
self.nested_clause_condition(elem, subject_tipo, &mut elem_props); self.nested_clause_condition(elem, subject_tipo, &mut elem_props);
*complex_clause = *complex_clause || elem_props.complex_clause; *complex_clause = *complex_clause || elem_props.complex_clause;
air_elems.push(statement); air_elems.push(statement);
list_tail = Some((tail.to_string(), elem_name)); list_tail = Some((tail.to_string(), elem_name));
}); });
let list_assign = AirTree::list_expose( let list_assign = AirTree::list_expose(
defined_tail_heads, defined_tail_heads,