## unnest-nextcode-fns.pkg
#
# This file implements one of the nextcode transforms.
# For context, see the comments in
#
#
src/lib/compiler/back/top/highcode/highcode-form.api#
# Overview: In this pass we eliminate the ncf::DEFINE_FUNS nodes from nextcode-form.
#
# Details: In nextcode-form we use ncf::DEFINE_FUNS nodes to define one or more functions
# over a given scope -- which is to say, to nest functions within each other.
#
# In this pass we eliminate those nodes and thus the scoping relationships,
# reducing the code to a flat list of functions.
# Compiled by:
#
src/lib/compiler/core.sublib# "Do not worry about your problems with mathematics,
# I assure you mine are far greater."
#
# --Albert Einstein
stipulate
package ncf = nextcode_form; # nextcode_form is from
src/lib/compiler/back/top/nextcode/nextcode-form.pkgherein
api Unnest_Nextcode_Fns {
#
unnest_nextcode_fns: ncf::Function -> List( ncf::Function );
};
end;
stipulate
package ncf = nextcode_form; # nextcode_form is from
src/lib/compiler/back/top/nextcode/nextcode-form.pkgherein
# This package is referenced (only) in:
#
#
src/lib/compiler/back/top/main/backend-tophalf-g.pkg #
package unnest_nextcode_fns
: (weak) Unnest_Nextcode_Fns # Unnest_Nextcode_Fns is from
src/lib/compiler/back/top/closures/unnest-nextcode-fns.pkg {
fun unnest_nextcode_fns (fk, f, vl, cl, cexp)
=
{ (gfix cexp) -> (l, body);
#
(fk, f, vl, cl, body) ! l;
}
where
fun gfix ce
=
case ce
#
ncf::DEFINE_FUNS { funs, next }
=>
{ (gfix next) -> (n, next');
l' = fold_forward
( \\ ((k, v, a, t, next), m)
=
{ (gfix next) -> (l, d);
#
(k, v, a, t, d) ! (l @ m);
}
)
n
funs;
(l', next');
};
# The remaining cases here just rewrite recursively
# without introducing any independent changes:
ncf::TAIL_CALL _ => ([], ce);
ncf::JUMPTABLE { i, xvar, nexts }
=>
{ my (f, nexts)
=
fold_backward
( \\ (c, (fl, cl))
=
{ (gfix c) -> (f, d);
( f @ fl,
d ! cl
);
}
)
#
([], [])
#
nexts;
(f, ncf::JUMPTABLE { i, xvar, nexts });
};
ncf::IF_THEN_ELSE { op, args, xvar, then_next, else_next }
=>
{ (gfix then_next) -> (f1, then_next);
(gfix else_next) -> (f2, else_next);
( f1 @ f2,
ncf::IF_THEN_ELSE { op, args, xvar, then_next, else_next }
);
};
ncf::DEFINE_RECORD { kind, fields, to_temp, next } => { (gfix next) -> (f, next); (f, ncf::DEFINE_RECORD { kind, fields, to_temp, next }); };
ncf::GET_FIELD_I { i, record, to_temp, type, next } => { (gfix next) -> (f, next); (f, ncf::GET_FIELD_I { i, record, type, to_temp, next }); };
ncf::GET_ADDRESS_OF_FIELD_I { i, record, to_temp, next } => { (gfix next) -> (f, next); (f, ncf::GET_ADDRESS_OF_FIELD_I { i, record, to_temp, next }); };
ncf::STORE_TO_RAM { op, args, next } => { (gfix next) -> (f, next); (f, ncf::STORE_TO_RAM { op, args, next }); };
ncf::FETCH_FROM_RAM { op, args, to_temp, type, next } => { (gfix next) -> (f, next); (f, ncf::FETCH_FROM_RAM { op, args, to_temp, type, next }); };
ncf::ARITH { op, args, to_temp, type, next } => { (gfix next) -> (f, next); (f, ncf::ARITH { op, args, to_temp, type, next }); };
ncf::PURE { op, args, to_temp, type, next } => { (gfix next) -> (f, next); (f, ncf::PURE { op, args, to_temp, type, next }); };
ncf::RAW_C_CALL { kind, cfun_name, cfun_type, args, to_ttemps, next }
=>
{ (gfix next) -> (f, next);
#
( f,
ncf::RAW_C_CALL { kind, cfun_name, cfun_type, args, to_ttemps, next }
);
};
esac;
end;
}; # package unnest_nextcode_fns
end;