1/* The contents of this file are subject to the Netscape Public
2 * License Version 1.1 (the "License"); you may not use this file
3 * except in compliance with the License. You may obtain a copy of
4 * the License at http://www.mozilla.org/NPL/
5 *
6 * Software distributed under the License is distributed on an "AS
7 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
8 * implied. See the License for the specific language governing
9 * rights and limitations under the License.
10 *
11 * The Original Code is Mozilla Communicator client code, released March
12 * 31, 1998.
13 *
14 * The Initial Developer of the Original Code is Netscape Communications
15 * Corporation. Portions created by Netscape are
16 * Copyright (C) 1998 Netscape Communications Corporation. All
17 * Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 */
22/**
23    File Name:          11.7.2.js
24    ECMA Section:       11.7.2  The signed right shift operator ( >> )
25    Description:
26    Performs a sign-filling bitwise right shift operation on the left argument
27    by the amount specified by the right argument.
28
29    The production ShiftExpression : ShiftExpression >> AdditiveExpression is
30    evaluated as follows:
31
32    1.  Evaluate ShiftExpression.
33    2.  Call GetValue(Result(1)).
34    3.  Evaluate AdditiveExpression.
35    4.  Call GetValue(Result(3)).
36    5.  Call ToInt32(Result(2)).
37    6.  Call ToUint32(Result(4)).
38    7.  Mask out all but the least significant 5 bits of Result(6), that is,
39        compute Result(6) & 0x1F.
40    8.  Perform sign-extending right shift of Result(5) by Result(7) bits. The
41        most significant bit is propagated. The result is a signed 32 bit
42        integer.
43    9.  Return Result(8).
44
45    Author:             christine@netscape.com
46    Date:               12 november 1997
47*/
48    var SECTION = "11.7.2";
49    var VERSION = "ECMA_1";
50    startTest();
51    var testcases = getTestCases();
52
53    writeHeaderToLog( SECTION + "  The signed right shift operator ( >> )");
54    test();
55
56function test() {
57    for ( tc=0; tc < testcases.length; tc++ ) {
58        testcases[tc].passed = writeTestCaseResult(
59                            testcases[tc].expect,
60                            testcases[tc].actual,
61                            testcases[tc].description +" = "+
62                            testcases[tc].actual );
63
64        testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
65    }
66    stopTest();
67    return ( testcases );
68}
69function getTestCases() {
70    var array = new Array();
71    var item = 0;
72    var power = 0;
73    var addexp = 0;
74
75    for ( power = 0; power <= 32; power++ ) {
76        shiftexp = Math.pow( 2, power );
77
78        for ( addexp = 0; addexp <= 32; addexp++ ) {
79            array[item++] = new TestCase( SECTION,
80                                    shiftexp + " >> " + addexp,
81                                    SignedRightShift( shiftexp, addexp ),
82                                    shiftexp >> addexp );
83        }
84    }
85
86    for ( power = 0; power <= 32; power++ ) {
87        shiftexp = -Math.pow( 2, power );
88
89        for ( addexp = 0; addexp <= 32; addexp++ ) {
90            array[item++] = new TestCase( SECTION,
91                                    shiftexp + " >> " + addexp,
92                                    SignedRightShift( shiftexp, addexp ),
93                                    shiftexp >> addexp );
94        }
95    }
96
97    return ( array );
98}
99
100function ToInteger( n ) {
101    n = Number( n );
102    var sign = ( n < 0 ) ? -1 : 1;
103
104    if ( n != n ) {
105        return 0;
106    }
107    if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY ) {
108        return n;
109    }
110    return ( sign * Math.floor(Math.abs(n)) );
111}
112function ToInt32( n ) {
113    n = Number( n );
114    var sign = ( n < 0 ) ? -1 : 1;
115
116    if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY) {
117        return 0;
118    }
119
120    n = (sign * Math.floor( Math.abs(n) )) % Math.pow(2,32);
121    n = ( n >= Math.pow(2,31) ) ? n - Math.pow(2,32) : n;
122
123    return ( n );
124}
125function ToUint32( n ) {
126    n = Number( n );
127    var sign = ( n < 0 ) ? -1 : 1;
128
129    if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY) {
130        return 0;
131    }
132    n = sign * Math.floor( Math.abs(n) )
133
134    n = n % Math.pow(2,32);
135
136    if ( n < 0 ){
137        n += Math.pow(2,32);
138    }
139
140    return ( n );
141}
142function ToUint16( n ) {
143    var sign = ( n < 0 ) ? -1 : 1;
144
145    if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY) {
146        return 0;
147    }
148
149    n = ( sign * Math.floor( Math.abs(n) ) ) % Math.pow(2,16);
150
151    if (n <0) {
152        n += Math.pow(2,16);
153    }
154
155    return ( n );
156}
157function Mask( b, n ) {
158    b = ToUint32BitString( b );
159    b = b.substring( b.length - n );
160    b = ToUint32Decimal( b );
161    return ( b );
162}
163function ToUint32BitString( n ) {
164    var b = "";
165    for ( p = 31; p >=0; p-- ) {
166        if ( n >= Math.pow(2,p) ) {
167            b += "1";
168            n -= Math.pow(2,p);
169        } else {
170            b += "0";
171        }
172    }
173    return b;
174}
175function ToInt32BitString( n ) {
176    var b = "";
177    var sign = ( n < 0 ) ? -1 : 1;
178
179    b += ( sign == 1 ) ? "0" : "1";
180
181    for ( p = 30; p >=0; p-- ) {
182        if ( (sign == 1 ) ? sign * n >= Math.pow(2,p) : sign * n > Math.pow(2,p) ) {
183            b += ( sign == 1 ) ? "1" : "0";
184            n -= sign * Math.pow( 2, p );
185        } else {
186            b += ( sign == 1 ) ? "0" : "1";
187        }
188    }
189
190    return b;
191}
192function ToInt32Decimal( bin ) {
193    var r = 0;
194    var sign;
195
196    if ( Number(bin.charAt(0)) == 0 ) {
197        sign = 1;
198        r = 0;
199    } else {
200        sign = -1;
201        r = -(Math.pow(2,31));
202    }
203
204    for ( var j = 0; j < 31; j++ ) {
205        r += Math.pow( 2, j ) * Number(bin.charAt(31-j));
206    }
207
208    return r;
209}
210function ToUint32Decimal( bin ) {
211    var r = 0;
212
213    for ( l = bin.length; l < 32; l++ ) {
214        bin = "0" + bin;
215    }
216
217    for ( j = 0; j < 31; j++ ) {
218        r += Math.pow( 2, j ) * Number(bin.charAt(31-j));
219    }
220
221    return r;
222}
223function SignedRightShift( s, a ) {
224    s = ToInt32( s );
225    a = ToUint32( a );
226    a = Mask( a, 5 );
227    return ( SignedRShift( s, a ) );
228}
229function SignedRShift( s, a ) {
230    s = ToInt32BitString( s );
231
232    var firstbit = s.substring(0,1);
233
234    s = s.substring( 1, s.length );
235
236    for ( var z = 0; z < a; z++ ) {
237        s = firstbit + s;
238    }
239
240    s = s.substring( 0, s.length - a);
241
242    s = firstbit +s;
243
244
245    return ToInt32(ToInt32Decimal(s));
246}