<< JunoAlgebra.mesa>> <<>> <> <> <> <> <> << This module is concerned with the interpretation of Juno symbolic expressions. It defines the semantics of the Juno language.>> DIRECTORY JunoStorage USING [Point, Coords], Rope USING [ROPE]; JunoAlgebra: DEFINITIONS = BEGIN OPEN Stor: JunoStorage; << - - - - SYMBOLIC EXPRESSIONS >> Se: TYPE = REF ANY; -- Symbolic Expression. Either: << ATOM (variable, operator, or function name) REF REAL, REF INT ROPE LIST OF Se of the form (operator arg) or (operator arg arg)>> << - - - - VALUES >> Value: TYPE = REF ANY; -- the result of evaluating a Symbolic Expression. Either: << REF REAL, REF INT ROPE Point (see JunoStorage) LIST OF Value>> ValueList: TYPE = LIST OF Value; << - - - - IMPORTED TYPES>> Point: TYPE = Stor.Point; Coords: TYPE = Stor.Coords; << - - - - RESERVED ATOMS >> and: READONLY ATOM; approx: READONLY ATOM; -- '~' symbol (hint/initial value for local variable) assign: READONLY ATOM; -- ':=' symbol at: READONLY ATOM; -- 'at' constraint ccw: READONLY ATOM; colon: READONLY ATOM; -- ':' infix operator (lambda expression) comma: READONLY ATOM; -- ',' (concatenate sequences of values) cong: READONLY ATOM; dec: READONLY ATOM; -- decrement by 1 do: READONLY ATOM; draw: READONLY ATOM; ends: READONLY ATOM; face: READONLY ATOM; -- infix; sets face (bold, italic, etc) for folowing prints fill: READONLY ATOM; font: READONLY ATOM; -- infix; sets font for following prints hor: READONLY ATOM; if: READONLY ATOM; inc: READONLY ATOM; -- increment by one justified: READONLY ATOM; -- infix; sets justification (left, center, right) for folowing prints. lambda: READONLY ATOM; -- infix; separates parm list from body in lambdas (faked for now). leftPren: READONLY ATOM; minus: READONLY ATOM; -- '-' operator (unary or binary) obox: READONLY ATOM; -- "or" ("else if") box to separate alternatives in if/do statements paint: READONLY ATOM; para: READONLY ATOM; perp: READONLY ATOM; 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 stroke: READONLY ATOM; suchThat: READONLY ATOM; -- '|' (separates declaations from constraints) true: READONLY ATOM; -- 'true' atom (for empty constraint lists) ver: READONLY ATOM; width: READONLY ATOM; << - - - - ALISTS >> AList: TYPE = LIST OF REF ANY; -- Association list. << Of the form (atom value atom value ... atom value) >> GetDef: PROC [name: ATOM, alist: AList] RETURNS [value: Value]; <> AddDef: PROC [name: ATOM, value: Value, alist: AList] RETURNS [newAlist: AList]; <> << - - - - EXPRESSION EVALUATION >> << Comand mode vs. eval mode:>> << The cmd flag in Eval and Apply specifies that the given Se should be interpreted as an executable command, rather than a value -returning expression.>> << If cmd = false, an atomic expr is looked up in the varable alist, and the result returned without further evaluations. If cmd=FALSE, atomic exprs are looked up in the proc file alist; the result must be a parameterless lambda, that is evaluated again (In juno, a call to a parameterless procedure Foo is written ``Foo'' instead of "Foo()"). >> << Some operations (like print and draw) are allowed only if cmd=TRUE; conversely, others (such as unary minus) are allowed only when cmd=FALSE. Note that function arguments are always evaluated with cmd=FALSE, and the left part of "A; B" is always evaluated with cmd=TRUE.>> Eval: PROC [expr: Se, alist: AList, cmd: BOOL _ FALSE] RETURNS [value: Value]; <> Apply: PROC[op: Se, args: ValueList, cmd: BOOL _ FALSE] RETURNS [value: Value]; <> <> < ...) ).>> EvalError: SIGNAL [what: Rope.ROPE] RETURNS [value: Value]; <> << - - - - PROCEDURE CALL>> Call: PROC[func: ATOM, args: ValueList]; <> << - - - - MISCELLANEOUS SUPPORT ROUTINES >> Car: PROC [r: Se] RETURNS [Se]; Cdr: PROC [r: Se] RETURNS [Se]; Cadr: PROC [r: Se] RETURNS [Se]; Caddr: PROC [r: Se] RETURNS [Se]; Cddr: PROC [r: Se] RETURNS [Se]; END. << - - - - JUNK >> << Shouldn't this be in the parser world?>> VerdictAndCulprit: TYPE = RECORD [verdict: Verdict, culprit: Se]; <> Verdict: TYPE = {Yes, No, OfCourseNot}; -- Yes == innocent WellFormedDef: PUBLIC PROC [f: Se] RETURNS [VerdictAndCulprit];