language-Modula2-0.1: examples/Modula-2_Libraries/andrea-m2/lib/generic/specialin.mod
IMPLEMENTATION MODULE SpecialInOut;
(* procedures to supplement those in InOut and RealInOut *)
(*
as defined in "Programming and Problem Solving in Modula-2"
by S. Leestma and L. Nyhoff, MacMillian Publishing Company, 1989
*)
(* some modifications by J. Andrea, Aug.28/91 *)
(* the FWriteReal procedure isn't very good *)
(* This code may be freely used and distributed, it may not be sold. *)
FROM InOut IMPORT Read, ReadString, Write, WriteString, WriteLn, WriteCard, EOL;
FROM RealInOut IMPORT WriteReal;
CONST
nul = 0C;
VAR
digits :ARRAY [0..9] OF CHAR;
(* ------------------------------------------------------------------ *)
PROCEDURE FWriteReal( real_number :REAL;
field_width, decimal_places :CARDINAL );
CONST
significant_digits = 10;
VAR
r_num, rounding_increment :REAL;
left_digits, digit :CARDINAL;
num_positions, sign, i :CARDINAL;
BEGIN
IF real_number >= 0.0 THEN
sign := 0;
r_num := real_number;
ELSE
sign := 1;
r_num := - real_number;
END;
(* round the value to 'decimal_places' *)
rounding_increment := 0.5;
FOR i := 1 TO decimal_places DO
rounding_increment := rounding_increment / 10.0;
END;
r_num := r_num + rounding_increment;
(* normalize the number *)
left_digits := 1;
WHILE r_num >= 10.0 DO
left_digits := left_digits + 1;
r_num := r_num / 10.0;
END;
(* if too many digits, display a message and output the number *)
num_positions := left_digits + decimal_places;
IF num_positions > significant_digits THEN
WriteString( '*** Too many places specified for ' );
WriteReal( real_number, significant_digits );
ELSE
(* print leading blanks so value is right justified *)
num_positions := num_positions + sign + 1;
FOR i := num_positions + 1 TO field_width DO
WriteString( ' ' );
END;
IF sign = 1 THEN
Write( '-' );
END;
FOR i := 1 TO left_digits DO
digit := TRUNC( r_num );
Write( digits[digit] );
r_num := 10.0 * ( r_num - FLOAT(digit) );
END;
(* decimal point *)
Write( '.' );
(* digits to the right of the decimal point *)
FOR i := 1 TO decimal_places DO
digit := TRUNC( r_num );
Write( digits[digit] );
r_num := 10.0 * ( r_num - FLOAT(digit) );
END;
END;
END FWriteReal;
(* ------------------------------------------------------------------ *)
PROCEDURE ReadBoole( VAR boolean_value :BOOLEAN );
VAR
string :ARRAY [0..5] OF CHAR;
i :CARDINAL;
BEGIN
ReadString( string );
FOR i := 0 TO 4 DO
string[i] := CAP( string[i] );
END;
IF ( string[0] = 'T' ) & ( string[1] = 'R' ) &
( string[2] = 'U' ) & ( string[3] = 'E' ) &
( string[4] = nul ) THEN
boolean_value := TRUE;
ELSE
IF ( string[0] = 'F' ) & ( string[1] = 'A' ) &
( string[2] = 'L' ) & ( string[3] = 'S' ) &
( string[4] = 'E' ) & ( string[5] = nul ) THEN
boolean_value := FALSE;
ELSE
WriteString( "***Bad Input -- not 'TRUE' or 'FALSE' ***" ); WriteLn;
END;
END;
END ReadBoole;
(* ------------------------------------------------------------------ *)
PROCEDURE WriteBoole( boolean_value :BOOLEAN );
BEGIN
IF boolean_value THEN
WriteString( 'TRUE ' );
ELSE
WriteString( 'FALSE ' );
END;
END WriteBoole;
(* ------------------------------------------------------------------ *)
PROCEDURE ReadAString( VAR string :ARRAY OF CHAR );
VAR
max_index, i :CARDINAL;
ch :CHAR;
BEGIN
max_index := HIGH( string );
i := 0;
Read( ch );
WHILE ch # EOL DO
IF i <= max_index THEN
string[i] := ch;
i := i + 1;
END;
Read( ch );
END;
IF i < max_index THEN string[i] := nul; END;
END ReadAString;
BEGIN
digits[0] := '0'; digits[1] := '1'; digits[2] := '2';
digits[3] := '3'; digits[4] := '4'; digits[5] := '5';
digits[6] := '6'; digits[7] := '7'; digits[8] := '8';
digits[9] := '9';
END SpecialInOut.