PreviousUpNext

15.4.471  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 hbt =  highcode_basetypes;                          # highcode_basetypes            is from   src/lib/compiler/back/top/highcode/highcode-basetypes.pkg
    package hcf =  highcode_form;                               # highcode_form                 is from   src/lib/compiler/back/top/highcode/highcode-form.pkg
    package mtt =  more_type_types;                             # more_type_types               is from   src/lib/compiler/front/typer/types/more-type-types.pkg
#   package pp  =  standard_prettyprinter;                      # standard_prettyprinter        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package tdt =  type_declaration_types;                      # type_declaration_types        is from   src/lib/compiler/front/typer-stuff/types/type-declaration-types.pkg
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 =    \\ x = x;


        my (true_valcon', false_valcon')
            = 
            {   type =  hcf::make_arrow_uniqtypoid              # "Void -> Bool" type.
                          (
                            hcf::rawraw_variable_calling_convention,
                            [ hcf::void_uniqtypoid ],
                            [ hcf::bool_uniqtypoid ]
                          );

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

                ( h mtt::true_valcon,
                  h mtt::false_valcon
                );
            };

        tc_eqv = hcf::same_uniqtype;


        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_valcon';
                     else  false_valcon';
                     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_uniqtypoid
              (
                hcf::rawraw_variable_calling_convention,
                [ lt, lt ],
                [ hcf::bool_uniqtypoid ]
              );

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

        inteqty   = eq_lty (hcf::int_uniqtypoid);
        int1eqty = eq_lty (hcf::int1_uniqtypoid);
        booleqty  = eq_lty (hcf::bool_uniqtypoid);
        realeqty  = eq_lty (hcf::float64_uniqtypoid);

        ###############################################################################
        #              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, mtt::bool_signature,
                          [ (acf::VAL_CASETAG (true_valcon',  [], make_var()), te),
                            (acf::VAL_CASETAG (false_valcon', [], 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::uniqtype_is_tuple tc )
                            #
                            case fe
                                #
                                (acf::APPLY _ | acf::RET _)
                                    =>
                                    eq_tuple (0, d, hcf::unpack_tuple_uniqtype tc, te, fe);

                                _ =>
                                    {   f = make_var();

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

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

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

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

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

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

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

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

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

                        elif ( (hcf::uniqtype_is_apply_typefun tc)
                                  and
                                  {   my (x, _) =   hcf::unpack_apply_typefun_uniqtype  tc;
                                      # 
                                      ((hcf::uniqtype_is_basetype x) and (hcf::unpack_basetype_uniqtype x == hbt::basetype_ref));
                                  }
                                )

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

                        else
                             raise exception POLY;
                        fi;
                    };
            end;

            \\ (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