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

« back to all changes in this revision

Viewing changes to 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
 
];