PreviousUpNext

15.4.454  src/lib/compiler/back/top/anormcode/anormcode-junk.pkg

## anormcode-junk.pkg 

# Compiled by:
#     src/lib/compiler/core.sublib

package highcodeint_map
    =
    int_binary_map;                                                     # int_binary_map                is from   src/lib/src/int-binary-map.pkg


stipulate
    package acf =  anormcode_form;                                      # anormcode_form                is from   src/lib/compiler/back/top/anormcode/anormcode-form.pkg
    package hct =  highcode_type;                                       # highcode_type                 is from   src/lib/compiler/back/top/highcode/highcode-type.pkg
    package hut =  highcode_uniq_types;                                 # highcode_uniq_types           is from   src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg
    package tmp =  highcode_codetemp;                                   # highcode_codetemp             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
herein

    api Anormcode_Junk {
        #
        rk_tuple:  acf::Record_Kind;

        make__make_exception_tag:   hut::Uniqtype -> acf::Baseop;
        make__wrap:                 hut::Uniqtype -> acf::Baseop;
        make__unwrap:               hut::Uniqtype -> acf::Baseop;

        wrap_primop
            :
            ( hut::Uniqtype,
              List( acf::Value ),
              tmp::Codetemp,
              acf::Expression
            )
            ->
            acf::Expression;


        unwrap_primop
            :
            ( hut::Uniqtype,
              List( acf::Value ),
              tmp::Codetemp,
              acf::Expression
            )
            ->
            acf::Expression;

        get_etag_type:     acf::Baseop -> hut::Uniqtype;
        get_wrap_type:     acf::Baseop -> hut::Uniqtype;
        get_un_wrap_type:  acf::Baseop -> hut::Uniqtype;


        # Copy a Expression with alpha renaming.
        # Free variables remain unchanged except for the renaming specified
        # in the first (types) and second (values) argument */

        copy:
            List( (tmp::Codetemp, hut::Uniqtype) )
            ->
            highcodeint_map::Map( tmp::Codetemp )
            ->
            acf::Expression
            ->
            acf::Expression;



        copyfdec
            :
            acf::Function
            ->
            acf::Function;



        freevars
            :
            acf::Expression
            ->
            int_red_black_set::Set;



        valcon_eq
            :
            ( acf::Valcon,
              acf::Valcon
            )
            ->
            Bool;

    };                                                  # api Anormcode_Utilities
end;                                                    # stipulate


stipulate
    package acf =  anormcode_form;              # anormcode_form                is from   src/lib/compiler/back/top/anormcode/anormcode-form.pkg
    package err =  error_message;               # error_message                 is from   src/lib/compiler/front/basics/errormsg/error-message.pkg
    package hbo =  highcode_baseops;            # highcode_baseops              is from   src/lib/compiler/back/top/highcode/highcode-baseops.pkg
    package hcf =  highcode_form;               # highcode_form                 is from   src/lib/compiler/back/top/highcode/highcode-form.pkg
    package him =  highcodeint_map;             # highcodeint_map               is from   src/lib/compiler/back/top/anormcode/anormcode-junk.pkg
    package is  =  int_red_black_set;           # int_red_black_set             is from   src/lib/src/int-red-black-set.pkg
    package lms =  list_mergesort;              # list_mergesort                is from   src/lib/src/list-mergesort.pkg
    package no  =  null_or;                     # null_or                       is from   src/lib/std/src/null-or.pkg
    package tmp =  highcode_codetemp;           # highcode_codetemp             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package vh  =  varhome;                     # varhome                       is from   src/lib/compiler/front/typer-stuff/basics/varhome.pkg
herein 

    package  anormcode_junk
    : (weak) Anormcode_Junk                     # Anormcode_Junk                is from   src/lib/compiler/back/top/anormcode/anormcode-junk.pkg
    {

        fun bug msg
            =
            err::impossible("anormcode_junk: " + msg);


        my rk_tuple:  acf::Record_Kind
            =
            acf::RK_TUPLE (hcf::useless_recordflag);

        # A set of useful baseops used by highcode 
        #
        tv0  = hcf::make_typevar_i_uniqtypoid 0;
        btv0 = hcf::make_type_uniqtypoid (hcf::make_boxed_uniqtype (hcf::make_typevar_i_uniqtype 0));

        etag_lty
            = 
            hcf::make_lambdacode_typeagnostic_uniqtypoid
              (
                [ hcf::plaintype_uniqkind ], 
                #
                hcf::make_arrow_uniqtypoid
                  (
                    hcf::rawraw_variable_calling_convention,
                    [ hcf::string_uniqtypoid ], 
                    [ hcf::make_exception_tag_uniqtypoid  tv0 ]
                  )
              );

        fun wrap_lty tc
            =
            hcf::make_type_uniqtypoid (hcf::make_arrow_uniqtype (hcf::fixed_calling_convention, [tc], [hcf::make_extensible_token_uniqtype tc]));

        fun unwrap_lty tc
            =
            hcf::make_type_uniqtypoid (hcf::make_arrow_uniqtype (hcf::fixed_calling_convention, [hcf::make_extensible_token_uniqtype tc], [tc]));

        fun make__make_exception_tag tc =   (NULL, hbo::MAKE_EXCEPTION_TAG, etag_lty,    [tc]);
        fun make__wrap               tc =   (NULL, hbo::WRAP,               wrap_lty tc, []  );
        fun make__unwrap             tc =   (NULL, hbo::UNWRAP,           unwrap_lty tc, []  );

        fun wrap_primop   (tc, vs, v, e) =   acf::BASEOP (  make__wrap tc, vs, v, e);
        fun unwrap_primop (tc, vs, v, e) =   acf::BASEOP (make__unwrap tc, vs, v, e);

        # The corresponding utility functions
        # to recover the Uniqtype:
        # 
        fun get_etag_type (_, _, lt, [tc])
                =>
                tc;

            get_etag_type (_, _, lt, [])
                => 
                {   nt =  hcf::unpack_type_uniqtypoid (#2 (hcf::unpack_lambdacode_arrow_uniqtypoid lt));

                    if (hcf::uniqtype_is_apply_typefun nt)
                        #                        
                        case (#2 (hcf::unpack_apply_typefun_uniqtype nt))
                            [x] =>  x;
                            _   =>  bug "unexpected case 1 in getEtagTypeConstructor";
                        esac;
                    else
                        hcf::truevoid_uniqtype;
                    fi;
                };

            get_etag_type _
                =>
                bug "unexpected case 2 in getEtagTypeConstructor";
        end;

        fun get_wrap_type (_, _, lt, []) =>  hcf::unpack_type_uniqtypoid (#1 (hcf::unpack_lambdacode_arrow_uniqtypoid lt));
            #
            get_wrap_type _              =>  bug "unexpected case in get_wrap_type";
        end;

        fun get_un_wrap_type (_, _, lt, []) =>   hcf::unpack_type_uniqtypoid (#2 (hcf::unpack_lambdacode_arrow_uniqtypoid lt));
            #
            get_un_wrap_type _              =>   bug "unexpected case in get_un_wrap_type";
        end;

        fun valcon_eq ((s1, c1, t1):       acf::Valcon, (s2, c2, t2))
            =
            symbol::eq (s1, s2)
            and (c1 == c2)
            and hcf::same_uniqtypoid (t1, t2);

        cplv =  tmp::clone_highcode_codetemp;


        # General alpha-conversion on Expression.
        # Free variables remain unchanged
        # except for the renaming specified in the first argument.
        #   my copy:  him::intmap( tmp::Codetemp ) -> Function_Declaration -> Function_Declaration
        #
        fun copy ta alpha le
            =
            copy' (tmap_sort ta)  alpha  le
            where

                tc_subst = hcf::tc_nvar_subst_fn();
                lt_subst = hcf::lt_nvar_subst_fn();

                tmap_sort = lms::sort_list  (\\ ((v1, _), (v2, _)) =  v1 > v2);

                fun substvar alpha lv
                    =
                    case (him::get (alpha, lv))
                        #
                        THE lv => lv;
                        noe    => lv;
                    esac;

                fun substval alpha (acf::VAR lv) =>   acf::VAR (substvar alpha lv);
                    substval alpha v             =>   v;
                end;

                fun newv (lv, alpha)
                    =
                    {   nlv = cplv lv;
                        (nlv, him::set (alpha, lv, nlv));
                    };

                fun newvs (lvs, alpha)
                    =
                    fold_backward
                        (\\ (lv, (lvs, alpha))
                            =
                            {   (newv (lv, alpha)) ->   (nlv, nalpha);
                                #
                                (nlv ! lvs, nalpha);
                            }
                        )
                        ([], alpha)
                        lvs;

                fun cdcon ta alpha (s, ac, lambda_type)
                    =
                    ( s,
                      case ac
                          #
                          vh::EXCEPTION (vh::HIGHCODE_VARIABLE lv) =>
                          vh::EXCEPTION (vh::HIGHCODE_VARIABLE (substvar alpha lv));

                          _ => ac;
                      esac,
                      lt_subst ta lambda_type
                    );

                fun cpo ta alpha (dictionary, po, lambda_type, types)
                    =
                    ( no::map
                          (\\ { default, table }
                               =
                               { default => substvar alpha default,
                                 table   => map (\\ (types, lv)
                                                    =
                                                    ( map (tc_subst ta) types,
                                                      substvar alpha lv
                                                    )
                                                )
                                                table
                               }
                          )
                          dictionary,

                      po,
                      lt_subst ta lambda_type,
                      map (tc_subst ta) types
                    );

                fun cfk ta { loop_info=>THE (ltys, lk), private, inlining_hint, call_as }
                        =>
                        { loop_info         =>  THE (map (lt_subst ta) ltys, lk),
                          private,
                          inlining_hint,
                          call_as
                        };

                    cfk _ fk
                        =>
                        fk;
                end;


                fun crk ta (acf::RK_VECTOR type)
                        =>
                        acf::RK_VECTOR (tc_subst ta type);

                    crk _ rk
                        =>
                        rk;
                end;


                fun copy' ta alpha le
                    =
                    {   cpo   =  cpo ta alpha;
                        cdcon =  cdcon ta alpha;

                        substvar =  substvar alpha;
                        substval =  substval alpha;

                        copy =  copy' ta;

                        case le
                            #
                            acf::RET vs =>   acf::RET (map substval vs);
                            #
                            acf::LET (lvs, le, body)
                                =>
                                {   nle = copy alpha le;
                                    my (nlvs, nalpha) = newvs (lvs, alpha);
                                    acf::LET (nlvs, nle, copy nalpha body);
                                };

                            acf::MUTUALLY_RECURSIVE_FNS (fdecs, le)
                                =>
                                {   fun cfun alpha ((fk, f, args, body):  acf::Function, nf)
                                        =
                                        {   (newvs (map #1 args, alpha)) ->   (nargs, nalpha);

                                            ( cfk ta fk,
                                              nf,
                                              paired_lists::zip (nargs, (map (lt_subst ta o #2) args)),
                                              copy nalpha body
                                            );
                                        };

                                    (newvs (map #2 fdecs, alpha)) ->   (nfs, nalpha);

                                    nfdecs =  paired_lists::map (cfun nalpha) (fdecs, nfs);

                                    acf::MUTUALLY_RECURSIVE_FNS (nfdecs, copy nalpha le);
                                };

                            acf::APPLY (f, args)
                                =>
                                acf::APPLY (substval f, map substval args);

                            acf::TYPEFUN ((tfk, lv, args, body), le)
                                =>
                                # Don't forget to rename the tvar also:
                                # 
                                {   my (nlv,   nalpha) = newv (lv, alpha);
                                    my (nargs, ialpha) = newvs (map #1 args, nalpha);

                                    ita = tmap_sort ( (paired_lists::map
                                                          (\\ ((t, k), nt) = (t, hcf::make_named_typevar_uniqtype nt))
                                                          (args, nargs)
                                                      )
                                                      @
                                                      ta
                                                    );

                                 acf::TYPEFUN
                                   (  ( tfk, nlv,
                                        paired_lists::zip (nargs, map #2 args),
                                        copy' ita ialpha body
                                       ),
                                       copy nalpha le
                                   );
                                };

                            acf::APPLY_TYPEFUN (f, types)
                                =>
                                acf::APPLY_TYPEFUN (substval f, map (tc_subst ta) types);

                            acf::SWITCH (v, ac, arms, def)
                                =>
                                acf::SWITCH
                                  ( substval v,
                                    ac,
                                    map  carm  arms,
                                    null_or::map (copy alpha) def
                                  )
                                where
                                    fun carm (acf::VAL_CASETAG (dc, types, lv), le)             # "carm" might be "compile [SWITCH] arm" or such...?
                                            =>
                                            {   (newv (lv, alpha)) ->   (nlv, nalpha);

                                                ( acf::VAL_CASETAG (cdcon dc, map (tc_subst ta) types, nlv),
                                                  copy nalpha le
                                                );
                                            };

                                        carm (con, le)
                                            => (con, copy alpha le);
                                    end;
                                end;

                            acf::CONSTRUCTOR (dc, types, v, lv, le)
                                =>
                                {   my (nlv, nalpha) = newv (lv, alpha);
                                    acf::CONSTRUCTOR (cdcon dc, map (tc_subst ta) types, substval v, nlv, copy nalpha le);
                                };

                            acf::RECORD (rk, vs, lv, le)
                                => 
                                {   my (nlv, nalpha) = newv (lv, alpha);
                                    acf::RECORD (crk ta rk, map substval vs, nlv, copy nalpha le);
                                };

                            acf::GET_FIELD (v, i, lv, le)
                                => 
                                {   (newv (lv, alpha)) ->   (nlv, nalpha);
                                    #
                                    acf::GET_FIELD (substval v, i, nlv, copy nalpha le);
                                };

                            acf::RAISE (v, ltys)
                                =>
                                acf::RAISE (substval v, map (lt_subst ta) ltys);

                            acf::EXCEPT (le, v)
                                =>
                                acf::EXCEPT (copy alpha le, substval v);

                            acf::BRANCH (po, vs, le1, le2)
                                =>
                                acf::BRANCH (cpo po, map substval vs, copy alpha le1, copy alpha le2);

                            acf::BASEOP (po, vs, lv, le)
                                =>
                                {   (newv (lv, alpha)) ->   (nlv, nalpha);

                                    acf::BASEOP (cpo po, map substval vs, nlv, copy nalpha le);
                                };
                        esac;
                    };
            end;


        fun copyfdec fdec
            =
            case (copy  []  him::empty  (acf::MUTUALLY_RECURSIVE_FNS([fdec], acf::RET [])))
                #             
                acf::MUTUALLY_RECURSIVE_FNS ([new_fdec], acf::RET [])
                    =>
                    new_fdec;

                _   =>   bug "copyfdec";
            esac;


        fun freevars lambda_expression
            =
            {   loop = freevars;
                #
                fun s_rmv (x, s)
                    =
                    is::drop (s, x);

                fun addv (s, acf::VAR lv) =>   is::add (s, lv);
                    addv (s, _          ) =>            s;
                end;


                fun addvs (s, vs) =  fold_forward (\\ (v, s) = addv  (s, v))  s  vs;
                fun rmvs (s, lvs) =  fold_forward (\\ (l, s) = s_rmv (l, s))  s  lvs;


                fun singleton (acf::VAR v) =>   is::singleton v;
                    singleton _            =>   is::empty;
                end;


                fun fpo (fv, (NULL: Null_Or( acf::Dictionary ), po, lambda_type, types))
                        =>
                        fv;

                    fpo (fv, (THE { default, table }, po, lambda_type, types))
                        =>
                        addvs (addv (fv, acf::VAR default), map (acf::VAR o #2) table);
                end;


                fun fdcon (fv, (s, varhome::EXCEPTION (varhome::HIGHCODE_VARIABLE lv), lambda_type))
                        =>
                        addv (fv, acf::VAR lv);

                    fdcon (fv, _)
                        =>
                        fv;
                end;


                case lambda_expression
                    #             
                    acf::RET vs
                        =>
                        addvs (is::empty, vs);

                    acf::LET (lvs, body, le)
                        =>
                        is::union (rmvs (loop le, lvs), loop body);

                    acf::MUTUALLY_RECURSIVE_FNS (fdecs, le)
                        =>
                        rmvs ( (fold_forward
                                   (\\ ((_, _, args, body), fv)
                                       =
                                       is::union (rmvs (loop body, map #1 args), fv)
                                   )
                                   (loop le)
                                   fdecs
                               ),
                               map #2 fdecs
                             );

                    acf::APPLY (f, args)
                        =>
                        addvs (is::empty, f ! args);

                    acf::TYPEFUN ((tfk, f, args, body), le)
                        =>
                        is::union (s_rmv (f, loop le), loop body);

                    acf::APPLY_TYPEFUN (f, args)
                        =>
                        singleton f;

                    acf::SWITCH (v, ac, arms, def)
                        =>
                        fold_forward farm fvs arms
                        where
                            fun farm ((dc, le), fv)
                                =
                                {   fvle = loop le;

                                    is::union
                                      (
                                        fv,
                                        case dc
                                            acf::VAL_CASETAG (dc, _, lv) =>  fdcon (s_rmv (lv, fvle), dc);
                                            _                            =>  fvle;
                                        esac
                                      );
                                };

                            fvs = case def    NULL   =>  singleton v;
                                              THE le =>  addv (loop le, v);
                                  esac;
                        end;

                    acf::CONSTRUCTOR (dc, types, v, lv, le)
                        =>
                        fdcon (addv (s_rmv (lv, loop le), v), dc);

                    acf::RECORD (rk, vs, lv, le)
                        =>
                        addvs (s_rmv (lv, loop le), vs);

                    acf::GET_FIELD (v, i, lv, le)
                        =>
                        addv (s_rmv (lv, loop le), v);

                    acf::RAISE (v, ltys)
                        =>
                        singleton v;

                    acf::EXCEPT (le, v)
                        =>
                        addv (loop le, v);

                    acf::BRANCH (po, vs, le1, le2)
                        =>
                        fpo (addvs (is::union (loop le1, loop le2), vs), po);

                    acf::BASEOP (po, vs, lv, le)
                        =>
                        fpo (addvs (s_rmv (lv, loop le), vs), po);
                esac;

            };                                                                  # fun freevars
    };                                                                          # package anormcode_junk 
end;                                                                            # stipulate


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext