~ubuntu-branches/ubuntu/vivid/inform/vivid

« back to all changes in this revision

Viewing changes to inform-6.31.1/include/longint.h

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2008-05-26 22:09:44 UTC
  • mfrom: (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526220944-ba7phz0d1k4vo7wx
Tags: 6.31.1+dfsg-1
* Remove a considerable number of files from the package
  due to unacceptable licensing terms.
* Repair library symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
! longint.h - support for signed and unsigned 4 byte integers in Inform.
 
2
!
 
3
! Mainly by Chris Hall - c@pobox.co.uk.
 
4
! Signed integer support by Francis Irving - francis@pobox.co.uk.
 
5
! Please email us with any errors, omissions or if you've 
 
6
! found this code useful.
 
7
!
 
8
! For example use of this module, see longint.inf, which should be
 
9
! available from the same place you got this file.
 
10
!
 
11
! For a complete Inform program using this module see
 
12
! http://www.meta.demon.co.uk/zbefunge.html
 
13
!
 
14
! (If you need to edit this file, note that indentations are 4 spaces
 
15
! and tabs are not used.)
 
16
!
 
17
! This source code is distributed free, but remains
 
18
! Copyright 1997-1998 Chris Hall and Francis Irving.  Release 1.
 
19
 
 
20
System_file;
 
21
 
 
22
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
23
 
 
24
! Functions beginning "LongSign" work on signed integers.
 
25
! Functions beginning "LongUnsign" work on unsigned integers.
 
26
! Functions beginning "Long" are generally applicable.
 
27
 
 
28
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
29
!! Printing.
 
30
 
 
31
Array _LongNegTemp0->4;
 
32
Array _LongNegTemp1->4;
 
33
 
 
34
! Print a signed long.  Use by writing "print (longsign)x;".
 
35
[longsign n;
 
36
    LongSignOutputAsChars(n, LongPrintChar);
 
37
];
 
38
 
 
39
! Print an unsigned long.  Use by writing "print (longunsign)x;".
 
40
[longunsign n;
 
41
    LongUnsignOutputAsChars(n, LongPrintChar);
 
42
];
 
43
 
 
44
! Generalised printing.
 
45
! This takes "n" and outputs it a character at
 
46
! a time, calling function "fn".  Returns the length
 
47
! in characters.
 
48
[LongSignOutputAsChars n fn
 
49
        len;
 
50
    len = 0;
 
51
    if (LongSignIsNeg(n))
 
52
    {
 
53
        indirect(fn, '-');
 
54
        ++len;
 
55
    }
 
56
    LongSignAbsAssign(_LongNegTemp0, n);
 
57
    len = len + LongNum4(_LongNegTemp0->0,_LongNegTemp0->1,_LongNegTemp0->2,_LongNegTemp0->3, fn);
 
58
    return len;
 
59
];
 
60
 
 
61
! As signed version above.
 
62
[LongUnsignOutputAsChars n fn
 
63
        len;
 
64
    len = LongNum4(n->0,n->1,n->2,n->3, fn);
 
65
    return len;
 
66
];
 
67
 
 
68
! Internal function.
 
69
[LongPrintChar ch;
 
70
    print (char)ch;
 
71
];
 
72
 
 
73
! Internal function.
 
74
[LongNum4 a b c d fn
 
75
        l len;
 
76
    len = 0;
 
77
    b=b+256*(a%10); a=a/10;
 
78
    c=c+256*(b%10); b=b/10;
 
79
    d=d+256*(c%10); c=c/10;
 
80
    l=d%10;         d=d/10;
 
81
    if(a||b||c||d)
 
82
    {
 
83
        len = len + LongNum4(a,b,c,d, fn);
 
84
    }
 
85
    indirect(fn, '0'+l);
 
86
    ++len;
 
87
 
 
88
    return len;
 
89
];
 
90
 
 
91
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
92
!! Simple testing and assigning
 
93
 
 
94
! Test to see if a signed long is negative.
 
95
[LongSignIsNeg a;
 
96
    if ((a->0)&$80)
 
97
        rtrue;
 
98
    else
 
99
        rfalse;
 
100
];
 
101
 
 
102
! Test to see if long is zero.  Signed or unsigned.
 
103
[LongIsZero a;
 
104
    if ((a->0 == 0) && (a->1 == 0) && (a->2 == 0) && (a->3 == 0))
 
105
        rtrue;
 
106
    else
 
107
        rfalse;
 
108
];
 
109
 
 
110
! Sets values into a signed or unsigned long.
 
111
! The appropriate encoding is left up to the caller:
 
112
! 1. We store our longs in big-endian (most significant first) order.
 
113
! 2. a&$80 is non-zero for negative signed integers.
 
114
! You might want to call this with parameters (0, 0, 0, x) to 
 
115
! set a value from 0 to 255.  Then use LongSignNegAssign to
 
116
! make it negative.
 
117
[LongSet l a b c d;   ! l=((a*256+b)*256+c)*256+d
 
118
    l->0=a;
 
119
    l->1=b;
 
120
    l->2=c;
 
121
    l->3=d;
 
122
];
 
123
 
 
124
! Copy either a signed or unsigned long.
 
125
[LongAssign d s;      ! d=s
 
126
    d->0=s->0;
 
127
    d->1=s->1;
 
128
    d->2=s->2;
 
129
    d->3=s->3;
 
130
];
 
131
 
 
132
! d=-s  d and s can be the same variable
 
133
[LongSignNegAssign d s  
 
134
        t;
 
135
    LongAssign(d, s);
 
136
    LongNot(d);
 
137
    t=d->3+1;       d->3=t%256;
 
138
    t=d->2+t/256; d->2=t%256;
 
139
    t=d->1+t/256; d->1=t%256;
 
140
    t=d->0+t/256; d->0=t%256;
 
141
];
 
142
 
 
143
! d=positive part of s
 
144
[LongSignAbsAssign d s; 
 
145
    if (LongSignIsNeg(s))
 
146
        LongSignNegAssign(d, s);
 
147
    else
 
148
        LongAssign(d, s);
 
149
];
 
150
 
 
151
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
152
!! Addition and subtraction.
 
153
 
 
154
! r=a+b;   (r may be same variable as a or b)
 
155
! Works for signed or unsigned longs.
 
156
[LongAdd r a b        
 
157
         t;
 
158
    t=a->3+b->3;       r->3=t%256;
 
159
    t=a->2+b->2+t/256; r->2=t%256;
 
160
    t=a->1+b->1+t/256; r->1=t%256;
 
161
    t=a->0+b->0+t/256; r->0=t%256;
 
162
];
 
163
 
 
164
! r=a-b;   (r may be same variable as a or b)
 
165
! Works for signed or unsigned longs.
 
166
[LongSub r a b
 
167
        t;
 
168
    t=256+a->3-b->3;         r->3=t%256;
 
169
    t=256+a->2-b->2-(t<256); r->2=t%256;
 
170
    t=256+a->1-b->1-(t<256); r->1=t%256;
 
171
    t=256+a->0-b->0-(t<256); r->0=t%256;
 
172
];                            
 
173
 
 
174
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
175
!! Multiplication and division.
 
176
 
 
177
! r=a*b;   (r may _not_ be same variable as a or b)
 
178
! Works for signed or unsigned longs.  Note that the
 
179
! destination variable must be a different variable
 
180
! from both of the source variables.
 
181
[LongMul r a b        
 
182
        t;
 
183
    t=(a->3%16)*(b->3%16);      r->3=t%16;
 
184
    t=(a->3%16)*(b->3/16)
 
185
        +(a->3/16)*(b->3%16)+t/16; r->3=r->3+16*(t%16);
 
186
    t=(a->3%16)*(b->2%16)
 
187
        +(a->3/16)*(b->3/16)
 
188
        +(a->2%16)*(b->3%16)+t/16; r->2=t%16;
 
189
    t=(a->3%16)*(b->2/16)
 
190
        +(a->3/16)*(b->2%16)
 
191
        +(a->2%16)*(b->3/16)
 
192
        +(a->2/16)*(b->3%16)+t/16; r->2=r->2+16*(t%16);
 
193
    t=(a->3%16)*(b->1%16)
 
194
        +(a->3/16)*(b->2/16)
 
195
        +(a->2%16)*(b->2%16)
 
196
        +(a->2/16)*(b->3/16)
 
197
        +(a->1%16)*(b->3%16)+t/16; r->1=t%16;
 
198
    t=(a->3%16)*(b->1/16)
 
199
        +(a->3/16)*(b->1%16)
 
200
        +(a->2%16)*(b->2/16)
 
201
        +(a->2/16)*(b->2%16)
 
202
        +(a->1%16)*(b->3/16)
 
203
        +(a->1/16)*(b->3%16)+t/16; r->1=r->1+16*(t%16);
 
204
    t=(a->3%16)*(b->0%16)
 
205
        +(a->3/16)*(b->1/16)
 
206
        +(a->2%16)*(b->1%16)
 
207
        +(a->2/16)*(b->2/16)
 
208
        +(a->1%16)*(b->2%16)
 
209
        +(a->1/16)*(b->3/16)
 
210
        +(a->0%16)*(b->3%16)+t/16; r->0=t%16;
 
211
    t=(a->3%16)*(b->0/16)
 
212
        +(a->3/16)*(b->0%16)
 
213
        +(a->2%16)*(b->1/16)
 
214
        +(a->2/16)*(b->1%16)+t/16;
 
215
    t=(a->1%16)*(b->2/16)
 
216
        +(a->1/16)*(b->2%16)
 
217
        +(a->0%16)*(b->3/16)
 
218
        +(a->0/16)*(b->3%16)+t;    r->0=r->0+16*(t%16);
 
219
];
 
220
 
 
221
Array _LongDMTemp0->4;
 
222
Array _LongDMTemp1->4;
 
223
 
 
224
! d=a/b; m=a%b   (d and m may be same variable as a or b)
 
225
! Works for unsigned longs only.
 
226
[LongUnsignDivMod d m a b   
 
227
        t;
 
228
 
 
229
    ! Division by zero!  The user is encouraged to test for this
 
230
    ! himself before calling the various division functions.  We
 
231
    ! simply force the interpreter to perform a divide by zero.
 
232
    if(LongIsZero(b)){a=0;a=a/0;}
 
233
 
 
234
    LongAssign(_LongDMTemp1,b);
 
235
    LongAssign(m,a);
 
236
    d->0=d->1=d->2=d->3=
 
237
    _LongDMTemp0->0=_LongDMTemp0->1=_LongDMTemp0->2=0; _LongDMTemp0->3=1;
 
238
 
 
239
    while(LongUnsignLE(_LongDMTemp1,m)){
 
240
                t=LongShl(_LongDMTemp0);
 
241
        if (t) break;
 
242
        LongShl(_LongDMTemp1);
 
243
    }
 
244
    for(::){
 
245
        if(LongShr(_LongDMTemp0,t)) break;
 
246
        t=0;
 
247
        if(~~t) LongShr(_LongDMTemp1);
 
248
        if(LongUnsignLE(_LongDMTemp1,m)){
 
249
            LongSub(m,m,_LongDMTemp1);
 
250
            LongAdd(d,d,_LongDMTemp0);
 
251
        }
 
252
    }
 
253
];
 
254
 
 
255
Array _LongDMTemp2->4;
 
256
 
 
257
! r=a/b;   (r may be same variable as a or b)
 
258
! Works for signed longs only.
 
259
[LongSignDiv r a b
 
260
        n;
 
261
    n = LongNegIndex(a, b,_LongNegTemp0,_LongNegTemp1);
 
262
    LongUnsignDivMod(r,_LongDMTemp2,_LongNegTemp0,_LongNegTemp1);
 
263
    LongUseNegIndex(n, r);
 
264
];
 
265
 
 
266
! r=a%b;   (r may be same variable as a or b)
 
267
! Works for signed longs only.
 
268
[LongSignMod r a b
 
269
        n;
 
270
    n = LongNegIndex(a, b,_LongNegTemp0,_LongNegTemp1);
 
271
    LongUnsignDivMod(_LongDMTemp2,r,_LongNegTemp0,_LongNegTemp1);
 
272
    LongUseNegIndex(n, r);
 
273
];
 
274
 
 
275
! Internal function.
 
276
! c=abs(a), d= abs(b) if a*b is negative, return that.
 
277
[LongNegIndex a b c d;
 
278
    LongSignAbsAssign(c, a);
 
279
    LongSignAbsAssign(d, b);
 
280
    if (LongSignIsNeg(a) ~= LongSignIsNeg(b))
 
281
        rtrue;
 
282
    else
 
283
        rfalse;
 
284
];
 
285
 
 
286
! Internal function.
 
287
! if n true, let r=-r
 
288
[ LongUseNegIndex n r;  
 
289
    if (n)
 
290
        LongSignNegAssign(r, r);
 
291
];
 
292
 
 
293
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
294
!! Comparison.
 
295
 
 
296
! Returns:
 
297
!  a<b -1
 
298
!  a>b 1
 
299
!  a==b 0);
 
300
! Works for signed longs only.
 
301
[LongSignCompare a b;     
 
302
    if (LongSignIsNeg(a) && (~~LongSignIsNeg(b))) return -1;
 
303
    if ((~~LongSignIsNeg(a)) && LongSignIsNeg(b)) return 1;
 
304
 
 
305
    if (~~LongSignIsNeg(a))
 
306
    {
 
307
        LongSignAbsAssign(_LongNegTemp0, a);
 
308
        LongSignAbsAssign(_LongNegTemp1, b);
 
309
    }
 
310
    else  
 
311
    {
 
312
        ! swap round if they are both negative
 
313
        LongSignAbsAssign(_LongNegTemp0, b);
 
314
        LongSignAbsAssign(_LongNegTemp1, a);
 
315
    }
 
316
 
 
317
    return LongUnsignCompare(_LongNegTemp0, _LongNegTemp1);
 
318
];
 
319
 
 
320
! Returns:
 
321
!  a<b -1
 
322
!  a>b 1
 
323
!  a==b 0);
 
324
! Works for unsigned longs only.
 
325
[LongUnsignCompare a b;
 
326
    if(a->0<b->0) return(-1);
 
327
    if(a->0>b->0) rtrue;
 
328
    if(a->1<b->1) return(-1);
 
329
    if(a->1>b->1) rtrue;
 
330
    if(a->2<b->2) return(-1);
 
331
    if(a->2>b->2) rtrue;
 
332
    if(a->3<b->3) return(-1);
 
333
    return(a->3>b->3);
 
334
];
 
335
 
 
336
! Unsigned versions.
 
337
[LongUnsignLT a b; return(LongUnsignCompare(a,b)< 0);]; ! return(a< b);
 
338
[LongUnsignLE a b; return(LongUnsignCompare(a,b)<=0);]; ! return(a<=b);
 
339
[LongUnsignGT a b; return(LongUnsignCompare(a,b)> 0);]; ! return(a> b);
 
340
[LongUnsignGE a b; return(LongUnsignCompare(a,b)>=0);]; ! return(a>=b);
 
341
[LongUnsignEQ a b; return(LongUnsignCompare(a,b)==0);]; ! return(a==b);
 
342
[LongUnsignNE a b; return(LongUnsignCompare(a,b)~=0);]; ! return(a~=b);
 
343
 
 
344
! Signed versions.
 
345
[LongSignLT a b; return(LongSignCompare(a,b)< 0);]; ! return(a< b);
 
346
[LongSignLE a b; return(LongSignCompare(a,b)<=0);]; ! return(a<=b);
 
347
[LongSignGT a b; return(LongSignCompare(a,b)> 0);]; ! return(a> b);
 
348
[LongSignGE a b; return(LongSignCompare(a,b)>=0);]; ! return(a>=b);
 
349
[LongSignEQ a b; return(LongSignCompare(a,b)==0);]; ! return(a==b);
 
350
[LongSignNE a b; return(LongSignCompare(a,b)~=0);]; ! return(a~=b);
 
351
 
 
352
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
353
!! Bitwise comparisons.
 
354
 
 
355
! These bitwise operators aren't really signed or unsigned.
 
356
 
 
357
! a=(a<<1+t); return(bit lost off end);
 
358
[LongShl a t;
 
359
    t=a->3*2+t;     a->3=t%256;
 
360
    t=a->2*2+t/256; a->2=t%256;
 
361
    t=a->1*2+t/256; a->1=t%256;
 
362
    t=a->0*2+t/256; a->0=t%256;
 
363
    return(t/256);
 
364
];
 
365
 
 
366
! a=((a+(t<<32))>>1); return(bit lost off end);
 
367
[LongShr a t;
 
368
    t=a->0+256*t;     a->0=t/2;
 
369
    t=a->1+256*(t%2); a->1=t/2;
 
370
    t=a->2+256*(t%2); a->2=t/2;
 
371
    t=a->3+256*(t%2); a->3=t/2;
 
372
    return(t%2);
 
373
];
 
374
 
 
375
! a=~a, bitwise not
 
376
[LongNot a;
 
377
    a->0 = ~(a->0);
 
378
    a->1 = ~(a->1);
 
379
    a->2 = ~(a->2);
 
380
    a->3 = ~(a->3);
 
381
];