PreviousUpNext

15.4.690  src/lib/compiler/src/stuff/literal-to-num.pkg

## literal-to-num.pkg

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



# Conversions from int/unt literals (which are represented as
# arbitrary precision Integers) to fixed size.
#
# This package is a hack, which should be replaced by parameterized
# numeric types.            XXX BUGGO FIXME

api Literal_To_Num {
    #
     int:           multiword_int::Int -> Int;
     one_word_int:          multiword_int::Int -> one_word_int::Int;
     two_word_int:          multiword_int::Int -> (one_word_unt::Unt, one_word_unt::Unt);
     unt:           multiword_int::Int -> Unt;
     one_byte_unt:          multiword_int::Int -> Unt;
     one_word_unt:          multiword_int::Int -> one_word_unt::Unt;
     two_word_unt:          multiword_int::Int -> (one_word_unt::Unt, one_word_unt::Unt);
     is_negative:   multiword_int::Int -> Bool;
     rep_digits:    multiword_int::Int -> List( Unt );  #  expose representation 
     low_val:       multiword_int::Int -> Null_Or( Int );
};



package   literal_to_num
: (weak)  Literal_To_Num                                        # Literal_To_Num        is from   src/lib/compiler/src/stuff/literal-to-num.pkg
{                                                               # inline_t              is from   src/lib/core/init/built-in.pkg

    my two_8:      multiword_int::Int =               0x100;
    my two_31:     multiword_int::Int =          0x80000000;
    my two_32:     multiword_int::Int =         0x100000000;
    my two_64:     multiword_int::Int = 0x10000000000000000;
    my int2_min:  multiword_int::Int = -0x8000000000000000;
    my int2_max:  multiword_int::Int =  0x7fffffffffffffff;

    fun twowords i
        =
        (   inline_t::in::trunc_unt1 (i / two_32),
            inline_t::in::trunc_unt1 i
        );

    fun negtwowords (x, y)
        =
        {   x' =   one_word_unt::bitwise_not x;
            y' =   one_word_unt::bitwise_not y;

            y'' = y' + 0u1;

            x'' =   if (y'' == 0u0)   x' + 0u1;
                    else              x';
                    fi;
        
            (x'', y'');
        };

    int          =           int::from_multiword_int;
    one_word_int =  one_word_int::from_multiword_int;

    fun two_word_int i
        =
        if   (i < int2_min or i > int2_max)  raise exception OVERFLOW;
        elif (i < 0)                           negtwowords (twowords (-i));
        else                                      twowords i;
        fi;

    fun one_byte_unt i
        =
        {   if (i < 0 or i >= two_8)   raise exception OVERFLOW;   fi;
            #
            unt::from_large_unt (one_byte_unt::to_large_unt (inline_t::in::trunc_unt8 i));
        };

    fun unt i
        =
        {   if (i < 0 or i >= two_31)    raise exception OVERFLOW;      fi;
            #
            inline_t::in::trunc_tagged_unt  i;
        };

    fun one_word_unt i
        =
        {   if (i < 0 or i >= two_32)   raise exception OVERFLOW;   fi;
            #
            inline_t::in::trunc_unt1  i;
        };

    fun two_word_unt i
        =
        {   if (i < 0 or i >= two_64)   raise exception OVERFLOW;   fi;
            #
            twowords i;
        };

    stipulate
        fun un_bi (core_multiword_int::BI x)
            =
            x;
    herein
        is_negative   =   .negative o un_bi o core_multiword_int::concrete;
        rep_digits    =   .digits   o un_bi o core_multiword_int::concrete;

        fun low_val i
            =
            { l = core_multiword_int::low_value i;
            
                if   (l == core_multiword_int::neg_base_as_int)
                     
                     NULL; 
                else
                     THE l;fi;
            };
    end;
};


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext