Oberon || Library || Module Index || Search Engine || Definition || Module
CONST mod = 5; pow = 6; inc = 7; dec = 8; mmul = 9; mpow = 10; CONST odd = 11; shift = 12; TYPE Operation = Operations.Operation; (* Operations.add..mpow *) TYPE Operand = POINTER TO OperandRec; TYPE OperandRec = RECORD (Operations.OperandRec) END; TYPE CapabilitySet = Operations.CapabilitySet; (* SET of [Operations.add..shift] *) TYPE IsLargeEnoughForProc = PROCEDURE (op: Operations.Operand n: LONGINT): BOOLEAN; TYPE UnsignedProc = PROCEDURE (op: Operations.Operand): BOOLEAN; TYPE IntToOpProc = PROCEDURE (int32: Types.Int32; VAR op: Operations.Operand); TYPE OpToIntProc = PROCEDURE (op: Operations.Operand; VAR int32: Types.Int32); TYPE Log2Proc = PROCEDURE (op: Operations.Operand): LONGINT; TYPE OddProc = PROCEDURE (op: Operations.Operand): BOOLEAN; TYPE ShiftProc = PROCEDURE (op: Operations.Operand; n: INTEGER): Operations.Operand; TYPE IntOperatorProc = PROCEDURE(op: Operation; op1, op2, op3: Operations.Operand; VAR result: Operations.Operand); TYPE Interface = POINTER TO InterfaceRec; TYPE InterfaceRec = RECORD (Operations.InterfaceRec) isLargeEnoughFor: IsLargeEnoughForProc; unsigned: UnsignedProc; intToOp: IntToOpProc; opToInt: OpToIntProc; log2: Log2Proc; odd: OddProc; shift: ShiftProc; intOp: IntOperatorProc; END;
PROCEDURE Init(op: Operand; if: Interface; caps: CapabilitySet); PROCEDURE Capabilities(op: Operand): CapabilitySet; PROCEDURE IsLargeEnoughFor(op: Operations.Operand; n: LONGINT): BOOLEAN; PROCEDURE Unsigned(op: Operations.Operand): BOOLEAN; PROCEDURE IntToOp(int32: Types.Int32; VAR op: Operations.Operand); PROCEDURE OpToInt(op: Operations.Operand; VAR int32: Types.Int32); PROCEDURE Log2(op: Operations.Operand): LONGINT; PROCEDURE Odd(op: Operations.Operand): BOOLEAN; PROCEDURE Shift(op1: Operations.Operand; n: INTEGER): Operations.Operand; PROCEDURE Shift2(VAR op1: Operations.Operand; n: INTEGER); PROCEDURE Shift3(VAR result: Operations.Operand; op1: Operations.Operand; n: INTEGER); PROCEDURE Inc(op1: Operations.Operand): Operations.Operand; PROCEDURE Inc2(VAR op1: Operations.Operand); PROCEDURE Inc3(VAR result: Operations.Operand; op1: Operations.Operand); PROCEDURE Dec(op1: Operations.Operand): Operations.Operand; PROCEDURE Dec2(VAR op1: Operations.Operand); PROCEDURE Dec3(VAR result: Operations.Operand; op1: Operations.Operand); PROCEDURE Mod(op1, op2: Operations.Operand) : Operations.Operand; PROCEDURE Mod2(VAR op1: Operations.Operand; op2: Operations.Operand); PROCEDURE Mod3(VAR result: Operations.Operand; op1, op2: Operations.Operand); PROCEDURE Pow(op1, op2: Operations.Operand): Operations.Operand; PROCEDURE Pow2(VAR op1: Operations.Operand; op2: Operations.Operand); PROCEDURE Pow3(VAR result: Operations.Operand; op1, op2: Operations.Operand); PROCEDURE MMul(op1, op2, op3: Operations.Operand): Operations.Operand; PROCEDURE MMul2(VAR op1: Operations.Operand; op2, op3: Operations.Operand); PROCEDURE MMul3(VAR result: Operations.Operand; op1, op2, op3: Operations.Operand); PROCEDURE MPow(op1, op2, op3: Operations.Operand): Operations.Operand; PROCEDURE MPow2(VAR op1: Operations.Operand; op2, op3: Operations.Operand); PROCEDURE MPow3(VAR result: Operations.Operand; op1, op2, op3: Operations.Operand);
The interface describes the set of available operations and contains the necessary procedures. The type Interface is an extension of Operations.Interface and therefore an explicit call of Operations.Init is not necessary because it is automatically called by Init. The interface procedures should meet the following specifications:
Init is to be called by modules implementing an arithmetic data type to connect the interface if to the operand op. Capabilities returns the set of capabilities of op. IsLargeEnoughFor returns TRUE if the type specified by op is large enough for $2 sup n - 1$, else returns FALSE. Unsigned returns TRUE if the type of op is unsigned and returns FALSE if the type is signed.
IntToOp converts a given integer int32 into the type Operations.Operand and stores the result into the already initialized variable op. OpToInt converts op into an integer of type Types.Int32 and stores the result in the variable int32. If op does not fit into a 32 bit variable, then the modulo operation is used for adaption.
Log2 returns the rounded up result of log2(op). Odd checks a given operand op if it is odd and returns TRUE if odd, else the procedure returns FALSE.
Arithmetic operations are implemented in three forms:
If more than one parameter is used in XXX resp. in XXX2 or in XXX3 then type equality is necessary. These procedures are provided for XXX equal to Inc, Dec, Mod, Pow, MMul and MPow. XXX2 and XXX3 allow result to be equal to op1, op2 or op3.
Shift works like SYSTEM.LSH and logically shifts op1 n bits to the left, provided that n is positive. Else op1 is shifted n bits to the right. Inc and Dec increment resp. decrement op1 by 1. Mod calculates op1 MOD op2 and Pow returns op1 to the power of op2. MMul multiplies op1 and op2 and assures that the result is less than op3. Like MMul, MPow computes the residue of power.
Oberon || Library || Module Index || Search Engine || Definition || Module