PreviousUpNext

15.4.712  src/lib/core/init/built-in.pkg

## built-in.pkg
#
# Interfaces to the compiler built-ins, infixes, etc.

# Compiled by:
#     src/lib/core/init/init.cmi

# Here we basically define package inline_t containing subpackages
#
#       float64
#       multword_int
#       one_word_unt
#       two_word_unt
#       one_word_int
#       tagged_unt
#       tagged_int
#       two_word_int
#       one_byte_unt
#       char
#
#       poly_rw_vector
#       poly_vector
#       rw_vector_of_eight_byte_floats
#       vector_of_eight_byte_floats
#       rw_vector_of_one_byte_unts
#       vector_of_one_byte_unts
#       vector_of_one_byte_unts
#       rw_vector_of_chars
#       rw_vector_of_chars
#       vector_of_chars
#
# and populate them with appropriate funs drawm from the 'inline' package defined in
#
#     src/lib/compiler/front/semantic/symbolmapstack/base-types-and-ops-symbolmapstack.pkg
#
# For the arithmetic-type packages those funs are add, divide, shift ...
# For the vector-type     packages those funs are fetch, store ...
#
# We also define the package synonyms
#
#     package default_int   =  tagged_int;
#     package default_unt  =  tagged_unt;
#     package default_float =  float64;





###                     "I was gratified to be able
###                      to answer promptly and I did.
###
###                     "I said I didn't know."
###
###                                  -- Mark Twain,
###                                     Life on the Mississippi



package base_types {
    #
    include  base_types;                                # base_types            is from   src/lib/compiler/front/semantic/symbolmapstack/base-types-and-ops-symbolmapstack.pkg
};

   # This silliness is to prevent elabstr.sml
   # from sticking a NO_ACCESS in the wrong place

stipulate
    include base_types;
    #
    package rt = core::runtime;                         # Private abbreviation.
herein

    package runtime                                     # This name gets used many places, starting with    src/lib/core/init/proto-pervasive.pkg   and   src/lib/core/init/pervasive.pkg
        =
        core::runtime;                                  # core                  is from   src/lib/core/init/core.pkg

    # The following code was used to create a type-safe version of the inline
    # package while preserving the inline property of the functions.
    # Since everything in inline is now properly typed already, the code
    # should now be seen as:
    #   - organizing things a bit better
    #   - confirming the type information
    #
    # For the origin of the type info in inline_t see
    #
    #     src/lib/compiler/front/semantic/symbolmapstack/base-types-and-ops-symbolmapstack.pkg
    #
    # (Blume, 1/2001)
    #
    package inline_t {

        Control_Fate(X)   = Control_Fate(X);

        callcc                          =   inline::callcc:                             (Fate(X) -> X) -> X;
        throw                           =   inline::throw:                               Fate(X) -> X -> Y;

        call_with_current_control_fate  =   inline::call_with_current_control_fate:     (Control_Fate(X) -> X) -> X;
        switch_to_control_fate          =   inline::switch_to_control_fate:              Control_Fate(X) -> X -> Y;   
        make_isolated_fate              =   inline::make_isolated_fate:                 (X -> Void) -> Fate(X);

        (*_)                            =   inline::deref:                              Ref(X) -> X;
        deref                           =   inline::deref:                              Ref(X) -> X;
        (:=)                            =   inline::(:=) :                              (Ref(X), X) -> Void;
        makeref                         =   inline::makeref:                            X -> Ref(X);

        (==)                            =   inline::(==) :                              (_X, _X) -> Bool;
        (!=)                            =   inline::(!=) :                              (_X, _X) -> Bool;

        boxed                           =   inline::boxed:                               X -> Bool;
        unboxed                         =   inline::unboxed:                             X -> Bool;
        cast                            =   inline::cast:                                X -> Y;

        identity                        = inline::cast:                                  X -> X;
        chunklength                     = inline::chunklength:                           X -> Int;
        make_special                    = inline::make_special:                         (Int, X) -> Y;

        getspecial                      = inline::getspecial:                            X -> Int;
        setspecial                      = inline::setspecial:                            (X, Int) -> Void;

        getpseudo                       = inline::getpseudo:                             Int -> X; 
        setpseudo                       = inline::setpseudo:                            (X, Int) -> Void; 

        gethandler                      = inline::gethandler:                            Void -> Fate(X);
        sethandler                      = inline::sethandler:                            Fate(X) -> Void;

        # We have one "register" used by threadkit
        # to hold the currently running thread.  This is
        # a real register on RISC architectures but a memory
        # location on the register-starved intel32 architecture:
        #
        get_current_thread_register     = inline::get_current_thread_register:           Void -> X;                     # Get reserved 'current_thread' register -- see src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg
        set_current_thread_register     = inline::set_current_thread_register:           X -> Void;                     # Set reserved 'current_thread' register -- see src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg

        compose                         = inline::compose:                              (Y -> Z,  X -> Y) -> (X -> Z);
        (before)                        = inline::before:                               (X, Y) -> X;

        ignore                          = inline::ignore:                                X -> Void;
        gettag                          = inline::gettag:                                X -> Int;
        setmark                         = inline::setmark:                               X -> Void; 
        dispose                         = inline::dispose:                               X -> Void; 

        (!_)                            = inline::inlnot:                                Bool -> Bool;
        inlnot                          = inline::inlnot:                                Bool -> Bool;

        record_get                      = inline::record_get:                           (X, Int) -> Y;
        raw64get                        = inline::raw64_get:                            (X, Int) -> Float;

        ptreql                          = inline::ptreql:                               (X, X) -> Bool;

        package f64 {                                                                   # "f64" == "64-bit float".
            #
            my (+)   : (Float, Float) -> Float          = inline::f64add;
            my (-)   : (Float, Float) -> Float          = inline::f64sub;

            my (/)   : (Float, Float) -> Float          = inline::f64div;
            my (*)   : (Float, Float) -> Float          = inline::f64mul;

            my (====): (Float, Float) -> Bool           = inline::f64eq;
            my (!=)  : (Float, Float) -> Bool           = inline::f64ne;

            my (>=)  : (Float, Float) -> Bool           = inline::f64ge;
            my (>)   : (Float, Float) -> Bool           = inline::f64gt;

            my (<=)  : (Float, Float) -> Bool           = inline::f64le;
            my (<)   : (Float, Float) -> Bool           = inline::f64lt;

            my (-_)   : Float -> Float                  = inline::f64neg;
            my neg    : Float -> Float                  = inline::f64neg;
            my abs:     Float -> Float                  = inline::f64abs;

            my min:     (Float, Float) -> Float         = inline::f64min;
            my max:     (Float, Float) -> Float         = inline::f64max;

            my from_tagged_int:  Int   -> Float         = inline::tagged_int_to_float64;
            my from_int1:  Int1 -> Float                = inline::int1_to_float64;
        };

        package in {                                                                    # "in" == "indefinite-precision integer" (implemented as list of ints).
            #
            my test_tagged_int: Multiword_Int -> Int            = inline::test_i0_31;
            my test_int1:       Multiword_Int -> Int1           = inline::test_i0_32;

            my trunc_unt8:    Multiword_Int -> Unt8             = inline::trunc_i0_8;
            my trunc_tagged_unt:   Multiword_Int -> Unt = inline::trunc_i0_31;
            my trunc_unt1:   Multiword_Int -> Unt1              = inline::trunc_i0_32;

            my copy_unt8:     Unt8  -> Multiword_Int            = inline::copy_8_inf;
            my copy_tagged_int:     Int   -> Multiword_Int      = inline::copy_31_i0_i;
            my copy_tagged_unt:    Unt   -> Multiword_Int       = inline::copy_31_i0_u;
            my copy_int1:     Int1 -> Multiword_Int             = inline::copy_32_i0_i;
            my copy_unt1:    Unt1 -> Multiword_Int              = inline::copy_32_i0_u;

            my extend_unt8:   Unt8  -> Multiword_Int            = inline::extend_8_inf;
            my extend_tagged_int:   Int   -> Multiword_Int      = inline::extend_31_i0_i;
            my extend_tagged_unt:  Unt   -> Multiword_Int       = inline::extend_31_i0_u;
            my extend_int1:   Int1 -> Multiword_Int             = inline::extend_32_i0_i;
            my extend_unt1:  Unt1 -> Multiword_Int              = inline::extend_32_i0_u;

            to_int   =   test_tagged_int;
            from_int = extend_tagged_int;

            my to_large:        Multiword_Int -> Multiword_Int  = inline::identity;
            my from_large:      Multiword_Int -> Multiword_Int  = inline::identity;
          };

        package u1 {
            #
            my test_tagged_int:    Unt1 -> Int          = inline::test_32_31_u;
            my testu_tagged_int:   Unt1 -> Int          = inline::testu_32_31;
            my testu_int1:   Unt1 -> Int1               = inline::testu_32_32;
            my trunc_tagged_unt:  Unt1 -> Unt           = inline::trunc_32_31_u;
            my trunc_unt8:   Unt1 -> Unt8               = inline::trunc_32_8_u;
            my copy_unt8:    Unt8 -> Unt1               = inline::copy_8_32_u;
            my copy_tagged_unt:   Unt -> Unt1           = inline::copy_31_32_u;
            my copyf_int1:   Int1 -> Unt1               = inline::copy_32_32_iu;
            my copyt_int1:   Unt1 -> Int1               = inline::copy_32_32_ui;
            my copy_unt1:   Unt1 -> Unt1                = inline::copy_32_32_uu;
            my extend_unt8:  Unt8 -> Unt1               = inline::extend_8_32_u;
            my extend_tagged_int:  Int -> Unt1          = inline::extend_31_32_iu;
            my extend_tagged_unt: Unt -> Unt1           = inline::extend_31_32_uu;

            to_large_unt        = copy_unt1;
            to_large_unt_x      = copy_unt1;
            from_large_unt      = copy_unt1;
            to_large_int        = in::copy_unt1;
            to_large_int_x      = in::extend_unt1;
            from_large_int      = in::trunc_unt1;
            to_int              = testu_tagged_int;
            to_int_x            = test_tagged_int;
            from_int            = extend_tagged_int;

            my bitwise_or:   (Unt1, Unt1) -> Unt1       = inline::u32orb;
            my bitwise_xor:  (Unt1, Unt1) -> Unt1       = inline::u32xorb;
            my bitwise_and:  (Unt1, Unt1) -> Unt1       = inline::u32andb;
            my bitwise_not:   Unt1 -> Unt1              = inline::u32notb;
            my (*)    :      (Unt1, Unt1) -> Unt1       = inline::u32mul;
            my (+)    :      (Unt1, Unt1) -> Unt1       = inline::u32add;
            my (-)    :      (Unt1, Unt1) -> Unt1       = inline::u32sub;
            my (-_)    :      Unt1 -> Unt1              = inline::u32neg;
            my neg     :      Unt1 -> Unt1              = inline::u32neg;
            my (div):        (Unt1, Unt1) -> Unt1       = inline::u32div;       # NB: w32div does round-to-zero division -- this is the native instruction on Intel32.
            my (mod):        (Unt1, Unt1) -> Unt1       = inline::u32mod;       # NB: w32mod does round-to-zero division -- this is the native instruction on Intel32. (Yes, this is called "rem" most other places in the code -- bug?)
            my (>)    :      (Unt1, Unt1) -> Bool       = inline::u32gt;
            my (>=)   :      (Unt1, Unt1) -> Bool       = inline::u32ge;
            my (<)    :      (Unt1, Unt1) -> Bool       = inline::u32lt;
            my (<=)   :      (Unt1, Unt1) -> Bool       = inline::u32le;
            my rshift:       (Unt1, Unt) -> Unt1        = inline::u32rshift;
            my rshiftl:      (Unt1, Unt) -> Unt1        = inline::u32rshiftl;
            my lshift:       (Unt1, Unt) -> Unt1        = inline::u32lshift;
            my check_lshift: (Unt1, Unt) -> Unt1        = inline::u32_check_lshift;
            my check_rshift: (Unt1, Unt) -> Unt1        = inline::u32_check_rshift;
            my check_rshiftl:(Unt1, Unt) -> Unt1        = inline::u32_check_rshiftl;

            my min:      (Unt1, Unt1) -> Unt1   = inline::u32min;
            my max:      (Unt1, Unt1) -> Unt1   = inline::u32max;
          };


        package u2 {
            my extern:  Unt2 -> (Unt1, Unt1)            = inline::u64p;
            my intern:  (Unt1, Unt1) -> Unt2            = inline::p64u;
        };


        package i1 {
            #
            my test_tagged_int:    Int1 -> Int          = inline::test_32_31_i;
            my trunc_unt8:   Int1 -> Unt8               = inline::trunc_32_8_i;
            my trunc_tagged_unt:  Int1 -> Unt           = inline::trunc_32_31_i;
            my copy_unt8:    Unt8 -> Int1               = inline::copy_8_32_i;
            my copy_tagged_unt:   Unt -> Int1           = inline::copy_31_32_i;
            my copy_int1:    Int1 -> Int1               = inline::copy_32_32_ii;
            my extend_unt8:  Unt8 -> Int1               = inline::extend_8_32_i;
            my extend_tagged_int:  Int -> Int1          = inline::extend_31_32_ii;
            my extend_tagged_unt: Unt -> Int1           = inline::extend_31_32_ui;

            to_int = test_tagged_int;
            from_int = extend_tagged_int;
            to_large = in::extend_int1;
            from_large = in::test_int1;

            my (*)    : (Int1, Int1) -> Int1            = inline::i32mul;
            my (quot):  (Int1, Int1) -> Int1            = inline::i32quot;                      # NB: i32quot does round-to-zero division -- this is the native instruction on Intel32.
            my (rem):   (Int1, Int1) -> Int1            = inline::i32rem;                       # NB: i32rem  does round-to-zero division -- this is the native instruction on Intel32.
            my (div):   (Int1, Int1) -> Int1            = inline::i32div;                       # NB: i32div  does round-to-negative-infinity division  -- this will be much slower on Intel32, has to be faked.
            my (mod):   (Int1, Int1) -> Int1            = inline::i32mod;                       # NB: i32mod  does round-to-negative-infinity division  -- this will be much slower on Intel32, has to be faked.
            my (+)    : (Int1, Int1) -> Int1            = inline::i32add;  
            my (-)    : (Int1, Int1) -> Int1            = inline::i32sub;
            my (-_)    : Int1 -> Int1                   = inline::i32neg; 
            my neg     : Int1 -> Int1                   = inline::i32neg; 
            my bitwise_and: (Int1, Int1) -> Int1        = inline::i32andb;
            my bitwise_or:  (Int1, Int1) -> Int1        = inline::i32orb;
            my bitwise_xor: (Int1, Int1) -> Int1        = inline::i32xorb;
            my rshift:   (Int1, Int1) -> Int1           = inline::i32rshift;
            my lshift:   (Int1, Int1) -> Int1           = inline::i32lshift;
            my (<)    : (Int1, Int1) -> Bool            = inline::i32lt;
            my (<=)   : (Int1, Int1) -> Bool            = inline::i32le;
            my (>)    : (Int1, Int1) -> Bool            = inline::i32gt;
            my (>=)   : (Int1, Int1) -> Bool            = inline::i32ge;
            my (==)   : (Int1, Int1) -> Bool            = inline::i32eq;
            my (<>)   : (Int1, Int1) -> Bool            = inline::i32ne;

            my min:      (Int1, Int1) -> Int1           = inline::i32min;
            my max:      (Int1, Int1) -> Int1           = inline::i32max;
            my abs:      Int1 -> Int1                   = inline::i32abs;
        };

        package tu {                                                                    # "tu" == "tagged unt": 31-bit on 32-bit archtectures, 63-bit on 64-bit architectures.
            #
            my testu_tagged_int:    Unt -> Int          = inline::testu_31_31;
            my copyt_tagged_int:    Unt -> Int          = inline::copy_31_31_ui;
            my copyf_tagged_int:    Int -> Unt          = inline::copy_31_31_iu;

            to_large_unt        =  u1::copy_tagged_unt;
            to_large_unt_x      =  u1::extend_tagged_unt;
            from_large_unt      =  u1::trunc_tagged_unt;
            to_large_int        =  in::copy_tagged_unt;
            to_large_int_x      =  in::extend_tagged_unt;
            from_large_int      =  in::trunc_tagged_unt;
            to_int              =  testu_tagged_int;
            to_int_x            =  copyt_tagged_int;
            from_int            =  copyf_tagged_int;

            my bitwise_or:      (Unt, Unt) -> Unt       = inline::u31orb;
            my bitwise_xor:     (Unt, Unt) -> Unt       = inline::u31xorb;
            my bitwise_and:     (Unt, Unt) -> Unt       = inline::u31andb;
            my (*)    : (Unt, Unt) -> Unt               = inline::u31mul;
            my (+)    : (Unt, Unt) -> Unt               = inline::u31add;
            my (-)    : (Unt, Unt) -> Unt               = inline::u31sub;
            my (-_)    : Unt -> Unt                     = inline::u31neg;
            my neg     : Unt -> Unt                     = inline::u31neg;
            my (div):   (Unt, Unt) -> Unt               = inline::u31div;               # NB: w31dev does round-to-zero division -- this is the native instruction on Intel32.
            my (mod):   (Unt, Unt) -> Unt               = inline::u31mod;               # NB: w31mod does round-to-zero division -- this is the native instruction on Intel32. (Called "rem" in most of the code -- bug?)
            my (>)    : (Unt, Unt) -> Bool              = inline::u31gt;
            my (>=)   : (Unt, Unt) -> Bool              = inline::u31ge;
            my (<)    : (Unt, Unt) -> Bool              = inline::u31lt;
            my (<=)   : (Unt, Unt) -> Bool              = inline::u31le;
            my rshift:   (Unt, Unt) -> Unt              = inline::u31rshift;
            my rshiftl:  (Unt, Unt) -> Unt              = inline::u31rshiftl;
            my lshift:   (Unt, Unt) -> Unt              = inline::u31lshift;
            my check_lshift:   (Unt, Unt) -> Unt        = inline::u31_check_lshift;
            my check_rshift:   (Unt, Unt) -> Unt        = inline::u31_check_rshift;
            my check_rshiftl:  (Unt, Unt) -> Unt        = inline::u31_check_rshiftl;
            my bitwise_not:     Unt -> Unt              = inline::u31notb;

            my min:      (Unt, Unt) -> Unt              = inline::u31min;
            my max:      (Unt, Unt) -> Unt              = inline::u31max;
        };

        package ti {                                                                    # "ti" == "tagged_int": 31-bit on 32-bit archtectures, 63-bit on 64-bit architectures.
            #
            my trunc_unt8:  Int -> Unt8         = inline::trunc_31_8;
            my copy_tagged_int:    Int -> Int           = inline::copy_31_31_ii;
            my copy_unt8:    Unt8 -> Int                = inline::copy_8_31;
            my extend_unt8:  Unt8 -> Int                = inline::extend_8_31;

            to_int      = copy_tagged_int;
            from_int    = copy_tagged_int;
            to_large    = in::extend_tagged_int;
            from_large  = in::test_tagged_int;

            my (*)    : (Int, Int) -> Int               = inline::i31mul;
            my (quot):  (Int, Int) -> Int               = inline::i31quot;              # NB: i32quot does round-to-zero division -- this is the native instruction on Intel32.
            my (rem):   (Int, Int) -> Int               = inline::i31rem;               # NB: i31rem  does round-to-zero division -- this is the native instruction on Intel32.
            my (div):   (Int, Int) -> Int               = inline::i31div;               # NB: i31div  does round-to-negative-infinity division  -- this will be much slower on Intel32, has to be faked.
            my (mod):   (Int, Int) -> Int               = inline::i31mod;               # NB: i31mod  does round-to-negative-infinity division  -- this will be much slower on Intel32, has to be faked.
            my (+)    : (Int, Int) -> Int               = inline::i31add;
            my (-)    : (Int, Int) -> Int               = inline::i31sub;
            my (-_)    : Int -> Int                     = inline::i31neg;
            my neg     : Int -> Int                     = inline::i31neg;
            my bitwise_and:     (Int, Int) -> Int       = inline::i31andb;
            my bitwise_or:      (Int, Int) -> Int       = inline::i31orb;
            my bitwise_xor:     (Int, Int) -> Int       = inline::i31xorb;
            my rshift:   (Int, Int) -> Int              = inline::i31rshift;
            my lshift:   (Int, Int) -> Int              = inline::i31lshift;
            my bitwise_not:     Int -> Int              = inline::i31notb;
            my (<)    : (Int, Int) -> Bool              = inline::i31lt;
            my (<=)   : (Int, Int) -> Bool              = inline::i31le;
            my (>)    : (Int, Int) -> Bool              = inline::i31gt;
            my (>=)   : (Int, Int) -> Bool              = inline::i31ge;
            my (==)   : (Int, Int) -> Bool              = inline::i31eq;
            my (<>)   : (Int, Int) -> Bool              = inline::i31ne;
            my ltu:      (Int, Int) -> Bool             = inline::i31ltu;
            my geu:      (Int, Int) -> Bool             = inline::i31geu;

            my min:      (Int, Int) -> Int              = inline::i31min;
            my max:      (Int, Int) -> Int              = inline::i31max;
            my abs:      Int -> Int                     = inline::i31abs;
        };

        package i2 {
            #
            my extern:  Int2 -> (Unt1, Unt1)            = inline::i64p;
            my intern:  (Unt1, Unt1) -> Int2            = inline::p64i;
        };

        package u8 {                                                    # "u8" == "8-bit unsigned int".
            #

            #  large_int is still 32 bit: 
            #
            to_large_unt        = u1::copy_unt8;
            to_large_unt_x      = u1::extend_unt8;
            from_large_unt      = u1::trunc_unt8;
            #   
            to_large_int        = in::copy_unt8;
            to_large_int_x      = in::extend_unt8;
            from_large_int      = in::trunc_unt8;
            #   
            to_int              = ti::copy_unt8;
            to_int_x            = ti::extend_unt8;
            from_int            = ti::trunc_unt8;



            # Temporary framework because the actual
            # one_byte_unt operators  are not implemented:

            # WARNING! some of the following operators
            #          don't get the high-order bits right XXX BUGGO FIXME
            #
            my bitwise_or:      (Unt8, Unt8) -> Unt8    = inline::u31orb_8;
            my bitwise_xor:     (Unt8, Unt8) -> Unt8    = inline::u31xorb_8;
            my bitwise_and:     (Unt8, Unt8) -> Unt8    = inline::u31andb_8;
            #
            my (*)    : (Unt8, Unt8) -> Unt8            = inline::u31mul_8;
            my (+)    : (Unt8, Unt8) -> Unt8            = inline::u31add_8;
            my (-)    : (Unt8, Unt8) -> Unt8            = inline::u31sub_8;
            #
            my (-_)    : Unt8 -> Unt8                   = inline::u31neg_8;
            my neg     : Unt8 -> Unt8                   = inline::u31neg_8;
            #
            my (div):   (Unt8, Unt8) -> Unt8            = inline::u31div_8;                     # NB: w31div_8 does round-to-zero division -- this is the native instruction on Intel32.
            my (mod):   (Unt8, Unt8) -> Unt8            = inline::u31mod_8;                     # NB: w31mod_8 does round-to-zero division -- this is the native instruction on Intel32. (Called "rem" in much of the code -- bug?)
            #
            my (>)    : (Unt8, Unt8) -> Bool            = inline::u31gt_8;
            my (>=)   : (Unt8, Unt8) -> Bool            = inline::u31ge_8;
            my (<)    : (Unt8, Unt8) -> Bool            = inline::u31lt_8;
            my (<=)   : (Unt8, Unt8) -> Bool            = inline::u31le_8;
            #
            my rshift:   (Unt8, Unt) -> Unt8            = inline::u31rshift_8;
            my rshiftl:  (Unt8, Unt) -> Unt8            = inline::u31rshift_8;
            my lshift:   (Unt8, Unt) -> Unt8            = inline::u31lshift_8;
            #
            my bitwise_not:     Unt8 -> Unt8            = inline::u31notb_8;
            #
            my check_lshift:   (Unt8, Unt) -> Unt8      = inline::u31_check_lshift_8;
            my check_rshift:   (Unt8, Unt) -> Unt8      = inline::u31_check_rshift_8;
            my check_rshiftl:  (Unt8, Unt) -> Unt8      = inline::u31_check_rshiftl_8;

            my min:      (Unt8, Unt8) -> Unt8           = inline::u31min_8;
            my max:      (Unt8, Unt8) -> Unt8           = inline::u31max_8;
        };

        package char {
            #
            max_ord = 255;
            #
            exception BAD_CHAR;

            # The following should be an inline operator:       XXX BUGGO FIXME
            # 
            fun chr i
                =
                if (ti::geu (i, (ti::(+))(max_ord, 1)))
                     raise exception BAD_CHAR;
                else ((inline::cast i) : Char);fi;

            my ord:  Char -> Int                        = inline::cast;

            my (<)  : (Char, Char) -> Bool              = inline::i31lt_c;
            my (<=) : (Char, Char) -> Bool              = inline::i31le_c;
            my (>)  : (Char, Char) -> Bool              = inline::i31gt_c;
            my (>=) : (Char, Char) -> Bool              = inline::i31ge_c;
        };



        package poly_rw_vector {
            #
            my new_array0:  Void -> Rw_Vector(X)                        = inline::new_array0;
            my array:      (Int, X) -> Rw_Vector(X)                     = inline::make_rw_vector; 
            my length:      Rw_Vector(X) -> Int                         = inline::length;
            my get:        (Rw_Vector(X), Int) -> X                     = inline::rw_vec_get;
            my check_sub:  (Rw_Vector(X), Int) -> X                     = inline::safe_rw_vec_get;
            my set:      (Rw_Vector(X), Int, X) -> Void                 = inline::rw_vec_set;
            my check_set:(Rw_Vector(X), Int, X) -> Void                 = inline::safe_rw_vec_set;
            my get_data:  Rw_Vector(X) -> Y                             = inline::get_seq_data;
        };

        package poly_vector {
            #
            my length:      Vector(X) -> Int                            = inline::length; 
            my get:        (Vector(X), Int) -> X                        = inline::vec_get;
            my check_sub:  (Vector(X), Int) -> X                        = inline::safe_vec_get;
            my get_data:    Vector(X) -> Y                              = inline::get_seq_data;
        };

        # The type of this ought to be float64array:
        #
        stipulate
            Vec = rt::asm::Float64_Rw_Vector;
        herein

            package rw_vector_of_eight_byte_floats {
                #
                my new_array0:  Void -> Vec                             = inline::new_array0;
                my length:              Vec -> Int                      = inline::length;
                #
                my get:                (Vec, Int) -> Float              = inline::f64_sub;
                my check_sub:          (Vec, Int) -> Float              = inline::f64chk_sub;
                #
                my set:                (Vec, Int, Float) -> Void        = inline::f64_update;
                my check_set:          (Vec, Int, Float) -> Void        = inline::f64chk_update;
                my get_data:            Vec -> Y                        = inline::get_seq_data;
            };
        end;

        # NOTE: we are currently using typeagnostic vectors
        # to implement the vector_of_eight_byte_floats package.         XXX BUGGO FIXME
        #
        package vector_of_eight_byte_floats {
            #
            my length:      Vector( Float ) -> Int                      = inline::length; 
            my get:        (Vector( Float ), Int) -> Float              = inline::vec_get;
            my check_sub:  (Vector( Float ), Int) -> Float              = inline::safe_vec_get;
            my get_data:    Vector( Float ) -> Y                        = inline::get_seq_data;
        };

        package rw_vector_of_one_byte_unts {
            #
            Rw_Vector = rt::asm::Unt8_Rw_Vector;
            #
            my new_array0:  Void -> Rw_Vector                           = inline::new_array0;
            my length:     Rw_Vector -> Int                             = inline::length;
            #
            # BUG: using "ordof" for w8a::sub is dangerous, because ordof is
            # (technically) fetching from immutable things.  A fancy optimizer might
            # someday be confused. XXX BUGGO FIXME
            #
            my get_data:    Rw_Vector -> X                              = inline::get_seq_data;
            my get:        (Rw_Vector, Int) -> Unt8                     = inline::ordof;
            my set:        (Rw_Vector, Int, Unt8) -> Void               = inline::store;
            #
            my check_sub:  (Rw_Vector, Int) -> Unt8                     = inline::inlbyteof;
            my check_set:  (Rw_Vector, Int, Unt8) -> Void               = inline::inlstore;
            #
          };


        # Preliminary version with just the type:
        #
        package vector_of_one_byte_unts : api {
                                  eqtype Vector;
                                   create:  Int -> Vector;
                              }
          {  Vector = String;
             create = rt::asm::make_string;
          };

        # Now the real version with all values:
        #
        package vector_of_one_byte_unts {
            #
            include vector_of_one_byte_unts;
            #
            my length:       Vector -> Int                              = inline::length;
            my get:         (Vector, Int) -> Unt8                       = inline::ordof;
            my check_sub:   (Vector, Int) -> Unt8                       = inline::inlordof;
            my set:         (Vector, Int, Unt8) -> Void                 = inline::store;
            my get_data:     Vector -> X                                = inline::get_seq_data;
        };

        package rw_vector_of_chars : api {              #  prelim 
                                     eqtype Rw_Vector;
                                      new_array0:  Void -> Rw_Vector;
                                      create:  Int -> Rw_Vector;
                                 }
        {
            Rw_Vector = rt::asm::Unt8_Rw_Vector;
            #
            my new_array0:  Void -> Rw_Vector                           =  inline::new_array0;
            #
            create =  rt::asm::make_unt8_rw_vector;
        };

        package rw_vector_of_chars {            #  full 
            #
            include rw_vector_of_chars;
            #
            my length:      Rw_Vector -> Int                            = inline::length;
            #
            my check_sub:   (Rw_Vector, Int) -> Char                    = inline::inlordof;
            my check_set :  (Rw_Vector, Int, Char) -> Void              = inline::inlstore;
            #
            my get:         (Rw_Vector, Int) -> Char                    = inline::ordof;
            my set:         (Rw_Vector, Int, Char) -> Void              = inline::store;
            my get_data:    Rw_Vector -> X                              = inline::get_seq_data;
        };

        package vector_of_chars {
            #
            my length:        String -> Int                             = inline::length;
            my check_sub:    (String, Int) -> Char                      = inline::inlordof;
            my get:          (String, Int) -> Char                      = inline::ordof;
            my set:          (String, Int, Char) -> Void                = inline::store;
            my get_data:      String -> X                               = inline::get_seq_data;
        };

        package default_int   =  ti;
        package default_unt   =  tu;
        package default_float =  f64;
    };                                                  # package inline_t 
end;                                                    # stipulate


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext