Pascal Data Structures for ANYPARM Calls [ HP Business BASIC/XL Reference Manual ] MPE/iX 5.0 Documentation
HP Business BASIC/XL Reference Manual
Pascal Data Structures for ANYPARM Calls
This section contains a Pascal program that illustrates type and constant
definitions required for ANYPARM externals.
$title 'ANYPARM.DECLS.BASIC/ANYPARM Data Declarations',page$
{----------------------------------------------------------------------------}
{ ANYPARM EXTERNAL DATA DECLARATIONS }
{----------------------------------------------------------------------------}
{----------------------------------------------------------------------------}
{ Constants related to the machine and operating system. }
{----------------------------------------------------------------------------}
const
c_bytes_per_pointer = 4;
c_bytes_per_integer = 4;
c_bytes_per_32_bit_word = 4;
c_bytes_per_16_bits = 2;
{----------------------------------------------------------------------------}
{ t_basic_data_types }
{ An enumerated type that associates a data type with a value. Used as a }
{ field selector for variant records to associate the relevant variant with }
{ the data type. }
{----------------------------------------------------------------------------}
type
t_basic_data_types = { 0 } ( basic_sinteger_type,
{ 1 } basic_integer_type,
{ 2 } basic_short_decimal_type,
{ 3 } basic_decimal_type,
{ 4 } basic_short_type,
{ 5 } basic_real_type,
{ 6 } basic_string_type
);
{----------------------------------------------------------------------------}
{ Data types that have corresponding Pascal data types. }
{----------------------------------------------------------------------------}
type
t_short_integer_type = shortint;
t_integer_type = integer;
t_short_real_type = real;
t_real_type = longreal;
$page$
{----------------------------------------------------------------------------}
{ DECIMAL data type }
{----------------------------------------------------------------------------}
const
c_dec_positive_mantissa = 12;
c_dec_negative_mantissa = 13;
type
t_shortint_rep_decimal = array [1..4] of shortint;
t_dec_digit_pack = packed array [-2..12] of 0..9;
t_decimal_exponent_mantissa_sign_rep =
packed record
exponent : -511..511; { 10 bits }
alignment_1_filler : 0..63; { 6 bits }
alignment_2_filler : shortint; { 16 bits }
alignment_3_filler : shortint; { 16 bits }
alignment_4_filler : -2048..2047; { 12 bits }
mantissa_sign : c_dec_positive_mantissa..
c_dec_negative_mantissa { 4 bits }
end;
{----------------------------------------------------------------------------}
{ DECIMAL TYPE }
{ The first variant of the record is designed to serve as a record overlay }
{ to quickly access the exponent and mantissa sign fields of the DECIMAL }
{ representation of a number. }
{ 1 1 1 1 1 1 }
{ bits: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 }
{ shortint |===============================================================| }
{ [1] |<-------------- exponent ------------->|<- alignment_1_filler->| }
{ |===============================================================| }
{ [2] |<-------------------- alignment_2_filler --------------------->| }
{ |===============================================================| }
{ [3] |<-------------------- alignment_3_filler --------------------->| }
{ |===============================================================| }
{ [4] |<-------------- alignment_4_filler ----------->|<mantissa sign>| }
{ |===============================================================| }
{ }
{ The second variant of the record is designed to serve as a record }
{ overlay to access each of the decimal digits of the DECIMAL value. The }
{ digits are stored in elements 1 to 12 of the array. }
{ 1 1 1 1 1 1 }
{ bits: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 }
{ shortint |===============================================================| }
{ [1] |<-digits[-2] ->|<-digits[-1] ->|<- digits[0] ->|<- digits[1] ->| }
{ |===============================================================| }
{ [2] |<- digits[2] ->|<- digits[3] ->|<- digits[4] ->|<- digits[5] ->| }
{ |===============================================================| }
{ [3] |<- digits[6] ->|<- digits[7] ->|<- digits[8] ->|<- digits[9] ->| }
{ |===============================================================| }
{ [4] |<- digits[10]->|<- digits[11]->|<- digits[12]->| | }
{ |===============================================================| }
{ }
{ NOTE: By definition, if shortint_rep[1] = 0 then the value of the DECIMAL }
{ number stored at that location is zero. }
{----------------------------------------------------------------------------}
type
t_decimal_type = packed record
case integer of
0: ( decimal_rep : t_decimal_exponent_mantissa_sign_rep );
1: ( digits : t_dec_digit_pack );
2: ( shortint_rep : t_shortint_rep_decimal );
3: ( longint_rep : longint );
end;
$page$
{----------------------------------------------------------------------------}
{ SHORT DECIMAL data type }
{----------------------------------------------------------------------------}
const
c_sdec_positive_mantissa = 0;
c_sdec_negative_mantissa = 1;
type
t_shortint_rep_short_decimal = array [1..2] of shortint;
t_sdec_digit_pack = packed array [-1..6] of 0..9;
t_sdecimal_exponent_mantissa_sign_rep =
packed record
exponent : -64..63;
mantissa_sign : c_sdec_positive_mantissa..c_sdec_negative_mantissa;
fill_16_bits : shortint
end;
{----------------------------------------------------------------------------}
{ SHORT DECIMAL }
{ The first variant of the record is designed to serve as a record overlay }
{ to quickly access the exponent and mantissa sign fields of the SHORT }
{ DECIMAL representation of a number. }
{ 1 1 1 1 1 1 }
{ bits: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 }
{ shortint |===============================================================| }
{ [1] |<------- exponent -------->| * | | }
{ |===============================================================| }
{ [2] |<------------------------ fill_16_bits ----------------------->| }
{ |===============================================================| }
{ }
{ where the * is the bit used to represent the mantissa sign. }
{ }
{ The second variant of the record is designed to serve as a record }
{ overlay to access each of the decimal digits of the SHORT DECIMAL. The }
{ digits are stored in elements 1 to 6 of the array. }
{ 1 1 1 1 1 1 }
{ bits: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 }
{ shortint |===============================================================| }
{ [1] |<-digits[-1] ->|<- digits[0] ->|<- digits[1] ->|<- digits[2] ->| }
{ |===============================================================| }
{ [2] |<- digits[3] ->|<- digits[4] ->|<- digits[5] ->|<- digits[6] ->| }
{ |===============================================================| }
{ }
{ NOTE: By definition, if shortint_rep[1] = 0 then the value of the SHORT }
{ DECIMAL number stored at that location is zero. }
{----------------------------------------------------------------------------}
type
t_short_decimal_type = record
case integer of
0: ( sdecimal_rep : t_sdecimal_exponent_mantissa_sign_rep );
1: ( digits : t_sdec_digit_pack );
2: ( shortint_rep : t_shortint_rep_short_decimal );
3: ( integer_rep : integer );
end;
$page$
{----------------------------------------------------------------------------}
{ STRING data types }
{ An even length string declared as DIM A$[4] is stored in consecutive }
{ 32 bit words as: }
{ +-------------------------------------------+ }
{ 1 | maximum_length | }
{ +-------------------------------------------+ }
{ 2 | logical_length | }
{ +-------------------------------------------+ }
{ 3 | char1 | char2 | char3 | char4 | }
{ +-------------------------------------------+ }
{ 4 | extra | not used | | }
{ +-------------------------------------------+ }
{ An odd length string declared as DIM Str$[3] is stored as: }
{ +-------------------------------------------+ }
{ 1 | maximum_length | }
{ +-------------------------------------------+ }
{ 2 | logical_length | }
{ +-------------------------------------------+ }
{ 3 | char1 | char2 | char3 | extra | }
{ +-------------------------------------------+ }
{----------------------------------------------------------------------------}
const
c_max_str_len = 32767;
type
t_string_length = integer;
t_basic_string_type =
record
max_len : t_string_length;
case integer of
0: ( actual_len : t_string_length;
bytes : packed array [1..c_max_str_len] of char
);
1: ( pascal_string_view : string[c_max_str_len] );
end; { record t_basic_string_type }
$page$
{----------------------------------------------------------------------------}
{ The constants that represent the amount of memory allocated for each }
{ of the BASIC data types. }
{----------------------------------------------------------------------------}
const
c_sizeof_short_integer = 2; { number of bytes in a SHORT INTEGER }
c_sizeof_integer = 4; { number of bytes in a INTEGER }
c_sizeof_short_real = 4; { number of bytes in a SHORT REAL }
c_sizeof_real = 8; { number of bytes in a REAL }
c_sizeof_short_decimal = 4; { number of bytes in a SHORT DECIMAL }
c_sizeof_decimal = 8; { number of bytes in a DECIMAL }
$page$
{----------------------------------------------------------------------------}
{ t_basic_scalar_type }
{ Definition of a variant record for which the representation of the data }
{ can be selected when the data type of the value is known. }
{----------------------------------------------------------------------------}
type
t_basic_scalar_type =
record
case t_basic_data_types of
basic_sinteger_type :
( sinteger_value : t_short_integer_type );
basic_integer_type :
( integer_value : t_integer_type );
basic_short_type :
( short_value : t_short_real_type );
basic_real_type :
( real_value : t_real_type );
basic_short_decimal_type :
( short_decimal_value : t_short_decimal_type );
basic_decimal_type :
( decimal_value : t_decimal_type );
basic_string_type :
( string_value : t_basic_string_type );
end; { record t_basic_scalar_type }
$page$
{----------------------------------------------------------------------------}
{ Array constant and type definitions. }
{----------------------------------------------------------------------------}
{----------------------------------------------------------------------------}
{ Constants describing array bounds and limits. }
{----------------------------------------------------------------------------}
const
c_max_array_bound = 32767;
c_min_array_bound = -32768;
c_max_array_elements = 32767;
c_max_array_size = 32767; { bytes }
c_max_array_dim = 6;
{----------------------------------------------------------------------------}
{ Definition of the array descriptor that precedes the area used to store }
{ the array data. }
{----------------------------------------------------------------------------}
type
t_dimension_subrange = integer;
t_array_single_dimension_descriptor =
record
dim_size : t_dimension_subrange; { number of elements in dimension }
lower_bound : t_dimension_subrange; { lower bound for dimension }
end; { record t_array_single_dimension_descriptor }
t_array_dimension_descriptor =
array [1..c_max_array_dim] of t_array_single_dimension_descriptor;
t_array_descriptor =
record
total_elements : integer;
bounds_info : t_array_dimension_descriptor;
end;
{----------------------------------------------------------------------------}
{ Definition of the DATA area of the array. }
{----------------------------------------------------------------------------}
{----------------------------------------------------------------------------}
{ Definition of the maximum size and dimensions of each array type. }
{----------------------------------------------------------------------------}
const
c_sizeof_single_dimension_descriptor = 2 * c_bytes_per_integer; { bytes }
c_max_array_bytes_unavail =
c_bytes_per_pointer + { pointer to the data area }
c_bytes_per_integer + { stores total number of elements in array }
c_max_array_dim * c_sizeof_single_dimension_descriptor; { bytes }
{-------------------------------------------------------------------------}
{ c_max_array_bytes defines the maximum space that an array of any type }
{ may use. }
{-------------------------------------------------------------------------}
c_max_array_bytes = c_max_array_size - c_max_array_bytes_unavail;
{-------------------------------------------------------------------------}
{ Calculate the maximum index for each of the arrays. Subtract one }
{ element when calculating because the array indexing is zero based. }
{-------------------------------------------------------------------------}
c_max_sinteger_array_index =
( c_max_array_bytes - c_sizeof_short_integer ) div c_sizeof_short_integer;
c_max_integer_array_index =
( c_max_array_bytes - c_sizeof_integer ) div c_sizeof_integer;
c_max_short_array_index =
( c_max_array_bytes - c_sizeof_short_real ) div c_sizeof_short_real;
c_max_real_array_index =
( c_max_array_bytes - c_sizeof_real ) div c_sizeof_real;
c_max_short_decimal_array_index =
( c_max_array_bytes - c_sizeof_short_decimal ) div c_sizeof_short_decimal;
c_max_decimal_array_index =
( c_max_array_bytes - c_sizeof_decimal ) div c_sizeof_decimal;
{-------------------------------------------------------------------------}
{ String arrays are contained in a "word_view", so max index is word, not }
{ element, related. Individual array elements are always 4 byte aligned }
{ because the t_basic_string_type record requires 4 byte alignment. }
{-------------------------------------------------------------------------}
c_max_string_array_index = c_max_array_bytes;
c_max_string_array_word_index = c_max_array_bytes div
c_bytes_per_32_bit_word;
{----------------------------------------------------------------------------}
{ Definition of the types that describe each array that is used to store }
{ data of that type. }
{----------------------------------------------------------------------------}
type
t_bas_sinteger_array =
array [0..c_max_sinteger_array_index] of t_short_integer_type;
t_bas_integer_array =
array [0..c_max_integer_array_index] of t_integer_type;
t_bas_short_array =
array [0..c_max_short_array_index] of t_short_real_type;
t_bas_real_array =
array [0..c_max_real_array_index] of t_real_type;
t_bas_short_decimal_array =
array [0..c_max_short_decimal_array_index] of t_short_decimal_type;
t_bas_decimal_array =
array [0..c_max_decimal_array_index] of t_decimal_type;
t_string_word_view =
array [0..c_max_string_array_index div 4] of integer;
{----------------------------------------------------------------------------}
{ t_basic_array_type }
{ Definition of an array data type that has a variant for each of the data }
{ types. }
{----------------------------------------------------------------------------}
type
t_basic_array_type =
record
case t_basic_data_types of
basic_sinteger_type : ( sinteger_array : t_bas_sinteger_array );
basic_integer_type : ( integer_array : t_bas_integer_array );
basic_short_decimal_type : ( short_decimal_array
: t_bas_short_decimal_array );
basic_decimal_type : ( decimal_array : t_bas_decimal_array );
basic_short_type : ( short_array : t_bas_short_array );
basic_real_type : ( real_array : t_bas_real_array );
basic_string_type : ( word_view : t_string_word_view );
end; { record t_basic_array_type }
$page$
{----------------------------------------------------------------------------}
{ t_basic_data_type }
{ The value referenced by the parameter address passed in the ANYPARM }
{ actual parameter table has this type. The correct representation of the }
{ parameter is determined by the dimensionality and data type of the }
{ parameter. }
{----------------------------------------------------------------------------}
type
t_dimension_range = 0..6; { a scalar has 0 dimensions, max array is 6 }
t_basic_data_type =
record
case t_dimension_range of
0 : ( scalar_value : t_basic_scalar_type );
1..6 :
(
{----------------------------------------------------------}
{ Pointer to the beginning of the actual data area of the }
{ array. The pointer is always used to reference the }
{ actual data. }
{----------------------------------------------------------}
p_array_data : ^t_basic_array_type;
{----------------------------------------------------------}
{ The area storing the total number of elements and the }
{ descriptor of each dimension - there are two words of }
{ information for each dimension. The data area of the }
{ array will overwrite unused dimension information. }
{----------------------------------------------------------}
array_descriptor : t_array_descriptor;
{----------------------------------------------------------}
{ A field that defines the beginning of the actual data }
{ area - not to be used to reference the data. }
{----------------------------------------------------------}
array_value : t_basic_array_type;
);
end; { record t_basic_data_type }
tp_basic_data_type = ^t_basic_data_type;
$page$
{----------------------------------------------------------------------------}
{ ANYPARM Parameter Type Field Values }
{ The parameter type flag passed to the external for a parameter has the }
{ same value as that which is returned by the TYP function. }
{----------------------------------------------------------------------------}
const
c_decimal_type = 1;
c_whole_string_type = 2;
c_short_integer_type = 5;
c_short_decimal_type = 6;
c_integer_type = 11;
c_short_real_type = 12;
c_real_type = 13;
$page$
{----------------------------------------------------------------------------}
{ The Actual Parameter Table }
{ An array of records describing the address, type and dimensionality of }
{ each of the actual parameters. t_parameter_record, a record which }
{ contains fields for the address, type and dimensionality of a single }
{ actual parameter in the actual parameter table, is defined. }
{ t_short_basic_string_type is defined to allow processing of strings. }
{ External declarations are made for the functions which process decimal }
{ values. }
{----------------------------------------------------------------------------}
const
c_max_num_parameters = 50;
c_short_basic_string_max_length = 400; { bytes }
type
t_parameter_record = packed record
param_address : tp_basic_data_type;
param_type : shortint;
number_of_dimensions: shortint;
end;
t_actual_parameter_array = array [1..c_max_num_parameters] of
t_parameter_record;
tp_actual_parameter_array = ^t_actual_parameter_array;
t_short_basic_string_type =
record
max_len : integer;
case integer of
0: (actual_len : integer;
case integer of
0: ( bytes: packed
array [1..c_short_basic_string_max_length] of char );
1: ( words:
array [1..c_short_basic_string_max_length div
c_bytes_per_32_bit_word] of integer )
);
1: (pascal_string_view: string[c_short_basic_string_max_length]);
end;
MPE/iX 5.0 Documentation