<< HerculesAlgebra.mesa>> << Last Edited by: Stolfi, February 25, 1984 5:10:25 am PST>> << Was JunoAlgebra (+ pieces from other modules)>> <> <> << 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. <> 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.