## 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;
};