JunoStorage.mesa

Coded June 81 by Greg Nelson.
Last edited by GNelson(?) September 14, 1982 4:38 pm
Last edited by Stolfi June 4, 1984 3:04:44 pm PDT

Definitions of record types for (image points and expanded constraints/actions) used by JunoTop (via JunoImage, JunoAlgebra, and JunoOldSolver). Also allocation and deallocation procedures.

This module is logically superfluous. A cleaner idea woud be to keep only the x,y and solver stuff in the point records, and not have constraints and action records at all. The points of the current image chould be kept in an a-list, with the frozen and winding number stuff kept separately; the actions and constraints shuld be kept as symbolic expressions (see JunoAlgebra). However, that would require too much allocation.deallocation/narrowing, and would slow down Juno significantly.

DIRECTORY

Imager USING [Pair];

JunoStorage: DEFINITIONS =

BEGIN

- - - - COORDINATES

Coords: TYPE = Imager.Pair; -- RECORD[x, y: REAL]
Coordinates of a point in the Juno system (big points from lower left corner of picture)

IntCoords: TYPE = RECORD [x, y: INTEGER];
Coordinates of a point in the Juno system (big points from lower left corner of picture), rounded to nearest integer for efficiency reasons. (Are they worthwhile?)

- - - - POINTS

Point: TYPE = REF PointRec;

PointList: TYPE = RECORD [first, last: REF PointRec];
Connected by link field; last.link always NIL. Both NIL if list is empty.

PointRec: TYPE = RECORD

[coords: Coords ← [0, 0], -- coordinates of point.
frozen: BOOLFALSE, -- p was frozen by user.
visible: BOOLFALSE, -- false for control points of strings
link: Point, -- next point in list
-- Input/output data for JunoImage, JunoOldSolver and JunoBody:
wn: INTEGER ← 0, -- winding number (#0 for blue-selected points)
copy: Point ← NIL, -- copy of point, or target in point identification.
name: ATOMNIL, -- used when building procedures
fixed: BOOLFALSE, -- TRUE = don't solve for/don't locally declare this point.
-- Temporary mark used internally in JunoImage, JunoBody, JunoOldSolver:
mark: BOOLFALSE, -- general-purpose mark bit
-- Temporary data used only by JunoOldSolver:
xCol, yCol: INTEGER ← 0, -- columns corresp. to each coordinate in tableau
old: Coords ← [0, 0] -- round values of x, y in previous iteration.
];

NewPoint: PROC [coords: Coords, visible: BOOLFALSE] RETURNS [p: Point];
Creates a new point record (allocates from pool if available).
Sets the visible flag as specified, but does not paint p on the screen.

DeletePoint: PROC [p, ant: Point, list: PointList] RETURNS [newList: PointList];
Deletes the point p from the list. The parameter ant is optional; if not NIL, it must be that ant.link = p.

InsertPoint: PROC [p, ant: Point, list: PointList] RETURNS [newList: PointList];
Inserts the point p into the list, just after ant (if ant=NIL inserts at beginning)

GcPoints: PROC[start: Point, lim: Point ← NIL];
Returns to the pool all point records from start (incl.) to lim (excl).

- - - - REFERENCE FRAMES

Frame: TYPE = RECORD [org, hor, ver: Point]; -- reference frame for constraints & c

nullFrame: Frame = [NIL, NIL, NIL]; -- null reference frame

- - - - CONSTRAINTS

Constr: TYPE = REF ConstrRec; -- to some kind of constraint record

ConstrKind: TYPE = {hor, ver, para, perp, cong, at, ccw}; -- kind of constraint

ConstrList: TYPE = RECORD [first, last: Constr];
Connected by link field; last.link always NIL. Both NIL if list is empty.

ConstrRec: TYPE = RECORD

[link: Constr,
frame: Frame ← [NIL, NIL, NIL], -- reference frame
constr: SELECT kind: ConstrKind FROM

hor =>  -- Constrains (i,j) to be horizontal
[i, j: Point ← NIL],
ver =>  -- Constrains (i,j) to be vertical
[i, j: Point ← NIL],
para => -- Constrains (i,j), (k,l) to be parallel
[i, j, k, l: Point ← NIL],
perp => -- Constrains (i,j), (k,l) to be perpendicular (relative to the given frame)
[i, j, k, l: Point ← NIL],
cong => -- Constrains segments (i,j), (k,l) to be congruent (relative to the given frame)
[i, j, k, l: Point ← NIL],
at => -- Constrains p to have coordinates (x,y) (relative to the given frame)
[p: Point ← NIL,
coords: Coords ← [0, 0]],
ccw =>  -- Constrains (i,j,k) to be counterclockwise (rel to frame)
[i, j, k: Point ← NIL],
ENDCASE];

HorConstr: TYPE = REF hor ConstrRec;

VerConstr: TYPE = REF ver ConstrRec;

ParaConstr: TYPE = REF para ConstrRec;

PerpConstr: TYPE = REF perp ConstrRec;

CongConstr: TYPE = REF cong ConstrRec;

AtConstr: TYPE = REF at ConstrRec;

CcwConstr: TYPE = REF ccw ConstrRec;

The following procedures create new constraint records of specific types (they allocate from pool if available):

NewHor
: PROC [i,j: Point] RETURNS [cp: HorConstr];

NewVer
: PROC [i,j: Point] RETURNS [cp: VerConstr];

NewPara
: PROC [i,j,k,l: Point] RETURNS [cp: ParaConstr];

NewPerp
: PROC [i,j,k,l: Point] RETURNS [cp: PerpConstr];

NewCong
: PROC [i,j,k,l: Point] RETURNS [cp: CongConstr];

NewAt: PROC [p: Point, coords: Coords] RETURNS [cp: AtConstr];

NewCcw
: PROC [i,j,k: Point] RETURNS [cp: CcwConstr];

DeleteConstr
: PROC [c, ant: Constr, list: ConstrList] RETURNS [newList: ConstrList];
Deletes the constraint c from the list. The parameter ant is optional; if not NIL, it must be that ant.link = c.

InsertConstr
: PROC [c, ant: Constr, list: ConstrList] RETURNS [newList: ConstrList];
Inserts the constraint c into the list, just after ant (if ant=NIL inserts at beginning)

GcConstrs: PROC[start: Constr, lim: Constr ← NIL];
Returns to the pool all constraint records from start (incl.) to lim (excl).

- - - - ACTIONS

Action: TYPE = REF ActionRec; -- to some kind of action record

ActionList: TYPE = RECORD [first, last: Action];
Connected by link field; last.link always NIL. Both NIL if list is empty.

ActionKind: TYPE = {draw, print, call, font, size, face, justify};

ActionArgs: TYPE = LIST OF REF ANY; -- arguments of actions:

draw: [p, q: Point] or [p, r, s, q: Point]
print: [p: Point, rope: ROPE]
call: [func: ATOM, p1, p2, ..., pn: Point] (where func is function name)
font: [font: ROPE]
size: [size: REF INT]
face: [face: ATOM] (one of $regular, $bold, $italic, $boldItalic)
justify: [justification: ATOM] (one of $left, $center, $right)

ActionRec: TYPE = RECORD
[link: Action,
kind: ActionKind, -- type of action
args: ActionArgs -- arguments of action
];

NewAction
: PROC [kind: ActionKind, args: ActionArgs] RETURNS [ap: Action];
Creates a new action record (allocates from pool if available).

DeleteAction
: PROC [a, ant: Action, list: ActionList] RETURNS [newList: ActionList];
Deletes the action a from the list. The parameter ant is optional; if not NIL, it must be that ant.link = a.

InsertAction
: PROC [a, ant: Action, list: ActionList] RETURNS [newList: ActionList];
Inserts the action a into the list, just after ant (if ant=NIL inserts at beginning)

GcActions: PROC[start: Action, lim: Action ← NIL];
Returns to the pool all action records from start (incl.) to lim (excl).
Also collects the top-level cells in the args list of each action.

- - - - LISTS

List: TYPE = LIST OF REF ANY;

Cons: PROC [first: REF ANY, rest: List] RETURNS [cons: List];
Same as built-in CONS, but allocates from pool if available.

GcList: PROC[start: List, lim: List ← NIL];
Returns to the pool all top-level cells in the list, from start (incl) to lim (excl).

END.

Edited by Stolfi, March 7, 1984 3:06:21 am PST
Tioga formatting

Edited by Stolfi, April 11, 1984 9:09:52 pm PST
Cleaned out PointRec, made constraints and actions into variant records

- - - - JUNK

HasDef: PUBLIC PROC [name: REF ANY, defList: LIST OF REF ANY] RETURNS [BOOL];

constructionList: PUBLIC LIST OF ApplyRecord;

AddX: PUBLIC PROC [f: REF ANY, args:LIST OF PointPtr];
-- adds (f, args) to constructionList, which is a list of ApplyRecords

ApplyRecord: TYPE = RECORD [f: REF ANY, args: LIST OF PointPtr];

Basis: TYPE = REF BasisRec;

BasisRec: TYPE = RECORD[head:TangentVector ← NIL, tail:Basis];

TangentVector: TYPE = REF TvRec;

TvRec: TYPE = RECORD[head:PointPtr ← NIL, x, y: REAL ← 0, tail:TangentVector];

PushState: PUBLIC PROCEDURE;

PopState: PUBLIC PROCEDURE;

NewPoint: PROCEDURE RETURNS [r: PointPtr];

GcPoint: PROCEDURE[p:PointPtr];

NewEdge: PROCEDURE RETURNS [r: EdgePtr];

GcEdge: PROCEDURE[p:EdgePtr];

NewArc: PROCEDURE RETURNS [r: ArcPtr];

GcArc: PROCEDURE[p:ArcPtr];

NewLine: PROCEDURE RETURNS [r: LinPtr];

GcLine: PROCEDURE[p:LinPtr];

NewString: PROCEDURE RETURNS [r: StringPtr];

GcString: PROCEDURE[p: StringPtr];

NewCong: PROCEDURE RETURNS [r: CongPtr];

GcCong: PROCEDURE[p:CongPtr];

NewHor: PROCEDURE RETURNS [r: HorPtr];

GcHor: PROCEDURE[p:HorPtr];

NewVer: PROCEDURE RETURNS [r: VerPtr];

GcVer: PROCEDURE[p:VerPtr];

NewCC: PROC RETURNS [r: CCPtr];

GcCC: PROC[p: CCPtr];

NewBasis: PROC RETURNS [Basis];

GcBasis: PROC[Basis];

NewTv: PROC RETURNS [TangentVector];

GcTv: PROC[TangentVector];

AddHor: PROC[a,b:PointPtr];

AddVer: PROC[a,b:PointPtr];

AddCong: PROC[a,b,c,d:PointPtr];

AddLin: PROC[a,b,c,d:PointPtr];

AddPoint: PROC [x,y:REAL] RETURNS [PointPtr];

FindPoint: PROC [x,y:REAL] RETURNS [PointPtr];

AddEdge: PROC[a,b:PointPtr];

AddArc: PROC[a,b,c,d:PointPtr];

AddString: PROC [c,d: PointPtr, h, w, dep : REAL,
stringText: Rope.ROPE, stringFont: Graphics.FontRef,
fontName: Rope.ROPE, fontSize: INT, bold, italic: BOOL];

AddCC: PROC [a, b, c: PointPtr];

InitJunoStorage: PROC;

ResetJunoStorage: PROC; -- reclaims all records.

pointLpad, pointRpad: PointPtr; -- The lists of points, edges, arcs
edgeLpad, edgeRpad: EdgePtr; -- line constraints, and cong. constraints
arcLpad, arcRpad: ArcPtr; -- are padded on both sides.
lineLpad, lineRpad: LinPtr;
congLpad, congRpad: CongPtr;
stringLpad, stringRpad: StringPtr;
horLpad, horRpad: HorPtr;
verLpad, verRpad: VerPtr;
ccLpad, ccRpad: CCPtr;