PreviousUpNext

15.4.498  src/lib/compiler/back/top/improve/recover-anormcode-type-info.pkg

## recover-anormcode-type-info.pkg 
## Recover the type information of a closed highcode program 

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




###               "Honesty is for the most part
###                less profitable than dishonesty."
###
###                                -- Plato



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 tmp =  highcode_codetemp;                                   # highcode_codetemp             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package hut =  highcode_uniq_types;                                 # highcode_uniq_types           is from   src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg
herein

    api Recover_Anormcode_Type_Info {
        #
        recover_anormcode_type_info
            :
            ( acf::Function,
              Bool
            )
            -> 
            { get_uniqtypoid_for_anormcode_value:       acf::Value -> hut::Uniqtypoid,
              clean_up:                                 Void -> Void,
              add_lty:                                  (tmp::Codetemp, hut::Uniqtypoid) -> Void
            };
    };
end;


stipulate
    package acf =  anormcode_form;                                      # anormcode_form                is from   src/lib/compiler/back/top/anormcode/anormcode-form.pkg
    package di  =  debruijn_index;                                      # debruijn_index                is from   src/lib/compiler/front/typer/basics/debruijn-index.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 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 iht =  int_hashtable;                                       # int_hashtable                 is from   src/lib/src/int-hashtable.pkg
herein

    package   recover_anormcode_type_info
    : (weak)  Recover_Anormcode_Type_Info
    {
        fun bug s
            =
            error_message::impossible ("Recover_Type_Info: " + s);


        fun lt_inst (lt, ts)
            =
            case (hcf::apply_typeagnostic_type_to_arglist (lt, ts))
                #
                [x] => x;
                _   => bug "unexpected case in ltInst";
            esac;

        # These two functions are applicable to the types of primops and data
        # constructors only (ZHONG)

        fun arglty (lt, ts)
            = 
            {   my (_, atys, _)
                    =
                    hcf::unpack_arrow_uniqtypoid (lt_inst (lt, ts));

                case atys
                    #
                    [x] =>  x;
                    _   =>  bug "unexpected case in arglty";
                esac;
            };

        fun reslty (lt, ts)
            =
            {   my (_, _, rtys)
                    =
                    hcf::unpack_arrow_uniqtypoid (lt_inst (lt, ts));

                case rtys
                    #
                    [x] => x;
                    _   => bug "unexpected case in reslty";
                esac;
            };

        exception RECOVER_LTY;

        fun recover_anormcode_type_info
              (
                fdec:           acf::Function,
                post_rep:       Bool
              )
            =
            {   my zz:  iht::Hashtable( hut::Uniqtypoid )
                    =
                    iht::make_hashtable  { size_hint => 32,  not_found_exception => RECOVER_LTY };

              get  = iht::get  zz;
              addv = iht::set   zz;

              fun addvs vts
                  =
                  apply addv vts;

              fun get_uniqtypoid_for_anormcode_value (acf::VAR v                 ) =>  get v;
                  get_uniqtypoid_for_anormcode_value (acf::INT _   | acf::UNT   _) =>  hcf::int_uniqtypoid;
                  get_uniqtypoid_for_anormcode_value (acf::INT1 _ | acf::UNT1 _) =>  hcf::int1_uniqtypoid;
                  get_uniqtypoid_for_anormcode_value (acf::FLOAT64              _) =>  hcf::float64_uniqtypoid;
                  get_uniqtypoid_for_anormcode_value (acf::STRING               _) =>  hcf::string_uniqtypoid;
              end;

              lt_nvar_cvt = hcf::lt_nvar_cvt_fn();

              #  loop:  depth -> Lambda_Expression -> List( Uniqtypoid )
              # 
              fun loop e
                  = 
                  lpe e
                  where

                      fun lpv u =   get_uniqtypoid_for_anormcode_value u;

                      fun lpvs vs = map lpv vs;

                      fun lpd (fk, f, vts, e)
                          = 
                          {    addvs vts;
                               addv (f, hcf::ltc_fkfun (fk, map #2 vts, lpe e));
                          }

                      also
                      fun lpds (fds as ((fk as { loop_info=>THE _, ... }, _, _, _) ! _))
                              =>
                              {   apply  h  fds
                                  where
                                      fun h ((fk as { loop_info=>THE (rts, _), ... }, f, vts, _): acf::Function)
                                              => 
                                              addv (f, hcf::ltc_fkfun (fk, map #2 vts, rts)); 

                                          h _ => bug "unexpected case in lpds";
                                      end; 
                                  end;

                                  apply lpd fds;
                              };

                         lpds [fd] => lpd fd;
                         lpds _ => bug "unexpected case 2 in lpds";
                      end 

                      also
                      fun lpc (acf::VAL_CASETAG((_, _, lt), ts, v), e)
                              => 
                              {   addv (v, arglty (lt, ts));
                                  lpe e;
                              };

                          lpc (_, e)
                              =>
                              lpe e;
                      end 

                      also
                      fun lpe (acf::RET vs)
                              =>
                              lpvs vs;

                          lpe (acf::LET (vs, e1, e2))
                              => 
                              {   addvs (paired_lists::zip (vs, lpe e1));
                                  lpe e2;
                              };

                          lpe (acf::MUTUALLY_RECURSIVE_FNS (fdecs, e))
                              =>
                              {   lpds fdecs;
                                  lpe e;
                              };

                          lpe (acf::APPLY (u, vs))
                              =>
                              #2 (hcf::ltd_fkfun (lpv u));

                          lpe (acf::TYPEFUN((tfk, v, tvks, e1), e2))
                              => 
                              {   addv (v, hcf::lt_nvpoly (tvks, loop e1));
                                  lpe e2;
                              };

                          lpe (acf::APPLY_TYPEFUN (v, ts))
                              =>
                              hcf::apply_typeagnostic_type_to_arglist (lpv v, ts);

                          lpe (acf::RECORD (rk, vs, v, e))
                              => 
                              {   addv (v, hcf::ltc_rkind (rk, lpvs vs));
                                  lpe e;
                              };

                          lpe (acf::GET_FIELD (u, i, v, e))
                              => 
                              {   addv (v, hcf::ltd_rkind (lpv u, i));
                                  lpe e;
                              };

                          lpe (acf::CONSTRUCTOR((_, _, lt), ts, _, v, e))
                              => 
                              {   addv (v, reslty (lt, ts));
                                  lpe e;
                              };

                          lpe (acf::SWITCH(_, _, ces, e))
                              =>
                              {   lts = map lpc ces;

                                  case e      NULL  =>  head lts;
                                              THE e =>  lpe e;
                                  esac;
                             };

                          lpe (acf::RAISE (_, lts)) => lts;
                          lpe (acf::EXCEPT (e, _)) => lpe e;

                          lpe (acf::BRANCH (p, _, e1, e2))
                              => 
                              {   lpe e1;
                                  lpe e2;
                              };

                          lpe (acf::BASEOP((_, hbo::WCAST, lt, []), _, v, e))
                             => 
                              if (post_rep)
                                #
                                   case (hcf::unpack_generic_package_uniqtypoid lt)
                                       #
                                       ([_],[r]) =>  { addv (v, r); lpe e;};
                                       _         =>  bug "unexpected case for WCAST";
                                   esac;
                              else
                                   bug "unexpected baseop WCAST in recover_type_info";
                              fi;

                          lpe (acf::BASEOP((_, _, lt, ts), _, v, e))
                              => 
                              {   addv (v, reslty (lt, ts));
                                  lpe e;
                              };
                      end;


                end; #  while (fun transform)

                my (fkind, f, vts, e) = fdec;

                addvs vts;
                atys = map #2 vts;

                rtys = loop e;
                addv (f, hcf::ltc_fkfun (fkind, atys, rtys));

                { get_uniqtypoid_for_anormcode_value,
                  clean_up =>  \\ () = iht::clear zz,
                  add_lty  =>  addv
                };

            };                                                                  # function recover_anormcode_type_info 
    };                                                                          # package  recover_anormcode_type_info 
end;                                                                            # stipulate


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext