tagged release 0.6.4
[parrot.git] / t / pmc / n_arithmetics.t
bloba17d861ee725cb6179e089d30a1c02497837b05a
1 #! parrot
2 # Copyright (C) 2001-2008, The Perl Foundation.
3 # $Id$
5 =head1 NAME
7 t/pmc/n_arithmetics.t - n_* Arithmetic Ops
9 =head1 SYNOPSIS
11     % prove t/pmc/n_arithmetics.t
13 =head1 DESCRIPTION
15 Tests basic arithmetic ops that construct a new return value on
16 various combinations of Parrot integer and number types.
18 =cut
21 .sub main :main
22     .include 'include/test_more.pir'
24     plan(73)
26     take_the_negative_of_an_integer()
27     take_the_absolute_value_of_an_integer()
28     add_integer_to_integer()
29     subtract_integer_from_integer()
30     multiply_integer_by_integer()
31     divide_integer_by_integer()
32     negate_a_float()
33     take_the_absolute_value_of_a_float()
34     add_integer_to_float()
35     subtract_integer_from_float()
36     multiply_float_by_integer()
37     divide_float_by_integer()
38     add_float_to_float()
39     add_sub_mul_div_of_float_with_constants()
40     subtract_float_from_float()
41     multiply_float_by_float()
42     divide_float_by_float()
43     verify_new_pmc()
44 .end
46 ###
47 ### Operations on a single INTVAL
48 ###
49 .sub take_the_negative_of_an_integer
50     P0 = new 'Integer'
51     ## negate zero.
52     set P0, 0
53     n_neg P1, P0
54     is( P1, 0, 'negavite of zero is zero' )
55     P30 = P1
56     ## negate a positive number.
57     set P0, 1234567890
58     n_neg P1, P0
59     is( P1, -1234567890, 'negavite of positive' )
60     ## check that we are not reusing P1.
61     ne_addr P30, P1, not_broken
62     ok( 0, 'not reusing P1' )
63     goto not_broken__done
64   not_broken:
65     ok( 1, 'not reusing P1' )
66   not_broken__done:
67     ## negate a negative number.
68     set P0, -1234567890
69     P1 = n_neg P0
70     is( P1, 1234567890, 'negative of negative' )
71 .end
73 .sub take_the_absolute_value_of_an_integer
74     P0 = new 'Integer'
75     ## find absolute zero (so to speak).
76     set P0, 0
77     P1 = n_abs P0
78     is( P1, 0, 'abs of zero' )
79     P30 = P1
80     ## find the absolute value of a positive Integer.
81     set P0, 1234567890
82     n_abs P1, P0
83     is( P1, 1234567890, 'abs of positive' )
84     ## check that we are not reusing P1.
85     ne_addr P30, P1, not_broken
86     ok( 0, 'not reusing P1' )
87     goto not_broken__done
88   not_broken:
89     ok( 1, 'not reusing P1' )
90   not_broken__done:
91     ## find the absolute value of a negative number.
92     set P0, -1234567890
93     n_abs P1, P0
94     is( P1, 1234567890, 'abs of negative' )
95 .end
97 ###
98 ### first arg is Integer, second arg is Integer
99 ###
100 .sub add_integer_to_integer
101     P0 = new 'Integer'
102     set P0, 4000
103     P1 = new 'Integer'
104     set P1, -123
105     P2 = new 'Integer'
106     set P2, 666
107     n_add P2, P0, P1
108     is( P2, 3877, 'add integer to integer' )
109     P30 = P2
110     P2 = n_add P0, P1
111     is( P2, 3877, 'add integer to integer in assignment' )
112     ## check that we are not reusing P2.
113     ne_addr P30, P2, not_broken
114     ok( 0, 'not reusing P2' )
115     goto not_broken__done
116   not_broken:
117     ok( 1, 'not reusing P2' )
118   not_broken__done:
119     ## check adding constants.
120     P2 = n_add P0, 11
121     is( P2, 4011, 'adding integer and constant' )
122     P0 = n_add P0, 11
123     is( P0, 4011, 'adding integer and constant and assign to Int arg' )
124 .end
126 .sub subtract_integer_from_integer
127     P0 = new 'Integer'
128     set P0, 4000
129     P1 = new 'Integer'
130     set P1, -123
131     P2 = new 'Integer'
132     set P2, 666
133     n_sub P2, P0, P1
134     is( P2, 4123, 'subtract Integer from Integer' )
135     P30 = P2
136     P2 = n_sub P0, P1
137     is( P2, 4123, 'subtract Integer from Integer in assignment' )
138     ## check that we are not reusing P2.
139     ne_addr P30, P2, not_broken
140     ok( 0, 'not reusing P2' )
141     goto not_broken__done
142   not_broken:
143     ok( 1, 'not reusing P2' )
144   not_broken__done:
145     ## check subtracting constants.
146     P2 = n_sub P0, 11
147     is( P2, 3989, 'subtract constant from Integer' )
148     P0 = n_sub P0, 11
149     is( P2, 3989, 'subtract constant from Integer and assign to Int arg' )
150 .end
152 .sub multiply_integer_by_integer
153     P0 = new 'Integer'
154     set P0, 4000
155     P1 = new 'Integer'
156     set P1, -123
157     P2 = new 'Integer'
158     set P2, 666
159     n_mul P2, P0, P1
160     is( P2, -492000, 'multiply Integer by Integer' )
161     P3 = n_mul P0, P1
162     is( P3, -492000, 'multiply Integer by Integer in assginment' )
163     ## check multiplying constants.
164     P2 = n_mul P0, 11
165     is( P2, 44000, 'multiply Integer by constant' )
166     P0 = n_mul P0, 11
167     is( P0, 44000, 'multiply Integer by constant and assign to Int arg' )
168 .end
170 .sub divide_integer_by_integer
171     P0 = new 'Integer'
172     set P0, 4000
173     P1 = new 'Integer'
174     set P1, -123
175     P2 = new 'Integer'
176     set P2, 666
177     n_div P2, P0, P1
178     is( P2, -32.5203, 'divide Integer by Integer' )
179     P3 = n_div P0, P1
180     is( P3, -32.5203, 'divide Integer by Integer in assignment' )
181     ## check dividing by constants.
182     P2 = n_div P0, 11
183     is( P2, 363.636, 'divide Integer by constant' )
184     P0 = n_div P0, 11
185     is( P0, 363.636, 'divide Integer by constant and assign to Int arg' )
186 .end
189 ### Operations on a single NUMVAL
191 .sub negate_a_float
192     P0 = new 'Float'
193     set P0, 0
194     P1 = n_neg P0
195     is( P1, 0, 'neg of Float 0 is 0' )
196     set P0, -0.0
197     n_neg P1, P0
198     is( P1, 0, 'neg of Float -0.0 is 0' )
199     set P0, 123.4567890
200     P1 = n_neg P0
201     is( P1, -123.4567890, 'neg of positive Float is negative' )
202     set P0, -123.4567890
203     n_neg P1, P0
204     is( P1, 123.4567890, 'neg of negavite Float is positive' )
205 .end
207 .sub take_the_absolute_value_of_a_float
208     P0 = new 'Integer'
209     set P0, 0
210     P1 = n_abs P0
211     is( P1, 0, 'abs value of float 0 is zero' )
212     set P0, -0.0
213     n_abs P1, P0
214     is( P1, 0, 'abs value of float -0.0 is zero' )
215     set P0, 123.45678901
216     n_abs P1, P0
217     is( P1, 123.45678901, 'abs value of positive float is positive' )
218     set P0, -123.45678901
219     P1 = n_abs P0
220     is( P1, 123.45678901, 'abs value of negative float is positive' )
221 .end
224 ### FLOATVAL and INTVAL tests
226 .sub add_integer_to_float
227     P10 = new 'Integer'
228     set P10, 4000
229     P0 = new 'Float'
230     set P0, -123.123
231     n_add P1, P0, P10
232     is( P1, 3876.877, 'add Float and Int' )
233     P30 = P1
234     P1 = n_add P0, P10
235     is( P1, 3876.877, 'add Float and Int in assignment' )
236     ## check that we are not reusing P1.
237     ne_addr P30, P1, not_broken
238     ok( 0, 'not reusing P1' )
239     goto not_broken__done
240   not_broken:
241     ok( 1, 'not reusing P1' )
242   not_broken__done:
243     ##
244     P2 = n_add P10, P0
245     is( P2, 3876.877, 'add Int and Float' )
246     P1 = n_add P1, P10
247     is( P1, 7876.877, 'add Float and Int and assign to Float arg' )
248 .end
250 .sub subtract_integer_from_float
251     P10 = new 'Integer'
252     set P10, 4000
253     P0 = new 'Float'
254     set P0, -123.123
255     n_sub P1, P0, P10
256     is( P1, -4123.123, 'subtract Int from Float' )
257     P30 = P1
258     P1 = n_sub P0, P10
259     is( P1, -4123.123, 'subtract Int from Float in assignment' )
260     ## check that we are not reusing P1.
261     ne_addr P30, P1, not_broken
262     ok( 0, 'not reusing P1' )
263     goto not_broken__done
264   not_broken:
265     ok( 1, 'not reusing P1' )
266   not_broken__done:
267     ##
268     P2 = n_sub P10, P0
269     is( P2, 4123.123, 'subtract Float from Int in assignment' )
270     P1 = n_sub P1, P10
271     is( P1, -8123.123, 'subtract Float from Int and assign to Float arg' )
272 .end
274 .sub multiply_float_by_integer
275     P10 = new 'Integer'
276     set P10, 4000
277     P0 = new 'Float'
278     set P0, -123.123
279     n_mul P1, P0, P10
280     is( P1, -492492, 'multiply Float by Int' )
281     P30 = P1
282     P1 = n_mul P0, P10
283     is( P1, -492492, 'multiply Float by Int in assignment' )
284     ## check that we are not reusing P1.
285     ne_addr P30, P1, not_broken
286     ok( 0, 'not reusing P1' )
287     goto not_broken__done
288   not_broken:
289     ok( 1, 'not reusing P1' )
290   not_broken__done:
291     ##
292     P1 = n_mul P10, P0
293     is( P1, -492492, 'multiply Int by Float in assignment' )
294     P1 = n_mul P1, -2
295     is( P1, 984984, 'multiply Float by const int and assign to Float arg' )
296 .end
298 .sub divide_float_by_integer
299     P10 = new 'Integer'
300     set P10, 4000
301     P0 = new 'Float'
302     set P0, -123.123
303     n_div P1, P0, P10
304     is( P1, -0.0307808, 'divide Float by Int' )
305     P30 = P1
306     P1 = n_div P0, P10
307     is( P1, -0.0307808, 'divide Float by Int in assignment' )
308     ## check that we are not reusing P1.
309     ne_addr P30, P1, not_broken
310     ok( 0, 'not reusing P1' )
311     goto not_broken__done
312   not_broken:
313     ok( 1, 'not reusing P1' )
314   not_broken__done:
315     ##
316     P1 = n_div P0, 1
317     is( P1, -123.123, 'divide Float by constant Int 1' )
318     set P0, 100.000
319     P1 = n_div P0, 100
320     is( P1, 1, 'divide Float by constant Int' )
321     P1 = n_div P1, 0.01
322     is( P1, 100, 'divide Float by constant Float' )
323 .end
326 ### FLOATVAL and FLOATVAL tests
328 .sub add_float_to_float
329     P0 = new 'Float'
330     set P0, 4000.246
331     P1 = new 'Float'
332     set P1, -123.123
333     P2 = new 'Float'
334     set P2, 6.66
335     n_add P2, P0, P1
336     is( P2, 3877.123, 'add Float to Float' )
337     P30 = P2
338     P2 = n_add P0, P1
339     is( P2, 3877.123, 'add Float to Float in assignment' )
340     ## check that we are not reusing P2.
341     ne_addr P30, P2, not_broken
342     ok( 0, 'not reusing P2' )
343     goto not_broken__done
344   not_broken:
345     ok( 1, 'not reusing P2' )
346   not_broken__done:
347     ##
348 .end
350 ## This tests n_infix_ic_p_p_nc for n_add, n_sub, n_mul, and n_div.  Note that
351 ## there is no n_infix_ic_p_nc_p op; the PMC argument always comes first.
352 .sub add_sub_mul_div_of_float_with_constants
353     P0 = new 'Float'
354     set P0, 4000.246
355     P1 = new 'Float'
356     set P1, -123.123
357     P2 = n_add P1, 6.78
358     is( P2, -116.343, 'add neg Float to constant Float' )
359     P2 = n_add P0, 6.78
360     is( P2,  4007.03, 'add pos Float to constant Float' )
361     P2 = n_mul P1, 6.78
362     is( P2, -834.774, 'multily Float by constant Float' )
363     P2 = n_div P0, 6.78
364     is( P2,  590.007, 'divide Float by constant Float' )
365 .end
367 .sub subtract_float_from_float
368     P0 = new 'Float'
369     set P0, 4000.246
370     P1 = new 'Float'
371     set P1, -123.123
372     P2 = new 'Float'
373     set P2, 6.66
374     n_sub P2, P0, P1
375     is( P2, 4123.369, 'subtract Float from Float' )
376     P30 = P2
377     P2 = n_sub P1, P0
378     is( P2, 4123.369, 'subtract Float from Float in assignment' )
379     ## check that we are not reusing P2.
380     ne_addr P30, P2, not_broken
381     ok( 0, 'not reusing P2' )
382     goto not_broken__done
383   not_broken:
384     ok( 1, 'not reusing P2' )
385   not_broken__done:
386     ##
387 .end
389 .sub multiply_float_by_float
390     P0 = new 'Float'
391     set P0, 400.0246
392     P1 = new 'Float'
393     set P1, -123.123
394     P2 = new 'Float'
395     set P2, 6.66
396     n_mul P2, P0, P1
397     is( P2, -49252.229, 'multiply Float from Float' )
398     P30 = P2
399     P2 = n_mul P0, P1
400     is( P2, -49252.229, 'muliply Float from Float in assignment' )
401     ## check that we are not reusing P2.
402     ne_addr P30, P2, not_broken
403     ok( 0, 'not reusing P2' )
404     goto not_broken__done
405   not_broken:
406     ok( 1, 'not reusing P2' )
407   not_broken__done:
408     ##
409 .end
411 .sub divide_float_by_float
412     P0 = new 'Float'
413     set P0, 4000.246
414     P1 = new 'Float'
415     set P1, -123.123
416     P2 = new 'Float'
417     set P2, 6.66
418     n_div P2, P1, P0
419     is( P2, -0.0307789, 'divide neg Float by pos Float' )
420     P30 = P2
421     P2 = n_div P0, P1
422     is( P2, -32.4898, 'divide pos Float by neg Float in assignment' )
423     ## check that we are not reusing P2.
424     ne_addr P30, P2, not_broken
425     ok( 0, 'not reusing P2' )
426     goto not_broken__done
427   not_broken:
428     ok( 1, 'not reusing P2' )
429   not_broken__done:
430     ##
431 .end
433 .sub verify_new_pmc
434     P0 = new 'Integer'
435     P1 = P0
436     P0 = n_add P0, 1
437     is( P0, 1, 'add constant to new (unassigned) PMC' )
438     eq_addr P0, P1, nok
439       ok( 1, 'variables have different addresses' )
440       .return() 
441   nok:
442     ok( 0, 'variables have different addresses' )
443 .end
445 ### Tests of ".pragma n_operators 1" moved to n_operators.t
447 # Local Variables:
448 #   mode: pir
449 #   fill-column: 100
450 # End:
451 # vim: expandtab shiftwidth=4 ft=pir: