-- TexNode.mesa -- implementation of procedures in TexNodeDefs -- last written by Doug Wyatt, December 18, 1979 6:37 PM DIRECTORY TexDefs: FROM "TexDefs", TexErrorDefs: FROM "TexErrorDefs" USING[Confusion], TexGlueDefs: FROM "TexGlueDefs" USING[GluePtr,AddGlueLink,DelGlueLink,zeroGlueSet,FlexSumsPtr], TexMemDefs: FROM "TexMemDefs" USING[AllocMem,FreeMem], TexNodeDefs: FROM "TexNodeDefs", TexTokenDefs: FROM "TexTokenDefs" USING[TokenListPtr,DelRCLink], InlineDefs: FROM "InlineDefs" USING[COPY]; TexNode: PROGRAM IMPORTS TexErrorDefs,TexGlueDefs,TexMemDefs,TexNodeDefs,TexTokenDefs, InlineDefs EXPORTS TexNodeDefs = BEGIN OPEN TexGlueDefs,TexDefs,TexNodeDefs; -- eventually, most of these procedures should be made INLINE -- and moved to TexNodeDefs AllocHead: PROCEDURE RETURNS[NodeListPtr] = INLINE BEGIN RETURN[TexMemDefs.AllocMem[SIZE[listhead Node]]] END; FreeHead: PROCEDURE[p: NodeListPtr] = INLINE BEGIN TexMemDefs.FreeMem[p,SIZE[listhead Node]] END; InitNodeList: PUBLIC PROCEDURE RETURNS[NodeListPtr] = BEGIN list: NodeListPtr←AllocHead[]; list↑←[link: NIL, body: listhead[last: list]]; RETURN[list]; END; MakeNodeList: PUBLIC PROCEDURE[p: NodePtr] RETURNS[NodeListPtr] = BEGIN list: NodeListPtr←AllocHead[]; list↑←[link: p, body: listhead[last: NIL]]; RETURN[list]; END; FinishNodeList: PUBLIC PROCEDURE[list: NodeListPtr] RETURNS[NodePtr] = BEGIN p: NodePtr←list.link; FreeHead[list]; RETURN[p]; END; StoreNode: PUBLIC PROCEDURE[list: NodeListPtr, p: NodePtr] = BEGIN list.last.link←p; list.last←p END; InsertNode: PUBLIC PROCEDURE[list: NodeListPtr, p: NodePtr] = BEGIN -- inserts node p at the front of list IF (p.link←list.link)=NIL THEN list.last←p; list.link←p; END; RemoveNode: PUBLIC PROCEDURE[list: NodeListPtr] RETURNS[NodePtr] = BEGIN -- removes the node at the front of list p: NodePtr; IF (p←list.link)=NIL THEN RETURN[NIL]; IF (list.link←p.link)=NIL THEN list.last←list ELSE p.link←NIL; RETURN[p]; END; InsertNodeList: PUBLIC PROCEDURE[list, inslist: NodeListPtr] = BEGIN -- inserts inslist at the front of list; destroys inslist's list head IF inslist.link#NIL THEN BEGIN -- link the lists together and update list.last if list was empty IF (inslist.last.link←list.link)=NIL THEN list.last←inslist.last; list.link←inslist.link; END; FreeHead[inslist]; END; AppendNodeList: PUBLIC PROCEDURE[list, applist: NodeListPtr] = BEGIN -- appends applist at the back of list; destroys applist's list head IF applist.link#NIL THEN BEGIN list.last.link←applist.link; -- link the lists together list.last←applist.last; -- tail of the new list is tail of applist END; FreeHead[applist]; END; RemoveNodeList: PUBLIC PROCEDURE[list: NodeListPtr, p: NodePtr] RETURNS[NodeListPtr] = BEGIN -- removes nodes up to and including p from the front of list; -- makes and returns a new list remlist: NodeListPtr←AllocHead[]; remlist↑←[link: list.link, body: listhead[last: p]]; IF (list.link←p.link)=NIL THEN list.last←list ELSE p.link←NIL; RETURN[remlist]; END; FreeNode: PROCEDURE[p: NodePtr, size: CARDINAL] = INLINE BEGIN TexMemDefs.FreeMem[p,size] END; DsNode: PUBLIC PROCEDURE[p: NodePtr] = BEGIN WITH pp:p SELECT FROM char,disc => FreeNode[p,SIZE[char Node]]; string => FreeNode[p,StringNodeSize[pp.length]]; box => BEGIN DsNodeList[pp.head]; FreeNode[p,SIZE[box Node]] END; rule => FreeNode[p,SIZE[rule Node]]; glue => BEGIN DelGlueLink[pp.g]; FreeNode[p,SIZE[glue Node]] END; space,kern => FreeNode[p,SIZE[space Node]]; leader => BEGIN DsNodeList[pp.p]; FreeNode[p,SIZE[leader Node]] END; hyph => FreeNode[p,SIZE[hyph Node]]; penalty => FreeNode[p,SIZE[penalty Node]]; eject => FreeNode[p,SIZE[eject Node]]; mark => BEGIN TexTokenDefs.DelRCLink[pp.t]; FreeNode[p,SIZE[mark Node]]; END; ins => BEGIN DsNodeList[pp.vlist]; DelGlueLink[pp.glue]; FreeNode[p,SIZE[ins Node]]; END; unset => BEGIN DsNode[pp.box]; FreeNode[p,SIZE[unset Node]]; END; listhead => ERROR TexErrorDefs.Confusion; ENDCASE => ERROR; -- bad node type END; DsNodeList: PUBLIC PROCEDURE[p: NodePtr] = BEGIN q: NodePtr←p; next: NodePtr; -- holds q.link WHILE q#NIL DO next←q.link; DsNode[q]; q←next ENDLOOP; END; MakeBoxNode: PUBLIC PROCEDURE[dir: Direction, head: NodePtr, h,d,w: Dimn] RETURNS[b: BoxNodePtr] = BEGIN b←TexMemDefs.AllocMem[SIZE[box Node]]; b↑←[link: NIL, body: box[ dir: dir, altered: FALSE, encloses: TRUE, head: head, width: w, depth: d, height: h, shiftamt: 0, glueset: zeroGlueSet]]; END; NullBox: PUBLIC PROCEDURE RETURNS[b: BoxNodePtr] = BEGIN b←TexMemDefs.AllocMem[SIZE[box Node]]; b↑←[link: NIL, body: box[ dir: hlist, altered: FALSE, encloses: TRUE, head: NIL, width: 0, depth: 0, height: 0, shiftamt: 0, glueset: zeroGlueSet]]; END; MakeCharNode: PUBLIC PROCEDURE[c: FChar] RETURNS[p: CharNodePtr] = BEGIN p←TexMemDefs.AllocMem[SIZE[char Node]]; p↑←[link: NIL, body: char[c]]; END; MakeDiscNode: PUBLIC PROCEDURE[c: FChar] RETURNS[p: POINTER TO disc Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[disc Node]]; p↑←[link: NIL, body: disc[c]]; END; MakeEjectNode: PUBLIC PROCEDURE RETURNS[p: POINTER TO eject Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[eject Node]]; p↑←[link: NIL, body: eject[]]; END; MakeGlueNode: PUBLIC PROCEDURE[g: GluePtr] RETURNS[p: GlueNodePtr] = BEGIN p←TexMemDefs.AllocMem[SIZE[glue Node]]; p↑←[link: NIL, body: glue[g]]; AddGlueLink[g]; -- increment reference count of GlueSpec END; MakeHyphNode: PUBLIC PROCEDURE[h: HyphControl] RETURNS[p: POINTER TO hyph Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[hyph Node]]; p↑←[link: NIL, body: hyph[h]]; END; MakeInsNode: PUBLIC PROCEDURE[tb: TopBotType, dir: Direction, hd: NodePtr, g: GluePtr] RETURNS[p: InsNodePtr] = BEGIN p←TexMemDefs.AllocMem[SIZE[ins Node]]; p↑←[link: NIL, body: ins[where: tb, dir: dir, vlist: hd, glue: g]]; END; MakeKernNode: PUBLIC PROCEDURE[k: Dimn] RETURNS[p: POINTER TO kern Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[kern Node]]; p↑←[link: NIL, body: kern[k]]; END; MakeLeaderNode: PUBLIC PROCEDURE[q: NodePtr] RETURNS[p: POINTER TO leader Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[leader Node]]; p↑←[link: NIL, body: leader[q]]; END; MakeMarkNode: PUBLIC PROCEDURE[t: TexTokenDefs.TokenListPtr] RETURNS[p: POINTER TO mark Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[mark Node]]; p↑←[link: NIL, body: mark[t]]; END; MakePenaltyNode: PUBLIC PROCEDURE[pen: Penalty] RETURNS[p: POINTER TO penalty Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[penalty Node]]; p↑←[link: NIL, body: penalty[pen]]; END; MakeRuleNode: PUBLIC PROCEDURE[width,height,depth: Dimn] RETURNS[p: RuleNodePtr] = BEGIN p←TexMemDefs.AllocMem[SIZE[rule Node]]; p↑←[link: NIL, body: rule[width: width, height: height, depth: depth]]; END; MakeSpace: PUBLIC PROCEDURE[s: Dimn] RETURNS[p: POINTER TO space Node] = BEGIN p←TexMemDefs.AllocMem[SIZE[space Node]]; p↑←[link: NIL, body: space[s]]; END; MakeStringNode: PUBLIC PROCEDURE[f: Font, s: STRING] RETURNS[p: POINTER TO string Node] = BEGIN len: CARDINAL←s.length; p←TexMemDefs.AllocMem[StringNodeSize[len]]; p↑←[link: NIL, body: string[font: f, length: len, text: ]]; InlineDefs.COPY[from: @s.text, to: @p.text, nwords: (len+1)/2]; END; MakeUnsetNode: PUBLIC PROCEDURE[box: BoxNodePtr,fPtr: FlexSumsPtr] RETURNS[p: UnsetNodePtr] = BEGIN p←TexMemDefs.AllocMem[SIZE[unset Node]]; p↑←[link: NIL, body: unset[box,fPtr↑]]; END; END.