CDGenerateSomeImpl.mesa (part of ChipNDale)
Copyright © 1985, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT
Last edited by: Christian Jacobi, April 9, 1987 5:57:06 pm PDT
DIRECTORY
CD,
CDDesignCache,
CDGenerate,
CDGenerateBackdoor,
CDGenerateImports,
CDImports,
CDDirectory,
CDProperties,
CDGenerateRemote,
FileNames,
RefTab,
Rope,
SymTab,
TerminalIO,
TokenIO;
CDGenerateSomeImpl: CEDAR PROGRAM
IMPORTS CDDesignCache, CDGenerate, CDGenerateBackdoor, CDDirectory, CDImports, CDProperties, FileNames, RefTab, Rope, SymTab, TerminalIO
EXPORTS CDGenerateRemote, CDGenerateImports
SHARES CDImports =
BEGIN
dummy: CDGenerate.Context ← CDGenerate.Create[];
dummy2: CDGenerate.Context ← CDGenerate.Create[];
contextToName: RefTab.Ref ← RefTab.Create[];
context ==> remote design name
nameToImportContext: SymTab.Ref ← SymTab.Create[];
nameToRemoteContext: SymTab.Ref ← SymTab.Create[];
remote design name ==> context
--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
UnspecImportSelector: CDGenerateBackdoor.SelectorProc = {
key ← TerminalIO.RequestRope[" import [design.object] >"];
};
ImportSelector: 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.ROPENIL] = {
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 nameToImportContext.Fetch[designName].val SELECT FROM
t: CDGenerate.Context => RETURN [t]
ENDCASE => NULL;
context ← CDGenerateBackdoor.CreateIndirect[onTopOf: dummy, iGenerator: ImportIGenerator,
selector: ImportSelector, cache: TRUE, flushThrough: FALSE, clearThrough: FALSE, registerThrough: FALSE];
[] ← contextToName.Insert[context, designName];
IF nameToImportContext.Insert[designName, context] THEN RETURN;
RETURN [GetImportContext[designName]] --indirection for concurrency problems
};
--Remote
UnspecRemoteSelector: CDGenerateBackdoor.SelectorProc = {
key ← TerminalIO.RequestRope[" include [design.oject] >"];
};
RemoteSelector: CDGenerateBackdoor.SelectorProc = {
dName: Rope.ROPE = RemoteDesignName[context];
key ← TerminalIO.RequestRope[Rope.Cat[label, " include oject from ", dName, " >"]];
};
UnspecRemoteIGenerator: CDGenerateBackdoor.IGeneratorProc = {
--this one even does not know what design to use
dotIndex: INT; remoteName, objectName: Rope.ROPENIL;
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];
remoteName ← Rope.Substr[name, 0, dotIndex]
};
IF ~Rope.IsEmpty[remoteName] AND ~Rope.IsEmpty[objectName] THEN {
context: CDGenerate.Context ← GetRemoteContext[remoteName];
ob ← CDGenerate.FetchNCall[context, design, objectName];
}
ELSE TerminalIO.PutRopes["**tried to access remote with bad syntax; [", key, "]\n"];
};
GetRemoteContext: PUBLIC PROC [remoteDesign: Rope.ROPE] RETURNS [context: CDGenerate.Context←NIL] = {
IF Rope.IsEmpty[remoteDesign] THEN ERROR;
WITH nameToRemoteContext.Fetch[remoteDesign].val SELECT FROM
t: CDGenerate.Context => RETURN [t]
ENDCASE => NULL;
context ← CDGenerateBackdoor.CreateIndirect[onTopOf: dummy2, iGenerator: RemoteIGenerator,
selector: RemoteSelector, cache: TRUE, flushThrough: FALSE, clearThrough: FALSE, registerThrough: FALSE];
[] ← contextToName.Insert[context, remoteDesign];
IF nameToRemoteContext.Insert[remoteDesign, context] THEN RETURN;
RETURN [GetRemoteContext[remoteDesign]] --indirection for concurrency problems
};
GetRemoteObject: PUBLIC PROC [for: CD.Design, remoteDesign: Rope.ROPE, object: Rope.ROPE] RETURNS [ob: CD.Object] = {
context: CDGenerate.Context = GetRemoteContext[remoteDesign];
ob ← CDGenerate.FetchNCall[context, for, object];
};
RemoteDesignName: PUBLIC PROC [context: CDGenerate.Context] RETURNS [r: Rope.ROPENIL] = {
WITH contextToName.Fetch[context].val SELECT FROM
rn: Rope.ROPE => RETURN [rn];
ENDCASE => {
context ← CDGenerateBackdoor.Indiretee[context];
IF context#NIL THEN RETURN [RemoteDesignName[context]]
};
};
RemoteIGenerator: CDGenerateBackdoor.IGeneratorProc = {
GetOver: PROC [into: CD.Design, from: CD.Design, ob: CD.Object, key: REFNIL] RETURNS [ob1: CD.Object←NIL] = {
replaceList: CDDirectory.ReplaceList ← NIL;
EachChild: CDDirectory.EachObjectProc = {
IF me.class.composed THEN {
replaceRec: REF CDDirectory.ReplaceRec; ob1: CD.Object;
IF CDDirectory.IsIncluded[from, me] THEN {
ob1 ← CDGenerate.FetchNCall[realContext, design, CDDirectory.Name[me, from]];
--will be cached !!
};
IF ob1=NIL THEN
ob1 ← GetOver[into, from, me, NIL];
IF ob1=NIL THEN ERROR;
replaceRec ← NEW[CDDirectory.ReplaceRec ← [old: me, new: ob1]];
replaceList ← CONS[replaceRec, replaceList];
}
};
ca: BOOL;
[ob1, ca] ← CDDirectory.Another1[me: ob, fromOrNil: from, into: into];
IF ob1#NIL THEN {
IF ~ca THEN {
[] ← CDDirectory.EnumerateChildObjects[me: ob1, proc: EachChild];
IF replaceList#NIL THEN
[] ← CDDirectory.ReplaceDirectChild[me: ob1, design: into, replace: replaceList, propagate: FALSE];
};
IF CDDirectory.IsIncluded[from, ob] THEN
[] ← CDDirectory.Include[design: into, object: ob1, name: CDDirectory.Name[ob, from]];
CDProperties.PutObjectProp[ob1, $CameFrom, from.name];
IF key=NIL THEN key ← CDDirectory.Name[ob, from];
CDProperties.PutObjectProp[ob1, $OriginalName, key];
};
};
remoteDesign: CD.Design;
remoteName: Rope.ROPE ← RemoteDesignName[passContext];
--test for silly case of using same design name
IF Rope.Equal[remoteName, design.name] THEN {
ob ← CDDirectory.Fetch[design, key].object; RETURN
};
IF Rope.IsEmpty[remoteName] THEN {
TerminalIO.PutRope["**generate with bad remote name\n"]; RETURN
};
remoteDesign ← CDDesignCache.GetOrRead[for: design, remoteName: remoteName, reload: FALSE, checkFile: TRUE].remote;
IF remoteDesign#NIL THEN {
rob: CD.Object ← CDDirectory.Fetch[remoteDesign, key].object;
IF rob#NIL THEN RETURN [GetOver[into: design, from: remoteDesign, ob: rob, key: key]];
};
};
fromDirectory: CDGenerate.Context ← CDGenerateBackdoor.CreateIndirect[
onTopOf: CDGenerate.Create[],
iGenerator: DirectoryIndirector,
selector: DirectorySelector
];
unspecImportContext: CDGenerate.Context ← CDGenerateBackdoor.CreateIndirect[
onTopOf: dummy,
iGenerator: UnspecImportIGenerator,
selector: UnspecImportSelector
];
unspecRemoteContext: CDGenerate.Context ← CDGenerateBackdoor.CreateIndirect[
onTopOf: dummy2,
iGenerator: UnspecRemoteIGenerator,
selector: UnspecRemoteSelector
];
[] ← SymTab.Insert[CDGenerateBackdoor.publicContexts, "INCLUDE", unspecRemoteContext];
[] ← SymTab.Insert[CDGenerateBackdoor.publicContexts, "IMPORT", unspecImportContext];
[] ← SymTab.Insert[CDGenerateBackdoor.publicContexts, "DIRECTORY", fromDirectory];
[] ← CDProperties.Register[$CameFrom, [autoRem: TRUE, exclusive: TRUE]];
[] ← CDProperties.Register[$OriginalName, [autoRem: TRUE, exclusive: TRUE]];
END.