-- SMSrcBcdImpl.mesa, -- last edit by Schmidt, May 5, 1983 3:45 pm -- last edited by Satterthwaite, May 26, 1983 12:53 pm DIRECTORY Atom: TYPE USING [MakeAtom], BcdDefs: TYPE USING [ Base, EXPIndex, FTIndex, IMPIndex, MTIndex, Namee, NameRecord, NullName], BcdOps: TYPE USING [ BcdBase, EXPHandle, IMPHandle, MTHandle, NameString, FindName, ProcessExports, ProcessImports, ProcessModules], CtoSP1: TYPE --P1-- USING [InstallParseTable, Parse], CtoSParseData: TYPE, File: TYPE USING [Capability, nullCapability], FileIO: TYPE USING [Open, OpenFailed], FileParms: TYPE USING [SymbolSpace], FileSegment: TYPE USING [], IO: TYPE USING [Close, Handle, PutF, rope], Rope: TYPE USING [Cat, Flatten, FromChar, ROPE, Text], Runtime: TYPE USING [GetTableBase], SMEval: TYPE USING [Eval], SMFI: TYPE USING [ BcdFileInfo, BcdInfo, BcdInfoRecord, BcdModuleRecord, SrcFileInfo], SMOps: TYPE USING [MS], SMSrcBcd: TYPE USING [], SMTree: TYPE Tree USING [Link, null], SMTreeOps: TYPE USING [PopTree], SMTypeCons: TYPE USING [ MkArrow, MkControlType, MkDeclElem, MkDeclReverse, MkInterfaceType], Space: TYPE USING [ Create, CreateUniformSwapUnits, Delete, Handle, LongPointer, MakeReadOnly, Map, virtualMemory], TimeStamp: TYPE USING [Stamp]; -- consider this a part of the SMFIImpl monitor SMSrcBcdImpl: CEDAR PROGRAM IMPORTS Atom, BcdOps, CtoSP1, CtoSParseData, FileIO, IO, Rope, Runtime, SMEval, SMTreeOps, SMTypeCons, Space EXPORTS SMSrcBcd ~ { OPEN Tree~~SMTree; -- no mds -- for Mesas AddCedarInfo: PUBLIC PROC[ms: SMOps.MS, fi: SMFI.SrcFileInfo] ~ { in: IO.Handle ← NIL; in ← FileIO.Open[fi.shortname ! FileIO.OpenFailed => {CONTINUE}]; IF in = NIL THEN fi.type ← Tree.null ELSE { complete: BOOL; nTokens, nErrors: NAT; TRUSTED {[complete, nTokens, nErrors] ← CtoSP1.Parse[ms, in]}; fi.type ← IF complete --AND nErrors = 0-- THEN SMEval.Eval[ms, (ms.tm).PopTree, NIL] ELSE Tree.null; IF nErrors # 0 THEN { (ms.out).PutF["%s was not parsed successfully\n", IO.rope[fi.shortname]]; fi.type ← Tree.null}; in.Close[]}}; -- for Bcds -- imports and exports are partially uncheckable (not enough info in Bcd) AddBcdInfo: PUBLIC PROC[ms: SMOps.MS, fi: SMFI.BcdFileInfo] ~ TRUSTED { bcdInfo: SMFI.BcdInfo; LinkList: TYPE ~ LIST OF Tree.Link; d, r: LinkList ← NIL; bcdBase: BcdOps.BcdBase ← NIL; nameString: BcdOps.NameString; ftb: BcdDefs.Base; sgb: BcdDefs.Base; NameToRope: PROC[name: BcdDefs.NameRecord] RETURNS[Rope.Text] ~ TRUSTED { r: Rope.ROPE ← NIL; FOR i: CARDINAL IN [0 .. nameString.size[name]) DO r ← r.Cat[Rope.FromChar[nameString.string.text[name+i]]]; ENDLOOP; RETURN [r.Flatten]}; NameeToRope: PROC[namee: BcdDefs.Namee] RETURNS[Rope.Text] ~ TRUSTED { name: BcdDefs.NameRecord ~ BcdOps.FindName[bcdBase, namee]; RETURN [IF name = BcdDefs.NullName THEN NIL ELSE NameToRope[name]]}; PrefixElem: PROC[id, typeId: Rope.Text, typeStamp: TimeStamp.Stamp, rest: LinkList] RETURNS[LinkList] ~ CHECKED { type: ATOM ~ Atom.MakeAtom[typeId]; RETURN [(ms.z).CONS[ SMTypeCons.MkDeclElem[ms.tm, IF id=NIL THEN type ELSE Atom.MakeAtom[id], type], rest]]}; { firstMth: BcdOps.MTHandle; space: Space.Handle; ForEachModule: PROC[mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS[stop: BOOL←FALSE] ~ TRUSTED { bcdInfo.modules ← CONS[ [moduleName~NameToRope[mth.name], symbolSpace~[ file~fi.bcdCap, span~[base~sgb[mth.sseg].base, pages~sgb[mth.sseg].pages]]], bcdInfo.modules]}; ForEachImport: PROC[ith: BcdOps.IMPHandle, iti: BcdDefs.IMPIndex] RETURNS[stop: BOOL←FALSE] ~ TRUSTED { d ← PrefixElem[ id~(IF ith.namedInstance THEN NameeToRope[[import[iti]]] ELSE NIL), typeId~NameToRope[ith.name], typeStamp~ftb[ith.file].version, rest~d]}; ForEachExport: PROC[eth: BcdOps.EXPHandle, eti: BcdDefs.EXPIndex] RETURNS[stop: BOOL←FALSE] ~ TRUSTED { r ← PrefixElem[ id~(IF eth.namedInstance THEN NameeToRope[[export[eti]]] ELSE NIL), typeId~NameToRope[ftb[eth.file].name], typeStamp~ftb[eth.file].version, rest~r]}; IF ~fi.bcdPresent THEN RETURN; [space, bcdBase] ← LoadUpBcd[fi.bcdCap]; nameString ← LOOPHOLE[bcdBase + bcdBase.ssOffset]; ftb ← LOOPHOLE[bcdBase, BcdDefs.Base] + bcdBase.ftOffset; firstMth ← @(LOOPHOLE[bcdBase, BcdDefs.Base] + bcdBase.mtOffset)[BcdDefs.MTIndex.FIRST]; sgb ← LOOPHOLE[bcdBase, BcdDefs.Base] + bcdBase.sgOffset; bcdInfo ← (ms.z).NEW[SMFI.BcdInfoRecord ← []]; bcdInfo.srcFileName ← NameToRope[bcdBase.source]; bcdInfo.srcCreate ← bcdBase.sourceVersion.time; [] ← BcdOps.ProcessModules[bcdBase, ForEachModule]; bcdInfo.isDefs ← bcdBase.definitions; bcdInfo.isConfig ← (bcdBase.nConfigs # 0); [] ← BcdOps.ProcessImports[bcdBase, ForEachImport]; FOR mod: LIST OF SMFI.BcdModuleRecord ← bcdInfo.modules, mod.rest UNTIL mod = NIL DO id: ATOM ~ Atom.MakeAtom[mod.first.moduleName]; type: Tree.Link ~ SMTypeCons.MkInterfaceType[ms.tm, id]; r ← CONS[SMTypeCons.MkDeclElem[ms.tm, id, type], r]; IF ~bcdInfo.isDefs THEN { -- if impl, then exports instances too idImpl: ATOM ~ Atom.MakeAtom[(mod.first.moduleName).Cat["Impl"]]; r ← CONS[SMTypeCons.MkDeclElem[ms.tm, idImpl, id], r]}; ENDLOOP; [] ← BcdOps.ProcessExports[bcdBase, ForEachExport]; IF ~bcdInfo.isDefs THEN { -- implementors export a variable of type CONTROL as well idType: Tree.Link ~ SMTypeCons.MkControlType[ms.tm]; idImpl: ATOM ~ Atom.MakeAtom[(bcdInfo.modules.first.moduleName).Cat["ImplC"]]; r ← CONS[SMTypeCons.MkDeclElem[ms.tm, idImpl, idType], r]}; fi.bcdInfo ← bcdInfo; fi.type ← SMEval.Eval[ ms, SMTypeCons.MkArrow[ tm~ms.tm, domain~SMTypeCons.MkDeclReverse[ms.tm, d], range~SMTypeCons.MkDeclReverse[ms.tm, r]], NIL]; Space.Delete[space]}}; LoadUpBcd: PROC[cap: File.Capability] RETURNS[space: Space.Handle, bcdBase: BcdOps.BcdBase] ~ TRUSTED { nPages: CARDINAL; IF cap = File.nullCapability THEN ERROR; space ← Space.Create[size~10, parent~Space.virtualMemory]; space.Map[window~[file~cap, base~1]]; bcdBase ← space.LongPointer; nPages ← bcdBase.nPages; IF nPages > 10 THEN { Space.Delete[space]; -- now map in the right number of pages space ← Space.Create[size~nPages, parent~Space.virtualMemory]; space.Map[window~[file~cap, base~1]]; bcdBase ← space.LongPointer}; Space.CreateUniformSwapUnits[parent~space, size~8]; space.MakeReadOnly}; TRUSTED {CtoSP1.InstallParseTable[Runtime.GetTableBase[LOOPHOLE[CtoSParseData]]]}; }.