CDGenerateImportsImpl.mesa (part of ChipNDale)
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT
Last edited by: Christian Jacobi, October 20, 1986 12:51:33 pm PDT
DIRECTORY
CD,
CDDirectory,
CDGenerate,
CDGenerateBackdoor,
CDGenerateImports,
CDImports,
FileNames,
RefTab,
Rope,
SymTab,
TerminalIO;
CDGenerateImportsImpl:
CEDAR
PROGRAM
IMPORTS CDDirectory, CDGenerate, CDGenerateBackdoor, CDImports, FileNames, RefTab, Rope, SymTab, TerminalIO
EXPORTS CDGenerateImports
SHARES CDImports =
BEGIN
--directory
DirectorySelector: CDGenerateBackdoor.SelectorProc = {
key ← TerminalIO.RequestRope[" from directory>"];
};
DirectoryIndirector: CDGenerateBackdoor.IGeneratorProc = {
IF Rope.IsEmpty[key] THEN key ← TerminalIO.RequestRope["type name >"];
RETURN [CDDirectory.Fetch[design, key].object]
};
--imports
dummy: CDGenerate.Context ← CDGenerate.Create[];
contextToName: RefTab.Ref ← RefTab.Create[];
nameToContext: SymTab.Ref ← SymTab.Create[];
UnspecSelector: CDGenerateBackdoor.SelectorProc = {
key ← TerminalIO.RequestRope[" import [design.object] >"];
};
Selector: CDGenerateBackdoor.SelectorProc = {
dName: Rope.ROPE = ImporteeName[context];
key ← TerminalIO.RequestRope[Rope.Cat[label, " import object from ", dName, " >"]];
};
ImportIGenerator: CDGenerateBackdoor.IGeneratorProc = {
importeeName: Rope.ROPE ← ImporteeName[realContext];
IF Rope.IsEmpty[importeeName]
THEN {
TerminalIO.PutRope["**generate with bad importee name\n"];
RETURN
};
IF Rope.Equal[importeeName, design.name]
THEN {
ob ← CDDirectory.Fetch[design, key].object;
RETURN
};
[] ← CDImports.GetCache[design, importeeName, true];
ob ← CDImports.CreateImportFromCache[design, key, importeeName];
};
UnspecImportIGenerator: CDGenerateBackdoor.IGeneratorProc = {
dotIndex: INT; importeeName, objectName: Rope.ROPE ← NIL;
name: Rope.ROPE ← FileNames.GetShortName[key];
dotIndex ← Rope.Index[name, 0, "."]; --the first dot! multiple dots belong to the object name
IF dotIndex<Rope.Length[name]
THEN {
objectName ← Rope.Substr[name, dotIndex+1];
importeeName ← Rope.Substr[name, 0, dotIndex]
};
IF ~Rope.IsEmpty[importeeName]
AND ~Rope.IsEmpty[objectName]
THEN {
context: CDGenerate.Context ← GetImportContext[importeeName];
ob ← CDGenerate.FetchNCall[context, design, objectName];
}
ELSE TerminalIO.PutRopes["**tried to import with bad syntax; [", key, "]\n"];
};
ImporteeName:
PUBLIC
PROC [context: CDGenerate.Context]
RETURNS [r: Rope.
ROPE←
NIL] = {
WITH contextToName.Fetch[context].val
SELECT
FROM
n: Rope.ROPE => r ← n
ENDCASE => {
context ← CDGenerateBackdoor.Indiretee[context];
IF context#NIL THEN RETURN[ImporteeName[context]]
};
};
GetImportContext:
PUBLIC PROC [designName: Rope.
ROPE]
RETURNS [context: CDGenerate.Context←
NIL] = {
WITH nameToContext.Fetch[designName].val
SELECT
FROM
t: CDGenerate.Context => RETURN [t]
ENDCASE => NULL;
context ← CDGenerateBackdoor.CreateIndirect[onTopOf: dummy, iGenerator: ImportIGenerator,
selector: Selector, cache: TRUE, flushThrough: FALSE, clearThrough: FALSE, registerThrough: FALSE];
[] ← contextToName.Insert[context, designName];
IF nameToContext.Insert[designName, context] THEN RETURN;
RETURN [GetImportContext[designName]] --indirection for concurrency problems
};
fromDirectory: CDGenerate.Context ← CDGenerateBackdoor.CreateIndirect[
onTopOf: CDGenerate.Create[],
iGenerator: DirectoryIndirector,
selector: DirectorySelector
];
unspecImportContext: CDGenerate.Context ← CDGenerateBackdoor.CreateIndirect[
onTopOf: dummy,
iGenerator: UnspecImportIGenerator,
selector: UnspecSelector
];
[] ← SymTab.Insert[CDGenerateBackdoor.publicContexts, "IMPORT", unspecImportContext];
[] ← SymTab.Insert[CDGenerateBackdoor.publicContexts, "DIRECTORY", fromDirectory];
END.