CDMakeProcCommands.mesa (module for ChipNDale)
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, May 9, 1985 1:58:40 pm PDT
Last edited by: Christian Jacobi, October 17, 1986 11:15:42 am PDT
DIRECTORY
Ascii,
Atom,
CD,
CDAtomicObjects,
CDBasics,
CDCells,
CDCommandOps,
CDDirectory,
CDInstances,
CDMakeProcPrivate,
CDProperties,
CDOrient,
CDSequencer,
CDSymbolicObjects,
Convert,
IO,
PriorityQueue,
RefTab,
Rope,
SymTab,
TerminalIO,
TiogaFileOps,
TiogaOps,
ViewerTools;
CDMakeProcCommands:
CEDAR
PROGRAM
IMPORTS Ascii, Atom, Convert, CD, CDAtomicObjects, CDBasics, CDCells, CDCommandOps, CDDirectory, CDInstances, CDProperties, CDOrient, CDSequencer, CDSymbolicObjects, IO, PriorityQueue, RefTab, Rope, SymTab, TerminalIO, TiogaFileOps, TiogaOps, ViewerTools
EXPORTS CDMakeProcPrivate =
BEGIN
Environment: TYPE = REF EnvironmentRep;
EnvironmentRep:
PUBLIC TYPE =
RECORD [
invocationKey: REF,
rootNode: TiogaFileOps.Ref,
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
procName: Rope.ROPE,
modifier: INT ← 0,
directory: SymTab.Ref,
imports: SymTab.Ref,
declaredLayers: ARRAY CD.Layer OF Rope.ROPE ← ALL[NIL],
nameToThing: SymTab.Ref,
thingToName: RefTab.Ref,
globalThingToName: RefTab.Ref,
hasDirGen: BOOL ← FALSE,
properties: CD.PropRef
];
ExpressionProc: TYPE = CDMakeProcPrivate.ExpressionProc;
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]
};
RegisterExpressionProc:
PUBLIC PROC [for:
REF, ep: ExpressionProc, tech:
CD.Technology ←
NIL] = {
WITH for
SELECT
FROM
c:
CD.ObjectClass =>
CDProperties.PutProp[c.properties, $MakeCallExpression, NEW[ExpressionProc𡤎p]];
a: ATOM => RegisterExpressionProc[CD.FetchObjectClass[a, tech], ep, tech];
ENDCASE => ERROR
};
SpecificCallExpression:
PROC [env: Environment, ob:
CD.Object]
RETURNS [r: Rope.
ROPE ←
NIL] = {
x: REF ← CDProperties.GetProp[ob.class.properties, $MakeCallExpression];
WITH x
SELECT
FROM
rmce: REF ExpressionProc => r ← rmce^[env, ob]
ENDCASE => NULL;
};
MakeNodeComment:
PROC [node: TiogaFileOps.Ref] = {
TRUSTED { TiogaOps.PutProp[LOOPHOLE[node], $Comment, NEW[BOOLEAN ← TRUE]] };
};
Reserve:
PROC [env: Environment, key: Rope.
ROPE] = {
[] ← SymTab.Store[env.nameToThing, key, $reserved];
};
IncludeDirectory:
PUBLIC
PROC [env: Environment, module: Rope.
ROPE, import:
BOOL←
TRUE] = {
[] ← 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.ROPE ← NIL;
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.
ROPE ←
NIL] = {
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 [t:
CD.Technology]
RETURNS [env: Environment] = {
env ← NEW[EnvironmentRep←[properties: CD.InitPropRef[]]];
env.invocationKey ← NEW[INT];
env.rootNode ← TiogaFileOps.CreateRoot[];
env.commentNode ← TiogaFileOps.InsertNode[env.rootNode,
TRUE];
TiogaFileOps.SetContents[env.commentNode, "--///temp/ChipNDale/temp.mesa"];
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"];
GlobalDeclaration1[env, IO.PutFR["tech: CD.Technology ← CD.FetchTechnology[$%g];", IO.atom[t.key]]];
env.procNode ← TiogaFileOps.InsertNode[env.declNode];
TiogaFileOps.SetContents[env.procNode, ""];
env.postDeclNode ← TiogaFileOps.InsertNode[env.procNode];
TiogaFileOps.SetContents[env.postDeclNode, "table: CDGenerate.Table ← CDGenerate.AssertTable[""USER""];"];
env.firstModStatementNode ← env.modStatementNode ← TiogaFileOps.InsertNode[env.postDeclNode];
env.nameToThing ← SymTab.Create[];
env.directory ← SymTab.Create[];
env.imports ← SymTab.Create[];
env.thingToName ← RefTab.Create[];
env.globalThingToName ← RefTab.Create[];
};
FinishUp:
PROC [env: Environment] = {
node: TiogaFileOps.Ref;
subNode: TiogaFileOps.Ref;
fileName: Rope.ROPE ← "///temp/ChipNDale/temp.mesa";
r: Rope.ROPE ← NIL;
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["[] ← table.Register[""%g"", %g];", IO.rope[env.procName], IO.rope[env.procName]];
TiogaFileOps.SetContents[env.firstModStatementNode, r];
GlobalStatement[env, "END."];
TiogaFileOps.Store[env.rootNode, 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.thingToName ← NIL;
env.globalThingToName ← NIL;
TerminalIO.WriteRope[fileName];
TerminalIO.WriteRope[" created\n"];
[] ← ViewerTools.MakeNewTextViewer[info: [
file: fileName,
label: fileName,
name: 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]
};
GlobalDeclaration1:
PUBLIC PROC [env: Environment, line: Rope.
ROPE] = {
node: TiogaFileOps.Ref ← MakeDeclarationNode[env];
TiogaFileOps.SetContents[node, line];
};
GlobalDeclaration2:
PUBLIC PROC [env: Environment, line: Rope.
ROPE] = {
env.postDeclNode ← TiogaFileOps.InsertNode[env.postDeclNode];
TiogaFileOps.SetContents[env.postDeclNode, line];
};
GlobalStatement:
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;
GlobalDeclaration2[env, "directory: CDGenerate.Table ← CDGenerate.AssertTable[""DIRECTORY""];"];
}
};
RequestGlobalIdent:
PUBLIC
PROC[env: Environment, proposed: Rope.
ROPE, whatFor:
REF←
NIL]
RETURNS [Rope.
ROPE] = {
RETURN [RequestIdent[env, proposed, whatFor, TRUE]];
};
GlobalIdent:
PUBLIC
PROC [env: Environment, whatFor:
REF]
RETURNS [Rope.
ROPE] = {
RETURN [Ident[env, whatFor, TRUE]];
};
RopeToId:
PROC [r: Rope.
ROPE]
RETURNS [id: Rope.
ROPE] = {
first: BOOL ← TRUE;
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";
};
RequestIdent:
PROC [env: Environment, proposed: Rope.
ROPE←
NIL, whatFor:
REF←
NIL, global:
BOOLLSE]
RETURNS [r: Rope.
ROPE] = {
proposed ← RopeToId[proposed];
r ← proposed;
DO
IF SymTab.Insert[env.nameToThing, r, whatFor]
THEN {
IF global
THEN
[] ← RefTab.Store[env.globalThingToName, whatFor, r];
[] ← RefTab.Store[env.thingToName, whatFor, r];
RETURN;
};
env.modifier ← env.modifier+1;
r ← IO.PutFR["%gx%g", IO.rope[proposed], IO.int[env.modifier]]
ENDLOOP
};
Ident:
PROC [env: Environment, whatFor:
REF, global:
BOOL]
RETURNS [Rope.
ROPE←
NIL] = {
tab: RefTab.Ref ← IF global THEN env.globalThingToName ELSE env.thingToName;
WITH RefTab.Fetch[tab, whatFor].val
SELECT
FROM
n: Rope.ROPE => RETURN [n];
ENDCASE =>NULL;
};
IdentForLocalObject:
PROC [env: Environment, ob:
CD.Object]
RETURNS [name: Rope.
ROPE] = {
first: CHAR;
name ← Ident[env, ob, FALSE];
IF name#NIL THEN RETURN [name];
name ← CDDirectory.Name[ob];
IF Rope.IsEmpty[name]
THEN {
name ← Atom.GetPName[ob.class.objectType]
};
first ← Rope.Fetch[name];
IF Ascii.Letter[first] THEN first ← Ascii.Lower[first];
name ← Rope.Replace[
base: name, start: 0, len: 1,
with: Rope.FromChar[first]
];
name ← RequestIdent[env, 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]
]]
};
LayerIdent:
PUBLIC PROC [env: Environment, l:
CD.Layer]
RETURNS [r: Rope.
ROPE] = {
IF env.declaredLayers[l]=
NIL
THEN {
r: Rope.ROPE;
name: Rope.ROPE ← RequestIdent[env, 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]]
];
GlobalDeclaration1[env, r];
};
RETURN [env.declaredLayers[l]]
};
MapIPos:
PROC [inst:
CD.Instance]
RETURNS [iPos:
CD.Position] = {
--given an instance find the origin in interest coordinates
iPos ← CDBasics.BaseOfRect[CDInstances.InstRectI[inst]];
};
MapClientPos:
PROC [inst:
CD.Instance]
RETURNS [originPos:
CD.Position] = {
RETURN [CDOrient.MapPoint[
pointInCell: CD.ClientOrigin[inst.ob],
cellSize: inst.ob.size,
cellInstOrient: inst.orientation,
cellInstPos: inst.location
]]
};
LocalStatement:
PUBLIC PROC [env: Environment, line: Rope.
ROPE] = {
node: TiogaFileOps.Ref;
node ← TiogaFileOps.InsertAsLastChild[env.procNode];
TiogaFileOps.SetContents[node, line];
};
ProgramText:
PROC [ob:
CD.Object, design:
CD.Design, env: Environment] = {
env.procName ← RequestGlobalIdent[env, CDDirectory.Name[ob], ob];
IF ~CDCells.IsCell[ob] THEN ob ← CDDirectory.Expand[ob, design, NIL].new;
IF ob#
NIL
AND CDCells.IsCell[ob]
THEN {
pq: PriorityQueue.Ref ← PriorityQueue.Create[SortPred, IF ob.size.x<ob.size.y THEN $y ELSE $x];
ir: CD.Rect;
hasInst: BOOL ← FALSE;
num: INT ← 0;
r: Rope.ROPE ← NIL;
cptr: CD.CellPtr = NARROW[ob.specificRef];
childs: RefTab.Ref ← RefTab.Create[];
node: TiogaFileOps.Ref ← MakeProcedureNode[env];
TiogaFileOps.SetContents[node, Rope.Cat[env.procName, ": CDGenerate.GeneratorProc ="]];
env.procDecNode ← TiogaFileOps.InsertAsLastChild[env.procNode];
TiogaFileOps.SetContents[env.procDecNode, "BEGIN"];
--make declarations
FOR list:
CD.InstanceList ← cptr.contents, list.rest
WHILE list#
NIL
DO
x: REF ← RefTab.Fetch[childs, list.first.ob].val;
PriorityQueue.Insert[pq, list.first];
IF x=
NIL
THEN {
num ← num+1;
[] ← RefTab.Store[childs, list.first.ob, $first]
}
ELSE
IF x=$first
THEN {
r: Rope.ROPE ← IdentForLocalObject[env, list.first.ob];
num ← num-1;
[] ← RefTab.Store[childs, list.first.ob, $hasName];
LocalStatement[env, Rope.Cat[r, ": CD.Object;"]];
}
ELSE NULL;
ENDLOOP;
IF num#0 THEN LocalStatement[env, "child: CD.Object;"];
LocalStatement[env, "IF design.technology#tech THEN ERROR;"];
LocalStatement[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: BOOL ← FALSE;
childName: Rope.ROPE ← "child";
pos: CD.Position ← MapClientPos[inst];
iPos: CD.Position ← MapIPos[inst];
orientationCode: Rope.ROPE ← NIL;
IF inst.orientation#0
THEN
orientationCode ← IO.PutFR[", orientation: %g", IO.int[inst.orientation]];
SELECT RefTab.Fetch[childs, inst.ob].val
FROM
$hasName => {
childName ← IdentForLocalObject[env, inst.ob];
[r, needInst] ← MakeACallExpression[env, inst.ob];
r ← Rope.Cat[childName, " ← ", r, ";"];
LocalStatement[env, r];
IF needInst THEN [] ← RefTab.Store[childs, inst.ob, $hasValueMI]
ELSE [] ← RefTab.Store[childs, inst.ob, $hasValue]
};
$hasValue => {
childName ← IdentForLocalObject[env, inst.ob];
needInst ← FALSE;
};
$hasValueMI => {
childName ← IdentForLocalObject[env, inst.ob];
needInst ← TRUE;
};
ENDCASE => {
childName ← "child";
[r, needInst] ← MakeACallExpression[env, inst.ob];
r ← Rope.Cat[childName, " ← ", r, ";"];
LocalStatement[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, position: %g%0g, obCSystem: interrestCoords].newInst;",
IO.rope[childName],
IO.rope[PosToRope[iPos]],
IO.rope[orientationCode]
]];
}
ELSE {
r ← Rope.Cat[
IO.PutFR["[] ← CDCells.IncludeOb[cell: ob, ob: %g, position: %g%0g, obCSystem: interrestCoords];",
IO.rope[childName],
IO.rope[PosToRope[iPos]],
IO.rope[orientationCode]
]];
};
LocalStatement[env, r];
IF needInst THEN MakeInstanceStuff[env, inst];
};
EachInst[inst];
ENDLOOP;
--interest rect
ir ← CD.InterestRect[ob];
r ← Rope.Cat["CDCells.SetInterestRect[ob, ", RectToRope[ir], "];"];
LocalStatement[env, r];
--include in directory
r ← Rope.Cat["[] ← CDDirectory.Include[design: design, object: ob"];
IF cptr.name#
NIL
THEN
r ← Rope.Cat[r, ", alternateName: ", RopeToRope[cptr.name]];
r ← Rope.Cat[r, "];"];
LocalStatement[env, r];
LocalStatement[env, "END;"];
LocalStatement[env, ""];
IF hasInst
THEN {
env.procDecNode ← TiogaFileOps.InsertNode[env.procDecNode];
TiogaFileOps.SetContents[env.procDecNode, "inst: CD.Instance;"];
};
childs ← NIL;
}
ELSE {
TerminalIO.WriteRope["**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]];
IncludeDirectory[env, "Atom"];
RETURN [ Rope.Cat["Atom.MakeAtom[", Convert.RopeFromRope[r], "]"] ];
};
MakeInstanceStuff:
PROC[env: Environment, inst:
CD.Instance] = {
r: Rope.ROPE←NIL;
HandleProp:
PROC [key:
ATOM] = {
val: Rope.ROPE ← CDCommandOps.ToRope[CDProperties.GetInstanceProp[inst, key]];
IF ~Rope.IsEmpty[val]
THEN {
r: Rope.
ROPE ← Rope.Cat[
"CDProperties.PutInstanceProp[inst, ",
AtomToRope[env, key],
", ",
RopeToRope[val],
"];"
];
IncludeDirectory[env, "CDProperties"];
LocalStatement[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], "];"];
LocalStatement[env, r];
};
l ← CDSymbolicObjects.GetLayer[inst];
IF l#
CD.undefLayer
THEN {
r ← Rope.Cat["CDSymbolicObjects.SetLayer[inst, ", LayerIdent[env, l], "];"];
LocalStatement[env, r];
};
owner ← CDSymbolicObjects.GetOwner[inst];
IF owner#
NIL
THEN {
r ← Rope.Cat["CDSymbolicObjects.SetOwner[inst, ", AtomToRope[env, owner], "];"];
LocalStatement[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.
ROPE ←
NIL, mustHandleInstance:
BOOL ←
FALSE] = {
r ← SpecificCallExpression[env, ob];
IF Rope.IsEmpty[r]
THEN {
IF ob.class.inDirectory
THEN {
MakeDirGenerator[env];
r ← Rope.Cat["CDGenerate.FetchNCall[directory, design, ", RopeToRope[CDDirectory.Name[ob]], "]"];
}
ELSE
IF CDAtomicObjects.IsAtomicOb[ob]
THEN {
IncludeDirectory[env, "CDAtomicObjects"];
r ← "CDAtomicObjects.CreateAtomicOb[classKey: ";
r ← Rope.Cat[r, "$", CDCommandOps.ToRope[ob.class.objectType], ", size: "];
r ← Rope.Cat[r, PosToRope[CD.InterestSize[ob]], ", "];
r ← Rope.Cat[r, "tech: tech, lev: ", LayerIdent[env, ob.layer], "]"];
}
ELSE
IF CDSymbolicObjects.IsPin[ob]
THEN {
IncludeDirectory[env, "CDSymbolicObjects"];
r ← IO.PutFR["CDSymbolicObjects.CreatePin[%g]", IO.rope[PosToRope[ob.size]]];
mustHandleInstance ← TRUE;
}
ELSE
IF CDSymbolicObjects.IsSegment[ob]
THEN {
IncludeDirectory[env, "CDSymbolicObjects"];
r ← IO.PutFR["CDSymbolicObjects.CreateSegment[length: %g, dummyWidth: %g]", IO.int[ob.size.y], IO.int[ob.size.x]];
mustHandleInstance ← TRUE;
}
ELSE
IF CDSymbolicObjects.IsMark[ob]
THEN {
IncludeDirectory[env, "CDSymbolicObjects"];
r ← IO.PutFR["CDSymbolicObjects.CreateMark[dummySize: %g]", IO.int[ob.size.y]];
mustHandleInstance ← TRUE;
}
ELSE
IF ob.class.wireTyped
THEN {
IncludeDirectory[env, "CDRects"];
r ← "CDRects.CreateRect[size: ";
r ← Rope.Cat[r, PosToRope[CD.InterestSize[ob]]];
r ← Rope.Cat[r, ", l: ", LayerIdent[env, ob.layer], "]"];
}
ELSE {
r ← "--Unknown[]--";
IncludeDirectory[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 = CDCommandOps.TheInstance[comm, "make program text"];
IF inst#
NIL
THEN {
env: Environment ← NewEnvironment[comm.design.technology];
Reserve[env, "design"];
Reserve[env, "key"];
Reserve[env, "table"];
Reserve[env, "directory"];
Reserve[env, "imports"];
Reserve[env, "data"];
Reserve[env, "tech"];
Reserve[env, "child"];
Reserve[env, "ob"];
Reserve[env, "inst"];
IncludeDirectory[env, "CDCells"];
IncludeDirectory[env, "CDGenerate"];
IncludeDirectory[env, "CD"];
IncludeDirectory[env, "CDDirectory"];
ProgramText[inst.ob, comm.design, env];
FinishUp[env];
}
};
[] ← CDProperties.RegisterProperty[$MakeCallExpression, $chj];
CDSequencer.ImplementCommand[$MakeProgram, MakeProgramCommand,, doQueue];
TerminalIO.WriteRope["make program command loaded\n"];
END.