1(* Ulm's Oberon Library
2   Copyright (C) 1989-1997 by University of Ulm, SAI, D-89069 Ulm, Germany
3   ----------------------------------------------------------------------------
4   Ulm's Oberon Library is free software; you can redistribute it
5   and/or modify it under the terms of the GNU Library General Public
6   License as published by the Free Software Foundation; either version
7   2 of the License, or (at your option) any later version.
8
9   Ulm's Oberon Library is distributed in the hope that it will be
10   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Library General Public License for more details.
13
14   You should have received a copy of the GNU Library General Public
15   License along with this library; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17   ----------------------------------------------------------------------------
18   E-mail contact: oberon@mathematik.uni-ulm.de
19   ----------------------------------------------------------------------------
20   $Id: IntOperatio.om,v 1.1 1997/04/03 09:38:51 borchert Exp $
21   ----------------------------------------------------------------------------
22   $Log: IntOperatio.om,v $
23   Revision 1.1  1997/04/03  09:38:51  borchert
24   Initial revision
25
26   ----------------------------------------------------------------------------
27*)
28
29MODULE ulmIntOperations; (* Frank B.J. Fischer *)
30
31   IMPORT
32      Operations := ulmOperations, PersistentObjects := ulmPersistentObjects,
33      Services   := ulmServices,   Streams           := ulmStreams,
34      Types      := ulmTypes;
35
36   CONST
37      mod* = 5; pow* = 6; inc* = 7; dec* = 8; mmul* = 9; mpow* = 10;
38      odd* = 11; shift* = 12;
39
40   TYPE
41      Operation* = Operations.Operation;  (* Operations.add..mpow *)
42      Operand* = POINTER TO OperandRec;
43
44   TYPE
45      CapabilitySet* = Operations.CapabilitySet;
46         (* Types.Set of [Operations.add..shift] *)
47      IsLargeEnoughForProc* = PROCEDURE (op: Operations.Operand;
48                                        n: Types.Int32): BOOLEAN;
49      UnsignedProc* = PROCEDURE (op: Operations.Operand): BOOLEAN;
50      IntToOpProc* = PROCEDURE (int32: Types.Int32; VAR op: Operations.Operand);
51      OpToIntProc* = PROCEDURE (op: Operations.Operand; VAR int32: Types.Int32);
52      Log2Proc* = PROCEDURE (op: Operations.Operand): Types.Int32;
53      OddProc* = PROCEDURE (op: Operations.Operand): BOOLEAN;
54      ShiftProc* = PROCEDURE (op: Operations.Operand;
55                             n: Types.Int32): Operations.Operand;
56      IntOperatorProc* = PROCEDURE(op: Operation;
57                                  op1, op2, op3: Operations.Operand;
58                                  VAR result: Operations.Operand);
59      Interface* = POINTER TO InterfaceRec;
60      InterfaceRec* = RECORD
61                        (Operations.InterfaceRec)
62                        isLargeEnoughFor*: IsLargeEnoughForProc;
63                        unsigned*        : UnsignedProc;
64                        intToOp*         : IntToOpProc;
65                        opToInt*         : OpToIntProc;
66                        log2*            : Log2Proc;
67                        odd*             : OddProc;
68                        shift*           : ShiftProc;
69                        intOp*           : IntOperatorProc;
70                     END;
71
72   TYPE
73      OperandRec* = RECORD
74                      (Operations.OperandRec);
75                      (* private components *)
76                      if  : Interface;
77                      caps: CapabilitySet;
78                   END;
79
80   VAR
81      operandType: Services.Type;
82
83
84   PROCEDURE Init*(op: Operand; if: Interface; caps: CapabilitySet);
85   BEGIN
86      Operations.Init(op, if, caps);
87      op.if := if;
88      op.caps := caps;
89   END Init;
90
91
92   PROCEDURE Capabilities*(op: Operand): CapabilitySet;
93   BEGIN
94      RETURN op.caps
95   END Capabilities;
96
97
98   PROCEDURE IsLargeEnoughFor*(op: Operations.Operand; n: Types.Int32): BOOLEAN;
99   BEGIN
100      WITH op: Operand DO
101         RETURN op.if.isLargeEnoughFor(op, n)
102      END;
103   END IsLargeEnoughFor;
104
105
106   PROCEDURE Unsigned*(op: Operations.Operand): BOOLEAN;
107   BEGIN
108      WITH op: Operand DO
109         RETURN op.if.unsigned(op)
110      END;
111   END Unsigned;
112
113
114   PROCEDURE IntToOp*(int32: Types.Int32; VAR op: Operations.Operand);
115      (* converts int32 into operand type, and stores result in already
116         initialized op
117      *)
118   BEGIN
119      ASSERT(op(Operand).if # NIL);
120      op(Operand).if.intToOp(int32, op);
121   END IntToOp;
122
123
124   PROCEDURE OpToInt*(op: Operations.Operand; VAR int32: Types.Int32);
125      (* converts op into int32 *)
126   BEGIN
127      WITH op: Operand DO
128         op.if.opToInt(op, int32);
129      END;
130   END OpToInt;
131
132
133   PROCEDURE Log2*(op: Operations.Operand): Types.Int32;
134   BEGIN
135      WITH op: Operand DO
136         RETURN op.if.log2(op)
137      END;
138   END Log2;
139
140
141   PROCEDURE Odd*(op: Operations.Operand): BOOLEAN;
142   BEGIN
143      WITH op: Operand DO
144         ASSERT(odd IN op.caps);
145         RETURN op.if.odd(op)
146      END;
147   END Odd;
148
149
150   PROCEDURE Op(op: Operation; op1, op2, op3: Operations.Operand;
151                VAR result: Operations.Operand);
152      VAR
153         tmpresult: Operations.Operand;
154   BEGIN
155      WITH op1: Operand DO
156            IF (op2#NIL) & (op3#NIL) THEN
157               ASSERT((op1.if = op2(Operand).if) &
158                      (op2(Operand).if = op3(Operand).if));
159            ELSIF (op2#NIL) THEN
160               ASSERT(op1.if = op2(Operand).if);
161            END;
162            ASSERT(op IN op1.caps);
163            op1.if.create(tmpresult);
164            op1.if.intOp(op, op1, op2, op3, tmpresult);
165            result := tmpresult;
166      END;
167   END Op;
168
169
170   PROCEDURE Shift*(op1: Operations.Operand; n: Types.Int32): Operations.Operand;
171   BEGIN
172      WITH op1: Operand DO
173         ASSERT(shift IN op1.caps);
174         RETURN op1.if.shift(op1,n);
175      END;
176   END Shift;
177
178
179   PROCEDURE Shift2*(VAR op1: Operations.Operand; n: Types.Int32);
180   BEGIN
181      op1 := Shift(op1, n);
182   END Shift2;
183
184
185   PROCEDURE Shift3*(VAR result: Operations.Operand; op1: Operations.Operand;
186                    n : Types.Int32);
187      VAR
188         tmpresult: Operations.Operand;
189   BEGIN
190      WITH op1: Operand DO
191         op1.if.create(tmpresult);
192         tmpresult := Shift(op1, n);
193         result := tmpresult;
194      END;
195   END Shift3;
196
197
198   PROCEDURE Inc*(op1: Operations.Operand): Operations.Operand;
199      VAR
200         result: Operations.Operand;
201   BEGIN
202      result := NIL;
203      Op(inc,op1,NIL,NIL,result);
204      RETURN result
205   END Inc;
206
207
208   PROCEDURE Inc2*(VAR op1: Operations.Operand);
209   BEGIN
210      Op(inc,op1,NIL,NIL,op1);
211   END Inc2;
212
213
214   PROCEDURE Inc3*(VAR result: Operations.Operand; op1: Operations.Operand);
215   BEGIN
216      Op(inc,op1,NIL,NIL,result);
217   END Inc3;
218
219
220   PROCEDURE Dec*(op1: Operations.Operand): Operations.Operand;
221      VAR
222         result: Operations.Operand;
223   BEGIN
224      result := NIL;
225      Op(dec,op1,NIL,NIL,result);
226      RETURN result
227   END Dec;
228
229
230   PROCEDURE Dec2*(VAR op1: Operations.Operand);
231   BEGIN
232      Op(dec,op1,NIL,NIL,op1);
233   END Dec2;
234
235
236   PROCEDURE Dec3*(VAR result: Operations.Operand; op1: Operations.Operand);
237   BEGIN
238      Op(dec,op1,NIL,NIL,result);
239   END Dec3;
240
241
242   PROCEDURE Mod*(op1, op2: Operations.Operand): Operations.Operand;
243      VAR
244         result: Operations.Operand;
245   BEGIN
246      result := NIL;
247      Op(mod, op1, op2, NIL, result);
248      RETURN result
249   END Mod;
250
251
252   PROCEDURE Mod2*(VAR op1: Operations.Operand; op2: Operations.Operand);
253   BEGIN
254      Op(mod, op1, op2, NIL, op1);
255   END Mod2;
256
257
258   PROCEDURE Mod3*(VAR result: Operations.Operand; op1, op2: Operations.Operand);
259   BEGIN
260      Op(mod, op1, op2, NIL, result);
261   END Mod3;
262
263
264   PROCEDURE Pow*(op1, op2: Operations.Operand): Operations.Operand;
265      VAR
266         result: Operations.Operand;
267   BEGIN
268      result := NIL;
269      Op(pow, op1, op2, NIL, result);
270      RETURN result
271   END Pow;
272
273
274   PROCEDURE Pow2*(VAR op1: Operations.Operand; op2: Operations.Operand);
275   BEGIN
276      Op(pow, op1, op2, NIL, op1);
277   END Pow2;
278
279
280   PROCEDURE Pow3*(VAR result: Operations.Operand; op1, op2: Operations.Operand);
281   BEGIN
282      Op(pow, op1, op2, NIL, result);
283   END Pow3;
284
285
286   PROCEDURE MMul*(op1, op2, op3: Operations.Operand): Operations.Operand;
287      VAR
288         result : Operations.Operand;
289   BEGIN
290      result := NIL;
291      Op(mmul, op1, op2, op3, result);
292      RETURN result
293   END MMul;
294
295
296   PROCEDURE MMul2*(VAR op1: Operations.Operand; op2, op3: Operations.Operand);
297   BEGIN
298      Op(mmul, op1, op2, op3, op1);
299   END MMul2;
300
301
302   PROCEDURE MMul3*(VAR result: Operations.Operand;
303                   op1, op2, op3: Operations.Operand);
304   BEGIN
305      Op(mmul, op1, op2, op3, result);
306   END MMul3;
307
308
309   PROCEDURE MPow*(op1, op2, op3: Operations.Operand): Operations.Operand;
310      VAR
311         result : Operations.Operand;
312   BEGIN
313      result := NIL;
314      Op(mpow, op1, op2, op3, result);
315      RETURN result
316   END MPow;
317
318
319   PROCEDURE MPow2*(VAR op1: Operations.Operand; op2, op3: Operations.Operand);
320   BEGIN
321      Op(mpow, op1, op2, op3, op1);
322   END MPow2;
323
324
325   PROCEDURE MPow3*(VAR result: Operations.Operand;
326                   op1, op2, op3: Operations.Operand);
327   BEGIN
328      Op(mpow, op1, op2, op3, result);
329   END MPow3;
330
331
332BEGIN
333    PersistentObjects.RegisterType(operandType,"IntOperations.Operand",
334                                   "Operations.Operand", NIL);
335END ulmIntOperations.
336