Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/tests/mathop.test @ 68

Last change on this file since 68 was 25, checked in by landauf, 16 years ago

added tcl to libs

File size: 52.6 KB
Line 
1# Commands covered: ::tcl::mathop::...
2#
3# This file contains a collection of tests for one or more of the Tcl built-in
4# commands. Sourcing this file into Tcl runs the tests and generates output
5# for errors. No output means no errors were found.
6#
7# Copyright (c) 2006 Donal K. Fellows
8# Copyright (c) 2006 Peter Spjuth
9#
10# See the file "license.terms" for information on usage and redistribution of
11# this file, and for a DISCLAIMER OF ALL WARRANTIES.
12#
13# RCS: @(#) $Id: mathop.test,v 1.11 2007/12/13 15:26:06 dgp Exp $
14
15if {[lsearch [namespace children] ::tcltest] == -1} {
16    package require tcltest 2.1
17    namespace import -force ::tcltest::*
18}
19
20# A namespace to test that operators are exported and that they
21# work when imported
22namespace eval ::testmathop2 {
23    namespace import ::tcl::mathop::*
24}
25
26# Helper to test math ops.
27# Test different invokation variants and see that they do the same thing.
28# Byte compiled / non byte compiled version
29# Shared / unshared arguments
30# Original / imported
31proc TestOp {op args} {
32    set results {}
33
34    # Non byte compiled version, shared args
35    if {[catch {::tcl::mathop::$op {*}$args} res]} {
36        append res " $::errorCode"
37    }
38    lappend results $res
39
40    # Non byte compiled version, unshared args
41    set cmd ::tcl::mathop::\$op
42    foreach arg $args {
43        append cmd " \[format %s [list $arg]\]"
44    }
45    if {[catch $cmd res]} {
46        append res " $::errorCode"
47    }
48    lappend results $res
49
50    # Non byte compiled imported
51    if {[catch {::testmathop2::$op {*}$args} res]} {
52        append res " $::errorCode"
53    }
54    lappend results [string map {testmathop2 tcl::mathop} $res]
55
56    # BC version
57    set argList1 {}
58    set argList2 {}
59    set argList3 {}
60    for {set t 0} {$t < [llength $args]} {incr t} {
61        lappend argList1 a$t
62        lappend argList2 \$a$t
63        lappend argList3 "\[format %s \$a$t\]"
64    }
65    # Shared args
66    proc _TestOp  $argList1 "::tcl::mathop::$op [join $argList2]"
67    # Unshared args
68    proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
69    # Imported
70    proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"
71
72    set ::tcl_traceCompile 0  ;# Set to 2 to help with debug
73    if {[catch {_TestOp {*}$args} res]} {
74        append res " $::errorCode"
75    }
76    set ::tcl_traceCompile 0
77    lappend results $res
78
79    if {[catch {_TestOp2 {*}$args} res]} {
80        append res " $::errorCode"
81    }
82    lappend results $res
83
84    if {[catch {_TestOp3 {*}$args} res]} {
85        append res " $::errorCode"
86    }
87    lappend results [string map {testmathop2 tcl::mathop} $res]
88
89    # Check that they do the same
90    set len [llength $results]
91    for {set i 0} {$i < ($len - 1)} {incr i} {
92        set res1 [lindex $results $i]
93        set res2 [lindex $results $i+1]
94        if {$res1 ne $res2} {
95            return "$i:($res1 != $res2)"
96        }
97    }
98    return [lindex $results 0]
99}
100
101# start of tests
102
103namespace eval ::testmathop {
104    namespace path ::tcl::mathop
105    variable op ;# stop surprises!
106
107    test mathop-1.1 {compiled +} { + } 0
108    test mathop-1.2 {compiled +} { + 1 } 1
109    test mathop-1.3 {compiled +} { + 1 2 } 3
110    test mathop-1.4 {compiled +} { + 1 2 3 } 6
111    test mathop-1.5 {compiled +} { + 1.0 2 3 } 6.0
112    test mathop-1.6 {compiled +} { + 1 2 3.0 } 6.0
113    test mathop-1.7 {compiled +} { + 100000000000 2 3 } 100000000005
114    test mathop-1.8 {compiled +} { + 1 2 300000000000 } 300000000003
115    test mathop-1.9 {compiled +} { + 1000000000000000000000 2 3 } 1000000000000000000005
116    test mathop-1.10 {compiled +} { + 1 2 3000000000000000000000 } 3000000000000000000003
117    test mathop-1.11 {compiled +: errors} -returnCodes error -body {
118        + x 0
119    } -result {can't use non-numeric string as operand of "+"}
120    test mathop-1.12 {compiled +: errors} -returnCodes error -body {
121        + nan 0
122    } -result {can't use non-numeric floating-point value as operand of "+"}
123    test mathop-1.13 {compiled +: errors} -returnCodes error -body {
124        + 0 x
125    } -result {can't use non-numeric string as operand of "+"}
126    test mathop-1.14 {compiled +: errors} -returnCodes error -body {
127        + 0 nan
128    } -result {can't use non-numeric floating-point value as operand of "+"}
129    test mathop-1.15 {compiled +: errors} -returnCodes error -body {
130        + 0o8 0
131    } -result {can't use invalid octal number as operand of "+"}
132    test mathop-1.16 {compiled +: errors} -returnCodes error -body {
133        + 0 0o8
134    } -result {can't use invalid octal number as operand of "+"}
135    test mathop-1.17 {compiled +: errors} -returnCodes error -body {
136        + 0 [error expectedError]
137    } -result expectedError
138    test mathop-1.18 {compiled +: argument processing order} -body {
139        # Bytecode compilation known hard for 3+ arguments
140        list [catch {
141            + [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
142        } msg] $msg $x
143    } -result {1 expected 2}
144    set op +
145    test mathop-1.19 {interpreted +} { $op } 0
146    test mathop-1.20 {interpreted +} { $op 1 } 1
147    test mathop-1.21 {interpreted +} { $op 1 2 } 3
148    test mathop-1.22 {interpreted +} { $op 1 2 3 } 6
149    test mathop-1.23 {interpreted +} { $op 1.0 2 3 } 6.0
150    test mathop-1.24 {interpreted +} { $op 1 2 3.0 } 6.0
151    test mathop-1.25 {interpreted +} { $op 100000000000 2 3 } 100000000005
152    test mathop-1.26 {interpreted +} { $op 1 2 300000000000 } 300000000003
153    test mathop-1.27 {interpreted +} { $op 1000000000000000000000 2 3 } 1000000000000000000005
154    test mathop-1.28 {interpreted +} { $op 1 2 3000000000000000000000 } 3000000000000000000003
155    test mathop-1.29 {interpreted +: errors} -returnCodes error -body {
156        $op x 0
157    } -result {can't use non-numeric string as operand of "+"}
158    test mathop-1.30 {interpreted +: errors} -returnCodes error -body {
159        $op nan 0
160    } -result {can't use non-numeric floating-point value as operand of "+"}
161    test mathop-1.31 {interpreted +: errors} -returnCodes error -body {
162        $op 0 x
163    } -result {can't use non-numeric string as operand of "+"}
164    test mathop-1.32 {interpreted +: errors} -returnCodes error -body {
165        $op 0 nan
166    } -result {can't use non-numeric floating-point value as operand of "+"}
167    test mathop-1.33 {interpreted +: errors} -returnCodes error -body {
168        $op 0o8 0
169    } -result {can't use invalid octal number as operand of "+"}
170    test mathop-1.34 {interpreted +: errors} -returnCodes error -body {
171        $op 0 0o8
172    } -result {can't use invalid octal number as operand of "+"}
173    test mathop-1.35 {interpreted +: errors} -returnCodes error -body {
174        $op 0 [error expectedError]
175    } -result expectedError
176    test mathop-1.36 {interpreted +: argument processing order} -body {
177        list [catch {
178            $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
179        } msg] $msg $x
180    } -result {1 expected 2}
181
182    test mathop-2.1 {compiled *} { * } 1
183    test mathop-2.2 {compiled *} { * 2 } 2
184    test mathop-2.3 {compiled *} { * 2 3 } 6
185    test mathop-2.4 {compiled *} { * 2 3 4 } 24
186    test mathop-2.5 {compiled *} { * 1.0 2 3 } 6.0
187    test mathop-2.6 {compiled *} { * 1 2 3.0 } 6.0
188    test mathop-2.7 {compiled *} { * 100000000000 2 3 } 600000000000
189    test mathop-2.8 {compiled *} { * 1 2 300000000000 } 600000000000
190    test mathop-2.9 {compiled *} { * 1000000000000000000000 2 3 } 6000000000000000000000
191    test mathop-2.10 {compiled *} { * 1 2 3000000000000000000000 } 6000000000000000000000
192    test mathop-2.11 {compiled *: errors} -returnCodes error -body {
193        * x 0
194    } -result {can't use non-numeric string as operand of "*"}
195    test mathop-2.12 {compiled *: errors} -returnCodes error -body {
196        * nan 0
197    } -result {can't use non-numeric floating-point value as operand of "*"}
198    test mathop-2.13 {compiled *: errors} -returnCodes error -body {
199        * 0 x
200    } -result {can't use non-numeric string as operand of "*"}
201    test mathop-2.14 {compiled *: errors} -returnCodes error -body {
202        * 0 nan
203    } -result {can't use non-numeric floating-point value as operand of "*"}
204    test mathop-2.15 {compiled *: errors} -returnCodes error -body {
205        * 0o8 0
206    } -result {can't use invalid octal number as operand of "*"}
207    test mathop-2.16 {compiled *: errors} -returnCodes error -body {
208        * 0 0o8
209    } -result {can't use invalid octal number as operand of "*"}
210    test mathop-2.17 {compiled *: errors} -returnCodes error -body {
211        * 0 [error expectedError]
212    } -result expectedError
213    test mathop-2.18 {compiled *: argument processing order} -body {
214        # Bytecode compilation known hard for 3+ arguments
215        list [catch {
216            * [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
217        } msg] $msg $x
218    } -result {1 expected 2}
219    set op *
220    test mathop-2.19 {interpreted *} { $op } 1
221    test mathop-2.20 {interpreted *} { $op 2 } 2
222    test mathop-2.21 {interpreted *} { $op 2 3 } 6
223    test mathop-2.22 {interpreted *} { $op 2 3 4 } 24
224    test mathop-2.23 {interpreted *} { $op 1.0 2 3 } 6.0
225    test mathop-2.24 {interpreted *} { $op 1 2 3.0 } 6.0
226    test mathop-2.25 {interpreted *} { $op 100000000000 2 3 } 600000000000
227    test mathop-2.26 {interpreted *} { $op 1 2 300000000000 } 600000000000
228    test mathop-2.27 {interpreted *} { $op 1000000000000000000000 2 3 } 6000000000000000000000
229    test mathop-2.28 {interpreted *} { $op 1 2 3000000000000000000000 } 6000000000000000000000
230    test mathop-2.29 {interpreted *: errors} -returnCodes error -body {
231        $op x 0
232    } -result {can't use non-numeric string as operand of "*"}
233    test mathop-2.30 {interpreted *: errors} -returnCodes error -body {
234        $op nan 0
235    } -result {can't use non-numeric floating-point value as operand of "*"}
236    test mathop-2.31 {interpreted *: errors} -returnCodes error -body {
237        $op 0 x
238    } -result {can't use non-numeric string as operand of "*"}
239    test mathop-2.32 {interpreted *: errors} -returnCodes error -body {
240        $op 0 nan
241    } -result {can't use non-numeric floating-point value as operand of "*"}
242    test mathop-2.33 {interpreted *: errors} -returnCodes error -body {
243        $op 0o8 0
244    } -result {can't use invalid octal number as operand of "*"}
245    test mathop-2.34 {interpreted *: errors} -returnCodes error -body {
246        $op 0 0o8
247    } -result {can't use invalid octal number as operand of "*"}
248    test mathop-2.35 {interpreted *: errors} -returnCodes error -body {
249        $op 0 [error expectedError]
250    } -result expectedError
251    test mathop-2.36 {interpreted *: argument processing order} -body {
252        list [catch {
253            $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
254        } msg] $msg $x
255    } -result {1 expected 2}
256
257    test mathop-3.1 {compiled !} {! 0} 1
258    test mathop-3.2 {compiled !} {! 1} 0
259    test mathop-3.3 {compiled !} {! false} 1
260    test mathop-3.4 {compiled !} {! true} 0
261    test mathop-3.5 {compiled !} {! 0.0} 1
262    test mathop-3.6 {compiled !} {! 10000000000} 0
263    test mathop-3.7 {compiled !} {! 10000000000000000000000000} 0
264    test mathop-3.8 {compiled !: errors} -body {
265        ! foobar
266    } -returnCodes error -result {can't use non-numeric string as operand of "!"}
267    test mathop-3.9 {compiled !: errors} -body {
268        ! 0 0
269    } -returnCodes error -result "wrong # args: should be \"! boolean\""
270    test mathop-3.10 {compiled !: errors} -body {
271        !
272    } -returnCodes error -result "wrong # args: should be \"! boolean\""
273    set op !
274    test mathop-3.11 {interpreted !} {$op 0} 1
275    test mathop-3.12 {interpreted !} {$op 1} 0
276    test mathop-3.13 {interpreted !} {$op false} 1
277    test mathop-3.14 {interpreted !} {$op true} 0
278    test mathop-3.15 {interpreted !} {$op 0.0} 1
279    test mathop-3.16 {interpreted !} {$op 10000000000} 0
280    test mathop-3.17 {interpreted !} {$op 10000000000000000000000000} 0
281    test mathop-3.18 {interpreted !: errors} -body {
282        $op foobar
283    } -returnCodes error -result {can't use non-numeric string as operand of "!"}
284    test mathop-3.19 {interpreted !: errors} -body {
285        $op 0 0
286    } -returnCodes error -result "wrong # args: should be \"! boolean\""
287    test mathop-3.20 {interpreted !: errors} -body {
288        $op
289    } -returnCodes error -result "wrong # args: should be \"! boolean\""
290    test mathop-3.21 {compiled !: error} -returnCodes error -body {
291        ! NaN
292    } -result {can't use non-numeric floating-point value as operand of "!"}
293    test mathop-3.22 {interpreted !: error} -returnCodes error -body {
294        $op NaN
295    } -result {can't use non-numeric floating-point value as operand of "!"}
296
297    test mathop-4.1 {compiled ~} {~ 0} -1
298    test mathop-4.2 {compiled ~} {~ 1} -2
299    test mathop-4.3 {compiled ~} {~ 31} -32
300    test mathop-4.4 {compiled ~} {~ -127} 126
301    test mathop-4.5 {compiled ~} {~ -0} -1
302    test mathop-4.6 {compiled ~} {~ 10000000000} -10000000001
303    test mathop-4.7 {compiled ~} {~ 10000000000000000000000000} -10000000000000000000000001
304    test mathop-4.8 {compiled ~: errors} -body {
305        ~ foobar
306    } -returnCodes error -result {can't use non-numeric string as operand of "~"}
307    test mathop-4.9 {compiled ~: errors} -body {
308        ~ 0 0
309    } -returnCodes error -result "wrong # args: should be \"~ integer\""
310    test mathop-4.10 {compiled ~: errors} -body {
311        ~
312    } -returnCodes error -result "wrong # args: should be \"~ integer\""
313    test mathop-4.11 {compiled ~: errors} -returnCodes error -body {
314        ~ 0.0
315    } -result {can't use floating-point value as operand of "~"}
316    test mathop-4.12 {compiled ~: errors} -returnCodes error -body {
317        ~ NaN
318    } -result {can't use non-numeric floating-point value as operand of "~"}
319    set op ~
320    test mathop-4.13 {interpreted ~} {$op 0} -1
321    test mathop-4.14 {interpreted ~} {$op 1} -2
322    test mathop-4.15 {interpreted ~} {$op 31} -32
323    test mathop-4.16 {interpreted ~} {$op -127} 126
324    test mathop-4.17 {interpreted ~} {$op -0} -1
325    test mathop-4.18 {interpreted ~} {$op 10000000000} -10000000001
326    test mathop-4.19 {interpreted ~} {$op 10000000000000000000000000} -10000000000000000000000001
327    test mathop-4.20 {interpreted ~: errors} -body {
328        $op foobar
329    } -returnCodes error -result {can't use non-numeric string as operand of "~"}
330    test mathop-4.21 {interpreted ~: errors} -body {
331        $op 0 0
332    } -returnCodes error -result "wrong # args: should be \"~ integer\""
333    test mathop-4.22 {interpreted ~: errors} -body {
334        $op
335    } -returnCodes error -result "wrong # args: should be \"~ integer\""
336    test mathop-4.23 {interpreted ~: errors} -returnCodes error -body {
337        $op 0.0
338    } -result {can't use floating-point value as operand of "~"}
339    test mathop-4.24 {interpreted ~: errors} -returnCodes error -body {
340        $op NaN
341    } -result {can't use non-numeric floating-point value as operand of "~"}
342
343    test mathop-5.1 {compiled eq} {eq {} a} 0
344    test mathop-5.2 {compiled eq} {eq a a} 1
345    test mathop-5.3 {compiled eq} {eq a {}} 0
346    test mathop-5.4 {compiled eq} {eq a b} 0
347    test mathop-5.5 {compiled eq} { eq } 1
348    test mathop-5.6 {compiled eq} {eq a} 1
349    test mathop-5.7 {compiled eq} {eq a a a} 1
350    test mathop-5.8 {compiled eq} {eq a a b} 0
351    test mathop-5.9 {compiled eq} -body {
352        eq a b [error foobar]
353    } -returnCodes error -result foobar
354    test mathop-5.10 {compiled eq} {eq NaN Na NaN} 0
355    set op eq
356    test mathop-5.11 {interpreted eq} {$op {} a} 0
357    test mathop-5.12 {interpreted eq} {$op a a} 1
358    test mathop-5.13 {interpreted eq} {$op a {}} 0
359    test mathop-5.14 {interpreted eq} {$op a b} 0
360    test mathop-5.15 {interpreted eq} { $op } 1
361    test mathop-5.16 {interpreted eq} {$op a} 1
362    test mathop-5.17 {interpreted eq} {$op a a a} 1
363    test mathop-5.18 {interpreted eq} {$op a a b} 0
364    test mathop-5.19 {interpreted eq} -body {
365        $op a b [error foobar]
366    } -returnCodes error -result foobar
367    test mathop-5.20 {interpreted eq} {$op NaN Na NaN} 0
368
369    variable big1      12135435435354435435342423948763867876
370    variable big2       2746237174783836746262564892918327847
371    variable wide1                             12345678912345
372    variable wide2                             87321847232215
373    variable small1                                     87345
374    variable small2                                     16753
375
376    test mathop-6.1 {compiled &} { & } -1
377    test mathop-6.2 {compiled &} { & 1 } 1
378    test mathop-6.3 {compiled &} { & 1 2 } 0
379    test mathop-6.4 {compiled &} { & 3 7 6 } 2
380    test mathop-6.5 {compiled &} -returnCodes error -body {
381        & 1.0 2 3
382    } -result {can't use floating-point value as operand of "&"}
383    test mathop-6.6 {compiled &} -returnCodes error -body {
384        & 1 2 3.0
385    } -result {can't use floating-point value as operand of "&"}
386    test mathop-6.7 {compiled &} { & 100000000002 18 -126 } 2
387    test mathop-6.8 {compiled &} { & 0xff 0o377 333333333333 } 85
388    test mathop-6.9 {compiled &} { & 1000000000000000000002 18 -126 } 2
389    test mathop-6.10 {compiled &} { & 0xff 0o377 3333333333333333333333 } 85
390    test mathop-6.11 {compiled &: errors} -returnCodes error -body {
391        & x 0
392    } -result {can't use non-numeric string as operand of "&"}
393    test mathop-6.12 {compiled &: errors} -returnCodes error -body {
394        & nan 0
395    } -result {can't use non-numeric floating-point value as operand of "&"}
396    test mathop-6.13 {compiled &: errors} -returnCodes error -body {
397        & 0 x
398    } -result {can't use non-numeric string as operand of "&"}
399    test mathop-6.14 {compiled &: errors} -returnCodes error -body {
400        & 0 nan
401    } -result {can't use non-numeric floating-point value as operand of "&"}
402    test mathop-6.15 {compiled &: errors} -returnCodes error -body {
403        & 0o8 0
404    } -result {can't use invalid octal number as operand of "&"}
405    test mathop-6.16 {compiled &: errors} -returnCodes error -body {
406        & 0 0o8
407    } -result {can't use invalid octal number as operand of "&"}
408    test mathop-6.17 {compiled &: errors} -returnCodes error -body {
409        & 0 [error expectedError]
410    } -result expectedError
411    test mathop-6.18 {compiled &: argument processing order} -body {
412        # Bytecode compilation known hard for 3+ arguments
413        list [catch {
414            & [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
415        } msg] $msg $x
416    } -result {1 expected 2}
417    set op &
418    test mathop-6.19 {interpreted &} { $op } -1
419    test mathop-6.20 {interpreted &} { $op 1 } 1
420    test mathop-6.21 {interpreted &} { $op 1 2 } 0
421    test mathop-6.22 {interpreted &} { $op 3 7 6 } 2
422    test mathop-6.23 {interpreted &} -returnCodes error -body {
423        $op 1.0 2 3
424    } -result {can't use floating-point value as operand of "&"}
425    test mathop-6.24 {interpreted &} -returnCodes error -body {
426        $op 1 2 3.0
427    } -result {can't use floating-point value as operand of "&"}
428    test mathop-6.25 {interpreted &} { $op 100000000002 18 -126 } 2
429    test mathop-6.26 {interpreted &} { $op 0xff 0o377 333333333333 } 85
430    test mathop-6.27 {interpreted &} { $op 1000000000000000000002 18 -126 } 2
431    test mathop-6.28 {interpreted &} { $op 0xff 0o377 3333333333333333333333 } 85
432    test mathop-6.29 {interpreted &: errors} -returnCodes error -body {
433        $op x 0
434    } -result {can't use non-numeric string as operand of "&"}
435    test mathop-6.30 {interpreted &: errors} -returnCodes error -body {
436        $op nan 0
437    } -result {can't use non-numeric floating-point value as operand of "&"}
438    test mathop-6.31 {interpreted &: errors} -returnCodes error -body {
439        $op 0 x
440    } -result {can't use non-numeric string as operand of "&"}
441    test mathop-6.32 {interpreted &: errors} -returnCodes error -body {
442        $op 0 nan
443    } -result {can't use non-numeric floating-point value as operand of "&"}
444    test mathop-6.33 {interpreted &: errors} -returnCodes error -body {
445        $op 0o8 0
446    } -result {can't use invalid octal number as operand of "&"}
447    test mathop-6.34 {interpreted &: errors} -returnCodes error -body {
448        $op 0 0o8
449    } -result {can't use invalid octal number as operand of "&"}
450    test mathop-6.35 {interpreted &: errors} -returnCodes error -body {
451        $op 0 [error expectedError]
452    } -result expectedError
453    test mathop-6.36 {interpreted &: argument processing order} -body {
454        list [catch {
455            $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
456        } msg] $msg $x
457    } -result {1 expected 2}
458    test mathop-6.37 {& and bignums} {
459        list [& $big1 $big2] [$op $big1 $big2]
460    } {712439449294653815890598856501796 712439449294653815890598856501796}
461    test mathop-6.38 {& and bignums} {
462        list [& $big1 $wide2] [$op $big1 $wide2]
463    } {78521450111684 78521450111684}
464    test mathop-6.39 {& and bignums} {
465        list [& $big1 $small2] [$op $big1 $small2]
466    } {96 96}
467    test mathop-6.40 {& and bignums} {
468        list [& $wide1 $big2] [$op $wide1 $big2]
469    } {2371422390785 2371422390785}
470    test mathop-6.41 {& and bignums} {
471        list [& $wide1 $wide2] [$op $wide1 $wide2]
472    } {12275881497169 12275881497169}
473    test mathop-6.42 {& and bignums} {
474        list [& $wide1 $small2] [$op $wide1 $small2]
475    } {16721 16721}
476    test mathop-6.43 {& and bignums} {
477        list [& $small1 $big2] [$op $small1 $big2]
478    } {33 33}
479    test mathop-6.44 {& and bignums} {
480        list [& $small1 $wide2] [$op $small1 $wide2]
481    } {87057 87057}
482    test mathop-6.45 {& and bignums} {
483        list [& $small1 $small2] [$op $small1 $small2]
484    } {16689 16689}
485
486    test mathop-7.1 {compiled |} { | } 0
487    test mathop-7.2 {compiled |} { | 1 } 1
488    test mathop-7.3 {compiled |} { | 1 2 } 3
489    test mathop-7.4 {compiled |} { | 3 7 6 } 7
490    test mathop-7.5 {compiled |} -returnCodes error -body {
491        | 1.0 2 3
492    } -result {can't use floating-point value as operand of "|"}
493    test mathop-7.6 {compiled |} -returnCodes error -body {
494        | 1 2 3.0
495    } -result {can't use floating-point value as operand of "|"}
496    test mathop-7.7 {compiled |} { | 100000000002 18 -126 } -110
497    test mathop-7.8 {compiled |} { | 0xff 0o377 333333333333 } 333333333503
498    test mathop-7.9 {compiled |} { | 1000000000000000000002 18 -126 } -110
499    test mathop-7.10 {compiled |} { | 0xff 0o377 3333333333333333333333 } 3333333333333333333503
500    test mathop-7.11 {compiled |: errors} -returnCodes error -body {
501        | x 0
502    } -result {can't use non-numeric string as operand of "|"}
503    test mathop-7.12 {compiled |: errors} -returnCodes error -body {
504        | nan 0
505    } -result {can't use non-numeric floating-point value as operand of "|"}
506    test mathop-7.13 {compiled |: errors} -returnCodes error -body {
507        | 0 x
508    } -result {can't use non-numeric string as operand of "|"}
509    test mathop-7.14 {compiled |: errors} -returnCodes error -body {
510        | 0 nan
511    } -result {can't use non-numeric floating-point value as operand of "|"}
512    test mathop-7.15 {compiled |: errors} -returnCodes error -body {
513        | 0o8 0
514    } -result {can't use invalid octal number as operand of "|"}
515    test mathop-7.16 {compiled |: errors} -returnCodes error -body {
516        | 0 0o8
517    } -result {can't use invalid octal number as operand of "|"}
518    test mathop-7.17 {compiled |: errors} -returnCodes error -body {
519        | 0 [error expectedError]
520    } -result expectedError
521    test mathop-7.18 {compiled |: argument processing order} -body {
522        # Bytecode compilation known hard for 3+ arguments
523        list [catch {
524            | [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
525        } msg] $msg $x
526    } -result {1 expected 2}
527    set op |
528    test mathop-7.19 {interpreted |} { $op } 0
529    test mathop-7.20 {interpreted |} { $op 1 } 1
530    test mathop-7.21 {interpreted |} { $op 1 2 } 3
531    test mathop-7.22 {interpreted |} { $op 3 7 6 } 7
532    test mathop-7.23 {interpreted |} -returnCodes error -body {
533        $op 1.0 2 3
534    } -result {can't use floating-point value as operand of "|"}
535    test mathop-7.24 {interpreted |} -returnCodes error -body {
536        $op 1 2 3.0
537    } -result {can't use floating-point value as operand of "|"}
538    test mathop-7.25 {interpreted |} { $op 100000000002 18 -126 } -110
539    test mathop-7.26 {interpreted |} { $op 0xff 0o377 333333333333 } 333333333503
540    test mathop-7.27 {interpreted |} { $op 1000000000000000000002 18 -126 } -110
541    test mathop-7.28 {interpreted |} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333503
542    test mathop-7.29 {interpreted |: errors} -returnCodes error -body {
543        $op x 0
544    } -result {can't use non-numeric string as operand of "|"}
545    test mathop-7.30 {interpreted |: errors} -returnCodes error -body {
546        $op nan 0
547    } -result {can't use non-numeric floating-point value as operand of "|"}
548    test mathop-7.31 {interpreted |: errors} -returnCodes error -body {
549        $op 0 x
550    } -result {can't use non-numeric string as operand of "|"}
551    test mathop-7.32 {interpreted |: errors} -returnCodes error -body {
552        $op 0 nan
553    } -result {can't use non-numeric floating-point value as operand of "|"}
554    test mathop-7.33 {interpreted |: errors} -returnCodes error -body {
555        $op 0o8 0
556    } -result {can't use invalid octal number as operand of "|"}
557    test mathop-7.34 {interpreted |: errors} -returnCodes error -body {
558        $op 0 0o8
559    } -result {can't use invalid octal number as operand of "|"}
560    test mathop-7.35 {interpreted |: errors} -returnCodes error -body {
561        $op 0 [error expectedError]
562    } -result expectedError
563    test mathop-7.36 {interpreted |: argument processing order} -body {
564        list [catch {
565            $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
566        } msg] $msg $x
567    } -result {1 expected 2}
568    test mathop-7.37 {| and bignums} {
569        list [| $big1 $big2] [$op $big1 $big2]
570    } {14880960170688977527789098242825693927 14880960170688977527789098242825693927}
571    test mathop-7.38 {| and bignums} {
572        list [| $big1 $wide2] [$op $big1 $wide2]
573    } {12135435435354435435342432749160988407 12135435435354435435342432749160988407}
574    test mathop-7.39 {| and bignums} {
575        list [| $big1 $small2] [$op $big1 $small2]
576    } {12135435435354435435342423948763884533 12135435435354435435342423948763884533}
577    test mathop-7.40 {| and bignums} {
578        list [| $wide1 $big2] [$op $wide1 $big2]
579    } {2746237174783836746262574867174849407 2746237174783836746262574867174849407}
580    test mathop-7.41 {| and bignums} {
581        list [| $wide1 $wide2] [$op $wide1 $wide2]
582    } {87391644647391 87391644647391}
583    test mathop-7.42 {| and bignums} {
584        list [| $wide1 $small2] [$op $wide1 $small2]
585    } {12345678912377 12345678912377}
586    test mathop-7.43 {| and bignums} {
587        list [| $small1 $big2] [$op $small1 $big2]
588    } {2746237174783836746262564892918415159 2746237174783836746262564892918415159}
589    test mathop-7.44 {| and bignums} {
590        list [| $small1 $wide2] [$op $small1 $wide2]
591    } {87321847232503 87321847232503}
592    test mathop-7.45 {| and bignums} {
593        list [| $small1 $small2] [$op $small1 $small2]
594    } {87409 87409}
595
596    test mathop-8.1 {compiled ^} { ^ } 0
597    test mathop-8.2 {compiled ^} { ^ 1 } 1
598    test mathop-8.3 {compiled ^} { ^ 1 2 } 3
599    test mathop-8.4 {compiled ^} { ^ 3 7 6 } 2
600    test mathop-8.5 {compiled ^} -returnCodes error -body {
601        ^ 1.0 2 3
602    } -result {can't use floating-point value as operand of "^"}
603    test mathop-8.6 {compiled ^} -returnCodes error -body {
604        ^ 1 2 3.0
605    } -result {can't use floating-point value as operand of "^"}
606    test mathop-8.7 {compiled ^} { ^ 100000000002 18 -126 } -100000000110
607    test mathop-8.8 {compiled ^} { ^ 0xff 0o377 333333333333 } 333333333333
608    test mathop-8.9 {compiled ^} { ^ 1000000000000000000002 18 -126 } -1000000000000000000110
609    test mathop-8.10 {compiled ^} { ^ 0xff 0o377 3333333333333333333333 } 3333333333333333333333
610    test mathop-8.11 {compiled ^: errors} -returnCodes error -body {
611        ^ x 0
612    } -result {can't use non-numeric string as operand of "^"}
613    test mathop-8.12 {compiled ^: errors} -returnCodes error -body {
614        ^ nan 0
615    } -result {can't use non-numeric floating-point value as operand of "^"}
616    test mathop-8.13 {compiled ^: errors} -returnCodes error -body {
617        ^ 0 x
618    } -result {can't use non-numeric string as operand of "^"}
619    test mathop-8.14 {compiled ^: errors} -returnCodes error -body {
620        ^ 0 nan
621    } -result {can't use non-numeric floating-point value as operand of "^"}
622    test mathop-8.15 {compiled ^: errors} -returnCodes error -body {
623        ^ 0o8 0
624    } -result {can't use invalid octal number as operand of "^"}
625    test mathop-8.16 {compiled ^: errors} -returnCodes error -body {
626        ^ 0 0o8
627    } -result {can't use invalid octal number as operand of "^"}
628    test mathop-8.17 {compiled ^: errors} -returnCodes error -body {
629        ^ 0 [error expectedError]
630    } -result expectedError
631    test mathop-8.18 {compiled ^: argument processing order} -body {
632        # Bytecode compilation known hard for 3+ arguments
633        list [catch {
634            ^ [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
635        } msg] $msg $x
636    } -result {1 expected 2}
637    set op ^
638    test mathop-8.19 {interpreted ^} { $op } 0
639    test mathop-8.20 {interpreted ^} { $op 1 } 1
640    test mathop-8.21 {interpreted ^} { $op 1 2 } 3
641    test mathop-8.22 {interpreted ^} { $op 3 7 6 } 2
642    test mathop-8.23 {interpreted ^} -returnCodes error -body {
643        $op 1.0 2 3
644    } -result {can't use floating-point value as operand of "^"}
645    test mathop-8.24 {interpreted ^} -returnCodes error -body {
646        $op 1 2 3.0
647    } -result {can't use floating-point value as operand of "^"}
648    test mathop-8.25 {interpreted ^} { $op 100000000002 18 -126 } -100000000110
649    test mathop-8.26 {interpreted ^} { $op 0xff 0o377 333333333333 } 333333333333
650    test mathop-8.27 {interpreted ^} { $op 1000000000000000000002 18 -126 } -1000000000000000000110
651    test mathop-8.28 {interpreted ^} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333333
652    test mathop-8.29 {interpreted ^: errors} -returnCodes error -body {
653        $op x 0
654    } -result {can't use non-numeric string as operand of "^"}
655    test mathop-8.30 {interpreted ^: errors} -returnCodes error -body {
656        $op nan 0
657    } -result {can't use non-numeric floating-point value as operand of "^"}
658    test mathop-8.31 {interpreted ^: errors} -returnCodes error -body {
659        $op 0 x
660    } -result {can't use non-numeric string as operand of "^"}
661    test mathop-8.32 {interpreted ^: errors} -returnCodes error -body {
662        $op 0 nan
663    } -result {can't use non-numeric floating-point value as operand of "^"}
664    test mathop-8.33 {interpreted ^: errors} -returnCodes error -body {
665        $op 0o8 0
666    } -result {can't use invalid octal number as operand of "^"}
667    test mathop-8.34 {interpreted ^: errors} -returnCodes error -body {
668        $op 0 0o8
669    } -result {can't use invalid octal number as operand of "^"}
670    test mathop-8.35 {interpreted ^: errors} -returnCodes error -body {
671        $op 0 [error expectedError]
672    } -result expectedError
673    test mathop-8.36 {interpreted ^: argument processing order} -body {
674        list [catch {
675            $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
676        } msg] $msg $x
677    } -result {1 expected 2}
678    test mathop-8.37 {^ and bignums} {
679        list [^ $big1 $big2] [$op $big1 $big2]
680    } {14880247731239682873973207643969192131 14880247731239682873973207643969192131}
681    test mathop-8.38 {^ and bignums} {
682        list [^ $big1 $wide2] [$op $big1 $wide2]
683    } {12135435435354435435342354227710876723 12135435435354435435342354227710876723}
684    test mathop-8.39 {^ and bignums} {
685        list [^ $big1 $small2] [$op $big1 $small2]
686    } {12135435435354435435342423948763884437 12135435435354435435342423948763884437}
687    test mathop-8.40 {^ and bignums} {
688        list [^ $wide1 $big2] [$op $wide1 $big2]
689    } {2746237174783836746262572495752458622 2746237174783836746262572495752458622}
690    test mathop-8.41 {^ and bignums} {
691        list [^ $wide1 $wide2] [$op $wide1 $wide2]
692    } {75115763150222 75115763150222}
693    test mathop-8.42 {^ and bignums} {
694        list [^ $wide1 $small2] [$op $wide1 $small2]
695    } {12345678895656 12345678895656}
696    test mathop-8.43 {^ and bignums} {
697        list [^ $small1 $big2] [$op $small1 $big2]
698    } {2746237174783836746262564892918415126 2746237174783836746262564892918415126}
699    test mathop-8.44 {^ and bignums} {
700        list [^ $small1 $wide2] [$op $small1 $wide2]
701    } {87321847145446 87321847145446}
702    test mathop-8.45 {^ and bignums} {
703        list [^ $small1 $small2] [$op $small1 $small2]
704    } {70720 70720}
705
706    # TODO: % ** << >>  - /  == != < <= > >=  ne  in ni
707
708    test mathop-13.100 {compiled -: argument processing order} -body {
709      # Bytecode compilation known hard for 3+ arguments
710      list [catch {
711          - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
712      } msg] $msg $x
713    } -result {1 expected 2}
714
715    test mathop-14.100 {compiled /: argument processing order} -body {
716      # Bytecode compilation known hard for 3+ arguments
717      list [catch {
718          / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
719      } msg] $msg $x
720    } -result {1 expected 2}
721}
722
723test mathop-20.1 { zero args, return unit } {
724    set res {}
725    foreach op {+ * & ^ | ** < <= > >= == eq} {
726        lappend res [TestOp $op]
727    }
728    set res
729} {0 1 -1 0 0 1 1 1 1 1 1 1}
730test mathop-20.2 { zero args, not allowed } {
731    set exp {}
732    foreach op {~ ! << >> % != ne in ni - /} {
733        set res [TestOp $op]
734        if {[string match "wrong # args* NONE" $res]} {
735            lappend exp 0
736        } else {
737            lappend exp $res
738        }
739    }
740    set exp
741} {0 0 0 0 0 0 0 0 0 0 0}
742test mathop-20.3 { one arg } {
743    set res {}
744    foreach val {7 8.3} {
745        foreach op {+ ** - * / < <= > >= == eq !} {
746            lappend res [TestOp $op $val]
747        }
748    }
749    set res
750} [list 7   7   -7   7   [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
751        8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
752test mathop-20.4 { one arg, integer only ops } {
753    set res {}
754    foreach val {23} {
755        foreach op {& | ^ ~} {
756            lappend res [TestOp $op $val]
757        }
758    }
759    set res
760} [list 23 23 23 -24]
761test mathop-20.5 { one arg, not allowed } {
762    set exp {}
763    foreach op {% != ne in ni << >>} {
764        set res [TestOp $op 1]
765        if {[string match "wrong # args* NONE" $res]} {
766            lappend exp 0
767        } else {
768            lappend exp $res
769        }
770    }
771    set exp
772} {0 0 0 0 0 0 0}
773test mathop-20.6 { one arg, error } {
774    set res {}
775    set exp {}
776    foreach vals {x {1 x} {1 1 x} {1 x 1}} {
777        # skipping - for now, knownbug...
778        foreach op {+ * / & | ^ **} {
779            lappend res [TestOp $op {*}$vals]
780            lappend exp "can't use non-numeric string as operand of \"$op\" NONE"
781        }
782    }
783    expr {$res eq $exp ? 0 : $res}
784} 0
785test mathop-20.7 { multi arg } {
786    set res {}
787    foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
788        foreach op {+ - * /} {
789            lappend res [TestOp $op {*}$vals]
790        }
791    }
792    set res
793} [list 3 -1 2 0  12 -6 60 0  10 -2 24 0]
794test mathop-20.8 { multi arg, double } {
795    set res {}
796    foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
797            {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
798        foreach op {+ - * /} {
799            lappend res [TestOp $op {*}$vals]
800        }
801    }
802    set res
803} [list 3.0 -1.0 2.0 0.5  12.0 -6.0 60.0 0.15  10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]
804
805test mathop-21.1 { unary ops, bitnot } {
806    set res {}
807    lappend res [TestOp ~ 7]
808    lappend res [TestOp ~ -5]
809    lappend res [TestOp ~ 354657483923456]
810    lappend res [TestOp ~ 123456789123456789123456789]
811    set res
812} [list -8 4 -354657483923457 -123456789123456789123456790]
813test mathop-21.2 { unary ops, logical not } {
814    set res {}
815    lappend res [TestOp ! 0]
816    lappend res [TestOp ! 1]
817    lappend res [TestOp ! true]
818    lappend res [TestOp ! false]
819    lappend res [TestOp ! 37]
820    lappend res [TestOp ! 8.5]
821    set res
822} [list 1 0 0 1 0 0]
823test mathop-21.3 { unary ops, negation } {
824    set res {}
825    lappend res [TestOp -  7.2]
826    lappend res [TestOp - -5]
827    lappend res [TestOp - -2147483648]                  ;# -2**31
828    lappend res [TestOp - -9223372036854775808]         ;# -2**63
829    lappend res [TestOp -  354657483923456]             ;# wide
830    lappend res [TestOp -  123456789123456789123456789] ;# big
831    set res
832} [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
833           -123456789123456789123456789]
834test mathop-21.4 { unary ops, inversion } {
835    set res {}
836    lappend res [TestOp / 1]
837    lappend res [TestOp / 5]
838    lappend res [TestOp / 5.6]
839    lappend res [TestOp / -8]
840    lappend res [TestOp /  354657483923456]             ;# wide
841    lappend res [TestOp /  123456789123456789123456789] ;# big
842    set res
843} [list 1.0 0.2 0.17857142857142858 -0.125 \
844           2.8196218755553604e-15 8.10000006561e-27]
845test mathop-21.5 { unary ops, bad values } {
846    set res {}
847    set exp {}
848    lappend res [TestOp / x]
849    lappend exp "can't use non-numeric string as operand of \"/\" NONE"
850    lappend res [TestOp - x]
851    lappend exp "can't use non-numeric string as operand of \"-\" NONE"
852    lappend res [TestOp ~ x]
853    lappend exp "can't use non-numeric string as operand of \"~\" NONE"
854    lappend res [TestOp ! x]
855    lappend exp "can't use non-numeric string as operand of \"!\" NONE"
856    lappend res [TestOp ~ 5.0]
857    lappend exp "can't use floating-point value as operand of \"~\" NONE"
858    expr {$res eq $exp ? 0 : $res}
859} 0
860test mathop-21.6 { unary ops, too many } {
861    set exp {}
862    foreach op {~ !} {
863        set res [TestOp $op 7 8]
864        if {[string match "wrong # args* NONE" $res]} {
865            lappend exp 0
866        } else {
867            lappend exp $res
868        }
869    }
870    set exp
871} {0 0}
872
873test mathop-22.1 { bitwise ops } {
874    set res {}
875    foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
876        foreach op {& | ^} {
877            lappend res [TestOp $op {*}$vals]
878        }
879    }
880    set res
881} [list 5 5 5  0 7 7  0 3 0  0 7 4]
882test mathop-22.2 { bitwise ops on bignums } {
883    set dig 50
884    set a 0x[string repeat 5 $dig]
885    set b 0x[string repeat 7 $dig]
886    set c 0x[string repeat 9 $dig]
887    set bn [expr {~$b}]
888    set cn [expr {~$c}]
889
890    set res {}
891    foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
892                          [list $a $bn] [list $bn $c] [list $bn $cn]] {
893        foreach op {& | ^} {
894            lappend res [TestOp $op {*}$vals]
895        }
896    }
897    set exp {}
898    foreach d {5 7 2  1 D C  1 F E  0 -D -D  8 -9 -1  -0 -E E} {
899        if {[string match "-*" $d]} {
900            set d [format %X [expr 15-0x[string range $d 1 end]]]
901            set val [expr -0x[string repeat $d $dig]-1]
902        } else {
903            set val [expr 0x[string repeat $d $dig]]
904        }
905        lappend exp $val
906    }
907    expr {$exp eq $res ? 1 : "($res != $exp"}
908} 1
909test mathop-22.3 { bitwise ops } {
910    set big1      12135435435354435435342423948763867876
911    set big2       2746237174783836746262564892918327847
912    set wide1                             12345678912345
913    set wide2                             87321847232215
914    set small1                                     87345
915    set small2                                     16753
916
917    set res {}
918    foreach op {& | ^} {
919        lappend res [TestOp $op $big1   $big2]
920        lappend res [TestOp $op $big1   $wide2]
921        lappend res [TestOp $op $big1   $small2]
922        lappend res [TestOp $op $wide1  $big2]
923        lappend res [TestOp $op $wide1  $wide2]
924        lappend res [TestOp $op $wide1  $small2]
925        lappend res [TestOp $op $small1 $big2]
926        lappend res [TestOp $op $small1 $wide2]
927        lappend res [TestOp $op $small1 $small2]
928    }
929    set res
930} [list \
931           712439449294653815890598856501796 \
932           78521450111684 \
933           96 \
934           2371422390785 \
935           12275881497169 \
936           16721 \
937           33 \
938           87057 \
939           16689 \
940           14880960170688977527789098242825693927 \
941           12135435435354435435342432749160988407 \
942           12135435435354435435342423948763884533 \
943           2746237174783836746262574867174849407 \
944           87391644647391 \
945           12345678912377 \
946           2746237174783836746262564892918415159 \
947           87321847232503 \
948           87409 \
949           14880247731239682873973207643969192131 \
950           12135435435354435435342354227710876723 \
951           12135435435354435435342423948763884437 \
952           2746237174783836746262572495752458622 \
953           75115763150222 \
954           12345678895656 \
955           2746237174783836746262564892918415126 \
956           87321847145446 \
957           70720 \
958          ]
959test mathop-22.4 { unary ops, bad values } {
960    set res {}
961    set exp {}
962    foreach op {& | ^} {
963        lappend res [TestOp $op x 5]
964        lappend exp "can't use non-numeric string as operand of \"$op\" NONE"
965        lappend res [TestOp $op 5 x]
966        lappend exp "can't use non-numeric string as operand of \"$op\" NONE"
967    }
968    expr {$res eq $exp ? 0 : $res}
969} 0
970
971test mathop-23.1 { comparison ops, numerical } {
972    set res {}
973    set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
974    lappend todo [list 2342476234762482734623842342 234827463876473 3434]
975    lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
976    lappend todo [list 2653 2384762472634982746239847637]
977    lappend todo [list 2653 -2384762472634982746239847637]
978    lappend todo [list 3789253678212653 -2384762472634982746239847637]
979    lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
980                          6734253647589123456784564378 2.3e50]
981    set a 7
982    lappend todo [list $a $a] ;# Same object
983    foreach vals $todo {
984        foreach op {< <= > >= == eq} {
985            lappend res [TestOp $op {*}$vals]
986        }
987    }
988    set res
989} [list 1 1 1 1 1 1 \
990        1 1 0 0 0 0 \
991        0 1 0 0 0 0 \
992        0 0 1 1 0 0 \
993        0 1 0 1 1 1 \
994        0 0 0 1 0 0 \
995        0 1 0 1 1 0 \
996        0 0 1 1 0 0 \
997        1 1 0 0 0 0 \
998        1 1 0 0 0 0 \
999        0 0 1 1 0 0 \
1000        0 0 1 1 0 0 \
1001        1 1 0 0 0 0 \
1002        0 1 0 1 1 1 \
1003       ]
1004test mathop-23.2 { comparison ops, string } {
1005    set res {}
1006    set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
1007    set a x
1008    lappend todo [list $a $a]
1009    foreach vals $todo {
1010        foreach op {< <= > >= == eq} {
1011            lappend res [TestOp $op {*}$vals]
1012        }
1013    }
1014    set res
1015} [list 1 1 1 1 1 1 \
1016        1 1 0 0 0 0 \
1017        0 1 0 0 0 0 \
1018        0 0 1 1 0 0 \
1019        0 1 0 1 1 1 \
1020        0 0 0 1 0 0 \
1021        0 1 0 1 1 1 \
1022       ]
1023test mathop-23.3 { comparison ops, nonequal} {
1024    set res {}
1025    foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
1026        foreach op {!= ne} {
1027            lappend res [TestOp $op {*}$vals]
1028        }
1029    }
1030    set res
1031} [list 1 1  0 1  0 0  0 0 ]
1032
1033test mathop-24.1 { binary ops } {
1034    set res {}
1035    foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
1036                  {5 1} {0 7}} {
1037        foreach op {% << >> in ni} {
1038            lappend res [TestOp $op {*}$vals]
1039        }
1040    }
1041    set res
1042} [list 3 96 0 0 1  3 2176 0 0 1  4 6368 6 0 1 \
1043        14 38434855421664852505557661908992 2237203031642412097749 0 1 \
1044        0 10 2 0 1  0 0 0 0 1]
1045test mathop-24.2 { binary ops, modulo } {
1046    # Test different combinations to get all code paths
1047    set res {}
1048
1049    set bigbig 14372423674564535234543545248972634923869
1050    set big       12135435435354435435342423948763867876
1051    set wide                              12345678912345
1052    set negwide                          -12345678912345
1053    set small                                          5
1054    set neg                                           -5
1055
1056    lappend res [TestOp % $bigbig  $big]
1057    lappend res [TestOp % $wide    $big]
1058    lappend res [TestOp % $negwide $big]
1059    lappend res [TestOp % $small   $big]
1060    lappend res [TestOp % $neg     $big]
1061    lappend res [TestOp % $small  $wide]
1062    lappend res [TestOp % $neg    $wide]
1063    lappend res [TestOp % $wide  $small]
1064    set res
1065} [list   4068119104883679098115293636215358685 \
1066                                 12345678912345 \
1067         12135435435354435435342411603084955531 \
1068                                              5 \
1069         12135435435354435435342423948763867871 \
1070                                              5 \
1071                                 12345678912340 \
1072                                              0 \
1073          ]
1074test mathop-24.3 { binary ops, bad values } {
1075    set res {}
1076    set exp {}
1077    foreach op {% << >>} {
1078        lappend res [TestOp $op x 1]
1079        lappend exp "can't use non-numeric string as operand of \"$op\" NONE"
1080        lappend res [TestOp $op 1 x]
1081        lappend exp "can't use non-numeric string as operand of \"$op\" NONE"
1082    }
1083    foreach op {% << >>} {
1084        lappend res [TestOp $op 5.0 1]
1085        lappend exp "can't use floating-point value as operand of \"$op\" NONE"
1086        lappend res [TestOp $op 1 5.0]
1087        lappend exp "can't use floating-point value as operand of \"$op\" NONE"
1088    }
1089    foreach op {in ni} {
1090        lappend res [TestOp $op 5 "a b \{ c"]
1091        lappend exp "unmatched open brace in list NONE"
1092    }
1093    lappend res [TestOp % 5 0]
1094    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1095    lappend res [TestOp % 9838923468297346238478737647637375 0]
1096    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1097    lappend res [TestOp / 5 0]
1098    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1099    lappend res [TestOp / 9838923468297346238478737647637375 0]
1100    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
1101    expr {$res eq $exp ? 0 : $res}
1102} 0
1103test mathop-24.4 { binary ops, negative shift } {
1104    set res {}
1105
1106    set big      -12135435435354435435342423948763867876
1107    set wide                             -12345678912345
1108    set small                                         -1
1109
1110    lappend res [TestOp << 10 $big]
1111    lappend res [TestOp << 10 $wide]
1112    lappend res [TestOp << 10 $small]
1113    lappend res [TestOp >> 10 $big]
1114    lappend res [TestOp >> 10 $wide]
1115    lappend res [TestOp >> 10 $small]
1116
1117    set exp [lrepeat 6 "negative shift argument NONE"]
1118    expr {$res eq $exp ? 0 : $res}
1119} 0
1120test mathop-24.5 { binary ops, large shift } {
1121    set res {}
1122    set exp {}
1123
1124    set big      12135435435354435435342423948763867876
1125    set wide                             12345678912345
1126    set small                                         1
1127
1128    lappend res [TestOp << 1 2147483648]
1129    lappend exp "integer value too large to represent NONE"
1130    lappend res [TestOp << 1 4294967296]
1131    lappend exp "integer value too large to represent NONE"
1132    lappend res [TestOp << $small $wide]
1133    lappend exp "integer value too large to represent NONE"
1134    lappend res [TestOp << $small $big]
1135    lappend exp "integer value too large to represent NONE"
1136    lappend res [TestOp >> $big $wide]
1137    lappend exp 0
1138    lappend res [TestOp >> $big $big]
1139    lappend exp 0
1140    lappend res [TestOp >> $small 70]
1141    lappend exp 0
1142    lappend res [TestOp >> $wide 70]
1143    lappend exp 0
1144    lappend res [TestOp >> -$big $wide]
1145    lappend exp -1
1146    lappend res [TestOp >> -$wide $wide]
1147    lappend exp -1
1148    lappend res [TestOp >> -$small $wide]
1149    lappend exp -1
1150    lappend res [TestOp >> -$small 70]
1151    lappend exp -1
1152    lappend res [TestOp >> -$wide 70]
1153    lappend exp -1
1154
1155    expr {$res eq $exp ? 0 : $res}
1156} 0
1157test mathop-24.6 { binary ops, shift } {
1158    # Test different combinations to get all code paths
1159    set res {}
1160
1161    set bigbig 14372423674564535234543545248972634923869
1162    set big       12135435435354435435342423948763867876
1163    set wide                              12345678912345
1164    set negwide                          -12345678912345
1165    set small                                          5
1166    set neg                                           -5
1167
1168    lappend res [TestOp << $wide $small]
1169    lappend res [TestOp >> $wide $small]
1170    set res
1171} [list   395061725195040 \
1172             385802466010 \
1173          ]
1174test mathop-24.7 { binary ops, list search } {
1175    set res {}
1176
1177    foreach op {in ni} {
1178        lappend res [TestOp $op 5 {7 5 8}]
1179        lappend res [TestOp $op hej {foo bar hej}]
1180        lappend res [TestOp $op 5 {7 0x5 8}]
1181    }
1182    set res
1183} [list 1 1 0  0 0 1]
1184test mathop-24.8 { binary ops, too many } {
1185    set exp {}
1186    foreach op {<< >> % != ne in ni ~ !} {
1187        set res [TestOp $op 7 8 9]
1188        if {[string match "wrong # args* NONE" $res]} {
1189            lappend exp 0
1190        } else {
1191            lappend exp $res
1192        }
1193    }
1194    set exp
1195} {0 0 0 0 0 0 0 0 0}
1196
1197test mathop-25.1  { exp operator } {TestOp **        } 1
1198test mathop-25.2  { exp operator } {TestOp **   0    } 0
1199test mathop-25.3  { exp operator } {TestOp **   0   5} 0
1200test mathop-25.4  { exp operator } {TestOp ** 7.5    } 7.5
1201test mathop-25.5  { exp operator } {TestOp **   1   5} 1
1202test mathop-25.6  { exp operator } {TestOp **   5   1} 5
1203test mathop-25.7  { exp operator } {TestOp ** 4 3 2 1} 262144
1204test mathop-25.8  { exp operator } {TestOp ** 5.5   4} 915.0625
1205test mathop-25.9  { exp operator } {TestOp **   6 3.5} 529.0897844411664
1206test mathop-25.10 { exp operator } {TestOp ** 3.5   0} 1.0
1207test mathop-25.11 { exp operator } {TestOp ** 378   0} 1
1208test mathop-25.12 { exp operator } {TestOp ** 7.8   1} 7.8
1209test mathop-25.13 { exp operator } {TestOp ** 748   1} 748
1210test mathop-25.14 { exp operator } {TestOp ** 6.3  -1} 0.15873015873015872
1211test mathop-25.15 { exp operator } {TestOp ** 683  -1} 0
1212test mathop-25.16 { exp operator } {TestOp **   1  -1} 1
1213test mathop-25.17 { exp operator } {TestOp **  -1  -1} -1
1214test mathop-25.18 { exp operator } {TestOp **  -1  -2} 1
1215test mathop-25.19 { exp operator } {TestOp **  -1   3} -1
1216test mathop-25.20 { exp operator } {TestOp **  -1   4} 1
1217test mathop-25.21 { exp operator } {TestOp **   2  63} 9223372036854775808
1218test mathop-25.22 { exp operator } {TestOp ** 83756485763458746358734658473567847567473 2} 7015148907444467657897585474493757781161998914521537835809623408157343003287605729
1219test mathop-25.23 { exp operator errors } {
1220    set res {}
1221    set exp {}
1222
1223    set huge     [string repeat 145782 1000]
1224    set big      12135435435354435435342423948763867876
1225    set wide                             12345678912345
1226    set small                                         2
1227
1228    lappend res [TestOp ** 0 -5]
1229    lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
1230    lappend res [TestOp ** 0.0 -5.0]
1231    lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
1232    lappend res [TestOp ** $small $wide]
1233    lappend exp "exponent too large NONE"
1234    lappend res [TestOp ** 2 $big]
1235    lappend exp "exponent too large NONE"
1236    lappend res [TestOp ** $huge 2.1]
1237    lappend exp "Inf"
1238    lappend res [TestOp ** 2 foo]
1239    lappend exp "can't use non-numeric string as operand of \"**\" NONE"
1240    lappend res [TestOp ** foo 2]
1241    lappend exp "can't use non-numeric string as operand of \"**\" NONE"
1242
1243    expr {$res eq $exp ? 0 : $res}
1244} 0
1245
1246test mathop-26.1 { misc ops, size combinations } {
1247    set big1      12135435435354435435342423948763867876
1248    set big2       2746237174783836746262564892918327847
1249    set wide1                             87321847232215
1250    set wide2                             12345678912345
1251    set small1                                     87345
1252    set small2                                     16753
1253
1254    set res {}
1255    foreach op {+ * - /} {
1256        lappend res [TestOp $op $big1   $big2]
1257        lappend res [TestOp $op $big1   $wide2]
1258        lappend res [TestOp $op $big1   $small2]
1259        lappend res [TestOp $op $wide1  $big2]
1260        lappend res [TestOp $op $wide1  $wide2]
1261        lappend res [TestOp $op $wide1  $small2]
1262        lappend res [TestOp $op $small1 $big2]
1263        lappend res [TestOp $op $small1 $wide2]
1264        lappend res [TestOp $op $small1 $small2]
1265    }
1266    set res
1267} [list \
1268           14881672610138272181604988841682195723 \
1269           12135435435354435435342436294442780221 \
1270           12135435435354435435342423948763884629 \
1271           2746237174783836746262652214765560062 \
1272           99667526144560 \
1273           87321847248968 \
1274           2746237174783836746262564892918415192 \
1275           12345678999690 \
1276           104098 \
1277           33326783924759424684447891401270222910405366244661685890993770489959542972 \
1278           149820189346379518024969783068410988366610965329220 \
1279           203304949848492856848291628413641078526628 \
1280           239806503039903915972546163440347114360602909991105 \
1281           1078047487961768329845194175 \
1282           1462902906681297895 \
1283           239870086031494220602303730571951345796215 \
1284           1078333324598774025 \
1285           1463290785 \
1286           9389198260570598689079859055845540029 \
1287           12135435435354435435342411603084955531 \
1288           12135435435354435435342423948763851123 \
1289           -2746237174783836746262477571071095632 \
1290           74976168319870 \
1291           87321847215462 \
1292           -2746237174783836746262564892918240502 \
1293           -12345678825000 \
1294           70592 \
1295           4 \
1296           982970278225822587257201 \
1297           724373869477373332259441529801460 \
1298           0 \
1299           7 \
1300           5212311062 \
1301           0 \
1302           0 \
1303           5 \
1304          ]
1305test mathop-26.2 { misc ops, corner cases } {
1306    set res {}
1307    lappend res [TestOp - 0 -2147483648]                  ;# -2**31
1308    lappend res [TestOp - 0 -9223372036854775808]         ;# -2**63
1309    lappend res [TestOp / -9223372036854775808 -1]
1310    lappend res [TestOp * 2147483648 2]
1311    lappend res [TestOp * 9223372036854775808 2]
1312    set res
1313} [list 2147483648 9223372036854775808 9223372036854775808 4294967296 18446744073709551616]
1314
1315if 0 {
1316    # Compare ops to expr bytecodes
1317    namespace import ::tcl::mathop::*
1318    proc _X {a b c} {
1319        set x [+ $a [- $b $c]]
1320        set y [expr {$a + ($b - $c)}]
1321        set z [< $a $b $c]
1322    }
1323    set ::tcl_traceCompile 2
1324    _X 3 4 5
1325    set ::tcl_traceCompile 0
1326}
1327
1328# cleanup
1329namespace delete ::testmathop
1330namespace delete ::testmathop2
1331::tcltest::cleanupTests
1332return
1333
1334# Local Variables:
1335# mode: tcl
1336# End:
Note: See TracBrowser for help on using the repository browser.