


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


