(***************************************************************************

     $RCSfile: OCG.mod $
  Description: Global constants for the compiler

   Created by: fjc (Frank Copeland)
    $Revision: 4.9 $
      $Author: fjc $
        $Date: 1994/07/26 18:27:38 $

  Copyright © 1993-1994, Frank Copeland
  This module forms part of the OC program
  See OC.doc for conditions of use and distribution

  Log entries are at the end of the file.

***************************************************************************)

MODULE OCG;

(*
** $C= CaseChk       $I= IndexChk  $L= LongAdr   $N= NilChk
** $P- PortableCode  $R= RangeChk  $S= StackChk  $T= TypeChk
** $V= OvflChk       $Z= ZeroVars
*)

IMPORT Dos, SYS := SYSTEM;

CONST

  (* Sizes in bytes of basic data types. *)

  ByteSize * = 1; BoolSize * = 1; CharSize * = 1;
  SIntSize * = 1; IntSize * = 2; LIntSize * = 4;
  RealSize * = 4; LRealSize * = RealSize;
  BSetSize * = 1; WSetSize * = 2; SetSize * = 4;
  PtrSize * = 4; ProcSize * = 4;

  (*
  ** Maximum size of a procedure's parameter list. This must correspond
  ** to the constant used by the stack checking code. See STACKCHK.asm.
  ** *Must* be at least 1500, to allow for the stack requirements of
  ** dos.library functions.
  *)

  ParLimit * = 1500;

  (* Minima and Maxima of basic data types. *)

  MinBool * = 0; MaxBool * = 1; MinChar * = 0; MaxChar * = 0FFH;
  MinSInt * = -80H; MaxSInt * = 7FH;
  MinInt * = -8000H; MaxInt * = 7FFFH;
  MinLInt * = 80000000H; MaxLInt * = 7FFFFFFFH;
  MinSet * = 0; MaxBSet * = 7; MaxWSet * = 15; MaxSet * = 31;

  (* REALs are implemented as Motorola FFP Single-Precision reals. *)
  MinReal * = MIN (REAL)(*-9.22337177E18*);
  MaxReal * = MAX (REAL)(*9.22337177E18*);
  MaxExp * = 18;

  (*
    For now, LONGREALs are the same as REALs.  In future, they will be
    implemented as IEEE double-precision reals.
  *)
  MinLReal * = MinReal; MaxLReal * = MaxReal; MaxLExp * = MaxExp;

  (*
   * Object and item modes, used by Module OCT and others. These are
   * subject to change.
   *)

  Undef   * =  0;
  Var     * =  1; (* local and global variables and value parameters *)
  VarX    * =  2; (* indexed array variables *)
  VarR    * =  3; (* value parameter passed in a register *)
  VarArg  * =  4; (* C-style vararg pushed on stack, for libcalls only *)
  Ind     * =  5; (* variable parameters *)
  IndX    * =  6; (* indexed dynamic array parameters *)
  IndR    * =  7; (* variable parameter passed in a register *)
  RegI    * =  8; (* register indirect mode with displacement *)
  RegX    * =  9; (* register indirect mode with displacement and index *)
  Lab     * = 10; (* absolute mode, the address of a label *)
  LabI    * = 11; (* immediate mode, the address of a label *)
  Abs     * = 12; (* absolute mode *)
  Con     * = 13; (* constants *)
  Push    * = 14; (* register indirect mode with predecrement *)
  Pop     * = 15; (* register indirect mode with postincrement *)
  Coc     * = 16; (* condition code *)
  Reg     * = 17; (* register direct mode *)
  Fld     * = 18; (* record fields *)
  Typ     * = 19; (* types *)
  LProc   * = 20; (* local (non-exportable) procedures *)
  XProc   * = 21; (* exportable procedures *)
  SProc   * = 22; (* standard procedures *)
  LibCall * = 23; (* Amiga library functions *)
  TProc   * = 24; (* Type-bound procedure *)
  FProc   * = 25; (* Foreign procedures (such as in amiga.lib) *)
  Mod     * = 26; (* Modules *)
  Head    * = 27; (* symbol scope header *)
  RList   * = 28; (* Register list for MOVEM *)

VAR
  Verbose *: BOOLEAN; (* Verbose compiler output. *)
  Trace -: BOOLEAN; (* Trace procedure calls *)
  indent : INTEGER; (* Indent level for tracing *)
  logFile : Dos.FileHandlePtr;
  Digit : ARRAY 17 OF CHAR;

CONST
  logFileName = "CON:100/56/540/189/Oberon.log/CLOSE/WAIT";
  DigitString = "0123456789ABCDEF";

(*------------------------------------*)
PROCEDURE Write * (ch : CHAR);

  VAR ignore : LONGINT;

BEGIN (* Write *)
  IF Trace THEN ignore := Dos.base.Write (logFile, ch, 1) END
END Write;

(*------------------------------------*)
(* $D- disable copying of open arrays *)
PROCEDURE WriteStr * (s : ARRAY OF CHAR);

  VAR ignore : LONGINT;

BEGIN (* WriteStr *)
  IF Trace THEN ignore := Dos.base.Write (logFile, s, SYS.STRLEN (s)) END
END WriteStr;

(*------------------------------------*)
PROCEDURE WriteInt * (i : LONGINT);

  VAR ignore : LONGINT;

  (*------------------------------------*)
  PROCEDURE WriteDigit (i : LONGINT);

    VAR ignore : LONGINT;

  BEGIN (* WriteDigit *)
    IF i > 0 THEN WriteDigit (i DIV 10); Write (Digit [i MOD 10]) END
  END WriteDigit;

BEGIN (* WriteInt *)
  IF Trace THEN
    IF i = 0 THEN Write ("0")
    ELSE IF i < 0 THEN Write ("-") END; WriteDigit (ABS (i))
    END
  END
END WriteInt;

(*------------------------------------*)
(* $D- disable copying of open arrays *)
PROCEDURE TraceIn * (mod, proc : ARRAY OF CHAR);

  VAR i : INTEGER;

BEGIN (* TraceIn *)
  IF Trace THEN
    i := 0; WHILE i < indent DO WriteStr ("  "); INC (i) END;
    WriteStr (">>"); WriteStr (mod); Write ("."); WriteStr (proc);
    Write ("\n");
    INC (indent)
  END
END TraceIn;

(*------------------------------------*)
(* $D- disable copying of open arrays *)
PROCEDURE TraceOut * (mod, proc : ARRAY OF CHAR);

  VAR i : INTEGER;

BEGIN (* TraceOut *)
  IF Trace THEN
    DEC (indent);
    i := 0; WHILE i < indent DO WriteStr ("  "); INC (i) END;
    WriteStr ("<<"); WriteStr (mod); Write ("."); WriteStr (proc);
    Write ("\n");
  END
END TraceOut;

(*------------------------------------*)
PROCEDURE StartTrace * ();

BEGIN (* StartTrace *)
  logFile := Dos.base.Open (logFileName, Dos.modeNewFile);
  Trace := TRUE;
END StartTrace;

(*------------------------------------*)
PROCEDURE EndTrace * ();

BEGIN (* EndTrace *)
  IF Trace THEN
    Dos.base.OldClose (logFile); Trace := FALSE; logFile := NIL
  END
END EndTrace;

(*------------------------------------*)
PROCEDURE* Cleanup ();

BEGIN (* Cleanup *)
  IF logFile # NIL THEN Dos.base.OldClose (logFile); logFile := NIL END;
END Cleanup;

BEGIN
  Digit := DigitString; indent := 0;
  Trace := FALSE; logFile := NIL;
  SYS.SETCLEANUP (Cleanup)
END OCG.

(***************************************************************************

  $Log: OCG.mod $
  Revision 4.9  1994/07/26  18:27:38  fjc
  *** empty log message ***

  Revision 4.8  1994/07/25  00:43:07  fjc
  - Exported ParLimit.

  Revision 4.7  1994/07/22  13:58:56  fjc
  - Exported FProc.

  Revision 4.6  1994/07/10  12:44:34  fjc
  - Changed to use new SETCLEANUP format.

  Revision 4.3  1994/06/06  18:34:55  fjc
  - Exported VarArg item mode.

  Revision 4.2  1994/06/05  22:43:28  fjc
  - Changed to use new Amiga interface.
  - Added code to cleanup log file.

  Revision 4.1  1994/06/01  09:33:44  fjc
  - Bumped version number

***************************************************************************)

