expressions: Major work to improve error messages.
[pspp.git] / tests / language / expressions / parse.at
blobbb3dc3db1383bee7dfb0bf6ec344e6d2e93ad496
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
3 dnl
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
8 dnl
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 dnl GNU General Public License for more details.
13 dnl
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 dnl
17 AT_BANNER([expression parsing])
19 AT_SETUP([parse expression with unknown variable crash])
20 AT_KEYWORDS([expression expressions parse])
21 AT_DATA([parse.sps], [dnl
22 INPUT PROGRAM.
23 LOOP c=1 to 10.
24 COMPUTE var1=NORMAL(100).
25 END CASE.
26 END LOOP.
27 END FILE.
28 END INPUT PROGRAM.
31 IF ( y > 0 ) .
32 COMPUTE x=y.
33 END IF.
35 AT_CHECK([pspp -O format=csv parse.sps], [1], [dnl
36 parse.sps:10: error: IF: Unknown identifier y.
38 parse.sps:11: error: Stopping syntax file processing here to avoid a cascade of dependent command failures.
40 AT_CLEANUP
42 AT_SETUP([parsing boolean expression with type mismatch])
43 AT_KEYWORDS([expression expressions parse])
44 AT_DATA([parse.sps], [dnl
45 DATA LIST NOTABLE/x 1(A).
46 IF 'foo'.
48 AT_CHECK([pspp parse.sps], [1], [dnl
49 parse.sps:2.4-2.8: error: IF: Type mismatch: expression has string type, but a
50 boolean value is required here.
51     2 | IF 'foo'.
52       |    ^~~~~
54 AT_CLEANUP
56 AT_SETUP([parsing numeric expression with type mismatch])
57 AT_KEYWORDS([expression expressions parse])
58 AT_DATA([parse.sps], [dnl
59 DATA LIST NOTABLE/x 1.
60 COMPUTE x='foo'.
62 AT_CHECK([pspp parse.sps], [1], [dnl
63 parse.sps:2.11-2.15: error: COMPUTE: Type mismatch: expression has type
64 'string', but a numeric value is required.
65     2 | COMPUTE x='foo'.
66       |           ^~~~~
68 AT_CLEANUP
70 AT_SETUP([parsing string expression with type mismatch])
71 AT_KEYWORDS([expression expressions parse negative])
72 AT_DATA([parse.sps], [dnl
73 DATA LIST NOTABLE/x 1(A).
74 COMPUTE x=1.
76 AT_CHECK([pspp parse.sps], [1], [dnl
77 parse.sps:2.11: error: COMPUTE: Type mismatch: expression has type 'number',
78 but a string value is required.
79     2 | COMPUTE x=1.
80       |           ^
82 AT_CLEANUP
84 AT_SETUP([assigning string expression to new variable])
85 AT_KEYWORDS([expression expressions parse negative])
86 AT_DATA([parse.sps], [dnl
87 DATA LIST NOTABLE/x 1(A).
88 COMPUTE y='a'.
90 AT_CHECK([pspp parse.sps], [1], [dnl
91 parse.sps:2: error: COMPUTE: This command tries to create a new variable y by
92 assigning a string value to it, but this is not supported.  Use the STRING
93 command to create the new variable with the correct width before assigning to
94 it, e.g. STRING y(A20).
96 AT_CLEANUP
98 AT_SETUP([parse expression with unknown system variable])
99 AT_KEYWORDS([expression expressions parse negative])
100 AT_DATA([parse.sps], [dnl
101 DATA LIST NOTABLE/x 1.
102 COMPUTE x=$nonexistent.
104 AT_CHECK([pspp parse.sps], [1], [dnl
105 parse.sps:2: error: COMPUTE: Unknown system variable $nonexistent.
107 AT_CLEANUP
109 AT_SETUP([parse expression with unknown identifier])
110 AT_KEYWORDS([expression expressions parse negative])
111 AT_DATA([parse.sps], [dnl
112 DATA LIST NOTABLE/x 1.
113 COMPUTE x=y.
115 AT_CHECK([pspp parse.sps], [1], [dnl
116 parse.sps:2: error: COMPUTE: Unknown identifier y.
118 AT_CLEANUP
120 AT_SETUP([parse expression with extension function in compatibility mode])
121 AT_KEYWORDS([expression expressions parse negative])
122 AT_DATA([parse.sps], [dnl
123 DEBUG EVALUATE/ACOS(0)*0.
125 AT_CHECK([pspp --testing-mode --syntax=compatible parse.sps], [0], [dnl
126 parse.sps:1.16-1.22: warning: DEBUG EVALUATE: ACOS(number) is a PSPP extension.
127     1 | DEBUG EVALUATE/ACOS(0)*0.
128       |                ^~~~~~~
130 ACOS(0)*0 => 0.00
132 AT_CLEANUP
134 AT_SETUP([LAG expression following TEMPORARY])
135 AT_KEYWORDS([expression expressions parse negative])
136 AT_DATA([parse.sps], [dnl
137 DATA LIST NOTABLE/x 1.
138 TEMPORARY
139 COMPUTE y=LAG(x).
141 AT_CHECK([pspp parse.sps], [1], [dnl
142 parse.sps:3.11-3.16: error: COMPUTE: LAG(num_variable) may not appear after
143 TEMPORARY.
144     3 | COMPUTE y=LAG(x).
145       |           ^~~~~~
147 AT_CLEANUP
149 AT_SETUP([parse expression with invalid logical expression])
150 AT_KEYWORDS([expression expressions parse negative])
151 AT_DATA([parse.sps], [dnl
152 INPUT PROGRAM.
153 LOOP c=1 to 10.
154 COMPUTE var1=NORMAL(100).
155 END CASE.
156 END LOOP.
157 END FILE.
158 END INPUT PROGRAM.
160 SELECT IF 2.
162 AT_CHECK([pspp parse.sps], [1], [dnl
163 parse.sps:9.11: error: SELECT IF: This expression, which must be 0 or 1,
164 evaluated to 2.  It will be treated as 0.
165     9 | SELECT IF 2.
166       |           ^
168 AT_CLEANUP
170 AT_SETUP([chaining operators that shouldn't be])
171 AT_KEYWORDS([expression expressions parse negative])
172 AT_DATA([parse.sps], [dnl
173 INPUT PROGRAM.
174 * These should provoke warnings.
175 COMPUTE a = 1 < 2 < 3.
176 COMPUTE b = 1 > 2 < 0.
177 COMPUTE c = 2**3**4.
179 * These should not provoke warnings.
180 COMPUTE d = (1 < 2) < 3.
181 COMPUTE e = (2**3)**4.
182 END INPUT PROGRAM.
184 AT_CHECK([pspp parse.sps], [1], [dnl
185 parse.sps:3.13-3.21: warning: COMPUTE: Chaining relational operators (e.g. `a <
186 b < c') will not produce the mathematically expected result.  Use the AND
187 logical operator to fix the problem (e.g. `a < b AND b < c').  To disable this
188 warning, insert parentheses.
189     3 | COMPUTE a = 1 < 2 < 3.
190       |             ^~~~~~~~~
192 parse.sps:4.13-4.21: warning: COMPUTE: Chaining relational operators (e.g. `a <
193 b < c') will not produce the mathematically expected result.  Use the AND
194 logical operator to fix the problem (e.g. `a < b AND b < c').  To disable this
195 warning, insert parentheses.
196     4 | COMPUTE b = 1 > 2 < 0.
197       |             ^~~~~~~~~
199 parse.sps:5.13-5.19: warning: COMPUTE: The exponentiation operator (`**') is
200 left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'.  To disable
201 this warning, insert parentheses.
202     5 | COMPUTE c = 2**3**4.
203       |             ^~~~~~~
205 parse.sps:10: error: INPUT PROGRAM: Input program must contain DATA LIST or END
206 FILE.
208 AT_CLEANUP
210 AT_SETUP([binary operator type mismatch])
211 AT_KEYWORDS([expression expressions parse negative])
212 AT_DATA([parse.sps], [dnl
213 DEBUG EVALUATE /1 + 'a'.
214 DEBUG EVALUATE /'a' + 1.
215 DEBUG EVALUATE /'a' + 'a'.
216 DEBUG EVALUATE /'a' + ('a').
218 DEBUG EVALUATE /1 < 'a'.
219 DEBUG EVALUATE /'a' < 1.
220 DEBUG EVALUATE /'a' < 'b' < 'c'.
222 AT_CHECK([pspp --testing-mode parse.sps], [1], [dnl
223 parse.sps:1.17-1.23: error: DEBUG EVALUATE: Both operands of + must be numeric.
224     1 | DEBUG EVALUATE /1 + 'a'.
225       |                 ^~~~~~~
227 parse.sps:1.17: note: DEBUG EVALUATE: This operand has type 'number'.
228     1 | DEBUG EVALUATE /1 + 'a'.
229       |                 ^
231 parse.sps:1.21-1.23: note: DEBUG EVALUATE: This operand has type 'string'.
232     1 | DEBUG EVALUATE /1 + 'a'.
233       |                     ^~~
235 1 + 'a' => error
237 parse.sps:2.17-2.23: error: DEBUG EVALUATE: Both operands of + must be numeric.
238     2 | DEBUG EVALUATE /'a' + 1.
239       |                 ^~~~~~~
241 parse.sps:2.17-2.19: note: DEBUG EVALUATE: This operand has type 'string'.
242     2 | DEBUG EVALUATE /'a' + 1.
243       |                 ^~~
245 parse.sps:2.23: note: DEBUG EVALUATE: This operand has type 'number'.
246     2 | DEBUG EVALUATE /'a' + 1.
247       |                       ^
249 'a' + 1 => error
251 'a' + 'a' => "aa"
253 parse.sps:4.17-4.26: error: DEBUG EVALUATE: Both operands of + must be numeric.
254     4 | DEBUG EVALUATE /'a' + ('a').
255       |                 ^~~~~~~~~~
257 parse.sps:4.17-4.19: note: DEBUG EVALUATE: This operand has type 'string'.
258     4 | DEBUG EVALUATE /'a' + ('a').
259       |                 ^~~
261 parse.sps:4.24-4.26: note: DEBUG EVALUATE: This operand has type 'string'.
262     4 | DEBUG EVALUATE /'a' + ('a').
263       |                        ^~~
265 'a' + ('a') => error
267 parse.sps:6.17-6.23: error: DEBUG EVALUATE: Both operands of < must have the
268 same type.
269     6 | DEBUG EVALUATE /1 < 'a'.
270       |                 ^~~~~~~
272 parse.sps:6.17: note: DEBUG EVALUATE: This operand has type 'number'.
273     6 | DEBUG EVALUATE /1 < 'a'.
274       |                 ^
276 parse.sps:6.21-6.23: note: DEBUG EVALUATE: This operand has type 'string'.
277     6 | DEBUG EVALUATE /1 < 'a'.
278       |                     ^~~
280 1 < 'a' => error
282 parse.sps:7.17-7.23: error: DEBUG EVALUATE: Both operands of < must have the
283 same type.
284     7 | DEBUG EVALUATE /'a' < 1.
285       |                 ^~~~~~~
287 parse.sps:7.17-7.19: note: DEBUG EVALUATE: This operand has type 'string'.
288     7 | DEBUG EVALUATE /'a' < 1.
289       |                 ^~~
291 parse.sps:7.23: note: DEBUG EVALUATE: This operand has type 'number'.
292     7 | DEBUG EVALUATE /'a' < 1.
293       |                       ^
295 'a' < 1 => error
297 parse.sps:8.17-8.31: error: DEBUG EVALUATE: Both operands of < must have the
298 same type.
299     8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
300       |                 ^~~~~~~~~~~~~~~
302 parse.sps:8.17-8.25: note: DEBUG EVALUATE: This operand has type 'number'.
303     8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
304       |                 ^~~~~~~~~
306 parse.sps:8.29-8.31: note: DEBUG EVALUATE: This operand has type 'string'.
307     8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
308       |                             ^~~
310 'a' < 'b' < 'c' => error
312 AT_CLEANUP
314 AT_SETUP([unary operator type mismatch])
315 AT_KEYWORDS([expression expressions parse negative])
316 AT_DATA([parse.sps], [dnl
317 DEBUG EVALUATE /-'a'.
318 DEBUG EVALUATE /----'a'.
319 DEBUG EVALUATE /NOT 'a'.
320 DEBUG EVALUATE /NOT NOT NOT 'a'.
321 DEBUG EVALUATE /NOT F5.2.
323 AT_CHECK([pspp --testing-mode parse.sps], [1], [dnl
324 parse.sps:1.17-1.20: error: DEBUG EVALUATE: The unary - operator requires a
325 numeric operand.
326     1 | DEBUG EVALUATE /-'a'.
327       |                 ^~~~
329 parse.sps:1.18-1.20: note: DEBUG EVALUATE: The operand of - has type 'string'.
330     1 | DEBUG EVALUATE /-'a'.
331       |                  ^~~
333 -'a' => error
335 parse.sps:2.17-2.23: error: DEBUG EVALUATE: The unary - operator requires a
336 numeric operand.
337     2 | DEBUG EVALUATE /----'a'.
338       |                 ^~~~~~~
340 parse.sps:2.21-2.23: note: DEBUG EVALUATE: The operand of - has type 'string'.
341     2 | DEBUG EVALUATE /----'a'.
342       |                     ^~~
344 ----'a' => error
346 parse.sps:3.17-3.23: error: DEBUG EVALUATE: The unary NOT operator requires a
347 numeric operand.
348     3 | DEBUG EVALUATE /NOT 'a'.
349       |                 ^~~~~~~
351 parse.sps:3.21-3.23: note: DEBUG EVALUATE: The operand of NOT has type
352 'string'.
353     3 | DEBUG EVALUATE /NOT 'a'.
354       |                     ^~~
356 NOT 'a' => error
358 parse.sps:4.17-4.31: error: DEBUG EVALUATE: The unary NOT operator requires a
359 numeric operand.
360     4 | DEBUG EVALUATE /NOT NOT NOT 'a'.
361       |                 ^~~~~~~~~~~~~~~
363 parse.sps:4.29-4.31: note: DEBUG EVALUATE: The operand of NOT has type
364 'string'.
365     4 | DEBUG EVALUATE /NOT NOT NOT 'a'.
366       |                             ^~~
368 NOT NOT NOT 'a' => error
370 parse.sps:5.17-5.24: error: DEBUG EVALUATE: The unary NOT operator requires a
371 numeric operand.
372     5 | DEBUG EVALUATE /NOT F5.2.
373       |                 ^~~~~~~~
375 parse.sps:5.21-5.24: note: DEBUG EVALUATE: The operand of NOT has type
376 'format'.
377     5 | DEBUG EVALUATE /NOT F5.2.
378       |                     ^~~~
380 NOT F5.2 => error
382 AT_CLEANUP
384 AT_SETUP([parsing with negative numbers])
385 AT_KEYWORDS([expression expressions parse])
386 AT_DATA([parse.sps], [dnl
387 DEBUG EVALUATE NOOPT POSTFIX /-2**3.
388 DEBUG EVALUATE NOOPT POSTFIX /-2**-3**-4.
389 DEBUG EVALUATE/1 - 2.
391 AT_CHECK([pspp --testing-mode parse.sps], [0], [dnl
392 number: n<2> number: n<3> POW NEG return_number
394 parse.sps:2.31-2.40: warning: DEBUG EVALUATE: The exponentiation operator
395 (`**') is left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'.  To
396 disable this warning, insert parentheses.
397     2 | DEBUG EVALUATE NOOPT POSTFIX /-2**-3**-4.
398       |                               ^~~~~~~~~~
400 number: n<2> number: n<-3> POW number: n<-4> POW NEG return_number
402 1 - 2 => -1.00
404 AT_CLEANUP
406 AT_SETUP([system variables])
407 AT_KEYWORDS([expression expressions parse])
408 AT_DATA([parse.sps], [dnl
409 DEBUG EVALUATE /$WIDTH.
410 DEBUG EVALUATE /$LENGTH.
411 DEBUG EVALUATE /$SYSMIS.
413 AT_CHECK([pspp --testing-mode parse.sps], [0], [dnl
414 $WIDTH => 79.00
416 $LENGTH => 24.00
418 $SYSMIS => sysmis
420 AT_CLEANUP
422 # This test will fail if the current date changes during the test.
423 AT_SETUP([system variables - $DATE $DATE11])
424 AT_KEYWORDS([expression expressions parse])
425 # Get the date in the formats that $DATE and $DATE11 support.
426 date=$(date +%d-%^b-%y)
427 date11=$(date +%d-%^b-%Y)
428 echo "date=$date"               # Should be date=DD-MMM-YY.
429 echo "date11=$date11"   # Should be date11=DD-MMM-YYYY.
431 # Maybe we don't have the 'date' program or it doesn't work as we
432 # expect.  Check by trying to see if $date and $date11 are in the
433 # expected format.  If not, skip the test.
434 AS_CASE([$date],
435   [[[0-9][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9]]], [],
436   [AT_SKIP_IF([:])])
437 AS_CASE([$date11],
438   [[[0-9][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9]]], [],
439   [AT_SKIP_IF([:])])
441 AT_DATA([parse.sps], [dnl
442 DEBUG EVALUATE /$DATE.
443 DEBUG EVALUATE /$DATE11.
445 AT_CHECK_UNQUOTED([pspp --testing-mode parse.sps], [0], [dnl
446 \$DATE => "$date"
448 \$DATE11 => "$date11"
450 AT_CLEANUP
452 AT_SETUP([expressions - negative checks])
453 AT_KEYWORDS([expression expressions parse])
454 AT_DATA([evaluate-base.sps], [dnl
455 SET EPOCH 1940.
456 DEBUG EVALUATE SET opt.
457 DEBUG EVALUATE /$nonexistent.
458 DEBUG EVALUATE /RANGE(1, 2).
459 DEBUG EVALUATE /CONCAT.1('a', 'b').
460 DEBUG EVALUATE /foobar(x).
461 DEBUG EVALUATE /CONCAT.1('a' b).
462 DEBUG EVALUATE /NCDF.CHISQ(1, 2, 3).
463 DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
466 for opt in OPT NOOPT; do
467     AS_BOX([$opt])
468     sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
469     AT_CHECK([pspp --testing-mode evaluate.sps], [1],
470 [[evaluate.sps:3: error: DEBUG EVALUATE: Unknown system variable $nonexistent.
472 $nonexistent => error
474 evaluate.sps:4.17-4.27: error: DEBUG EVALUATE: RANGE(number, number, number[,
475 number, number]...) must have an odd number of arguments.
476     4 | DEBUG EVALUATE /RANGE(1, 2).
477       |                 ^~~~~~~~~~~
479 RANGE(1, 2) => error
481 evaluate.sps:5.17-5.34: error: DEBUG EVALUATE: CONCAT(string[, string]...)
482 function cannot accept suffix .1 to specify the minimum number of valid
483 arguments.
484     5 | DEBUG EVALUATE /CONCAT.1('a', 'b').
485       |                 ^~~~~~~~~~~~~~~~~~
487 CONCAT.1('a', 'b') => error
489 evaluate.sps:6: error: DEBUG EVALUATE: No function or vector named foobar.
491 foobar(x) => error
493 evaluate.sps:7.30: error: DEBUG EVALUATE: Syntax error at `b': expecting `,' or
494 `)'.
496 CONCAT.1('a' b) => error
498 evaluate.sps:8.17-8.35: error: DEBUG EVALUATE: NCDF.CHISQ(number, number,
499 number) is not available in this version of PSPP.
500     8 | DEBUG EVALUATE /NCDF.CHISQ(1, 2, 3).
501       |                 ^~~~~~~~~~~~~~~~~~~
503 NCDF.CHISQ(1, 2, 3) => error
505 evaluate.sps:9.34-9.41: error: DEBUG EVALUATE: A vector index must be numeric.
506     9 | DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
507       |                                  ^~~~~~~~
509 evaluate.sps:9.36-9.40: note: DEBUG EVALUATE: This vector index has type
510 'string'.
511     9 | DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
512       |                                    ^~~~~
514 v('abc') => error
516 done
517 AT_CLEANUP