fix: optmizer should never inline recursive functions
chore: some renames
chore: some renames
pub mod shrinker;
pub fn aiken_optimize_and_intern(program: Program<Name>) -> Program<Name> {
let mut program = program.builtin_force_reduce();
let mut program = program.builtin_force_reducer();
let mut interner = Interner::new();
let program: Program<Name> = program_named.try_into().unwrap();
program
.lambda_reduce()
.inline_reduce()
.lambda_reduce()
.inline_reduce()
.force_delay_reduce()
.wrap_data_reduce()
.lambda_reduce()
.inline_reduce()
.lambda_reduce()
.inline_reduce()
.lambda_reducer()
.inline_reducer()
.lambda_reducer()
.inline_reducer()
.force_delay_reducer()
.cast_data_reducer()
.lambda_reducer()
.inline_reducer()
.lambda_reducer()
.inline_reducer()
}
}
impl Program<Name> {
pub fn lambda_reduce(self) -> Program<Name> {
pub fn lambda_reducer(self) -> Program<Name> {
let mut term = self.term;
lambda_reduce(&mut term);
lambda_reducer(&mut term);
Program {
version: self.version,
term,
}
}
pub fn builtin_force_reduce(self) -> Program<Name> {
pub fn builtin_force_reducer(self) -> Program<Name> {
let mut term = self.term;
let mut builtin_map = IndexMap::new();
builtin_force_reduce(&mut term, &mut builtin_map);
builtin_force_reducer(&mut term, &mut builtin_map);
for default_func_index in builtin_map.keys().sorted().cloned() {
let default_func: DefaultFunction = default_func_index.try_into().unwrap();
}
}
pub fn inline_reduce(self) -> Program<Name> {
pub fn inline_reducer(self) -> Program<Name> {
let mut term = self.term;
inline_basic_reduce(&mut term);
inline_direct_reduce(&mut term);
inline_identity_reduce(&mut term);
inline_single_occurrence_reducer(&mut term);
inline_direct_reducer(&mut term);
inline_identity_reducer(&mut term);
Program {
version: self.version,
term,
}
}
pub fn force_delay_reduce(self) -> Program<Name> {
pub fn force_delay_reducer(self) -> Program<Name> {
let mut term = self.term;
force_delay_reduce(&mut term);
force_delay_reducer(&mut term);
Program {
version: self.version,
term,
}
}
pub fn wrap_data_reduce(self) -> Program<Name> {
pub fn cast_data_reducer(self) -> Program<Name> {
let mut term = self.term;
wrap_data_reduce(&mut term);
cast_data_reducer(&mut term);
Program {
version: self.version,
term,
}
}
}
fn builtin_force_reduce(term: &mut Term<Name>, builtin_map: &mut IndexMap<u8, ()>) {
fn builtin_force_reducer(term: &mut Term<Name>, builtin_map: &mut IndexMap<u8, ()>) {
match term {
Term::Force(f) => {
let f = Rc::make_mut(f);
}
_ => {}
}
builtin_force_reduce(f, builtin_map);
builtin_force_reducer(f, builtin_map);
}
Term::Delay(d) => {
let d = Rc::make_mut(d);
builtin_force_reduce(d, builtin_map);
builtin_force_reducer(d, builtin_map);
}
Term::Lambda { body, .. } => {
let body = Rc::make_mut(body);
builtin_force_reduce(body, builtin_map);
builtin_force_reducer(body, builtin_map);
}
Term::Apply { function, argument } => {
let func = Rc::make_mut(function);
builtin_force_reduce(func, builtin_map);
builtin_force_reducer(func, builtin_map);
let arg = Rc::make_mut(argument);
builtin_force_reduce(arg, builtin_map);
builtin_force_reducer(arg, builtin_map);
}
Term::Case { .. } => todo!(),
Term::Constr { .. } => todo!(),
_ => {}
}
}
fn force_delay_reduce(term: &mut Term<Name>) {
fn force_delay_reducer(term: &mut Term<Name>) {
match term {
Term::Force(f) => {
let f = Rc::make_mut(f);
if let Term::Delay(body) = f {
*term = body.as_ref().clone();
force_delay_reduce(term);
force_delay_reducer(term);
} else {
force_delay_reduce(f);
force_delay_reducer(f);
}
}
Term::Delay(d) => {
let d = Rc::make_mut(d);
force_delay_reduce(d);
force_delay_reducer(d);
}
Term::Lambda { body, .. } => {
let body = Rc::make_mut(body);
force_delay_reduce(body);
force_delay_reducer(body);
}
Term::Apply { function, argument } => {
let func = Rc::make_mut(function);
force_delay_reduce(func);
force_delay_reducer(func);
let arg = Rc::make_mut(argument);
force_delay_reduce(arg);
force_delay_reducer(arg);
}
Term::Case { .. } => todo!(),
Term::Constr { .. } => todo!(),
_ => {}
}
}
fn inline_direct_reduce(term: &mut Term<Name>) {
fn lambda_reducer(term: &mut Term<Name>) {
match term {
// TODO: change this to handle any amount of consecutive applies and lambdas
Term::Apply { function, argument } => {
let func = Rc::make_mut(function);
lambda_reducer(func);
let arg = Rc::make_mut(argument);
lambda_reducer(arg);
if let Term::Lambda {
parameter_name,
body,
} = func
{
if let replace_term @ (Term::Var(_) | Term::Constant(_) | Term::Builtin(_)) = arg {
let body = Rc::make_mut(body);
*term = substitute_term(body, parameter_name.clone(), replace_term);
}
}
}
Term::Delay(d) => {
let d = Rc::make_mut(d);
lambda_reducer(d);
}
Term::Lambda { body, .. } => {
let body = Rc::make_mut(body);
lambda_reducer(body);
}
Term::Force(f) => {
let f = Rc::make_mut(f);
lambda_reducer(f);
}
Term::Case { .. } => todo!(),
Term::Constr { .. } => todo!(),
_ => {}
}
}
fn inline_direct_reducer(term: &mut Term<Name>) {
match term {
Term::Delay(d) => {
let d = Rc::make_mut(d);
inline_direct_reduce(d);
inline_direct_reducer(d);
}
Term::Lambda { body, .. } => {
let body = Rc::make_mut(body);
inline_direct_reduce(body);
inline_direct_reducer(body);
}
Term::Apply { function, argument } => {
let func = Rc::make_mut(function);
let arg = Rc::make_mut(argument);
Alonzo builds