-- file SMTypeConsImpl.mesa
-- last modified by Satterthwaite, August 11, 1983 1:52 pm
DIRECTORY
Rope: TYPE USING [ROPE, Flatten],
SMTree: TYPE Tree USING [Link],
SMTreeOps: TYPE --TreeOps-- USING [
TM, MakeNode, NthSon, OpName, PopTree, PushNode, PushTree, PushName,
PushText, SetAttr, Zone],
SMTypeCons: TYPE --TypeCons-- USING [],
TimeStamp: TYPE USING [Stamp];
SMTypeConsImpl: CEDAR PROGRAM
IMPORTS Rope, SMTreeOps
EXPORTS SMTypeCons ~ {
-- type tree building (for Cedar units)
OPEN Tree~~SMTree, TreeOps~~SMTreeOps;
TM: TYPE ~ TreeOps.TM;
MkString: PUBLIC PROC[tm: TM, text: Rope.ROPE] RETURNS[Tree.Link] ~ {
tm.PushText[text.Flatten[]];
RETURN [tm.PopTree]};
-- type construction
MkStringType: PUBLIC PROC[tm: TM] RETURNS[Tree.Link] ~ {
RETURN [tm.MakeNode[$typeSTRING, 0]]};
MkControlType: PUBLIC PROC[tm: TM] RETURNS[Tree.Link] ~ {
RETURN [tm.MakeNode[$control, 0]]};
MkInterfaceType: PUBLIC PROC[tm: TM, id: ATOM] RETURNS[Tree.Link] ~ {
tm.PushName[id];
RETURN [tm.MakeNode[$type, 1]]};
MkStampType: PUBLIC PROC[tm: TM, stamp: TimeStamp.Stamp] RETURNS[Tree.Link] ~ {
tm.PushTree[(tm.Zone).NEW[TimeStamp.Stamp ← stamp]];
RETURN [tm.MakeNode[$stamp, 1]]};
MkPair: PUBLIC PROC[tm: TM, type1, type2: Tree.Link] RETURNS[Tree.Link] ~ {
tm.PushTree[type1]; tm.PushTree[type2];
RETURN [tm.MakeNode[$cross, 2]]};
MkCross: PUBLIC PROC[tm: TM, typeList: LIST OF Tree.Link] RETURNS[Tree.Link] ~ {
IF typeList = NIL THEN tm.PushNode[$nil, 0]
ELSE {
tm.PushTree[typeList.first]; tm.PushTree[MkCross[tm, typeList.rest]];
tm.PushNode[$cross, 2]};
RETURN [tm.PopTree]};
MkCrossReverse: PUBLIC PROC[tm: TM, typeList: LIST OF Tree.Link] RETURNS[Tree.Link] ~ {
tm.PushNode[$nil, 0];
FOR l: LIST OF Tree.Link ← typeList, l.rest UNTIL l = NIL DO
tm.PushTree[l.first]; tm.PushNode[$cross, -2];
ENDLOOP;
RETURN [tm.PopTree]};
MkCross2: PUBLIC PROC[tm: TM, decl, type: Tree.Link] RETURNS[Tree.Link] ~ {
tm.PushTree[decl]; tm.SetAttr[1, TRUE];
tm.PushTree[type];
RETURN [tm.MakeNode[$cross2, 2]]};
MkDeclElem: PUBLIC PROC[tm: TM, id: ATOM, type: Tree.Link] RETURNS[Tree.Link] ~ {
tm.PushName[id]; tm.PushTree[type];
RETURN [tm.MakeNode[$declElem, 2]]};
MkDecl: PUBLIC PROC[tm: TM, elemList: LIST OF Tree.Link] RETURNS[Tree.Link] ~ {
n: NAT←0;
FOR l: LIST OF Tree.Link ← elemList, l.rest UNTIL l = NIL DO
tm.PushTree[l.first]; n ← n+1;
ENDLOOP;
tm.PushNode[$decl, n]; tm.SetAttr[1, TRUE];
RETURN [tm.PopTree]};
MkDeclReverse: PUBLIC PROC[tm: TM, elemList: LIST OF Tree.Link] RETURNS[Tree.Link] ~ {
n: NAT←0;
FOR l: LIST OF Tree.Link ← elemList, l.rest UNTIL l = NIL DO
tm.PushTree[l.first]; n ← n+1;
ENDLOOP;
tm.PushNode[$decl, -n]; tm.SetAttr[1, TRUE];
RETURN [tm.PopTree]};
MkArrow: PUBLIC PROC[tm: TM, domain, range: Tree.Link] RETURNS[Tree.Link] ~ {
tm.PushTree[domain]; tm.PushTree[range];
RETURN [tm.MakeNode[$arrow, 2]]};
-- type decomposition
Domain: PUBLIC PROC[tm: TM, arrow: Tree.Link] RETURNS[Tree.Link] ~ {
IF TreeOps.OpName[arrow] # $arrow THEN ERROR;
RETURN [TreeOps.NthSon[arrow, 1]]};
Range: PUBLIC PROC[tm: TM, arrow: Tree.Link] RETURNS[Tree.Link] ~ {
IF TreeOps.OpName[arrow] # $arrow THEN ERROR;
RETURN [TreeOps.NthSon[arrow, 2]]};
-- utilities
PushLink: PUBLIC PROC[tm: TM, link: Tree.Link] ~ {tm.PushTree[link]};
PopLink: PUBLIC PROC[tm: TM] RETURNS[Tree.Link] ~ {RETURN [tm.PopTree]};
}.