PreviousUpNext

15.4.464  src/lib/compiler/back/top/closures/unnest-nextcode-fns.pkg

## 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.pkg
herein

    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.pkg
herein

    # 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;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext