--December 7, 1982 11:38 am -- JunoStorageImpl.mesa, coded June 81 by Greg Nelson. -- Defines record types, allocation and deallocation functions. DIRECTORY JunoStorage, RealFns, Rope, Graphics, List, JunoButtons; JunoStorageImpl: PROGRAM IMPORTS RealFns, List EXPORTS JunoStorage = BEGIN OPEN JunoStorage, List; GetBody: PUBLIC PROC [name: REF ANY] RETURNS [REF ANY] = {deflist : LIST OF REF ANY ← lambdaAlist; WHILE deflist # NIL AND deflist.first # name DO deflist ← deflist.rest.rest.rest ENDLOOP; IF deflist # NIL THEN RETURN [Car[Cddr[deflist]]] ELSE RETURN [NIL]}; GetLocals: PUBLIC PROC [name: REF ANY] RETURNS [REF ANY] = {deflist : LIST OF REF ANY ← lambdaAlist; WHILE deflist # NIL AND deflist.first # name DO deflist ← deflist.rest.rest.rest ENDLOOP; IF deflist = NIL THEN RETURN [NIL] ELSE RETURN [Cadr[deflist]] }; AddDef: PUBLIC PROC [name, locals, body: REF ANY] = {lambdaAlist ← CONS[name, CONS[locals, CONS[body, lambdaAlist]]]}; lambdaAlist: PUBLIC LIST OF REF ANY; constructionList: PUBLIC LIST OF ApplyRecord; AddX: PUBLIC PROC [f: REF ANY, args:LIST OF PointPtr] = {constructionList ← CONS[[f, args], constructionList]}; pointAvail: PointPtr ← NIL; edgeAvail: EdgePtr ← NIL; arcAvail: ArcPtr ← NIL; lineAvail: LinPtr ← NIL; congAvail: CongPtr ← NIL; horAvail: HorPtr ← NIL; verAvail: VerPtr ← NIL; ccAvail: CCPtr ← NIL; tvAvail: TangentVector ← NIL; basisAvail: Basis ← NIL; stringAvail: StringPtr ← NIL; saveStateList: LIST OF SaveStateRec ← NIL; -- saveStateList: LIST OF REF ANY ← NIL; npoint, nedge, narc, nline, nstring: PUBLIC INTEGER ← 0; ncong, nhor, nver, ntv, nbasis, ncc: PUBLIC INTEGER ← 0; PushState: PUBLIC PROCEDURE = BEGIN saveStateList ← CONS[ [savePointLpad: pointLpad.link, saveEdgeLpad: edgeLpad.link, saveArcLpad: arcLpad.link, saveLineLpad: lineLpad.link, saveCongLpad: congLpad.link, saveHorLpad: horLpad.link, saveVerLpad: verLpad.link, saveStringLpad: stringLpad.link, saveCCLpad: ccLpad.link ], saveStateList] ; ResetJunoStorage[]; END; PopState: PUBLIC PROCEDURE = BEGIN ResetJunoStorage[]; pointLpad.link ← saveStateList.first.savePointLpad; edgeLpad.link ← saveStateList.first.saveEdgeLpad; arcLpad.link ← saveStateList.first.saveArcLpad; lineLpad.link ← saveStateList.first.saveLineLpad; congLpad.link ← saveStateList.first.saveCongLpad; horLpad.link ← saveStateList.first.saveHorLpad; verLpad.link ← saveStateList.first.saveVerLpad; stringLpad.link ← saveStateList.first.saveStringLpad; ccLpad.link ← saveStateList.first.saveCCLpad; saveStateList ← saveStateList.rest; END; NewPoint: PUBLIC PROCEDURE RETURNS [r: PointPtr] = BEGIN npoint ← npoint + 1; IF pointAvail = NIL THEN XPoint[]; r ← pointAvail; pointAvail ← pointAvail.link; r.fixed ← FALSE; r.visible ← TRUE; r.wn ← 0; r.copy ← NIL; END; NewEdge: PUBLIC PROCEDURE RETURNS [r: EdgePtr] = BEGIN nedge ← nedge + 1; IF edgeAvail = NIL THEN XEdge[]; r ← edgeAvail; edgeAvail ← edgeAvail.link END; NewArc: PUBLIC PROCEDURE RETURNS [r: ArcPtr] = BEGIN narc ← narc + 1; IF arcAvail = NIL THEN XArc[]; r ← arcAvail; arcAvail ← arcAvail.link END; NewLine: PUBLIC PROCEDURE RETURNS [r: LinPtr] = BEGIN nline ← nline + 1; IF lineAvail = NIL THEN XLine[]; r ← lineAvail; lineAvail ← lineAvail.link END; NewCong: PUBLIC PROCEDURE RETURNS [r: CongPtr] = BEGIN ncong ← ncong + 1; IF congAvail = NIL THEN XCong[]; r ← congAvail; congAvail ← congAvail.link END; NewHor: PUBLIC PROCEDURE RETURNS [r: HorPtr] = BEGIN nhor ← nhor + 1; IF horAvail = NIL THEN XHor[]; r ← horAvail; horAvail ← horAvail.link END; NewVer: PUBLIC PROCEDURE RETURNS [r: VerPtr] = BEGIN nver ← nver + 1; IF verAvail = NIL THEN XVer[]; r ← verAvail; verAvail ← verAvail.link END; NewCC: PUBLIC PROCEDURE RETURNS [r: CCPtr] = {ncc ← ncc + 1; IF ccAvail = NIL THEN XCC[]; r ← ccAvail; ccAvail ← ccAvail.link}; NewTv: PUBLIC PROCEDURE RETURNS[r:TangentVector] = {ntv ← ntv + 1; IF tvAvail = NIL THEN XTv[]; r ← tvAvail; tvAvail ← tvAvail.tail}; NewBasis: PUBLIC PROCEDURE RETURNS[r:Basis] = {nbasis ← nbasis + 1; IF basisAvail = NIL THEN XBasis[]; r ← basisAvail; basisAvail ← basisAvail.tail}; NewString : PUBLIC PROCEDURE RETURNS [r: StringPtr] = BEGIN nstring ← nstring + 1; IF stringAvail = NIL THEN XString[]; r ← stringAvail; stringAvail ← stringAvail.link END; GcPoint: PUBLIC PROCEDURE[p:PointPtr] = BEGIN npoint ← npoint - 1; p.link ← pointAvail; pointAvail ← p END; GcEdge: PUBLIC PROCEDURE[p:EdgePtr] = BEGIN nedge ← nedge - 1; p.link ← edgeAvail; edgeAvail ← p END; GcArc: PUBLIC PROCEDURE[p:ArcPtr] = BEGIN narc ← narc - 1; p.link ← arcAvail; arcAvail ← p END; GcLine: PUBLIC PROCEDURE[p:LinPtr] = BEGIN nline ← nline + 1; p.link ← lineAvail; lineAvail ← p END; GcString: PUBLIC PROCEDURE [p: StringPtr] = BEGIN nstring ← nstring + 1; p.link ← stringAvail; stringAvail ← p END; GcCong: PUBLIC PROCEDURE[p:CongPtr] = BEGIN ncong ← ncong - 1; p.link ← congAvail; congAvail ← p END; GcHor: PUBLIC PROCEDURE[p:HorPtr] = BEGIN nhor ← nhor - 1; p.link ← horAvail; horAvail ← p END; GcVer: PUBLIC PROCEDURE[p:VerPtr] = BEGIN nver ← nver - 1; p.link ← verAvail; verAvail ← p END; GcCC: PUBLIC PROC[p: CCPtr] = {ncc ← ncc - 1; p.link ← ccAvail; ccAvail ← p}; GcTv: PUBLIC PROC[t:TangentVector] = {ntv ← ntv - 1; t.tail ← tvAvail; tvAvail ← t}; GcBasis: PUBLIC PROC[b:Basis] = {nbasis ← nbasis - 1; b.tail ← basisAvail; basisAvail ← b}; XPoint: PROC = {THROUGH [1..50] DO pointAvail ← NEW[Point ← [link: pointAvail]] ENDLOOP}; XEdge: PROC = {THROUGH [1..50] DO edgeAvail ← NEW[Edge ← [link: edgeAvail]] ENDLOOP}; XArc: PROC = {THROUGH [1..50] DO arcAvail ← NEW[Arc ← [link: arcAvail]] ENDLOOP}; XLine: PROC = {THROUGH [1..50] DO lineAvail ← NEW[LineConstraint ← [link:lineAvail]] ENDLOOP}; XCong: PROC = {THROUGH [1..50] DO congAvail ← NEW[CongruenceConstraint ← [link:congAvail]] ENDLOOP}; XHor: PROC = {THROUGH [1..50] DO horAvail ← NEW[HorizontalConstraint ← [link:horAvail]] ENDLOOP}; XVer: PROC = {THROUGH [1..50] DO verAvail ← NEW[VerticalConstraint ← [link:verAvail]] ENDLOOP}; XCC: PROC = {THROUGH [1..50] DO ccAvail ← NEW[CCConstraint ← [link:ccAvail]] ENDLOOP}; XTv: PROC = {THROUGH [1..50] DO tvAvail ← NEW[TvRec ← [tail:tvAvail]] ENDLOOP}; XBasis: PROC = {THROUGH [1..50] DO basisAvail ← NEW[BasisRec ← [tail:basisAvail]] ENDLOOP}; XString : PROC = { THROUGH [1..50] DO stringAvail ← NEW [String ← [link: stringAvail]] ENDLOOP}; AddPoint: PUBLIC PROCEDURE[x,y:REAL] RETURNS [PointPtr] = BEGIN p: PointPtr ← NewPoint[]; p.x ← x; p.y ← y; p.link ← pointLpad.link; pointLpad.link ← p; RETURN [p]; END; Distance: PROC[a,b,c,d:REAL] RETURNS [REAL] = INLINE {RETURN[RealFns.SqRt[(a-c)*(a-c)+(b-d)*(b-d)]]}; FindPoint: PUBLIC PROCEDURE[x,y:REAL] RETURNS [PointPtr] = BEGIN -- This procedure finds the point closest to the current mouse coordinates. p: PointPtr ← pointLpad.link; champdistance, pdistance: REAL; champ: PointPtr; IF p = pointRpad THEN RETURN[NIL]; -- no points. champ ← p; champdistance ← Distance[p.x, p.y, x, y]; p ← p.link; WHILE p # pointRpad DO pdistance ← Distance[p.x, p.y, x, y]; IF pdistance < champdistance THEN BEGIN champ ← p; champdistance ← pdistance END; p ← p.link; ENDLOOP; RETURN [champ]; END; AddEdge: PUBLIC PROCEDURE[a,b:PointPtr] = BEGIN p: EdgePtr; IF a = NIL OR b = NIL THEN RETURN; -- why reversed a & b assignments? p ← NewEdge[]; p.b1 ← b; p.b2 ← a; p.link ← edgeLpad.link; edgeLpad.link ← p; END; AddArc: PUBLIC PROCEDURE[a,b,c,d:PointPtr] = BEGIN p: ArcPtr; IF a = NIL OR b = NIL OR c = NIL OR d = NIL THEN RETURN; p ← NewArc[]; p.b1 ← a; p.b2 ← b; p.b3 ← c; p.b4 ← d; p.link ← arcLpad.link; arcLpad.link ← p; END; AddHor: PUBLIC PROCEDURE[a,b:PointPtr] = BEGIN p: HorPtr; IF a = NIL OR b = NIL THEN RETURN; p ← NewHor[]; p.i ← a; p.j ← b; p.link ← horLpad.link; horLpad.link ← p; END; AddVer: PUBLIC PROCEDURE[a,b:PointPtr] = BEGIN p: VerPtr; IF a = NIL OR b = NIL THEN RETURN; p ← NewVer[]; p.i ← b; p.j ← a; p.link ← verLpad.link; verLpad.link ← p; END; AddCong: PUBLIC PROCEDURE[a,b,c,d:PointPtr] = BEGIN p: CongPtr; IF d = NIL OR c = NIL OR b = NIL OR a = NIL THEN RETURN; p ← NewCong[]; p.i ← c; p.j ← d; p.k ← a; p.l ← b; p.link ← congLpad.link; congLpad.link ← p; END; AddLin: PUBLIC PROCEDURE[a,b,c,d:PointPtr] = BEGIN p: LinPtr; IF a = NIL OR b = NIL OR c = NIL THEN RETURN; p ← NewLine[]; p.i ← a; p.j ← b; p.k ← c; p.l ← d; p.link ← lineLpad.link; lineLpad.link ← p; END; AddCC: PUBLIC PROC[a, b, c: PointPtr] = {p: CCPtr; IF a = NIL OR b = NIL OR c = NIL THEN ERROR; p ← NewCC[]; p.i ← a; p.j ← b; p.k ← c; p.link ← ccLpad.link; ccLpad.link ← p}; AddString: PUBLIC PROCEDURE [c,d: PointPtr, h, w, dep : REAL, stringText: Rope.ROPE, stringFont: Graphics.FontRef, fontName: Rope.ROPE, fontSize: INT, bold, italic: BOOL] = BEGIN p : StringPtr; IF c = NIL OR d = NIL THEN RETURN; p ← NewString[ ]; p.b3 ← c; p.b4 ← d; p.height ← h; p.width ← w; p.depth ← dep; p.stringText ← stringText; p.stringFont ← stringFont; p.fontName ←fontName; p.fontSize ← fontSize; p.bold ← bold; p.italic ← italic; p.link ← stringLpad.link; stringLpad.link ← p; END; InitJunoStorage: PUBLIC PROCEDURE = BEGIN pointRpad ← NewPoint[]; pointRpad.x ← 32767; pointLpad ← NewPoint[]; pointLpad.x ← -32767; -- for some reason -32768 won't work pointLpad.link ← pointRpad; pointLpad.slink ← pointRpad; edgeLpad ← NewEdge[]; edgeRpad ← NewEdge[]; edgeLpad.link ← edgeRpad; arcLpad ← NewArc[]; arcRpad ← NewArc[]; arcLpad.link ← arcRpad; lineLpad ← NewLine[]; lineRpad ← NewLine[]; lineLpad.link ← lineRpad; congLpad ← NewCong[]; congRpad ← NewCong[]; congLpad.link ← congRpad; horLpad ← NewHor[]; horRpad ← NewHor[]; horLpad.link ← horRpad; verLpad ← NewVer[]; verRpad ← NewVer[]; verLpad.link ← verRpad; ccLpad ← NewCC[]; ccRpad ← NewCC[]; ccLpad.link ← ccRpad; stringLpad ← NewString[ ]; stringRpad ← NewString[ ]; stringLpad.link ← stringRpad; END; ResetJunoStorage: PUBLIC PROC = -- test the cedar collector: {pointLpad.link ← pointRpad; pointLpad.slink ← pointRpad; edgeLpad.link ← edgeRpad; arcLpad.link ← arcRpad; lineLpad.link ← lineRpad; congLpad.link ← congRpad; horLpad.link ← horRpad; verLpad.link ← verRpad; ccLpad.link ← ccRpad; stringLpad.link ← stringRpad; }; pointLpad, pointRpad: PUBLIC PointPtr; -- The lists of points, edges, arcs edgeLpad, edgeRpad:PUBLIC EdgePtr; -- line constraints, and cong. constraints arcLpad, arcRpad: PUBLIC ArcPtr; -- are padded on both sides. lineLpad, lineRpad: PUBLIC LinPtr; congLpad, congRpad:PUBLIC CongPtr; horLpad, horRpad: PUBLIC HorPtr; verLpad, verRpad: PUBLIC VerPtr; ccLpad, ccRpad: PUBLIC CCPtr; stringLpad, stringRpad: PUBLIC StringPtr; END.