<> <> <> DIRECTORY MathRules USING [AtomBoxProc, AtomPaintProc, CompoundBoxProc, CompositionProc, AtomToRopeProc, Size], MathBox, MathTypes USING [Style, AtomValue, AtomValueRep], MathDB USING [LookupAtomClass, LookupCompoundClass, notFound], ImagerFont USING [Extents], Vector USING [VEC], Rope USING [ROPE], MathExpr; MathExprImpl: CEDAR PROGRAM IMPORTS MathDB EXPORTS MathExpr ~ BEGIN <> ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector.VEC; BOX: TYPE ~ MathBox.BOX; Style: TYPE ~ MathTypes.Style; AtomValue: TYPE ~ MathTypes.AtomValue; AtomValueRep: TYPE ~ MathTypes.AtomValueRep; AtomBoxProc: TYPE ~ MathRules.AtomBoxProc; AtomPaintProc: TYPE ~ MathRules.AtomPaintProc; CompoundBoxProc: TYPE ~ MathRules.CompoundBoxProc; CompositionProc: TYPE ~ MathRules.CompositionProc; AtomToRopeProc: TYPE ~ MathRules.AtomToRopeProc; Size: TYPE ~ MathRules.Size; TaggedMathExpr: TYPE ~ MathExpr.TaggedMathExpr; ExprFlavors: TYPE ~ MathExpr.ExprFlavors; AtomClass: TYPE ~ MathExpr.AtomClass; AtomClassRep: TYPE ~ MathExpr.AtomClassRep; AtomFlavor: TYPE ~ MathExpr.AtomFlavor; CompoundClass: TYPE ~ MathExpr.CompoundClass; CompoundClassRep: TYPE ~ MathExpr.CompoundClassRep; Argument: TYPE ~ MathExpr.Argument; Symbol: TYPE ~ MathExpr.Symbol; MatrixFlavor: TYPE ~ MathExpr.MatrixFlavor; <> <<>> <> MathExprRep: PUBLIC TYPE ~ RECORD [ SELECT type:* FROM atom => [ class: AtomClass, -- atomic data type value: AtomValue -- atomic value, e.g. integer as rope ], compound => [ class: CompoundClass, -- compound operation class, e.g. summation or product subExprs: LIST OF TaggedMathExpr _ NIL -- class operation arguments ], matrix => [ flavor: MatrixFlavor, -- type of matrix op, e.g. determinant or matrix, etc. nRows, nCols: INT, -- matrix size as rows x cols elements: LIST OF TaggedMathExpr _ NIL, -- matrix elements openSym, closeSym: EXPR, -- left and right brackets or parentheses space: EXPR -- space to use between elements ], ENDCASE ]; AtomExprRep: PUBLIC TYPE ~ atom MathExprRep; CompoundExprRep: PUBLIC TYPE ~ compound MathExprRep; MatrixExprRep: PUBLIC TYPE ~ matrix MathExprRep; <> EXPR: TYPE ~ REF MathExprRep; AtomEXPR: TYPE ~ REF AtomExprRep; CompoundEXPR: TYPE ~ REF CompoundExprRep; MatrixEXPR: TYPE ~ REF MatrixExprRep; <> <> <<>> MakeArgument: PUBLIC PROC[name: ATOM, aliases: LIST OF ATOM, size: Size] RETURNS[Argument] ~ { <> RETURN[[name: name, aliases: aliases, size: size]]; }; <<>> MakeSymbol: PUBLIC PROC[name: ATOM, aliases: LIST OF ATOM, size: Size, value: EXPR] RETURNS[Symbol] ~ { <> RETURN[[name: name, aliases: aliases, size: size, value: value]]; }; MakeAtomClass: PUBLIC PROC[name: ATOM, flavor: AtomFlavor, style: Style, boxRule: AtomBoxProc, paintRule: AtomPaintProc, cvtRope: AtomToRopeProc] RETURNS[AtomClass] ~ { <> RETURN[NEW[AtomClassRep _ [name: name, flavor: flavor, style: style, boxRule: boxRule, paintRule: paintRule, cvtRope: cvtRope]]]; }; MakeCompoundClass: PUBLIC PROC[name: ATOM, description: ROPE, args: LIST OF Argument, syms: LIST OF Symbol, boxRule: CompoundBoxProc, compBox: CompositionProc, cvtAS: ROPE _ NIL] RETURNS[CompoundClass] ~ { <> RETURN[NEW[CompoundClassRep _ [name: name, description: description, arguments: args, symbols: syms, boxRule: boxRule, compBox: compBox, cvtAS: cvtAS]]]; }; MakeAtomChar: PUBLIC PROC[c: CHAR] RETURNS[AtomValue] ~ { <> RETURN[NEW[char AtomValueRep _ [char[char: [0, ORD[c]]]]]]; }; MakeAtomRope: PUBLIC PROC[r: ROPE] RETURNS[AtomValue] ~ { <> RETURN[NEW[rope AtomValueRep _ [rope[rope: r]]]]; }; MakeAtomBox: PUBLIC PROC[b: ImagerFont.Extents] RETURNS[AtomValue] ~ { <> RETURN[NEW[box AtomValueRep _ [box[box: b]]]]; }; MakeAtomOther: PUBLIC PROC[other: REF ANY] RETURNS[AtomValue] ~ { <> RETURN[NEW[other AtomValueRep _ [other[other: other]]]]; }; <> MakeAtomicExpr: PUBLIC PROC[class: ATOM, value: AtomValue] RETURNS[EXPR] ~ { <> << SIGNALS badAtomClass if class is unrecognized>> <> atomClass: AtomClass _ MathDB.LookupAtomClass[class ! MathDB.notFound => {ERROR badAtomClass}]; RETURN[NEW[atom MathExprRep _ [atom[class: atomClass, value: value]]]]; }; MakeCompoundExpr: PUBLIC PROC[class: ATOM, args: LIST OF TaggedMathExpr] RETURNS[EXPR] ~ { <> << SIGNALS badCompoundClass if class is unrecognized>> << SIGNALS badExprs if exprs has the wrong number or wrong type of elements>> <<>> <> validExprs: LIST OF TaggedMathExpr _ NIL; <> compClass: CompoundClass _ MathDB.LookupCompoundClass[class ! MathDB.notFound => {ERROR badCompoundClass}]; <> <> FOR l: LIST OF Argument _ compClass.arguments, l.rest UNTIL l = NIL DO validExprs _ CONS[GetTaggedExpr[l.first.name, args ! exprNotFound => {ERROR badExprs[l.first.name]}], validExprs]; ENDLOOP; FOR l: LIST OF Symbol _ compClass.symbols, l.rest UNTIL l = NIL DO validExprs _ CONS[[l.first.name, l.first.value], validExprs]; ENDLOOP; <> RETURN[NEW[compound MathExprRep _ [compound[class: compClass, subExprs: validExprs]]]]; }; MakeMatrixExpr: PUBLIC PROC[flavor: MatrixFlavor, nRows, nCols: NAT, elements: LIST OF TaggedMathExpr, openSym, closeSym, space: EXPR] RETURNS[EXPR] ~ { <> << SIGNALS badMatrixSize if nRows or nCols is invalid>> << SIGNALS badMatrix if rows has the wrong number or wrong type of elements>> <> RETURN[NEW[matrix MathExprRep _ [matrix[flavor: flavor, nRows: nRows, nCols: nCols, elements: elements, openSym: openSym, closeSym: closeSym, space: space]]]]; }; <> <<>> GetType: PUBLIC PROC[expr: EXPR] RETURNS[ExprFlavors] ~ { <> << Returns compound if expr is a CompoundEXPR>> WITH expr SELECT FROM a: AtomEXPR => RETURN[atom]; c: CompoundEXPR => RETURN[compound]; m: MatrixEXPR => RETURN[matrix]; ENDCASE => ERROR; }; <<>> GetAtomClass: PUBLIC PROC[expr: AtomEXPR] RETURNS[AtomClass] ~ { <> RETURN[expr.class]; }; GetAtomExpr: PUBLIC PROC[expr: EXPR] RETURNS[AtomEXPR] ~ { <> << Otherwise SIGNALS wrongExprType>> WITH expr SELECT FROM a: AtomEXPR => RETURN[a]; c: CompoundEXPR => ERROR wrongExprType; m: MatrixEXPR => ERROR wrongExprType; ENDCASE => ERROR; }; <<>> GetValue: PUBLIC PROC[expr: AtomEXPR] RETURNS[AtomValue] ~ { <> RETURN[expr.value]; }; GetCompoundClass: PUBLIC PROC[expr: CompoundEXPR] RETURNS[CompoundClass] ~ { <> RETURN[expr.class]; }; GetCompoundExpr: PUBLIC PROC[expr: EXPR] RETURNS[CompoundEXPR] ~ { <> << Otherwise SIGNALS wrongExprType>> WITH expr SELECT FROM a: AtomEXPR => ERROR wrongExprType; c: CompoundEXPR => RETURN[c]; m: MatrixEXPR => ERROR wrongExprType; ENDCASE => ERROR; }; GetMatrixExpr: PUBLIC PROC[expr: EXPR] RETURNS[MatrixEXPR] ~ { <> << Otherwise SIGNALS wrongExprType>> WITH expr SELECT FROM a: AtomEXPR => ERROR wrongExprType; c: CompoundEXPR => ERROR wrongExprType; m: MatrixEXPR => RETURN[m]; ENDCASE => ERROR; }; <<>> GetSubExprs: PUBLIC PROC[expr: CompoundEXPR] RETURNS[LIST OF TaggedMathExpr] ~ { <> RETURN[expr.subExprs]; }; GetMatrixElements: PUBLIC PROC[expr: MatrixEXPR] RETURNS[LIST OF TaggedMathExpr] ~ { <> RETURN[expr.elements]; }; GetMatrixSize: PUBLIC PROC[expr: MatrixEXPR] RETURNS[NAT, NAT] ~ { <> RETURN[expr.nRows, expr.nCols]; }; GetMatrixFlavor: PUBLIC PROC[expr: MatrixEXPR] RETURNS[MatrixFlavor] ~ { <> RETURN[expr.flavor]; }; GetMatrixOpenSym: PUBLIC PROC[expr: MatrixEXPR] RETURNS[EXPR] ~ { <> RETURN[expr.openSym]; }; GetMatrixCloseSym: PUBLIC PROC[expr: MatrixEXPR] RETURNS[EXPR] ~ { <> RETURN[expr.closeSym]; }; <<>> GetMatrixSpace: PUBLIC PROC[expr: MatrixEXPR] RETURNS[EXPR] ~ { <> RETURN[expr.space]; }; <<>> <> GetTaggedExpr: PUBLIC PROC[tag: ATOM, exprs: LIST OF TaggedMathExpr] RETURNS[TaggedMathExpr] ~ { <> << SIGNALS exprNotFound if no association exists.>> <<>> <> FOR l: LIST OF TaggedMathExpr _ exprs, l.rest UNTIL l = NIL DO IF l.first.id = tag THEN RETURN[l.first]; ENDLOOP; <> ERROR exprNotFound; }; <> badAtomClass: PUBLIC ERROR = CODE; badCompoundClass: PUBLIC ERROR = CODE; badExprs: PUBLIC ERROR[reason: ATOM] = CODE; exprNotFound: PUBLIC ERROR = CODE; wrongExprType: PUBLIC ERROR = CODE; invalidReplacement: PUBLIC ERROR = CODE; <<>> END.