DIRECTORY FS USING [StreamOpen], IO USING [PutFR, RIS, rope, STREAM, time], PasPrivate, PasPrivateVars, Rope USING [Cat, Equal, Length]; PasInit: CEDAR PROGRAM IMPORTS FS, IO, PasPrivate, PasPrivateVars, Rope EXPORTS PasPrivate = BEGIN OPEN PasPrivate, PasPrivateVars; PascalStandardFileNames: PUBLIC ARRAY StandardFiles OF ROPE _ ["INPUT", "OUTPUT", "TTY", "?FILE1", "?FILE2"]; PascalStandardProcedureNames: PUBLIC ARRAY StandardProcedures OF ROPE _ ["HALT", "GET", "PUT", "RESET", "REWRITE", "READ", "READLN", "WRITE", "WRITELN", "BREAK", "PACK", "UNPACK", "NEW", "DISPOSE", "PAGE", "RELEASE", "ASSIGN", "CONCAT", "PUTCHAR", "GETFILENAME", "DATE", "TIME", "?PROC1", "?PROC2", "?PROC3", "?PROC4", "?PROC5"]; PascalStandardFunctionNames: PUBLIC ARRAY StandardFunctions OF ROPE _ ["CLOCK", "ABS", "SQR", "SIN", "COS", "EXP", "LN", "SQRT", "ARCTAN", "ODD", "ORD", "CHR", "PRED", "SUCC", "EOF", "EOLN", "EOPAGE", "CARD", "LOWERBOUND", "UPPERBOUND", "MIN", "MAX", "FIRST", "LAST", "ROUND", "TRUNC", "LENGTH", "GETCHAR", "?FN1", "?FN2", "?FN3", "?FN4", "?FN5"]; textFile: FileTypePtr; configName: ROPE; configQ: OutputQueuePtr; makeFileQ: OutputQueuePtr _ NIL; alfa, alfaIndexRange: TypePtr; readySourceFileSeq: SourceFileSeqPtr _ NIL; compilerSwitches: ROPE; InitializeStandards: PUBLIC PROCEDURE= BEGIN s: Standards; MakeType: PROCEDURE [name: ROPE, t: GeneralTypePtr] RETURNS [IdentifierPtr] = BEGIN id: IdentifierPtr _ NewIdent[name: name]; id.type _ t; id.class _ Z.NEW[IdentifierTail_[type[]]]; RETURN[id]; END; -- of MakeType integerId _ MakeType["INTEGER", integer]; realId _ MakeType["REAL", real]; charId _ MakeType["CHAR", char]; [] _ MakeType["ASCII", charId]; booleanId _ MakeType["BOOLEAN", boolean]; stringId _ MakeType["STRING", string]; alfaIndexRange _ Z.NEW[subRange Type _ [subRange[hostType: integer, lower: 1, upper: 10]]]; alfa _ Z.NEW[array Type _ [array[ aIsPacked: TRUE, aElType: char, aIxType: alfaIndexRange]]]; [] _ MakeType["ALFA", alfa]; textFile _ Z.NEW[file Type _ [file[fileIsPacked: TRUE, textFile: TRUE, fileType: charId]]]; [] _ MakeType["TEXT", textFile]; maxIntegerId _ NARROW[NewIdent[name: "MAXINT"], ConstantIdentifierPtr]; maxIntegerId.type _ integerId; maxIntegerId.class _ Z.NEW[IdentifierTail_[constant[ scalarLink: NIL, value: LAST[PascalInteger]]]]; trueId _ NARROW[NewIdent[name: "TRUE"], ConstantIdentifierPtr]; trueId.type _ booleanId; trueId.class _ Z.NEW[IdentifierTail_[constant[scalarLink: NIL, value: 1]]]; falseId _ NARROW[NewIdent[name: "FALSE"], ConstantIdentifierPtr]; falseId.type _ booleanId; falseId.class _ Z.NEW[IdentifierTail_[constant[scalarLink: trueId, value: 0]]]; boolean.firstId _ falseId; nilId _ NARROW[NewIdent[name: "NIL"], ConstantIdentifierPtr]; nilId.type _ nil; -- I guess... nilId.class _ Z.NEW[IdentifierTail_[constant[scalarLink: NIL, value: 0]]]; FOR s IN StandardFiles DO id: IdentifierPtr _ NewIdent[name: PascalStandardFileNames[s]]; id.type _ textFile; id.class _ Z.NEW[IdentifierTail_[variable[]]]; ENDLOOP; FOR s IN StandardProcedures DO id: IdentifierPtr _ NewIdent[name: PascalStandardProcedureNames[s]]; id.type _ nilGeneralTypePtr; id.class _ Z.NEW[IdentifierTail_[procedure[source: standard[s]]]]; ENDLOOP; FOR s IN StandardFunctions DO id: IdentifierPtr _ NewIdent[name: PascalStandardFunctionNames[s]]; id.type _ integer; id.class _ Z.NEW[IdentifierTail_[procedure[source: standard[s]]]]; ENDLOOP; END; -- of InitializeStandards InitializeModules: PUBLIC PROCEDURE = BEGIN MB: PROCEDURE [sy: Symbol] = {MustBe[sy, "", MalformedInstr]}; GetFileNameFromSource: PROCEDURE [ext: ROPE] RETURNS [ROPE] = BEGIN fileName: ROPE; IF sy = identSy THEN BEGIN fileName_RopeSayIdent[]; InSymbol[]; IF CouldBe[periodSy, ""] AND sy = identSy THEN BEGIN fileName _ Rope.Cat[fileName, ".", ident]; InSymbol[]; END ELSE fileName _ Rope.Cat[fileName, ext]; END ELSE Error[MalformedInstr]; RETURN[fileName]; END; -- of GetFileNameFromSource NewFileQ: PROCEDURE [ext: ROPE] RETURNS [OutputQueuePtr] = { RETURN[Z.NEW[OutputQueue_ [contents: "", fileName: GetFileNameFromSource[ext]]]]}; ReadDestination: PROCEDURE RETURNS [dest: DestinationPtr] = { defs, impl: IdentifierPtr; defsTail: REF defsModule IdentifierTail; implTail: REF implModule IdentifierTail; markAsExportee: BOOL; IF sy # identSy THEN Error[MalformedInstr]; defs _ IdentLookup[pset: defsModules]; defsTail _ NARROW[defs.class]; markAsExportee _ defsTail.exportMe; InSymbol[]; IF sy = mulOpSy AND op = mulOp THEN {markAsExportee _ FALSE; InSymbol[]}; MB[commaSy]; impl _ IdentLookup[pset: implModules]; InSymbol[]; implTail _ NARROW[impl.class]; IF markAsExportee AND IdentLookup[name: defs.name, pset: implTail.exportees, couldFail: TRUE] = NIL THEN InsertOldIdent[id: defs, pset: implTail.exportees]; dest _ Z.NEW[Destination _ [defsModule: defs, implModule: impl]]; RETURN[dest]; }; DeclareDefs: PROCEDURE = { -- process the declaration of a defs module in the mod file defs: IdentifierPtr; defsTail: REF defsModule IdentifierTail; exportFromConfig: BOOLEAN _ FALSE; InSymbol[]; -- throw away the word "definitions" IF sy # identSy THEN Error[MalformedInstr]; defs _ NewIdent[pset: defsModules]; defsTail _ Z.NEW[defsModule IdentifierTail _ [defsModule[q: NewFileQ[".mesa"]]]]; defs.class _ defsTail; defsTail.openees _ CreateIdentifierSet[]; defsTail.importees _ CreateIdentifierSet[]; IF sy = mulOpSy AND op = mulOp THEN { -- exported interface InSymbol[]; exportFromConfig _ TRUE; }; IF CouldBe[lParentSy] THEN { ReadOpenee: PROC = { openee: IdentifierPtr; IF sy # identSy THEN Error[MalformedInstr]; openee _ IdentLookup[pset: defsModules, couldFail: TRUE]; IF openee = NIL THEN openee _ IdentLookup[pset: configImports]; InsertOldIdent[id: openee, pset: defsTail.openees]; InSymbol[]; IF sy = mulOpSy AND op = mulOp THEN InSymbol[] ELSE InsertOldIdent[id: openee, pset: defsTail.importees]; }; SequenceOf[ReadOpenee, commaSy]; MB[rParentSy]; }; MB[semiColonSy]; SELECT sy FROM externSy => { defsTail.compileMe _ FALSE; defsTail.q.fileName _ ""; }; forwardSy => NULL; identSy => { IF NOT Rope.Equal[ident, "TRASH"] THEN Error[MalformedInstr]; defsTail.compileMe _ defsTail.exportMe _ FALSE; defsTail.q.fileName _ ""; }; ENDCASE => Error[MalformedInstr]; IF exportFromConfig THEN { IF sy = identSy THEN Error[ImproperType]; [] _ NewIdent[name: defs.name, pset: configExports]; }; InSymbol[]; MB[semiColonSy]; }; DeclareImpl: PROCEDURE = { impl: IdentifierPtr; implTail: REF implModule IdentifierTail; InSymbol[]; -- throw away the word "program" IF sy # identSy THEN Error[MalformedInstr]; impl _ NewIdent[pset: implModules]; implTail _ Z.NEW[implModule IdentifierTail _ [implModule[q: NewFileQ[".mesa"]]]]; impl.class _ implTail; implTail.openedDefs _ CreateIdentifierSet[]; implTail.importedDefs _ CreateIdentifierSet[]; implTail.openedAndImportedImpls _ CreateIdentifierSet[]; implTail.exportees _ CreateIdentifierSet[]; IF CouldBe[lParentSy] THEN {ReadOpenee: PROC = {openee: IdentifierPtr; IF sy # identSy THEN Error[MalformedInstr]; openee _ IdentLookup[pset: defsModules, couldFail: TRUE]; IF openee = NIL THEN openee _ IdentLookup[pset: configImports, couldFail: TRUE]; IF openee = NIL THEN { -- special case of importing a program module via pointer to frame openee _ IdentLookup[pset: implModules]; InsertOldIdent[id: openee, pset: implTail.openedAndImportedImpls]; InSymbol[]} ELSE {InSymbol[]; InsertOldIdent[id: openee, pset: implTail.openedDefs]; IF sy = mulOpSy AND op = mulOp THEN InSymbol[] ELSE InsertOldIdent[id: openee, pset: implTail.importedDefs]}; }; SequenceOf[ReadOpenee, commaSy]; MB[rParentSy]}; MB[semiColonSy]; SELECT sy FROM externSy => {implTail.compileMe _ FALSE; implTail.q.fileName _ ""}; forwardSy => NULL; identSy => {IF NOT Rope.Equal[ident, "TRASH"] THEN Error[MalformedInstr]; implTail.compileMe _ implTail.bindMe _ FALSE; implTail.q.fileName _ ""}; ENDCASE => Error[MalformedInstr]; InSymbol[]; MB[semiColonSy]}; ModuleDefine: PROCEDURE[] = BEGIN dest: DestinationPtr; ParseOuterItem: PROCEDURE[] = BEGIN IF sy # identSy THEN Error[MalformedInstr]; SELECT TRUE FROM Rope.Equal[ident, "$OTHER_PROCS$"] => defaultDest[proc] _ dest; Rope.Equal[ident, "$OTHER_TYPES$"] => defaultDest[type] _ dest; Rope.Equal[ident, "$OTHER_CONSTS$"] => defaultDest[const] _ dest; Rope.Equal[ident, "$OTHER_VARS$"] => defaultDest[var] _ dest; Rope.Equal[ident, "$GLOBAL_LABELS$"] => defaultDest[globalLabel] _ dest; Rope.Equal[ident, "$MAIN$"] => defaultDest[main] _ dest; Rope.Equal[ident, "$REST$"] => FOR t: ItemType IN ItemType DO IF defaultDest[t] = NIL THEN defaultDest[t] _ dest ENDLOOP; ENDCASE => BEGIN m: IdentifierPtr _ NewIdent[pset: configTail.mentionedIdents]; m.type _ nilGeneralTypePtr; m.class _ Z.NEW[IdentifierTail_[outerItem[dest: dest]]]; END; InSymbol[]; END; -- of ParseModuleSon; dest _ ReadDestination[]; MB[becomesSy]; IF sy # semiColonSy THEN SequenceOf[ParseOuterItem, commaSy, ""]; END; -- of ModuleDefine SayTimeComment: PROCEDURE = BEGIN time: ROPE; time _ IO.PutFR["-- Pascal-to-Mesa translator output, translated at %g",IO.time[]]; SayLine[time]; SayLine[]; END; -- of SayTimeComment SayFileNameComment: PROCEDURE [r: ROPE] = BEGIN comment: ROPE; comment _ IO.PutFR["-- file: %g",IO.rope[r]]; SayLine[comment]; END; -- of SayFileNameComment GenerateModuleBoilerPlate: PROCEDURE [id: IdentifierPtr] = BEGIN q: OutputQueuePtr; moduleKind: {defs, impl}; defsTail: REF defsModule IdentifierTail; implTail: REF implModule IdentifierTail; first: BOOLEAN; SayDirLine: PROCEDURE [id: IdentifierPtr] = BEGIN IF first THEN first _ FALSE ELSE {SayLine[","]; Say[" "]}; SayIdent[id.name]; IF targetLanguage # cedar THEN { Say[": FROM """]; SayIdent[id.name]; Say[""""]}; END; SayModule: PROCEDURE [id: IdentifierPtr] = BEGIN IF first THEN first _ FALSE ELSE Say[", "]; SayIdent[id.name]; END; WITH id.class SELECT FROM thisTail: REF defsModule IdentifierTail => {moduleKind _ defs; defsTail _ thisTail; q _ thisTail.q}; thisTail: REF implModule IdentifierTail => {moduleKind _ impl; implTail _ thisTail; q _ thisTail.q}; ENDCASE => ERROR; PushOut[q]; SayFileNameComment[q.fileName]; SayTimeComment[]; SayLine[]; SayLine["DIRECTORY"]; Say[" "]; first _ TRUE; SELECT moduleKind FROM defs => EnumerateIdentifierSet[pset: defsTail.openees, p: SayDirLine]; -- only the asked for impl => {EnumerateIdentifierSet[pset: implTail.openedDefs, p: SayDirLine]; EnumerateIdentifierSet[pset: implTail.openedAndImportedImpls, p: SayDirLine]}; ENDCASE => ERROR; SayLine[";"]; SayLine[]; SayIdent[id.name]; SELECT moduleKind FROM defs => Say[": DEFINITIONS"]; impl => Say[": PROGRAM"]; ENDCASE => ERROR; Say[" IMPORTS "]; first _ TRUE; SELECT moduleKind FROM defs => {EnumerateIdentifierSet[pset: defsTail.importees, p: SayModule]; SayLine[" ="]}; impl => { EnumerateIdentifierSet[pset: implTail.importedDefs, p: SayModule]; EnumerateIdentifierSet[pset: implTail.openedAndImportedImpls, p: SayModule]; Say[" EXPORTS "]; first _ TRUE; EnumerateIdentifierSet[pset: implTail.exportees, p: SayModule]; SayLine[" = PUBLIC"]; }; ENDCASE => ERROR; Say["BEGIN OPEN "]; first _ TRUE; SELECT moduleKind FROM defs => EnumerateIdentifierSet[pset: defsTail.openees, p: SayModule]; impl => {EnumerateIdentifierSet[pset: implTail.openedDefs, p: SayModule]; EnumerateIdentifierSet[pset: implTail.openedAndImportedImpls, p: SayModule]}; ENDCASE => ERROR; SayLine[";"]; q _ CopyAndPopOut[]; SELECT moduleKind FROM defs => defsTail.q _ q; impl => implTail.q _ q; ENDCASE => ERROR; END; -- of GenerateModuleBoilerPlate ParseCompileDifferently: PROCEDURE [method: REF ANY] = BEGIN id: IdentifierPtr; curSeg: SegmentIdentifierTailPtr _ segmentsTail; name: Name _ ident; cid: REF compileDifferently IdentifierTail; MB[identSy]; WHILE CouldBe[periodSy, ""] DO id _ IdentLookup[ name: name, pset: curSeg.mentionedProcedures, couldFail: TRUE]; IF id = NIL THEN BEGIN id _ NewIdent[name: name, pset: curSeg.mentionedProcedures]; id.class _ Z.NEW[programSegment IdentifierTail _ [programSegment[mentionedVariables: CreateIdentifierSet[], mentionedProcedures: CreateIdentifierSet[]]]]; END; WITH id.class SELECT FROM sid: REF programSegment IdentifierTail => curSeg _ sid; ENDCASE; name _ ident; MB[identSy]; ENDLOOP; id _ IdentLookup[ name: name, pset: curSeg.mentionedVariables, couldFail: TRUE]; IF id = NIL THEN BEGIN id _ NewIdent[name: name, pset: curSeg.mentionedVariables]; cid _ Z.NEW[compileDifferently IdentifierTail _[compileDifferently[]]]; id.class _ cid; END ELSE cid _ NARROW[id.class]; WITH method SELECT FROM arrayMethod: REF ArrayDifferentlyMethod => cid.arrayHow _ arrayMethod^; procMethod: REF ProcDifferentlyMethod => cid.procHow _ procMethod^; ENDCASE; END; -- of ParseCompileDifferently ParseSpecialArray: PROCEDURE = {ParseCompileDifferently[ NEW[ArrayDifferentlyMethod _ specialArray]]}; ParseProcArray: PROCEDURE = {ParseCompileDifferently[ NEW[ArrayDifferentlyMethod _ procArray]]}; ParseComputedSeqArray: PROCEDURE = {ParseCompileDifferently[ NEW[ArrayDifferentlyMethod _ computedSeqArray]]}; ParseInlineProc: PROCEDURE = {ParseCompileDifferently[ NEW[ProcDifferentlyMethod _ inlineProc]]}; instrStream: STREAM; instrName: ROPE; PushOut[]; -- throw away the translated output until we really start! SourceFromStream[IO.RIS[commandHandle.commandLine], "commandLine"]; InSymbol[]; instrName _ GetFileNameFromSource[ext: ".mod"]; instrStream _ FS.StreamOpen[instrName]; SourceFromStream[instrStream, instrName]; InSymbol[]; defsModules _ CreateIdentifierSet[]; implModules _ CreateIdentifierSet[]; configImports _ CreateIdentifierSet[]; configExports _ CreateIdentifierSet[]; segmentsTail _ Z.NEW[programSegment IdentifierTail]; segmentsTail.mentionedProcedures _ CreateIdentifierSet[]; segmentsTail.mentionedVariables _ CreateIdentifierSet[]; segments _ Z.NEW[Identifier_ [hash: 0]]; -- a nil hash is OK since we never search for it segments.class _ segmentsTail; configTail _ Z.NEW[config IdentifierTail]; configTail.mentionedIdents _ CreateIdentifierSet[]; config _ Z.NEW[Identifier_ [hash: 0]]; config.class _ configTail; FOR t: ItemType IN ItemType DO defaultDest[t] _ NIL ENDLOOP; readySourceFileSeq _ NIL; IF CouldBe[lParentSy, ""] THEN BEGIN -- we should modularize the program AddSourceFile: PROCEDURE = BEGIN IF sy=identSy THEN BEGIN p: SourceFileSeqPtr _ readySourceFileSeq; IF p=NIL THEN readySourceFileSeq _ Z.NEW[SourceFileSeq_ [next: NIL, name: GetFileNameFromSource[".pas"]]] ELSE BEGIN WHILE p.next#NIL DO p _ p.next ENDLOOP; p.next _ Z.NEW[SourceFileSeq_ [next: NIL, name: GetFileNameFromSource[".pas"]]]; END END ELSE Error[MalformedIdList]; END; IF NOT Rope.Equal[ident, "CONFIGURATION"] THEN Error[MalformedInstr]; InSymbol[]; configName _ ident; configQ _ NewFileQ[".config"]; IF CouldBe[lParentSy] THEN { ReadConfigImportee: PROC = { IF sy # identSy THEN Error[MalformedInstr]; [] _ NewIdent[pset: configImports]; InSymbol[] }; SequenceOf[ReadConfigImportee, commaSy]; MB[rParentSy] }; MB[semiColonSy]; modularize _ TRUE; DO SELECT sy FROM beginSy => EXIT; programSy => DeclareImpl[]; identSy => {IF NOT Rope.Equal[ident, "DEFINITIONS"] THEN Error[MalformedInstr]; DeclareDefs[]}; ENDCASE => Error[MalformedInstr]; ENDLOOP; MB[beginSy]; SequenceOf[ModuleDefine, semiColonSy, ""]; [] _ CouldBe[semiColonSy, ""]; MB[endSy]; MB[rParentSy]; MB[becomesSy]; SequenceOf[AddSourceFile, commaSy]; END ELSE BEGIN -- we shouldn't modularize the program ERROR; -- SIMPLE CASE NOT CURRENTLY IMPLEMENTED END; [] _ CouldBe[semiColonSy, ""]; IF Rope.Equal[ident, "CAPITALIZE"] AND CouldBe[identSy, ""] THEN BEGIN SELECT TRUE FROM Rope.Equal[ident, "CHARS"] AND CouldBe[identSy, ""] => capitalizeChars _ TRUE; ENDCASE => {capitalizeChars _ TRUE; capitalizeStrings _ TRUE}; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "COMPILERSWITCHES"] AND CouldBe[identSy, ""] THEN BEGIN MB[stringConstSy]; compilerSwitches _ ident; [] _ CouldBe[semiColonSy, ""]; END ELSE compilerSwitches _ NIL; IF Rope.Equal[ident, "COMPUTEDSEQARRAY"] AND CouldBe[identSy, ""] THEN BEGIN SequenceOf[ParseComputedSeqArray, commaSy, ""]; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "INLINE"] AND CouldBe[identSy, ""] THEN BEGIN SequenceOf[ParseInlineProc, commaSy, ""]; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "INVENTFILENAMES"] AND CouldBe[identSy, ""] THEN BEGIN IF Rope.Equal[ident, "TRUE"] AND CouldBe[identSy, ""] THEN useVarNamesForFileNames _ TRUE ELSE IF Rope.Equal[ident, "FALSE"] AND CouldBe[identSy, ""] THEN useVarNamesForFileNames _ FALSE ELSE Error[MalformedInstr]; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "MAKEFILE"] AND CouldBe[identSy, ""] THEN BEGIN makeFileQ _ NewFileQ[".cm"]; InSymbol[]; END; IF Rope.Equal[ident, "NAMED"] AND CouldBe[identSy, ""] THEN BEGIN [] _ CouldBe[identSy, ""]; -- parameters paramsHaveNames _ TRUE; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "PREDEFINE"] AND CouldBe[identSy, ""] THEN BEGIN TranslateBlock[inner]; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "PROCARRAY"] AND CouldBe[identSy, ""] THEN BEGIN SequenceOf[ParseProcArray, commaSy, ""]; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "SPECIAL"] AND CouldBe[identSy, ""] THEN BEGIN [] _ CouldBe[arraySy, ""]; SequenceOf[ParseSpecialArray, commaSy, ""]; [] _ CouldBe[semiColonSy, ""]; END; IF Rope.Equal[ident, "TARGET"] AND CouldBe[identSy, ""] THEN BEGIN SELECT TRUE FROM Rope.Equal[ident, "MESA"] AND CouldBe[identSy, ""] => { targetLanguage _ mesa; PascalIntegerName _ "INTEGER"; pointerName _ "POINTER TO "; varPointerName _ "POINTER TO "}; Rope.Equal[ident, "LONG"] AND CouldBe[identSy, ""] => { [] _ CouldBe[identSy, ""]; --throw away MESA targetLanguage _ longMesa; PascalIntegerName _ "INTEGER"; pointerName _ "LONG POINTER TO "; varPointerName _ "LONG POINTER TO "}; ENDCASE => { [] _ CouldBe[identSy, ""]; --throw away CEDAR targetLanguage _ cedar; PascalIntegerName _ "INT"; pointerName _ "LONG POINTER TO "; varPointerName _ "LONG POINTER TO "}; [] _ CouldBe[semiColonSy, ""]; END; sourceFileSeq _ readySourceFileSeq; SourceFromNextStream[]; PopOut[]; IF modularize THEN BEGIN first: BOOLEAN _ TRUE; SayDefsModule: PROCEDURE [id: IdentifierPtr] = BEGIN IF first THEN first _ FALSE ELSE Say[", "]; SayIdent[id.name]; END; -- of SayDefsModule SayImplModule: PROCEDURE [id: IdentifierPtr] = BEGIN implTail: REF implModule IdentifierTail _ NARROW[id.class]; IF implTail.bindMe THEN {IF first THEN first _ FALSE ELSE Say[", "]; SayIdent[id.name]}; END; -- of SayImplModule SayCodeModule: PROCEDURE [id: IdentifierPtr] = BEGIN implTail: REF implModule IdentifierTail _ NARROW[id.class]; IF implTail.bindMe THEN {IF first THEN first _ FALSE ELSE Say["; "]; SayIdent[id.name]}; END; -- of SayCodeModule PushOut[configQ]; SayFileNameComment[configQ.fileName]; SayLine["-- Pascal-to-Mesa Configuration"]; SayLine[""]; SayTimeComment[]; SayIdent[configName]; Say[": CONFIGURATION IMPORTS "]; first _ TRUE; EnumerateIdentifierSet[pset: configImports, p: SayDefsModule]; SayLine[""]; IF NOT EmptyIdentifierSet[configExports] THEN { Say["EXPORTS "]; first _ TRUE; EnumerateIdentifierSet[pset: configExports, p: SayDefsModule]; SayLine[""]; }; Say["CONTROL "]; first _ TRUE; EnumerateIdentifierSet[pset: implModules, p: SayImplModule]; SayLine[" ="]; SayLine["BEGIN"]; first _ TRUE; EnumerateIdentifierSet[pset: implModules, p: SayCodeModule]; SayLine[""]; SayLine["END."]; PopOut[]; -- doesn't delete the file, merely closes it IF makeFileQ # NIL THEN BEGIN SayADefs: PROC [id: IdentifierPtr] = {defsTail: REF defsModule IdentifierTail = NARROW[id.class]; IF defsTail.compileMe THEN {Say[" "]; SayIdent[id.name]}}; SayAnImpl: PROC [id: IdentifierPtr] = {implTail: REF implModule IdentifierTail = NARROW[id.class]; IF implTail.compileMe THEN {Say[" "]; SayIdent[id.name]}}; PushOut[makeFileQ]; Say["Compile"]; IF Rope.Length[compilerSwitches]#0 THEN {Say[" "]; Say[compilerSwitches]}; EnumerateIdentifierSet[pset: defsModules, p: SayADefs]; EnumerateIdentifierSet[pset: implModules, p: SayAnImpl]; Say["; Bind "]; SayIdent[configName]; SayCh['\n]; PopOut[]; END; END; EnumerateIdentifierSet[defsModules, GenerateModuleBoilerPlate]; EnumerateIdentifierSet[implModules, GenerateModuleBoilerPlate]; PushOut[]; SayIdent[configName]; SayLine["Run: UnsafeCommandProc = BEGIN "]; initCodeQPtr _ CopyAndPopOut[]; END; -- of InitializeModules FinishModules: PUBLIC PROCEDURE = BEGIN CloseOutputFile: PROCEDURE [id: IdentifierPtr] = BEGIN WITH id.class SELECT FROM implTail: REF implModule IdentifierTail => BEGIN PushOut[implTail.q]; IF id = defaultDest[main].implModule THEN BEGIN SayLine[" END;"]; SayLine[""]; Say["PascalRegister["""]; SayIdent[configName]; Say[""", "]; SayIdent[configName]; SayLine["Run];"]; END; SayLine[""]; SayLine["END."]; PopOut[]; -- closes the file END; defsTail: REF defsModule IdentifierTail => BEGIN PushOut[defsTail.q]; SayLine[""]; SayLine["END."]; PopOut[]; -- closes the file END; ENDCASE; END; -- of CloseOutputFile WHILE outLevel > 0 DO PopOut[] ENDLOOP; -- close any files EnumerateIdentifierSet[defsModules, CloseOutputFile]; DisposeIdentifierSet[defsModules]; EnumerateIdentifierSet[implModules, CloseOutputFile]; DisposeIdentifierSet[implModules]; DisposeIdentifierSet[configTail.mentionedIdents]; DisposeIdentifierSet[segmentsTail.mentionedProcedures]; DisposeIdentifierSet[segmentsTail.mentionedVariables]; FOR t: ItemType IN ItemType DO defaultDest[t] _ NIL ENDLOOP; END; -- of FinishModules END. -- of PasInit -- άfile: PasInit.mesa modified by Ramshaw, January 20, 1984 4:21 pm written by McCreight, November 21, 1980 1:12 PM Last changed by Pavel, May 29, 1985 8:51:16 pm PDT May 29, 1985: Changed by Pavel to add the ability to export an interface from the bound BCD. If the name of a definitions file in the .mod file is followed by a star (*), then that interface is exported in the generated .config file. Said interface file must have been given as either ``external'' or ``forward''. Saying ``trash'' causes a type error. the function actually tells its own type read a defsModule, implModule pair from the input stream, and return the corresponding Destination record process the declaration of an impl module in the mod file and imported programs too, sad to say moduleId: IdentifierPtr; fileName: Name; modularize _ notAtAll; IF sy # identSy THEN Error[MalformedInstr]; moduleId _ NewIdent[pset: modules]; fileName _ Rope.Cat[RopeSayIdent[ident], ".mesa"]; configName _ ident; readySourceFileSeq _ Z.NEW[SourceFileSeq _ [next: NIL, name: GetFileNameFromSource[".pas"]]]; mainQPtr _ Z.NEW[OutputQueue _ [contents: "", fileName: fileName]]; moduleId.class _ Z.NEW[IdentifierTail _ [moduleName[q: mainQPtr, f: impl]]]; mainId _ moduleId; ΚΛ˜Jšœ™Jšœ-™-Jšœ0™0Icode™2K™K™βJ˜šΟk ˜ Jšœœ˜Jšœœ œœ˜*J˜ J˜Jšœœ˜ J˜—šœ œœ˜Jšœœ"˜(Jšœ ˜J˜Jšœœ˜&J˜J˜š œœœœœ˜=J˜/J˜—š œœœœœ˜G˜EJ˜JJ˜GJ˜(J˜——š œœœœœ˜E˜KJ˜LJ˜HJ˜3J˜J˜——J˜J˜Jšœ œ˜J˜Jšœœ˜ J˜J˜Jšœ'œ˜+J˜Jšœœ˜J˜J˜šΟnœœ œ˜&Jš˜J˜ J˜šžœ œœ˜3Jšœ˜Jš˜J˜)J˜ Jšœ œœ˜*Jšœ˜ JšœΟc˜J˜—J˜)J˜ J˜ J˜J˜)J˜&J˜šœœœ˜&J˜4—šœœœ ˜˜Jšœ œ˜J˜——J˜J˜šœ œœ ˜Jšœœ œ˜>—J˜ J˜Jšœœ2˜GJ˜šœœœ˜4Jšœ œ œ˜/J˜—Jšœ œ0˜?J˜Jšœœœ&œ˜KJšœ œ1˜AJ˜Jšœœœ:˜OJ˜J˜Jšœœ/˜=JšœŸ ˜Jšœœœ&œ˜JJ˜šœœ˜J˜?J˜Jšœ œœ˜.Jšœ˜J˜—šœœ˜J˜DJ˜Jšœ œœ2˜BJšœ˜J˜—šœœ˜J˜CJ˜Jšœ(™(Jšœ œœ2˜BJšœ˜J˜—JšœŸ˜J˜J˜—šžœœ œ˜%Jš˜J˜Jšœ œ1˜>J˜š žœ œœœœ˜=Jš˜Jšœ œ˜šœ˜Jš˜J˜J˜ šœœ˜.Jš˜J˜*J˜ Jš˜—Jšœ$˜(Jš˜—Jšœ˜Jšœ ˜JšœŸ˜ J˜—šžœ œœœ˜<šœœœ ˜˜J˜)J˜———šžœ œœ˜=JšœD™DJšœ$™$J˜Jšœ œ˜(Jšœ œ˜(Jšœœ˜Jšœœ˜+J˜&Jšœ œ ˜Jšœ#˜#J˜ Jšœœ œœ˜IJšœ ˜ J˜&J˜ Jšœ œ ˜šœœ˜JšœBœ˜MJšœ4˜8—Jšœœœ5˜AJšœ˜ J˜J˜—šž œ œŸ;˜VJ˜Jšœ œ˜(Jšœœœ˜"J˜Jšœ Ÿ$˜1Jšœœ˜+J˜J˜#Jšœ œœA˜QJ˜J˜)J˜+J˜šœœ œŸ˜;Jšœ ˜ Jšœœ˜J˜—J˜šœœ˜šž œœ˜J˜Jšœœ˜+Jšœ3œ˜9Jšœ œœ+˜?Jšœ3˜3J˜ Jšœœ œ ˜.Jšœ6˜:Jšœ˜—J˜ Jšœ ˜Jšœ˜J˜—Jšœ˜J˜šœ˜šœ ˜ Jšœœ˜Jšœ˜Jšœ˜—Jšœ œ˜šœ ˜ Jšœœœ˜=Jšœ&œ˜/J˜J˜—Jšœ˜!J˜—šœ˜Jšœ œ˜)J˜4J˜—J˜J˜ Jšœ˜Jšœ˜J˜—šž œ œ˜Jšœ9™9J˜Jšœ œ˜(Jšœ Ÿ ˜-Jšœœ˜+J˜#Jšœ œœA˜QJ˜J˜,J˜.Jšœ8˜8J˜+šœ˜šœž œœ˜J˜Jšœœ˜+Jšœ3œ˜9Jšœ œœ6œ˜Pšœ œ˜JšœŸB˜DJšœ(˜(JšœB˜BJ˜ —šœ˜Jšœ ˜ Jšœ6˜6Jšœœ œ ˜.Jšœ:˜>—J˜—J˜ Jšœ ˜—Jšœ˜šœ˜Jšœ"œ˜CJšœ œ˜šœ œœœ˜IJšœ'œ˜-J˜—Jšœ˜!—J˜ Jšœ˜J˜J˜—šž œ œ˜Jš˜J˜J˜šžœ œ˜Jš˜Jšœœ˜+šœœ˜J˜?J˜?J˜AJ˜=J˜HJ˜8˜šœ œ ˜Jšœœœœ˜;——šœ˜ Jš˜J˜>J˜Jšœ œœ)˜8Jšœ˜——J˜ JšœŸ˜J˜—J˜Jšœ ˜šœœ˜J˜(—JšœŸ˜J˜—šžœ œ˜Jš˜Jšœœ˜ Jšœœ?œ ˜SJ˜J˜ JšœŸ˜J˜—šžœ œœ˜)Jš˜Jšœ œ˜Jšœ œœ ˜-J˜JšœŸ˜J˜J˜—šžœ œ˜:Jš˜J˜J˜Jšœ œ˜(Jšœ œ˜(Jšœœ˜J˜šž œ œ˜+Jš˜Jšœœ œœ˜;J˜šœ˜J˜3—Jšœ˜J˜—šž œ œ˜*Jš˜Jšœœ œœ ˜+J˜Jšœ˜J˜—šœ œ˜šœ œ˜+J˜:—šœ œ˜*J˜:—Jšœœ˜—J˜ J˜J˜J˜ J˜J˜ Jšœœ˜ šœ ˜JšœGŸ˜\šœJ˜JšœN˜NJšœ%™%——Jšœœ˜—J˜ J˜ J˜šœ ˜J˜J˜Jšœœ˜—J˜Jšœœ˜ šœ ˜JšœX˜X˜ J˜BJšœL˜LJ˜Jšœœ˜ J˜?J˜J˜—Jšœœ˜—J˜Jšœœ˜ šœ ˜J˜E˜IJšœM˜M—Jšœœ˜—J˜ J˜šœ ˜J˜J˜Jšœœ˜—JšœŸ˜$J˜J˜—šžœ œ œœ˜7Jš˜J˜J˜0J˜Jšœœ#˜+Jšœ ˜ šœ˜˜Jšœ9œ˜?—šœœ˜Jš˜J˜<šœ œœ!˜1˜:J˜.——Jšœ˜—šœ œœ˜Jšœœ0œ˜@—J˜ Jšœ ˜ Jšœ˜J˜—˜Jšœ8œ˜>—šœœ˜Jš˜J˜;Jšœœœ<˜GJ˜Jš˜—Jšœœ ˜šœœ˜Jšœ œ7˜GJšœ œ4˜CJšœ˜—JšœŸ˜"J˜—šžœ œ˜8Jšœ*˜-J˜—šžœ œ˜5Jšœ'˜*J˜—šžœ œ˜—J˜Jšœ˜J˜—šœ'œ˜FJš˜Jšœ˜J˜J˜Jšœœœ˜ J˜—šœ'œ˜FJš˜J˜/J˜Jšœ˜J˜—šœœ˜Jš˜J˜J˜ Jšœ˜J˜J˜—šœœ˜;Jš˜JšœŸ ˜(Jšœœ˜J˜Jšœ˜J˜—šœ œ˜?Jš˜J˜J˜Jšœ˜J˜—šœ œ˜?Jš˜J˜(J˜Jšœ˜J˜—šœœ˜=Jš˜J˜J˜+J˜Jšœ˜J˜J˜—šœœ˜J˜ šœœ#œ˜/J˜Jšœœ˜ J˜>J˜ J˜—J˜Jšœœ˜ J˜