DEFINITION MODULE MCP4AttributSys;  (* Ch. Jacobi  5.4.81 *)
  
(* Attribut-System 
   for Pass 4 of the Compiler for the Lilith Computer *)


  FROM MCBase IMPORT Idptr, Stptr, Stringptr;
 
  EXPORT QUALIFIED 
    ArithmeticType, AtMode, ModeSet, Attribut,
    HasAlreadyCode,
    TestBaseType, ResultType, Arithmetic,
    RangeCheckForConstant, RangeCheck, 
    SizeType, SimpleType,
    Load, LoadAddr, Store,
    LoadDynHigh, PreAssign, Assign;

  
  TYPE
    ArithmeticType = (signed, unSigned, bitwise, floating, logical);
  
    AtMode =
      (globalMod, localMod, loadedMod, addrLoadedMod, externalMod,
       indexMod, byteIndexMod, doubleIndexMod, absolutMod,
       constantMod, procedureMod, stringConstMod, doubleConstMod,
       stringTemplateMod, illegalMod);

      (* globalMod:         LGW, LGD 
         localMod:          LLW, LLD 
         loadedMod:
         addrLoadedMod:     LSW
         externalMod:       LEW
         indexMod:          LXW 
         byteIndexMod:      LXB
         doubleIndexMod:    LXD
         absolutMod:        LIW addr; addr := 0 --> addrLoadedMod
         constantMod:       LIn, LIB, LIW
         procedureMod:      CL, CX
         stringConstMod:    RDS (not generated by the current implementation)
         doubleConstMod:    LID
         stringTemplateMod: LGW2 --> addrLoadedMod
         illegalMod:
      *)

    ModeSet  = SET OF AtMode;
  
    Attribut = 
      RECORD
        typtr: Stptr;
        CASE mode: AtMode OF
            globalMod, localMod, addrLoadedMod, externalMod,
            absolutMod, stringTemplateMod:
              addr: CARDINAL; (*in case of addrLoadedMod this is an offset*)
              CASE AtMode OF
                  externalMod: (*only variabes, no constants*)
                    moduleNo: CARDINAL
                | localMod, addrLoadedMod:
                    CASE BOOLEAN OF (*used for dynamic array parameters*)
                      TRUE: dynArrLevelDiff, dynArrOffset, dynArrPS: CARDINAL 
                    END
              END
          | constantMod:
              CASE BOOLEAN OF 
                  TRUE:  value:  CARDINAL;
                | FALSE: iValue: INTEGER;  
              END
          | doubleConstMod:
              CASE BOOLEAN OF
                  TRUE:  r1, r2: CARDINAL
                | FALSE: r: REAL  
              END
          | stringConstMod:
              strgPtr: Stringptr
          | procedureMod:
              procPtr: Idptr (*for module number use procPtr^.globmod^.modnum*)
          | loadedMod, indexMod, byteIndexMod, doubleIndexMod: 
        END;
      END (* Attribut *);
  
     (* module numbers: variables: there is an explicite field;
                        constants: a copy is made 
                        procedures, strings: follow the pointers; for strings
                                             the current implementation makes a copy *)

  CONST 
    HasAlreadyCode = ModeSet{indexMod, byteIndexMod,
                             doubleIndexMod, loadedMod, addrLoadedMod};


  PROCEDURE TestBaseType(ft: Stptr): Stptr;
    (* Basetype of subrange types, otherwise no change, 
       but gives intcard whenever possible *)

  PROCEDURE ResultType(VAR fat1,fat2: Attribut): Stptr;
    (* result type of arithmetic operations *)

  PROCEDURE Arithmetic(VAR fat1,fat2: Attribut): ArithmeticType;
    (* result type of arithmetic operations *)

  PROCEDURE RangeCheckForConstant(dest: Stptr; VAR fat: Attribut);
    (* tests assignment of a constant to an typed variable if fat is constant; 
       constant in an Attribut variable allows distinction
       of very negative integers from very big cardinals *)

  PROCEDURE RangeCheck(dest: Stptr; VAR fat: Attribut);
    (* may load fat if not constant *)

  PROCEDURE SizeType(VAR fat: Attribut) : INTEGER;   
    (* Return the size of the entity given by fat *)
  
  PROCEDURE SimpleType(VAR fat: Attribut): BOOLEAN;   
    (* Returns fat describes an simple typed attribut *)
  
  PROCEDURE Load(VAR fat: Attribut);
    (* Generate code to load the value of        
       fat onto the expression stack *)       
      
  PROCEDURE LoadAddr(VAR fat: Attribut);
    (* Generate code to load the address of                                     
       fat onto the expression stack *)

  PROCEDURE Store(VAR fat: Attribut);
    (* Generate code to store the value from        
       the expression stack onto fat *)       
      
  PROCEDURE LoadDynHigh(VAR fat: Attribut);
    (* loads the HIGH value of an dynamic array *)

  PROCEDURE PreAssign(VAR fat: Attribut);
    (* Generate code to prepare the attribut such that 
       a subsequent value may be loaded and assigned 
       to with assign (address prepaired..) *)

  PROCEDURE Assign(VAR desAT, expAT: Attribut);
    (* code for assignment desAT := expAT;
       dynamic array not allowed, see Language definition *)

END MCP4AttributSys.  

