(**************************************** * * * MODULA-2 Multi-Pass Compiler * * **************************** * * * * VAX/VMS Implementation * * * * * * MVCPublic: * * * * public part of the common base * * of the Modula-2 compiler * * * * Version 3.1 of 1-FEB-1983 * * Update 9 of 21-SEP-1983 * * * * Based on PDP11 Implementation: * * Version M22 of 17.03.81 * * * * Institut fuer Informatik * * ETH-Zuerich * * CH-8092 Zuerich * * * ****************************************) (**************************************** * Updates: * * - - - - - - - - - - - - - - - - - - - * * Nr. 1 of 7-APR-1983 by M. Mall * * Module MVCLi4 Nr. 1 * * - - - - - - - - - - - - - - - - - - - * * Nr. 2 of 14-APR-1983 by M. Mall * * Module MVCP3 Nr. 1 * * - - - - - - - - - - - - - - - - - - - * * Nr. 3 of 29-APR-1983 by J. Koch * * Module MVCP4 Nr. 1 * * - - - - - - - - - - - - - - - - - - - * * Nr. 4 of 24-MAY-1983 by M. Mall * * Module MVCP4 Nr. 2 * * - - - - - - - - - - - - - - - - - - - * * Nr. 5 of 13-JUN-1983 by J. Koch * * Module MVCP4 Nr. 3 * * - - - - - - - - - - - - - - - - - - - * * Nr. 6 of 13-JUN-1983 by M. Mall * * Module MVCAttributHandling Nr. 1 * * - - - - - - - - - - - - - - - - - - - * * Nr. 7 of 28-JUN-1983 by M. Mall * * Module MVCP4 Nr. 4 * * - - - - - - - - - - - - - - - - - - - * * Nr. 8 of 12-JUL-1983 by M. Mall * * Module MVCLi4 Nr. 2 * * - - - - - - - - - - - - - - - - - - - * * Nr. 9 of 21-SEP-1983 by J. Koch * * Module MVCP4 Nr. 5 * ****************************************) IMPLEMENTATION MODULE MVCPublic; (* M. Mall, P. Putfarken, EK *) IMPORT MVCMonitor, MVCP1, MVCP2, MVCListing, MVCSymFile, MVCP3, MVCP4, MVCErrors, FileSystem, FileNames, Terminal, DateTime, CommandLanguageInterface; FROM MVCMonitor IMPORT StopMonitorValues; FROM Terminal IMPORT WriteString, WriteLn; FROM FileNames IMPORT FileName; FROM FileSystem IMPORT File, Create, Close, Release, Reset, Parse, Done, ShowStatus; TYPE Passes = (pass1, pass2, pass3, pass4, pass5, finis); FileType = (newLIS, newOBJ, newSYM); NewFiles = SET OF FileType; VAR passindicator: Passes; proc: PROC; allfilesok : BOOLEAN; createdfiles : NewFiles; lisSpec, objSpec, symSpec: FileName; MODULE MVCInit; FROM FileSystem IMPORT File, ShowStatus, Done, Open, Name, Parse; FROM FileNames IMPORT FileName; FROM Terminal IMPORT WriteString, WriteLn; FROM DateTime IMPORT Time; FROM CommandLanguageInterface IMPORT CLI$PRESENT, CLI$GET_VALUE; IMPORT MVCompilerVersion, source, InterInFile, InterOutFile, modFile, Compilerstatus, Statset, compstat, optStrings, comptime, symfileextension, lisSpec, objSpec, symSpec; VAR compiling : BOOLEAN; (* compiler may run *) PROCEDURE SetOption (option: ARRAY OF CHAR; cstat: Compilerstatus); VAR i: INTEGER; PROCEDURE SetFileName (VAR filename: FileName; defnam: ARRAY OF CHAR); VAR fnstatus: BITSET; i: CARDINAL; BEGIN filename := ""; IF ODD(CLI$GET_VALUE(option,filename)) THEN i := HIGH(filename); WHILE (i > 0) AND (filename[i] = " ") DO filename[i] := 0C; DEC(i); END; Parse (filename, defnam, filename, fnstatus); IF Done() THEN Parse(filename, source, filename, fnstatus); END; ELSE Parse (defnam, source, filename, fnstatus); END; IF NOT Done() THEN ShowStatus; compiling := FALSE; END; END SetFileName; BEGIN FOR i := 0 TO HIGH(option) DO optStrings[cstat][i] := option[i]; END; optStrings[cstat][HIGH(option)+1] := 0C; IF ODD(CLI$PRESENT(option)) THEN INCL(compstat,cstat); CASE cstat OF listings: SetFileName (lisSpec, "SYS$DISK:[].LIS;"); | objects: SetFileName (objSpec, "SYS$DISK:[].OBJ;"); | symfiles: SetFileName (symSpec, "SYS$DISK:[].SYM;"); ELSE END; END; END SetOption; PROCEDURE WriteOption(cstat: Compilerstatus; set: BOOLEAN); BEGIN IF set THEN IF cstat IN compstat THEN WriteString("/"); WriteString(optStrings[cstat]) END; ELSIF NOT (cstat IN compstat) THEN WriteString("/NO"); WriteString(optStrings[cstat]); END; END WriteOption; PROCEDURE InitCompilation; VAR Result,i : CARDINAL; fnstatus: BITSET; BEGIN (* init compiler work files *) InterInFile := File(NIL); InterOutFile := File(NIL); (* get compilation time *) Time(comptime); (* read source file name *) source := ""; Result := CLI$GET_VALUE("FILESPEC",source); i := HIGH(source); WHILE (i > 0) AND (source[i] = " ") DO source[i] := 0C; DEC(i); END; (* lookup for source file *) Parse( source, ".MOD", source, fnstatus ); IF Done() THEN Open (modFile, source, FALSE); END; IF NOT Done() THEN ShowStatus; ELSE Name(modFile,source); compiling := TRUE; SetOption("CHECK",checks); SetOption("DEBUG",debugs); SetOption("LIST",listings); SetOption("LOG",logs); SetOption("OBJECT",objects); SetOption("QUERY",querys); SetOption("SYMFILE",symfiles); SetOption("MACHINE_CODE",machinecodes); SetOption("CROSS_REFERENCE",crossrefs); IF NOT (listings IN compstat) THEN EXCL(compstat,machinecodes); EXCL(compstat,crossrefs); ELSIF NOT (objects IN compstat) THEN EXCL(compstat,machinecodes); END; IF logs IN compstat THEN WriteString(MVCompilerVersion); WriteString(" compiling "); WriteString(source); WriteOption(checks,FALSE); WriteOption(crossrefs,TRUE); WriteOption(debugs,TRUE); WriteOption(listings,TRUE); WriteOption(machinecodes,TRUE); WriteOption(objects,FALSE); WriteOption(querys,TRUE); WriteOption(symfiles,FALSE); WriteLn; END; END END InitCompilation; BEGIN (*MVCInit*) MVCompilerVersion := 'VAX-11 Modula-2 V3.1-9'; compstat := Statset{}; compiling := FALSE; InitCompilation; IF compiling THEN INCL(compstat,compiles) END; END MVCInit; PROCEDURE CreateFile(VAR f: File; filtyp: FileType; filspec: FileName); BEGIN Create(f, filspec, TRUE, filtyp=newLIS); IF NOT Done() THEN ShowStatus; allfilesok := FALSE ELSE INCL(createdfiles,filtyp) END END CreateFile; PROCEDURE Compilation; VAR mess : CARDINAL; passtitle : ARRAY [1..7], [0..24] OF CHAR; (* contains titles for the monitoring * system (MODULE MVCMonitor) *) PROCEDURE SetTitles; BEGIN passtitle[1] := 'Syntax analysis'; passtitle[2] := 'Declaration analysis'; passtitle[3] := 'Body analysis'; passtitle[4] := 'Code generation'; passtitle[5] := 'Symbol file generation'; passtitle[6] := 'Listing generation'; passtitle[7] := 'Error messages'; END SetTitles; PROCEDURE WriteMessage(fmess: CARDINAL); BEGIN IF logs IN compstat THEN CASE fmess OF 1 .. 7 : WriteString(passtitle[fmess]); | 8 : WriteString(" ---- error"); | 9 : WriteString("End of compilation"); ELSE END; WriteLn; END; END WriteMessage; PROCEDURE ResetInterPassFiles; BEGIN Reset(InterOutFile); Release(InterInFile); InterInFile := InterOutFile; IF (passindicator < pass4) OR (passindicator = pass4) AND (machinecodes IN compstat) THEN Create(InterOutFile, "INTERFILE.MVC", TRUE, passindicator = pass4); IF NOT Done() THEN ShowStatus; allfilesok := FALSE END ELSE InterOutFile := File(NIL); END; END ResetInterPassFiles; BEGIN (* Compilation *) SetTitles; passindicator := pass1; allfilesok := TRUE; LOOP CASE passindicator OF pass1: symfileextension := ".SYM"; mess := 1; ResetInterPassFiles; proc := MVCP1.Pass1; | pass2: IF symerrs IN compstat THEN (* stop compilation *) WriteString(" ---- symbolfiles missing"); WriteLn; INCL(compstat,globerrs); EXIT ELSE mess := 2; ResetInterPassFiles; proc := MVCP2.Pass2; END; | pass3: IF defs IN compstat THEN EXCL(compstat,machinecodes); EXCL(compstat,objects); IF (globerrs IN compstat) OR (listings IN compstat) AND NOT (symfiles IN compstat) THEN (* listing generation *) proc := MVCListing.Listing; passindicator := finis; IF listings IN compstat THEN mess := 6; CreateFile(lstFile,newLIS,lisSpec) ELSE mess := 7; END; ELSIF symfiles IN compstat THEN (* symbol file generation *) mess := 5; proc := MVCSymFile.SymFile; CreateFile(symFile,newSYM,symSpec) ELSE EXIT END; ELSE EXCL(compstat,symfiles); mess := 3; ResetInterPassFiles; proc := MVCP3.Pass3; END; | pass4: IF (globerrs IN compstat) OR (defs IN compstat) OR (listings IN compstat) AND NOT (objects IN compstat) THEN proc := MVCListing.Listing; passindicator := finis; IF listings IN compstat THEN mess := 6; CreateFile(lstFile,newLIS,lisSpec); ELSIF globerrs IN compstat THEN mess := 7; ELSE EXIT; END; ELSIF objects IN compstat THEN mess := 4; ResetInterPassFiles; proc := MVCP4.Pass4; CreateFile(objFile,newOBJ,objSpec); ELSE EXIT END; | pass5: IF (globerrs IN compstat) OR (listings IN compstat) THEN (* listing *) proc := MVCListing.Listing; passindicator := finis; IF listings IN compstat THEN mess := 6; IF machinecodes IN compstat THEN ResetInterPassFiles; END; CreateFile(lstFile,newLIS,lisSpec); ELSE mess := 7; END; ELSE EXIT; END; END; (* CASE *) IF NOT allfilesok THEN EXIT END; WriteMessage(mess); proc; IF passerrs IN compstat THEN compstat := compstat-Statset{passerrs,objects,symfiles,machinecodes}+ Statset{globerrs}; WriteMessage(8); END; StopMonitorValues(passtitle[mess]); IF passindicator = finis THEN EXIT END; INC(passindicator); END; (* LOOP *) (* termination *) Release(InterInFile); Release(InterOutFile); Close(modFile); IF newLIS IN createdfiles THEN Close(lstFile) END; IF newOBJ IN createdfiles THEN IF compstat * Statset{globerrs,defs,objects} = Statset{objects} THEN Close(objFile) ELSE Release(objFile) END; END; IF newSYM IN createdfiles THEN IF compstat*Statset{globerrs,syms,symfiles} = Statset{syms,symfiles} THEN Close(symFile) ELSE Release(symFile) END; END; WriteMessage(9); END Compilation; BEGIN (* MVCPublic *) createdfiles := NewFiles{}; IF compiles IN compstat THEN Compilation END; END MVCPublic.