feat: Add boolean conditions to when statements

This commit is contained in:
Kasey White 2023-01-17 03:43:47 -05:00 committed by Lucas
parent 75808cc046
commit d7e4aef4c5
2 changed files with 218 additions and 155 deletions

View File

@ -24,6 +24,11 @@ pub enum Air {
bytes: Vec<u8>, bytes: Vec<u8>,
}, },
Bool {
scope: Vec<u64>,
value: bool,
},
Var { Var {
scope: Vec<u64>, scope: Vec<u64>,
constructor: ValueConstructor, constructor: ValueConstructor,
@ -228,6 +233,7 @@ impl Air {
Air::Int { scope, .. } Air::Int { scope, .. }
| Air::String { scope, .. } | Air::String { scope, .. }
| Air::ByteArray { scope, .. } | Air::ByteArray { scope, .. }
| Air::Bool { scope, .. }
| Air::Var { scope, .. } | Air::Var { scope, .. }
| Air::List { scope, .. } | Air::List { scope, .. }
| Air::ListAccessor { scope, .. } | Air::ListAccessor { scope, .. }

View File

@ -838,12 +838,19 @@ impl<'a> CodeGenerator<'a> {
let mut temp_clause_properties = clause_properties.clone(); let mut temp_clause_properties = clause_properties.clone();
*temp_clause_properties.needs_constr_var() = false; *temp_clause_properties.needs_constr_var() = false;
if tipo.is_bool() {
pattern_vec.push(Air::Bool {
scope,
value: constr_name == "True",
});
} else {
for arg in arguments { for arg in arguments {
check_when_pattern_needs(&arg.value, &mut temp_clause_properties); check_when_pattern_needs(&arg.value, &mut temp_clause_properties);
} }
// find data type definition // find data type definition
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); let data_type =
lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
let (index, _) = data_type let (index, _) = data_type
.constructors .constructors
@ -892,7 +899,7 @@ impl<'a> CodeGenerator<'a> {
scope, scope,
); );
} }
}
pattern_vec.append(values); pattern_vec.append(values);
// unify clause properties // unify clause properties
@ -2684,6 +2691,10 @@ impl<'a> CodeGenerator<'a> {
let term = Term::Constant(UplcConstant::ByteString(bytes)); let term = Term::Constant(UplcConstant::ByteString(bytes));
arg_stack.push(term); arg_stack.push(term);
} }
Air::Bool { value, .. } => {
let term = Term::Constant(UplcConstant::Bool(value));
arg_stack.push(term);
}
Air::Var { Air::Var {
name, name,
constructor, constructor,
@ -3626,6 +3637,27 @@ impl<'a> CodeGenerator<'a> {
// the next branch in the when expression // the next branch in the when expression
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
if tipo.is_bool() {
if matches!(clause, Term::Constant(UplcConstant::Bool(true))) {
term = delayed_if_else(
Term::Var(Name {
text: subject_name,
unique: 0.into(),
}),
body,
term,
);
} else {
term = delayed_if_else(
Term::Var(Name {
text: subject_name,
unique: 0.into(),
}),
term,
body,
);
}
} else {
let checker = if tipo.is_int() { let checker = if tipo.is_int() {
apply_wrap( apply_wrap(
DefaultFunction::EqualsInteger.into(), DefaultFunction::EqualsInteger.into(),
@ -3642,8 +3674,6 @@ impl<'a> CodeGenerator<'a> {
unique: 0.into(), unique: 0.into(),
}), }),
) )
} else if tipo.is_bool() {
todo!("Bool in when statements not done yet")
} else if tipo.is_string() { } else if tipo.is_string() {
apply_wrap( apply_wrap(
DefaultFunction::EqualsString.into(), DefaultFunction::EqualsString.into(),
@ -3687,6 +3717,7 @@ impl<'a> CodeGenerator<'a> {
} else { } else {
term = delayed_if_else(apply_wrap(checker, clause), body, term); term = delayed_if_else(apply_wrap(checker, clause), body, term);
} }
}
arg_stack.push(term); arg_stack.push(term);
} }
@ -3767,6 +3798,34 @@ impl<'a> CodeGenerator<'a> {
let then = arg_stack.pop().unwrap(); let then = arg_stack.pop().unwrap();
if tipo.is_bool() {
let mut term = Term::Var(Name {
text: "__other_clauses_delayed".to_string(),
unique: 0.into(),
});
if matches!(condition, Term::Constant(UplcConstant::Bool(true))) {
term = if_else(
Term::Var(Name {
text: subject_name,
unique: 0.into(),
}),
Term::Delay(then.into()),
term,
)
.force_wrap();
} else {
term = if_else(
Term::Var(Name {
text: subject_name,
unique: 0.into(),
}),
term,
Term::Delay(then.into()),
)
.force_wrap();
}
arg_stack.push(term);
} else {
let checker = if tipo.is_int() { let checker = if tipo.is_int() {
apply_wrap( apply_wrap(
DefaultFunction::EqualsInteger.into(), DefaultFunction::EqualsInteger.into(),
@ -3783,8 +3842,6 @@ impl<'a> CodeGenerator<'a> {
unique: 0.into(), unique: 0.into(),
}), }),
) )
} else if tipo.is_bool() {
todo!("Nested bool usage in when statements not yet implemented")
} else if tipo.is_string() { } else if tipo.is_string() {
apply_wrap( apply_wrap(
DefaultFunction::EqualsString.into(), DefaultFunction::EqualsString.into(),
@ -3814,9 +3871,9 @@ impl<'a> CodeGenerator<'a> {
}), }),
) )
.force_wrap(); .force_wrap();
arg_stack.push(term); arg_stack.push(term);
} }
}
Air::ListClauseGuard { Air::ListClauseGuard {
tail_name, tail_name,
next_tail_name, next_tail_name,