dnl PSPP - a program for statistical analysis.
dnl Copyright (C) 2017 Free Software Foundation, Inc.
dnl
dnl This program is free software: you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation, either version 3 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([expressions])

AT_SETUP([expressions - numeric syntax])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /1e2.
DEBUG EVALUATE /1e+2.
DEBUG EVALUATE /1e-2.
DEBUG EVALUATE /1e-99.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
1e2 => 100.00

1e+2 => 100.00

1e-2 => 0.01

1e-99 => 0.00
])
done
AT_CLEANUP

AT_SETUP([expressions - coercion to and from Boolean])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE/0 AND 1.
DEBUG EVALUATE/$true AND 1.
DEBUG EVALUATE/1 OR $false.
DEBUG EVALUATE/1 OR $sysmis.
DEBUG EVALUATE/2 OR $sysmis.
DEBUG EVALUATE/1 AND 3.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
0 AND 1 => false

$true AND 1 => true

1 OR $false => true

1 OR $sysmis => true

evaluate.sps:7.16-7.27: error: DEBUG EVALUATE: The operands of OR must have
value 0 or 1.
    7 | DEBUG EVALUATE/2 OR $sysmis.
      |                ^~~~~~~~~~~~

evaluate.sps:7.16: note: DEBUG EVALUATE: This operand with unexpected value 2
will be treated as 0.
    7 | DEBUG EVALUATE/2 OR $sysmis.
      |                ^

2 OR $sysmis => sysmis

evaluate.sps:8.16-8.22: error: DEBUG EVALUATE: The operands of AND must have
value 0 or 1.
    8 | DEBUG EVALUATE/1 AND 3.
      |                ^~~~~~~

evaluate.sps:8.22: note: DEBUG EVALUATE: This operand with unexpected value 3
will be treated as 0.
    8 | DEBUG EVALUATE/1 AND 3.
      |                      ^

1 AND 3 => false
])
done
AT_CLEANUP

AT_SETUP([expressions - addition and subtraction])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /1 + $true.
DEBUG EVALUATE /$sysmis + 1.
DEBUG EVALUATE /7676 + $sysmis.
DEBUG EVALUATE /1 +3 - 2 +4 - 5.
DEBUG EVALUATE /$true - 4/3.
DEBUG EVALUATE /1 - 2.
DEBUG EVALUATE /52 -23.

DEBUG EVALUATE /('foo') + 5.
DEBUG EVALUATE /('foo') + ('bar').   /* Concatenation requires CONCAT.
DEBUG EVALUATE /'foo' + 'bar'.       /* Lexical concatenation succeeds.

DEBUG EVALUATE /'string' - 1e10.
DEBUG EVALUATE /9.5 - ''.

DEBUG EVALUATE /F2.0 + 3.

/* Bug #62557.
DEBUG EVALUATE (y=3)(x=2) /(1 - y) + (1 - x).
DEBUG EVALUATE (y=3)(x=2) /((1 - y) + (1 - x)).
DEBUG EVALUATE (y=3)(x=2) /(1-y) + (1-x).
DEBUG EVALUATE (y=3)(x=2) /( (1-y) + (1-x) ).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
1 + $true => 2.00

$sysmis + 1 => sysmis

7676 + $sysmis => sysmis

1 +3 - 2 +4 - 5 => 1.00

$true - 4/3 => -0.33

1 - 2 => -1.00

52 -23 => 29.00

evaluate.sps:11.18-11.27: error: DEBUG EVALUATE: Both operands of + must be
numeric.
   11 | DEBUG EVALUATE /('foo') + 5.
      |                  ^~~~~~~~~~

evaluate.sps:11.18-11.22: note: DEBUG EVALUATE: This operand has type 'string'.
   11 | DEBUG EVALUATE /('foo') + 5.
      |                  ^~~~~

evaluate.sps:11.27: note: DEBUG EVALUATE: This operand has type 'number'.
   11 | DEBUG EVALUATE /('foo') + 5.
      |                           ^

('foo') + 5 => error

evaluate.sps:12.18-12.32: error: DEBUG EVALUATE: Both operands of + must be
numeric.
   12 | DEBUG EVALUATE /('foo') + ('bar').   /* Concatenation requires CONCAT.
      |                  ^~~~~~~~~~~~~~~

evaluate.sps:12.18-12.22: note: DEBUG EVALUATE: This operand has type 'string'.
   12 | DEBUG EVALUATE /('foo') + ('bar').   /* Concatenation requires CONCAT.
      |                  ^~~~~

evaluate.sps:12.28-12.32: note: DEBUG EVALUATE: This operand has type 'string'.
   12 | DEBUG EVALUATE /('foo') + ('bar').   /* Concatenation requires CONCAT.
      |                            ^~~~~

('foo') + ('bar') => error

'foo' + 'bar' => "foobar"

evaluate.sps:15.17-15.31: error: DEBUG EVALUATE: Both operands of - must be
numeric.
   15 | DEBUG EVALUATE /'string' - 1e10.
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:15.17-15.24: note: DEBUG EVALUATE: This operand has type 'string'.
   15 | DEBUG EVALUATE /'string' - 1e10.
      |                 ^~~~~~~~

evaluate.sps:15.26-15.31: note: DEBUG EVALUATE: This operand has type 'number'.
   15 | DEBUG EVALUATE /'string' - 1e10.
      |                          ^~~~~~

'string' - 1e10 => error

evaluate.sps:16.17-16.24: error: DEBUG EVALUATE: Both operands of - must be
numeric.
   16 | DEBUG EVALUATE /9.5 - ''.
      |                 ^~~~~~~~

evaluate.sps:16.17-16.19: note: DEBUG EVALUATE: This operand has type 'number'.
   16 | DEBUG EVALUATE /9.5 - ''.
      |                 ^~~

evaluate.sps:16.23-16.24: note: DEBUG EVALUATE: This operand has type 'string'.
   16 | DEBUG EVALUATE /9.5 - ''.
      |                       ^~

9.5 - '' => error

evaluate.sps:18.17-18.24: error: DEBUG EVALUATE: Both operands of + must be
numeric.
   18 | DEBUG EVALUATE /F2.0 + 3.
      |                 ^~~~~~~~

evaluate.sps:18.17-18.20: note: DEBUG EVALUATE: This operand has type 'format'.
   18 | DEBUG EVALUATE /F2.0 + 3.
      |                 ^~~~

evaluate.sps:18.24: note: DEBUG EVALUATE: This operand has type 'number'.
   18 | DEBUG EVALUATE /F2.0 + 3.
      |                        ^

F2.0 + 3 => error

(1 - y) + (1 - x) => -3.00

((1 - y) + (1 - x)) => -3.00

(1-y) + (1-x) => -3.00

( (1-y) + (1-x) ) => -3.00
])
done
AT_CLEANUP

AT_SETUP([expressions - multiplication and division])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /5 * 10.
DEBUG EVALUATE /10 * $true.
DEBUG EVALUATE /$true * 5.
DEBUG EVALUATE /1.5 * $true.
DEBUG EVALUATE /$sysmis * 15.
DEBUG EVALUATE /8.5 / $sysmis.
DEBUG EVALUATE /2 * 5 / 10.
DEBUG EVALUATE /1 / 2.
DEBUG EVALUATE /2 / 5.
DEBUG EVALUATE /12 / 3 / 2.

DEBUG EVALUATE /'x' * 1.
DEBUG EVALUATE /2 / 'x'.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
5 * 10 => 50.00

10 * $true => 10.00

$true * 5 => 5.00

1.5 * $true => 1.50

$sysmis * 15 => sysmis

8.5 / $sysmis => sysmis

2 * 5 / 10 => 1.00

1 / 2 => 0.50

2 / 5 => 0.40

12 / 3 / 2 => 2.00

evaluate.sps:14.17-14.23: error: DEBUG EVALUATE: Both operands of * must be
numeric.
   14 | DEBUG EVALUATE /'x' * 1.
      |                 ^~~~~~~

evaluate.sps:14.17-14.19: note: DEBUG EVALUATE: This operand has type 'string'.
   14 | DEBUG EVALUATE /'x' * 1.
      |                 ^~~

evaluate.sps:14.23: note: DEBUG EVALUATE: This operand has type 'number'.
   14 | DEBUG EVALUATE /'x' * 1.
      |                       ^

'x' * 1 => error

evaluate.sps:15.17-15.23: error: DEBUG EVALUATE: Both operands of / must be
numeric.
   15 | DEBUG EVALUATE /2 / 'x'.
      |                 ^~~~~~~

evaluate.sps:15.17: note: DEBUG EVALUATE: This operand has type 'number'.
   15 | DEBUG EVALUATE /2 / 'x'.
      |                 ^

evaluate.sps:15.21-15.23: note: DEBUG EVALUATE: This operand has type 'string'.
   15 | DEBUG EVALUATE /2 / 'x'.
      |                     ^~~

2 / 'x' => error
])
done
AT_CLEANUP

AT_SETUP([expressions - exponentiation])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /2**8.
DEBUG EVALUATE /(2**3)**4.
DEBUG EVALUATE /2**3**4.
DEBUG EVALUATE /-2**2.
DEBUG EVALUATE /-2**-3**-4.
DEBUG EVALUATE /-((2**-3)**-4).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
2**8 => 256.00

(2**3)**4 => 4096.00

evaluate.sps:5.17-5.23: warning: DEBUG EVALUATE: The exponentiation operator
(`**') is left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'.  To
disable this warning, insert parentheses.
    5 | DEBUG EVALUATE /2**3**4.
      |                 ^~~~~~~

2**3**4 => 4096.00

-2**2 => -4.00

evaluate.sps:7.17-7.26: warning: DEBUG EVALUATE: The exponentiation operator
(`**') is left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'.  To
disable this warning, insert parentheses.
    7 | DEBUG EVALUATE /-2**-3**-4.
      |                 ^~~~~~~~~~

-2**-3**-4 => -4096.00

-((2**-3)**-4) => -4096.00
])
done
AT_CLEANUP

AT_SETUP([expressions - unary minus])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /2+-3.
DEBUG EVALUATE /2*-3.
DEBUG EVALUATE /-3**2.
DEBUG EVALUATE /(-3)**2.
DEBUG EVALUATE /-(3**2).
DEBUG EVALUATE /2**-1.
DEBUG EVALUATE /0**0.
DEBUG EVALUATE /0**-1.
DEBUG EVALUATE /(-3)**1.5.
])

for opt in OPT NOOPT; do
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
2+-3 => -1.00

2*-3 => -6.00

-3**2 => -9.00

(-3)**2 => 9.00

-(3**2) => -9.00

2**-1 => 0.50

0**0 => sysmis

0**-1 => sysmis

(-3)**1.5 => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - AND truth table])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /$false AND $false.
DEBUG EVALUATE /$false AND $true.
DEBUG EVALUATE /$false AND $sysmis.
DEBUG EVALUATE /$true AND $false.
DEBUG EVALUATE /$true AND $true.
DEBUG EVALUATE /$true AND $sysmis.
DEBUG EVALUATE /$sysmis AND $false.
DEBUG EVALUATE /$sysmis AND $true.
DEBUG EVALUATE /$sysmis AND $sysmis.
DEBUG EVALUATE /$false & $false.
DEBUG EVALUATE /$false & $true.
DEBUG EVALUATE /$false & $sysmis.
DEBUG EVALUATE /$true & $false.
DEBUG EVALUATE /$true & $true.
DEBUG EVALUATE /$true & $sysmis.
DEBUG EVALUATE /$sysmis & $false.
DEBUG EVALUATE /$sysmis & $true.
DEBUG EVALUATE /$sysmis & $sysmis.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
$false AND $false => false

$false AND $true => false

$false AND $sysmis => false

$true AND $false => false

$true AND $true => true

$true AND $sysmis => sysmis

$sysmis AND $false => false

$sysmis AND $true => sysmis

$sysmis AND $sysmis => sysmis

$false & $false => false

$false & $true => false

$false & $sysmis => false

$true & $false => false

$true & $true => true

$true & $sysmis => sysmis

$sysmis & $false => false

$sysmis & $true => sysmis

$sysmis & $sysmis => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - OR truth table])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /$false OR $false.
DEBUG EVALUATE /$false OR $true.
DEBUG EVALUATE /$false OR $sysmis.
DEBUG EVALUATE /$true OR $false.
DEBUG EVALUATE /$true OR $true.
DEBUG EVALUATE /$true OR $sysmis.
DEBUG EVALUATE /$sysmis OR $false.
DEBUG EVALUATE /$sysmis OR $true.
DEBUG EVALUATE /$sysmis OR $sysmis.
DEBUG EVALUATE /$false | $false.
DEBUG EVALUATE /$false | $true.
DEBUG EVALUATE /$false | $sysmis.
DEBUG EVALUATE /$true | $false.
DEBUG EVALUATE /$true | $true.
DEBUG EVALUATE /$true | $sysmis.
DEBUG EVALUATE /$sysmis | $false.
DEBUG EVALUATE /$sysmis | $true.
DEBUG EVALUATE /$sysmis | $sysmis.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
$false OR $false => false

$false OR $true => true

$false OR $sysmis => sysmis

$true OR $false => true

$true OR $true => true

$true OR $sysmis => true

$sysmis OR $false => sysmis

$sysmis OR $true => true

$sysmis OR $sysmis => sysmis

$false | $false => false

$false | $true => true

$false | $sysmis => sysmis

$true | $false => true

$true | $true => true

$true | $sysmis => true

$sysmis | $false => sysmis

$sysmis | $true => true

$sysmis | $sysmis => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - NOT truth table])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /not $false.
DEBUG EVALUATE /not 0.
DEBUG EVALUATE /not 2.5.
DEBUG EVALUATE /not $true.
DEBUG EVALUATE /not 1.
DEBUG EVALUATE /not $sysmis.
DEBUG EVALUATE /~ $false.
DEBUG EVALUATE /~ 0.
DEBUG EVALUATE /~ 2.5.
DEBUG EVALUATE /~ $true.
DEBUG EVALUATE /~ 1.
DEBUG EVALUATE /~ $sysmis.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
not $false => true

not 0 => true

evaluate.sps:5.17-5.23: error: DEBUG EVALUATE: The operand of NOT must have
value 0 or 1.
    5 | DEBUG EVALUATE /not 2.5.
      |                 ^~~~~~~

evaluate.sps:5.21-5.23: note: DEBUG EVALUATE: This operand with unexpected
value 2.5 will be treated as 0.
    5 | DEBUG EVALUATE /not 2.5.
      |                     ^~~

not 2.5 => true

not $true => false

not 1 => false

not $sysmis => sysmis

~ $false => true

~ 0 => true

evaluate.sps:11.17-11.21: error: DEBUG EVALUATE: The operand of NOT must have
value 0 or 1.
   11 | DEBUG EVALUATE /~ 2.5.
      |                 ^~~~~

evaluate.sps:11.19-11.21: note: DEBUG EVALUATE: This operand with unexpected
value 2.5 will be treated as 0.
   11 | DEBUG EVALUATE /~ 2.5.
      |                   ^~~

~ 2.5 => true

~ $true => false

~ 1 => false

~ $sysmis => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - = <= <])
AT_KEYWORDS([expression expressions evaluate eq le lt])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /1 eq 1.
DEBUG EVALUATE /1 = 1.
DEBUG EVALUATE /1 eq 2.
DEBUG EVALUATE /2 = 3.
DEBUG EVALUATE /1 eq 'foobar'.
DEBUG EVALUATE /'baz' = 10.
DEBUG EVALUATE /'baz' = f8.2.
DEBUG EVALUATE /'baz' = 'baz'.
DEBUG EVALUATE /'quux' = 'bar'.
DEBUG EVALUATE /'bar  ' = 'bar'.
DEBUG EVALUATE /'asdf     ' = 'asdf  '.
DEBUG EVALUATE /'asdfj     ' = 'asdf'.
DEBUG EVALUATE /1 + 2 = 3.
DEBUG EVALUATE /1 >= 2 = 2 ge 3.
DEBUG EVALUATE /3 ne 2 != 1.
DEBUG EVALUATE /3 > 2 > 1.

DEBUG EVALUATE /1 <= 2.
DEBUG EVALUATE /2.5 <= 1.5.
DEBUG EVALUATE /1 le 2.
DEBUG EVALUATE /2 <= 2.
DEBUG EVALUATE /2 le 2.
DEBUG EVALUATE /2 < = 2.
DEBUG EVALUATE /1 <= 'foobar'.
DEBUG EVALUATE /'baz' <= 10.
DEBUG EVALUATE /'quux' <= 5.55.
DEBUG EVALUATE /'0123' <= '0123'.
DEBUG EVALUATE /'0123' <= '0124'.
DEBUG EVALUATE /'0124' le '0123'.
DEBUG EVALUATE /'0123  ' <= '0123'.
DEBUG EVALUATE /'0123' le '0123  '.

DEBUG EVALUATE /1 < 2.
DEBUG EVALUATE /2.5 < 1.5.
DEBUG EVALUATE /3.5 lt 4.
DEBUG EVALUATE /4 lt 3.5
DEBUG EVALUATE /1 lt 'foobar'.
DEBUG EVALUATE /5 lt 'foobar'.
DEBUG EVALUATE /'baz' < 10.
DEBUG EVALUATE /'quux' < 5.55.
DEBUG EVALUATE /'0123' lt '0123'.
DEBUG EVALUATE /'0123' < '0124'.
DEBUG EVALUATE /'0124' lt '0123'.
DEBUG EVALUATE /'0123  ' < '0123'.
DEBUG EVALUATE /'0123' lt '0123  '.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
1 eq 1 => true

1 = 1 => true

1 eq 2 => false

2 = 3 => false

evaluate.sps:7.17-7.29: error: DEBUG EVALUATE: Both operands of EQ must have
the same type.
    7 | DEBUG EVALUATE /1 eq 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:7.17: note: DEBUG EVALUATE: This operand has type 'number'.
    7 | DEBUG EVALUATE /1 eq 'foobar'.
      |                 ^

evaluate.sps:7.22-7.29: note: DEBUG EVALUATE: This operand has type 'string'.
    7 | DEBUG EVALUATE /1 eq 'foobar'.
      |                      ^~~~~~~~

1 eq 'foobar' => error

evaluate.sps:8.17-8.26: error: DEBUG EVALUATE: Both operands of = must have the
same type.
    8 | DEBUG EVALUATE /'baz' = 10.
      |                 ^~~~~~~~~~

evaluate.sps:8.17-8.21: note: DEBUG EVALUATE: This operand has type 'string'.
    8 | DEBUG EVALUATE /'baz' = 10.
      |                 ^~~~~

evaluate.sps:8.25-8.26: note: DEBUG EVALUATE: This operand has type 'number'.
    8 | DEBUG EVALUATE /'baz' = 10.
      |                         ^~

'baz' = 10 => error

evaluate.sps:9.17-9.28: error: DEBUG EVALUATE: Both operands of = must have the
same type.
    9 | DEBUG EVALUATE /'baz' = f8.2.
      |                 ^~~~~~~~~~~~

evaluate.sps:9.17-9.21: note: DEBUG EVALUATE: This operand has type 'string'.
    9 | DEBUG EVALUATE /'baz' = f8.2.
      |                 ^~~~~

evaluate.sps:9.25-9.28: note: DEBUG EVALUATE: This operand has type 'format'.
    9 | DEBUG EVALUATE /'baz' = f8.2.
      |                         ^~~~

'baz' = f8.2 => error

'baz' = 'baz' => true

'quux' = 'bar' => false

'bar  ' = 'bar' => true

'asdf     ' = 'asdf  ' => true

'asdfj     ' = 'asdf' => false

1 + 2 = 3 => true

evaluate.sps:16.17-16.31: warning: DEBUG EVALUATE: Chaining relational
operators (e.g. `a < b < c') will not produce the mathematically expected
result.  Use the AND logical operator to fix the problem (e.g. `a < b AND b <
c').  To disable this warning, insert parentheses.
   16 | DEBUG EVALUATE /1 >= 2 = 2 ge 3.
      |                 ^~~~~~~~~~~~~~~

1 >= 2 = 2 ge 3 => false

evaluate.sps:17.24: error: DEBUG EVALUATE: Syntax error expecting end of
command.
   17 | DEBUG EVALUATE /3 ne 2 != 1.
      |                        ^

3 ne 2 != 1 => error

evaluate.sps:18.17-18.25: warning: DEBUG EVALUATE: Chaining relational
operators (e.g. `a < b < c') will not produce the mathematically expected
result.  Use the AND logical operator to fix the problem (e.g. `a < b AND b <
c').  To disable this warning, insert parentheses.
   18 | DEBUG EVALUATE /3 > 2 > 1.
      |                 ^~~~~~~~~

3 > 2 > 1 => false

1 <= 2 => true

2.5 <= 1.5 => false

1 le 2 => true

2 <= 2 => true

2 le 2 => true

evaluate.sps:25.21: error: DEBUG EVALUATE: Syntax error parsing expression.
   25 | DEBUG EVALUATE /2 < = 2.
      |                     ^

2 < = 2 => error

evaluate.sps:26.17-26.29: error: DEBUG EVALUATE: Both operands of <= must have
the same type.
   26 | DEBUG EVALUATE /1 <= 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:26.17: note: DEBUG EVALUATE: This operand has type 'number'.
   26 | DEBUG EVALUATE /1 <= 'foobar'.
      |                 ^

evaluate.sps:26.22-26.29: note: DEBUG EVALUATE: This operand has type 'string'.
   26 | DEBUG EVALUATE /1 <= 'foobar'.
      |                      ^~~~~~~~

1 <= 'foobar' => error

evaluate.sps:27.17-27.27: error: DEBUG EVALUATE: Both operands of <= must have
the same type.
   27 | DEBUG EVALUATE /'baz' <= 10.
      |                 ^~~~~~~~~~~

evaluate.sps:27.17-27.21: note: DEBUG EVALUATE: This operand has type 'string'.
   27 | DEBUG EVALUATE /'baz' <= 10.
      |                 ^~~~~

evaluate.sps:27.26-27.27: note: DEBUG EVALUATE: This operand has type 'number'.
   27 | DEBUG EVALUATE /'baz' <= 10.
      |                          ^~

'baz' <= 10 => error

evaluate.sps:28.17-28.30: error: DEBUG EVALUATE: Both operands of <= must have
the same type.
   28 | DEBUG EVALUATE /'quux' <= 5.55.
      |                 ^~~~~~~~~~~~~~

evaluate.sps:28.17-28.22: note: DEBUG EVALUATE: This operand has type 'string'.
   28 | DEBUG EVALUATE /'quux' <= 5.55.
      |                 ^~~~~~

evaluate.sps:28.27-28.30: note: DEBUG EVALUATE: This operand has type 'number'.
   28 | DEBUG EVALUATE /'quux' <= 5.55.
      |                           ^~~~

'quux' <= 5.55 => error

'0123' <= '0123' => true

'0123' <= '0124' => true

'0124' le '0123' => false

'0123  ' <= '0123' => true

'0123' le '0123  ' => true

1 < 2 => true

2.5 < 1.5 => false

3.5 lt 4 => true

4 lt 3.5 => false

evaluate.sps:39.17-39.29: error: DEBUG EVALUATE: Both operands of < must have
the same type.
   39 | DEBUG EVALUATE /1 lt 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:39.17: note: DEBUG EVALUATE: This operand has type 'number'.
   39 | DEBUG EVALUATE /1 lt 'foobar'.
      |                 ^

evaluate.sps:39.22-39.29: note: DEBUG EVALUATE: This operand has type 'string'.
   39 | DEBUG EVALUATE /1 lt 'foobar'.
      |                      ^~~~~~~~

1 lt 'foobar' => error

evaluate.sps:40.17-40.29: error: DEBUG EVALUATE: Both operands of < must have
the same type.
   40 | DEBUG EVALUATE /5 lt 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:40.17: note: DEBUG EVALUATE: This operand has type 'number'.
   40 | DEBUG EVALUATE /5 lt 'foobar'.
      |                 ^

evaluate.sps:40.22-40.29: note: DEBUG EVALUATE: This operand has type 'string'.
   40 | DEBUG EVALUATE /5 lt 'foobar'.
      |                      ^~~~~~~~

5 lt 'foobar' => error

evaluate.sps:41.17-41.26: error: DEBUG EVALUATE: Both operands of < must have
the same type.
   41 | DEBUG EVALUATE /'baz' < 10.
      |                 ^~~~~~~~~~

evaluate.sps:41.17-41.21: note: DEBUG EVALUATE: This operand has type 'string'.
   41 | DEBUG EVALUATE /'baz' < 10.
      |                 ^~~~~

evaluate.sps:41.25-41.26: note: DEBUG EVALUATE: This operand has type 'number'.
   41 | DEBUG EVALUATE /'baz' < 10.
      |                         ^~

'baz' < 10 => error

evaluate.sps:42.17-42.29: error: DEBUG EVALUATE: Both operands of < must have
the same type.
   42 | DEBUG EVALUATE /'quux' < 5.55.
      |                 ^~~~~~~~~~~~~

evaluate.sps:42.17-42.22: note: DEBUG EVALUATE: This operand has type 'string'.
   42 | DEBUG EVALUATE /'quux' < 5.55.
      |                 ^~~~~~

evaluate.sps:42.26-42.29: note: DEBUG EVALUATE: This operand has type 'number'.
   42 | DEBUG EVALUATE /'quux' < 5.55.
      |                          ^~~~

'quux' < 5.55 => error

'0123' lt '0123' => false

'0123' < '0124' => true

'0124' lt '0123' => false

'0123  ' < '0123' => false

'0123' lt '0123  ' => false
])
done
AT_CLEANUP

AT_SETUP([expressions - >= > <>])
AT_KEYWORDS([expression expressions evaluate ge gt ne])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /1 >= 2.
DEBUG EVALUATE /2.5 >= 1.5
DEBUG EVALUATE /1 ge 2.
DEBUG EVALUATE /2 >= 2.
DEBUG EVALUATE /2 ge 2.
DEBUG EVALUATE /2 > = 2.
DEBUG EVALUATE /1 >= 'foobar'.
DEBUG EVALUATE /5 ge 'foobar'.
DEBUG EVALUATE /'baz' ge 10.
DEBUG EVALUATE /'0123' ge '0123'.
DEBUG EVALUATE /'0123' >= '0124'.
DEBUG EVALUATE /'0124' >= '0123'.
DEBUG EVALUATE /'0123  ' ge '0123'.
DEBUG EVALUATE /'0123' >= '0123 '.

DEBUG EVALUATE /1 > 2.
DEBUG EVALUATE /2.5 > 1.5
DEBUG EVALUATE /3.5 gt 4.
DEBUG EVALUATE /4 gt 3.5
DEBUG EVALUATE /1 gt 'foobar'.
DEBUG EVALUATE /'baz' > 10.
DEBUG EVALUATE /'0123' > '0123'.
DEBUG EVALUATE /'0123' > '0124'.
DEBUG EVALUATE /'0124' > '0123'.
DEBUG EVALUATE /'0123   ' > '0123'.
DEBUG EVALUATE /'0123    ' > '0123 '.

DEBUG EVALUATE /1 ne 1.
DEBUG EVALUATE /1 ~= 1.
DEBUG EVALUATE /1 <> 2.
DEBUG EVALUATE /2 ne 3.
DEBUG EVALUATE /1 ~= 'foobar'.
DEBUG EVALUATE /'baz' ne 10.
DEBUG EVALUATE /'quux' ~= 5.55.
DEBUG EVALUATE /'foobar' <> 'foobar'.
DEBUG EVALUATE /'quux' ne 'bar'.
DEBUG EVALUATE /'bar   ' <> 'bar'.
DEBUG EVALUATE /'asdf       ' ~= "asdf   ".
DEBUG EVALUATE /1 < > 1.
DEBUG EVALUATE /1 ~ = 1.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
1 >= 2 => false

2.5 >= 1.5 => true

1 ge 2 => false

2 >= 2 => true

2 ge 2 => true

evaluate.sps:8.21: error: DEBUG EVALUATE: Syntax error parsing expression.
    8 | DEBUG EVALUATE /2 > = 2.
      |                     ^

2 > = 2 => error

evaluate.sps:9.17-9.29: error: DEBUG EVALUATE: Both operands of >= must have
the same type.
    9 | DEBUG EVALUATE /1 >= 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:9.17: note: DEBUG EVALUATE: This operand has type 'number'.
    9 | DEBUG EVALUATE /1 >= 'foobar'.
      |                 ^

evaluate.sps:9.22-9.29: note: DEBUG EVALUATE: This operand has type 'string'.
    9 | DEBUG EVALUATE /1 >= 'foobar'.
      |                      ^~~~~~~~

1 >= 'foobar' => error

evaluate.sps:10.17-10.29: error: DEBUG EVALUATE: Both operands of >= must have
the same type.
   10 | DEBUG EVALUATE /5 ge 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:10.17: note: DEBUG EVALUATE: This operand has type 'number'.
   10 | DEBUG EVALUATE /5 ge 'foobar'.
      |                 ^

evaluate.sps:10.22-10.29: note: DEBUG EVALUATE: This operand has type 'string'.
   10 | DEBUG EVALUATE /5 ge 'foobar'.
      |                      ^~~~~~~~

5 ge 'foobar' => error

evaluate.sps:11.17-11.27: error: DEBUG EVALUATE: Both operands of >= must have
the same type.
   11 | DEBUG EVALUATE /'baz' ge 10.
      |                 ^~~~~~~~~~~

evaluate.sps:11.17-11.21: note: DEBUG EVALUATE: This operand has type 'string'.
   11 | DEBUG EVALUATE /'baz' ge 10.
      |                 ^~~~~

evaluate.sps:11.26-11.27: note: DEBUG EVALUATE: This operand has type 'number'.
   11 | DEBUG EVALUATE /'baz' ge 10.
      |                          ^~

'baz' ge 10 => error

'0123' ge '0123' => true

'0123' >= '0124' => false

'0124' >= '0123' => true

'0123  ' ge '0123' => true

'0123' >= '0123 ' => true

1 > 2 => false

2.5 > 1.5 => true

3.5 gt 4 => false

4 gt 3.5 => true

evaluate.sps:22.17-22.29: error: DEBUG EVALUATE: Both operands of > must have
the same type.
   22 | DEBUG EVALUATE /1 gt 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:22.17: note: DEBUG EVALUATE: This operand has type 'number'.
   22 | DEBUG EVALUATE /1 gt 'foobar'.
      |                 ^

evaluate.sps:22.22-22.29: note: DEBUG EVALUATE: This operand has type 'string'.
   22 | DEBUG EVALUATE /1 gt 'foobar'.
      |                      ^~~~~~~~

1 gt 'foobar' => error

evaluate.sps:23.17-23.26: error: DEBUG EVALUATE: Both operands of > must have
the same type.
   23 | DEBUG EVALUATE /'baz' > 10.
      |                 ^~~~~~~~~~

evaluate.sps:23.17-23.21: note: DEBUG EVALUATE: This operand has type 'string'.
   23 | DEBUG EVALUATE /'baz' > 10.
      |                 ^~~~~

evaluate.sps:23.25-23.26: note: DEBUG EVALUATE: This operand has type 'number'.
   23 | DEBUG EVALUATE /'baz' > 10.
      |                         ^~

'baz' > 10 => error

'0123' > '0123' => false

'0123' > '0124' => false

'0124' > '0123' => true

'0123   ' > '0123' => false

'0123    ' > '0123 ' => false

1 ne 1 => false

1 ~= 1 => false

1 <> 2 => true

2 ne 3 => true

evaluate.sps:34.17-34.29: error: DEBUG EVALUATE: Both operands of ~= must have
the same type.
   34 | DEBUG EVALUATE /1 ~= 'foobar'.
      |                 ^~~~~~~~~~~~~

evaluate.sps:34.17: note: DEBUG EVALUATE: This operand has type 'number'.
   34 | DEBUG EVALUATE /1 ~= 'foobar'.
      |                 ^

evaluate.sps:34.22-34.29: note: DEBUG EVALUATE: This operand has type 'string'.
   34 | DEBUG EVALUATE /1 ~= 'foobar'.
      |                      ^~~~~~~~

1 ~= 'foobar' => error

evaluate.sps:35.17-35.27: error: DEBUG EVALUATE: Both operands of ~= must have
the same type.
   35 | DEBUG EVALUATE /'baz' ne 10.
      |                 ^~~~~~~~~~~

evaluate.sps:35.17-35.21: note: DEBUG EVALUATE: This operand has type 'string'.
   35 | DEBUG EVALUATE /'baz' ne 10.
      |                 ^~~~~

evaluate.sps:35.26-35.27: note: DEBUG EVALUATE: This operand has type 'number'.
   35 | DEBUG EVALUATE /'baz' ne 10.
      |                          ^~

'baz' ne 10 => error

evaluate.sps:36.17-36.30: error: DEBUG EVALUATE: Both operands of ~= must have
the same type.
   36 | DEBUG EVALUATE /'quux' ~= 5.55.
      |                 ^~~~~~~~~~~~~~

evaluate.sps:36.17-36.22: note: DEBUG EVALUATE: This operand has type 'string'.
   36 | DEBUG EVALUATE /'quux' ~= 5.55.
      |                 ^~~~~~

evaluate.sps:36.27-36.30: note: DEBUG EVALUATE: This operand has type 'number'.
   36 | DEBUG EVALUATE /'quux' ~= 5.55.
      |                           ^~~~

'quux' ~= 5.55 => error

'foobar' <> 'foobar' => false

'quux' ne 'bar' => true

'bar   ' <> 'bar' => false

'asdf       ' ~= "asdf   " => false

evaluate.sps:41.21: error: DEBUG EVALUATE: Syntax error parsing expression.
   41 | DEBUG EVALUATE /1 < > 1.
      |                     ^

1 < > 1 => error

evaluate.sps:42.19: error: DEBUG EVALUATE: Syntax error expecting end of
command.
   42 | DEBUG EVALUATE /1 ~ = 1.
      |                   ^

1 ~ = 1 => error
])
done
AT_CLEANUP

AT_SETUP([expressions - EXP LG10 LN SQRT ABS MOD MOD10 RND TRUNC])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /EXP(10).
DEBUG EVALUATE /EXP('x').

DEBUG EVALUATE /LG10(500).
DEBUG EVALUATE /LG10('x').

DEBUG EVALUATE /SQRT(500).
DEBUG EVALUATE /SQRT(-1).

DEBUG EVALUATE /ABS(-10.5).
DEBUG EVALUATE /ABS(55.79).
DEBUG EVALUATE /ABS(0).
DEBUG EVALUATE /ABS(-0).

DEBUG EVALUATE /MOD(55.5, 2).
DEBUG EVALUATE /MOD(-55.5, 2).
DEBUG EVALUATE /MOD(55.5, -2).
DEBUG EVALUATE /MOD(-55.5, -2).
DEBUG EVALUATE /MOD('a', 2).
DEBUG EVALUATE /MOD(2, 'a').
DEBUG EVALUATE /MOD('a', 'b').

DEBUG EVALUATE /MOD10(55.5).
DEBUG EVALUATE /MOD10(-55.5).

DEBUG EVALUATE /RND(5.4).
DEBUG EVALUATE /RND(5.6).
DEBUG EVALUATE /RND(-5.4).
DEBUG EVALUATE /RND(-5.6).
DEBUG EVALUATE /RND(5.56, .1).
DEBUG EVALUATE /RND(-5.56, .1)
DEBUG EVALUATE /RND(.5).
DEBUG EVALUATE /RND(.5 - 2**-53).
DEBUG EVALUATE /RND(.5 - 2**-52).
DEBUG EVALUATE /RND(.5 - 2**-51).
DEBUG EVALUATE /RND(.5 - 2**-45).
DEBUG EVALUATE /RND(.5 - 2**-45, 1, 10).
DEBUG EVALUATE /RND('x').

DEBUG EVALUATE /TRUNC(1.2).
DEBUG EVALUATE /TRUNC(1.9).
DEBUG EVALUATE /TRUNC(-1.2).
DEBUG EVALUATE /TRUNC(-1.9).
DEBUG EVALUATE /TRUNC(5.06, .1).
DEBUG EVALUATE /TRUNC(-5.06, .1).
DEBUG EVALUATE /TRUNC(1).
DEBUG EVALUATE /TRUNC(1 - 2**-53).
DEBUG EVALUATE /TRUNC(1 - 2**-52).
DEBUG EVALUATE /TRUNC(1 - 2**-51).
DEBUG EVALUATE /TRUNC(1 - 2**-45).
DEBUG EVALUATE /TRUNC(1 - 2**-45, 1, 10).
DEBUG EVALUATE /TRUNC('x').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
EXP(10) => 22026.47

evaluate.sps:4.17-4.24: error: DEBUG EVALUATE: Type mismatch invoking
EXP(number) as EXP(string).
    4 | DEBUG EVALUATE /EXP('x').
      |                 ^~~~~~~~

evaluate.sps:4.21-4.23: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
    4 | DEBUG EVALUATE /EXP('x').
      |                     ^~~

EXP('x') => error

LG10(500) => 2.70

evaluate.sps:7.17-7.25: error: DEBUG EVALUATE: Type mismatch invoking
LG10(number) as LG10(string).
    7 | DEBUG EVALUATE /LG10('x').
      |                 ^~~~~~~~~

evaluate.sps:7.22-7.24: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
    7 | DEBUG EVALUATE /LG10('x').
      |                      ^~~

LG10('x') => error

SQRT(500) => 22.36

SQRT(-1) => sysmis

ABS(-10.5) => 10.50

ABS(55.79) => 55.79

ABS(0) => 0.00

ABS(-0) => 0.00

MOD(55.5, 2) => 1.50

MOD(-55.5, 2) => -1.50

MOD(55.5, -2) => 1.50

MOD(-55.5, -2) => -1.50

evaluate.sps:21.17-21.27: error: DEBUG EVALUATE: Type mismatch invoking
MOD(number, number) as MOD(string, number).
   21 | DEBUG EVALUATE /MOD('a', 2).
      |                 ^~~~~~~~~~~

evaluate.sps:21.21-21.23: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   21 | DEBUG EVALUATE /MOD('a', 2).
      |                     ^~~

MOD('a', 2) => error

evaluate.sps:22.17-22.27: error: DEBUG EVALUATE: Type mismatch invoking
MOD(number, number) as MOD(number, string).
   22 | DEBUG EVALUATE /MOD(2, 'a').
      |                 ^~~~~~~~~~~

evaluate.sps:22.24-22.26: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   22 | DEBUG EVALUATE /MOD(2, 'a').
      |                        ^~~

MOD(2, 'a') => error

evaluate.sps:23.17-23.29: error: DEBUG EVALUATE: Type mismatch invoking
MOD(number, number) as MOD(string, string).
   23 | DEBUG EVALUATE /MOD('a', 'b').
      |                 ^~~~~~~~~~~~~

evaluate.sps:23.21-23.23: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   23 | DEBUG EVALUATE /MOD('a', 'b').
      |                     ^~~

evaluate.sps:23.26-23.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   23 | DEBUG EVALUATE /MOD('a', 'b').
      |                          ^~~

MOD('a', 'b') => error

MOD10(55.5) => 5.50

MOD10(-55.5) => -5.50

RND(5.4) => 5.00

RND(5.6) => 6.00

RND(-5.4) => -5.00

RND(-5.6) => -6.00

RND(5.56, .1) => 5.60

RND(-5.56, .1) => -5.60

RND(.5) => 1.00

RND(.5 - 2**-53) => 1.00

RND(.5 - 2**-52) => 1.00

RND(.5 - 2**-51) => 1.00

RND(.5 - 2**-45) => 0.00

RND(.5 - 2**-45, 1, 10) => 1.00

evaluate.sps:40.17-40.24: error: DEBUG EVALUATE: Function invocation
RND(string) does not match any known function.  Candidates are:
RND(number)
RND(number, number)
RND(number, number, number).
   40 | DEBUG EVALUATE /RND('x').
      |                 ^~~~~~~~

RND('x') => error

TRUNC(1.2) => 1.00

TRUNC(1.9) => 1.00

TRUNC(-1.2) => -1.00

TRUNC(-1.9) => -1.00

TRUNC(5.06, .1) => 5.00

TRUNC(-5.06, .1) => -5.00

TRUNC(1) => 1.00

TRUNC(1 - 2**-53) => 1.00

TRUNC(1 - 2**-52) => 1.00

TRUNC(1 - 2**-51) => 1.00

TRUNC(1 - 2**-45) => 0.00

TRUNC(1 - 2**-45, 1, 10) => 1.00

evaluate.sps:54.17-54.26: error: DEBUG EVALUATE: Function invocation
TRUNC(string) does not match any known function.  Candidates are:
TRUNC(number)
TRUNC(number, number)
TRUNC(number, number, number).
   54 | DEBUG EVALUATE /TRUNC('x').
      |                 ^~~~~~~~~~

TRUNC('x') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - ACOS ARSIN ARTAN COS SIN TAN])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ACOS(.5) / 3.14159 * 180.
DEBUG EVALUATE /ARCOS(.75) / 3.14159 * 180.
DEBUG EVALUATE /ARCOS(-.5) / 3.14159 * 180.
DEBUG EVALUATE /ACOS(-.75) / 3.14159 * 180.
DEBUG EVALUATE /ACOS(-1) / 3.14159 * 180.
DEBUG EVALUATE /ARCOS(1) / 3.14159 * 180.
DEBUG EVALUATE /ACOS(-1.01) / 3.14159 * 180.
DEBUG EVALUATE /ARCOS(1.01) / 3.14159 * 180.
DEBUG EVALUATE /ACOS('x') / 3.14159 * 180.

DEBUG EVALUATE /ASIN(.5) / 3.14159 * 180.
DEBUG EVALUATE /ARSIN(.25) / 3.14159 * 180.
DEBUG EVALUATE /ARSIN(-.5) / 3.14159 * 180.
DEBUG EVALUATE /ASIN(-.25) / 3.14159 * 180.
DEBUG EVALUATE /ASIN(-1.01) / 3.14159 * 180.
DEBUG EVALUATE /ARSIN(1.01) / 3.14159 * 180.
DEBUG EVALUATE /ASIN('x') / 3.14159 * 180.

DEBUG EVALUATE /ATAN(1) / 3.14159 * 180.
DEBUG EVALUATE /ARTAN(10) / 3.14159 * 180.
DEBUG EVALUATE /ARTAN(-1) / 3.14159 * 180.
DEBUG EVALUATE /ATAN(-10) / 3.14159 * 180.
DEBUG EVALUATE /ATAN('x') / 3.14159 * 180.

DEBUG EVALUATE /COS(60 / 180 * 3.14159).
DEBUG EVALUATE /COS(45 / 180 * 3.14159).
DEBUG EVALUATE /COS(30 / 180 * 3.14159).
DEBUG EVALUATE /COS(15 / 180 * 3.14159).
DEBUG EVALUATE /COS(-60 / 180 * 3.14159).
DEBUG EVALUATE /COS(-45 / 180 * 3.14159).
DEBUG EVALUATE /COS(-30 / 180 * 3.14159).
DEBUG EVALUATE /COS(-15 / 180 * 3.14159).
DEBUG EVALUATE /COS(123 / 180 * 3.14159).
DEBUG EVALUATE /COS(321 / 180 * 3.14159).
DEBUG EVALUATE /COS('x').

DEBUG EVALUATE /SIN(60 / 180 * 3.14159).
DEBUG EVALUATE /SIN(45 / 180 * 3.14159).
DEBUG EVALUATE /SIN(30 / 180 * 3.14159).
DEBUG EVALUATE /SIN(15 / 180 * 3.14159).
DEBUG EVALUATE /SIN(-60 / 180 * 3.14159).
DEBUG EVALUATE /SIN(-45 / 180 * 3.14159).
DEBUG EVALUATE /SIN(-30 / 180 * 3.14159).
DEBUG EVALUATE /SIN(-15 / 180 * 3.14159).
DEBUG EVALUATE /SIN(123 / 180 * 3.14159).
DEBUG EVALUATE /SIN(321 / 180 * 3.14159).
DEBUG EVALUATE /SIN('x').

DEBUG EVALUATE /TAN(60 / 180 * 3.14159).
DEBUG EVALUATE /TAN(45 / 180 * 3.14159).
DEBUG EVALUATE /TAN(30 / 180 * 3.14159).
DEBUG EVALUATE /TAN(15 / 180 * 3.14159).
DEBUG EVALUATE /TAN(-60 / 180 * 3.14159).
DEBUG EVALUATE /TAN(-45 / 180 * 3.14159).
DEBUG EVALUATE /TAN(-30 / 180 * 3.14159).
DEBUG EVALUATE /TAN(-15 / 180 * 3.14159).
DEBUG EVALUATE /TAN(123 / 180 * 3.14159).
DEBUG EVALUATE /TAN(321 / 180 * 3.14159).
DEBUG EVALUATE /TAN('x').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ACOS(.5) / 3.14159 * 180 => 60.00

ARCOS(.75) / 3.14159 * 180 => 41.41

ARCOS(-.5) / 3.14159 * 180 => 120.00

ACOS(-.75) / 3.14159 * 180 => 138.59

ACOS(-1) / 3.14159 * 180 => 180.00

ARCOS(1) / 3.14159 * 180 => 0.00

ACOS(-1.01) / 3.14159 * 180 => sysmis

ARCOS(1.01) / 3.14159 * 180 => sysmis

evaluate.sps:11.17-11.25: error: DEBUG EVALUATE: Type mismatch invoking
ACOS(number) as ACOS(string).
   11 | DEBUG EVALUATE /ACOS('x') / 3.14159 * 180.
      |                 ^~~~~~~~~

evaluate.sps:11.22-11.24: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   11 | DEBUG EVALUATE /ACOS('x') / 3.14159 * 180.
      |                      ^~~

ACOS('x') / 3.14159 * 180 => error

ASIN(.5) / 3.14159 * 180 => 30.00

ARSIN(.25) / 3.14159 * 180 => 14.48

ARSIN(-.5) / 3.14159 * 180 => -30.00

ASIN(-.25) / 3.14159 * 180 => -14.48

ASIN(-1.01) / 3.14159 * 180 => sysmis

ARSIN(1.01) / 3.14159 * 180 => sysmis

evaluate.sps:19.17-19.25: error: DEBUG EVALUATE: Type mismatch invoking
ASIN(number) as ASIN(string).
   19 | DEBUG EVALUATE /ASIN('x') / 3.14159 * 180.
      |                 ^~~~~~~~~

evaluate.sps:19.22-19.24: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   19 | DEBUG EVALUATE /ASIN('x') / 3.14159 * 180.
      |                      ^~~

ASIN('x') / 3.14159 * 180 => error

ATAN(1) / 3.14159 * 180 => 45.00

ARTAN(10) / 3.14159 * 180 => 84.29

ARTAN(-1) / 3.14159 * 180 => -45.00

ATAN(-10) / 3.14159 * 180 => -84.29

evaluate.sps:25.17-25.25: error: DEBUG EVALUATE: Type mismatch invoking
ATAN(number) as ATAN(string).
   25 | DEBUG EVALUATE /ATAN('x') / 3.14159 * 180.
      |                 ^~~~~~~~~

evaluate.sps:25.22-25.24: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   25 | DEBUG EVALUATE /ATAN('x') / 3.14159 * 180.
      |                      ^~~

ATAN('x') / 3.14159 * 180 => error

COS(60 / 180 * 3.14159) => 0.50

COS(45 / 180 * 3.14159) => 0.71

COS(30 / 180 * 3.14159) => 0.87

COS(15 / 180 * 3.14159) => 0.97

COS(-60 / 180 * 3.14159) => 0.50

COS(-45 / 180 * 3.14159) => 0.71

COS(-30 / 180 * 3.14159) => 0.87

COS(-15 / 180 * 3.14159) => 0.97

COS(123 / 180 * 3.14159) => -0.54

COS(321 / 180 * 3.14159) => 0.78

evaluate.sps:37.17-37.24: error: DEBUG EVALUATE: Type mismatch invoking
COS(number) as COS(string).
   37 | DEBUG EVALUATE /COS('x').
      |                 ^~~~~~~~

evaluate.sps:37.21-37.23: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   37 | DEBUG EVALUATE /COS('x').
      |                     ^~~

COS('x') => error

SIN(60 / 180 * 3.14159) => 0.87

SIN(45 / 180 * 3.14159) => 0.71

SIN(30 / 180 * 3.14159) => 0.50

SIN(15 / 180 * 3.14159) => 0.26

SIN(-60 / 180 * 3.14159) => -0.87

SIN(-45 / 180 * 3.14159) => -0.71

SIN(-30 / 180 * 3.14159) => -0.50

SIN(-15 / 180 * 3.14159) => -0.26

SIN(123 / 180 * 3.14159) => 0.84

SIN(321 / 180 * 3.14159) => -0.63

evaluate.sps:49.17-49.24: error: DEBUG EVALUATE: Type mismatch invoking
SIN(number) as SIN(string).
   49 | DEBUG EVALUATE /SIN('x').
      |                 ^~~~~~~~

evaluate.sps:49.21-49.23: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   49 | DEBUG EVALUATE /SIN('x').
      |                     ^~~

SIN('x') => error

TAN(60 / 180 * 3.14159) => 1.73

TAN(45 / 180 * 3.14159) => 1.00

TAN(30 / 180 * 3.14159) => 0.58

TAN(15 / 180 * 3.14159) => 0.27

TAN(-60 / 180 * 3.14159) => -1.73

TAN(-45 / 180 * 3.14159) => -1.00

TAN(-30 / 180 * 3.14159) => -0.58

TAN(-15 / 180 * 3.14159) => -0.27

TAN(123 / 180 * 3.14159) => -1.54

TAN(321 / 180 * 3.14159) => -0.81

evaluate.sps:61.17-61.24: error: DEBUG EVALUATE: Type mismatch invoking
TAN(number) as TAN(string).
   61 | DEBUG EVALUATE /TAN('x').
      |                 ^~~~~~~~

evaluate.sps:61.21-61.23: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   61 | DEBUG EVALUATE /TAN('x').
      |                     ^~~

TAN('x') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - vector indexing])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(1).
DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(2).
DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(3).
DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v($sysmis).
DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(0).
DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(4).

DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(1).
DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(2).
DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(3).
DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v($sysmis).
DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(0).
DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(4).

])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
v(1) => 11.00

v(2) => 22.00

v(3) => 33.00

evaluate.sps:7.42-7.51: error: DEBUG EVALUATE: Index outside valid range 1 to
3, inclusive, for vector V.  The value will be treated as system-missing.
    7 | DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v($sysmis).
      |                                          ^~~~~~~~~~

evaluate.sps:7.44-7.50: note: DEBUG EVALUATE: The index is system-missing.
    7 | DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v($sysmis).
      |                                            ^~~~~~~

v($sysmis) => sysmis

evaluate.sps:8.42-8.45: error: DEBUG EVALUATE: Index outside valid range 1 to
3, inclusive, for vector V.  The value will be treated as system-missing.
    8 | DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(0).
      |                                          ^~~~

evaluate.sps:8.44: note: DEBUG EVALUATE: The index has value 0.
    8 | DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(0).
      |                                            ^

v(0) => sysmis

evaluate.sps:9.42-9.45: error: DEBUG EVALUATE: Index outside valid range 1 to
3, inclusive, for vector V.  The value will be treated as system-missing.
    9 | DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(4).
      |                                          ^~~~

evaluate.sps:9.44: note: DEBUG EVALUATE: The index has value 4.
    9 | DEBUG EVALUATE (a=11)(b=22)(c=33) VECTOR/v(4).
      |                                            ^

v(4) => sysmis

v(1) => "abc"

v(2) => "def"

v(3) => "ghi"

evaluate.sps:14.51-14.60: error: DEBUG EVALUATE: Index outside valid range 1 to
3, inclusive, for vector V.  The value will be treated as system-missing.
   14 | DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v($sysmis).
      |                                                   ^~~~~~~~~~

evaluate.sps:14.53-14.59: note: DEBUG EVALUATE: The index is system-missing.
   14 | DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v($sysmis).
      |                                                     ^~~~~~~

v($sysmis) => ""

evaluate.sps:15.51-15.54: error: DEBUG EVALUATE: Index outside valid range 1 to
3, inclusive, for vector V.  The value will be treated as system-missing.
   15 | DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(0).
      |                                                   ^~~~

evaluate.sps:15.53: note: DEBUG EVALUATE: The index has value 0.
   15 | DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(0).
      |                                                     ^

v(0) => ""

evaluate.sps:16.51-16.54: error: DEBUG EVALUATE: Index outside valid range 1 to
3, inclusive, for vector V.  The value will be treated as system-missing.
   16 | DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(4).
      |                                                   ^~~~

evaluate.sps:16.53: note: DEBUG EVALUATE: The index has value 4.
   16 | DEBUG EVALUATE (a='abc')(b='def')(c='ghi') VECTOR/v(4).
      |                                                     ^

v(4) => ""
])
done
AT_CLEANUP

AT_SETUP([expressions - MISSING NMISS NVALID SYSMIS])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /MISSING(10).
DEBUG EVALUATE /MISSING($SYSMIS).
DEBUG EVALUATE /MISSING(ASIN(1.01)).
DEBUG EVALUATE /MISSING(ASIN(.5)).
DEBUG EVALUATE /MISSING('    ').

DEBUG EVALUATE (x=5)/x.
DEBUG EVALUATE (x=5 MISSING)/x.
DEBUG EVALUATE (x=5 MISSING)/x + 1.
DEBUG EVALUATE (x=SYSMIS)/x.

DEBUG EVALUATE (x=5) VECTOR/v(1).
DEBUG EVALUATE (x=5 MISSING) VECTOR/v(1).
DEBUG EVALUATE (x=5 MISSING) VECTOR/v(1) + 1.
DEBUG EVALUATE (x=SYSMIS) VECTOR/v(1).

DEBUG EVALUATE (x=5)/VALUE(x).
DEBUG EVALUATE (x=5 MISSING)/VALUE(x).
DEBUG EVALUATE (x=SYSMIS)/VALUE(x).

DEBUG EVALUATE (x=5) VECTOR/VALUE(v(1)).
DEBUG EVALUATE (x=5 MISSING) VECTOR/VALUE(v(1)).
DEBUG EVALUATE (x=SYSMIS) VECTOR/VALUE(v(1)).

DEBUG EVALUATE (x=5)/MISSING(x).
DEBUG EVALUATE (x=5 MISSING)/MISSING(x).
DEBUG EVALUATE (x=SYSMIS)/MISSING(x).

DEBUG EVALUATE (x=5)/SYSMIS(x).
DEBUG EVALUATE (x=5 MISSING)/SYSMIS(x).
DEBUG EVALUATE (x=SYSMIS)/SYSMIS(x).

DEBUG EVALUATE /NMISS($sysmis).
DEBUG EVALUATE /NMISS(0).
DEBUG EVALUATE /NMISS($sysmis, $sysmis, $sysmis).
DEBUG EVALUATE /NMISS(1, 2, 3, 4).
DEBUG EVALUATE /NMISS(1, $sysmis, $sysmis, 2, 2, $sysmis, $sysmis, 3, 4).
DEBUG EVALUATE (a=1 MISSING) (b=2) (c=3 MISSING) (d=4)/NMISS(a, b, c, d).

DEBUG EVALUATE /NVALID($sysmis).
DEBUG EVALUATE /NVALID(0).
DEBUG EVALUATE /NVALID($sysmis, $sysmis, $sysmis).
DEBUG EVALUATE /NVALID(1, 2, 3, 4).
DEBUG EVALUATE /NVALID(1, $sysmis, $sysmis, 2, 2, $sysmis, $sysmis, 3, 4).
DEBUG EVALUATE (a=1 MISSING) (b=2) (c=3 MISSING) (d=4)/NVALID(a, b, c, d).

DEBUG EVALUATE /SYSMIS(1).
DEBUG EVALUATE /SYSMIS($SYSMIS).
DEBUG EVALUATE /SYSMIS(1 + $SYSMIS).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
MISSING(10) => false

MISSING($SYSMIS) => true

MISSING(ASIN(1.01)) => true

MISSING(ASIN(.5)) => false

evaluate.sps:7.17-7.31: error: DEBUG EVALUATE: Type mismatch invoking
MISSING(number) as MISSING(string).
    7 | DEBUG EVALUATE /MISSING('    ').
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:7.25-7.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
    7 | DEBUG EVALUATE /MISSING('    ').
      |                         ^~~~~~

MISSING('    ') => error

x => 5.00

x => sysmis

x + 1 => sysmis

x => sysmis

v(1) => 5.00

v(1) => sysmis

v(1) + 1 => sysmis

v(1) => sysmis

VALUE(x) => 5.00

VALUE(x) => 5.00

VALUE(x) => sysmis

VALUE(v(1)) => 5.00

VALUE(v(1)) => 5.00

VALUE(v(1)) => sysmis

MISSING(x) => false

MISSING(x) => true

MISSING(x) => true

SYSMIS(x) => false

SYSMIS(x) => false

SYSMIS(x) => true

NMISS($sysmis) => 1.00

NMISS(0) => 0.00

NMISS($sysmis, $sysmis, $sysmis) => 3.00

NMISS(1, 2, 3, 4) => 0.00

NMISS(1, $sysmis, $sysmis, 2, 2, $sysmis, $sysmis, 3, 4) => 4.00

NMISS(a, b, c, d) => 2.00

NVALID($sysmis) => 0.00

NVALID(0) => 1.00

NVALID($sysmis, $sysmis, $sysmis) => 0.00

NVALID(1, 2, 3, 4) => 4.00

NVALID(1, $sysmis, $sysmis, 2, 2, $sysmis, $sysmis, 3, 4) => 5.00

NVALID(a, b, c, d) => 2.00

SYSMIS(1) => false

SYSMIS($SYSMIS) => true

SYSMIS(1 + $SYSMIS) => true
])
done
AT_CLEANUP

AT_SETUP([expressions - ANY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /any(1, 1, 2, 3).
DEBUG EVALUATE /any(1, $true, 2, 3).
DEBUG EVALUATE /any(1, $false, 2, 3).
DEBUG EVALUATE /any(2, 1, 2, 3).
DEBUG EVALUATE /any(3, 1, 2, 3).
DEBUG EVALUATE /any(5, 1, 2, 3).
DEBUG EVALUATE /any(1, 1, 1, 1).
DEBUG EVALUATE /any($sysmis, 1, 1, 1).
DEBUG EVALUATE /any($sysmis, 1, $sysmis, 3).
DEBUG EVALUATE /any(1, 1, $sysmis, $sysmis).
DEBUG EVALUATE /any(1, $sysmis, $sysmis, $sysmis).
DEBUG EVALUATE /any($sysmis, $sysmis, $sysmis, $sysmis).

DEBUG EVALUATE /any(1).
DEBUG EVALUATE /any('1', 2, 3, 4).
DEBUG EVALUATE /any(1, '2', 3, 4).
DEBUG EVALUATE /any(1, 2, '3', 4).
DEBUG EVALUATE /any(1, 2, 3, '4').

DEBUG EVALUATE /any('', 'a', '', 'c').
DEBUG EVALUATE /any('a', 'a', 'b', 'c').
DEBUG EVALUATE /any('b', 'a', 'b', 'c').
DEBUG EVALUATE /any('c', 'a', 'b', 'c').
DEBUG EVALUATE /any('e', 'a', 'b', 'c').
DEBUG EVALUATE /any('a', 'a', 'a', 'a').
DEBUG EVALUATE /any('', 'a', 'a', 'a').
DEBUG EVALUATE /any('a', '', '', '').
DEBUG EVALUATE /any('a').

DEBUG EVALUATE /any('a', 'a  ', 'b', 'c').
DEBUG EVALUATE /any('b   ', 'a', 'b', 'c').
DEBUG EVALUATE /any('c   ', 'a', 'b', 'c     ').
DEBUG EVALUATE /any(a10, 'b', 'c', 'd').
DEBUG EVALUATE /any('a', b, 'c', 'd').
DEBUG EVALUATE /any('a', 'b', c, 'd').
DEBUG EVALUATE /any('a', 'b', 'c', d).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1],
[[any(1, 1, 2, 3) => true

any(1, $true, 2, 3) => true

any(1, $false, 2, 3) => false

any(2, 1, 2, 3) => true

any(3, 1, 2, 3) => true

any(5, 1, 2, 3) => false

any(1, 1, 1, 1) => true

any($sysmis, 1, 1, 1) => sysmis

any($sysmis, 1, $sysmis, 3) => sysmis

any(1, 1, $sysmis, $sysmis) => true

any(1, $sysmis, $sysmis, $sysmis) => sysmis

any($sysmis, $sysmis, $sysmis, $sysmis) => sysmis

evaluate.sps:17.17-17.22: error: DEBUG EVALUATE: Function invocation
any(number) does not match any known function.  Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   17 | DEBUG EVALUATE /any(1).
      |                 ^~~~~~

any(1) => error

evaluate.sps:18.17-18.33: error: DEBUG EVALUATE: Function invocation
any(string, number, number, number) does not match any known function.
Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   18 | DEBUG EVALUATE /any('1', 2, 3, 4).
      |                 ^~~~~~~~~~~~~~~~~

any('1', 2, 3, 4) => error

evaluate.sps:19.17-19.33: error: DEBUG EVALUATE: Function invocation
any(number, string, number, number) does not match any known function.
Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   19 | DEBUG EVALUATE /any(1, '2', 3, 4).
      |                 ^~~~~~~~~~~~~~~~~

any(1, '2', 3, 4) => error

evaluate.sps:20.17-20.33: error: DEBUG EVALUATE: Function invocation
any(number, number, string, number) does not match any known function.
Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   20 | DEBUG EVALUATE /any(1, 2, '3', 4).
      |                 ^~~~~~~~~~~~~~~~~

any(1, 2, '3', 4) => error

evaluate.sps:21.17-21.33: error: DEBUG EVALUATE: Function invocation
any(number, number, number, string) does not match any known function.
Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   21 | DEBUG EVALUATE /any(1, 2, 3, '4').
      |                 ^~~~~~~~~~~~~~~~~

any(1, 2, 3, '4') => error

any('', 'a', '', 'c') => true

any('a', 'a', 'b', 'c') => true

any('b', 'a', 'b', 'c') => true

any('c', 'a', 'b', 'c') => true

any('e', 'a', 'b', 'c') => false

any('a', 'a', 'a', 'a') => true

any('', 'a', 'a', 'a') => false

any('a', '', '', '') => false

evaluate.sps:31.17-31.24: error: DEBUG EVALUATE: Function invocation
any(string) does not match any known function.  Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   31 | DEBUG EVALUATE /any('a').
      |                 ^~~~~~~~

any('a') => error

any('a', 'a  ', 'b', 'c') => true

any('b   ', 'a', 'b', 'c') => true

any('c   ', 'a', 'b', 'c     ') => true

evaluate.sps:36.17-36.39: error: DEBUG EVALUATE: Function invocation
any(format, string, string, string) does not match any known function.
Candidates are:
ANY(number, number[, number]...)
ANY(string, string[, string]...).
   36 | DEBUG EVALUATE /any(a10, 'b', 'c', 'd').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

any(a10, 'b', 'c', 'd') => error

evaluate.sps:37.26: error: DEBUG EVALUATE: Unknown identifier b.
   37 | DEBUG EVALUATE /any('a', b, 'c', 'd').
      |                          ^

any('a', b, 'c', 'd') => error

evaluate.sps:38.31: error: DEBUG EVALUATE: Unknown identifier c.
   38 | DEBUG EVALUATE /any('a', 'b', c, 'd').
      |                               ^

any('a', 'b', c, 'd') => error

evaluate.sps:39.36: error: DEBUG EVALUATE: Unknown identifier d.
   39 | DEBUG EVALUATE /any('a', 'b', 'c', d).
      |                                    ^

any('a', 'b', 'c', d) => error
]])
done
AT_CLEANUP

AT_SETUP([expressions - RANGE])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /range(5, 1, 10).
DEBUG EVALUATE /range(1, 1, 10).
DEBUG EVALUATE /range(10, 1, 10).
DEBUG EVALUATE /range(-1, 1, 10).
DEBUG EVALUATE /range(12, 1, 10).

DEBUG EVALUATE /range(5, $sysmis, 6, 1, 10).
DEBUG EVALUATE /range(5, $sysmis, $sysmis, 1, 10).
DEBUG EVALUATE /range(1, 1, 10, 6, $sysmis).
DEBUG EVALUATE /range(1, 1, 10, $sysmis, $sysmis).

DEBUG EVALUATE /range(5, 5, 10, 3, 7).
DEBUG EVALUATE /range(5, 10, 5, 3, 7).
DEBUG EVALUATE /range(5, 3, 7, 5, 10).
DEBUG EVALUATE /range(5, 3, 7, 10, 5).

DEBUG EVALUATE /range($sysmis, 1, 10).
DEBUG EVALUATE /range(5, 1, $sysmis).
DEBUG EVALUATE /range(5, $sysmis, 10).
DEBUG EVALUATE /range(1, 1, $sysmis).
DEBUG EVALUATE /range(10, $sysmis, 10).
DEBUG EVALUATE /range(5, 10, 5).
DEBUG EVALUATE /range($sysmis, $sysmis, 10).
DEBUG EVALUATE /range($sysmis, 1, $sysmis).
DEBUG EVALUATE /range($sysmis, $sysmis, $sysmis).

DEBUG EVALUATE /range(0, 1, 8, 10, 18).
DEBUG EVALUATE /range(1, 1, 8, 10, 18).
DEBUG EVALUATE /range(6, 1, 8, 10, 18).
DEBUG EVALUATE /range(8, 1, 8, 10, 18).
DEBUG EVALUATE /range(9, 1, 8, 10, 18).
DEBUG EVALUATE /range(10, 1, 8, 10, 18).
DEBUG EVALUATE /range(13, 1, 8, 10, 18).
DEBUG EVALUATE /range(16, 1, 8, 10, 18).
DEBUG EVALUATE /range(18, 1, 8, 10, 18).
DEBUG EVALUATE /range(20, 1, 8, 10, 18).
DEBUG EVALUATE /range(1).
DEBUG EVALUATE /range(1, 2).
DEBUG EVALUATE /range(1, 2, 3, 4).
DEBUG EVALUATE /range(1, 2, 3, 4, 5, 6).
DEBUG EVALUATE /range('1', 2, 3).
DEBUG EVALUATE /range(1, '2', 3).
DEBUG EVALUATE /range(1, 2, '3').

DEBUG EVALUATE /range('123', '111', '888').
DEBUG EVALUATE /range('111', '111', '888').
DEBUG EVALUATE /range('888', '111', '888').
DEBUG EVALUATE /range('110', '111', '888').
DEBUG EVALUATE /range('889', '111', '888').
DEBUG EVALUATE /range('000', '111', '888').
DEBUG EVALUATE /range('999', '111', '888').

DEBUG EVALUATE /range('123   ', '111', '888').
DEBUG EVALUATE /range('123', '111   ', '888').
DEBUG EVALUATE /range('123', '111', '888   ').
DEBUG EVALUATE /range('123', '111    ', '888   ').

DEBUG EVALUATE /range('00', '01', '08', '10', '18').
DEBUG EVALUATE /range('01', '01', '08', '10', '18').
DEBUG EVALUATE /range('06', '01', '08', '10', '18').
DEBUG EVALUATE /range('08', '01', '08', '10', '18').
DEBUG EVALUATE /range('09', '01', '08', '10', '18').
DEBUG EVALUATE /range('10', '01', '08', '10', '18').
DEBUG EVALUATE /range('15', '01', '08', '10', '18').
DEBUG EVALUATE /range('18', '01', '08', '10', '18').
DEBUG EVALUATE /range('19', '01', '08', '10', '18').

DEBUG EVALUATE /range('07', '01', '08', '18', '10').
DEBUG EVALUATE /range('12', '08', '01', '10', '18').

DEBUG EVALUATE /range('1').
DEBUG EVALUATE /range('1', '2').
DEBUG EVALUATE /range('1', '2', '3', '4').
DEBUG EVALUATE /range('1', '2', '3', '4', '5', '6').
DEBUG EVALUATE /range(1, '2', '3').
DEBUG EVALUATE /range('1', 2, '3').
DEBUG EVALUATE /range('1', '2', 3).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1],
[[range(5, 1, 10) => true

range(1, 1, 10) => true

range(10, 1, 10) => true

range(-1, 1, 10) => false

range(12, 1, 10) => false

range(5, $sysmis, 6, 1, 10) => true

range(5, $sysmis, $sysmis, 1, 10) => true

range(1, 1, 10, 6, $sysmis) => true

range(1, 1, 10, $sysmis, $sysmis) => true

range(5, 5, 10, 3, 7) => true

range(5, 10, 5, 3, 7) => sysmis

range(5, 3, 7, 5, 10) => true

range(5, 3, 7, 10, 5) => sysmis

range($sysmis, 1, 10) => sysmis

range(5, 1, $sysmis) => sysmis

range(5, $sysmis, 10) => sysmis

range(1, 1, $sysmis) => sysmis

range(10, $sysmis, 10) => sysmis

range(5, 10, 5) => sysmis

range($sysmis, $sysmis, 10) => sysmis

range($sysmis, 1, $sysmis) => sysmis

range($sysmis, $sysmis, $sysmis) => sysmis

range(0, 1, 8, 10, 18) => false

range(1, 1, 8, 10, 18) => true

range(6, 1, 8, 10, 18) => true

range(8, 1, 8, 10, 18) => true

range(9, 1, 8, 10, 18) => false

range(10, 1, 8, 10, 18) => true

range(13, 1, 8, 10, 18) => true

range(16, 1, 8, 10, 18) => true

range(18, 1, 8, 10, 18) => true

range(20, 1, 8, 10, 18) => false

evaluate.sps:40.17-40.24: error: DEBUG EVALUATE: Function invocation
range(number) does not match any known function.  Candidates are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   40 | DEBUG EVALUATE /range(1).
      |                 ^~~~~~~~

range(1) => error

evaluate.sps:41.17-41.27: error: DEBUG EVALUATE: RANGE(number, number, number[,
number, number]...) must have an odd number of arguments.
   41 | DEBUG EVALUATE /range(1, 2).
      |                 ^~~~~~~~~~~

range(1, 2) => error

evaluate.sps:42.17-42.33: error: DEBUG EVALUATE: RANGE(number, number, number[,
number, number]...) must have an odd number of arguments.
   42 | DEBUG EVALUATE /range(1, 2, 3, 4).
      |                 ^~~~~~~~~~~~~~~~~

range(1, 2, 3, 4) => error

evaluate.sps:43.17-43.39: error: DEBUG EVALUATE: RANGE(number, number, number[,
number, number]...) must have an odd number of arguments.
   43 | DEBUG EVALUATE /range(1, 2, 3, 4, 5, 6).
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

range(1, 2, 3, 4, 5, 6) => error

evaluate.sps:44.17-44.32: error: DEBUG EVALUATE: Function invocation
range(string, number, number) does not match any known function.  Candidates
are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   44 | DEBUG EVALUATE /range('1', 2, 3).
      |                 ^~~~~~~~~~~~~~~~

range('1', 2, 3) => error

evaluate.sps:45.17-45.32: error: DEBUG EVALUATE: Function invocation
range(number, string, number) does not match any known function.  Candidates
are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   45 | DEBUG EVALUATE /range(1, '2', 3).
      |                 ^~~~~~~~~~~~~~~~

range(1, '2', 3) => error

evaluate.sps:46.17-46.32: error: DEBUG EVALUATE: Function invocation
range(number, number, string) does not match any known function.  Candidates
are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   46 | DEBUG EVALUATE /range(1, 2, '3').
      |                 ^~~~~~~~~~~~~~~~

range(1, 2, '3') => error

range('123', '111', '888') => true

range('111', '111', '888') => true

range('888', '111', '888') => true

range('110', '111', '888') => false

range('889', '111', '888') => false

range('000', '111', '888') => false

range('999', '111', '888') => false

range('123   ', '111', '888') => true

range('123', '111   ', '888') => true

range('123', '111', '888   ') => true

range('123', '111    ', '888   ') => true

range('00', '01', '08', '10', '18') => false

range('01', '01', '08', '10', '18') => true

range('06', '01', '08', '10', '18') => true

range('08', '01', '08', '10', '18') => true

range('09', '01', '08', '10', '18') => false

range('10', '01', '08', '10', '18') => true

range('15', '01', '08', '10', '18') => true

range('18', '01', '08', '10', '18') => true

range('19', '01', '08', '10', '18') => false

range('07', '01', '08', '18', '10') => sysmis

range('12', '08', '01', '10', '18') => sysmis

evaluate.sps:74.17-74.26: error: DEBUG EVALUATE: Function invocation
range(string) does not match any known function.  Candidates are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   74 | DEBUG EVALUATE /range('1').
      |                 ^~~~~~~~~~

range('1') => error

evaluate.sps:75.17-75.31: error: DEBUG EVALUATE: RANGE(string, string, string[,
string, string]...) must have an odd number of arguments.
   75 | DEBUG EVALUATE /range('1', '2').
      |                 ^~~~~~~~~~~~~~~

range('1', '2') => error

evaluate.sps:76.17-76.41: error: DEBUG EVALUATE: RANGE(string, string, string[,
string, string]...) must have an odd number of arguments.
   76 | DEBUG EVALUATE /range('1', '2', '3', '4').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~

range('1', '2', '3', '4') => error

evaluate.sps:77.17-77.51: error: DEBUG EVALUATE: RANGE(string, string, string[,
string, string]...) must have an odd number of arguments.
   77 | DEBUG EVALUATE /range('1', '2', '3', '4', '5', '6').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

range('1', '2', '3', '4', '5', '6') => error

evaluate.sps:78.17-78.34: error: DEBUG EVALUATE: Function invocation
range(number, string, string) does not match any known function.  Candidates
are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   78 | DEBUG EVALUATE /range(1, '2', '3').
      |                 ^~~~~~~~~~~~~~~~~~

range(1, '2', '3') => error

evaluate.sps:79.17-79.34: error: DEBUG EVALUATE: Function invocation
range(string, number, string) does not match any known function.  Candidates
are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   79 | DEBUG EVALUATE /range('1', 2, '3').
      |                 ^~~~~~~~~~~~~~~~~~

range('1', 2, '3') => error

evaluate.sps:80.17-80.34: error: DEBUG EVALUATE: Function invocation
range(string, string, number) does not match any known function.  Candidates
are:
RANGE(number, number, number[, number, number]...)
RANGE(string, string, string[, string, string]...).
   80 | DEBUG EVALUATE /range('1', '2', 3).
      |                 ^~~~~~~~~~~~~~~~~~

range('1', '2', 3) => error
]])
done
AT_CLEANUP

AT_SETUP([expressions - MAX MIN])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /max(1, 2, 3, 4, 5).
DEBUG EVALUATE /max(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /max(1, 2).
DEBUG EVALUATE /max().
DEBUG EVALUATE /max(1).
DEBUG EVALUATE /max(1, $sysmis).
DEBUG EVALUATE /max(1, 2, 3, $sysmis).
DEBUG EVALUATE /max.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /max.4(1, 2, 3).

DEBUG EVALUATE /max("2", "3", "5", "1", "4").
DEBUG EVALUATE /max("1", "2").
DEBUG EVALUATE /max("1").

DEBUG EVALUATE /min(1, 2, 3, 4, 5).
DEBUG EVALUATE /min(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /min(1, 2).
DEBUG EVALUATE /min().
DEBUG EVALUATE /min(1).
DEBUG EVALUATE /min(1, $sysmis).
DEBUG EVALUATE /min(1, 2, 3, $sysmis).
DEBUG EVALUATE /min.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /min.4(1, 2, 3).

DEBUG EVALUATE /min("2", "3", "5", "1", "4").
DEBUG EVALUATE /min("1", "2").
DEBUG EVALUATE /min("1").
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1],
[[max(1, 2, 3, 4, 5) => 5.00

max(1, $sysmis, 2, 3, $sysmis, 4, 5) => 5.00

max(1, 2) => 2.00

evaluate.sps:6.17-6.20: error: DEBUG EVALUATE: Function invocation max() does
not match any known function.  Candidates are:
MAX(number[, number]...)
MAX(string[, string]...).
    6 | DEBUG EVALUATE /max().
      |                 ^~~~

max() => error

max(1) => 1.00

max(1, $sysmis) => 1.00

max(1, 2, 3, $sysmis) => 3.00

max.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:11.17-11.30: error: DEBUG EVALUATE: For MAX(number[, number]...)
with 3 arguments, at most 3 (not 4) may be required to be valid.
   11 | DEBUG EVALUATE /max.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~~

max.4(1, 2, 3) => error

max("2", "3", "5", "1", "4") => "5"

max("1", "2") => "2"

max("1") => "1"

min(1, 2, 3, 4, 5) => 1.00

min(1, $sysmis, 2, 3, $sysmis, 4, 5) => 1.00

min(1, 2) => 1.00

evaluate.sps:20.17-20.20: error: DEBUG EVALUATE: Function invocation min() does
not match any known function.  Candidates are:
MIN(number[, number]...)
MIN(string[, string]...).
   20 | DEBUG EVALUATE /min().
      |                 ^~~~

min() => error

min(1) => 1.00

min(1, $sysmis) => 1.00

min(1, 2, 3, $sysmis) => 1.00

min.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:25.17-25.30: error: DEBUG EVALUATE: For MIN(number[, number]...)
with 3 arguments, at most 3 (not 4) may be required to be valid.
   25 | DEBUG EVALUATE /min.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~~

min.4(1, 2, 3) => error

min("2", "3", "5", "1", "4") => "1"

min("1", "2") => "1"

min("1") => "1"
]])
done
AT_CLEANUP

AT_SETUP([expressions - CFVAR MEAN MEDIAN])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /cfvar(1, 2, 3, 4, 5).
DEBUG EVALUATE /cfvar(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /cfvar(1, 2).
DEBUG EVALUATE /cfvar(1).
DEBUG EVALUATE /cfvar(1, $sysmis).
DEBUG EVALUATE /cfvar(1, 2, 3, $sysmis).
DEBUG EVALUATE /cfvar.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /cfvar.4(1, 2, 3).
DEBUG EVALUATE /cfvar('x').
DEBUG EVALUATE /cfvar('x', 1, 2, 3).

DEBUG EVALUATE /mean(1, 2, 3, 4, 5).
DEBUG EVALUATE /mean(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /mean(1, 2).
DEBUG EVALUATE /mean().
DEBUG EVALUATE /mean(1).
DEBUG EVALUATE /mean(1, $sysmis).
DEBUG EVALUATE /mean(1, 2, 3, $sysmis).
DEBUG EVALUATE /mean.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /mean.4(1, 2, 3).

DEBUG EVALUATE /median(1, 2, 3, 4, 5).
DEBUG EVALUATE /median(2, 3, 4, 5, 1).
DEBUG EVALUATE /median(2, 3, 4, 1, 5).
DEBUG EVALUATE /median(2, 1, 4, 5, 3).
DEBUG EVALUATE /median(1, 2, 3, 4).
DEBUG EVALUATE /median(2, 3, 1, 4).
DEBUG EVALUATE /median(2, 3, 4, 1).
DEBUG EVALUATE /median(2, 1, 4, 3).
DEBUG EVALUATE /median(1, $sysmis, 3, 4, 5).
DEBUG EVALUATE /median(2, 3, 4, 5, $sysmis, 1).
DEBUG EVALUATE /median($sysmis, $sysmis, $sysmis, 2, 3, 4, 1, 5).
DEBUG EVALUATE /median(1, 2, 3).
DEBUG EVALUATE /median(1).
DEBUG EVALUATE /median(1, 2).
DEBUG EVALUATE /median(1, 2, $sysmis).
DEBUG EVALUATE /median(1, $sysmis, $sysmis).
DEBUG EVALUATE /median($sysmis, $sysmis, $sysmis).
DEBUG EVALUATE /median.3(1, 2, $sysmis).
DEBUG EVALUATE /median.2(1, $sysmis).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1],
[[cfvar(1, 2, 3, 4, 5) => 0.53

cfvar(1, $sysmis, 2, 3, $sysmis, 4, 5) => 0.53

cfvar(1, 2) => 0.47

evaluate.sps:7.17-7.24: error: DEBUG EVALUATE: Type mismatch invoking
CFVAR(number, number[, number]...) as cfvar(number).
    7 | DEBUG EVALUATE /cfvar(1).
      |                 ^~~~~~~~

cfvar(1) => error

cfvar(1, $sysmis) => sysmis

cfvar(1, 2, 3, $sysmis) => 0.50

cfvar.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:11.17-11.32: error: DEBUG EVALUATE: For CFVAR(number, number[,
number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.
   11 | DEBUG EVALUATE /cfvar.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~~~~

cfvar.4(1, 2, 3) => error

evaluate.sps:12.17-12.26: error: DEBUG EVALUATE: Type mismatch invoking
CFVAR(number, number[, number]...) as cfvar(string).
   12 | DEBUG EVALUATE /cfvar('x').
      |                 ^~~~~~~~~~

evaluate.sps:12.23-12.25: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   12 | DEBUG EVALUATE /cfvar('x').
      |                       ^~~

cfvar('x') => error

evaluate.sps:13.17-13.35: error: DEBUG EVALUATE: Type mismatch invoking
CFVAR(number, number[, number]...) as cfvar(string, number, number, number).
   13 | DEBUG EVALUATE /cfvar('x', 1, 2, 3).
      |                 ^~~~~~~~~~~~~~~~~~~

cfvar('x', 1, 2, 3) => error

mean(1, 2, 3, 4, 5) => 3.00

mean(1, $sysmis, 2, 3, $sysmis, 4, 5) => 3.00

mean(1, 2) => 1.50

evaluate.sps:18.17-18.21: error: DEBUG EVALUATE: Type mismatch invoking
MEAN(number[, number]...) as mean().
   18 | DEBUG EVALUATE /mean().
      |                 ^~~~~

mean() => error

mean(1) => 1.00

mean(1, $sysmis) => 1.00

mean(1, 2, 3, $sysmis) => 2.00

mean.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:23.17-23.31: error: DEBUG EVALUATE: For MEAN(number[, number]...)
with 3 arguments, at most 3 (not 4) may be required to be valid.
   23 | DEBUG EVALUATE /mean.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~~~

mean.4(1, 2, 3) => error

median(1, 2, 3, 4, 5) => 3.00

median(2, 3, 4, 5, 1) => 3.00

median(2, 3, 4, 1, 5) => 3.00

median(2, 1, 4, 5, 3) => 3.00

median(1, 2, 3, 4) => 2.50

median(2, 3, 1, 4) => 2.50

median(2, 3, 4, 1) => 2.50

median(2, 1, 4, 3) => 2.50

median(1, $sysmis, 3, 4, 5) => 3.50

median(2, 3, 4, 5, $sysmis, 1) => 3.00

median($sysmis, $sysmis, $sysmis, 2, 3, 4, 1, 5) => 3.00

median(1, 2, 3) => 2.00

median(1) => 1.00

median(1, 2) => 1.50

median(1, 2, $sysmis) => 1.50

median(1, $sysmis, $sysmis) => 1.00

median($sysmis, $sysmis, $sysmis) => sysmis

median.3(1, 2, $sysmis) => sysmis

median.2(1, $sysmis) => sysmis
]])
done
AT_CLEANUP

AT_SETUP([expressions - SD SUM VARIANCE])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /sd(1, 2, 3, 4, 5).
DEBUG EVALUATE /sd(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /sd(1, 2).
DEBUG EVALUATE /sd(1).
DEBUG EVALUATE /sd(1, $sysmis).
DEBUG EVALUATE /sd(1, 2, 3, $sysmis).
DEBUG EVALUATE /sd.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /sd.4(1, 2, 3).
DEBUG EVALUATE /sd('x').
DEBUG EVALUATE /sd('x', 1, 2, 3).
DEBUG EVALUATE (a=1)(b=2)(c=3)(d=4)(e=5)(f=6)(g=7)/sd(a TO c).

DEBUG EVALUATE /sum(1, 2, 3, 4, 5).
DEBUG EVALUATE /sum(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /sum(1, 2).
DEBUG EVALUATE /sum().
DEBUG EVALUATE /sum(1).
DEBUG EVALUATE /sum(1, $sysmis).
DEBUG EVALUATE /sum(1, 2, 3, $sysmis).
DEBUG EVALUATE /sum.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /sum.4(1, 2, 3).
DEBUG EVALUATE (a=1)(b=2)(c=3)(d=4)(e=5)(f=6)(g=7)/sum(b TO F).

DEBUG EVALUATE /variance(1, 2, 3, 4, 5).
DEBUG EVALUATE /variance(1, $sysmis, 2, 3, $sysmis, 4, 5).
DEBUG EVALUATE /variance(1, 2).
DEBUG EVALUATE /variance(1).
DEBUG EVALUATE /variance(1, $sysmis).
DEBUG EVALUATE /variance(1, 2, 3, $sysmis).
DEBUG EVALUATE /variance.4(1, 2, 3, $sysmis).
DEBUG EVALUATE /variance.4(1, 2, 3).
DEBUG EVALUATE /variance('x').
DEBUG EVALUATE /variance('x', 1, 2, 3).
DEBUG EVALUATE (a=1)(b=2)(c=3)(d=4)(e=5)(f=6)(g=7)/variance(a TO e).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1],
[[sd(1, 2, 3, 4, 5) => 1.58

sd(1, $sysmis, 2, 3, $sysmis, 4, 5) => 1.58

sd(1, 2) => 0.71

evaluate.sps:7.17-7.21: error: DEBUG EVALUATE: Type mismatch invoking
SD(number, number[, number]...) as sd(number).
    7 | DEBUG EVALUATE /sd(1).
      |                 ^~~~~

sd(1) => error

sd(1, $sysmis) => sysmis

sd(1, 2, 3, $sysmis) => 1.00

sd.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:11.17-11.29: error: DEBUG EVALUATE: For SD(number, number[,
number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.
   11 | DEBUG EVALUATE /sd.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~

sd.4(1, 2, 3) => error

evaluate.sps:12.17-12.23: error: DEBUG EVALUATE: Type mismatch invoking
SD(number, number[, number]...) as sd(string).
   12 | DEBUG EVALUATE /sd('x').
      |                 ^~~~~~~

evaluate.sps:12.20-12.22: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   12 | DEBUG EVALUATE /sd('x').
      |                    ^~~

sd('x') => error

evaluate.sps:13.17-13.32: error: DEBUG EVALUATE: Type mismatch invoking
SD(number, number[, number]...) as sd(string, number, number, number).
   13 | DEBUG EVALUATE /sd('x', 1, 2, 3).
      |                 ^~~~~~~~~~~~~~~~

sd('x', 1, 2, 3) => error

sd(a TO c) => 1.00

sum(1, 2, 3, 4, 5) => 15.00

sum(1, $sysmis, 2, 3, $sysmis, 4, 5) => 15.00

sum(1, 2) => 3.00

evaluate.sps:19.17-19.20: error: DEBUG EVALUATE: Type mismatch invoking
SUM(number[, number]...) as sum().
   19 | DEBUG EVALUATE /sum().
      |                 ^~~~

sum() => error

sum(1) => 1.00

sum(1, $sysmis) => 1.00

sum(1, 2, 3, $sysmis) => 6.00

sum.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:24.17-24.30: error: DEBUG EVALUATE: For SUM(number[, number]...)
with 3 arguments, at most 3 (not 4) may be required to be valid.
   24 | DEBUG EVALUATE /sum.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~~

sum.4(1, 2, 3) => error

sum(b TO F) => 20.00

variance(1, 2, 3, 4, 5) => 2.50

variance(1, $sysmis, 2, 3, $sysmis, 4, 5) => 2.50

variance(1, 2) => 0.50

evaluate.sps:30.17-30.27: error: DEBUG EVALUATE: Type mismatch invoking
VARIANCE(number, number[, number]...) as variance(number).
   30 | DEBUG EVALUATE /variance(1).
      |                 ^~~~~~~~~~~

variance(1) => error

variance(1, $sysmis) => sysmis

variance(1, 2, 3, $sysmis) => 1.00

variance.4(1, 2, 3, $sysmis) => sysmis

evaluate.sps:34.17-34.35: error: DEBUG EVALUATE: For VARIANCE(number, number[,
number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.
   34 | DEBUG EVALUATE /variance.4(1, 2, 3).
      |                 ^~~~~~~~~~~~~~~~~~~

variance.4(1, 2, 3) => error

evaluate.sps:35.17-35.29: error: DEBUG EVALUATE: Type mismatch invoking
VARIANCE(number, number[, number]...) as variance(string).
   35 | DEBUG EVALUATE /variance('x').
      |                 ^~~~~~~~~~~~~

evaluate.sps:35.26-35.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   35 | DEBUG EVALUATE /variance('x').
      |                          ^~~

variance('x') => error

evaluate.sps:36.17-36.38: error: DEBUG EVALUATE: Type mismatch invoking
VARIANCE(number, number[, number]...) as variance(string, number, number,
number).
   36 | DEBUG EVALUATE /variance('x', 1, 2, 3).
      |                 ^~~~~~~~~~~~~~~~~~~~~~

variance('x', 1, 2, 3) => error

variance(a TO e) => 2.50
]])
done
AT_CLEANUP

AT_SETUP([expressions - CONCAT])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /concat('').
DEBUG EVALUATE /concat('a', 'b').
DEBUG EVALUATE /concat('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h').
DEBUG EVALUATE /concat('abcdefgh', 'ijklmnopq').
DEBUG EVALUATE /concat('a', 1).
DEBUG EVALUATE /concat(1, 2).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1],
[[concat('') => ""

concat('a', 'b') => "ab"

concat('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') => "abcdefgh"

concat('abcdefgh', 'ijklmnopq') => "abcdefghijklmnopq"

evaluate.sps:8.17-8.30: error: DEBUG EVALUATE: Type mismatch invoking
CONCAT(string[, string]...) as concat(string, number).
    8 | DEBUG EVALUATE /concat('a', 1).
      |                 ^~~~~~~~~~~~~~

concat('a', 1) => error

evaluate.sps:9.17-9.28: error: DEBUG EVALUATE: Type mismatch invoking
CONCAT(string[, string]...) as concat(number, number).
    9 | DEBUG EVALUATE /concat(1, 2).
      |                 ^~~~~~~~~~~~

concat(1, 2) => error
]])
done
AT_CLEANUP

AT_SETUP([expressions - INDEX])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /index('abcbcde', 'bc').
DEBUG EVALUATE /index('abcbcde', 'bcd').
DEBUG EVALUATE /index('abcbcde', 'bcbc').
DEBUG EVALUATE /index('abcdefgh', 'abc').
DEBUG EVALUATE /index('abcdefgh', 'bcd').
DEBUG EVALUATE /index('abcdefgh', 'cde').
DEBUG EVALUATE /index('abcdefgh', 'def').
DEBUG EVALUATE /index('abcdefgh', 'efg').
DEBUG EVALUATE /index('abcdefgh', 'fgh').
DEBUG EVALUATE /index('abcdefgh', 'fghi').
DEBUG EVALUATE /index('abcdefgh', 'x').
DEBUG EVALUATE /index('abcdefgh', 'abch').
DEBUG EVALUATE /index('banana', 'na').
DEBUG EVALUATE /index('banana', 'ana').
DEBUG EVALUATE /index('', 'x').
DEBUG EVALUATE /index('x', '').
DEBUG EVALUATE /index('', '').
DEBUG EVALUATE /index('abcdefgh', '').
DEBUG EVALUATE /index('abcdefgh', 'alkjsfdjlskalkjfa').

DEBUG EVALUATE /index('abcbcde', 'bc', 1).
DEBUG EVALUATE /index('abcbcde', 'dc', 1).
DEBUG EVALUATE /index('abcbcde', 'abc', 1).
DEBUG EVALUATE /index('abcbcde', 'bc', 2).
DEBUG EVALUATE /index('abcbcde', 'dc', 2).
DEBUG EVALUATE /index('abcbcde', 'abc', 1).
DEBUG EVALUATE /index('abcbcde', 'bccb', 2).
DEBUG EVALUATE /index('abcbcde', 'bcbc', 2).
DEBUG EVALUATE /index('abcbcde', 'bcbc', $sysmis).
DEBUG EVALUATE /index('abcbcde', 'bcbc', 3).
DEBUG EVALUATE /index('abcbcde', '', 1).
DEBUG EVALUATE /index('', '', 1).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
index('abcbcde', 'bc') => 2.00

index('abcbcde', 'bcd') => 4.00

index('abcbcde', 'bcbc') => 2.00

index('abcdefgh', 'abc') => 1.00

index('abcdefgh', 'bcd') => 2.00

index('abcdefgh', 'cde') => 3.00

index('abcdefgh', 'def') => 4.00

index('abcdefgh', 'efg') => 5.00

index('abcdefgh', 'fgh') => 6.00

index('abcdefgh', 'fghi') => 0.00

index('abcdefgh', 'x') => 0.00

index('abcdefgh', 'abch') => 0.00

index('banana', 'na') => 3.00

index('banana', 'ana') => 2.00

index('', 'x') => 0.00

index('x', '') => 1.00

index('', '') => 1.00

index('abcdefgh', '') => 1.00

index('abcdefgh', 'alkjsfdjlskalkjfa') => 0.00

index('abcbcde', 'bc', 1) => 2.00

index('abcbcde', 'dc', 1) => 3.00

index('abcbcde', 'abc', 1) => 1.00

index('abcbcde', 'bc', 2) => 2.00

index('abcbcde', 'dc', 2) => 0.00

index('abcbcde', 'abc', 1) => 1.00

index('abcbcde', 'bccb', 2) => 2.00

index('abcbcde', 'bcbc', 2) => 2.00

index('abcbcde', 'bcbc', $sysmis) => sysmis

evaluate.sps:33.17-33.43: error: DEBUG EVALUATE: INDEX needle length argument
must evenly divide the length of the needles argument.
   33 | DEBUG EVALUATE /index('abcbcde', 'bcbc', 3).
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~

evaluate.sps:33.34-33.39: note: DEBUG EVALUATE: The needles argument has length
4.
   33 | DEBUG EVALUATE /index('abcbcde', 'bcbc', 3).
      |                                  ^~~~~~

evaluate.sps:33.42: note: DEBUG EVALUATE: The needle length argument has value
3.
   33 | DEBUG EVALUATE /index('abcbcde', 'bcbc', 3).
      |                                          ^

index('abcbcde', 'bcbc', 3) => sysmis

index('abcbcde', '', 1) => 0.00

index('', '', 1) => 0.00
])
done
AT_CLEANUP

AT_SETUP([expressions - RINDEX])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /rindex('abcbcde', 'bc').
DEBUG EVALUATE /rindex('abcbcde', 'bcd').
DEBUG EVALUATE /rindex('abcbcde', 'bcbc').
DEBUG EVALUATE /rindex('abcdefgh', 'abc').
DEBUG EVALUATE /rindex('abcdefgh', 'bcd').
DEBUG EVALUATE /rindex('abcdefgh', 'cde').
DEBUG EVALUATE /rindex('abcdefgh', 'def').
DEBUG EVALUATE /rindex('abcdefgh', 'efg').
DEBUG EVALUATE /rindex('abcdefgh', 'fgh').
DEBUG EVALUATE /rindex('abcdefgh', 'fghi').
DEBUG EVALUATE /rindex('abcdefgh', 'x').
DEBUG EVALUATE /rindex('abcdefgh', 'abch').
DEBUG EVALUATE /rindex('banana', 'na').
DEBUG EVALUATE /rindex('banana', 'ana').
DEBUG EVALUATE /rindex('', 'x').
DEBUG EVALUATE /rindex('x', '').
DEBUG EVALUATE /rindex('', '').
DEBUG EVALUATE /rindex('abcdefgh', '').
DEBUG EVALUATE /rindex('abcdefgh', 'alkjsfdjlskalkjfa').

DEBUG EVALUATE /rindex('abcbcde', 'bc', 1).
DEBUG EVALUATE /rindex('abcbcde', 'dc', 1).
DEBUG EVALUATE /rindex('abcbcde', 'abc', 1).
DEBUG EVALUATE /rindex('abcbcde', 'bc', 2).
DEBUG EVALUATE /rindex('abcbcde', 'dc', 2).
DEBUG EVALUATE /rindex('abcbcde', 'abc', 1).
DEBUG EVALUATE /rindex('abcbcde', 'bccb', 2).
DEBUG EVALUATE /rindex('abcbcde', 'bcbc', 2).
DEBUG EVALUATE /rindex('abcbcde', 'bcbc', 0).
DEBUG EVALUATE /rindex('abcbcde', 'bcbc', $sysmis).
DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', 2).
DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', $sysmis).
DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', 'x').
DEBUG EVALUATE /rindex(1, 'bcdfkjl', 2).
DEBUG EVALUATE /rindex('aksj', 2, 2).
DEBUG EVALUATE /rindex(1, 2, 3).
DEBUG EVALUATE /rindex(1, 2, '3').
DEBUG EVALUATE /rindex('abcbcde', '', 1).
DEBUG EVALUATE /rindex('', '', 1).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
rindex('abcbcde', 'bc') => 4.00

rindex('abcbcde', 'bcd') => 4.00

rindex('abcbcde', 'bcbc') => 2.00

rindex('abcdefgh', 'abc') => 1.00

rindex('abcdefgh', 'bcd') => 2.00

rindex('abcdefgh', 'cde') => 3.00

rindex('abcdefgh', 'def') => 4.00

rindex('abcdefgh', 'efg') => 5.00

rindex('abcdefgh', 'fgh') => 6.00

rindex('abcdefgh', 'fghi') => 0.00

rindex('abcdefgh', 'x') => 0.00

rindex('abcdefgh', 'abch') => 0.00

rindex('banana', 'na') => 5.00

rindex('banana', 'ana') => 4.00

rindex('', 'x') => 0.00

rindex('x', '') => 2.00

rindex('', '') => 1.00

rindex('abcdefgh', '') => 9.00

rindex('abcdefgh', 'alkjsfdjlskalkjfa') => 0.00

rindex('abcbcde', 'bc', 1) => 5.00

rindex('abcbcde', 'dc', 1) => 6.00

rindex('abcbcde', 'abc', 1) => 5.00

rindex('abcbcde', 'bc', 2) => 4.00

rindex('abcbcde', 'dc', 2) => 0.00

rindex('abcbcde', 'abc', 1) => 5.00

rindex('abcbcde', 'bccb', 2) => 4.00

rindex('abcbcde', 'bcbc', 2) => 4.00

evaluate.sps:32.17-32.44: error: DEBUG EVALUATE: RINDEX needle length argument
must evenly divide the length of the needles argument.
   32 | DEBUG EVALUATE /rindex('abcbcde', 'bcbc', 0).
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

evaluate.sps:32.35-32.40: note: DEBUG EVALUATE: The needles argument has length
4.
   32 | DEBUG EVALUATE /rindex('abcbcde', 'bcbc', 0).
      |                                   ^~~~~~

evaluate.sps:32.43: note: DEBUG EVALUATE: The needle length argument has value
0.
   32 | DEBUG EVALUATE /rindex('abcbcde', 'bcbc', 0).
      |                                           ^

rindex('abcbcde', 'bcbc', 0) => sysmis

rindex('abcbcde', 'bcbc', $sysmis) => sysmis

evaluate.sps:34.17-34.45: error: DEBUG EVALUATE: RINDEX needle length argument
must evenly divide the length of the needles argument.
   34 | DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', 2).
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

evaluate.sps:34.35-34.41: note: DEBUG EVALUATE: The needles argument has length
5.
   34 | DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', 2).
      |                                   ^~~~~~~

evaluate.sps:34.44: note: DEBUG EVALUATE: The needle length argument has value
2.
   34 | DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', 2).
      |                                            ^

rindex('abcbcde', 'bcbcg', 2) => sysmis

rindex('abcbcde', 'bcbcg', $sysmis) => sysmis

evaluate.sps:36.17-36.47: error: DEBUG EVALUATE: Function invocation
rindex(string, string, string) does not match any known function.  Candidates
are:
RINDEX(string, string)
RINDEX(string, string, integer).
   36 | DEBUG EVALUATE /rindex('abcbcde', 'bcbcg', 'x').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

rindex('abcbcde', 'bcbcg', 'x') => error

evaluate.sps:37.17-37.39: error: DEBUG EVALUATE: Function invocation
rindex(number, string, number) does not match any known function.  Candidates
are:
RINDEX(string, string)
RINDEX(string, string, integer).
   37 | DEBUG EVALUATE /rindex(1, 'bcdfkjl', 2).
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

rindex(1, 'bcdfkjl', 2) => error

evaluate.sps:38.17-38.36: error: DEBUG EVALUATE: Function invocation
rindex(string, number, number) does not match any known function.  Candidates
are:
RINDEX(string, string)
RINDEX(string, string, integer).
   38 | DEBUG EVALUATE /rindex('aksj', 2, 2).
      |                 ^~~~~~~~~~~~~~~~~~~~

rindex('aksj', 2, 2) => error

evaluate.sps:39.17-39.31: error: DEBUG EVALUATE: Function invocation
rindex(number, number, number) does not match any known function.  Candidates
are:
RINDEX(string, string)
RINDEX(string, string, integer).
   39 | DEBUG EVALUATE /rindex(1, 2, 3).
      |                 ^~~~~~~~~~~~~~~

rindex(1, 2, 3) => error

evaluate.sps:40.17-40.33: error: DEBUG EVALUATE: Function invocation
rindex(number, number, string) does not match any known function.  Candidates
are:
RINDEX(string, string)
RINDEX(string, string, integer).
   40 | DEBUG EVALUATE /rindex(1, 2, '3').
      |                 ^~~~~~~~~~~~~~~~~

rindex(1, 2, '3') => error

rindex('abcbcde', '', 1) => 0.00

rindex('', '', 1) => 0.00
])
done
AT_CLEANUP

AT_SETUP([expressions - LENGTH])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /length('').
DEBUG EVALUATE /length('a').
DEBUG EVALUATE /length('xy').
DEBUG EVALUATE /length('adsf    ').
DEBUG EVALUATE /length('abcdefghijkl').
DEBUG EVALUATE /length(0).
DEBUG EVALUATE /length($sysmis).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
length('') => 0.00

length('a') => 1.00

length('xy') => 2.00

length('adsf    ') => 8.00

length('abcdefghijkl') => 12.00

evaluate.sps:9.17-9.25: error: DEBUG EVALUATE: Type mismatch invoking
LENGTH(string) as length(number).
    9 | DEBUG EVALUATE /length(0).
      |                 ^~~~~~~~~

evaluate.sps:9.24: note: DEBUG EVALUATE: This argument has type 'number' but
'string' is required.
    9 | DEBUG EVALUATE /length(0).
      |                        ^

length(0) => error

evaluate.sps:10.17-10.31: error: DEBUG EVALUATE: Type mismatch invoking
LENGTH(string) as length(number).
   10 | DEBUG EVALUATE /length($sysmis).
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:10.24-10.30: note: DEBUG EVALUATE: This argument has type 'number'
but 'string' is required.
   10 | DEBUG EVALUATE /length($sysmis).
      |                        ^~~~~~~

length($sysmis) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - LOWER])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /lower('ABCDEFGHIJKLMNOPQRSTUVWXYZ!@%&*089').
DEBUG EVALUATE /lower('').
DEBUG EVALUATE /lower(1).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
lower('ABCDEFGHIJKLMNOPQRSTUVWXYZ!@%&*089') => "abcdefghijklmnopqrstuvwxyz!
@%&*089"

lower('') => ""

evaluate.sps:6.17-6.24: error: DEBUG EVALUATE: Type mismatch invoking
LOWER(string) as lower(number).
    6 | DEBUG EVALUATE /lower(1).
      |                 ^~~~~~~~

evaluate.sps:6.23: note: DEBUG EVALUATE: This argument has type 'number' but
'string' is required.
    6 | DEBUG EVALUATE /lower(1).
      |                       ^

lower(1) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - REPLACE])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /replace('banana', 'an', 'AN').
DEBUG EVALUATE /replace('banana', 'an', 'a').
DEBUG EVALUATE /replace('banana', 'an', '').
DEBUG EVALUATE /replace('banana', 'na', '').
DEBUG EVALUATE /replace('banana', 'ba', 'BA').
DEBUG EVALUATE /replace('banana', 'na', 'xyzzy').
DEBUG EVALUATE /replace('banana', 'an', 'xyzzy', 1).
DEBUG EVALUATE /replace('banana', 'an', 'xyzzy', 1.5).
DEBUG EVALUATE /replace('banana', 'bananana', 'xyzzy').
DEBUG EVALUATE /replace('banana', '', 'xyzzy').
DEBUG EVALUATE /replace('banana', 'ba', '', 0).
DEBUG EVALUATE /replace('banana', 'ba', '', -1).
DEBUG EVALUATE /replace('banana', 'ba', '', $sysmis).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
replace('banana', 'an', 'AN') => "bANANa"

replace('banana', 'an', 'a') => "baaa"

replace('banana', 'an', '') => "ba"

replace('banana', 'na', '') => "ba"

replace('banana', 'ba', 'BA') => "BAnana"

replace('banana', 'na', 'xyzzy') => "baxyzzyxyzzy"

replace('banana', 'an', 'xyzzy', 1) => "bxyzzyana"

evaluate.sps:10.50-10.52: error: DEBUG EVALUATE: Treating unexpected non-
integer value 1.5 as missing.
   10 | DEBUG EVALUATE /replace('banana', 'an', 'xyzzy', 1.5).
      |                                                  ^~~

replace('banana', 'an', 'xyzzy', 1.5) => "banana"

replace('banana', 'bananana', 'xyzzy') => "banana"

replace('banana', '', 'xyzzy') => "banana"

replace('banana', 'ba', '', 0) => "banana"

replace('banana', 'ba', '', -1) => "banana"

replace('banana', 'ba', '', $sysmis) => "banana"
])
done
AT_CLEANUP

AT_SETUP([expressions - LPAD])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /lpad('abc', 0).
DEBUG EVALUATE /lpad('abc', 2).
DEBUG EVALUATE /lpad('abc', 3).
DEBUG EVALUATE /lpad('abc', 10).

DEBUG EVALUATE /lpad('abc', -1).
DEBUG EVALUATE /lpad('abc', 32768).
DEBUG EVALUATE /lpad('abc', $sysmis).

DEBUG EVALUATE /lpad('abc', -1, '*').
DEBUG EVALUATE /lpad('abc', 0, '*').
DEBUG EVALUATE /lpad('abc', 2, '*').
DEBUG EVALUATE /lpad('abc', 3, '*').
DEBUG EVALUATE /lpad('abc', 10, '*').

DEBUG EVALUATE /lpad('abc', 5, 'de').
DEBUG EVALUATE /lpad('abc', 6, 'de').
DEBUG EVALUATE /lpad('abc', 7, 'de').
DEBUG EVALUATE /lpad('abc', 8, 'de').
DEBUG EVALUATE /lpad('abc', 9, 'de').

DEBUG EVALUATE /lpad('abc', 32768, '*').
DEBUG EVALUATE /lpad('abc', $sysmis, '*').
DEBUG EVALUATE /lpad('abc', $sysmis, '').
DEBUG EVALUATE /lpad('abc', $sysmis, 'xy').
DEBUG EVALUATE /lpad(0, 10).
DEBUG EVALUATE /lpad('abc', 'def').
DEBUG EVALUATE /lpad(0, 10, ' ').
DEBUG EVALUATE /lpad('abc', 'def', ' ').
DEBUG EVALUATE /lpad('x', 5, 0).
DEBUG EVALUATE /lpad('x', 5, 2).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
lpad('abc', 0) => "abc"

lpad('abc', 2) => "abc"

lpad('abc', 3) => "abc"

lpad('abc', 10) => "       abc"

evaluate.sps:9.17-9.31: error: DEBUG EVALUATE: The length argument to LPAD must
be between 0 and 32767.
    9 | DEBUG EVALUATE /lpad('abc', -1).
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:9.29-9.30: note: DEBUG EVALUATE: The length argument is -1.
    9 | DEBUG EVALUATE /lpad('abc', -1).
      |                             ^~

lpad('abc', -1) => "abc"

evaluate.sps:10.17-10.34: error: DEBUG EVALUATE: The length argument to LPAD
must be between 0 and 32767.
   10 | DEBUG EVALUATE /lpad('abc', 32768).
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:10.29-10.33: note: DEBUG EVALUATE: The length argument is 32768.
   10 | DEBUG EVALUATE /lpad('abc', 32768).
      |                             ^~~~~

lpad('abc', 32768) => "abc"

lpad('abc', $sysmis) => "abc"

evaluate.sps:13.17-13.36: error: DEBUG EVALUATE: The length argument to LPAD
must be between 0 and 32767.
   13 | DEBUG EVALUATE /lpad('abc', -1, '*').
      |                 ^~~~~~~~~~~~~~~~~~~~

evaluate.sps:13.29-13.30: note: DEBUG EVALUATE: The length argument is -1.
   13 | DEBUG EVALUATE /lpad('abc', -1, '*').
      |                             ^~

lpad('abc', -1, '*') => "abc"

lpad('abc', 0, '*') => "abc"

lpad('abc', 2, '*') => "abc"

lpad('abc', 3, '*') => "abc"

lpad('abc', 10, '*') => "*******abc"

lpad('abc', 5, 'de') => "deabc"

lpad('abc', 6, 'de') => "deabc"

lpad('abc', 7, 'de') => "dedeabc"

lpad('abc', 8, 'de') => "dedeabc"

lpad('abc', 9, 'de') => "dededeabc"

evaluate.sps:25.17-25.39: error: DEBUG EVALUATE: The length argument to LPAD
must be between 0 and 32767.
   25 | DEBUG EVALUATE /lpad('abc', 32768, '*').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

evaluate.sps:25.29-25.33: note: DEBUG EVALUATE: The length argument is 32768.
   25 | DEBUG EVALUATE /lpad('abc', 32768, '*').
      |                             ^~~~~

lpad('abc', 32768, '*') => "abc"

lpad('abc', $sysmis, '*') => "abc"

lpad('abc', $sysmis, '') => "abc"

lpad('abc', $sysmis, 'xy') => "abc"

evaluate.sps:29.17-29.27: error: DEBUG EVALUATE: Function invocation
lpad(number, number) does not match any known function.  Candidates are:
LPAD(string, integer)
LPAD(string, integer, string).
   29 | DEBUG EVALUATE /lpad(0, 10).
      |                 ^~~~~~~~~~~

lpad(0, 10) => error

evaluate.sps:30.17-30.34: error: DEBUG EVALUATE: Function invocation
lpad(string, string) does not match any known function.  Candidates are:
LPAD(string, integer)
LPAD(string, integer, string).
   30 | DEBUG EVALUATE /lpad('abc', 'def').
      |                 ^~~~~~~~~~~~~~~~~~

lpad('abc', 'def') => error

evaluate.sps:31.17-31.32: error: DEBUG EVALUATE: Function invocation
lpad(number, number, string) does not match any known function.  Candidates
are:
LPAD(string, integer)
LPAD(string, integer, string).
   31 | DEBUG EVALUATE /lpad(0, 10, ' ').
      |                 ^~~~~~~~~~~~~~~~

lpad(0, 10, ' ') => error

evaluate.sps:32.17-32.39: error: DEBUG EVALUATE: Function invocation
lpad(string, string, string) does not match any known function.  Candidates
are:
LPAD(string, integer)
LPAD(string, integer, string).
   32 | DEBUG EVALUATE /lpad('abc', 'def', ' ').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

lpad('abc', 'def', ' ') => error

evaluate.sps:33.17-33.31: error: DEBUG EVALUATE: Function invocation
lpad(string, number, number) does not match any known function.  Candidates
are:
LPAD(string, integer)
LPAD(string, integer, string).
   33 | DEBUG EVALUATE /lpad('x', 5, 0).
      |                 ^~~~~~~~~~~~~~~

lpad('x', 5, 0) => error

evaluate.sps:34.17-34.31: error: DEBUG EVALUATE: Function invocation
lpad(string, number, number) does not match any known function.  Candidates
are:
LPAD(string, integer)
LPAD(string, integer, string).
   34 | DEBUG EVALUATE /lpad('x', 5, 2).
      |                 ^~~~~~~~~~~~~~~

lpad('x', 5, 2) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - NUMBER])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /number("123", f3.0).
DEBUG EVALUATE /number(" 123", f3.0).
DEBUG EVALUATE /number("123", f3.1).
DEBUG EVALUATE /number("   ", f3.1).
DEBUG EVALUATE /number("123", a8).
dnl CCA is not an input format:
DEBUG EVALUATE /number("123", cca1.2).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
number("123", f3.0) => 123.00

number(" 123", f3.0) => 12.00

number("123", f3.1) => 12.30

number("   ", f3.1) => sysmis

evaluate.sps:7.17-7.33: error: DEBUG EVALUATE: Type mismatch invoking
NUMBER(string, num_input_format) as number(string, format).
    7 | DEBUG EVALUATE /number("123", a8).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:7.31-7.32: note: DEBUG EVALUATE: Numeric variables are not
compatible with string format A8.
    7 | DEBUG EVALUATE /number("123", a8).
      |                               ^~

number("123", a8) => error

evaluate.sps:8.17-8.37: error: DEBUG EVALUATE: Type mismatch invoking
NUMBER(string, num_input_format) as number(string, format).
    8 | DEBUG EVALUATE /number("123", cca1.2).
      |                 ^~~~~~~~~~~~~~~~~~~~~

evaluate.sps:8.31-8.36: note: DEBUG EVALUATE: Format CCA1.2 may not be used for
input.
    8 | DEBUG EVALUATE /number("123", cca1.2).
      |                               ^~~~~~

number("123", cca1.2) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - LTRIM])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ltrim('   abc').
DEBUG EVALUATE /rtrim('   abc   ').
DEBUG EVALUATE /ltrim('abc').
* The following string contains a tab.
DEBUG EVALUATE /ltrim('	abc').
DEBUG EVALUATE /ltrim('    ').
DEBUG EVALUATE /ltrim('').
DEBUG EVALUATE /ltrim(8).

DEBUG EVALUATE /ltrim('***abc', '*').
DEBUG EVALUATE /ltrim('abc', '*').
DEBUG EVALUATE /ltrim('*abc', '*').
DEBUG EVALUATE /ltrim('', '*').

DEBUG EVALUATE /ltrim('abc', 'xy').
DEBUG EVALUATE /ltrim('xyabc', 'xy').
DEBUG EVALUATE /ltrim('xyxyabc', 'xy').

DEBUG EVALUATE /ltrim(8, '*').
DEBUG EVALUATE /ltrim(' x', 8).
DEBUG EVALUATE /ltrim(8, 9).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ltrim('   abc') => "abc"

rtrim('   abc   ') => "   abc"

ltrim('abc') => "abc"

ltrim('	abc') => "	abc"

ltrim('    ') => ""

ltrim('') => ""

evaluate.sps:10.17-10.24: error: DEBUG EVALUATE: Function invocation
ltrim(number) does not match any known function.  Candidates are:
LTRIM(string)
LTRIM(string, string).
   10 | DEBUG EVALUATE /ltrim(8).
      |                 ^~~~~~~~

ltrim(8) => error

ltrim('***abc', '*') => "abc"

ltrim('abc', '*') => "abc"

ltrim('*abc', '*') => "abc"

ltrim('', '*') => ""

ltrim('abc', 'xy') => "abc"

ltrim('xyabc', 'xy') => "abc"

ltrim('xyxyabc', 'xy') => "abc"

evaluate.sps:21.17-21.29: error: DEBUG EVALUATE: Function invocation
ltrim(number, string) does not match any known function.  Candidates are:
LTRIM(string)
LTRIM(string, string).
   21 | DEBUG EVALUATE /ltrim(8, '*').
      |                 ^~~~~~~~~~~~~

ltrim(8, '*') => error

evaluate.sps:22.17-22.30: error: DEBUG EVALUATE: Function invocation
ltrim(string, number) does not match any known function.  Candidates are:
LTRIM(string)
LTRIM(string, string).
   22 | DEBUG EVALUATE /ltrim(' x', 8).
      |                 ^~~~~~~~~~~~~~

ltrim(' x', 8) => error

evaluate.sps:23.17-23.27: error: DEBUG EVALUATE: Function invocation
ltrim(number, number) does not match any known function.  Candidates are:
LTRIM(string)
LTRIM(string, string).
   23 | DEBUG EVALUATE /ltrim(8, 9).
      |                 ^~~~~~~~~~~

ltrim(8, 9) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - RPAD])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /rpad('abc', 0).
DEBUG EVALUATE /rpad('abc', 2).
DEBUG EVALUATE /rpad('abc', 3).
DEBUG EVALUATE /rpad('abc', 10).

DEBUG EVALUATE /rpad('abc', -1).
DEBUG EVALUATE /rpad('abc', 32768).
DEBUG EVALUATE /rpad('abc', $sysmis).

DEBUG EVALUATE /rpad('abc', -1, '*').
DEBUG EVALUATE /rpad('abc', 0, '*').
DEBUG EVALUATE /rpad('abc', 2, '*').
DEBUG EVALUATE /rpad('abc', 3, '*').
DEBUG EVALUATE /rpad('abc', 10, '*').

DEBUG EVALUATE /rpad('abc', 5, 'de').
DEBUG EVALUATE /rpad('abc', 6, 'de').
DEBUG EVALUATE /rpad('abc', 7, 'de').
DEBUG EVALUATE /rpad('abc', 8, 'de').
DEBUG EVALUATE /rpad('abc', 9, 'de').

DEBUG EVALUATE /rpad('abc', 32768, '*').
DEBUG EVALUATE /rpad('abc', $sysmis, '*').
DEBUG EVALUATE /rpad('abc', $sysmis, '').
DEBUG EVALUATE /rpad('abc', $sysmis, 'xy').
DEBUG EVALUATE /rpad(0, 10).
DEBUG EVALUATE /rpad('abc', 'def').
DEBUG EVALUATE /rpad(0, 10, ' ').
DEBUG EVALUATE /rpad('abc', 'def', ' ').
DEBUG EVALUATE /rpad('x', 5, 0).
DEBUG EVALUATE /rpad('x', 5, 2).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
rpad('abc', 0) => "abc"

rpad('abc', 2) => "abc"

rpad('abc', 3) => "abc"

rpad('abc', 10) => "abc       "

evaluate.sps:9.17-9.31: error: DEBUG EVALUATE: The length argument to RPAD must
be between 0 and 32767.
    9 | DEBUG EVALUATE /rpad('abc', -1).
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:9.29-9.30: note: DEBUG EVALUATE: The length argument is -1.
    9 | DEBUG EVALUATE /rpad('abc', -1).
      |                             ^~

rpad('abc', -1) => "abc"

evaluate.sps:10.17-10.34: error: DEBUG EVALUATE: The length argument to RPAD
must be between 0 and 32767.
   10 | DEBUG EVALUATE /rpad('abc', 32768).
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:10.29-10.33: note: DEBUG EVALUATE: The length argument is 32768.
   10 | DEBUG EVALUATE /rpad('abc', 32768).
      |                             ^~~~~

rpad('abc', 32768) => "abc"

rpad('abc', $sysmis) => "abc"

evaluate.sps:13.17-13.36: error: DEBUG EVALUATE: The length argument to RPAD
must be between 0 and 32767.
   13 | DEBUG EVALUATE /rpad('abc', -1, '*').
      |                 ^~~~~~~~~~~~~~~~~~~~

evaluate.sps:13.29-13.30: note: DEBUG EVALUATE: The length argument is -1.
   13 | DEBUG EVALUATE /rpad('abc', -1, '*').
      |                             ^~

rpad('abc', -1, '*') => "abc"

rpad('abc', 0, '*') => "abc"

rpad('abc', 2, '*') => "abc"

rpad('abc', 3, '*') => "abc"

rpad('abc', 10, '*') => "abc*******"

rpad('abc', 5, 'de') => "abcde"

rpad('abc', 6, 'de') => "abcde"

rpad('abc', 7, 'de') => "abcdede"

rpad('abc', 8, 'de') => "abcdede"

rpad('abc', 9, 'de') => "abcdedede"

evaluate.sps:25.17-25.39: error: DEBUG EVALUATE: The length argument to RPAD
must be between 0 and 32767.
   25 | DEBUG EVALUATE /rpad('abc', 32768, '*').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

evaluate.sps:25.29-25.33: note: DEBUG EVALUATE: The length argument is 32768.
   25 | DEBUG EVALUATE /rpad('abc', 32768, '*').
      |                             ^~~~~

rpad('abc', 32768, '*') => "abc"

rpad('abc', $sysmis, '*') => "abc"

rpad('abc', $sysmis, '') => "abc"

rpad('abc', $sysmis, 'xy') => "abc"

evaluate.sps:29.17-29.27: error: DEBUG EVALUATE: Function invocation
rpad(number, number) does not match any known function.  Candidates are:
RPAD(string, integer)
RPAD(string, integer, string).
   29 | DEBUG EVALUATE /rpad(0, 10).
      |                 ^~~~~~~~~~~

rpad(0, 10) => error

evaluate.sps:30.17-30.34: error: DEBUG EVALUATE: Function invocation
rpad(string, string) does not match any known function.  Candidates are:
RPAD(string, integer)
RPAD(string, integer, string).
   30 | DEBUG EVALUATE /rpad('abc', 'def').
      |                 ^~~~~~~~~~~~~~~~~~

rpad('abc', 'def') => error

evaluate.sps:31.17-31.32: error: DEBUG EVALUATE: Function invocation
rpad(number, number, string) does not match any known function.  Candidates
are:
RPAD(string, integer)
RPAD(string, integer, string).
   31 | DEBUG EVALUATE /rpad(0, 10, ' ').
      |                 ^~~~~~~~~~~~~~~~

rpad(0, 10, ' ') => error

evaluate.sps:32.17-32.39: error: DEBUG EVALUATE: Function invocation
rpad(string, string, string) does not match any known function.  Candidates
are:
RPAD(string, integer)
RPAD(string, integer, string).
   32 | DEBUG EVALUATE /rpad('abc', 'def', ' ').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~

rpad('abc', 'def', ' ') => error

evaluate.sps:33.17-33.31: error: DEBUG EVALUATE: Function invocation
rpad(string, number, number) does not match any known function.  Candidates
are:
RPAD(string, integer)
RPAD(string, integer, string).
   33 | DEBUG EVALUATE /rpad('x', 5, 0).
      |                 ^~~~~~~~~~~~~~~

rpad('x', 5, 0) => error

evaluate.sps:34.17-34.31: error: DEBUG EVALUATE: Function invocation
rpad(string, number, number) does not match any known function.  Candidates
are:
RPAD(string, integer)
RPAD(string, integer, string).
   34 | DEBUG EVALUATE /rpad('x', 5, 2).
      |                 ^~~~~~~~~~~~~~~

rpad('x', 5, 2) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - RTRIM])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /rtrim('abc   ').
DEBUG EVALUATE /rtrim('   abc   ').
DEBUG EVALUATE /rtrim('abc').
* The following string contains a tab.
DEBUG EVALUATE /rtrim('abc	').
DEBUG EVALUATE /rtrim('    ').
DEBUG EVALUATE /rtrim('').
DEBUG EVALUATE /rtrim(8).

DEBUG EVALUATE /rtrim('abc***', '*').
DEBUG EVALUATE /rtrim('abc', '*').
DEBUG EVALUATE /rtrim('abc*', '*').
DEBUG EVALUATE /rtrim('', '*').

DEBUG EVALUATE /rtrim('abc', 'xy').
DEBUG EVALUATE /rtrim('abcxy', 'xy').
DEBUG EVALUATE /rtrim('abcxyxy', 'xy').

DEBUG EVALUATE /rtrim(8, '*').
DEBUG EVALUATE /rtrim('x ', 8).
DEBUG EVALUATE /rtrim(8, 9).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
rtrim('abc   ') => "abc"

rtrim('   abc   ') => "   abc"

rtrim('abc') => "abc"

rtrim('abc	') => "abc	"

rtrim('    ') => ""

rtrim('') => ""

evaluate.sps:10.17-10.24: error: DEBUG EVALUATE: Function invocation
rtrim(number) does not match any known function.  Candidates are:
RTRIM(string)
RTRIM(string, string).
   10 | DEBUG EVALUATE /rtrim(8).
      |                 ^~~~~~~~

rtrim(8) => error

rtrim('abc***', '*') => "abc"

rtrim('abc', '*') => "abc"

rtrim('abc*', '*') => "abc"

rtrim('', '*') => ""

rtrim('abc', 'xy') => "abc"

rtrim('abcxy', 'xy') => "abc"

rtrim('abcxyxy', 'xy') => "abc"

evaluate.sps:21.17-21.29: error: DEBUG EVALUATE: Function invocation
rtrim(number, string) does not match any known function.  Candidates are:
RTRIM(string)
RTRIM(string, string).
   21 | DEBUG EVALUATE /rtrim(8, '*').
      |                 ^~~~~~~~~~~~~

rtrim(8, '*') => error

evaluate.sps:22.17-22.30: error: DEBUG EVALUATE: Function invocation
rtrim(string, number) does not match any known function.  Candidates are:
RTRIM(string)
RTRIM(string, string).
   22 | DEBUG EVALUATE /rtrim('x ', 8).
      |                 ^~~~~~~~~~~~~~

rtrim('x ', 8) => error

evaluate.sps:23.17-23.27: error: DEBUG EVALUATE: Function invocation
rtrim(number, number) does not match any known function.  Candidates are:
RTRIM(string)
RTRIM(string, string).
   23 | DEBUG EVALUATE /rtrim(8, 9).
      |                 ^~~~~~~~~~~

rtrim(8, 9) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - STRING])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /string(123.56, f5.1).
DEBUG EVALUATE /string($sysmis, f5.1).
DEBUG EVALUATE /string("abc", A5).
dnl E has a minimum width of 6 on output:
DEBUG EVALUATE /string(123, e1).
DEBUG EVALUATE /string(123, e6.0).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
string(123.56, f5.1) => "123.6"

string($sysmis, f5.1) => "   . "

evaluate.sps:5.17-5.33: error: DEBUG EVALUATE: Type mismatch invoking
STRING(number, num_output_format) as string(string, format).
    5 | DEBUG EVALUATE /string("abc", A5).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:5.24-5.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
    5 | DEBUG EVALUATE /string("abc", A5).
      |                        ^~~~~

evaluate.sps:5.31-5.32: note: DEBUG EVALUATE: Numeric variables are not
compatible with string format A5.
    5 | DEBUG EVALUATE /string("abc", A5).
      |                               ^~

string("abc", A5) => error

evaluate.sps:6.17-6.31: error: DEBUG EVALUATE: Type mismatch invoking
STRING(number, num_output_format) as string(number, format).
    6 | DEBUG EVALUATE /string(123, e1).
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:6.29-6.30: note: DEBUG EVALUATE: Output format E1.0 specifies
width 1, but E requires a width between 6 and 40.
    6 | DEBUG EVALUATE /string(123, e1).
      |                             ^~

string(123, e1) => error

string(123, e6.0) => "1E+002"
])
done
AT_CLEANUP

AT_SETUP([expressions - STRUNC])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /strunc('a c   ', 9).
DEBUG EVALUATE /strunc('a c   ', 7).
DEBUG EVALUATE /strunc('a c   ', 6).
DEBUG EVALUATE /strunc('a c   ', 5).
DEBUG EVALUATE /strunc('a c   ', 4).
DEBUG EVALUATE /strunc('a c   ', 3).
DEBUG EVALUATE /strunc('a c   ', 2).
DEBUG EVALUATE /strunc('a c   ', 1).
DEBUG EVALUATE /strunc('a c   ', 0).

DEBUG EVALUATE /strunc('a c   ', 0.75).
DEBUG EVALUATE /strunc('a c   ', -1).
DEBUG EVALUATE /strunc('a c   ', $sysmis).

DEBUG EVALUATE /strunc('  abc  ', 9).
DEBUG EVALUATE /strunc('  abc  ', 8).
DEBUG EVALUATE /strunc('  abc  ', 7).
DEBUG EVALUATE /strunc('  abc  ', 6).
DEBUG EVALUATE /strunc('  abc  ', 5).
DEBUG EVALUATE /strunc('  abc  ', 4).
DEBUG EVALUATE /strunc('  abc  ', 3).
DEBUG EVALUATE /strunc('  abc  ', 2).
DEBUG EVALUATE /strunc('  abc  ', 1).

DEBUG EVALUATE /strunc('  abc  ', 1.5).
DEBUG EVALUATE /strunc('  abc  ', -1).
DEBUG EVALUATE /strunc('  abc  ', $sysmis).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
strunc('a c   ', 9) => "a c"

strunc('a c   ', 7) => "a c"

strunc('a c   ', 6) => "a c"

strunc('a c   ', 5) => "a c"

strunc('a c   ', 4) => "a c"

strunc('a c   ', 3) => "a c"

strunc('a c   ', 2) => "a"

strunc('a c   ', 1) => "a"

strunc('a c   ', 0) => ""

evaluate.sps:13.34-13.37: error: DEBUG EVALUATE: Treating unexpected non-
integer value 0.75 as missing.
   13 | DEBUG EVALUATE /strunc('a c   ', 0.75).
      |                                  ^~~~

strunc('a c   ', 0.75) => "a c   "

strunc('a c   ', -1) => ""

strunc('a c   ', $sysmis) => "a c   "

strunc('  abc  ', 9) => "  abc"

strunc('  abc  ', 8) => "  abc"

strunc('  abc  ', 7) => "  abc"

strunc('  abc  ', 6) => "  abc"

strunc('  abc  ', 5) => "  abc"

strunc('  abc  ', 4) => "  ab"

strunc('  abc  ', 3) => "  a"

strunc('  abc  ', 2) => ""

strunc('  abc  ', 1) => ""

evaluate.sps:27.35-27.37: error: DEBUG EVALUATE: Treating unexpected non-
integer value 1.5 as missing.
   27 | DEBUG EVALUATE /strunc('  abc  ', 1.5).
      |                                   ^~~

strunc('  abc  ', 1.5) => "  abc  "

strunc('  abc  ', -1) => ""

strunc('  abc  ', $sysmis) => "  abc  "
])
done
AT_CLEANUP

AT_SETUP([expressions - SUBSTR])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /substr('abcdefgh', 1).
DEBUG EVALUATE /substr('abcdefgh', 3).
DEBUG EVALUATE /substr('abcdefgh', 5).
DEBUG EVALUATE /substr('abcdefgh', 6).
DEBUG EVALUATE /substr('abcdefgh', 7).
DEBUG EVALUATE /substr('abcdefgh', 8).
DEBUG EVALUATE /substr('abcdefgh', 9).
DEBUG EVALUATE /substr('abcdefgh', 10).
DEBUG EVALUATE /substr('abcdefgh', 20).
DEBUG EVALUATE /substr('abcdefgh', $sysmis).
DEBUG EVALUATE /substr('abcdefgh', -5).
DEBUG EVALUATE /substr('abcdefgh', 0).
DEBUG EVALUATE /substr(0, 10).
DEBUG EVALUATE /substr('abcd', 'abc').
DEBUG EVALUATE /substr(0, 'abc').

DEBUG EVALUATE /substr('abcdefgh', 0, 0).
DEBUG EVALUATE /substr('abcdefgh', 3, 0).
DEBUG EVALUATE /substr('abcdefgh', 5, 0).
DEBUG EVALUATE /substr('abcdefgh', 9, 0).
DEBUG EVALUATE /substr('abcdefgh', 0, 1).
DEBUG EVALUATE /substr('abcdefgh', 0, 5).
DEBUG EVALUATE /substr('abcdefgh', 1, 8).
DEBUG EVALUATE /substr('abcdefgh', 1, 10).
DEBUG EVALUATE /substr('abcdefgh', 1, 20).
DEBUG EVALUATE /substr('abcdefgh', 3, 4).
DEBUG EVALUATE /substr('abcdefgh', 5, 2).
DEBUG EVALUATE /substr('abcdefgh', 6, 1).
DEBUG EVALUATE /substr('abcdefgh', 7, 10).
DEBUG EVALUATE /substr('abcdefgh', 8, 1).
DEBUG EVALUATE /substr('abcdefgh', 8, 2).
DEBUG EVALUATE /substr('abcdefgh', 9, 11).
DEBUG EVALUATE /substr('abcdefgh', 10, 52).
DEBUG EVALUATE /substr('abcdefgh', 20, 1).
DEBUG EVALUATE /substr('abcdefgh', $sysmis, 2).
DEBUG EVALUATE /substr('abcdefgh', 9, $sysmis).
DEBUG EVALUATE /substr('abcdefgh', $sysmis, $sysmis).
DEBUG EVALUATE /substr('abc', 1, 'x').
DEBUG EVALUATE /substr(0, 10, 1).
DEBUG EVALUATE /substr(0, 10, 'x').
DEBUG EVALUATE /substr('abcd', 'abc', 0).
DEBUG EVALUATE /substr('abcd', 'abc', 'j').
DEBUG EVALUATE /substr(0, 'abc', 4).
DEBUG EVALUATE /substr(0, 'abc', 'k').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
substr('abcdefgh', 1) => "abcdefgh"

substr('abcdefgh', 3) => "cdefgh"

substr('abcdefgh', 5) => "efgh"

substr('abcdefgh', 6) => "fgh"

substr('abcdefgh', 7) => "gh"

substr('abcdefgh', 8) => "h"

substr('abcdefgh', 9) => ""

substr('abcdefgh', 10) => ""

substr('abcdefgh', 20) => ""

substr('abcdefgh', $sysmis) => ""

substr('abcdefgh', -5) => ""

substr('abcdefgh', 0) => ""

evaluate.sps:14.17-14.29: error: DEBUG EVALUATE: Function invocation
substr(number, number) does not match any known function.  Candidates are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   14 | DEBUG EVALUATE /substr(0, 10).
      |                 ^~~~~~~~~~~~~

substr(0, 10) => error

evaluate.sps:15.17-15.37: error: DEBUG EVALUATE: Function invocation
substr(string, string) does not match any known function.  Candidates are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   15 | DEBUG EVALUATE /substr('abcd', 'abc').
      |                 ^~~~~~~~~~~~~~~~~~~~~

substr('abcd', 'abc') => error

evaluate.sps:16.17-16.32: error: DEBUG EVALUATE: Function invocation
substr(number, string) does not match any known function.  Candidates are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   16 | DEBUG EVALUATE /substr(0, 'abc').
      |                 ^~~~~~~~~~~~~~~~

substr(0, 'abc') => error

substr('abcdefgh', 0, 0) => ""

substr('abcdefgh', 3, 0) => ""

substr('abcdefgh', 5, 0) => ""

substr('abcdefgh', 9, 0) => ""

substr('abcdefgh', 0, 1) => ""

substr('abcdefgh', 0, 5) => ""

substr('abcdefgh', 1, 8) => "abcdefgh"

substr('abcdefgh', 1, 10) => "abcdefgh"

substr('abcdefgh', 1, 20) => "abcdefgh"

substr('abcdefgh', 3, 4) => "cdef"

substr('abcdefgh', 5, 2) => "ef"

substr('abcdefgh', 6, 1) => "f"

substr('abcdefgh', 7, 10) => "gh"

substr('abcdefgh', 8, 1) => "h"

substr('abcdefgh', 8, 2) => "h"

substr('abcdefgh', 9, 11) => ""

substr('abcdefgh', 10, 52) => ""

substr('abcdefgh', 20, 1) => ""

substr('abcdefgh', $sysmis, 2) => ""

substr('abcdefgh', 9, $sysmis) => ""

substr('abcdefgh', $sysmis, $sysmis) => ""

evaluate.sps:39.17-39.37: error: DEBUG EVALUATE: Function invocation
substr(string, number, string) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   39 | DEBUG EVALUATE /substr('abc', 1, 'x').
      |                 ^~~~~~~~~~~~~~~~~~~~~

substr('abc', 1, 'x') => error

evaluate.sps:40.17-40.32: error: DEBUG EVALUATE: Function invocation
substr(number, number, number) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   40 | DEBUG EVALUATE /substr(0, 10, 1).
      |                 ^~~~~~~~~~~~~~~~

substr(0, 10, 1) => error

evaluate.sps:41.17-41.34: error: DEBUG EVALUATE: Function invocation
substr(number, number, string) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   41 | DEBUG EVALUATE /substr(0, 10, 'x').
      |                 ^~~~~~~~~~~~~~~~~~

substr(0, 10, 'x') => error

evaluate.sps:42.17-42.40: error: DEBUG EVALUATE: Function invocation
substr(string, string, number) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   42 | DEBUG EVALUATE /substr('abcd', 'abc', 0).
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~

substr('abcd', 'abc', 0) => error

evaluate.sps:43.17-43.42: error: DEBUG EVALUATE: Function invocation
substr(string, string, string) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   43 | DEBUG EVALUATE /substr('abcd', 'abc', 'j').
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~

substr('abcd', 'abc', 'j') => error

evaluate.sps:44.17-44.35: error: DEBUG EVALUATE: Function invocation
substr(number, string, number) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   44 | DEBUG EVALUATE /substr(0, 'abc', 4).
      |                 ^~~~~~~~~~~~~~~~~~~

substr(0, 'abc', 4) => error

evaluate.sps:45.17-45.37: error: DEBUG EVALUATE: Function invocation
substr(number, string, string) does not match any known function.  Candidates
are:
SUBSTR(string, integer)
SUBSTR(string, integer, integer).
   45 | DEBUG EVALUATE /substr(0, 'abc', 'k').
      |                 ^~~~~~~~~~~~~~~~~~~~~

substr(0, 'abc', 'k') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - UPCASE])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /upcase('abcdefghijklmnopqrstuvwxyz!@%&*089').
DEBUG EVALUATE /upcase('').
DEBUG EVALUATE /upcase(1).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
upcase('abcdefghijklmnopqrstuvwxyz!@%&*089') => "ABCDEFGHIJKLMNOPQRSTUVWXYZ!
@%&*089"

upcase('') => ""

evaluate.sps:4.17-4.25: error: DEBUG EVALUATE: Type mismatch invoking
UPCASE(string) as upcase(number).
    4 | DEBUG EVALUATE /upcase(1).
      |                 ^~~~~~~~~

evaluate.sps:4.24: note: DEBUG EVALUATE: This argument has type 'number' but
'string' is required.
    4 | DEBUG EVALUATE /upcase(1).
      |                        ^

upcase(1) => error
])
done
AT_CLEANUP

AT_SETUP([expressions - TIME.DAYS])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /time.days(1).
DEBUG EVALUATE /time.days(-1).
DEBUG EVALUATE /time.days(0.5).
DEBUG EVALUATE /time.days('x').
DEBUG EVALUATE /time.days($sysmis).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
time.days(1) => 86400.00

time.days(-1) => -86400.00

time.days(0.5) => 43200.00

evaluate.sps:6.17-6.30: error: DEBUG EVALUATE: Type mismatch invoking
TIME.DAYS(number) as time.days(string).
    6 | DEBUG EVALUATE /time.days('x').
      |                 ^~~~~~~~~~~~~~

evaluate.sps:6.27-6.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
    6 | DEBUG EVALUATE /time.days('x').
      |                           ^~~

time.days('x') => error

time.days($sysmis) => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - TIME.HMS])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /time.hms(4,50,38).
DEBUG EVALUATE /time.hms(12,31,35).
DEBUG EVALUATE /time.hms(12,47,53).
DEBUG EVALUATE /time.hms(1,26,0).
DEBUG EVALUATE /time.hms(20,58,11).
DEBUG EVALUATE /time.hms(7,36,5).
DEBUG EVALUATE /time.hms(15,43,49).
DEBUG EVALUATE /time.hms(4,25,9).
DEBUG EVALUATE /time.hms(6,49,27).
DEBUG EVALUATE /time.hms(2,57,52).
DEBUG EVALUATE /time.hms(16,45,44).
DEBUG EVALUATE /time.hms(21,30,57).
DEBUG EVALUATE /time.hms(22,30,4).
DEBUG EVALUATE /time.hms(1,56,51).
DEBUG EVALUATE /time.hms(5, 6, 7).
DEBUG EVALUATE /time.hms(5, 6, 0).
DEBUG EVALUATE /time.hms(5, 0, 7).
DEBUG EVALUATE /time.hms(0, 6, 7).
DEBUG EVALUATE /time.hms(-5, 6, -7).
DEBUG EVALUATE /time.hms(-5, 5, -7).
DEBUG EVALUATE /time.hms($sysmis, 6, 7).
DEBUG EVALUATE /time.hms(5, $sysmis, 7).
DEBUG EVALUATE /time.hms(5, $sysmis, 7).
DEBUG EVALUATE /time.hms($sysmis, $sysmis, 7).
DEBUG EVALUATE /time.hms(5, $sysmis, $sysmis).
DEBUG EVALUATE /time.hms($sysmis, $sysmis, 7).
DEBUG EVALUATE /time.hms($sysmis, $sysmis, $sysmis).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
time.hms(4,50,38) => 17438.00

time.hms(12,31,35) => 45095.00

time.hms(12,47,53) => 46073.00

time.hms(1,26,0) => 5160.00

time.hms(20,58,11) => 75491.00

time.hms(7,36,5) => 27365.00

time.hms(15,43,49) => 56629.00

time.hms(4,25,9) => 15909.00

time.hms(6,49,27) => 24567.00

time.hms(2,57,52) => 10672.00

time.hms(16,45,44) => 60344.00

time.hms(21,30,57) => 77457.00

time.hms(22,30,4) => 81004.00

time.hms(1,56,51) => 7011.00

time.hms(5, 6, 7) => 18367.00

time.hms(5, 6, 0) => 18360.00

time.hms(5, 0, 7) => 18007.00

time.hms(0, 6, 7) => 367.00

evaluate.sps:21.17-21.35: warning: DEBUG EVALUATE: TIME.HMS cannot accept a mix
of positive and negative arguments.
   21 | DEBUG EVALUATE /time.hms(-5, 6, -7).
      |                 ^~~~~~~~~~~~~~~~~~~

evaluate.sps:21.26-21.27: note: DEBUG EVALUATE: This argument has negative
value -5.
   21 | DEBUG EVALUATE /time.hms(-5, 6, -7).
      |                          ^~

evaluate.sps:21.30: note: DEBUG EVALUATE: This argument has positive value 6.
   21 | DEBUG EVALUATE /time.hms(-5, 6, -7).
      |                              ^

evaluate.sps:21.33-21.34: note: DEBUG EVALUATE: This argument has negative
value -7.
   21 | DEBUG EVALUATE /time.hms(-5, 6, -7).
      |                                 ^~

time.hms(-5, 6, -7) => sysmis

evaluate.sps:22.17-22.35: warning: DEBUG EVALUATE: TIME.HMS cannot accept a mix
of positive and negative arguments.
   22 | DEBUG EVALUATE /time.hms(-5, 5, -7).
      |                 ^~~~~~~~~~~~~~~~~~~

evaluate.sps:22.26-22.27: note: DEBUG EVALUATE: This argument has negative
value -5.
   22 | DEBUG EVALUATE /time.hms(-5, 5, -7).
      |                          ^~

evaluate.sps:22.30: note: DEBUG EVALUATE: This argument has positive value 5.
   22 | DEBUG EVALUATE /time.hms(-5, 5, -7).
      |                              ^

evaluate.sps:22.33-22.34: note: DEBUG EVALUATE: This argument has negative
value -7.
   22 | DEBUG EVALUATE /time.hms(-5, 5, -7).
      |                                 ^~

time.hms(-5, 5, -7) => sysmis

time.hms($sysmis, 6, 7) => sysmis

time.hms(5, $sysmis, 7) => sysmis

time.hms(5, $sysmis, 7) => sysmis

time.hms($sysmis, $sysmis, 7) => sysmis

time.hms(5, $sysmis, $sysmis) => sysmis

time.hms($sysmis, $sysmis, 7) => sysmis

time.hms($sysmis, $sysmis, $sysmis) => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - CTIME.*])
AT_KEYWORDS([expression expressions evaluate ctime])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(106272).
DEBUG EVALUATE /ctime.hours(106272).
DEBUG EVALUATE /ctime.minutes(106272).
DEBUG EVALUATE /ctime.seconds(106272).
DEBUG EVALUATE /ctime.days(-106272).
DEBUG EVALUATE /ctime.hours(-106272).
DEBUG EVALUATE /ctime.minutes(-106272).
DEBUG EVALUATE /ctime.seconds(-106272).
DEBUG EVALUATE /ctime.days($sysmis).
DEBUG EVALUATE /ctime.hours($sysmis).
DEBUG EVALUATE /ctime.minutes($sysmis).
DEBUG EVALUATE /ctime.seconds($sysmis).
DEBUG EVALUATE /ctime.days('a').
DEBUG EVALUATE /ctime.hours('b').
DEBUG EVALUATE /ctime.minutes('c').
DEBUG EVALUATE /ctime.seconds('d').

DEBUG EVALUATE /ctime.days(date.dmy(15,10,1582)).
DEBUG EVALUATE /ctime.days(date.dmy(6,9,1719)).
DEBUG EVALUATE /ctime.days(date.dmy(24,1,1583)).
DEBUG EVALUATE /ctime.days(date.dmy(14,12,1585)).
DEBUG EVALUATE /ctime.days(date.dmy(26,11,1621)).
DEBUG EVALUATE /ctime.days(date.dmy(25,12,1821)).
DEBUG EVALUATE /ctime.days(date.dmy(3,12,1882)).
DEBUG EVALUATE /ctime.days(date.dmy(6,4,2002)).
DEBUG EVALUATE /ctime.days(date.dmy(19,12,1999)).
DEBUG EVALUATE /ctime.days(date.dmy(1,10,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(0,10,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(32,10,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(31,0,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(31,13,1978)).
DEBUG EVALUATE /ctime.days(date.dmy($sysmis,10,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(31,$sysmis,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(31,10,$sysmis)).
DEBUG EVALUATE /ctime.days(date.dmy($sysmis,$sysmis,1978)).
DEBUG EVALUATE /ctime.days(date.dmy(31,$sysmis,$sysmis)).
DEBUG EVALUATE /ctime.days(date.dmy($sysmis,10,$sysmis)).
DEBUG EVALUATE /ctime.days(date.dmy($sysmis,$sysmis,$sysmis)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ctime.days(106272) => 1.23

ctime.hours(106272) => 29.52

ctime.minutes(106272) => 1771.20

ctime.seconds(106272) => 106272.00

ctime.days(-106272) => -1.23

ctime.hours(-106272) => -29.52

ctime.minutes(-106272) => -1771.20

ctime.seconds(-106272) => -106272.00

ctime.days($sysmis) => sysmis

ctime.hours($sysmis) => sysmis

ctime.minutes($sysmis) => sysmis

ctime.seconds($sysmis) => sysmis

evaluate.sps:15.17-15.31: error: DEBUG EVALUATE: Type mismatch invoking
CTIME.DAYS(number) as ctime.days(string).
   15 | DEBUG EVALUATE /ctime.days('a').
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:15.28-15.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   15 | DEBUG EVALUATE /ctime.days('a').
      |                            ^~~

ctime.days('a') => error

evaluate.sps:16.17-16.32: error: DEBUG EVALUATE: Type mismatch invoking
CTIME.HOURS(number) as ctime.hours(string).
   16 | DEBUG EVALUATE /ctime.hours('b').
      |                 ^~~~~~~~~~~~~~~~

evaluate.sps:16.29-16.31: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   16 | DEBUG EVALUATE /ctime.hours('b').
      |                             ^~~

ctime.hours('b') => error

evaluate.sps:17.17-17.34: error: DEBUG EVALUATE: Type mismatch invoking
CTIME.MINUTES(number) as ctime.minutes(string).
   17 | DEBUG EVALUATE /ctime.minutes('c').
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:17.31-17.33: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   17 | DEBUG EVALUATE /ctime.minutes('c').
      |                               ^~~

ctime.minutes('c') => error

evaluate.sps:18.17-18.34: error: DEBUG EVALUATE: Type mismatch invoking
CTIME.SECONDS(number) as ctime.seconds(string).
   18 | DEBUG EVALUATE /ctime.seconds('d').
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:18.31-18.33: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   18 | DEBUG EVALUATE /ctime.seconds('d').
      |                               ^~~

ctime.seconds('d') => error

ctime.days(date.dmy(15,10,1582)) => 1.00

ctime.days(date.dmy(6,9,1719)) => 50000.00

ctime.days(date.dmy(24,1,1583)) => 102.00

ctime.days(date.dmy(14,12,1585)) => 1157.00

ctime.days(date.dmy(26,11,1621)) => 14288.00

ctime.days(date.dmy(25,12,1821)) => 87365.00

ctime.days(date.dmy(3,12,1882)) => 109623.00

ctime.days(date.dmy(6,4,2002)) => 153211.00

ctime.days(date.dmy(19,12,1999)) => 152372.00

ctime.days(date.dmy(1,10,1978)) => 144623.00

ctime.days(date.dmy(0,10,1978)) => 144622.00

evaluate.sps:31.28-31.47: error: DEBUG EVALUATE: Invalid arguments to DATE.DMY
function.
   31 | DEBUG EVALUATE /ctime.days(date.dmy(32,10,1978)).
      |                            ^~~~~~~~~~~~~~~~~~~~

evaluate.sps:31.37-31.38: note: DEBUG EVALUATE: Day 32 is not in the acceptable
range of 0 to 31.
   31 | DEBUG EVALUATE /ctime.days(date.dmy(32,10,1978)).
      |                                     ^~

ctime.days(date.dmy(32,10,1978)) => sysmis

ctime.days(date.dmy(31,0,1978)) => 144349.00

ctime.days(date.dmy(31,13,1978)) => 144745.00

ctime.days(date.dmy($sysmis,10,1978)) => sysmis

ctime.days(date.dmy(31,$sysmis,1978)) => sysmis

ctime.days(date.dmy(31,10,$sysmis)) => sysmis

ctime.days(date.dmy($sysmis,$sysmis,1978)) => sysmis

ctime.days(date.dmy(31,$sysmis,$sysmis)) => sysmis

ctime.days(date.dmy($sysmis,10,$sysmis)) => sysmis

ctime.days(date.dmy($sysmis,$sysmis,$sysmis)) => sysmis
])
done
AT_CLEANUP

AT_SETUP([expressions - DATE.DMY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /date.dmy('a',1,2).
DEBUG EVALUATE /date.dmy(1,'a',2).
DEBUG EVALUATE /date.dmy(1,2,'a').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
evaluate.sps:3.17-3.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.DMY(integer, integer, integer) as date.dmy(string, number, number).
    3 | DEBUG EVALUATE /date.dmy('a',1,2).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:3.26-3.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
    3 | DEBUG EVALUATE /date.dmy('a',1,2).
      |                          ^~~

date.dmy('a',1,2) => error

evaluate.sps:4.17-4.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.DMY(integer, integer, integer) as date.dmy(number, string, number).
    4 | DEBUG EVALUATE /date.dmy(1,'a',2).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:4.28-4.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
    4 | DEBUG EVALUATE /date.dmy(1,'a',2).
      |                            ^~~

date.dmy(1,'a',2) => error

evaluate.sps:5.17-5.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.DMY(integer, integer, integer) as date.dmy(number, number, string).
    5 | DEBUG EVALUATE /date.dmy(1,2,'a').
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:5.30-5.32: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
    5 | DEBUG EVALUATE /date.dmy(1,2,'a').
      |                              ^~~

date.dmy(1,2,'a') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - YRMODA])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
dnl FIXME: check out-of-range and nearly out-of-range values
DEBUG EVALUATE /yrmoda(1582,10,15).
DEBUG EVALUATE /yrmoda(1719,9,6).
DEBUG EVALUATE /yrmoda(1583,1,24).
DEBUG EVALUATE /yrmoda(1585,12,14).
DEBUG EVALUATE /yrmoda(1621,11,26).
DEBUG EVALUATE /yrmoda(1821,12,25).
DEBUG EVALUATE /yrmoda(1882,12,3).
DEBUG EVALUATE /yrmoda(2002,4,6).
DEBUG EVALUATE /yrmoda(1999,12,19).
DEBUG EVALUATE /yrmoda(1978,10,1).
DEBUG EVALUATE /yrmoda(1978,10,0).
DEBUG EVALUATE /yrmoda(1978,10,32).
DEBUG EVALUATE /yrmoda(1978,0,31).
DEBUG EVALUATE /yrmoda(1978,13,31).
DEBUG EVALUATE /yrmoda(1978,10,$sysmis).
DEBUG EVALUATE /yrmoda(1978,$sysmis,31).
DEBUG EVALUATE /yrmoda($sysmis,10,31).
DEBUG EVALUATE /yrmoda(1978,$sysmis,$sysmis).
DEBUG EVALUATE /yrmoda($sysmis,$sysmis,31).
DEBUG EVALUATE /yrmoda($sysmis,10,$sysmis).
DEBUG EVALUATE /yrmoda($sysmis,$sysmis,$sysmis).
DEBUG EVALUATE /yrmoda('a',1,2).
DEBUG EVALUATE /yrmoda(1,'a',2).
DEBUG EVALUATE /yrmoda(1,2,'a').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
yrmoda(1582,10,15) => 1.00

yrmoda(1719,9,6) => 50000.00

yrmoda(1583,1,24) => 102.00

yrmoda(1585,12,14) => 1157.00

yrmoda(1621,11,26) => 14288.00

yrmoda(1821,12,25) => 87365.00

yrmoda(1882,12,3) => 109623.00

yrmoda(2002,4,6) => 153211.00

yrmoda(1999,12,19) => 152372.00

yrmoda(1978,10,1) => 144623.00

yrmoda(1978,10,0) => 144622.00

evaluate.sps:14.17-14.34: error: DEBUG EVALUATE: Invalid arguments to YRMODA
function.
   14 | DEBUG EVALUATE /yrmoda(1978,10,32).
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:14.32-14.33: note: DEBUG EVALUATE: Day 32 is not in the acceptable
range of 0 to 31.
   14 | DEBUG EVALUATE /yrmoda(1978,10,32).
      |                                ^~

yrmoda(1978,10,32) => sysmis

yrmoda(1978,0,31) => 144349.00

yrmoda(1978,13,31) => 144745.00

yrmoda(1978,10,$sysmis) => sysmis

yrmoda(1978,$sysmis,31) => sysmis

yrmoda($sysmis,10,31) => sysmis

yrmoda(1978,$sysmis,$sysmis) => sysmis

yrmoda($sysmis,$sysmis,31) => sysmis

yrmoda($sysmis,10,$sysmis) => sysmis

yrmoda($sysmis,$sysmis,$sysmis) => sysmis

evaluate.sps:24.17-24.31: error: DEBUG EVALUATE: Type mismatch invoking
YRMODA(integer, integer, integer) as yrmoda(string, number, number).
   24 | DEBUG EVALUATE /yrmoda('a',1,2).
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:24.24-24.26: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   24 | DEBUG EVALUATE /yrmoda('a',1,2).
      |                        ^~~

yrmoda('a',1,2) => error

evaluate.sps:25.17-25.31: error: DEBUG EVALUATE: Type mismatch invoking
YRMODA(integer, integer, integer) as yrmoda(number, string, number).
   25 | DEBUG EVALUATE /yrmoda(1,'a',2).
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:25.26-25.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   25 | DEBUG EVALUATE /yrmoda(1,'a',2).
      |                          ^~~

yrmoda(1,'a',2) => error

evaluate.sps:26.17-26.31: error: DEBUG EVALUATE: Type mismatch invoking
YRMODA(integer, integer, integer) as yrmoda(number, number, string).
   26 | DEBUG EVALUATE /yrmoda(1,2,'a').
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:26.28-26.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   26 | DEBUG EVALUATE /yrmoda(1,2,'a').
      |                            ^~~

yrmoda(1,2,'a') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - DATE.MDY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

dnl FIXME: check out-of-range and nearly out-of-range values
DEBUG EVALUATE /ctime.days(date.mdy(6,10,1648)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(6,30,1680)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(7,24,1716)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(6,19,1768)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(8,2,1819)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(3,27,1839)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(4,19,1903)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(8,25,1929)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(9,29,1941)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(4,19,1943)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(10,7,1943)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(3,17,1992)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(2,25,1996)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(11,10,2038)) + 577735.
DEBUG EVALUATE /ctime.days(date.mdy(7,18,2094)) + 577735.

dnl FIXME: check out-of-range and nearly out-of-range values
DEBUG EVALUATE /ctime.days(date.mdy(10,15,1582)).
DEBUG EVALUATE /ctime.days(date.mdy(9,6,1719)).
DEBUG EVALUATE /ctime.days(date.mdy(1,24,1583)).
DEBUG EVALUATE /ctime.days(date.mdy(12,14,1585)).
DEBUG EVALUATE /ctime.days(date.mdy(11,26,1621)).
DEBUG EVALUATE /ctime.days(date.mdy(12,25,1821)).
DEBUG EVALUATE /ctime.days(date.mdy(12,3,1882)).
DEBUG EVALUATE /ctime.days(date.mdy(4,6,2002)).
DEBUG EVALUATE /ctime.days(date.mdy(12,19,1999)).
DEBUG EVALUATE /ctime.days(date.mdy(10,1,1978)).
DEBUG EVALUATE /ctime.days(date.mdy(10,0,1978)).
DEBUG EVALUATE /ctime.days(date.mdy(10,32,1978)).
DEBUG EVALUATE /ctime.days(date.mdy(0,31,1978)).
DEBUG EVALUATE /ctime.days(date.mdy(13,31,1978)).
DEBUG EVALUATE /ctime.days(date.mdy(10,$sysmis,1978)).
DEBUG EVALUATE /ctime.days(date.mdy($sysmis,31,1978)).
DEBUG EVALUATE /ctime.days(date.mdy(10,31,$sysmis)).
DEBUG EVALUATE /ctime.days(date.mdy($sysmis,$sysmis,1978)).
DEBUG EVALUATE /ctime.days(date.mdy($sysmis,31,$sysmis)).
DEBUG EVALUATE /ctime.days(date.mdy(10,$sysmis,$sysmis)).
DEBUG EVALUATE /ctime.days(date.mdy($sysmis,$sysmis,$sysmis)).
DEBUG EVALUATE /date.mdy('a',1,2).
DEBUG EVALUATE /date.mdy(1,'a',2).
DEBUG EVALUATE /date.mdy(1,2,'a').
DEBUG EVALUATE /ctime.days(date.mdy(0,0,0)).
DEBUG EVALUATE /ctime.days(date.mdy(0,0,999)).
DEBUG EVALUATE /date.mdy(1,1,1582).
DEBUG EVALUATE /date.mdy(10,14,1582).
DEBUG EVALUATE /date.mdy(10,15,1582).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ctime.days(date.mdy(6,10,1648)) + 577735 => 601716.00

ctime.days(date.mdy(6,30,1680)) + 577735 => 613424.00

ctime.days(date.mdy(7,24,1716)) + 577735 => 626596.00

ctime.days(date.mdy(6,19,1768)) + 577735 => 645554.00

ctime.days(date.mdy(8,2,1819)) + 577735 => 664224.00

ctime.days(date.mdy(3,27,1839)) + 577735 => 671401.00

ctime.days(date.mdy(4,19,1903)) + 577735 => 694799.00

ctime.days(date.mdy(8,25,1929)) + 577735 => 704424.00

ctime.days(date.mdy(9,29,1941)) + 577735 => 708842.00

ctime.days(date.mdy(4,19,1943)) + 577735 => 709409.00

ctime.days(date.mdy(10,7,1943)) + 577735 => 709580.00

ctime.days(date.mdy(3,17,1992)) + 577735 => 727274.00

ctime.days(date.mdy(2,25,1996)) + 577735 => 728714.00

ctime.days(date.mdy(11,10,2038)) + 577735 => 744313.00

ctime.days(date.mdy(7,18,2094)) + 577735 => 764652.00

ctime.days(date.mdy(10,15,1582)) => 1.00

ctime.days(date.mdy(9,6,1719)) => 50000.00

ctime.days(date.mdy(1,24,1583)) => 102.00

ctime.days(date.mdy(12,14,1585)) => 1157.00

ctime.days(date.mdy(11,26,1621)) => 14288.00

ctime.days(date.mdy(12,25,1821)) => 87365.00

ctime.days(date.mdy(12,3,1882)) => 109623.00

ctime.days(date.mdy(4,6,2002)) => 153211.00

ctime.days(date.mdy(12,19,1999)) => 152372.00

ctime.days(date.mdy(10,1,1978)) => 144623.00

ctime.days(date.mdy(10,0,1978)) => 144622.00

evaluate.sps:31.28-31.47: error: DEBUG EVALUATE: Invalid arguments to DATE.MDY
function.
   31 | DEBUG EVALUATE /ctime.days(date.mdy(10,32,1978)).
      |                            ^~~~~~~~~~~~~~~~~~~~

evaluate.sps:31.40-31.41: note: DEBUG EVALUATE: Day 32 is not in the acceptable
range of 0 to 31.
   31 | DEBUG EVALUATE /ctime.days(date.mdy(10,32,1978)).
      |                                        ^~

ctime.days(date.mdy(10,32,1978)) => sysmis

ctime.days(date.mdy(0,31,1978)) => 144349.00

ctime.days(date.mdy(13,31,1978)) => 144745.00

ctime.days(date.mdy(10,$sysmis,1978)) => sysmis

ctime.days(date.mdy($sysmis,31,1978)) => sysmis

ctime.days(date.mdy(10,31,$sysmis)) => sysmis

ctime.days(date.mdy($sysmis,$sysmis,1978)) => sysmis

ctime.days(date.mdy($sysmis,31,$sysmis)) => sysmis

ctime.days(date.mdy(10,$sysmis,$sysmis)) => sysmis

ctime.days(date.mdy($sysmis,$sysmis,$sysmis)) => sysmis

evaluate.sps:41.17-41.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.MDY(integer, integer, integer) as date.mdy(string, number, number).
   41 | DEBUG EVALUATE /date.mdy('a',1,2).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:41.26-41.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   41 | DEBUG EVALUATE /date.mdy('a',1,2).
      |                          ^~~

date.mdy('a',1,2) => error

evaluate.sps:42.17-42.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.MDY(integer, integer, integer) as date.mdy(number, string, number).
   42 | DEBUG EVALUATE /date.mdy(1,'a',2).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:42.28-42.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   42 | DEBUG EVALUATE /date.mdy(1,'a',2).
      |                            ^~~

date.mdy(1,'a',2) => error

evaluate.sps:43.17-43.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.MDY(integer, integer, integer) as date.mdy(number, number, string).
   43 | DEBUG EVALUATE /date.mdy(1,2,'a').
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:43.30-43.32: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   43 | DEBUG EVALUATE /date.mdy(1,2,'a').
      |                              ^~~

date.mdy(1,2,'a') => error

ctime.days(date.mdy(0,0,0)) => 152353.00

evaluate.sps:45.28-45.44: error: DEBUG EVALUATE: Invalid arguments to DATE.MDY
function.
   45 | DEBUG EVALUATE /ctime.days(date.mdy(0,0,999)).
      |                            ^~~~~~~~~~~~~~~~~

evaluate.sps:45.41-45.43: note: DEBUG EVALUATE: Date 0998-12-0 is before the
earliest supported date 1582-10-15.
   45 | DEBUG EVALUATE /ctime.days(date.mdy(0,0,999)).
      |                                         ^~~

ctime.days(date.mdy(0,0,999)) => sysmis

evaluate.sps:46.17-46.34: error: DEBUG EVALUATE: Invalid arguments to DATE.MDY
function.
   46 | DEBUG EVALUATE /date.mdy(1,1,1582).
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:46.17-46.34: note: DEBUG EVALUATE: Date 1582-1-1 is before the
earliest supported date 1582-10-15.
   46 | DEBUG EVALUATE /date.mdy(1,1,1582).
      |                 ^~~~~~~~~~~~~~~~~~

date.mdy(1,1,1582) => sysmis

evaluate.sps:47.17-47.36: error: DEBUG EVALUATE: Invalid arguments to DATE.MDY
function.
   47 | DEBUG EVALUATE /date.mdy(10,14,1582).
      |                 ^~~~~~~~~~~~~~~~~~~~

evaluate.sps:47.17-47.36: note: DEBUG EVALUATE: Date 1582-10-14 is before the
earliest supported date 1582-10-15.
   47 | DEBUG EVALUATE /date.mdy(10,14,1582).
      |                 ^~~~~~~~~~~~~~~~~~~~

date.mdy(10,14,1582) => sysmis

date.mdy(10,15,1582) => 86400.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATE.MOYR])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(date.moyr(1,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(2,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(3,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(4,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(5,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(13,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(14,2000)).
DEBUG EVALUATE /ctime.days(date.moyr($sysmis,2000)).
DEBUG EVALUATE /ctime.days(date.moyr(1,$sysmis)).
DEBUG EVALUATE /ctime.days(date.moyr($sysmis,$sysmis)).
DEBUG EVALUATE /date.moyr('a',2000).
DEBUG EVALUATE /date.moyr(5,'a').
DEBUG EVALUATE /date.moyr('a','b').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ctime.days(date.moyr(1,2000)) => 152385.00

ctime.days(date.moyr(2,2000)) => 152416.00

ctime.days(date.moyr(3,2000)) => 152445.00

ctime.days(date.moyr(4,2000)) => 152476.00

ctime.days(date.moyr(5,2000)) => 152506.00

ctime.days(date.moyr(13,2000)) => 152751.00

evaluate.sps:9.28-9.45: error: DEBUG EVALUATE: Invalid arguments to DATE.MOYR
function.
    9 | DEBUG EVALUATE /ctime.days(date.moyr(14,2000)).
      |                            ^~~~~~~~~~~~~~~~~~

evaluate.sps:9.38-9.39: note: DEBUG EVALUATE: Month 14 is not in the acceptable
range of 0 to 13.
    9 | DEBUG EVALUATE /ctime.days(date.moyr(14,2000)).
      |                                      ^~

ctime.days(date.moyr(14,2000)) => sysmis

ctime.days(date.moyr($sysmis,2000)) => sysmis

ctime.days(date.moyr(1,$sysmis)) => sysmis

ctime.days(date.moyr($sysmis,$sysmis)) => sysmis

evaluate.sps:13.17-13.35: error: DEBUG EVALUATE: Type mismatch invoking
DATE.MOYR(integer, integer) as date.moyr(string, number).
   13 | DEBUG EVALUATE /date.moyr('a',2000).
      |                 ^~~~~~~~~~~~~~~~~~~

evaluate.sps:13.27-13.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   13 | DEBUG EVALUATE /date.moyr('a',2000).
      |                           ^~~

date.moyr('a',2000) => error

evaluate.sps:14.17-14.32: error: DEBUG EVALUATE: Type mismatch invoking
DATE.MOYR(integer, integer) as date.moyr(number, string).
   14 | DEBUG EVALUATE /date.moyr(5,'a').
      |                 ^~~~~~~~~~~~~~~~

evaluate.sps:14.29-14.31: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   14 | DEBUG EVALUATE /date.moyr(5,'a').
      |                             ^~~

date.moyr(5,'a') => error

evaluate.sps:15.17-15.34: error: DEBUG EVALUATE: Type mismatch invoking
DATE.MOYR(integer, integer) as date.moyr(string, string).
   15 | DEBUG EVALUATE /date.moyr('a','b').
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:15.27-15.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   15 | DEBUG EVALUATE /date.moyr('a','b').
      |                           ^~~

evaluate.sps:15.31-15.33: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   15 | DEBUG EVALUATE /date.moyr('a','b').
      |                               ^~~

date.moyr('a','b') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - DATE.QYR])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(date.qyr(1,2000)).
DEBUG EVALUATE /ctime.days(date.qyr(2,2000)).
DEBUG EVALUATE /ctime.days(date.qyr(5,2000)).
DEBUG EVALUATE /ctime.days(date.qyr(6,2000)).
DEBUG EVALUATE /ctime.days(date.qyr($sysmis,2000)).
DEBUG EVALUATE /ctime.days(date.qyr(1,$sysmis)).
DEBUG EVALUATE /ctime.days(date.qyr($sysmis,$sysmis)).
DEBUG EVALUATE /date.qyr('a',2000).
DEBUG EVALUATE /date.qyr(5,'a').
DEBUG EVALUATE /date.qyr('a','b').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ctime.days(date.qyr(1,2000)) => 152385.00

ctime.days(date.qyr(2,2000)) => 152476.00

evaluate.sps:5.37: warning: DEBUG EVALUATE: Argument 1 to DATE.QYR must be 1,
2, 3, or 4 (not 5).
    5 | DEBUG EVALUATE /ctime.days(date.qyr(5,2000)).
      |                                     ^

ctime.days(date.qyr(5,2000)) => sysmis

evaluate.sps:6.37: warning: DEBUG EVALUATE: Argument 1 to DATE.QYR must be 1,
2, 3, or 4 (not 6).
    6 | DEBUG EVALUATE /ctime.days(date.qyr(6,2000)).
      |                                     ^

ctime.days(date.qyr(6,2000)) => sysmis

ctime.days(date.qyr($sysmis,2000)) => sysmis

ctime.days(date.qyr(1,$sysmis)) => sysmis

ctime.days(date.qyr($sysmis,$sysmis)) => sysmis

evaluate.sps:10.17-10.34: error: DEBUG EVALUATE: Type mismatch invoking
DATE.QYR(integer, integer) as date.qyr(string, number).
   10 | DEBUG EVALUATE /date.qyr('a',2000).
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:10.26-10.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   10 | DEBUG EVALUATE /date.qyr('a',2000).
      |                          ^~~

date.qyr('a',2000) => error

evaluate.sps:11.17-11.31: error: DEBUG EVALUATE: Type mismatch invoking
DATE.QYR(integer, integer) as date.qyr(number, string).
   11 | DEBUG EVALUATE /date.qyr(5,'a').
      |                 ^~~~~~~~~~~~~~~

evaluate.sps:11.28-11.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   11 | DEBUG EVALUATE /date.qyr(5,'a').
      |                            ^~~

date.qyr(5,'a') => error

evaluate.sps:12.17-12.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.QYR(integer, integer) as date.qyr(string, string).
   12 | DEBUG EVALUATE /date.qyr('a','b').
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:12.26-12.28: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   12 | DEBUG EVALUATE /date.qyr('a','b').
      |                          ^~~

evaluate.sps:12.30-12.32: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   12 | DEBUG EVALUATE /date.qyr('a','b').
      |                              ^~~

date.qyr('a','b') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - DATE.WKYR])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(date.wkyr(1,2000)).
DEBUG EVALUATE /ctime.days(date.wkyr(15,1999)).
DEBUG EVALUATE /ctime.days(date.wkyr(36,1999)).
DEBUG EVALUATE /ctime.days(date.wkyr(54,1999)).
DEBUG EVALUATE /ctime.days(date.wkyr($sysmis,1999)).
DEBUG EVALUATE /ctime.days(date.wkyr(1,$sysmis)).
DEBUG EVALUATE /ctime.days(date.wkyr($sysmis,$sysmis)).
DEBUG EVALUATE /date.wkyr('a',1999).
DEBUG EVALUATE /date.wkyr(5,'a').
DEBUG EVALUATE /date.wkyr('a','b').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ctime.days(date.wkyr(1,2000)) => 152385.00

ctime.days(date.wkyr(15,1999)) => 152118.00

ctime.days(date.wkyr(36,1999)) => 152265.00

evaluate.sps:6.38-6.39: error: DEBUG EVALUATE: The week argument to DATE.WKYR
is outside the acceptable range of 1 to 53.  The result will be system-missing.
    6 | DEBUG EVALUATE /ctime.days(date.wkyr(54,1999)).
      |                                      ^~

ctime.days(date.wkyr(54,1999)) => sysmis

ctime.days(date.wkyr($sysmis,1999)) => sysmis

ctime.days(date.wkyr(1,$sysmis)) => sysmis

ctime.days(date.wkyr($sysmis,$sysmis)) => sysmis

evaluate.sps:10.17-10.35: error: DEBUG EVALUATE: Type mismatch invoking
DATE.WKYR(integer, integer) as date.wkyr(string, number).
   10 | DEBUG EVALUATE /date.wkyr('a',1999).
      |                 ^~~~~~~~~~~~~~~~~~~

evaluate.sps:10.27-10.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   10 | DEBUG EVALUATE /date.wkyr('a',1999).
      |                           ^~~

date.wkyr('a',1999) => error

evaluate.sps:11.17-11.32: error: DEBUG EVALUATE: Type mismatch invoking
DATE.WKYR(integer, integer) as date.wkyr(number, string).
   11 | DEBUG EVALUATE /date.wkyr(5,'a').
      |                 ^~~~~~~~~~~~~~~~

evaluate.sps:11.29-11.31: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   11 | DEBUG EVALUATE /date.wkyr(5,'a').
      |                             ^~~

date.wkyr(5,'a') => error

evaluate.sps:12.17-12.34: error: DEBUG EVALUATE: Type mismatch invoking
DATE.WKYR(integer, integer) as date.wkyr(string, string).
   12 | DEBUG EVALUATE /date.wkyr('a','b').
      |                 ^~~~~~~~~~~~~~~~~~

evaluate.sps:12.27-12.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   12 | DEBUG EVALUATE /date.wkyr('a','b').
      |                           ^~~

evaluate.sps:12.31-12.33: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   12 | DEBUG EVALUATE /date.wkyr('a','b').
      |                               ^~~

date.wkyr('a','b') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - DATE.YRDAY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(date.yrday(2000,1)).
DEBUG EVALUATE /ctime.days(date.yrday(2000,100)).
DEBUG EVALUATE /ctime.days(date.yrday(2000,253)).
DEBUG EVALUATE /ctime.days(date.yrday(2000,500)).
DEBUG EVALUATE /ctime.days(date.yrday(2000,-100)).
DEBUG EVALUATE /ctime.days(date.yrday(1999,$sysmis)).
DEBUG EVALUATE /ctime.days(date.yrday($sysmis,1)).
DEBUG EVALUATE /ctime.days(date.yrday($sysmis,$sysmis)).
DEBUG EVALUATE /date.yrday(1999,'a').
DEBUG EVALUATE /date.yrday('a',5).
DEBUG EVALUATE /date.yrday('a','b').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
ctime.days(date.yrday(2000,1)) => 152385.00

ctime.days(date.yrday(2000,100)) => 152484.00

ctime.days(date.yrday(2000,253)) => 152637.00

evaluate.sps:6.44-6.46: error: DEBUG EVALUATE: The value 500 as day argument to
DATE.YRDAY is outside the acceptable range of 1 to 366.  The result will be
system-missing.
    6 | DEBUG EVALUATE /ctime.days(date.yrday(2000,500)).
      |                                            ^~~

ctime.days(date.yrday(2000,500)) => sysmis

evaluate.sps:7.44-7.47: error: DEBUG EVALUATE: The value -100 as day argument
to DATE.YRDAY is outside the acceptable range of 1 to 366.  The result will be
system-missing.
    7 | DEBUG EVALUATE /ctime.days(date.yrday(2000,-100)).
      |                                            ^~~~

ctime.days(date.yrday(2000,-100)) => sysmis

ctime.days(date.yrday(1999,$sysmis)) => sysmis

ctime.days(date.yrday($sysmis,1)) => sysmis

ctime.days(date.yrday($sysmis,$sysmis)) => sysmis

evaluate.sps:11.17-11.36: error: DEBUG EVALUATE: Type mismatch invoking
DATE.YRDAY(integer, integer) as date.yrday(number, string).
   11 | DEBUG EVALUATE /date.yrday(1999,'a').
      |                 ^~~~~~~~~~~~~~~~~~~~

evaluate.sps:11.33-11.35: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   11 | DEBUG EVALUATE /date.yrday(1999,'a').
      |                                 ^~~

date.yrday(1999,'a') => error

evaluate.sps:12.17-12.33: error: DEBUG EVALUATE: Type mismatch invoking
DATE.YRDAY(integer, integer) as date.yrday(string, number).
   12 | DEBUG EVALUATE /date.yrday('a',5).
      |                 ^~~~~~~~~~~~~~~~~

evaluate.sps:12.28-12.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   12 | DEBUG EVALUATE /date.yrday('a',5).
      |                            ^~~

date.yrday('a',5) => error

evaluate.sps:13.17-13.35: error: DEBUG EVALUATE: Type mismatch invoking
DATE.YRDAY(integer, integer) as date.yrday(string, string).
   13 | DEBUG EVALUATE /date.yrday('a','b').
      |                 ^~~~~~~~~~~~~~~~~~~

evaluate.sps:13.28-13.30: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   13 | DEBUG EVALUATE /date.yrday('a','b').
      |                            ^~~

evaluate.sps:13.32-13.34: note: DEBUG EVALUATE: This argument has type 'string'
but 'integer' is required.
   13 | DEBUG EVALUATE /date.yrday('a','b').
      |                                ^~~

date.yrday('a','b') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.DATE])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.date(date.mdy(6,10,1648) + time.hms(0,0,0)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(6,30,1680) + time.hms(4,50,38)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(7,24,1716) + time.hms(12,31,35)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(6,19,1768) + time.hms(12,47,53)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(8,2,1819) + time.hms(1,26,0)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(3,27,1839) + time.hms(20,58,11)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(4,19,1903) + time.hms(7,36,5)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(8,25,1929) + time.hms(15,43,49)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(9,29,1941) + time.hms(4,25,9)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(4,19,1943) + time.hms(6,49,27)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(10,7,1943) + time.hms(2,57,52)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(3,17,1992) + time.hms(16,45,44)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(2,25,1996) + time.hms(21,30,57)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(9,29,1941) + time.hms(4,25,9)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(4,19,43) + time.hms(6,49,27)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(10,7,43) + time.hms(2,57,52)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(3,17,92) + time.hms(16,45,44)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(2,25,96) + time.hms(21,30,57)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(11,10,2038) + time.hms(22,30,4)) / 86400.
DEBUG EVALUATE /xdate.date(date.mdy(7,18,2094) + time.hms(1,56,51)) / 86400.
DEBUG EVALUATE /xdate.date(123.4).
DEBUG EVALUATE /xdate.date('').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
xdate.date(date.mdy(6,10,1648) + time.hms(0,0,0)) / 86400 => 23981.00

xdate.date(date.mdy(6,30,1680) + time.hms(4,50,38)) / 86400 => 35689.00

xdate.date(date.mdy(7,24,1716) + time.hms(12,31,35)) / 86400 => 48861.00

xdate.date(date.mdy(6,19,1768) + time.hms(12,47,53)) / 86400 => 67819.00

xdate.date(date.mdy(8,2,1819) + time.hms(1,26,0)) / 86400 => 86489.00

xdate.date(date.mdy(3,27,1839) + time.hms(20,58,11)) / 86400 => 93666.00

xdate.date(date.mdy(4,19,1903) + time.hms(7,36,5)) / 86400 => 117064.00

xdate.date(date.mdy(8,25,1929) + time.hms(15,43,49)) / 86400 => 126689.00

xdate.date(date.mdy(9,29,1941) + time.hms(4,25,9)) / 86400 => 131107.00

xdate.date(date.mdy(4,19,1943) + time.hms(6,49,27)) / 86400 => 131674.00

xdate.date(date.mdy(10,7,1943) + time.hms(2,57,52)) / 86400 => 131845.00

xdate.date(date.mdy(3,17,1992) + time.hms(16,45,44)) / 86400 => 149539.00

xdate.date(date.mdy(2,25,1996) + time.hms(21,30,57)) / 86400 => 150979.00

xdate.date(date.mdy(9,29,1941) + time.hms(4,25,9)) / 86400 => 131107.00

xdate.date(date.mdy(4,19,43) + time.hms(6,49,27)) / 86400 => 131674.00

xdate.date(date.mdy(10,7,43) + time.hms(2,57,52)) / 86400 => 131845.00

xdate.date(date.mdy(3,17,92) + time.hms(16,45,44)) / 86400 => 149539.00

xdate.date(date.mdy(2,25,96) + time.hms(21,30,57)) / 86400 => 150979.00

xdate.date(date.mdy(11,10,2038) + time.hms(22,30,4)) / 86400 => 166578.00

xdate.date(date.mdy(7,18,2094) + time.hms(1,56,51)) / 86400 => 186917.00

xdate.date(123.4) => 0.00

evaluate.sps:24.17-24.30: error: DEBUG EVALUATE: Type mismatch invoking
XDATE.DATE(number) as xdate.date(string).
   24 | DEBUG EVALUATE /xdate.date('').
      |                 ^~~~~~~~~~~~~~

evaluate.sps:24.28-24.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   24 | DEBUG EVALUATE /xdate.date('').
      |                            ^~

xdate.date('') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.HOUR])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.hour(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.hour(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.hour(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.hour(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.hour(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.hour(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.hour(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.hour(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.hour(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.hour(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.hour(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.hour(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.hour(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.hour(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.hour(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.hour(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.hour(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.hour(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.hour(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.hour(date.mdy(7,18,2094) + time.hms(1,56,51)).
DEBUG EVALUATE /xdate.hour(-1).
DEBUG EVALUATE /xdate.hour(1).
DEBUG EVALUATE /xdate.hour($sysmis).
DEBUG EVALUATE /xdate.hour('').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
xdate.hour(date.mdy(6,10,1648) + time.hms(0,0,0)) => 0.00

xdate.hour(date.mdy(6,30,1680) + time.hms(4,50,38)) => 4.00

xdate.hour(date.mdy(7,24,1716) + time.hms(12,31,35)) => 12.00

xdate.hour(date.mdy(6,19,1768) + time.hms(12,47,53)) => 12.00

xdate.hour(date.mdy(8,2,1819) + time.hms(1,26,0)) => 1.00

xdate.hour(date.mdy(3,27,1839) + time.hms(20,58,11)) => 20.00

xdate.hour(date.mdy(4,19,1903) + time.hms(7,36,5)) => 7.00

xdate.hour(date.mdy(8,25,1929) + time.hms(15,43,49)) => 15.00

xdate.hour(date.mdy(9,29,1941) + time.hms(4,25,9)) => 4.00

xdate.hour(date.mdy(4,19,1943) + time.hms(6,49,27)) => 6.00

xdate.hour(date.mdy(10,7,1943) + time.hms(2,57,52)) => 2.00

xdate.hour(date.mdy(3,17,1992) + time.hms(16,45,44)) => 16.00

xdate.hour(date.mdy(2,25,1996) + time.hms(21,30,57)) => 21.00

xdate.hour(date.mdy(9,29,1941) + time.hms(4,25,9)) => 4.00

xdate.hour(date.mdy(4,19,43) + time.hms(6,49,27)) => 6.00

xdate.hour(date.mdy(10,7,43) + time.hms(2,57,52)) => 2.00

xdate.hour(date.mdy(3,17,92) + time.hms(16,45,44)) => 16.00

xdate.hour(date.mdy(2,25,96) + time.hms(21,30,57)) => 21.00

xdate.hour(date.mdy(11,10,2038) + time.hms(22,30,4)) => 22.00

xdate.hour(date.mdy(7,18,2094) + time.hms(1,56,51)) => 1.00

xdate.hour(-1) => -1.00

xdate.hour(1) => 0.00

xdate.hour($sysmis) => sysmis

evaluate.sps:26.17-26.30: error: DEBUG EVALUATE: Type mismatch invoking
XDATE.HOUR(number) as xdate.hour(string).
   26 | DEBUG EVALUATE /xdate.hour('').
      |                 ^~~~~~~~~~~~~~

evaluate.sps:26.28-26.29: note: DEBUG EVALUATE: This argument has type 'string'
but 'number' is required.
   26 | DEBUG EVALUATE /xdate.hour('').
      |                            ^~

xdate.hour('') => error
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.JDAY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.jday(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.jday(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.jday(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.jday(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.jday(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.jday(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.jday(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.jday(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.jday(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.jday(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.jday(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.jday(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.jday(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.jday(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.jday(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.jday(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.jday(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.jday(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.jday(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.jday(date.mdy(7,18,2094) + time.hms(1,56,51)).
DEBUG EVALUATE /xdate.jday(0).
DEBUG EVALUATE /xdate.jday(1).
DEBUG EVALUATE /xdate.jday(86400).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.jday(date.mdy(6,10,1648) + time.hms(0,0,0)) => 162.00

xdate.jday(date.mdy(6,30,1680) + time.hms(4,50,38)) => 182.00

xdate.jday(date.mdy(7,24,1716) + time.hms(12,31,35)) => 206.00

xdate.jday(date.mdy(6,19,1768) + time.hms(12,47,53)) => 171.00

xdate.jday(date.mdy(8,2,1819) + time.hms(1,26,0)) => 214.00

xdate.jday(date.mdy(3,27,1839) + time.hms(20,58,11)) => 86.00

xdate.jday(date.mdy(4,19,1903) + time.hms(7,36,5)) => 109.00

xdate.jday(date.mdy(8,25,1929) + time.hms(15,43,49)) => 237.00

xdate.jday(date.mdy(9,29,1941) + time.hms(4,25,9)) => 272.00

xdate.jday(date.mdy(4,19,1943) + time.hms(6,49,27)) => 109.00

xdate.jday(date.mdy(10,7,1943) + time.hms(2,57,52)) => 280.00

xdate.jday(date.mdy(3,17,1992) + time.hms(16,45,44)) => 77.00

xdate.jday(date.mdy(2,25,1996) + time.hms(21,30,57)) => 56.00

xdate.jday(date.mdy(9,29,1941) + time.hms(4,25,9)) => 272.00

xdate.jday(date.mdy(4,19,43) + time.hms(6,49,27)) => 109.00

xdate.jday(date.mdy(10,7,43) + time.hms(2,57,52)) => 280.00

xdate.jday(date.mdy(3,17,92) + time.hms(16,45,44)) => 77.00

xdate.jday(date.mdy(2,25,96) + time.hms(21,30,57)) => 56.00

xdate.jday(date.mdy(11,10,2038) + time.hms(22,30,4)) => 314.00

xdate.jday(date.mdy(7,18,2094) + time.hms(1,56,51)) => 199.00

xdate.jday(0) => sysmis

xdate.jday(1) => sysmis

xdate.jday(86400) => 288.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.MDAY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.mday(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.mday(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.mday(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.mday(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.mday(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.mday(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.mday(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.mday(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.mday(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.mday(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.mday(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.mday(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.mday(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.mday(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.mday(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.mday(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.mday(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.mday(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.mday(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.mday(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.mday(date.mdy(6,10,1648) + time.hms(0,0,0)) => 10.00

xdate.mday(date.mdy(6,30,1680) + time.hms(4,50,38)) => 30.00

xdate.mday(date.mdy(7,24,1716) + time.hms(12,31,35)) => 24.00

xdate.mday(date.mdy(6,19,1768) + time.hms(12,47,53)) => 19.00

xdate.mday(date.mdy(8,2,1819) + time.hms(1,26,0)) => 2.00

xdate.mday(date.mdy(3,27,1839) + time.hms(20,58,11)) => 27.00

xdate.mday(date.mdy(4,19,1903) + time.hms(7,36,5)) => 19.00

xdate.mday(date.mdy(8,25,1929) + time.hms(15,43,49)) => 25.00

xdate.mday(date.mdy(9,29,1941) + time.hms(4,25,9)) => 29.00

xdate.mday(date.mdy(4,19,1943) + time.hms(6,49,27)) => 19.00

xdate.mday(date.mdy(10,7,1943) + time.hms(2,57,52)) => 7.00

xdate.mday(date.mdy(3,17,1992) + time.hms(16,45,44)) => 17.00

xdate.mday(date.mdy(2,25,1996) + time.hms(21,30,57)) => 25.00

xdate.mday(date.mdy(9,29,1941) + time.hms(4,25,9)) => 29.00

xdate.mday(date.mdy(4,19,43) + time.hms(6,49,27)) => 19.00

xdate.mday(date.mdy(10,7,43) + time.hms(2,57,52)) => 7.00

xdate.mday(date.mdy(3,17,92) + time.hms(16,45,44)) => 17.00

xdate.mday(date.mdy(2,25,96) + time.hms(21,30,57)) => 25.00

xdate.mday(date.mdy(11,10,2038) + time.hms(22,30,4)) => 10.00

xdate.mday(date.mdy(7,18,2094) + time.hms(1,56,51)) => 18.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.MINUTE])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.minute(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.minute(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.minute(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.minute(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.minute(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.minute(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.minute(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.minute(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.minute(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.minute(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.minute(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.minute(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.minute(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.minute(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.minute(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.minute(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.minute(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.minute(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.minute(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.minute(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.minute(date.mdy(6,10,1648) + time.hms(0,0,0)) => 0.00

xdate.minute(date.mdy(6,30,1680) + time.hms(4,50,38)) => 50.00

xdate.minute(date.mdy(7,24,1716) + time.hms(12,31,35)) => 31.00

xdate.minute(date.mdy(6,19,1768) + time.hms(12,47,53)) => 47.00

xdate.minute(date.mdy(8,2,1819) + time.hms(1,26,0)) => 26.00

xdate.minute(date.mdy(3,27,1839) + time.hms(20,58,11)) => 58.00

xdate.minute(date.mdy(4,19,1903) + time.hms(7,36,5)) => 36.00

xdate.minute(date.mdy(8,25,1929) + time.hms(15,43,49)) => 43.00

xdate.minute(date.mdy(9,29,1941) + time.hms(4,25,9)) => 25.00

xdate.minute(date.mdy(4,19,1943) + time.hms(6,49,27)) => 49.00

xdate.minute(date.mdy(10,7,1943) + time.hms(2,57,52)) => 57.00

xdate.minute(date.mdy(3,17,1992) + time.hms(16,45,44)) => 45.00

xdate.minute(date.mdy(2,25,1996) + time.hms(21,30,57)) => 30.00

xdate.minute(date.mdy(9,29,1941) + time.hms(4,25,9)) => 25.00

xdate.minute(date.mdy(4,19,43) + time.hms(6,49,27)) => 49.00

xdate.minute(date.mdy(10,7,43) + time.hms(2,57,52)) => 57.00

xdate.minute(date.mdy(3,17,92) + time.hms(16,45,44)) => 45.00

xdate.minute(date.mdy(2,25,96) + time.hms(21,30,57)) => 30.00

xdate.minute(date.mdy(11,10,2038) + time.hms(22,30,4)) => 30.00

xdate.minute(date.mdy(7,18,2094) + time.hms(1,56,51)) => 56.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.MONTH])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.month(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.month(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.month(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.month(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.month(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.month(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.month(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.month(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.month(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.month(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.month(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.month(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.month(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.month(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.month(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.month(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.month(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.month(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.month(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.month(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.month(date.mdy(6,10,1648) + time.hms(0,0,0)) => 6.00

xdate.month(date.mdy(6,30,1680) + time.hms(4,50,38)) => 6.00

xdate.month(date.mdy(7,24,1716) + time.hms(12,31,35)) => 7.00

xdate.month(date.mdy(6,19,1768) + time.hms(12,47,53)) => 6.00

xdate.month(date.mdy(8,2,1819) + time.hms(1,26,0)) => 8.00

xdate.month(date.mdy(3,27,1839) + time.hms(20,58,11)) => 3.00

xdate.month(date.mdy(4,19,1903) + time.hms(7,36,5)) => 4.00

xdate.month(date.mdy(8,25,1929) + time.hms(15,43,49)) => 8.00

xdate.month(date.mdy(9,29,1941) + time.hms(4,25,9)) => 9.00

xdate.month(date.mdy(4,19,1943) + time.hms(6,49,27)) => 4.00

xdate.month(date.mdy(10,7,1943) + time.hms(2,57,52)) => 10.00

xdate.month(date.mdy(3,17,1992) + time.hms(16,45,44)) => 3.00

xdate.month(date.mdy(2,25,1996) + time.hms(21,30,57)) => 2.00

xdate.month(date.mdy(9,29,1941) + time.hms(4,25,9)) => 9.00

xdate.month(date.mdy(4,19,43) + time.hms(6,49,27)) => 4.00

xdate.month(date.mdy(10,7,43) + time.hms(2,57,52)) => 10.00

xdate.month(date.mdy(3,17,92) + time.hms(16,45,44)) => 3.00

xdate.month(date.mdy(2,25,96) + time.hms(21,30,57)) => 2.00

xdate.month(date.mdy(11,10,2038) + time.hms(22,30,4)) => 11.00

xdate.month(date.mdy(7,18,2094) + time.hms(1,56,51)) => 7.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.QUARTER])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.quarter(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.quarter(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.quarter(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.quarter(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.quarter(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.quarter(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.quarter(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.quarter(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.quarter(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.quarter(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.quarter(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.quarter(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.quarter(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.quarter(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.quarter(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.quarter(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.quarter(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.quarter(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.quarter(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.quarter(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.quarter(date.mdy(6,10,1648) + time.hms(0,0,0)) => 2.00

xdate.quarter(date.mdy(6,30,1680) + time.hms(4,50,38)) => 2.00

xdate.quarter(date.mdy(7,24,1716) + time.hms(12,31,35)) => 3.00

xdate.quarter(date.mdy(6,19,1768) + time.hms(12,47,53)) => 2.00

xdate.quarter(date.mdy(8,2,1819) + time.hms(1,26,0)) => 3.00

xdate.quarter(date.mdy(3,27,1839) + time.hms(20,58,11)) => 1.00

xdate.quarter(date.mdy(4,19,1903) + time.hms(7,36,5)) => 2.00

xdate.quarter(date.mdy(8,25,1929) + time.hms(15,43,49)) => 3.00

xdate.quarter(date.mdy(9,29,1941) + time.hms(4,25,9)) => 3.00

xdate.quarter(date.mdy(4,19,1943) + time.hms(6,49,27)) => 2.00

xdate.quarter(date.mdy(10,7,1943) + time.hms(2,57,52)) => 4.00

xdate.quarter(date.mdy(3,17,1992) + time.hms(16,45,44)) => 1.00

xdate.quarter(date.mdy(2,25,1996) + time.hms(21,30,57)) => 1.00

xdate.quarter(date.mdy(9,29,1941) + time.hms(4,25,9)) => 3.00

xdate.quarter(date.mdy(4,19,43) + time.hms(6,49,27)) => 2.00

xdate.quarter(date.mdy(10,7,43) + time.hms(2,57,52)) => 4.00

xdate.quarter(date.mdy(3,17,92) + time.hms(16,45,44)) => 1.00

xdate.quarter(date.mdy(2,25,96) + time.hms(21,30,57)) => 1.00

xdate.quarter(date.mdy(11,10,2038) + time.hms(22,30,4)) => 4.00

xdate.quarter(date.mdy(7,18,2094) + time.hms(1,56,51)) => 3.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.SECOND])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.second(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.second(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.second(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.second(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.second(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.second(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.second(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.second(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.second(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.second(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.second(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.second(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.second(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.second(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.second(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.second(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.second(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.second(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.second(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.second(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.second(date.mdy(6,10,1648) + time.hms(0,0,0)) => 0.00

xdate.second(date.mdy(6,30,1680) + time.hms(4,50,38)) => 38.00

xdate.second(date.mdy(7,24,1716) + time.hms(12,31,35)) => 35.00

xdate.second(date.mdy(6,19,1768) + time.hms(12,47,53)) => 53.00

xdate.second(date.mdy(8,2,1819) + time.hms(1,26,0)) => 0.00

xdate.second(date.mdy(3,27,1839) + time.hms(20,58,11)) => 11.00

xdate.second(date.mdy(4,19,1903) + time.hms(7,36,5)) => 5.00

xdate.second(date.mdy(8,25,1929) + time.hms(15,43,49)) => 49.00

xdate.second(date.mdy(9,29,1941) + time.hms(4,25,9)) => 9.00

xdate.second(date.mdy(4,19,1943) + time.hms(6,49,27)) => 27.00

xdate.second(date.mdy(10,7,1943) + time.hms(2,57,52)) => 52.00

xdate.second(date.mdy(3,17,1992) + time.hms(16,45,44)) => 44.00

xdate.second(date.mdy(2,25,1996) + time.hms(21,30,57)) => 57.00

xdate.second(date.mdy(9,29,1941) + time.hms(4,25,9)) => 9.00

xdate.second(date.mdy(4,19,43) + time.hms(6,49,27)) => 27.00

xdate.second(date.mdy(10,7,43) + time.hms(2,57,52)) => 52.00

xdate.second(date.mdy(3,17,92) + time.hms(16,45,44)) => 44.00

xdate.second(date.mdy(2,25,96) + time.hms(21,30,57)) => 57.00

xdate.second(date.mdy(11,10,2038) + time.hms(22,30,4)) => 4.00

xdate.second(date.mdy(7,18,2094) + time.hms(1,56,51)) => 51.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.TDAY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.tday(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.tday(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.tday(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.tday(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.tday(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.tday(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.tday(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.tday(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.tday(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.tday(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.tday(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.tday(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.tday(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.tday(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.tday(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.tday(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.tday(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.tday(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.tday(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.tday(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.tday(date.mdy(6,10,1648) + time.hms(0,0,0)) => 23981.00

xdate.tday(date.mdy(6,30,1680) + time.hms(4,50,38)) => 35689.00

xdate.tday(date.mdy(7,24,1716) + time.hms(12,31,35)) => 48861.00

xdate.tday(date.mdy(6,19,1768) + time.hms(12,47,53)) => 67819.00

xdate.tday(date.mdy(8,2,1819) + time.hms(1,26,0)) => 86489.00

xdate.tday(date.mdy(3,27,1839) + time.hms(20,58,11)) => 93666.00

xdate.tday(date.mdy(4,19,1903) + time.hms(7,36,5)) => 117064.00

xdate.tday(date.mdy(8,25,1929) + time.hms(15,43,49)) => 126689.00

xdate.tday(date.mdy(9,29,1941) + time.hms(4,25,9)) => 131107.00

xdate.tday(date.mdy(4,19,1943) + time.hms(6,49,27)) => 131674.00

xdate.tday(date.mdy(10,7,1943) + time.hms(2,57,52)) => 131845.00

xdate.tday(date.mdy(3,17,1992) + time.hms(16,45,44)) => 149539.00

xdate.tday(date.mdy(2,25,1996) + time.hms(21,30,57)) => 150979.00

xdate.tday(date.mdy(9,29,1941) + time.hms(4,25,9)) => 131107.00

xdate.tday(date.mdy(4,19,43) + time.hms(6,49,27)) => 131674.00

xdate.tday(date.mdy(10,7,43) + time.hms(2,57,52)) => 131845.00

xdate.tday(date.mdy(3,17,92) + time.hms(16,45,44)) => 149539.00

xdate.tday(date.mdy(2,25,96) + time.hms(21,30,57)) => 150979.00

xdate.tday(date.mdy(11,10,2038) + time.hms(22,30,4)) => 166578.00

xdate.tday(date.mdy(7,18,2094) + time.hms(1,56,51)) => 186917.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.TIME])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.time(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.time(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.time(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.time(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.time(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.time(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.time(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.time(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.time(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.time(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.time(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.time(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.time(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.time(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.time(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.time(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.time(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.time(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.time(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.time(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.time(date.mdy(6,10,1648) + time.hms(0,0,0)) => 0.00

xdate.time(date.mdy(6,30,1680) + time.hms(4,50,38)) => 17438.00

xdate.time(date.mdy(7,24,1716) + time.hms(12,31,35)) => 45095.00

xdate.time(date.mdy(6,19,1768) + time.hms(12,47,53)) => 46073.00

xdate.time(date.mdy(8,2,1819) + time.hms(1,26,0)) => 5160.00

xdate.time(date.mdy(3,27,1839) + time.hms(20,58,11)) => 75491.00

xdate.time(date.mdy(4,19,1903) + time.hms(7,36,5)) => 27365.00

xdate.time(date.mdy(8,25,1929) + time.hms(15,43,49)) => 56629.00

xdate.time(date.mdy(9,29,1941) + time.hms(4,25,9)) => 15909.00

xdate.time(date.mdy(4,19,1943) + time.hms(6,49,27)) => 24567.00

xdate.time(date.mdy(10,7,1943) + time.hms(2,57,52)) => 10672.00

xdate.time(date.mdy(3,17,1992) + time.hms(16,45,44)) => 60344.00

xdate.time(date.mdy(2,25,1996) + time.hms(21,30,57)) => 77457.00

xdate.time(date.mdy(9,29,1941) + time.hms(4,25,9)) => 15909.00

xdate.time(date.mdy(4,19,43) + time.hms(6,49,27)) => 24567.00

xdate.time(date.mdy(10,7,43) + time.hms(2,57,52)) => 10672.00

xdate.time(date.mdy(3,17,92) + time.hms(16,45,44)) => 60344.00

xdate.time(date.mdy(2,25,96) + time.hms(21,30,57)) => 77457.00

xdate.time(date.mdy(11,10,2038) + time.hms(22,30,4)) => 81004.00

xdate.time(date.mdy(7,18,2094) + time.hms(1,56,51)) => 7011.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.WEEK])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.week(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.week(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.week(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.week(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.week(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.week(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.week(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.week(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.week(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.week(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.week(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.week(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.week(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.week(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.week(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.week(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.week(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.week(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.week(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.week(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.week(date.mdy(6,10,1648) + time.hms(0,0,0)) => 24.00

xdate.week(date.mdy(6,30,1680) + time.hms(4,50,38)) => 26.00

xdate.week(date.mdy(7,24,1716) + time.hms(12,31,35)) => 30.00

xdate.week(date.mdy(6,19,1768) + time.hms(12,47,53)) => 25.00

xdate.week(date.mdy(8,2,1819) + time.hms(1,26,0)) => 31.00

xdate.week(date.mdy(3,27,1839) + time.hms(20,58,11)) => 13.00

xdate.week(date.mdy(4,19,1903) + time.hms(7,36,5)) => 16.00

xdate.week(date.mdy(8,25,1929) + time.hms(15,43,49)) => 34.00

xdate.week(date.mdy(9,29,1941) + time.hms(4,25,9)) => 39.00

xdate.week(date.mdy(4,19,1943) + time.hms(6,49,27)) => 16.00

xdate.week(date.mdy(10,7,1943) + time.hms(2,57,52)) => 40.00

xdate.week(date.mdy(3,17,1992) + time.hms(16,45,44)) => 11.00

xdate.week(date.mdy(2,25,1996) + time.hms(21,30,57)) => 8.00

xdate.week(date.mdy(9,29,1941) + time.hms(4,25,9)) => 39.00

xdate.week(date.mdy(4,19,43) + time.hms(6,49,27)) => 16.00

xdate.week(date.mdy(10,7,43) + time.hms(2,57,52)) => 40.00

xdate.week(date.mdy(3,17,92) + time.hms(16,45,44)) => 11.00

xdate.week(date.mdy(2,25,96) + time.hms(21,30,57)) => 8.00

xdate.week(date.mdy(11,10,2038) + time.hms(22,30,4)) => 45.00

xdate.week(date.mdy(7,18,2094) + time.hms(1,56,51)) => 29.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.WKDAY])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.wkday(date.mdy(6,10,1648)).
DEBUG EVALUATE /xdate.wkday(date.mdy(6,30,1680)).
DEBUG EVALUATE /xdate.wkday(date.mdy(7,24,1716)).
DEBUG EVALUATE /xdate.wkday(date.mdy(6,19,1768)).
DEBUG EVALUATE /xdate.wkday(date.mdy(8,2,1819)).
DEBUG EVALUATE /xdate.wkday(date.mdy(3,27,1839)).
DEBUG EVALUATE /xdate.wkday(date.mdy(4,19,1903)).
DEBUG EVALUATE /xdate.wkday(date.mdy(8,25,1929)).
DEBUG EVALUATE /xdate.wkday(date.mdy(9,29,1941)).
DEBUG EVALUATE /xdate.wkday(date.mdy(4,19,1943)).
DEBUG EVALUATE /xdate.wkday(date.mdy(10,7,1943)).
DEBUG EVALUATE /xdate.wkday(date.mdy(3,17,1992)).
DEBUG EVALUATE /xdate.wkday(date.mdy(2,25,1996)).
DEBUG EVALUATE /xdate.wkday(date.mdy(9,29,1941)).
DEBUG EVALUATE /xdate.wkday(date.mdy(4,19,43)).
DEBUG EVALUATE /xdate.wkday(date.mdy(10,7,43)).
DEBUG EVALUATE /xdate.wkday(date.mdy(3,17,92)).
DEBUG EVALUATE /xdate.wkday(date.mdy(2,25,96)).
DEBUG EVALUATE /xdate.wkday(date.mdy(11,10,2038)).
DEBUG EVALUATE /xdate.wkday(date.mdy(7,18,2094)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.wkday(date.mdy(6,10,1648)) => 4.00

xdate.wkday(date.mdy(6,30,1680)) => 1.00

xdate.wkday(date.mdy(7,24,1716)) => 6.00

xdate.wkday(date.mdy(6,19,1768)) => 1.00

xdate.wkday(date.mdy(8,2,1819)) => 2.00

xdate.wkday(date.mdy(3,27,1839)) => 4.00

xdate.wkday(date.mdy(4,19,1903)) => 1.00

xdate.wkday(date.mdy(8,25,1929)) => 1.00

xdate.wkday(date.mdy(9,29,1941)) => 2.00

xdate.wkday(date.mdy(4,19,1943)) => 2.00

xdate.wkday(date.mdy(10,7,1943)) => 5.00

xdate.wkday(date.mdy(3,17,1992)) => 3.00

xdate.wkday(date.mdy(2,25,1996)) => 1.00

xdate.wkday(date.mdy(9,29,1941)) => 2.00

xdate.wkday(date.mdy(4,19,43)) => 2.00

xdate.wkday(date.mdy(10,7,43)) => 5.00

xdate.wkday(date.mdy(3,17,92)) => 3.00

xdate.wkday(date.mdy(2,25,96)) => 1.00

xdate.wkday(date.mdy(11,10,2038)) => 4.00

xdate.wkday(date.mdy(7,18,2094)) => 1.00
])
done
AT_CLEANUP

AT_SETUP([expressions - XDATE.YEAR])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /xdate.year(date.mdy(6,10,1648) + time.hms(0,0,0)).
DEBUG EVALUATE /xdate.year(date.mdy(6,30,1680) + time.hms(4,50,38)).
DEBUG EVALUATE /xdate.year(date.mdy(7,24,1716) + time.hms(12,31,35)).
DEBUG EVALUATE /xdate.year(date.mdy(6,19,1768) + time.hms(12,47,53)).
DEBUG EVALUATE /xdate.year(date.mdy(8,2,1819) + time.hms(1,26,0)).
DEBUG EVALUATE /xdate.year(date.mdy(3,27,1839) + time.hms(20,58,11)).
DEBUG EVALUATE /xdate.year(date.mdy(4,19,1903) + time.hms(7,36,5)).
DEBUG EVALUATE /xdate.year(date.mdy(8,25,1929) + time.hms(15,43,49)).
DEBUG EVALUATE /xdate.year(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.year(date.mdy(4,19,1943) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.year(date.mdy(10,7,1943) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.year(date.mdy(3,17,1992) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.year(date.mdy(2,25,1996) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.year(date.mdy(9,29,1941) + time.hms(4,25,9)).
DEBUG EVALUATE /xdate.year(date.mdy(4,19,43) + time.hms(6,49,27)).
DEBUG EVALUATE /xdate.year(date.mdy(10,7,43) + time.hms(2,57,52)).
DEBUG EVALUATE /xdate.year(date.mdy(3,17,92) + time.hms(16,45,44)).
DEBUG EVALUATE /xdate.year(date.mdy(2,25,96) + time.hms(21,30,57)).
DEBUG EVALUATE /xdate.year(date.mdy(11,10,2038) + time.hms(22,30,4)).
DEBUG EVALUATE /xdate.year(date.mdy(7,18,2094) + time.hms(1,56,51)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
xdate.year(date.mdy(6,10,1648) + time.hms(0,0,0)) => 1648.00

xdate.year(date.mdy(6,30,1680) + time.hms(4,50,38)) => 1680.00

xdate.year(date.mdy(7,24,1716) + time.hms(12,31,35)) => 1716.00

xdate.year(date.mdy(6,19,1768) + time.hms(12,47,53)) => 1768.00

xdate.year(date.mdy(8,2,1819) + time.hms(1,26,0)) => 1819.00

xdate.year(date.mdy(3,27,1839) + time.hms(20,58,11)) => 1839.00

xdate.year(date.mdy(4,19,1903) + time.hms(7,36,5)) => 1903.00

xdate.year(date.mdy(8,25,1929) + time.hms(15,43,49)) => 1929.00

xdate.year(date.mdy(9,29,1941) + time.hms(4,25,9)) => 1941.00

xdate.year(date.mdy(4,19,1943) + time.hms(6,49,27)) => 1943.00

xdate.year(date.mdy(10,7,1943) + time.hms(2,57,52)) => 1943.00

xdate.year(date.mdy(3,17,1992) + time.hms(16,45,44)) => 1992.00

xdate.year(date.mdy(2,25,1996) + time.hms(21,30,57)) => 1996.00

xdate.year(date.mdy(9,29,1941) + time.hms(4,25,9)) => 1941.00

xdate.year(date.mdy(4,19,43) + time.hms(6,49,27)) => 1943.00

xdate.year(date.mdy(10,7,43) + time.hms(2,57,52)) => 1943.00

xdate.year(date.mdy(3,17,92) + time.hms(16,45,44)) => 1992.00

xdate.year(date.mdy(2,25,96) + time.hms(21,30,57)) => 1996.00

xdate.year(date.mdy(11,10,2038) + time.hms(22,30,4)) => 2038.00

xdate.year(date.mdy(7,18,2094) + time.hms(1,56,51)) => 2094.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATEDIFF years])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.

DEBUG EVALUATE /datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'years').
DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'years').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'years').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'years').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'years').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'years').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'years').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'years').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'years').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'years').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'years').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'years').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'years').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'years').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'years').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'years').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'years').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'years').

DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(6,10,1648), 'years').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,30,1680), 'years').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(7,24,1716), 'years').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(6,19,1768), 'years').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(8,2,1819), 'years').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(3,27,1839), 'years').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(4,19,1903), 'years').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(8,25,1929), 'years').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(9,29,1941), 'years').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'years').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'years').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'years').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'years').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'years').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(2,25,96), 'years').
DEBUG EVALUATE /datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'years').
DEBUG EVALUATE /datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'years').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'years') => -32.00

datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'years') => -36.00

datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'years') => -51.00

datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'years') => -51.00

datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'years') => -19.00

datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'years') => -64.00

datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'years') => -26.00

datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'years') => -12.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'years') => -1.00

datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'years') => 0.00

datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'years') => -48.00

datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'years') => -3.00

datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'years') => -54.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'years') => -1.00

datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'years') => 0.00

datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'years') => -48.00

datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'years') => -3.00

datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'years') => -42.00

datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'years') => -55.00

datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'years') => -3.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'years') => -4.00

datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'years') => -2.00

datediff(date.mdy(6,30,1680), date.mdy(6,10,1648), 'years') => 32.00

datediff(date.mdy(7,24,1716), date.mdy(6,30,1680), 'years') => 36.00

datediff(date.mdy(6,19,1768), date.mdy(7,24,1716), 'years') => 51.00

datediff(date.mdy(8,2,1819), date.mdy(6,19,1768), 'years') => 51.00

datediff(date.mdy(3,27,1839), date.mdy(8,2,1819), 'years') => 19.00

datediff(date.mdy(4,19,1903), date.mdy(3,27,1839), 'years') => 64.00

datediff(date.mdy(8,25,1929), date.mdy(4,19,1903), 'years') => 26.00

datediff(date.mdy(9,29,1941), date.mdy(8,25,1929), 'years') => 12.00

datediff(date.mdy(4,19,1943), date.mdy(9,29,1941), 'years') => 1.00

datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'years') => 0.00

datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'years') => 48.00

datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'years') => 3.00

datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'years') => 54.00

datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'years') => 1.00

datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'years') => 0.00

datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'years') => 48.00

datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'years') => 3.00

datediff(date.mdy(11,10,2038), date.mdy(2,25,96), 'years') => 42.00

datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'years') => 55.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'years') => 3.00

datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'years') => 4.00

datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'years') => 2.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATEDIFF quarters])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'quarters').

DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(6,10,1648), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,30,1680), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(7,24,1716), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(6,19,1768), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(8,2,1819), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(3,27,1839), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(4,19,1903), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(8,25,1929), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(9,29,1941), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(2,25,96), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'quarters').
DEBUG EVALUATE /datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'quarters').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'quarters') => -128.00

datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'quarters') => -144.00

datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'quarters') => -207.00

datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'quarters') => -204.00

datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'quarters') => -78.00

datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'quarters') => -256.00

datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'quarters') => -105.00

datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'quarters') => -48.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'quarters') => -6.00

datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'quarters') => -1.00

datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'quarters') => -193.00

datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'quarters') => -15.00

datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'quarters') => -217.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'quarters') => -6.00

datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'quarters') => -1.00

datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'quarters') => -193.00

datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'quarters') => -15.00

datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'quarters') => -170.00

datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'quarters') => -222.00

datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'quarters') => -15.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'quarters') => -16.00

datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'quarters') => -11.00

datediff(date.mdy(6,30,1680), date.mdy(6,10,1648), 'quarters') => 128.00

datediff(date.mdy(7,24,1716), date.mdy(6,30,1680), 'quarters') => 144.00

datediff(date.mdy(6,19,1768), date.mdy(7,24,1716), 'quarters') => 207.00

datediff(date.mdy(8,2,1819), date.mdy(6,19,1768), 'quarters') => 204.00

datediff(date.mdy(3,27,1839), date.mdy(8,2,1819), 'quarters') => 78.00

datediff(date.mdy(4,19,1903), date.mdy(3,27,1839), 'quarters') => 256.00

datediff(date.mdy(8,25,1929), date.mdy(4,19,1903), 'quarters') => 105.00

datediff(date.mdy(9,29,1941), date.mdy(8,25,1929), 'quarters') => 48.00

datediff(date.mdy(4,19,1943), date.mdy(9,29,1941), 'quarters') => 6.00

datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'quarters') => 1.00

datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'quarters') => 193.00

datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'quarters') => 15.00

datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'quarters') => 217.00

datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'quarters') => 6.00

datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'quarters') => 1.00

datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'quarters') => 193.00

datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'quarters') => 15.00

datediff(date.mdy(11,10,2038), date.mdy(2,25,96), 'quarters') => 170.00

datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'quarters') => 222.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'quarters') => 15.00

datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'quarters') => 16.00

datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'quarters') => 11.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATEDIFF months])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'months').
DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'months').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'months').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'months').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'months').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'months').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'months').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'months').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'months').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'months').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'months').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'months').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'months').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'months').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'months').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'months').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'months').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'months').

DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(6,10,1648), 'months').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,30,1680), 'months').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(7,24,1716), 'months').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(6,19,1768), 'months').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(8,2,1819), 'months').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(3,27,1839), 'months').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(4,19,1903), 'months').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(8,25,1929), 'months').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(9,29,1941), 'months').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'months').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'months').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'months').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'months').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'months').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(2,25,96), 'months').
DEBUG EVALUATE /datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'months').
DEBUG EVALUATE /datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'months').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'months') => -384.00

datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'months') => -432.00

datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'months') => -622.00

datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'months') => -613.00

datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'months') => -235.00

datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'months') => -768.00

datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'months') => -316.00

datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'months') => -145.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'months') => -18.00

datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'months') => -5.00

datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'months') => -581.00

datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'months') => -47.00

datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'months') => -652.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'months') => -18.00

datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'months') => -5.00

datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'months') => -581.00

datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'months') => -47.00

datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'months') => -512.00

datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'months') => -668.00

datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'months') => -47.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'months') => -48.00

datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'months') => -35.00

datediff(date.mdy(6,30,1680), date.mdy(6,10,1648), 'months') => 384.00

datediff(date.mdy(7,24,1716), date.mdy(6,30,1680), 'months') => 432.00

datediff(date.mdy(6,19,1768), date.mdy(7,24,1716), 'months') => 622.00

datediff(date.mdy(8,2,1819), date.mdy(6,19,1768), 'months') => 613.00

datediff(date.mdy(3,27,1839), date.mdy(8,2,1819), 'months') => 235.00

datediff(date.mdy(4,19,1903), date.mdy(3,27,1839), 'months') => 768.00

datediff(date.mdy(8,25,1929), date.mdy(4,19,1903), 'months') => 316.00

datediff(date.mdy(9,29,1941), date.mdy(8,25,1929), 'months') => 145.00

datediff(date.mdy(4,19,1943), date.mdy(9,29,1941), 'months') => 18.00

datediff(date.mdy(10,7,1943), date.mdy(4,19,1943), 'months') => 5.00

datediff(date.mdy(3,17,1992), date.mdy(10,7,1943), 'months') => 581.00

datediff(date.mdy(2,25,1996), date.mdy(3,17,1992), 'months') => 47.00

datediff(date.mdy(2,25,1996), date.mdy(9,29,1941), 'months') => 652.00

datediff(date.mdy(4,19,43), date.mdy(9,29,1941), 'months') => 18.00

datediff(date.mdy(10,7,43), date.mdy(4,19,43), 'months') => 5.00

datediff(date.mdy(3,17,92), date.mdy(10,7,43), 'months') => 581.00

datediff(date.mdy(2,25,96), date.mdy(3,17,92), 'months') => 47.00

datediff(date.mdy(11,10,2038), date.mdy(2,25,96), 'months') => 512.00

datediff(date.mdy(7,18,2094), date.mdy(11,10,2038), 'months') => 668.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1900), 'months') => 47.00

datediff(date.mdy(2,29,1908), date.mdy(2,29,1904), 'months') => 48.00

datediff(date.mdy(2,28,1903), date.mdy(2,29,1900), 'months') => 35.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATEDIFF weeks])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'weeks').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'weeks').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'weeks') => -1672.00

datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'weeks') => -1881.00

datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'weeks') => -2708.00

datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'weeks') => -2667.00

datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'weeks') => -1025.00

datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'weeks') => -3342.00

datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'weeks') => -1375.00

datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'weeks') => -631.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'weeks') => -81.00

datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'weeks') => -24.00

datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'weeks') => -2527.00

datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'weeks') => -205.00

datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'weeks') => -2838.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'weeks') => -81.00

datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'weeks') => -24.00

datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'weeks') => -2527.00

datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'weeks') => -205.00

datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'weeks') => -2228.00

datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'weeks') => -2905.00

datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'weeks') => -208.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'weeks') => -208.00

datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'weeks') => -156.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATEDIFF days])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'days').
DEBUG EVALUATE /datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'days').
DEBUG EVALUATE /datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'days').
DEBUG EVALUATE /datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'days').
DEBUG EVALUATE /datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'days').
DEBUG EVALUATE /datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'days').
DEBUG EVALUATE /datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'days').
DEBUG EVALUATE /datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'days').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'days').
DEBUG EVALUATE /datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'days').
DEBUG EVALUATE /datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'days').
DEBUG EVALUATE /datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'days').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'days').
DEBUG EVALUATE /datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'days').
DEBUG EVALUATE /datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'days').
DEBUG EVALUATE /datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'days').
DEBUG EVALUATE /datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'days').
DEBUG EVALUATE /datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'days').
DEBUG EVALUATE /datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'days').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'days').
DEBUG EVALUATE /datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'days').
DEBUG EVALUATE /datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'days').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
datediff(date.mdy(6,10,1648), date.mdy(6,30,1680), 'days') => -11708.00

datediff(date.mdy(6,30,1680), date.mdy(7,24,1716), 'days') => -13172.00

datediff(date.mdy(7,24,1716), date.mdy(6,19,1768), 'days') => -18958.00

datediff(date.mdy(6,19,1768), date.mdy(8,2,1819), 'days') => -18670.00

datediff(date.mdy(8,2,1819), date.mdy(3,27,1839), 'days') => -7177.00

datediff(date.mdy(3,27,1839), date.mdy(4,19,1903), 'days') => -23398.00

datediff(date.mdy(4,19,1903), date.mdy(8,25,1929), 'days') => -9625.00

datediff(date.mdy(8,25,1929), date.mdy(9,29,1941), 'days') => -4418.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,1943), 'days') => -567.00

datediff(date.mdy(4,19,1943), date.mdy(10,7,1943), 'days') => -171.00

datediff(date.mdy(10,7,1943), date.mdy(3,17,1992), 'days') => -17694.00

datediff(date.mdy(3,17,1992), date.mdy(2,25,1996), 'days') => -1440.00

datediff(date.mdy(9,29,1941), date.mdy(2,25,1996), 'days') => -19872.00

datediff(date.mdy(9,29,1941), date.mdy(4,19,43), 'days') => -567.00

datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'days') => -171.00

datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'days') => -17694.00

datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'days') => -1440.00

datediff(date.mdy(2,25,96), date.mdy(11,10,2038), 'days') => -15599.00

datediff(date.mdy(11,10,2038), date.mdy(7,18,2094), 'days') => -20339.00

datediff(date.mdy(2,29,1900), date.mdy(2,29,1904), 'days') => -1460.00

datediff(date.mdy(2,29,1904), date.mdy(2,29,1908), 'days') => -1461.00

datediff(date.mdy(2,29,1900), date.mdy(2,28,1903), 'days') => -1094.00
])
done
AT_CLEANUP

dnl time of day is significant for DATEDIFF
AT_SETUP([expressions - DATEDIFF time of day])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /datediff(date.mdy(10,15,1910) + 234, date.mdy(10,10,1910) + 123, 'days').
DEBUG EVALUATE /datediff(date.mdy(10,15,1910) + 123, date.mdy(10,10,1910) + 234, 'days').
DEBUG EVALUATE /datediff(date.mdy(10,24,1910) + 234, date.mdy(10,10,1910) + 123, 'weeks').
DEBUG EVALUATE /datediff(date.mdy(10,24,1910) + 123, date.mdy(10,10,1910) + 234, 'weeks').
DEBUG EVALUATE /datediff(date.mdy(10,10,1910) + 234, date.mdy(5,10,1910) + 123, 'months').
DEBUG EVALUATE /datediff(date.mdy(10,10,1910) + 123, date.mdy(5,10,1910) + 234, 'months').
DEBUG EVALUATE /datediff(date.mdy(5,10,1919) + 234, date.mdy(5,10,1910) + 123, 'years').
DEBUG EVALUATE /datediff(date.mdy(5,10,1919) + 123, date.mdy(5,10,1910) + 234, 'years').

DEBUG EVALUATE /datediff(date.mdy(10,10,1910) + 123, date.mdy(10,15,1910) + 234, 'days').
DEBUG EVALUATE /datediff(date.mdy(10,10,1910) + 234, date.mdy(10,15,1910) + 123, 'days').
DEBUG EVALUATE /datediff(date.mdy(10,10,1910) + 123, date.mdy(10,24,1910) + 234, 'weeks').
DEBUG EVALUATE /datediff(date.mdy(10,10,1910) + 234, date.mdy(10,24,1910) + 123, 'weeks').
DEBUG EVALUATE /datediff(date.mdy(5,10,1910) + 123, date.mdy(10,10,1910) + 234, 'months').
DEBUG EVALUATE /datediff(date.mdy(5,10,1910) + 234, date.mdy(10,10,1910) + 123, 'months').
DEBUG EVALUATE /datediff(date.mdy(5,10,1910) + 123, date.mdy(5,10,1919) + 234, 'years').
DEBUG EVALUATE /datediff(date.mdy(5,10,1910) + 234, date.mdy(5,10,1919) + 123, 'years').
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
datediff(date.mdy(10,15,1910) + 234, date.mdy(10,10,1910) + 123, 'days') =>
5.00

datediff(date.mdy(10,15,1910) + 123, date.mdy(10,10,1910) + 234, 'days') =>
4.00

datediff(date.mdy(10,24,1910) + 234, date.mdy(10,10,1910) + 123, 'weeks') =>
2.00

datediff(date.mdy(10,24,1910) + 123, date.mdy(10,10,1910) + 234, 'weeks') =>
1.00

datediff(date.mdy(10,10,1910) + 234, date.mdy(5,10,1910) + 123, 'months') =>
5.00

datediff(date.mdy(10,10,1910) + 123, date.mdy(5,10,1910) + 234, 'months') =>
4.00

datediff(date.mdy(5,10,1919) + 234, date.mdy(5,10,1910) + 123, 'years') => 9.00

datediff(date.mdy(5,10,1919) + 123, date.mdy(5,10,1910) + 234, 'years') => 8.00

datediff(date.mdy(10,10,1910) + 123, date.mdy(10,15,1910) + 234, 'days') =>
-5.00

datediff(date.mdy(10,10,1910) + 234, date.mdy(10,15,1910) + 123, 'days') =>
-4.00

datediff(date.mdy(10,10,1910) + 123, date.mdy(10,24,1910) + 234, 'weeks') =>
-2.00

datediff(date.mdy(10,10,1910) + 234, date.mdy(10,24,1910) + 123, 'weeks') =>
-1.00

datediff(date.mdy(5,10,1910) + 123, date.mdy(10,10,1910) + 234, 'months') =>
-5.00

datediff(date.mdy(5,10,1910) + 234, date.mdy(10,10,1910) + 123, 'months') =>
-4.00

datediff(date.mdy(5,10,1910) + 123, date.mdy(5,10,1919) + 234, 'years') =>
-9.00

datediff(date.mdy(5,10,1910) + 234, date.mdy(5,10,1919) + 123, 'years') =>
-8.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATESUM with non-leap year])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 1, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 2, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 3, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 4, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 5.4, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 6, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 7, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 8, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 9, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 10, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 11, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 12, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 13.9, 'months') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 1, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 2, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 3.2, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 4, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 5, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 6, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 7, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 8, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 9, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 10, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 11, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 12, 'months', 'rollover') - date.mdy(1,1,1900)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1900), 13, 'months', 'rollover') - date.mdy(1,1,1900)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
ctime.days(datesum(date.mdy(1,31,1900), 1, 'months') - date.mdy(1,1,1900)) =>
58.00

ctime.days(datesum(date.mdy(1,31,1900), 2, 'months') - date.mdy(1,1,1900)) =>
89.00

ctime.days(datesum(date.mdy(1,31,1900), 3, 'months') - date.mdy(1,1,1900)) =>
119.00

ctime.days(datesum(date.mdy(1,31,1900), 4, 'months') - date.mdy(1,1,1900)) =>
150.00

ctime.days(datesum(date.mdy(1,31,1900), 5.4, 'months') - date.mdy(1,1,1900)) =>
180.00

ctime.days(datesum(date.mdy(1,31,1900), 6, 'months') - date.mdy(1,1,1900)) =>
211.00

ctime.days(datesum(date.mdy(1,31,1900), 7, 'months') - date.mdy(1,1,1900)) =>
242.00

ctime.days(datesum(date.mdy(1,31,1900), 8, 'months') - date.mdy(1,1,1900)) =>
272.00

ctime.days(datesum(date.mdy(1,31,1900), 9, 'months') - date.mdy(1,1,1900)) =>
303.00

ctime.days(datesum(date.mdy(1,31,1900), 10, 'months') - date.mdy(1,1,1900)) =>
333.00

ctime.days(datesum(date.mdy(1,31,1900), 11, 'months') - date.mdy(1,1,1900)) =>
364.00

ctime.days(datesum(date.mdy(1,31,1900), 12, 'months') - date.mdy(1,1,1900)) =>
395.00

ctime.days(datesum(date.mdy(1,31,1900), 13.9, 'months') - date.mdy(1,1,1900))
=> 423.00

ctime.days(datesum(date.mdy(1,31,1900), 1, 'months', 'rollover') -
date.mdy(1,1,1900)) => 61.00

ctime.days(datesum(date.mdy(1,31,1900), 2, 'months', 'rollover') -
date.mdy(1,1,1900)) => 89.00

ctime.days(datesum(date.mdy(1,31,1900), 3.2, 'months', 'rollover') -
date.mdy(1,1,1900)) => 120.00

ctime.days(datesum(date.mdy(1,31,1900), 4, 'months', 'rollover') -
date.mdy(1,1,1900)) => 150.00

ctime.days(datesum(date.mdy(1,31,1900), 5, 'months', 'rollover') -
date.mdy(1,1,1900)) => 181.00

ctime.days(datesum(date.mdy(1,31,1900), 6, 'months', 'rollover') -
date.mdy(1,1,1900)) => 211.00

ctime.days(datesum(date.mdy(1,31,1900), 7, 'months', 'rollover') -
date.mdy(1,1,1900)) => 242.00

ctime.days(datesum(date.mdy(1,31,1900), 8, 'months', 'rollover') -
date.mdy(1,1,1900)) => 273.00

ctime.days(datesum(date.mdy(1,31,1900), 9, 'months', 'rollover') -
date.mdy(1,1,1900)) => 303.00

ctime.days(datesum(date.mdy(1,31,1900), 10, 'months', 'rollover') -
date.mdy(1,1,1900)) => 334.00

ctime.days(datesum(date.mdy(1,31,1900), 11, 'months', 'rollover') -
date.mdy(1,1,1900)) => 364.00

ctime.days(datesum(date.mdy(1,31,1900), 12, 'months', 'rollover') -
date.mdy(1,1,1900)) => 395.00

ctime.days(datesum(date.mdy(1,31,1900), 13, 'months', 'rollover') -
date.mdy(1,1,1900)) => 426.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATESUM with leap year])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 1, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 2.5, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 3, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 4.9, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 5.1, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 6, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 7, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 8, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 9, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 10, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 11, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 12, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 13, 'months') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 1, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 2, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 3, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 4, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 5, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 6, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 7, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 8, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 9, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 10, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 11, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 12, 'months', 'rollover') - date.mdy(1,1,1904)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(1,31,1904), 13, 'months', 'rollover') - date.mdy(1,1,1904)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
ctime.days(datesum(date.mdy(1,31,1904), 1, 'months') - date.mdy(1,1,1904)) =>
59.00

ctime.days(datesum(date.mdy(1,31,1904), 2.5, 'months') - date.mdy(1,1,1904)) =>
90.00

ctime.days(datesum(date.mdy(1,31,1904), 3, 'months') - date.mdy(1,1,1904)) =>
120.00

ctime.days(datesum(date.mdy(1,31,1904), 4.9, 'months') - date.mdy(1,1,1904)) =>
151.00

ctime.days(datesum(date.mdy(1,31,1904), 5.1, 'months') - date.mdy(1,1,1904)) =>
181.00

ctime.days(datesum(date.mdy(1,31,1904), 6, 'months') - date.mdy(1,1,1904)) =>
212.00

ctime.days(datesum(date.mdy(1,31,1904), 7, 'months') - date.mdy(1,1,1904)) =>
243.00

ctime.days(datesum(date.mdy(1,31,1904), 8, 'months') - date.mdy(1,1,1904)) =>
273.00

ctime.days(datesum(date.mdy(1,31,1904), 9, 'months') - date.mdy(1,1,1904)) =>
304.00

ctime.days(datesum(date.mdy(1,31,1904), 10, 'months') - date.mdy(1,1,1904)) =>
334.00

ctime.days(datesum(date.mdy(1,31,1904), 11, 'months') - date.mdy(1,1,1904)) =>
365.00

ctime.days(datesum(date.mdy(1,31,1904), 12, 'months') - date.mdy(1,1,1904)) =>
396.00

ctime.days(datesum(date.mdy(1,31,1904), 13, 'months') - date.mdy(1,1,1904)) =>
424.00

ctime.days(datesum(date.mdy(1,31,1904), 1, 'months', 'rollover') -
date.mdy(1,1,1904)) => 61.00

ctime.days(datesum(date.mdy(1,31,1904), 2, 'months', 'rollover') -
date.mdy(1,1,1904)) => 90.00

ctime.days(datesum(date.mdy(1,31,1904), 3, 'months', 'rollover') -
date.mdy(1,1,1904)) => 121.00

ctime.days(datesum(date.mdy(1,31,1904), 4, 'months', 'rollover') -
date.mdy(1,1,1904)) => 151.00

ctime.days(datesum(date.mdy(1,31,1904), 5, 'months', 'rollover') -
date.mdy(1,1,1904)) => 182.00

ctime.days(datesum(date.mdy(1,31,1904), 6, 'months', 'rollover') -
date.mdy(1,1,1904)) => 212.00

ctime.days(datesum(date.mdy(1,31,1904), 7, 'months', 'rollover') -
date.mdy(1,1,1904)) => 243.00

ctime.days(datesum(date.mdy(1,31,1904), 8, 'months', 'rollover') -
date.mdy(1,1,1904)) => 274.00

ctime.days(datesum(date.mdy(1,31,1904), 9, 'months', 'rollover') -
date.mdy(1,1,1904)) => 304.00

ctime.days(datesum(date.mdy(1,31,1904), 10, 'months', 'rollover') -
date.mdy(1,1,1904)) => 335.00

ctime.days(datesum(date.mdy(1,31,1904), 11, 'months', 'rollover') -
date.mdy(1,1,1904)) => 365.00

ctime.days(datesum(date.mdy(1,31,1904), 12, 'months', 'rollover') -
date.mdy(1,1,1904)) => 396.00

ctime.days(datesum(date.mdy(1,31,1904), 13, 'months', 'rollover') -
date.mdy(1,1,1904)) => 427.00
])
done
AT_CLEANUP

AT_SETUP([expressions - DATESUM])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,10,1648), 1, 'weeks') - date.mdy(6,10,1648)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'weeks') - date.mdy(6,30,1680)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(7,24,1716), -3, 'weeks') - date.mdy(7,24,1716)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,19,1768), 4, 'weeks') - date.mdy(6,19,1768)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819), 5, 'weeks') - date.mdy(8,2,1819)).

DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,10,1648), 1, 'days') - date.mdy(6,10,1648)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'days') - date.mdy(6,30,1680)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(7,24,1716), -3, 'days') - date.mdy(7,24,1716)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,19,1768), 4, 'days') - date.mdy(6,19,1768)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819), 5, 'days') - date.mdy(8,2,1819)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,10,1648), 1, 'hours') - date.mdy(6,10,1648)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'hours') - date.mdy(6,30,1680)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(6,19,1768), -4, 'hours') - date.mdy(6,19,1768)).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819), 5, 'hours') - date.mdy(8,2,1819)).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
ctime.days(datesum(date.mdy(6,10,1648), 1, 'weeks') - date.mdy(6,10,1648)) =>
7.00

ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'weeks') - date.mdy(6,30,1680)) =>
17.50

ctime.days(datesum(date.mdy(7,24,1716), -3, 'weeks') - date.mdy(7,24,1716)) =>
-21.00

ctime.days(datesum(date.mdy(6,19,1768), 4, 'weeks') - date.mdy(6,19,1768)) =>
28.00

ctime.days(datesum(date.mdy(8,2,1819), 5, 'weeks') - date.mdy(8,2,1819)) =>
35.00

ctime.days(datesum(date.mdy(6,10,1648), 1, 'days') - date.mdy(6,10,1648)) =>
1.00

ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'days') - date.mdy(6,30,1680)) =>
2.50

ctime.days(datesum(date.mdy(7,24,1716), -3, 'days') - date.mdy(7,24,1716)) =>
-3.00

ctime.days(datesum(date.mdy(6,19,1768), 4, 'days') - date.mdy(6,19,1768)) =>
4.00

ctime.days(datesum(date.mdy(8,2,1819), 5, 'days') - date.mdy(8,2,1819)) => 5.00

ctime.days(datesum(date.mdy(6,10,1648), 1, 'hours') - date.mdy(6,10,1648)) =>
0.04

ctime.days(datesum(date.mdy(6,30,1680), 2.5, 'hours') - date.mdy(6,30,1680)) =>
0.10

ctime.days(datesum(date.mdy(6,19,1768), -4, 'hours') - date.mdy(6,19,1768)) =>
-0.17

ctime.days(datesum(date.mdy(8,2,1819), 5, 'hours') - date.mdy(8,2,1819)) =>
0.21
])
done
AT_CLEANUP

AT_SETUP([expressions - DATESUM preserves time of day for units of days and longer])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'days') - (date.mdy(8,2,1819) + time.hms(1,2,3))).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'weeks') - (date.mdy(8,2,1819) + time.hms(1,2,3))).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'months') - (date.mdy(8,2,1819) + time.hms(1,2,3))).
DEBUG EVALUATE /ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'years') - (date.mdy(8,2,1819) + time.hms(1,2,3))).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'days') -
(date.mdy(8,2,1819) + time.hms(1,2,3))) => 5.00

ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'weeks') -
(date.mdy(8,2,1819) + time.hms(1,2,3))) => 35.00

ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'months') -
(date.mdy(8,2,1819) + time.hms(1,2,3))) => 153.00

ctime.days(datesum(date.mdy(8,2,1819) + time.hms(1,2,3), 5, 'years') -
(date.mdy(8,2,1819) + time.hms(1,2,3))) => 1827.00
])
done
AT_CLEANUP

dnl These test values are from Applied Statistics, Algorithm AS 310.
AT_SETUP([expressions - NCDF.BETA])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE /1000 * ncdf.beta(.868,10,20,150).
DEBUG EVALUATE /1000 * ncdf.beta(.9,10,10,120).
DEBUG EVALUATE /1000 * ncdf.beta(.88,15,5,80).
DEBUG EVALUATE /1000 * ncdf.beta(.85,20,10,110).
DEBUG EVALUATE /1000 * ncdf.beta(.66,20,30,65).
DEBUG EVALUATE /1000 * ncdf.beta(.72,20,50,130).
DEBUG EVALUATE /1000 * ncdf.beta(.72,30,20,80).
DEBUG EVALUATE /1000 * ncdf.beta(.8,30,40,130).
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
1000 * ncdf.beta(.868,10,20,150) => 937.66

1000 * ncdf.beta(.9,10,10,120) => 730.68

1000 * ncdf.beta(.88,15,5,80) => 160.43

1000 * ncdf.beta(.85,20,10,110) => 186.75

1000 * ncdf.beta(.66,20,30,65) => 655.94

1000 * ncdf.beta(.72,20,50,130) => 979.69

1000 * ncdf.beta(.72,30,20,80) => 116.24

1000 * ncdf.beta(.8,30,40,130) => 993.04
])
done
AT_CLEANUP

dnl FIXME: LAG
dnl
  [[X], [1.00], [], [(X = 1.00)]],

dnl FIXME: out-of-range and nearly out-of-range values on dates
dnl
dnl Tests correctness of generic optimizations in optimize_tree().
AT_SETUP([expressions - generic tree optimizations])
AT_KEYWORDS([expression expressions evaluate])
AT_DATA([evaluate-base.sps], [dnl
SET EPOCH 1940.
DEBUG EVALUATE SET opt.
DEBUG EVALUATE (x=10) /x + 0.
DEBUG EVALUATE (x=-3) /x - 0.
DEBUG EVALUATE (x=5) /0 + x.
DEBUG EVALUATE (x=10) /x * 1.
DEBUG EVALUATE (x=-3) /1 * x.
DEBUG EVALUATE (x=5) /x / 1.
DEBUG EVALUATE (x=10) /0 * x.
DEBUG EVALUATE (x=-3) /x * 0.
DEBUG EVALUATE (x=5) /0 / x.
DEBUG EVALUATE (x=5) /mod(0, x).
DEBUG EVALUATE (x=5) /x ** 1.
DEBUG EVALUATE (x=5) /x ** 2.
])

for opt in OPT NOOPT; do
    AS_BOX([$opt])
    sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
    AT_CHECK([pspp --testing-mode evaluate.sps], [0], [dnl
x + 0 => 10.00

x - 0 => -3.00

0 + x => 5.00

x * 1 => 10.00

1 * x => -3.00

x / 1 => 5.00

0 * x => 0.00

x * 0 => 0.00

0 / x => 0.00

mod(0, x) => 0.00

x ** 1 => 5.00

x ** 2 => 25.00
])
done
AT_CLEANUP

AT_SETUP([expressions - LAG])
AT_DATA([lag.sps], [dnl
data list /W 1.
begin data.
1
2
3
4
5
end data.

compute X=lag(w,1).
compute Y=lag(x).
compute Z=lag(w,2).
list.
])
AT_CHECK([pspp -o pspp.csv lag.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Reading 1 record from INLINE.
Variable,Record,Columns,Format
W,1,1-1,F1.0

Table: Data List
W,X,Y,Z
1,.  ,.  ,.  @&t@
2,1.00,.  ,.  @&t@
3,2.00,1.00,1.00
4,3.00,2.00,2.00
5,4.00,3.00,3.00
])
AT_CLEANUP

AT_SETUP([expression - LAG crash])
AT_DATA([lag.sps], [dnl
DATA LIST LIST /x.
BEGIN DATA
1
2
END DATA.

DO IF (x <> LAG(x) ).
	ECHO 'hello'.
END IF.

EXECUTE.
])
AT_CHECK([pspp -o pspp.csv lag.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Reading free-form data from INLINE.
Variable,Format
x,F8.0

hello
])
AT_CLEANUP

dnl Tests for a bug which caused UNIFORM(x) to always return zero.
AT_SETUP([expressions - UNIFORM])
AT_DATA([uniform.sps], [dnl
set seed=10.
input program.
+ loop #i = 1 to 20.
+    do repeat response=R1.
+       compute response = uniform(10).
+    end repeat.
+    end case.
+ end loop.
+ end file.
end input program.

list.
])
AT_CHECK([pspp -o pspp.csv uniform.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Data List
R1
7.71
2.99
.21
4.95
6.34
4.43
7.49
8.32
4.99
5.83
2.25
.25
1.98
7.09
7.61
2.66
1.69
2.64
.88
1.50
])
AT_CLEANUP

AT_SETUP([expressions - VALUELABEL])
AT_DATA([valuelabel.sps], [dnl
DATA LIST notable /n 1 s 2(a).
VALUE LABELS /n 0 'Very dissatisfied'
                1 'Dissatisfied'
		1.5 'Slightly Peeved'
                2 'Neutral'
                3 'Satisfied'
                4 'Very satisfied'.
VALUE LABELS /s 'a' 'Wouldn''t buy again'
                'b' 'Unhappy'
                'c' 'Bored'
                'd' 'Satiated'
                'e' 'Elated'.
STRING nlabel slabel(a10).
COMPUTE nlabel = VALUELABEL(n).
COMPUTE slabel = VALUELABEL(s).
LIST.
BEGIN DATA.

0a
1b
2c
3d
4e
5f
6g
END DATA.
])
AT_CHECK([pspp -o pspp.csv valuelabel.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Data List
n,s,nlabel,slabel
.,,,
0,a,Very dissa,Wouldn't b
1,b,Dissatisfi,Unhappy
2,c,Neutral,Bored
3,d,Satisfied,Satiated
4,e,Very satis,Elated
5,f,,
6,g,,
])
AT_CLEANUP

AT_SETUP([expressions - variables])
AT_DATA([variables.sps], [dnl
DATA LIST NOTABLE/N1 TO N5 1-5.
MISSING VALUES N1 TO N5 (3 THRU 5, 1).
BEGIN DATA.
12345
6789
END DATA.

COMPUTE P1=N1.
COMPUTE P2=N2.
COMPUTE P3=N3.
COMPUTE P4=N4.
COMPUTE P5=N5.

COMPUTE MC=NMISS(N1 TO N5).
COMPUTE VC=NVALID(N1 TO N5).

COMPUTE S1=SYSMIS(N1).
COMPUTE S2=SYSMIS(N2).
COMPUTE S3=SYSMIS(N3).
COMPUTE S4=SYSMIS(N4).
COMPUTE S5=SYSMIS(N5).

COMPUTE M1=MISSING(N1).
COMPUTE M2=MISSING(N2).
COMPUTE M3=MISSING(N3).
COMPUTE M4=MISSING(N4).
COMPUTE M5=MISSING(N5).

COMPUTE V1=VALUE(N1).
COMPUTE V2=VALUE(N2).
COMPUTE V3=VALUE(N3).
COMPUTE V4=VALUE(N4).
COMPUTE V5=VALUE(N5).

FORMATS ALL (F1).

LIST.
])
AT_CHECK([pspp -o pspp.csv variables.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Data List
N1,N2,N3,N4,N5,P1,P2,P3,P4,P5,MC,VC,S1,S2,S3,S4,S5,M1,M2,M3,M4,M5,V1,V2,V3,V4,V5
1,2,3,4,5,.,2,.,.,.,4,1,0,0,0,0,0,1,0,1,1,1,1,2,3,4,5
6,7,8,9,.,6,7,8,9,.,1,4,0,0,0,0,1,0,0,0,0,1,6,7,8,9,.
])
AT_CLEANUP

AT_SETUP([expressions - vectors])
AT_DATA([vectors.sps], [dnl
DATA LIST NOTABLE /N1 TO N5 1-5.
MISSING VALUES N1 TO N5 (3 THRU 5, 1).
BEGIN DATA.
12345
6789
END DATA.

VECTOR N=N1 TO N5.
VECTOR X(5).
LOOP I=1 TO 5.
COMPUTE X(I)=N(I) + 1.
END LOOP.

FORMATS ALL (F2).

LIST.
])
AT_CHECK([pspp -o pspp.csv vectors.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Data List
N1,N2,N3,N4,N5,X1,X2,X3,X4,X5,I
1,2,3,4,5,.,3,.,.,.,5
6,7,8,9,.,7,8,9,10,.,5
])
AT_CLEANUP
