<> <> <> DIRECTORY IPBasic USING [Any, Identifier, Integer, maxInteger, Number, Vector, VectorShape], IPConvert USING [AnyToIdentifier, AnyToNumber, AnyToVector, NumberToReal], IPErrors USING [Bug], IPOps USING [], IPReal USING [Ceiling, Floor, Mod, Rem, Round, Trunc], IPVector USING [Get, Shape]; IPOpsImpl: CEDAR PROGRAM IMPORTS IPConvert, IPErrors, IPReal, IPVector EXPORTS IPOps = BEGIN OPEN IPBasic; <<2.4.8 Test operators>> EqNumber: PROC[a, b: Number] RETURNS[BOOL] = { WITH a: a SELECT FROM int => WITH b: b SELECT FROM int => RETURN[a.i=b.i]; real => RETURN[a.i=b.r]; ENDCASE; real => WITH b: b SELECT FROM int => RETURN[a.r=b.i]; real => RETURN[a.r=b.r]; ENDCASE; ENDCASE; ERROR IPErrors.Bug; }; EqIdentifier: PROC[a, b: ATOM] RETURNS[BOOL] = INLINE { RETURN[a=b] }; EqVector: PROC[a, b: Vector] RETURNS[BOOL] = { ashape: VectorShape = IPVector.Shape[a]; bshape: VectorShape = IPVector.Shape[b]; IF ashape#bshape THEN RETURN[FALSE]; FOR i: Integer IN[ashape.l..ashape.l+ashape.n) DO IF NOT Eq[IPVector.Get[a, i], IPVector.Get[b, i]] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE] }; IsNumber: PROC[x: Any] RETURNS[BOOL] = INLINE { RETURN[x.type=number OR x.type=nil] }; Eq: PUBLIC PROC[a, b: Any] RETURNS[BOOL] = { IF IsNumber[a] AND IsNumber[b] THEN RETURN[EqNumber[IPConvert.AnyToNumber[a], IPConvert.AnyToNumber[b]]] ELSE IF a.type=identifier AND b.type=identifier THEN RETURN[EqIdentifier[IPConvert.AnyToIdentifier[a], IPConvert.AnyToIdentifier[b]]] ELSE RETURN[FALSE]; }; EqN: PUBLIC PROC[a, b: Any] RETURNS[BOOL] = { IF Eq[a, b] THEN RETURN[TRUE] ELSE IF a.type=vector AND b.type=vector THEN RETURN[EqVector[IPConvert.AnyToVector[a], IPConvert.AnyToVector[b]]] ELSE RETURN[FALSE]; }; Gt: PUBLIC PROC[a, b: Number] RETURNS[BOOL] = { WITH a: a SELECT FROM int => WITH b: b SELECT FROM int => RETURN[a.i>b.i]; real => RETURN[a.i>b.r]; ENDCASE; real => WITH b: b SELECT FROM int => RETURN[a.r>b.i]; real => RETURN[a.r>b.r]; ENDCASE; ENDCASE; ERROR IPErrors.Bug; }; Ge: PUBLIC PROC[a, b: Number] RETURNS[BOOL] = { WITH a: a SELECT FROM int => WITH b: b SELECT FROM int => RETURN[a.i>=b.i]; real => RETURN[a.i>=b.r]; ENDCASE; real => WITH b: b SELECT FROM int => RETURN[a.r>=b.i]; real => RETURN[a.r>=b.r]; ENDCASE; ENDCASE; ERROR IPErrors.Bug; }; Type: PUBLIC PROC[a: Any] RETURNS[Integer] = { IF IsNumber[a] THEN RETURN[1] ELSE RETURN[LOOPHOLE[a.type, CARDINAL]]; }; <<2.4.9 Arithmetic operators>> R: PROC[i: INT] RETURNS[REAL] = INLINE { RETURN[i] }; Add: PUBLIC PROC[a, b: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => WITH b: b SELECT FROM int => IF (maxInteger-a.i)>=b.i THEN RETURN[[int[a.i+b.i]]] ELSE RETURN[[real[R[a.i]+R[b.i]]]]; real => RETURN[[real[a.i+b.r]]]; ENDCASE; real => WITH b: b SELECT FROM int => RETURN[[real[a.r+b.i]]]; real => RETURN[[real[a.r+b.r]]]; ENDCASE; ENDCASE; ERROR IPErrors.Bug; }; Sub: PUBLIC PROC[a, b: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => WITH b: b SELECT FROM int => IF a.i>=b.i THEN RETURN[[int[a.i-b.i]]] ELSE RETURN[[real[R[a.i]-R[b.i]]]]; real => RETURN[[real[a.i-b.r]]]; ENDCASE; real => WITH b: b SELECT FROM int => RETURN[[real[a.r-b.i]]]; real => RETURN[[real[a.r-b.r]]]; ENDCASE; ENDCASE; ERROR IPErrors.Bug; }; Neg: PUBLIC PROC[a: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => IF a.i=0 THEN RETURN[a] ELSE RETURN[[real[-R[a.i]]]]; real => RETURN[[real[-a.r]]]; ENDCASE; ERROR IPErrors.Bug; }; Abs: PUBLIC PROC[a: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => RETURN[a]; real => RETURN[[real[ABS[a.r]]]]; ENDCASE; ERROR IPErrors.Bug; }; Floor: PUBLIC PROC[a: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => RETURN[a]; real => RETURN[[real[IPReal.Floor[a.r]]]]; ENDCASE; ERROR IPErrors.Bug; }; Ceiling: PUBLIC PROC[a: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => RETURN[a]; real => RETURN[[real[IPReal.Ceiling[a.r]]]]; ENDCASE; ERROR IPErrors.Bug; }; Trunc: PUBLIC PROC[a: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => RETURN[a]; real => RETURN[[real[IPReal.Trunc[a.r]]]]; ENDCASE; ERROR IPErrors.Bug; }; Round: PUBLIC PROC[a: Number] RETURNS[Number] = { WITH a: a SELECT FROM int => RETURN[a]; real => RETURN[[real[IPReal.Round[a.r]]]]; ENDCASE; ERROR IPErrors.Bug; }; Mul: PUBLIC PROC[a, b: Number] RETURNS[Number] = { RETURN[[real[IPConvert.NumberToReal[a]*IPConvert.NumberToReal[b]]]]; }; Div: PUBLIC PROC[a, b: Number] RETURNS[Number] = { RETURN[[real[IPConvert.NumberToReal[a]/IPConvert.NumberToReal[b]]]]; }; Mod: PUBLIC PROC[a, b: Number] RETURNS[Number] = { RETURN[[real[IPReal.Mod[IPConvert.NumberToReal[a], IPConvert.NumberToReal[b]]]]]; }; Rem: PUBLIC PROC[a, b: Number] RETURNS[Number] = { RETURN[[real[IPReal.Rem[IPConvert.NumberToReal[a], IPConvert.NumberToReal[b]]]]]; }; END.