DIRECTORY Convert USING [Error, RealFromRope], Graph USING [Entity, EntityGroupList, EntityList, NtNan, SegmentDataList, ROPE], GraphPrivate USING [GraphAtomProc, PaintAllCurves, PaintEntity], GraphUtil USING [BlinkMsg, ControllerViewerExits, GraphViewerExits, NotANumber, SetSegments, UpdateSegAll, UpdateSegEnd], Real USING [ExceptionFlags, RealException], RealFns USING [ArcTan, ArcTanDeg, Cos, CosDeg, Exp, Ln, Power, Root, Sin, SinDeg, SqRt, Tan, TanDeg], Rope USING [Concat, IsEmpty], ViewerTools USING [GetContents]; GraphOperations: CEDAR PROGRAM IMPORTS Convert, GraphPrivate, GraphUtil, Real, RealFns, Rope, ViewerTools EXPORTS GraphPrivate = { OPEN Graph, GraphPrivate, GraphUtil; DbFactor: REAL = 20.0/2.30258509; OpType: TYPE = {unary, binary, original}; UnaryProc: TYPE = PROC [a: REAL] RETURNS [r: REAL]; BinaryProc: TYPE = PROC [a, b: REAL] RETURNS [r: REAL]; Operate: PUBLIC GraphAtomProc = { IF ControllerViewerExits[handle] AND GraphViewerExits[handle] THEN { OPEN handle; ActOnY: PROC [et: Entity, op: OpType] = { IF opType = original THEN UpdateSegAll[et, et.oldValues] ELSE { FOR sdl: SegmentDataList _ et.segments, sdl.rest UNTIL sdl = NIL DO sdl.first.end _ IF opType = unary THEN unaryProc[sdl.first.end] ELSE binaryProc[sdl.first.end, arg]; ENDLOOP; SetSegments[et]; }; }; -- ActOnY ok: BOOL _ TRUE; -- may be false only if there is problem converting argument for binary operation. unaryProc: UnaryProc _ NIL; binaryProc: BinaryProc _ NIL; arg: REAL; opType: OpType _ original; entity: Entity _ chart.selectedEntity; IF entity = NIL THEN RETURN; SELECT atom FROM $Sign, $Abs, $Reciprocal, $Exponential, $NaturalLog, $DB, $SqRt, $Sine, $Cosine, $Tangent, $ArcTan => { -- unary procs opType _ unary; unaryProc _ SELECT atom FROM $Sign => Sign, $Abs => Abs, $Reciprocal => Recip, $Exponential => Exp, $NaturalLog => Ln, $DB => DB, $SqRt => SqRt, $Sine => IF controller.angle = radians THEN Sin ELSE SinDeg, $Cosine => IF controller.angle = radians THEN Cos ELSE CosDeg, $Tangent => IF controller.angle = radians THEN Tan ELSE TanDeg, ENDCASE => IF controller.angle = radians THEN ArcTan ELSE ArcTanDeg; }; -- unary procs $Plus, $Minus, $Multiply, $Divide, $Root, $Power => { ENABLE Convert.Error => { -- binary procs BlinkMsg["Problem parsing the argument."]; ok _ FALSE; CONTINUE}; argRope: ROPE _ ViewerTools.GetContents[controller.argument]; opType _ binary; binaryProc _ SELECT atom FROM $Plus => Plus, $Minus => Minus, $Multiply => Multiply, $Divide => Divide, $Root => Root, ENDCASE => Power; IF argRope.IsEmpty[] THEN {BlinkMsg["Argument is not specified."]; RETURN}; arg _ Convert.RealFromRope[argRope]; -- may raise Convert.Error. SELECT atom FROM $Divide => { ok _ arg # 0.0; IF NOT ok THEN BlinkMsg["Can't divide by zero. Operation not performed."]; }; $Root => { ok _ arg # 0.0; IF NOT ok THEN BlinkMsg["Can't do it with index zero. Root operation not performed."]; }; $Power => { ok _ arg <= 0.0; IF NOT ok THEN BlinkMsg["Base must be nonnegative. Power operation not performed."]; }; ENDCASE; }; -- binary procs ENDCASE; -- original IF ok THEN SELECT controller.operand FROM y => { FOR el: EntityList _ graph.entityList, el.rest UNTIL el = NIL DO IF el.first = entity THEN { PaintEntity[handle, erase, entity, FALSE]; ActOnY[entity, opType]; PaintEntity[handle, paint, entity, FALSE]; EXIT; }; ENDLOOP; }; plottedYs => { FOR el: EntityList _ graph.entityList, el.rest UNTIL el = NIL DO ActOnY[el.first, opType]; ENDLOOP; PaintAllCurves[handle, TRUE]; }; allX => { FOR egl: EntityGroupList _ entityGroupList, egl.rest UNTIL egl = NIL DO IF opType = original THEN UpdateSegEnd[egl.first.x, egl.first.x.oldValues] ELSE FOR sdl: SegmentDataList _ egl.first.x.segments, sdl.rest UNTIL sdl = NIL DO sdl.first.end _ IF opType = unary THEN unaryProc[sdl.first.end] ELSE binaryProc[sdl.first.end, arg]; ENDLOOP; ENDLOOP; FOR el: EntityList _ graph.entityList, el.rest UNTIL el = NIL DO SetSegments[el.first]; ENDLOOP; PaintAllCurves[handle, TRUE]; }; ENDCASE; }; -- viewers exist }; -- Operate ExceptionRope: PROC [flags: Real.ExceptionFlags] RETURNS [rope: ROPE _ NIL] = { IF flags[fixOverflow] THEN rope _ rope.Concat["fixOverflow. "]; IF flags[inexactResult] THEN rope _ rope.Concat["inexactResult. "]; IF flags[invalidOperation] THEN rope _ rope.Concat["invalidOperation. "]; IF flags[divisionByZero] THEN rope _ rope.Concat["divisionByZero. "]; IF flags[overflow] THEN rope _ rope.Concat["overflow. "]; IF flags[underflow] THEN rope _ rope.Concat["underflow. "]; }; Sign: UnaryProc = {RETURN[IF NotANumber[a] THEN NtNan ELSE -a]}; Abs: UnaryProc = {RETURN[IF NotANumber[a] THEN NtNan ELSE ABS[a]]}; Recip: UnaryProc = { msg: ROPE _ NIL; IF a = 0 THEN msg _ "Divide by zero." ELSE IF NotANumber[a] THEN r _ NtNan ELSE { ENABLE { Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; }; r _ 1.0/a; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Recip Exp: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE IF a > 88.7228 THEN {msg _ "Overflow."} ELSE { ENABLE { Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; }; r _ RealFns.Exp[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Exp Ln: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR a <= 0.0 THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.Ln[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Ln DB: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR a <= 0.0 THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ DbFactor*RealFns.Ln[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- DB SqRt: UnaryProc = { msg: ROPE _ NIL; IF a = 0.0 THEN r _ 0.0 ELSE IF NotANumber[a] OR a < 0.0 THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.SqRt[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- SqRt Sin: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.Sin[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Sin SinDeg: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.SinDeg[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- SinDeg Cos: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.Cos[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Cos CosDeg: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.CosDeg[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- CosDeg Tan: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.Tan[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Tan TanDeg: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.TanDeg[a]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- TanDeg ArcTan: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.ArcTan[a, 1.0]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- ArcTan ArcTanDeg: UnaryProc = { msg: ROPE _ NIL; IF NotANumber[a] THEN {msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.ArcTanDeg[a, 1.0]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- ArcTanDeg Plus: BinaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR NotANumber[b] THEN msg _ "Invalid operand." ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ a + b; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Plus Minus: BinaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR NotANumber[b] THEN msg _ "Invalid operand." ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ a - b; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Minus Multiply: BinaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR NotANumber[b] THEN msg _ "Invalid operand." ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ a * b; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Multiply Divide: BinaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR NotANumber[b] THEN msg _ "Invalid operand." ELSE IF b = 0.0 THEN msg _ "Divide by zero." ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ a / b; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Divide Root: BinaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR NotANumber[b] THEN msg _ "Invalid operand." ELSE IF a = 0.0 THEN r _ 0.0 ELSE IF a < 0.0 THEN msg _ "Invalid operation." ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.Root[b, a]; -- note the order of arguments !! }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Root Power: BinaryProc = { msg: ROPE _ NIL; IF NotANumber[a] OR NotANumber[b] THEN msg _ "Invalid operand." ELSE IF a = 0.0 THEN r _ 0.0 ELSE IF b = 0.0 THEN {IF a # 0.0 THEN r _ 1.0 ELSE msg _ "Invalid operation."} ELSE { ENABLE Real.RealException => {msg _ ExceptionRope[flags]; CONTINUE}; r _ RealFns.Power[a, b]; }; IF msg # NIL THEN {BlinkMsg[msg]; r _ NtNan}; }; -- Power }. LOG. SChen, October 11, 1985 1:48:06 am PDT, created. ²GraphOperations.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last Edited: Sweetsun Chen, November 15, 1985 6:09:32 pm PST constants Use this loop to make sure entity is on the plotted list, graph.entityList. unary procs RealError => RaiseError[$Other, "Real resume error."]; RealError => {msg _ "Real resume error."; CONTINUE}; -- ? binary procs -- a is arg and b is index !! a is base and b is exponent. Κ Ϊ˜J™Jšœ Οmœ1™<šœ ™ Icode™/—J˜šΟk ˜ Jšœžœ˜$Jšœžœ?žœ˜PJšœ žœ.˜@Jšœ žœj˜yJšœžœ!˜+JšœžœX˜eJšœžœ˜Jšœ žœ˜ —J˜šœžœž˜JšžœC˜JJšžœžœ ˜=J˜—J™ Jšœ žœ˜!J˜Jšœžœ˜)Jš Οn œžœžœžœžœžœ˜3Jš Ÿ œžœžœžœžœžœ˜7J˜šœ žœ˜!šžœžœžœžœ˜QšŸœžœ˜)Jšžœžœ˜8šžœ˜šžœ.žœžœž˜Cšœžœžœ˜?Jšžœ ˜$—Jšžœ˜—Jšœ˜J˜—JšœΟc ˜ J˜—Jšœžœžœ R˜cJšœžœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ&˜&Jšžœ žœžœžœ˜J˜šžœž˜šœh ˜vJ˜šœ žœž˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜Jšœ žœžœžœ˜Jšœ žœžœžœ˜?Jšžœžœžœžœ ˜D—Jšœ ˜—J™šœ5˜5šžœ ˜)Jšœ0žœžœ˜A—Jšœ žœ0˜=J˜šœ žœž˜Jšœ6˜6Jšœ!žœ ˜3—Jšžœžœ*žœ˜KJšœ% ˜@šžœž˜˜ J˜Jšžœžœžœ<˜JJ˜—˜ J˜JšžœžœžœH˜VJ˜—šœ ˜ Jšœ˜JšžœžœžœF˜TJ˜—Jšžœ˜—Jšœ ˜—J˜Jšžœ  ˜—J˜šžœžœžœž˜)˜šžœ,žœžœž˜@JšœK™Kšžœžœ˜Jšœ#žœ˜*J˜Jšœ#žœ˜*Jšžœ˜J˜—Jšžœ˜—J˜—˜šžœ,žœžœž˜@Jšœ˜Jšžœ˜—Jšœžœ˜J˜—˜ šžœ2žœžœž˜GJšžœžœ1˜Jš žœžœ7žœžœž˜Qšœžœžœ˜?Jšžœ ˜$—Jšžœ˜—Jšžœ˜—šžœ,žœžœž˜@Jšœ˜Jšžœ˜—Jšœžœ˜J˜—Jšžœ˜—Jšœ ˜—Jšœ  ˜ J˜š Ÿ œžœžœžœžœ˜OJšžœžœ%˜?Jšžœžœ'˜CJšžœžœ*˜IJšžœžœ(˜EJšžœžœ"˜9Jšžœžœ#˜;J˜J˜—J™ š œžœžœžœžœ˜@J˜—š œžœžœžœžœžœ˜CJ˜—šœ˜Jšœžœžœ˜Jšžœžœ˜%Jšžœžœžœ ˜$šžœ˜šžœ˜Jšœ3žœ˜=Jšœ6™6J˜—J˜ J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2Jšžœžœ žœ˜,šžœ˜šžœ˜Jšœ3žœ˜=Jšœ*žœ ™9J˜—J˜J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ žœ˜>šžœ˜Jšžœ4žœ˜DJ˜J˜—Jšžœžœžœ˜-Jšœ ˜J˜—šœ˜Jšœžœžœ˜Jšžœžœ žœ˜>šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ ˜J˜—šœ˜Jšœžœžœ˜Jšžœ žœ˜Jšžœžœžœ žœ˜Bšžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ  ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ  ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ  ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ  ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœ˜2šžœ˜Jšžœ4žœ˜DJšœ˜J˜—Jšžœžœžœ˜-Jšœ  ˜J˜—J™ ˜Jšœžœžœ˜Jšžœžœžœ˜?šžœ˜Jšžœ4žœ˜DJ˜ J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—˜Jšœžœžœ˜Jšžœžœžœ˜?šžœ˜Jšžœ4žœ˜DJ˜ J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—šœ˜Jšœžœžœ˜Jšžœžœžœ˜?šžœ˜Jšžœ4žœ˜DJ˜ J˜—Jšžœžœžœ˜-Jšœ  ˜J˜—šœ˜Jšœžœžœ˜Jšžœžœžœ˜?Jšžœžœ žœ˜,šžœ˜Jšžœ4žœ˜DJ˜ J˜—Jšžœžœžœ˜-Jšœ  ˜ —J˜˜J™Jšœžœžœ˜Jšžœžœžœ˜?Jšžœžœ žœ˜Jšžœžœ žœ˜/šžœ˜Jšžœ4žœ˜DJšœ !˜9J˜—Jšžœžœžœ˜-Jšœ ˜ J˜—˜Jšœ™Jšœžœžœ˜Jšžœžœžœ˜?Jšžœžœ žœ˜Jš žœžœ žœžœ žœ žœ˜Nšžœ˜Jšžœ4žœ˜DJ˜J˜—Jšžœžœžœ˜-Jšœ ˜ ——J˜J˜šžœ˜J˜0—J˜—…—&˜6$