(*
    Title: 	Module handling - Definitions
    LastEdit:	"Sun Sep 23 16:42:30 1984"
    Author: 	Mick Jordan
		Cambridge University Computer Laboratory
*)

DEFINITION MODULE LModule;

FROM SystemTypes IMPORT String;
FROM HashStrings IMPORT HashTable, HashId;
IMPORT KeyTypes;

EXPORT QUALIFIED 
    MODULENAMESIZE, KEYSIZE, KEY, MODULENAME, ModuleStatus,
    IMPORTFRAMEPTR, IMPORTFRAME, MODULEPTR, ISIMPORTEDBYPTR,
    Add, CheckKeys, modulelist, Mtable, Pname, InitTable, InitTableUpb;

CONST 
    MODULENAMESIZE = KeyTypes.ModulenameSize;
    KEYSIZE = KeyTypes.KeySize;

TYPE KEY = KeyTypes.Keys;
    ModuleStatus = KeyTypes.ModuleStatus;
    MODULENAME = HashId;

    MODULEPTR = POINTER TO RMODULE;
    IMPORTFRAMEPTR = POINTER TO IMPORTFRAME;
    IMPORTFRAME = RECORD
    (*  Used for Import frames and the  header frame *)
        link: IMPORTFRAMEPTR;
        name: MODULENAME;
	keys:  KEY;
        status: ModuleStatus;   (* only for Headerframe *)
        module: MODULEPTR;		(* ptr to corres. RMODULE record *)
    END;
    
TYPE ISIMPORTEDBYPTR = POINTER TO ISIMPORTEDBY;
TYPE ISIMPORTEDBY = RECORD
(*  back pointers to all the modules which import a given module,
    plus a pointer to the import frame record in the associated module *)
        link: ISIMPORTEDBYPTR;
        module: MODULEPTR;
        import: IMPORTFRAMEPTR;
    END (* record *);

TYPE RMODULE = 
    RECORD
        link: MODULEPTR;
	fname: ARRAY [0..79] OF CHAR;
        itself, imports : IMPORTFRAMEPTR;
        isimportedbylist: ISIMPORTEDBYPTR;
        visited: BOOLEAN;
    END;

PROCEDURE Add(name: MODULENAME; level: CARDINAL; VAR mp: MODULEPTR);
(*  Add module 'name' to the list of modules, and then add all the
    modules it imports.
*)

PROCEDURE CheckKeys(mp: MODULEPTR): BOOLEAN;
(*  Ensure that all the modules in the program are consistent
    with each other, return TRUE if so.
*)

PROCEDURE Pname(name: MODULENAME; VAR pname: String);
(*  maps 'name' into 'pname'.
*)

VAR modulelist: MODULEPTR;
(*  List of all modules in the program.
*)
VAR Mtable: HashTable;
(*  Hash table for module names.
*)
VAR InitTable: ARRAY [0 .. 255] OF MODULEPTR;
(*  table to record the order for module initialisation
*)
VAR InitTableUpb: CARDINAL;
(*  upper bound for InitTable
*)

END LModule .

