HerculesAlgebra.mesa

Last Edited by: Stolfi, February 25, 1984 5:10:25 am PST

Was JunoAlgebra (+ pieces from other modules)
written July, 1982 by Donna M. Auguste and Greg Nelson
Last Edited by: Gnelson, October 11, 1983 4:15 pm

Evaluator/interpreter for symbolic expressions. This module defines the semantics of Juno/Hercules language (and, implicitly, its syntax)

To do:
Procedure for expanding an IF statement or a simple statement and adding its contents to the current image. (February 15, 1984 1:21 am)

To do:
Move global alist to HerculesImage, and remove backup mechanism from Apply and Eval; instead, pass them the global alist and let them elongate it. This not good: it requires funargs to be closed with respect to global alist too. (February 10, 1984 3:44 am)

To do
: add new operators and constructs to parser (February 10, 1984 2:48 am)

HerculesAlgebra: DEFINITIONS

=

BEGIN

- - - - RESERVED ATOMS
and: READONLY ATOM;
approx: READONLY ATOM; -- '~' symbol (hint/initial value for local variable)
assign: READONLY ATOM; -- ':=' symbol
at: READONLY ATOM; -- 'at' constraint
blow: READONLY ATOM; -- '!' operator (open up a list into a sequence of values)
ccw: READONLY ATOM;
colon: READONLY ATOM; -- ':' infix operator (lambda expression)
comma: READONLY ATOM; -- ',' (concatenate sequences of values)
cong: READONLY ATOM;
div: READONLY ATOM; -- 'div' (integer division) operator
do: READONLY ATOM;
draw: READONLY ATOM;
ends: READONLY ATOM;
equals: READONLY ATOM; -- '=' predicate
fill: READONLY ATOM;
font: READONLY ATOM; -- infix; sets font for following prints
gtr: READONLY ATOM; -- '>' predicate
hor: READONLY ATOM;
if: READONLY ATOM;
is: READONLY ATOM;
leftBrack: READONLY ATOM;
leftPren: READONLY ATOM;
lss: READONLY ATOM; -- '<' predicate
minus: READONLY ATOM; -- '-' operator (unary or binary)
mod: READONLY ATOM; -- modulus operator (binary)
obox: READONLY ATOM; -- "or" ("else if") box to separate alternatives in if/do statements
paint: READONLY ATOM;
para: READONLY ATOM;
perp: READONLY ATOM;
plus: READONLY ATOM; -- the '+' operator (unary or binary)
print: READONLY ATOM;
rel: READONLY ATOM;
rightArrow: READONLY ATOM; -- '->' ("then") operator for if/do sataements
semicolon: READONLY ATOM;
size: READONLY ATOM; -- infix; sets font size for folowing prints
skip: READONLY ATOM; -- 'skip' ("do nothing") statement
slash: READONLY ATOM; -- '/' (real division) operator
stroke: READONLY ATOM;
style: READONLY ATOM; -- infix; sets style (bold, italic, etc) for folowing prints
suchThat: READONLY ATOM; -- '|' ("such that") operator
times: READONLY ATOM; -- '*' (product) operator
true: READONLY ATOM; -- 'true' atom (for empty constraint lists)
ver: READONLY ATOM;
width: READONLY ATOM;

- - - - GLOBAL ALIST

The global alist is used as a backup alist by the interpreter. It is where the parsed procedures are deposited (as FunVals), and where predefined constants (such as the standard colors) are stored. The alist passed to Eval and Apply is automatically extended by the globals list.

globals
: Alist; -- (name value name value ... )

AddGlobalDef
: PUBLIC PROC [name: ATOM, value: Value];
-- Adds a new (name, value) pair to the list of procedures.

basicGlobals
: READONLY Alist; -- standard tail of global alist, set up by initialization.

- - - - SYMBOLIC EXPRESSION EVALUATION

Results: TYPE = LIST OF Se.
The evaluation of a symbolic expression results in a list of zero or more values.

EvApError: ERROR [why: ROPE]; -- raised by Eval/Apply

Eval: PROC [e: Se, alist: Alist] RETURNS [results: Results];
-- Evaluates a Juno expression with the variable bindings specified by the given alist.
-- The given tail, if given, is appended without any change to the results of e.

Apply
: PROC [function: Se, args: Results] RETURNS [results: Results];
-- Applies a "unary" function (funVal, or primitive prefix/postfix operation)
-- to the given arguments. The arguments and the function are assumed to be evaluated.

ApplyBinary
: PROC [function: Se, largs, rargs: Results] RETURNS [results: Results];
-- Same as above, for "binary" function (currently, only primitive infix operations).

- - - - SOME USEFUL MOLDS AND PREDICATES

pointMold: READONLY Mold; -- a point is a list of two NumCells

frameMold: READONLY Mold; -- a frame is a list of one to three points

edgeMold: READONLY Mold; -- an edge is a list of two points.

arcMold: READONLY Mold; -- an arc is a list four points.

pathMold: READONLY Mold; -- a path is a list of one or more edges and/or arcs.

NumPair: TYPE = RECORD [x, y: NumPtr];

ToNumPair: PROC [e: Se] RETURNS [p: NumPair];
-- Narrows e to a point (a list of two NumPtr), and returns them.

Frame: TYPE = RECORD
[np: [0..3], -- number of points in frame
org, hor, ver: NumPair -- origin and axis of a frame
];

nullFrame: READONLY Frame; -- for convenience: [[NIL, NIL], [NIL, NIL], [NIL, NIL]]

ToFrame
: PROC [e: Se] RETURNS [frame: Frame];
-- Narrows e to a list of one, two or three points and
-- returns their coordinates as a Frame.

ToReal
: PROC [e: Se] RETURNS [r: REAL];
-- Narrows e to NumPtr and extracts its val field.

Coords: TYPE = RECORD [x, y: REAL]; -- usually represents a point

ToCoords
: PROC [e: Se] RETURNS [c: Coords];
-- Narrows e to a point (a list of two NumPtr), and returns their val's.

- - - - COORDINATE TRANSFORMATION MATRICES

Matrix: TYPE = ARRAY [1..3] OF ARRAY [1..3] OF REAL;

GetFrameMatrix
: PROC [frame: Frame, m: REF Matrix ← NIL]
RETURNS [mr: REF Matrix];
-- Returns the coordinate transform matrix for the frame determined
-- by the points
org, xP, yP (the last one or two may be NIL).

InvertMatrix
: PROC [m: REF Matrix, work: REF Matrix ← NIL]
RETURNS [mInv: REF Matrix, singular: BOOL];
-- Inverts m^ into mInv^ by pivoting three times; or sets "singular" flag.

MultiplyMatrix
: PUBLIC PROC [ma, mb: REF Matrix, mc: REF Matrix ← NIL]
RETURNS [mr: REF Matrix];
-- Multiply ma^ * mb^.

ComputeTransform
: PROC
[src, dest: Frame, mm: REF Matrix ← NIL]
RETURNS [mat: REF Matrix, singular: BOOL];
-- Computes the transform matrix that maps src to dest
-- column vectors with third component 1. Hence we compute the inverse
-- of src and multipy on the left by dest.
-- The matrix mm is optional, and used to store the result if given (saves alloc.)

ComputeSomeTransform
: PROC
[src, dest: Frame, mm: REF Matrix ← NIL]
RETURNS [mat: REF Matrix, singular: BOOL];
-- Similar to the above, except that tries simpler transforms (by dropping
-- last one or two pairs) if the given frames specify a singular transformation.

TransformPoint
: PROC [x, y: REAL, mat: REF Matrix] RETURNS [xT, yT: REAL];
-- Transforms p by the given matrix

END
.