PreviousUpNext

15.4.473  src/lib/compiler/back/top/forms/make-anormcode-equality-fn.pkg

## make-anormcode-equality-fn.pkg 
#
# Constructing generic equality functions. The current version will
# use runtime polyequal function to deal with abstract types. (ZHONG)
#
# We're invoked only from:
#
#     src/lib/compiler/back/top/forms/insert-anormcode-boxing-and-coercion-code.pkg

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



###                 "Every child is an artist. The problem is
###                  how to remain an artist once he grows up."
###
###                                    -- Pablo Picasso



stipulate
    package acf =  anormcode_form;                              # anormcode_form                        is from   src/lib/compiler/back/top/anormcode/anormcode-form.pkg
herein

    api Make_Anormcode_Equality_Fn {
        #

        make_equal_branch_fn
          :
          ( acf::Baseop,
            List( acf::Value ),
            acf::Expression,
            acf::Expression
          )
          ->
          acf::Expression;

        debugging:  Ref(  Bool );     
    };
end;


stipulate
    package acf =  anormcode_form;                              # anormcode_form                is from   src/lib/compiler/back/top/anormcode/anormcode-form.pkg
    package acj =  anormcode_junk;                              # anormcode_junk                is from   src/lib/compiler/back/top/anormcode/anormcode-junk.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 hbt =  highcode_basetypes;                          # highcode_basetypes            is from   src/lib/compiler/back/top/highcode/highcode-basetypes.pkg
    package pp  =  prettyprint;                                 # prettyprint                   is from   src/lib/prettyprint/big/src/prettyprint.pkg
    package ty  =  types;                                       # types                         is from   src/lib/compiler/front/typer-stuff/types/types.pkg
    package tt  =  type_types;
herein

    package   make_anormcode_equality_fn
    : (weak)  Make_Anormcode_Equality_Fn                        # Make_Anormcode_Equality_Fn    is from   src/lib/compiler/back/top/forms/make-anormcode-equality-fn.pkg
    {
        debugging = REF FALSE;

        fun bug msg
            =
            error_message::impossible("Equal: " + msg);

        say = global_controls::print::say;

        make_var = highcode_codetemp::issue_highcode_codetemp;

        ident =    fn x = x;


        my (true_dcon', false_dcon')
            = 
            {   type =  hcf::make_arrow_uniqtype                # "Void -> Bool" type.
                          (
                            hcf::rawraw_variable_calling_convention,
                            [ hcf::void_uniqtype ],
                            [ hcf::bool_uniqtype ]
                          );

                fun h (ty::VALCON { name, form, ... } )
                    =
                    (name, form, type);

                ( h tt::true_dcon,
                  h tt::false_dcon
                );
            };

        tc_eqv = hcf::same_uniqtyp;


        fun bool_lexp b
            = 
            acf::RECORD ( acj::rk_tuple,
                     [],
                     v,
                     acf::CONSTRUCTOR (dc, [], acf::VAR v, w, acf::RET [acf::VAR w])
                   )
            where  

                v = make_var();
                w = make_var();

                dc = if b  true_dcon'; else false_dcon';fi;
            end;

        exception POLY;

        ###############################################################################
        #                   Commonly-used Anormcode Types
        ###############################################################################


        # We assume types created here will
        # be reprocessed in  src/lib/compiler/back/top/forms/insert-anormcode-boxing-and-coercion-code.pkg
        #
        fun eq_lty  lt
            =
            hcf::make_arrow_uniqtype
              (
                hcf::rawraw_variable_calling_convention,
                [ lt, lt ],
                [ hcf::bool_uniqtype ]
              );

        fun eq_type tc =  eq_lty (hcf::make_typ_uniqtype tc);

        inteqty   = eq_lty (hcf::int_uniqtype);
        int1eqty = eq_lty (hcf::int1_uniqtype);
        booleqty  = eq_lty (hcf::bool_uniqtype);
        realeqty  = eq_lty (hcf::float64_uniqtype);

        ###############################################################################
        #              equal --- the equality function generator
        ###############################################################################
        exception NOT_FOUND;

        fkfun = { loop_info         =>  NULL,
                  private =>  FALSE,
                  call_as           =>  acf::CALL_AS_FUNCTION  hcf::rawraw_variable_calling_convention,
                  inlining_hint     =>  acf::INLINE_IF_SIZE_SAFE
                };

        fun branch (e, te, fe)
            =
            {   x = make_var();

                acf::LET ([x], e,
                   acf::SWITCH (acf::VAR x, tt::bool_signature,
                          [ (acf::VAL_CASETAG (true_dcon',  [], make_var()), te),
                            (acf::VAL_CASETAG (false_dcon', [], make_var()), fe)
                          ],
                          NULL));
            };

        fun equal (peqv, seqv)
            =
            {

            fun eq (tc, x, y, 0, te, fe)
                    =>
                    raise exception POLY;

                eq (tc, x, y, d, te, fe)
                    =>
                    {   fun eq_tuple (_, _, [], te, fe)
                                =>
                                te;

                            eq_tuple (n, d, type ! tys, te, fe)
                                =>
                                {   a = make_var();
                                    b = make_var();

                                    acf::GET_FIELD (x, n, a,
                                          acf::GET_FIELD (y, n, b,
                                                 eq (type, acf::VAR a, acf::VAR b, d - 1,
                                                    eq_tuple (n + 1, d - 1, tys, te, fe),
                                                    fe)));
                                };
                        end;


                        if (hcf::uniqtyp_is_tuple tc )
                            #
                            case fe
                                #
                                (acf::APPLY _ | acf::RET _)
                                    =>
                                    eq_tuple (0, d, hcf::unpack_tuple_uniqtyp tc, te, fe);

                                _ =>
                                    {   f = make_var();

                                        acf::MUTUALLY_RECURSIVE_FNS([(fkfun, f, [], fe)],
                                              eq_tuple (0, d, hcf::unpack_tuple_uniqtyp tc,
                                                       te, acf::APPLY (acf::VAR f, [])));
                                    };
                            esac;

                        elif (tc_eqv (tc, hcf::int_uniqtyp) )

                            acf::BRANCH((NULL, hbo::ieql, inteqty, []), [x, y], te, fe);

                        elif (tc_eqv (tc, hcf::int1_uniqtyp) )

                            acf::BRANCH((NULL, hbo::ieql, int1eqty, []), [x, y], te, fe);

                        elif (tc_eqv (tc, hcf::bool_uniqtyp) )

                            acf::BRANCH((NULL, hbo::ieql, booleqty, []), [x, y], te, fe);

                        elif (tc_eqv (tc, hcf::string_uniqtyp) )

                            branch (acf::APPLY (acf::VAR seqv, [x, y]), te, fe);

                        elif ( (hcf::uniqtyp_is_apply_typefun tc)
                                  and
                                  {   my (x, _) =   hcf::unpack_apply_typefun_uniqtyp  tc;
                                      # 
                                      ((hcf::uniqtyp_is_basetype x) and (hcf::unpack_basetype_uniqtyp x == hbt::basetype_ref));
                                  }
                                )

                             acf::BRANCH((NULL, hbo::POINTER_EQL, eq_type tc, []), [x, y], te, fe);

                        else
                             raise exception POLY;
                        fi;
                    };
            end;

            fn (tc, x, y, d, te, fe)
                =
                eq (tc, x, y, d, te, fe)
                except
                    POLY =
                        {   f = make_var();
                            #
                            acf::LET ([f], acf::APPLY_TYPEFUN (acf::VAR peqv, [tc]), branch (acf::APPLY (acf::VAR f, [x, y]), te, fe));
                        };

        };

        fun make_equal_branch_fn ((d, p, lt, ts), vs, e1, e2)
            =
            case (d, p, ts, vs)
                #
                ( THE { default => pv, table => [(_, sv)] },
                  hbo::POLY_EQL,
                  [tc],
                  [x, y]
                )
                    =>
                    equal (pv, sv) (tc, x, y, 10, e1, e2);

                _ =>   bug "unexpected case in equal_branch";
            esac;

    };                                                                          # package equal 
end;                                                                            # toplevel stipulate 


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext