cleanup if then else a bit
This commit is contained in:
parent
eddd202253
commit
e6c59dca2c
|
@ -4,7 +4,10 @@ use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{
|
ast::{
|
||||||
builder::{self, constr_index_exposer, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD},
|
builder::{
|
||||||
|
self, constr_index_exposer, delayed_if_else, if_else, CONSTR_FIELDS_EXPOSER,
|
||||||
|
CONSTR_GET_FIELD,
|
||||||
|
},
|
||||||
Constant as UplcConstant, Name, Program, Term, Type as UplcType,
|
Constant as UplcConstant, Name, Program, Term, Type as UplcType,
|
||||||
},
|
},
|
||||||
builtins::DefaultFunction,
|
builtins::DefaultFunction,
|
||||||
|
@ -2453,80 +2456,24 @@ impl<'a> CodeGenerator<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let term = match name {
|
let term = match name {
|
||||||
BinOp::And => Term::Apply {
|
BinOp::And => {
|
||||||
function: Term::Apply {
|
delayed_if_else(left, right, Term::Constant(UplcConstant::Bool(false)))
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: left.into(),
|
|
||||||
}
|
}
|
||||||
.into(),
|
BinOp::Or => {
|
||||||
argument: Term::Delay(right.into()).into(),
|
delayed_if_else(left, Term::Constant(UplcConstant::Bool(true)), right)
|
||||||
}
|
}
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(Term::Constant(UplcConstant::Bool(false)).into())
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.force_wrap(),
|
|
||||||
BinOp::Or => Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: left.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(Term::Constant(UplcConstant::Bool(true)).into())
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(right.into()).into(),
|
|
||||||
}
|
|
||||||
.force_wrap(),
|
|
||||||
BinOp::Eq => {
|
BinOp::Eq => {
|
||||||
if tipo.is_bool() {
|
if tipo.is_bool() {
|
||||||
let term = Term::Force(
|
let term = delayed_if_else(
|
||||||
Term::Apply {
|
left,
|
||||||
function: Term::Apply {
|
right.clone(),
|
||||||
function: Term::Apply {
|
if_else(
|
||||||
function: Term::Force(
|
right,
|
||||||
Term::Builtin(DefaultFunction::IfThenElse).into(),
|
Term::Constant(UplcConstant::Bool(false)),
|
||||||
)
|
Term::Constant(UplcConstant::Bool(true)),
|
||||||
.into(),
|
),
|
||||||
argument: left.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(right.clone().into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Force(
|
|
||||||
Term::Builtin(DefaultFunction::IfThenElse)
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
argument: right.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Constant(UplcConstant::Bool(false))
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Constant(UplcConstant::Bool(true))
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
return;
|
return;
|
||||||
} else if tipo.is_map() {
|
} else if tipo.is_map() {
|
||||||
|
@ -2636,50 +2583,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
BinOp::NotEq => {
|
BinOp::NotEq => {
|
||||||
if tipo.is_bool() {
|
if tipo.is_bool() {
|
||||||
let term = Term::Force(
|
let term = delayed_if_else(
|
||||||
Term::Apply {
|
left,
|
||||||
function: Term::Apply {
|
if_else(
|
||||||
function: Term::Apply {
|
right.clone(),
|
||||||
function: Term::Force(
|
Term::Constant(UplcConstant::Bool(false)),
|
||||||
Term::Builtin(DefaultFunction::IfThenElse).into(),
|
Term::Constant(UplcConstant::Bool(true)),
|
||||||
)
|
),
|
||||||
.into(),
|
right,
|
||||||
argument: left.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Force(
|
|
||||||
Term::Builtin(
|
|
||||||
DefaultFunction::IfThenElse,
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
argument: right.clone().into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Constant(UplcConstant::Bool(
|
|
||||||
false,
|
|
||||||
))
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Constant(UplcConstant::Bool(true))
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(right.into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
return;
|
return;
|
||||||
} else if tipo.is_map() {
|
} else if tipo.is_map() {
|
||||||
|
@ -3156,28 +3068,18 @@ impl<'a> CodeGenerator<'a> {
|
||||||
text: "__other_clauses_delayed".to_string(),
|
text: "__other_clauses_delayed".to_string(),
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
},
|
},
|
||||||
body: Term::Apply {
|
body: if_else(
|
||||||
function: Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: checker.into(),
|
function: checker.into(),
|
||||||
argument: clause.into(),
|
argument: clause.into(),
|
||||||
}
|
},
|
||||||
.into(),
|
Term::Delay(body.into()),
|
||||||
}
|
Term::Var(Name {
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(body.into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Var(Name {
|
|
||||||
text: "__other_clauses_delayed".to_string(),
|
text: "__other_clauses_delayed".to_string(),
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})
|
}),
|
||||||
.into(),
|
)
|
||||||
}
|
.force_wrap()
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -3185,23 +3087,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
} else {
|
} else {
|
||||||
term = Term::Apply {
|
term = delayed_if_else(
|
||||||
function: Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Force(DefaultFunction::IfThenElse.into()).into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: checker.into(),
|
function: checker.into(),
|
||||||
argument: clause.into(),
|
argument: clause.into(),
|
||||||
}
|
},
|
||||||
.into(),
|
body,
|
||||||
}
|
term,
|
||||||
.into(),
|
);
|
||||||
argument: Term::Delay(body.into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(term.into()).into(),
|
|
||||||
}
|
|
||||||
.force_wrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
|
@ -3316,28 +3209,17 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let term = Term::Apply {
|
let term = if_else(
|
||||||
function: Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: checker.into(),
|
function: checker.into(),
|
||||||
argument: condition.into(),
|
argument: condition.into(),
|
||||||
}
|
},
|
||||||
.into(),
|
Term::Delay(then.into()),
|
||||||
}
|
Term::Var(Name {
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(then.into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Var(Name {
|
|
||||||
text: "__other_clauses_delayed".to_string(),
|
text: "__other_clauses_delayed".to_string(),
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})
|
}),
|
||||||
.into(),
|
)
|
||||||
}
|
|
||||||
.force_wrap();
|
.force_wrap();
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
|
@ -3350,23 +3232,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let then = arg_stack.pop().unwrap();
|
let then = arg_stack.pop().unwrap();
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
term = Term::Force(
|
term = delayed_if_else(condition, then, term);
|
||||||
Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: condition.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(then.into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Delay(term.into()).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
@ -3647,20 +3513,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Air::Negate { .. } => {
|
Air::Negate { .. } => {
|
||||||
let value = arg_stack.pop().unwrap();
|
let value = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
let term = Term::Apply {
|
let term = if_else(
|
||||||
function: Term::Apply {
|
value,
|
||||||
function: Term::Apply {
|
Term::Constant(UplcConstant::Bool(false)),
|
||||||
function: Term::Builtin(DefaultFunction::IfThenElse)
|
Term::Constant(UplcConstant::Bool(true)),
|
||||||
.force_wrap()
|
);
|
||||||
.into(),
|
|
||||||
argument: value.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Constant(UplcConstant::Bool(false)).into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
argument: Term::Constant(UplcConstant::Bool(true)).into(),
|
|
||||||
};
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
Air::TupleAccessor { tipo, names, .. } => {
|
Air::TupleAccessor { tipo, names, .. } => {
|
||||||
|
|
|
@ -266,3 +266,42 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delayed_if_else(
|
||||||
|
condition: Term<Name>,
|
||||||
|
then_term: Term<Name>,
|
||||||
|
else_term: Term<Name>,
|
||||||
|
) -> Term<Name> {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: condition.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(then_term.into()).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(else_term.into()).into(),
|
||||||
|
}
|
||||||
|
.force_wrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn if_else(condition: Term<Name>, then_term: Term<Name>, else_term: Term<Name>) -> Term<Name> {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: condition.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: then_term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: else_term.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue