-- MDSubr.Mesa, last edit December 30, 1982 5:58 pm
-- Pilot 5.0/ Mesa 7.0
-- definitions file for subroutines for the modeller

DIRECTORY
Environment: TYPE USING [wordsPerPage],
File: TYPE USING [Capability, nullCapability],
Stream: TYPE USING [Handle],
Subr: TYPE USING [PackedTime, TTYProcs];

MDSubr: DEFINITIONS = {

-- TYPES and CONSTANTS
versionUnknown: Subr.PackedTime = LONG[0];
versionNil: Subr.PackedTime = LONG[-1];

-- look for this file in the directory
lookNil: CARDINAL = 32767;
Look: TYPE = LONG POINTER TO LookRecord;
LookRecord: TYPE = RECORD[
 name: LONG STRINGNIL,  -- name of file to look for
 need: BOOLFALSE,   -- if false all info below garb.
 presentonlocaldisk: BOOLFALSE, -- is on disk, otherwise FALSE
 cap: File.Capability ← File.nullCapability, -- if presentonlocaldisk, its cap
 localversion: Subr.PackedTime ← versionUnknown,-- for local file
 remoteversion: Subr.PackedTime ← versionUnknown,-- for a remote file
 cardhi: CARDINAL ← 0,
 cardlow: CARDINAL ← 32000,
 remotelength: LONG CARDINAL ← 0,
 locallength: LONG CARDINAL ← 0,
 besttime: Subr.PackedTime ← versionNil -- the best time from remote&loc
 ];
LookSeq: TYPE = LONG POINTER TO LookSeqRecord;
LookSeqRecord: TYPE = RECORD[
 lookzone: UNCOUNTED ZONENIL,
 size: CARDINAL ← 0,  -- current size
 body: SEQUENCE maxsize: CARDINAL OF LookRecord
 ];

entNil: CARDINAL = 32767;
Entry: TYPE = LONG POINTER TO EntryRecord;
EntryRecord: TYPE = RECORD[
 name: LONG STRINGNIL,
 depends: LONG DESCRIPTOR FOR ARRAY OF CARDINAL,
 rule: LONG STRINGNIL,
 made: BOOLFALSE,  -- if true, already made
 visited: BOOLFALSE, -- used by tree walkers
 lookinx: CARDINAL ← lookNil -- index of "name" in look array
 ];
EntrySeq: TYPE = LONG POINTER TO EntrySeqRecord;
EntrySeqRecord: TYPE = RECORD[
 entryzone: UNCOUNTED ZONENIL,
 size: CARDINAL ← 0,  -- current size
 body: SEQUENCE maxsize: CARDINAL OF EntryRecord
 ];

SMALLDEPLIST: CARDINAL = 10;
HUGEDEPLIST: CARDINAL = Environment.wordsPerPage - 1;

-- be sure to update array TokString in mdsubrimpl.mesa if you change this
Token: TYPE = {tokBAD, tokEOF, tokLP, tokRP, tokLB, tokRB, tokDOT, tokCOLON,
tokCOMMA, tokEQ, tokAT, tokBANG, tokSEMI, tokGT, tokLT, tokUP, tokIMPLIES,
tokARROW, tokID, tokNUM, tokTYPE, tokPLUS, tokTHEN, tokPROC,
tokRETURNS, tokSTRLIT, tokSTRING, tokSELECT, tokFROM,tokDIR,
tokIMPORTS, tokEXPORTS,tokPROGRAM, tokBEGIN, tokDEFINITIONS,
tokOTHERS, tokCONTROL, tokCONFIG, tokLINKS, tokCODE, tokFRAME, tokPACK,
tokEND, tokUSING, tokSHARES, tokLET, tokOPEN, tokMONITOR};

StringSeq: TYPE = LONG POINTER TO StringSeqRecord;
StringSeqRecord: TYPE = RECORD[
 size: CARDINAL ← 0,
 body: SEQUENCE maxsize: CARDINAL OF StringVarRecord
 ];
StringVarRecord: TYPE = RECORD[
 str: LONG STRINGNIL,
 val: LONG STRINGNIL
 ];

MAXDEP: CARDINAL = 165; -- biggest is CoPilotDorado.Config
ModType: TYPE = {errortype, imports, exports, directory};
ModInfo: TYPE = LONG POINTER TO ModInfoRecord;
ModInfoRecord: TYPE = RECORD[
 parent: CARDINAL ← entNil, -- an index into entryse
 modulename: LONG STRINGNIL,
 sourcefileinx: CARDINAL ← entNil, -- an index into entryseq
 isdefn, isconfig: BOOLFALSE,
 dirinx, impinx, expinx: CARDINAL ← 0,
 dirname, imports, exports: ARRAY [0 .. MAXDEP) OF CARDINALALL[entNil]
 ];

-- a more refined Dependency structure
DepSeq: TYPE = LONG POINTER TO DepSeqRecord;
DepSeqRecord: TYPE = RECORD[
 bcdfilename: LONG STRINGNIL,
 bcdtime: LONG CARDINAL ← 0,
 srcfilename: LONG STRINGNIL,
 srctime: LONG CARDINAL ← 0,
 modulename: LONG STRINGNIL,
FreeString: PROC[LONG STRING] ← NIL, -- use to free the strings ...
 aflag: BOOLFALSE,  -- compiler switch /a
 bflag: BOOLTRUE,  -- etc.
 fflag: BOOLTRUE,
 jflag: BOOLFALSE,
 lflag: BOOLFALSE,
 nflag: BOOLTRUE,
 sflag: BOOLTRUE,
 uflag: BOOLFALSE,
 isdefns: BOOLFALSE,
 isconfig: BOOLFALSE,
 fromsource: BOOLFALSE, -- T => info from source file
 size: CARDINAL ← 0,
 body: SEQUENCE maxsize: CARDINAL OF ADepRecord
 ];
ADepRecord: TYPE = RECORD[
 relation: ModType ← errortype,
 modulename: LONG STRINGNIL,
 bcdfilename: LONG STRINGNIL,
 bcdtime: LONG CARDINAL ← 0,
 srctime: LONG CARDINAL ← 0
 ];

-- GLOBAL VARIABLES
-- defined in MDScanImpl.Mesa
peektok: Token;
peekvalue: LONG UNSPECIFIED;

-- PROGRAMS
MDSubrImpl, MDScanImpl: PROGRAM;

-- PROCS
-- defined in MDSubrImpl.Mesa
-- utilities
StripFirstWord: PROC[str, result: LONG STRING];

-- having to do with EntrySeq's
PrintEntries: PROC[entryseq: EntrySeq,
 sh: Stream.Handle ← NIL, stringseq: StringSeq,
 ttyhandle: Subr.TTYProcs];
GetAnEntry: PROC[name: LONG STRING, entryseq: EntrySeq]
RETURNS[i: CARDINAL, new: BOOL];
AddToDepends: PROC[parent, child: CARDINAL, entryseq: EntrySeq];
FreeEntrySeq: PROC[pentryseq: LONG POINTER TO EntrySeq];
WalkTheGraph: PROC[firstinx: CARDINAL, entryseq: EntrySeq, proc: PROC[Entry]];

-- having to do with Look's and Entry's together
ThrowAwayLeaves: PROC[firstinx: CARDINAL, entryseq: EntrySeq,
 lookseq: LookSeq, ismodel: BOOL];
CheckNames: PROC[entryseq: EntrySeq, lookseq: LookSeq];
ConvertToLook: PROC[entryseq: EntrySeq, lookseq: LookSeq];
-- having to do with compiler and binder options
InsertOtherSym: PROC[str, val: LONG STRING, stringseq: StringSeq];
LookupOtherSym: PROC[str: LONG STRING, stringseq: StringSeq]
RETURNS[LONG STRING];
GetCompilerRule: PROC[stringseq: StringSeq, name: LONG STRING,
 zone: UNCOUNTED ZONE] RETURNS[LONG STRING];
GetBinderRule: PROC[stringseq: StringSeq, name: LONG STRING,
 zone: UNCOUNTED ZONE] RETURNS[LONG STRING];


-- defined in MDScanImpl.Mesa
-- parsing of Mesa source files and .Configs
ParseObject: PROC[sh: Stream.Handle, parent: CARDINAL,
 entryseq: EntrySeq, pmod: ModInfo, depseq: DepSeq,
 stringseq: StringSeq, sfn: LONG STRING];
ScanInit: PROC[Stream.Handle];
NextTok: PROC[Stream.Handle] RETURNS[Token, LONG UNSPECIFIED];
GetTokString: PROC[tok: Token] RETURNS[LONG STRING];
CheckTok: PROC[Token, Token, LONG STRING];
StopScanner: PROC;
AddToMod: PROC[ModInfo, CARDINAL, ModType];
AddToDep: PROC[depseq: DepSeq, padeprecord: POINTER TO ADepRecord];

-- having to with looks
ReadLocalDirectory: PROC[lookseq: LookSeq];
ReadInLocalDirectoryAll: PROC[lookseq: LookSeq,
ThrowAwayThisFile: PROC[name: LONG STRING] RETURNS[BOOL]];
AnalyzeLocalFiles: PROC[oktosort: BOOL, lookseq: LookSeq,
 getcreatedate: BOOL];
PrintLook: PROC[lookseq: LookSeq];
SortByFileTime: PROC[lookseq: LookSeq, descending: BOOLFALSE];
SortByFileName: PROC[lookseq: LookSeq, descending: BOOLFALSE];
LookLook: PROC[name: LONG STRING, lookseq: LookSeq]
RETURNS[look: Look, lookinx: CARDINAL]; -- index in lookd
FreeLookSeq: PROC[plookseq: LONG POINTER TO LookSeq];
AddToLook: PROC[name: LONG STRING, lookseq: LookSeq] RETURNS[Look];

-- Inline Procedures
IsAlpha: PROC[c: CHAR] RETURNS[BOOL] = INLINE {
RETURN['a <= c AND c <= 'z OR 'A <= c AND c <= 'Z];
};

IsDigit: PROC[c: CHAR] RETURNS[BOOL] = INLINE {
RETURN['0 <= c AND c <= '9];
};

-- just like StringDefs.LowerCase but INLINE
ToLower: PROC[ch: CHAR] RETURNS[CHAR] = INLINE {
IF 'A <= ch AND ch <= 'Z THEN ch ← ch + ('a-'A);
RETURN[ch];
};

}.