tagged release 0.6.4
[parrot.git] / languages / tcl / t / cmd_expr.t
blobba35218425283cf469cd7d8397db2ba3dc46d5a7
1 #!perl
3 # Copyright (C) 2006-2008, The Perl Foundation.
4 # $Id$
6 # the following lines re-execute this as a tcl script
7 # the \ at the end of these lines makes them a comment in tcl \
8 use lib qw(languages/tcl/lib tcl/lib lib ../lib ../../lib); # \
9 use Tcl::Test; #\
10 __DATA__
12 source lib/test_more.tcl
13 plan 294
15 # namespace
16 namespace eval test { variable x 5 }
17 is [namespace eval test {expr {$x}}] 5 {correct namespace}
19 # simple scalars
20 is [expr 42]     42   {int}
21 is [expr 4.2]     4.2 {float}
22 is [expr 4.0]     4.0 {float stays float}
23 is [expr 3e2]   300.0 {scientific}
24 is [expr 3e0]     3.0 {scientific with 0 exponent}
25 is [expr 2.3e2] 230.0 {scientific with float base}
26 is [expr 2.3E2] 230.0 {scientific with float base (upper E)}
27 is [expr 2e17]  2e+17 {scientific in, scientific out}
28 eval_is {expr 3e2.0} \
29  {missing operator at _@_
30 in expression "3e2_@_.0"} \
31  {can only e with an integer exponent} \
32 {TODO {new behavior in tcl 8.5.1}}
34 # booleans
35 is [expr TrUe]    TrUe  {true}
36 is [expr !!TrUe]  1  {true}
37 is [expr !!TrU]   1  {tru}
38 is [expr !!Tr]    1  {tr}
39 is [expr !!T]     1  {t}
40 is [expr !!FaLsE] 0  {false}
41 is [expr !!FaLs]  0  {fals}
42 is [expr !!FaL]   0  {fal}
43 is [expr !!Fa]    0  {fa}
44 is [expr !!F]     0  {f}
45 is [expr !!On]    1  {on}
46 is [expr !!OfF]   0  {off}
47 is [expr !!Of]    0  {of}
48 is [expr !!YeS]   1  {yes}
49 is [expr !!Ye]    1  {ye}
50 is [expr !!Y]     1  {y}
51 is [expr !!No]    0  {no}
52 is [expr !!N]     0  {n}
54 eval_is {expr trues} \
55  {invalid bareword "trues"
56 in expression "trues";
57 should be "$trues" or "{trues}" or "trues(...)" or ...} {trues} \
58 {TODO {new behavior in tcl 8.5.1}}
59 eval_is {expr falses} \
60  {invalid bareword "falses"
61 in expression "falses";
62 should be "$falses" or "{falses}" or "falses(...)" or ...} {falses} \
63 {TODO {new behavior in tcl 8.5.1}}
65 is [expr 0b1001]    9 {binary}
66 is [expr 0b10]      2 {binary}
67 is [expr 0b101010] 42 {binary}
69 eval_is {expr {}} {empty expression
70 in expression ""} {empty expr}
72 # simple unary ops.
73 is [expr -2]   -2   {unary -}
74 is [expr +2]    2   {unary +}
75 is [expr +2.0]  2.0 {unary + (float)}
76 is [expr ~0]   -1   {unary ~}
77 is [expr !2]    0   {unary !}
78 is [expr !true] 0   {unary ! - boolean}
79 is [expr !!2]   1   {double unary !}
81 # simple unary ops - stringified args
82 is [expr {-"2"}]  -2 {unary -}
83 is [expr {+"2"}]   2 {unary +}
84 is [expr {~"0"}]  -1 {unary ~}
85 is [expr {!"2"}]   0 {unary !}
86 is [expr {!!"2"}]  1 {double unary !}
88 # simple unary ops  - octal
90 # simple binary ops - integer
91 is [expr 2 ** 3]   8 {pow}
92 is [expr 0 ** 1]   0 {pow}
93 is [expr 0 ** 0]   1 {pow}
94 eval_is {expr 0 ** -1} {exponentiation of zero by negative power} \
95   {pow of 0 with neg exp}
96 is [expr 2 * 3]    6 {mul}
97 is [expr 6 / 2]    3 {times}
98 is [expr 3 % 2]    1 {remainder}
99 is [expr 2 + 3]    5 {plus}
100 is [expr 2 - 3]   -1 {minus}
101 is [expr 16 << 2] 64 {left shift}
102 is [expr 16 >> 2]  4 {right shift}
103 is [expr 5 & 6]    4 {&}
104 is [expr 5 | 6]    7 {|}
105 is [expr 5 ^ 6]    3 {^}
107 set j 7
108 is [expr {${j}}]      7 {braced variable names}
109 is [expr {"$j"}]      7 {variables in quotes}
110 is [expr {"#$j"}]    #7 {variables in quotes after literal}
111 is [expr {"$"}]       $ {dollar-sign in quotes}
112 is [expr {"[set j]"}] 7 {commands in quotes}
113 is [
114   set foo a
115   set hash(abar) 5
116   expr {$hash(${foo}bar)}
117 ] 5 {variables - complex array index}
119 is [expr {1 ? 14 : [expr {}]}] 14 \
120   {make sure expr errors happen at runtime}
122 # numification
123 is [expr {"foo"}] foo {non-numeric string}
124 is [expr {"0001234"}] 668 {string octal}
125 is [expr {"0o1234"}]  668 {string 0o octal}
126 set j 0001234
127 is [expr {$j}] 668 {variable octal}
129 # simple binary ops - stringified integers
130 is [expr {2 ** "3"}]   8 {pow "}
131 is [expr {"2" ** 3}]   8 {pow "}
132 is [expr {2 * "3"}]    6 {mul "}
133 is [expr {"2" * 3}]    6 {mul "}
134 is [expr {6 / "2"}]    3 {times "}
135 is [expr {"6" / 2}]    3 {times "}
136 is [expr {3 % "2"}]    1 {remainder "}
137 is [expr {"3" % 2}]    1 {remainder "}
138 is [expr {2 + "3"}]    5 {plus "}
139 is [expr {"2" + 3}]    5 {plus "}
140 is [expr {2 - "3"}]   -1 {minus "}
141 is [expr {"2" - 3}]   -1 {minus "}
142 is [expr {16 << "2"}] 64 {left shift "}
143 is [expr {"16" << 2}] 64 {left shift "}
144 is [expr {16 >> "2"}]  4 {right shift "}
145 is [expr {"16" >> 2}]  4 {right shift "}
146 is [expr {5 & "6"}]    4 {& "}
147 is [expr {"5" & 6}]    4 {& "}
148 is [expr {5 | "6"}]    7 {| "}
149 is [expr {"5" | 6}]    7 {| "}
150 is [expr {5 ^ "6"}]    3 {^ "}
151 is [expr {"5" ^ 6}]    3 {^ "}
153 # comparison ops.
154 is [expr 10<9] 0 {lt, numeric, not alpha}
155 is [expr 2<3]  1 {lt, true}
156 is [expr 3<2]  0 {lt, false}
157 is [expr 3>2]  1 {gt, true}
158 is [expr 2>3]  0 {gt, false}
159 is [expr 2<=3] 1 {lte, lt}
160 is [expr 3<=2] 0 {lte, gt}
161 is [expr 3<=3] 1 {lte, eq}
162 is [expr 3>=2] 1 {gte, gt}
163 is [expr 2>=3] 0 {gte, lt}
164 is [expr 3>=3] 1 {gte, eq}
165 is [expr 2==2] 1 {==, eq}
166 is [expr 2==1] 0 {==, ne}
167 is [expr 1!=1] 0 {!=, eq}
168 is [expr 2!=1] 1 {!=, ne}
170 is [expr {[list \;] == {{;}}}] 1 {==, string and list}
171 is [expr {[list \;] != {{;}}}] 0 {!=, string and list}
173 # short circuting ops
174 is [expr 2&&2] 1 {&&}
175 is [expr {2>=2 && 2>=2}] 1 {&&}
176 is [expr 2&&0] 0 {&&}
177 is [expr 0&&2] 0 {&&}
178 is [expr 0&&0] 0 {&&}
179 is [expr 2||2] 1 {||}
180 is [expr 2||0] 1 {||}
181 is [expr 0||2] 1 {||}
182 is [expr 0||0] 0 {||}
184 # invalid (string) operands for some unary ops
185 set ops_list [list - + ~ !]
186 foreach operator $ops_list {
187   eval_is "expr {${operator}\"a\"}" \
188     "can't use non-numeric string as operand of \"$operator\"" \
189     "string unary $operator"
190   eval_is "expr {${operator}\"\"}" \
191     "can't use empty string as operand of \"$operator\"" \
192     "string unary $operator"
195 # invalid (string) operands for some binary ops
196 set ops_list [list ** * / % + - << >> & | ^]
197 foreach operator $ops_list {
198   eval_is "expr {\"a\" $operator \"b\"}" \
199     "can't use non-numeric string as operand of \"$operator\"" \
200     "string $operator"
201   eval_is "expr {\"\" $operator \"\"}" \
202     "can't use empty string as operand of \"$operator\"" \
203     "string $operator"
206 # invalid (string) operands for logical ops
207 set logic_ops_list [list && ||]
208 foreach operator $logic_ops_list {
209   eval_is "expr {\"a\" $operator \"b\"}" \
210     {expected boolean value but got "a"} \
211     "string $operator"
212   eval_is "expr {\"\" $operator \"\"}" \
213     {expected boolean value but got ""} \
214     "string $operator"
217 is [expr bool(4)]       1 {bool - true}
218 is [expr bool("yes")]   1 {bool - yes}
219 is [expr bool(0)]       0 {bool - false}
220 is [expr bool("no")]    0 {bool - no}
221 eval_is {expr bool("foo")} {expected boolean value but got "foo"} {bool - bad value}
222 eval_is {expr entier("foo")} {expected number but got "foo"} {entier - bad value}
224 set TODO {TODO "correct precision"}
226 # math functions, happy path
227 is [expr abs(-1)]       1
228 is [expr abs(1)]        1
229 is [expr abs(1.0)]      1.0
230 is [expr abs(-1.0)]     1.0
231 is [expr acos(0)]       1.5707963267948966 {} $TODO
232 is [expr asin(1)]       1.5707963267948966 {} $TODO
233 is [expr atan(1)]       0.7853981633974483
234 is [expr atan2(4,5)]    0.6747409422235526
235 is [expr ceil(4.6)]     5.0
236 is [expr ceil(-1.6)]   -1.0
237 is [expr cos(0)]        1.0
238 is [expr cosh(1)]       1.5430806348152437 {} $TODO
239 is [expr double(5)]     5.0
240 is [expr entier(3)]     3
241 is [expr entier(3.5)]   3
242 is [expr exp(1)]        2.718281828459045
243 is [expr floor(0.1)]    0.0
244 is [expr floor(0.0)]    0.0
245 is [expr floor(-0.1)]   -1.0
246 is [expr fmod(3,2)]     1.0
247 is [expr fmod(-4, -1)] -0.0 {} $TODO
248 is [expr hypot(3,4)]    5.0
249 is [expr hypot(-3,4)]   5.0
250 is [expr int(4.6)]      4
251 is [expr log(32)]       3.4657359027997265 {} $TODO
252 is [expr log10(32)]     1.505149978319906
253 is [expr max(1,4,2)]    4
254 is [expr min(1,4,2)]    1
255 is [expr pow(2,10)]  1024.0
256 is [expr round(4.5)]    5
257 is [expr round(5.5)]    6
258 is [expr round(4.4)]    4
259 is [expr round(2)]      2
260 is [expr sin(1)]        0.8414709848078965
261 is [expr sinh(1)]       1.1752011936438014 {} $TODO
262 is [expr sqrt(64)]      8.0
263 is [expr tan(1)]        1.5574077246549023 {} $TODO
264 is [expr tanh(1)]       0.7615941559557649
266 # math functions, stringified numeric args
267 is [expr abs("-1")]       1
268 is [expr acos("0")]       1.5707963267948966 {} $TODO
269 is [expr asin("1")]       1.5707963267948966 {} $TODO
270 is [expr atan("1")]       0.7853981633974483
271 is [expr atan2("4",5)]    0.6747409422235526
272 is [expr atan2(4,"5")]    0.6747409422235526
273 is [expr atan2("4","5")]  0.6747409422235526
274 is [expr ceil("4.6")]     5.0
275 is [expr ceil("-1.6")]   -1.0
276 is [expr cos("0")]        1.0
277 is [expr cosh("1")]       1.5430806348152437 {} $TODO
278 is [expr double("5")]     5.0
279 is [expr entier("3.4")]   3
280 is [expr exp("1")]        2.718281828459045
281 is [expr fmod("3",2)]     1.0
282 is [expr fmod(3,"2")]     1.0
283 is [expr fmod("3","2")]   1.0
284 is [expr hypot("3",4)]    5.0
285 is [expr hypot(3,"4")]    5.0
286 is [expr hypot("3","4")]  5.0
287 is [expr int("4.6")]      4
288 is [expr log("32")]       3.4657359027997265 {} $TODO
289 is [expr log10("32")]     1.505149978319906
290 is [expr pow("2",10)]  1024.0
291 is [expr pow(2,"10")]  1024.0
292 is [expr pow("2","10")] 1024.0
293 is [expr round("4.5")]    5
294 is [expr sin("1")]        0.8414709848078965
295 is [expr sinh("1")]       1.1752011936438014 {} $TODO
296 is [expr sqrt("64")]      8.0
297 is [expr tan("1")]        1.5574077246549023 {} $TODO
298 is [expr tanh("1")]       0.7615941559557649
300 eval_is {expr exp(exp(50))} Inf Inf {TODO unimplemented}
302 # unary math functions, invalid string ops.
303 set function_list \
304   [list acos asin atan cos cosh exp floor log log10 sin sinh sqrt tan tanh]
305 foreach function $function_list {
306   eval_is "expr ${function}(\"a\")" \
307     {expected floating-point number but got "a"} \
308     "string $function"
310 eval_is {expr {~2.0}} {can't use floating-point value as operand of "~"} \
311   {can't use floating-point value as operand of "~"}
313 # test namespaces with operators
314 is [namespace eval lib {if {+2} {}}] {} {[expr] in a namespace}
316 # infinity tests
317 set TODO {TODO "pending Inf implementation"}
319 eval_is {expr inf} Inf {infinity lc} $TODO
320 eval_is {expr iNf} Inf {infinity mixed case} $TODO
321 eval_is {expr inf + inf} Inf {infinity add} $TODO
322 eval_is {expr inf - inf} \
323   {domain error: argument not in valid range} {infinity subtract} \
324   $TODO
325 eval_is {expr sin(inf)} \
326   {domain error: argument not in valid range} {infinity function} \
327   $TODO
328 eval_is {expr inf/0} Inf {infinity trumps div by 0} $TODO
329 eval_is {expr 0/inf} 0.0 {div by infinity} $TODO
330 eval_is {expr 0 < inf} 1 {infinite comparison} $TODO
332 eval_is {expr 3/0} {divide by zero} {divide by zero}
335 # not a number tests.
336 set TODO {TODO "pending NaN implementation"}
338 eval_is {expr nan} \
339   {domain error: argument not in valid range} {NaN lc} \
340   $TODO
341 eval_is {expr nAn} \
342   {domain error: argument not in valid range} {NaN mixed case} \
343   $TODO
344 eval_is {expr nan/0} \
345   {can't use non-numeric floating-point value as operand of "/"} \
346   {nan trumps div by 0} \
347   $TODO
348 foreach function $function_list {
349   eval_is "expr ${function}(nan)" \
350     {floating point value is Not a Number} \
351     "${function}(nan)" \
352     $TODO
354 foreach operator $ops_list {
355   eval_is "expr nan $operator nan" \
356     "can't use non-numeric floating-point value as operand of \"$operator\"" \
357     "nan $operator nan" \
358     $TODO
362 # variable expansions..
363 is [
364   set q(1) 2
365   expr {$q(1)}
366 ] 2 {array variables}
367 is [
368   set under_score0 3
369   expr {$under_score0}
370 ] 3 {_, 0 in varnames}
372 #command expansions
373 is [expr {[]}] {} {empty command}
374 is [
375   expr {[list a] eq [list a]}
376 ] 1 {command expansion inside, list types.}
377 is [
378   expr {[set a a] eq [set b a]}
379 ] 1 {command expansion inside, string types}
382 # XXX  add tests for ::tcl::mathfunc
384 # tcl_precision
385 is [set tcl_precision 3; expr 1/3.] 0.333 { precision 3}
386 is [set tcl_precision 7; expr 1/3.] 0.3333333 { precision 7}
387 is [set tcl_precision 12; expr 1/3.] 0.333333333333 { precision 12}
389 # blocker bugs for t_tcl/expr.t parsing.
390 set TODO {TODO "awaiting real bigint support"}
391 eval_is {expr (1<<63)-1} 9223372036854775807 {expr-32.4} $TODO
392 eval_is {expr -2147483648} -2147483648 {expr-46.17} $TODO
393 eval_is {expr 9223372036854775808} 9223372036854775808 {expr-46.19} $TODO