CDMakeProcCommands.mesa (module for ChipNDale)
Copyright © 1985, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, May 9, 1985 1:58:40 pm PDT
Last edited by: Christian Jacobi, January 5, 1987 8:12:52 pm PST
DIRECTORY
Ascii,
Atom,
CD,
CDAtomicObjects,
CDBasics,
CDCells,
CDDirectory,
CDEnvironment,
CDInstances,
CDMakeProc,
CDProperties,
CDOps,
CDSequencer,
CDSymbolicObjects,
Convert,
IO,
PriorityQueue,
RefTab,
Rope,
SymTab,
TerminalIO,
TiogaFileOps,
TiogaOps,
ViewerTools;
CDMakeProcCommands: CEDAR PROGRAM
IMPORTS Ascii, Atom, Convert, CD, CDAtomicObjects, CDBasics, CDCells, CDDirectory, CDEnvironment, CDInstances, CDProperties, CDOps, CDSequencer, CDSymbolicObjects, IO, PriorityQueue, RefTab, Rope, SymTab, TerminalIO, TiogaFileOps, TiogaOps, ViewerTools
EXPORTS CDMakeProc =
BEGIN
Environment: TYPE = REF EnvironmentRep;
EnvironmentRep: PUBLIC TYPE = RECORD [
invocationKey: REF,
rootNode: TiogaFileOps.Ref,
mustDo: RefTab.Ref,
done: RefTab.Ref,
fileName: Rope.ROPE,
commentNode: TiogaFileOps.Ref, --insert sibling for next comment
modHeaderNode: TiogaFileOps.Ref, --DIRECTORY... to excluding BEGIN
declNode: TiogaFileOps.Ref, --insert sibling for next declaration on module level
procNode: TiogaFileOps.Ref, --insert sibling for next global procedures
procDecNode: TiogaFileOps.Ref, --insert sibling for next local declaration
postDeclNode: TiogaFileOps.Ref, --insert sibling for next declaration on module level
firstModStatementNode: TiogaFileOps.Ref, --reserved for first statement
modStatementNode: TiogaFileOps.Ref, --insert sibling for next mudule statement
mainName: Rope.ROPE ← NIL,
modifier: INT ← 0,
directory: SymTab.Ref,
imports: SymTab.Ref,
declaredLayers: ARRAY CD.Layer OF Rope.ROPEALL[NIL],
nameToThing: SymTab.Ref,
localThingToName: RefTab.Ref,
globalThingToName: RefTab.Ref,
hasDirGen: BOOLFALSE,
design: CD.Design,
properties: CD.PropRef
];
ObjectExpressionProc: TYPE = CDMakeProc.ObjectExpressionProc;
GetEnvironmentProp: PUBLIC PROC [env: Environment, key: REF] RETURNS [REF] = {
RETURN [CDProperties.GetProp[env.properties, key]]
};
PutEnvironmentProp: PUBLIC PROC [env: Environment, key: REF, val: REF] = {
CDProperties.PutProp[env.properties, key, val]
};
RegisterObjectExpressionProc: PUBLIC PROC [for: REF, ep: ObjectExpressionProc, tech: CD.Technology ← NIL] = {
WITH for SELECT FROM
c: CD.ObjectClass =>
CDProperties.PutProp[c.properties, $MakeCallExpression, NEW[ObjectExpressionProc𡤎p]];
a: ATOM => RegisterObjectExpressionProc[CD.FetchObjectClass[a, tech], ep, tech];
ENDCASE => ERROR
};
CallObjectExpressionProc: PROC [env: Environment, ob: CD.Object] RETURNS [r: Rope.ROPENIL] = {
x: REF ← CDProperties.GetProp[ob.class.properties, $MakeCallExpression];
WITH x SELECT FROM
rmce: REF ObjectExpressionProc => r ← rmce^[env, ob]
ENDCASE => NULL;
};
MakeNodeComment: PROC [node: TiogaFileOps.Ref] = {
TRUSTED { TiogaOps.PutProp[LOOPHOLE[node], $Comment, NEW[BOOLEANTRUE]] };
};
Reserve: PROC [env: Environment, key: Rope.ROPE] = {
[] ← SymTab.Store[env.nameToThing, key, $reserved];
};
MakePreamble: PUBLIC PROC [env: Environment, module: Rope.ROPE, import: BOOLTRUE] = {
[] ← SymTab.Store[env.nameToThing, module, $module];
[] ← SymTab.Insert[env.directory, module, module];
IF import THEN [] ← SymTab.Insert[env.imports, module, module];
};
MakeDirectory: PROC [env: Environment] = {
r: Rope.ROPENIL;
Each: SymTab.EachPairAction = {
IF num=0 THEN TiogaFileOps.SetContents[env.modHeaderNode, "DIRECTORY"]
ELSE r ← r.Concat[", "];
r ← r.Concat[key];
num ← num+1;
quit ← FALSE
};
num: INT ← 0;
[] ← env.directory.Pairs[Each];
IF num>0 THEN {
node: TiogaFileOps.Ref ← TiogaFileOps.InsertNode[env.modHeaderNode, TRUE];
TiogaFileOps.SetContents[node, r.Concat[";"]];
}
ELSE TiogaFileOps.SetContents[env.modHeaderNode, ""];
};
MakeImportsExpr: PROC [env: Environment] RETURNS [r: Rope.ROPENIL] = {
Each: SymTab.EachPairAction = {
IF num=0 THEN r ← "IMPORTS "
ELSE r ← r.Concat[", "];
r ← r.Concat[key];
num ← num+1;
quit ← FALSE
};
num: INT ← 0;
[] ← env.imports.Pairs[Each];
};
NewEnvironment: PROC [design: CD.Design] RETURNS [env: Environment] = {
env ← NEW[EnvironmentRep←[properties: CD.InitPropRef[]]];
env.fileName ← Rope.Cat[CDEnvironment.GetWorkingDirectory[design], "CDMakeProc-Temp.mesa"];
env.invocationKey ← NEW[INT];
env.rootNode ← TiogaFileOps.CreateRoot[];
env.mustDo ← RefTab.Create[];
env.done ← RefTab.Create[];
env.commentNode ← TiogaFileOps.InsertNode[env.rootNode, TRUE];
TiogaFileOps.SetContents[env.commentNode, Rope.Cat["--", env.fileName]];
MakeNodeComment[env.commentNode];
env.commentNode ← TiogaFileOps.InsertNode[env.commentNode];
TiogaFileOps.SetContents[env.commentNode, "--created by ChipNDale"];
MakeNodeComment[env.commentNode];
env.modHeaderNode ← TiogaFileOps.InsertNode[env.commentNode];
env.declNode ← TiogaFileOps.InsertNode[env.modHeaderNode];
TiogaFileOps.SetContents[env.declNode, "BEGIN"];
PlaceDeclarationM1[env, IO.PutFR["tech: CD.Technology ← CD.FetchTechnology[$%g];", IO.atom[design.technology.key]]];
env.procNode ← TiogaFileOps.InsertNode[env.declNode];
TiogaFileOps.SetContents[env.procNode, ""];
env.postDeclNode ← TiogaFileOps.InsertNode[env.procNode];
TiogaFileOps.SetContents[env.postDeclNode, "context: CDGenerate.Context ← CDGenerate.AssertContext[""USER""];"];
env.firstModStatementNode ← env.modStatementNode ← TiogaFileOps.InsertNode[env.postDeclNode];
env.nameToThing ← SymTab.Create[];
env.directory ← SymTab.Create[];
env.imports ← SymTab.Create[];
env.localThingToName ← RefTab.Create[];
env.globalThingToName ← RefTab.Create[];
env.design ← design;
};
FinishUp: PROC [env: Environment] = {
node: TiogaFileOps.Ref;
subNode: TiogaFileOps.Ref;
r: Rope.ROPENIL;
MakeDirectory[env];
node ← TiogaFileOps.InsertNode[env.modHeaderNode];
TiogaFileOps.SetContents[node, "Temp: CEDAR PROGRAM"];
subNode ← TiogaFileOps.InsertNode[node, TRUE];
TiogaFileOps.SetContents[subNode, Rope.Cat[MakeImportsExpr[env], " ="]];
r ← IO.PutFR["[] ← context.Register[""%g"", %g];", IO.rope[env.mainName], IO.rope[env.mainName]];
TiogaFileOps.SetContents[env.firstModStatementNode, r];
PlaceStatementM[env, "END."];
TiogaFileOps.Store[env.rootNode, env.fileName];
env.rootNode ← env.commentNode ← env.modHeaderNode ← NIL;
env.declNode ← env.procNode ← env.postDeclNode ← NIL;
env.firstModStatementNode ← env.modStatementNode ← NIL;
env.directory ← env.imports ← env.nameToThing ← NIL;
env.localThingToName ← NIL;
env.globalThingToName ← NIL;
TerminalIO.PutRope[env.fileName];
TerminalIO.PutRope[" created\n"];
[] ← ViewerTools.MakeNewTextViewer[info: [
file: env.fileName,
label: env.fileName,
name: env.fileName,
iconic: FALSE
]];
};
MakeProcedureNode: PROC [env: Environment] RETURNS [TiogaFileOps.Ref] = {
env.procNode ← TiogaFileOps.InsertNode[env.procNode];
env.procDecNode ← NIL;
RETURN [env.procNode]
};
MakeDeclarationNode: PROC [env: Environment] RETURNS [TiogaFileOps.Ref] = {
env.declNode ← TiogaFileOps.InsertNode[env.declNode];
RETURN [env.declNode]
};
PlaceDeclarationM1: PUBLIC PROC [env: Environment, line: Rope.ROPE] = {
node: TiogaFileOps.Ref ← MakeDeclarationNode[env];
TiogaFileOps.SetContents[node, line];
};
PlaceDeclarationM2: PUBLIC PROC [env: Environment, line: Rope.ROPE] = {
env.postDeclNode ← TiogaFileOps.InsertNode[env.postDeclNode];
TiogaFileOps.SetContents[env.postDeclNode, line];
};
PlaceStatementM: PUBLIC PROC [env: Environment, line: Rope.ROPE] = {
env.modStatementNode ← TiogaFileOps.InsertNode[env.modStatementNode];
TiogaFileOps.SetContents[env.modStatementNode, line];
};
MakeDirGenerator: PROC [env: Environment] = {
IF ~env.hasDirGen THEN {
env.hasDirGen ← TRUE;
PlaceDeclarationM2[env, "directory: CDGenerate.Context ← CDGenerate.AssertContext[""DIRECTORY""];"];
}
};
Identifier: PUBLIC PROC [r: Rope.ROPE] RETURNS [id: Rope.ROPE] = {
first: BOOLTRUE;
Trans: Rope.TranslatorType = {
IF Ascii.Letter[old] THEN new ← old
ELSE IF Ascii.Digit[old] AND ~first THEN new ← old
ELSE new ← 'x;
first ← FALSE
};
id ← Rope.Translate[base: r, translator: Trans];
IF Rope.IsEmpty[id] THEN id ← "x";
IF SymTab.Fetch[reservedWords, id].found THEN {id ← Rope.Concat[id, "X"]}
};
ForceGlobalIdent: PUBLIC PROC[env: Environment, proposed: Rope.ROPE, whatFor: REFNIL] RETURNS [ident: Rope.ROPE] = {
ident ← ForeceNewIdent[env, proposed, whatFor, TRUE];
};
GetGlobalIdent: PUBLIC PROC [env: Environment, whatFor: REF] RETURNS [Rope.ROPE] = {
RETURN [GetIdent[env, whatFor, TRUE]];
};
EnsureGlobalObjectIdent: PROC [env: Environment, ob: CD.Object] RETURNS [r: Rope.ROPE] = {
r ← GetGlobalIdent[env, ob];
IF Rope.IsEmpty[r] THEN {
name: Rope.ROPE ← CDDirectory.Name[ob, env.design];
IF Rope.IsEmpty[name] THEN name ← "CreateSubObject";
r ← ForceGlobalIdent[env, name, ob];
}
};
ForeceNewIdent: PROC [env: Environment, proposed: Rope.ROPENIL, whatFor: REFNIL, global: BOOLFALSE] RETURNS [ident: Rope.ROPE] = {
refTab: RefTab.Ref ← IF global THEN env.globalThingToName ELSE env.localThingToName;
proposed ← Identifier[proposed];
ident ← proposed;
DO
IF SymTab.Insert[env.nameToThing, ident, whatFor] THEN {
IF whatFor#NIL THEN [] ← RefTab.Store[refTab, whatFor, ident];
RETURN;
};
env.modifier ← env.modifier+1;
ident ← IO.PutFR["%gx%g", IO.rope[proposed], IO.int[env.modifier]]
ENDLOOP
};
GetIdent: PROC [env: Environment, whatFor: REF, global: BOOL] RETURNS [Rope.ROPENIL] = {
tab: RefTab.Ref ← IF global THEN env.globalThingToName ELSE env.localThingToName;
WITH RefTab.Fetch[tab, whatFor].val SELECT FROM
n: Rope.ROPE => RETURN [n];
ENDCASE => NULL;
};
Capital: PUBLIC PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = {
IF ~Rope.IsEmpty[r] AND Rope.Fetch[r, 0] IN ['a..'z] THEN
RETURN [ Rope.Replace[base: r, start: 0, len: 1,
with: Rope.FromChar[Ascii.Upper[Rope.Fetch[r, 0]]]
]];
RETURN [r];
};
Small: PUBLIC PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = {
IF ~Rope.IsEmpty[r] AND Rope.Fetch[r, 0] IN ['A..'Z] THEN
RETURN [ Rope.Replace[base: r, start: 0, len: 1,
with: Rope.FromChar[Ascii.Lower[Rope.Fetch[r, 0]]]
]];
RETURN [r];
};
IdentForLocalObject: PROC [env: Environment, ob: CD.Object] RETURNS [name: Rope.ROPE] = {
name ← GetIdent[env, ob, FALSE];
IF name=NIL THEN {
name ← CD.Describe[ob, NIL, env.design, 0];
IF Rope.IsEmpty[name] THEN {
name ← Atom.GetPName[ob.class.objectType]
};
name ← ForeceNewIdent[env, Small[name], ob, FALSE];
}
};
PosToRope: PUBLIC PROC [pos: CD.Position] RETURNS [r: Rope.ROPE] = {
RETURN [IO.PutFR["[x: %g, y: %g]",
IO.int[pos.x],
IO.int[pos.y]
]]
};
RectToRope: PUBLIC PROC [rect: CD.Rect] RETURNS [r: Rope.ROPE] = {
RETURN [IO.PutFR["[x1: %g, y1: %g, x2: %g, y2: %g]",
IO.int[rect.x1],
IO.int[rect.y1],
IO.int[rect.x2],
IO.int[rect.y2]
]]
};
MakeLayer: PUBLIC PROC [env: Environment, l: CD.Layer] RETURNS [r: Rope.ROPE] = {
IF env.declaredLayers[l]=NIL THEN {
r: Rope.ROPE;
name: Rope.ROPE ← ForeceNewIdent[env, Small[Atom.GetPName[CD.LayerKey[l]]]];
env.declaredLayers[l] ← name;
r ← IO.PutFR["%g: CD.Layer ← CD.FetchLayer[t: tech, uniqueKey: $%g];",
IO.rope[name],
IO.atom[CD.LayerKey[l]]
];
PlaceDeclarationM1[env, r];
};
RETURN [env.declaredLayers[l]]
};
PlaceStatement: PUBLIC PROC [env: Environment, line: Rope.ROPE] = {
node: TiogaFileOps.Ref;
node ← TiogaFileOps.InsertAsLastChild[env.procNode];
TiogaFileOps.SetContents[node, line];
};
OrientationToRope: PUBLIC PROC [o: CD.Orientation] RETURNS [r: Rope.ROPE] = {
RETURN [SELECT o FROM
original => "original",
mirrorX => "mirrorX",
rotate90 => "rotate90",
rotate90X => "rotate90X",
rotate180 => "rotate180",
rotate180X => "rotate180X",
rotate270 => "rotate270",
rotate270X => "rotate270X"
ENDCASE => "bad"]
};
TransformationToRope: PUBLIC PROC [trans: CD.Transformation] RETURNS [r: Rope.ROPE] = {
r ← IO.PutFR["[[x: %g, y: %g]",
IO.int[trans.off.x],
IO.int[trans.off.y]
];
IF trans.orient#original THEN r ← Rope.Cat[r, ", ", OrientationToRope[trans.orient]];
r ← Rope.Concat[r, "]"];
};
NextObject: PROC [env: Environment] RETURNS [ob: CD.Object←NIL] = {
EachOb: RefTab.EachPairAction = {
ob1: CD.Object ← NARROW[key];
IF RefTab.Fetch[env.done, ob1].found THEN RETURN [FALSE];
ob ← ob1; quit ← TRUE
};
[] ← RefTab.Pairs[env.mustDo, EachOb]
};
ProgramText: PROC [ob: CD.Object, design: CD.Design, env: Environment] = {
ob1: CD.Object;
env.mainName ← ForceGlobalIdent[env, CDDirectory.Name[ob, env.design], ob];
OneObject[ob, design, env];
WHILE (ob1←NextObject[env]) #NIL DO
env.localThingToName ← RefTab.Create[];
OneObject[ob1, design, env];
ENDLOOP
};
OneObject: PROC [ob: CD.Object, design: CD.Design, env: Environment] = {
[] ← RefTab.Insert[env.done, ob, ob];
IF ~CDCells.IsCell[ob] THEN ob ← CDDirectory.Expand1[ob, design, NIL].new;
IF ob#NIL AND CDCells.IsCell[ob] THEN {
is: CD.Position ← CD.InterestSize[ob];
pq: PriorityQueue.Ref ← PriorityQueue.Create[SortPred, IF is.x<is.y THEN $y ELSE $x];
ir: CD.Rect;
hasInst: BOOLFALSE;
num: INT ← 0;
r: Rope.ROPENIL;
cptr: CD.CellSpecific = NARROW[ob.specific];
childs: RefTab.Ref ← RefTab.Create[];
node: TiogaFileOps.Ref ← MakeProcedureNode[env];
EnQueueInst: CDCells.InstEnumerator = {
x: REF ← RefTab.Fetch[childs, inst.ob].val;
PriorityQueue.Insert[pq, inst];
IF x=NIL THEN {
num ← num+1;
[] ← RefTab.Store[childs, inst.ob, $occurs]
}
ELSE IF x=$occurs THEN {
r: Rope.ROPE ← IdentForLocalObject[env, inst.ob];
num ← num-1;
[] ← RefTab.Store[childs, inst.ob, $needsName];
PlaceStatement[env, Rope.Cat[r, ": CD.Object;"]];
}
ELSE NULL;
};
TiogaFileOps.SetContents[node, Rope.Cat[EnsureGlobalObjectIdent[env, ob], ": CDGenerate.GeneratorProc ="]];
env.procDecNode ← TiogaFileOps.InsertAsLastChild[env.procNode];
TiogaFileOps.SetContents[env.procDecNode, "BEGIN"];
--make declarations
[] ← CDCells.EnumerateInstances[ob, EnQueueInst];
IF num#0 THEN PlaceStatement[env, "child: CD.Object;"];
PlaceStatement[env, "IF design.technology#tech THEN ERROR;"];
PlaceStatement[env, "ob ← CDCells.CreateEmptyCell[];"];
--make instances
FOR num: INT IN [0..PriorityQueue.Size[pq]) DO
inst: CD.Instance ← NARROW[PriorityQueue.Remove[pq]];
EachInst: PROC [inst: CD.Instance] = {
needInst: BOOLFALSE;
childName: Rope.ROPE ← "child";
trans: CD.Transformation ← inst.trans;
SELECT RefTab.Fetch[childs, inst.ob].val FROM
$needsName => {
childName ← IdentForLocalObject[env, inst.ob];
[r, needInst] ← MakeACallExpression[env, inst.ob];
r ← Rope.Cat[childName, " ← ", r, ";"];
PlaceStatement[env, r];
IF needInst THEN [] ← RefTab.Store[childs, inst.ob, $hasValueAndNeedsInst]
ELSE [] ← RefTab.Store[childs, inst.ob, $hasValue]
};
$hasValue => {
childName ← IdentForLocalObject[env, inst.ob];
needInst ← FALSE;
};
$hasValueAndNeedsInst => {
childName ← IdentForLocalObject[env, inst.ob];
needInst ← TRUE;
};
ENDCASE => {
childName ← "child";
[r, needInst] ← MakeACallExpression[env, inst.ob];
r ← Rope.Cat[childName, " ← ", r, ";"];
PlaceStatement[env, r];
};
IF CDProperties.GetInstanceProp[inst, $SignalName]#NIL OR CDProperties.GetInstanceProp[inst, $InstanceName]#NIL THEN needInst ← TRUE;
IF needInst THEN {
hasInst ← TRUE;
r ← Rope.Cat[
IO.PutFR["inst ← CDCells.IncludeOb[cell: ob, ob: %g, trans: %g, mode: dontResize].newInst;",
IO.rope[childName],
IO.rope[TransformationToRope[trans]]
]];
}
ELSE {
r ← Rope.Cat[
IO.PutFR["[] ← CDCells.IncludeOb[cell: ob, ob: %g, trans: %g, mode: dontResize];",
IO.rope[childName],
IO.rope[TransformationToRope[trans]]
]];
};
PlaceStatement[env, r];
IF needInst THEN MakeInstanceStuff[env, inst];
};
EachInst[inst];
ENDLOOP;
--interest rect
ir ← CD.InterestRect[ob];
r ← Rope.Cat["CDCells.SetInterestRect[NIL, ob, ", RectToRope[ir], "];"];
PlaceStatement[env, r];
--include in directory ???
r ← Rope.Cat["[] ← CDDirectory.Include[design: design, object: ob"];
IF cptr.name#NIL THEN
r ← Rope.Cat[r, ", name: ", RopeToRope[cptr.name]];
r ← Rope.Cat[r, "];"];
PlaceStatement[env, r];
PlaceStatement[env, "END;"];
PlaceStatement[env, ""];
IF hasInst THEN {
env.procDecNode ← TiogaFileOps.InsertNode[env.procDecNode];
TiogaFileOps.SetContents[env.procDecNode, "inst: CD.Instance;"];
};
childs ← NIL;
}
ELSE {
TerminalIO.PutRope["**could not convert to cell\n"];
ERROR ABORTED;
}
};
RopeToRope: PUBLIC PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = {
RETURN [Convert.RopeFromRope[r]];
};
AtomToRope: PUBLIC PROC [env: Environment, a: ATOM] RETURNS [Rope.ROPE] = {
r: Rope.ROPE ← Atom.GetPName[a];
leng: INT ← Rope.Length[r];
normalCase: BOOL ← leng>0;
FOR i: INT IN [0..leng) DO
c: CHAR ← Rope.Fetch[r, i];
IF ~(Ascii.Letter[c] OR Ascii.Digit[c]) THEN {normalCase←FALSE; EXIT}
ENDLOOP;
IF normalCase THEN RETURN [Rope.Cat["$", r]];
MakePreamble[env, "Atom"];
RETURN [ Rope.Cat["Atom.MakeAtom[", Convert.RopeFromRope[r], "]"] ];
};
MakeInstanceStuff: PROC[env: Environment, inst: CD.Instance] = {
r: Rope.ROPENIL;
HandleProp: PROC [key: ATOM] = {
val: Rope.ROPE ← CDOps.ToRope[CDProperties.GetInstanceProp[inst, key]];
IF ~Rope.IsEmpty[val] THEN {
r: Rope.ROPE ← Rope.Cat[
"CDProperties.PutInstanceProp[inst, ",
AtomToRope[env, key],
", ",
RopeToRope[val],
"];"
];
MakePreamble[env, "CDProperties"];
PlaceStatement[env, r];
};
};
IF CDSymbolicObjects.IsSymbolicOb[inst.ob] THEN {
l: CD.Layer;
owner: ATOM;
name: Rope.ROPE ← CDSymbolicObjects.GetName[inst];
IF ~Rope.IsEmpty[name] THEN {
r ← Rope.Cat["CDSymbolicObjects.SetName[inst, ", RopeToRope[name], "];"];
PlaceStatement[env, r];
};
l ← CDSymbolicObjects.GetLayer[inst];
IF l#CD.undefLayer THEN {
r ← Rope.Cat["CDSymbolicObjects.SetLayer[inst, ", MakeLayer[env, l], "];"];
PlaceStatement[env, r];
};
owner ← CDSymbolicObjects.GetOwner[inst];
IF owner#NIL THEN {
r ← Rope.Cat["CDSymbolicObjects.SetOwner[inst, ", AtomToRope[env, owner], "];"];
PlaceStatement[env, r];
};
}
ELSE {
HandleProp[$SignalName];
HandleProp[$InstanceName];
}
};
SortPred: PriorityQueue.SortPred = {
p1: CD.Position ← CDBasics.BaseOfRect[CDInstances.InstRectI[NARROW[x]]];
p2: CD.Position ← CDBasics.BaseOfRect[CDInstances.InstRectI[NARROW[y]]];
IF data=$y AND p1.y#p2.y THEN RETURN[p1.y<p2.y];
IF p1.x=p2.x THEN RETURN[p1.y<p2.y];
RETURN [p1.x<p2.x];
};
MakeACallExpression: PROC[env: Environment, ob: CD.Object] RETURNS [r: Rope.ROPENIL, mustHandleInstance: BOOLFALSE] = {
r ← CallObjectExpressionProc[env, ob];
IF Rope.IsEmpty[r] THEN {
IF ob.class.composed THEN {
IF CDDirectory.IsIncluded[env.design, ob] THEN {
MakeDirGenerator[env];
r ← Rope.Cat["CDGenerate.FetchNCall[directory, design, ", RopeToRope[CDDirectory.Name[ob, env.design]], "]"];
}
ELSE {
r ← EnsureGlobalObjectIdent[env, ob];
[] ← RefTab.Insert[env.mustDo, ob, r];
r ← Rope.Cat[r, "[design, NIL, context, NIL]"];
}
}
ELSE IF CDAtomicObjects.IsAtomicOb[ob] THEN {
MakePreamble[env, "CDAtomicObjects"];
r ← "CDAtomicObjects.CreateAtomicOb[classKey: ";
r ← Rope.Cat[r, "$", CDOps.ToRope[ob.class.objectType], ", size: "];
r ← Rope.Cat[r, PosToRope[CD.InterestSize[ob]], ", "];
r ← Rope.Cat[r, "tech: tech, layer: ", MakeLayer[env, ob.layer], "]"];
}
ELSE IF CDSymbolicObjects.IsPin[ob] THEN {
MakePreamble[env, "CDSymbolicObjects"];
r ← IO.PutFR["CDSymbolicObjects.CreatePin[%g]", IO.rope[PosToRope[CD.InterestSize[ob]]]];
mustHandleInstance ← TRUE;
}
ELSE IF CDSymbolicObjects.IsSegment[ob] THEN {
MakePreamble[env, "CDSymbolicObjects"];
r ← IO.PutFR["CDSymbolicObjects.CreateSegment[length: %g, dummyWidth: %g]", IO.int[CD.InterestSize[ob].y], IO.int[CD.InterestSize[ob].x]];
mustHandleInstance ← TRUE;
}
ELSE IF CDSymbolicObjects.IsMark[ob] THEN {
MakePreamble[env, "CDSymbolicObjects"];
r ← IO.PutFR["CDSymbolicObjects.CreateMark[dummySize: %g]", IO.int[CD.InterestSize[ob].y]];
mustHandleInstance ← TRUE;
}
ELSE IF ob.class.wireTyped THEN {
MakePreamble[env, "CDRects"];
r ← "CDRects.CreateRect[size: ";
r ← Rope.Cat[r, PosToRope[CD.InterestSize[ob]]];
r ← Rope.Cat[r, ", l: ", MakeLayer[env, ob.layer], "]"];
}
ELSE {
r ← "--Unknown[]--";
MakePreamble[env, "CDRects"];
r ← Rope.Cat[r, "CDRects.CreateRect[size: "];
r ← Rope.Cat[r, PosToRope[CD.InterestSize[ob]]];
r ← Rope.Cat[r, ", l: CD.highLightError]"];
};
};
};
MakeProgramCommand: PROC [comm: CDSequencer.Command] = {
inst: CD.Instance = CDOps.TheInstance[comm.design, "make program text\n"];
IF inst#NIL THEN {
env: Environment ← NewEnvironment[comm.design];
Reserve[env, "design"];
Reserve[env, "key"];
Reserve[env, "context"];
Reserve[env, "directory"];
Reserve[env, "imports"];
Reserve[env, "data"];
Reserve[env, "tech"];
Reserve[env, "child"];
Reserve[env, "ob"];
Reserve[env, "inst"];
MakePreamble[env, "CDCells"];
MakePreamble[env, "CDGenerate"];
MakePreamble[env, "CD"];
MakePreamble[env, "CDDirectory"];
ProgramText[inst.ob, comm.design, env];
FinishUp[env];
}
};
reservedWords: SymTab.Ref ← SymTab.Create[];
InitReservedWords: PROC [] = {
[] ← SymTab.Insert[reservedWords, "ALL", $x];
[] ← SymTab.Insert[reservedWords, "ANY", $x];
[] ← SymTab.Insert[reservedWords, "ARRAY", $x];
[] ← SymTab.Insert[reservedWords, "ATOM", $x];
[] ← SymTab.Insert[reservedWords, "BEGIN", $x];
[] ← SymTab.Insert[reservedWords, "BOOL", $x];
[] ← SymTab.Insert[reservedWords, "BOOLEAN", $x];
[] ← SymTab.Insert[reservedWords, "CARD", $x];
[] ← SymTab.Insert[reservedWords, "CARD16", $x];
[] ← SymTab.Insert[reservedWords, "CARD32", $x];
[] ← SymTab.Insert[reservedWords, "CARDINAL", $x];
[] ← SymTab.Insert[reservedWords, "CEDAR", $x];
[] ← SymTab.Insert[reservedWords, "CONTINUE", $x];
[] ← SymTab.Insert[reservedWords, "DIRECTORY", $x];
[] ← SymTab.Insert[reservedWords, "DO", $x];
[] ← SymTab.Insert[reservedWords, "ELSE", $x];
[] ← SymTab.Insert[reservedWords, "END", $x];
[] ← SymTab.Insert[reservedWords, "ENDCASE", $x];
[] ← SymTab.Insert[reservedWords, "ENDLOOP", $x];
[] ← SymTab.Insert[reservedWords, "ERROR", $x];
[] ← SymTab.Insert[reservedWords, "EXIT", $x];
[] ← SymTab.Insert[reservedWords, "EXITS", $x];
[] ← SymTab.Insert[reservedWords, "EXPORTS", $x];
[] ← SymTab.Insert[reservedWords, "FALSE", $x];
[] ← SymTab.Insert[reservedWords, "FROM", $x];
[] ← SymTab.Insert[reservedWords, "GOTO", $x];
[] ← SymTab.Insert[reservedWords, "IMPORTS", $x];
[] ← SymTab.Insert[reservedWords, "INT", $x];
[] ← SymTab.Insert[reservedWords, "INTEGER", $x];
[] ← SymTab.Insert[reservedWords, "IF", $x];
[] ← SymTab.Insert[reservedWords, "LIST", $x];
[] ← SymTab.Insert[reservedWords, "LONG", $x];
[] ← SymTab.Insert[reservedWords, "LOOPHOLE", $x];
[] ← SymTab.Insert[reservedWords, "OF", $x];
[] ← SymTab.Insert[reservedWords, "NARROW", $x];
[] ← SymTab.Insert[reservedWords, "NEW", $x];
[] ← SymTab.Insert[reservedWords, "NIL", $x];
[] ← SymTab.Insert[reservedWords, "NULL", $x];
[] ← SymTab.Insert[reservedWords, "POINTER", $x];
[] ← SymTab.Insert[reservedWords, "PRIVATE", $x];
[] ← SymTab.Insert[reservedWords, "PROGRAM", $x];
[] ← SymTab.Insert[reservedWords, "PROC", $x];
[] ← SymTab.Insert[reservedWords, "PROCEDURE", $x];
[] ← SymTab.Insert[reservedWords, "PUBLIC", $x];
[] ← SymTab.Insert[reservedWords, "REAL", $x];
[] ← SymTab.Insert[reservedWords, "RECORD", $x];
[] ← SymTab.Insert[reservedWords, "REF", $x];
[] ← SymTab.Insert[reservedWords, "REJECT", $x];
[] ← SymTab.Insert[reservedWords, "RETURN", $x];
[] ← SymTab.Insert[reservedWords, "RETURNS", $x];
[] ← SymTab.Insert[reservedWords, "SELECT", $x];
[] ← SymTab.Insert[reservedWords, "SIGNAL", $x];
[] ← SymTab.Insert[reservedWords, "THEN", $x];
[] ← SymTab.Insert[reservedWords, "TRUE", $x];
[] ← SymTab.Insert[reservedWords, "TRUSTED", $x];
[] ← SymTab.Insert[reservedWords, "TO", $x];
[] ← SymTab.Insert[reservedWords, "TYPE", $x];
[] ← SymTab.Insert[reservedWords, "WITH", $x];
};
InitReservedWords[];
[] ← CDProperties.RegisterProperty[$MakeCallExpression, $chj];
CDSequencer.ImplementCommand[$MakeProgram, MakeProgramCommand,, doQueue];
TerminalIO.PutRope["make program command loaded\n"];
END.