IMPLEMENTATION MODULE SIntIO;

        (********************************************************)
        (*                                                      *)
        (*                Integer I/O operations                *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Last edited:        3 June 2024                     *)
        (*  Status:             OK                              *)
        (*                                                      *)
        (********************************************************)


FROM Arith64 IMPORT
    (* type *)  CARD64LE, INT64LE,
    (* proc *)  Compare64LE, Div10LE, ABS64;

FROM Conversions IMPORT
    (* proc *)  HexByteToString, Card32ToHexString;

FROM STextIO IMPORT
    (* proc *)  WriteChar, WriteString, WriteLn;

(************************************************************************)
(*                     DECIMAL OUTPUT, LEFT JUSTIFIED                   *)
(************************************************************************)

PROCEDURE WriteCard (N: CARDINAL);

    (* Writes N in decimal. *)

    BEGIN
        IF N > 9 THEN
            WriteCard (N DIV 10);
            N := N MOD 10;
        END (*IF*);
        WriteChar (CHR(ORD('0')+N));
    END WriteCard;

(************************************************************************)

PROCEDURE WriteCard64 (N: CARD64LE);

    (* Writes N in decimal. *)

    CONST ten = CARD64LE {10, 0};

    VAR remainder: CARDINAL;

    BEGIN
        IF Compare64LE (N, ten) >= 0 THEN
            Div10LE (N, N, remainder);
            WriteCard64 (N);
        ELSE
            remainder := N.low;
        END (*IF*);
        WriteChar (CHR(ORD('0') + remainder));
    END WriteCard64;

(************************************************************************)

PROCEDURE WriteInt64 (A: INT64LE);

    (* Writes N in decimal. *)

    CONST ten = CARD64LE {10, 0};

    BEGIN
        IF A.high < 0 THEN
            WriteChar ('-');
        END (*IF*);
        WriteCard64 (ABS64(A));
    END WriteInt64;

(************************************************************************)

PROCEDURE WriteCardRJ (N, space: CARDINAL);

    (* Writes N in decimal, right-justified in space spaces. *)

    VAR j: CARDINAL;

    BEGIN
        IF space = 0 THEN
            WriteChar ('*');
        ELSE
            IF N < 10 THEN
                FOR j := 1 TO space-1 DO
                    WriteChar (' ');
                END (*FOR*);
            END (*IF*);
            IF N >= 10 THEN
                IF space < 2 THEN
                    WriteChar ('*');
                ELSE
                    WriteCardRJ (N DIV 10, space-1);
                END (*IF*);
            END (*IF*);
            N := N MOD 10;
            WriteChar (CHR(ORD('0') + N));
        END (*IF*);
    END WriteCardRJ;

(************************************************************************)
(*                   HEXADECIMAL OUTPUT, LEFT JUSTIFIED                 *)
(************************************************************************)

PROCEDURE WriteHex16 (N: CARDINAL);

    (* Writes N in hexadecimal. *)

    VAR buffer: ARRAY [0..3] OF CHAR;

    BEGIN
        HexByteToString (N DIV 256, buffer, 0);
        HexByteToString (N MOD 256, buffer, 2);
        WriteString (buffer);
    END WriteHex16;

(************************************************************************)

PROCEDURE WriteHex32 (N: CARDINAL);

    (* Writes N in hexadecimal. *)

    VAR buffer: ARRAY [0..7] OF CHAR;

    BEGIN
        Card32ToHexString (N, buffer);
        WriteString (buffer);
    END WriteHex32;

(************************************************************************)

PROCEDURE WriteHex64 (N: CARD64LE);

    (* Writes N in hexadecimal. *)

    BEGIN
        WriteHex32 (N.high);
        WriteHex32 (N.low);
    END WriteHex64;

(************************************************************************)

END SIntIO.

