expressions: Major work to improve error messages.
[pspp] / tests / language / expressions / evaluate.at
index cd574eb10f79eb8cea949a754d6b20ffc2947355..baf2266d98873621e89a466ccb61329d65b65e94 100644 (file)
@@ -13,1999 +13,7556 @@ 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/>.
-m4_define([CHECK_EXPR_EVAL],
-  [AT_SETUP([expressions - $1])
-   AT_KEYWORDS([expression])
-   AT_DATA([evaluate.sps],
-     [set mxwarn 1000.
-set mxerr 1000.
-set epoch 1940.
-m4_foreach([check], [m4_shift($@)],
-                 [DEBUG EVALUATE NOOPT m4_argn(4, check)/[]m4_car(check).
-DEBUG EVALUATE m4_argn(4, check)/[]m4_car(check).
-])])
-   AT_CAPTURE_FILE([evaluate.sps])
-   m4_pushdef([i], [3])
-   AT_CHECK([pspp --testing-mode -O format=csv evaluate.sps],
-     [m4_if(m4_bregexp([m4_foreach([check], [m4_shift($@)], [m4_argn(3, check)])], [error:]), [-1], [0], [1])],
-     [stdout])
-   AT_DATA([expout], [m4_foreach([check], [m4_shift($@)],
-        [m4_define([i], m4_incr(i))dnl
-m4_if(m4_argn(3, check), [], [], [evaluate.sps:[]i[]: m4_argn(3, check)
-])dnl
-m4_argn(2, check)
-m4_define([i], m4_incr(i))dnl
-m4_if(m4_argn(3, check), [], [], [evaluate.sps:[]i[]: m4_argn(3, check)
-])dnl
-m4_argn(2, check)
-])])
-   AT_CHECK([[sed '
-# Transform "file:line.column:" into plain "file:line:",
-# because column numbers change between opt and noopt versions.
-s/\(evaluate.sps:[0-9]\{1,\}\)\.[0-9]\{1,\}:/\1:/
-
-# Remove leading or trailing quotes and un-double CSV quotes.
-s/^"//
-s/"$//
-s/""/"/g
-# "
-
-# Delete blank lines
-/^$/d' stdout]],
-     [0], [expout], [])
-   m4_popdef([i])
-   AT_CLEANUP])
+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.
+])
+
+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
+])
+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 at `!': expecting end
+of command.
+
+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 at `='.
+
+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 at `='.
+
+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 at `>'.
+
+1 < > 1 => error
+
+evaluate.sps:42.19: error: DEBUG EVALUATE: Syntax error at `~': expecting end
+of command.
+
+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: error: DEBUG EVALUATE: Unknown identifier b.
+
+any('a', b, 'c', 'd') => error
+
+evaluate.sps:38: error: DEBUG EVALUATE: Unknown identifier c.
+
+any('a', 'b', c, 'd') => error
+
+evaluate.sps:39: error: DEBUG EVALUATE: Unknown identifier 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
 
-AT_BANNER([expressions])
+datediff(date.mdy(4,19,43), date.mdy(10,7,43), 'months') => -5.00
 
-CHECK_EXPR_EVAL([numeric syntax],
-  [[1e2], [100.00]],
-  [[1e+2], [100.00]],
-  [[1e-2], [0.01]],
-  [[1e-99], [0.00]])
-
-CHECK_EXPR_EVAL([coercion to/from Boolean],
-  [[0 AND 1], [false]],
-  [[$true AND 1], [true]],
-  [[1 OR $false], [true]],
-  [[1 OR $sysmis], [true]],
-  [[2 OR $sysmis], [sysmis],
-   [error: DEBUG EVALUATE: An operand of the logical disjunction (`OR') operator was found to have a value other than 0 (false), 1 (true), or the system-missing value.  The result was forced to 0.]],
-  [[2 AND $sysmis], [false],
-   [error: DEBUG EVALUATE: An operand of the logical conjunction (`AND') operator was found to have a value other than 0 (false), 1 (true), or the system-missing value.  The result was forced to 0.]],
-  [['string' AND $sysmis], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying logical conjunction (`AND') operator: cannot convert string to boolean.]],
-  [[0 AND $sysmis], [false]],
-  [[(1>2) + 1], [1.00]],
-  [[$true + $false], [1.00]])
-
-CHECK_EXPR_EVAL([addition and subtraction],
-  [[1 + 2], [3.00]],
-  [[1 + $true], [2.00]],
-  [[$sysmis + 1], [sysmis]],
-  [[7676 + $sysmis], [sysmis]],
-  [[('foo') + 5], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying addition (`+') operator: cannot convert string to number.]],
-  dnl Arithmetic concatenation requires CONCAT:
-  [[('foo') + ('bar')], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying addition (`+') operator: cannot convert string to number.]],
-  dnl Lexical concatenation succeeds:
-  [['foo' + 'bar'], ["foobar"]],
-  [[1 +3 - 2 +4 -5], [1.00]],
-  [[1 - $true], [0.00]],
-  [[$true - 4/3], [-0.33]],
-  [['string' - 1e10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying subtraction (`-') operator: cannot convert string to number.]],
-  [[9.5 - ''], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying subtraction (`-') operator: cannot convert string to number.]],
-  [[1 - 2], [-1.00]],
-  [[52 -23], [29.00]])
-
-CHECK_EXPR_EVAL([multiplication and division],
-  [[5 * 10], [50.00]],
-  [[10 * $true], [10.00]],
-  [[$true * 5], [5.00]],
-  [[1.5 * $true], [1.50]],
-  [[5 * $sysmis], [sysmis]],
-  [[$sysmis * 15], [sysmis]],
-  [[2 * 5 / 10], [1.00]],
-  [[1 / 2], [0.50]],
-  [[2 / 5], [0.40]],
-  [[12 / 3 / 2], [2.00]])
-
-CHECK_EXPR_EVAL([exponentiation],
-  [[2**8], [256.00]],
-  [[(2**3)**4], [4096.00]],
-  [[2**3**4], [4096.00],
-   [warning: DEBUG EVALUATE: The exponentiation operator (`**') is left-associative, even though right-associative semantics are more useful.  That is, `a**b**c' equals `(a**b)**c', not as `a**(b**c)'.  To disable this warning, insert parentheses.]])
-
-CHECK_EXPR_EVAL([unary minus],
-  [[2+-3], [-1.00]],
-  [[2*-3], [-6.00]],
-  [[-3**2], [-9.00]],
-  [[(-3)**2], [9.00]],
-  [[2**-1], [0.50]],
-  [[0**0], [sysmis]],
-  [[0**-1], [sysmis]],
-  [[(-3)**1.5], [sysmis]])
-
-CHECK_EXPR_EVAL([AND truth table],
-  [[$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]])
-
-CHECK_EXPR_EVAL([OR truth table],
-  [[$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]])
-
-CHECK_EXPR_EVAL([NOT truth table],
-  [[not $false], [true]],
-  [[not 0], [true]],
-  [[not 2.5], [true],
-   [error: DEBUG EVALUATE: An operand of the logical negation (`NOT') operator was found to have a value other than 0 (false), 1 (true), or the system-missing value.  The result was forced to 0.]],
-  [[not $true], [false]],
-  [[not 1], [false]],
-  [[not $sysmis], [sysmis]],
-  [[~ $false], [true]],
-  [[~ 0], [true]],
-  [[~ 2.5], [true],
-   [error: DEBUG EVALUATE: An operand of the logical negation (`NOT') operator was found to have a value other than 0 (false), 1 (true), or the system-missing value.  The result was forced to 0.]],
-  [[~ $true], [false]],
-  [[~ 1], [false]],
-  [[~ $sysmis], [sysmis]])
-
-CHECK_EXPR_EVAL([= <= <],
-  [[1 eq 1], [true]],
-  [[1 = 1], [true]],
-  [[1 eq 2], [false]],
-  [[2 = 3], [false]],
-  [[1 eq 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric equality (`EQ') operator: cannot convert string to number.]],
-  [[5 eq 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric equality (`EQ') operator: cannot convert string to number.]],
-  [['baz' = 10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string equality (`=') operator: cannot convert number to string.]],
-  [['quux' = 5.55], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string equality (`=') operator: cannot convert number to string.]],
-  [['foobar' = 'foobar'], [true]],
-  [['quux' = 'bar'], [false]],
-  [['bar   ' = 'bar'], [true]],
-  [['asdf         ' = 'asdf  '], [true]],
-  [['asdfj   ' = 'asdf'], [false]],
-dnl Check precedence:
-  [[1 + 2 = 3], [true]],
-  [[1 >= 2 = 2 ge 3], [false],
-   [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').  If chaining is really intended, parentheses will disable this warning (e.g. `(a < b) < c'.)]],
-dnl Mathematically true:
-  [[3 ne 2 ~= 1], [false],
-   [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').  If chaining is really intended, parentheses will disable this warning (e.g. `(a < b) < c'.)]],
-  [[3 > 2 > 1], [false],
-   [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').  If chaining is really intended, parentheses will disable this warning (e.g. `(a < b) < c'.)]],
-
-  [[1 <= 2], [true]],
-  [[2.5 <= 1.5], [false]],
-  [[1 le 2], [true]],
-  [[2 <= 2], [true]],
-  [[2 le 2], [true]],
-dnl Make sure <= token can't be split:
-  [[2 < = 2], [error],
-   [error: DEBUG EVALUATE: Syntax error at `='.]],
-  [[1 <= 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric less-than-or-equal-to (`<=') operator: cannot convert string to number.]],
-  [[5 <= 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric less-than-or-equal-to (`<=') operator: cannot convert string to number.]],
-  [['baz' <= 10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string less-than-or-equal-to (`<=') operator: cannot convert number to string.]],
-  [['quux' <= 5.55], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string less-than-or-equal-to (`<=') operator: cannot convert number to string.]],
-  [['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]],
-  [[1 lt 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric less than (`<') operator: cannot convert string to number.]],
-  [[5 lt 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric less than (`<') operator: cannot convert string to number.]],
-  [['baz' < 10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string less than (`<') operator: cannot convert number to string.]],
-  [['quux' < 5.55], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string less than (`<') operator: cannot convert number to string.]],
-  [['0123' lt '0123'], [false]],
-  [['0123' < '0124'], [true]],
-  [['0124' lt '0123'], [false]],
-  [['0123  ' < '0123'], [false]],
-  [['0123' lt '0123  '], [false]])
-
-CHECK_EXPR_EVAL([>= > <>],
-  [[1 >= 2], [false]],
-  [[2.5 >= 1.5], [true]],
-  [[1 ge 2], [false]],
-  [[2 >= 2], [true]],
-  [[2 ge 2], [true]],
-dnl Make sure >= token can't be split:
-  [[2 > = 2], [error],
-   [error: DEBUG EVALUATE: Syntax error at `='.]],
-  [[1 >= 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric greater-than-or-equal-to (`>=') operator: cannot convert string to number.]],
-  [[5 ge 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric greater-than-or-equal-to (`>=') operator: cannot convert string to number.]],
-  [['baz' ge 10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string greater-than-or-equal-to (`>=') operator: cannot convert number to string.]],
-  [['quux' >= 5.55], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string greater-than-or-equal-to (`>=') operator: cannot convert number to string.]],
-  [['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]],
-  [[1 gt 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric greater than (`>') operator: cannot convert string to number.]],
-  [[5 gt 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric greater than (`>') operator: cannot convert string to number.]],
-  [['baz' > 10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string greater than (`>') operator: cannot convert number to string.]],
-  [['quux' > 5.55], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string greater than (`>') operator: cannot convert number to string.]],
-  [['0123' gt '0123'], [false]],
-  [['0123' > '0124'], [false]],
-  [['0124' gt '0123'], [true]],
-  [['0123  ' > '0123'], [false]],
-  [['0123' gt '0123  '], [false]],
-
-  [[1 ne 1], [false]],
-  [[1 ~= 1], [false]],
-  [[1 <> 2], [true]],
-  [[2 ne 3], [true]],
-  [[1 ~= 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric inequality (`<>') operator: cannot convert string to number.]],
-  [[5 <> 'foobar'], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying numeric inequality (`<>') operator: cannot convert string to number.]],
-  [['baz' ne 10], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string inequality (`<>') operator: cannot convert number to string.]],
-  [['quux' ~= 5.55], [error],
-   [error: DEBUG EVALUATE: Type mismatch while applying string inequality (`<>') operator: cannot convert number to string.]],
-  [['foobar' <> 'foobar'], [false]],
-  [['quux' ne 'bar'], [true]],
-  [['bar   ' <> 'bar'], [false]],
-  [['asdf         ' ~= 'asdf  '], [false]],
-  [['asdfj   ' ne 'asdf'], [true]],
-dnl <> token can't be split:
-  [[1 < > 1], [error],
-   [error: DEBUG EVALUATE: Syntax error at `>'.]],
-dnl # ~= token can't be split:
-  [[1 ~ = 1], [error],
-   [error: DEBUG EVALUATE: Syntax error at `~': expecting end of command.]])
-
-CHECK_EXPR_EVAL([exp lg10 ln sqrt abs mod mod10 rnd trunc],
-  [[exp(10)], [22026.47]],
-  [[exp('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking EXP(number) as exp(string).]],
-
-  [[lg10(500)], [2.70]],
-  [[lg10('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking LG10(number) as lg10(string).]],
-
-  [[ln(10)], [2.30]],
-  [[ln('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking LN(number) as ln(string).]],
-
-  [[sqrt(500)], [22.36]],
-  [[sqrt('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking SQRT(number) as sqrt(string).]],
-
-  [[abs(-10.5)], [10.50]],
-  [[abs(-55.79)], [55.79]],
-  [[abs(22)], [22.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]],
-  [[mod('a', 2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking MOD(number, number) as mod(string, number).]],
-  [[mod(2, 'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking MOD(number, number) as mod(number, string).]],
-  [[mod('a', 'b')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking MOD(number, number) as mod(string, string).]],
-
-  [[mod10(55.5)], [5.50]],
-  [[mod10(-55.5)], [-5.50]],
-  [[mod10('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking MOD10(number) as mod10(string).]],
-
-  [[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]],
-  [[rnd('x')], [error],
-   [error: DEBUG EVALUATE: Function invocation rnd(string) does not match any known function.  Candidates are:
-RND(number)
-RND(number, number)
-RND(number, number, number).]],
-
-  [[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]],
-  [[trunc('x')], [error],
-   [error: DEBUG EVALUATE: Function invocation trunc(string) does not match any known function.  Candidates are:
-TRUNC(number)
-TRUNC(number, number)
-TRUNC(number, number, number).]])
-
-CHECK_EXPR_EVAL([acos arsin artan cos sin tan],
-  [[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)], [sysmis]],
-  [[arcos(1.01)], [sysmis]],
-  [[acos('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking ACOS(number) as acos(string).]],
-
-  [[arsin(.5) / 3.14159 * 180], [30.00]],
-  [[asin(.25) / 3.14159 * 180], [14.48]],
-  [[arsin(-.5) / 3.14159 * 180], [-30.00]],
-  [[asin(-.25) / 3.14159 * 180], [-14.48]],
-  [[arsin(-1.01)], [sysmis]],
-  [[asin(1.01)], [sysmis]],
-  [[arsin('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking ARSIN(number) as arsin(string).]],
-
-  [[artan(1) / 3.14159 * 180], [45.00]],
-  [[atan(10) / 3.14159 * 180], [84.29]],
-  [[artan(-1) / 3.14159 * 180], [-45.00]],
-  [[atan(-10) / 3.14159 * 180], [-84.29]],
-  [[artan('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking ARTAN(number) as artan(string).]],
-
-  [[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]],
-  [[cos('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking COS(number) as cos(string).]],
-
-  [[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]],
-  [[sin('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking SIN(number) as sin(string).]],
-
-  [[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]],
-  [[tan('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking TAN(number) as tan(string).]])
-# FIXME: a variable name as the argument to SYSMIS is a special case
-# that we don't yet test.  We also can't test VALUE this way.
-CHECK_EXPR_EVAL([missing nmiss nvalid sysmis any range max min],
-  [[missing(10)], [false]],
-  [[missing($sysmis)], [true]],
-  [[missing(asin(1.01))], [true]],
-  [[missing(asin(.5))], [false]],
-  [[missing('    ')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking MISSING(number) as missing(string).]],
-
-  [[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]],
-
-  [[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]],
-
-  [[sysmis(10)], [false]],
-  [[sysmis($sysmis)], [true]],
-  [[sysmis(asin(1.01))], [true]],
-  [[sysmis(asin(.5))], [false]],
-  [[sysmis('    ')], [error],
-   [error: DEBUG EVALUATE: Function invocation sysmis(string) does not match any known function.  Candidates are:
-SYSMIS(num_variable)
-SYSMIS(number).]],
-
-  [[any($sysmis, 1, $sysmis, 3)], [sysmis]],
-  [[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(1, $sysmis, $sysmis, $sysmis)], [sysmis]],
-  [[any($sysmis, $sysmis, $sysmis, $sysmis)], [sysmis]],
-  [[any(1)], [error],
-   [error: DEBUG EVALUATE: Function invocation any(number) does not match any known function.  Candidates are:
-ANY(number, number[, number]...)
-ANY(string, string[, string]...).]],
-  [[any('1', 2, 3, 4)], [error],
-   [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]...).]],
-  [[any(1, '2', 3, 4)], [error],
-   [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]...).]],
-  [[any(1, 2, '3', 4)], [error],
-   [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]...).]],
-  [[any(1, 2, 3, '4')], [error],
-   [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]...).]],
-
-  [[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]],
-  [[any('a')], [error],
-   [error: DEBUG EVALUATE: Function invocation any(string) does not match any known function.  Candidates are:
-ANY(number, number[, number]...)
-ANY(string, string[, string]...).]],
-  [[any('a', 'a  ', 'b', 'c')], [true]],
-  [[any('b   ', 'a', 'b', 'c')], [true]],
-  [[any('c   ', 'a', 'b', 'c     ')], [true]],
-  [[any(a10, 'b', 'c', 'd')], [error],
-   [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]...).]],
-  [[any('a', b, 'c', 'd')], [error],
-   [error: DEBUG EVALUATE: Unknown identifier b.]],
-  [[any('a', 'b', c, 'd')], [error],
-   [error: DEBUG EVALUATE: Unknown identifier c.]],
-  [[any('a', 'b', 'c', d)], [error],
-   [error: DEBUG EVALUATE: Unknown identifier d.]],
-
-  [[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($sysmis, 1, 10)], [sysmis]],
-  [[range(5, 1, $sysmis)], [sysmis]],
-  [[range(5, $sysmis, 10)], [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]],
-  [[range(1)], [error],
-   [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]...).]],
-  [[range(1, 2)], [error],
-   [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an odd number of arguments.]],
-  [[range(1, 2, 3, 4)], [error],
-   [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an odd number of arguments.]],
-  [[range(1, 2, 3, 4, 5, 6)], [error],
-   [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an odd number of arguments.]],
-  [[range('1', 2, 3)], [error],
-   [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]...).]],
-  [[range(1, '2', 3)], [error],
-   [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]...).]],
-  [[range(1, 2, '3')], [error],
-   [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]...).]],
-
-  [[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('1')], [error],
-   [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]...).]],
-  [[range('1', '2')], [error],
-   [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have an odd number of arguments.]],
-  [[range('1', '2', '3', '4')], [error],
-   [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have an odd number of arguments.]],
-  [[range('1', '2', '3', '4', '5', '6')], [error],
-   [error: DEBUG EVALUATE: RANGE(string, string, string[, string, string]...) must have an odd number of arguments.]],
-  [[range(1, '2', '3')], [error],
-   [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]...).]],
-  [[range('1', 2, '3')], [error],
-   [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]...).]],
-  [[range('1', '2', 3)], [error],
-   [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]...).]],
+datediff(date.mdy(10,7,43), date.mdy(3,17,92), 'months') => -581.00
 
-  [[max(1, 2, 3, 4, 5)], [5.00]],
-  [[max(1, $sysmis, 2, 3, $sysmis, 4, 5)], [5.00]],
-  [[max(1, 2)], [2.00]],
-  [[max()], [error],
-   [error: DEBUG EVALUATE: Function invocation max() does not match any known function.  Candidates are:
-MAX(number[, number]...)
-MAX(string[, string]...).]],
-  [[max(1)], [1.00]],
-  [[max(1, $sysmis)], [1.00]],
-  [[max(1, 2, 3, $sysmis)], [3.00]],
-  [[max.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[max.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For MAX(number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-
-  [[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]],
-  [[min()], [error],
-   [error: DEBUG EVALUATE: Function invocation min() does not match any known function.  Candidates are:
-MIN(number[, number]...)
-MIN(string[, string]...).]],
-  [[min(1)], [1.00]],
-  [[min(1, $sysmis)], [1.00]],
-  [[min(1, 2, 3, $sysmis)], [1.00]],
-  [[min.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[min.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For MIN(number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-
-  [[min("2", "3", "5", "1", "4")], ["1"]],
-  [[min("1", "2")], ["1"]],
-  [[min("1")], ["1"]])
-
-CHECK_EXPR_EVAL([cfvar mean median sd sum variance],
-  [[cfvar(1, 2, 3, 4, 5)], [0.53]],
-  [[cfvar(1, $sysmis, 2, 3, $sysmis, 4, 5)], [0.53]],
-  [[cfvar(1, 2)], [0.47]],
-  [[cfvar(1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CFVAR(number, number[, number]...) as cfvar(number).]],
-  [[cfvar(1, $sysmis)], [sysmis]],
-  [[cfvar(1, 2, 3, $sysmis)], [0.50]],
-  [[cfvar.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[cfvar.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For CFVAR(number, number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-  [[cfvar('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CFVAR(number, number[, number]...) as cfvar(string).]],
-  [[cfvar('x', 1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CFVAR(number, number[, number]...) as cfvar(string, number, number, number).]],
-
-  [[mean(1, 2, 3, 4, 5)], [3.00]],
-  [[mean(1, $sysmis, 2, 3, $sysmis, 4, 5)], [3.00]],
-  [[mean(1, 2)], [1.50]],
-  [[mean()], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking MEAN(number[, number]...) as mean().]],
-  [[mean(1)], [1.00]],
-  [[mean(1, $sysmis)], [1.00]],
-  [[mean(1, 2, 3, $sysmis)], [2.00]],
-  [[mean.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[mean.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For MEAN(number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-
-  [[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]],
-
-  [[sd(1, 2, 3, 4, 5)], [1.58]],
-  [[sd(1, $sysmis, 2, 3, $sysmis, 4, 5)], [1.58]],
-  [[sd(1, 2)], [0.71]],
-  [[sd(1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking SD(number, number[, number]...) as sd(number).]],
-  [[sd(1, $sysmis)], [sysmis]],
-  [[sd(1, 2, 3, $sysmis)], [1.00]],
-  [[sd.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[sd.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For SD(number, number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-  [[sd('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking SD(number, number[, number]...) as sd(string).]],
-  [[sd('x', 1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking SD(number, number[, number]...) as sd(string, number, number, number).]],
-
-  [[sum(1, 2, 3, 4, 5)], [15.00]],
-  [[sum(1, $sysmis, 2, 3, $sysmis, 4, 5)], [15.00]],
-  [[sum(1, 2)], [3.00]],
-  [[sum()], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking SUM(number[, number]...) as sum().]],
-  [[sum(1)], [1.00]],
-  [[sum(1, $sysmis)], [1.00]],
-  [[sum(1, 2, 3, $sysmis)], [6.00]],
-  [[sum.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[sum.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For SUM(number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-
-  [[variance(1, 2, 3, 4, 5)], [2.50]],
-  [[variance(1, $sysmis, 2, 3, $sysmis, 4, 5)], [2.50]],
-  [[variance(1, 2)], [0.50]],
-  [[variance(1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking VARIANCE(number, number[, number]...) as variance(number).]],
-  [[variance(1, $sysmis)], [sysmis]],
-  [[variance(1, 2, 3, $sysmis)], [1.00]],
-  [[variance.4(1, 2, 3, $sysmis)], [sysmis]],
-  [[variance.4(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: For VARIANCE(number, number[, number]...) with 3 arguments, at most 3 (not 4) may be required to be valid.]],
-  [[variance('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking VARIANCE(number, number[, number]...) as variance(string).]],
-  [[variance('x', 1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking VARIANCE(number, number[, number]...) as variance(string, number, number, number).]])
-
-CHECK_EXPR_EVAL([concat index rindex length lower],
-  [[concat('')], [""]],
-  [[concat('a', 'b')], ["ab"]],
-  [[concat('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')], ["abcdefgh"]],
-  [[concat('abcdefgh', 'ijklmnopq')], ["abcdefghijklmnopq"]],
-  [[concat('a', 1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CONCAT(string[, string]...) as concat(string, number).]],
-  [[concat(1, 2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CONCAT(string[, string]...) as concat(number, number).]],
-
-  [[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('', '')], [sysmis]],
-  [[index('abcdefgh', '')], [sysmis]],
-  [[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]],
-
-  [[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('', '')], [sysmis]],
-  [[rindex('abcdefgh', '')], [sysmis]],
-  [[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]],
-  [[rindex('abcbcde', 'bcbc', 0)], [sysmis]],
-  [[rindex('abcbcde', 'bcbc', $sysmis)], [sysmis]],
-  [[rindex('abcbcde', 'bcbcg', 2)], [sysmis]],
-  [[rindex('abcbcde', 'bcbcg', $sysmis)], [sysmis]],
-  [[rindex('abcbcde', 'bcbcg', 'x')], [error],
-   [error: DEBUG EVALUATE: Function invocation rindex(string, string, string) does not match any known function.  Candidates are:
-RINDEX(string, string)
-RINDEX(string, string, number).]],
-  [[rindex(1, 'bcdfkjl', 2)], [error],
-   [error: DEBUG EVALUATE: Function invocation rindex(number, string, number) does not match any known function.  Candidates are:
-RINDEX(string, string)
-RINDEX(string, string, number).]],
-  [[rindex('aksj', 2, 2)], [error],
-   [error: DEBUG EVALUATE: Function invocation rindex(string, number, number) does not match any known function.  Candidates are:
-RINDEX(string, string)
-RINDEX(string, string, number).]],
-  [[rindex(1, 2, 3)], [error],
-   [error: DEBUG EVALUATE: Function invocation rindex(number, number, number) does not match any known function.  Candidates are:
-RINDEX(string, string)
-RINDEX(string, string, number).]],
-  [[rindex(1, 2, '3')], [error],
-   [error: DEBUG EVALUATE: Function invocation rindex(number, number, string) does not match any known function.  Candidates are:
-RINDEX(string, string)
-RINDEX(string, string, number).]],
-
-  [[length('')], [0.00]],
-  [[length('a')], [1.00]],
-  [[length('xy')], [2.00]],
-  [[length('adsf    ')], [8.00]],
-  [[length('abcdefghijkl')], [12.00]],
-  [[length(0)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking LENGTH(string) as length(number).]],
-  [[length($sysmis)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking LENGTH(string) as length(number).]],
-
-  [[lower('ABCDEFGHIJKLMNOPQRSTUVWXYZ!@%&*089')], ["abcdefghijklmnopqrstuvwxyz!@%&*089"]],
-  [[lower('')], [""]],
-  [[lower(1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking LOWER(string) as lower(number).]])
-
-CHECK_EXPR_EVAL([replace],
-  [[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"]],
-  [[replace('banana', 'an', 'xyzzy', 1.5)], ["bxyzzyana"]],
-  [[replace('banana', 'bananana', 'xyzzy')], ["banana"]],
-  [[replace('banana', '', 'xyzzy')], ["banana"]],
-  [[replace('banana', 'ba', '', 0)], ["banana"]],
-  [[replace('banana', 'ba', '', -1)], ["banana"]],
-  [[replace('banana', 'ba', '', $sysmis)], ["banana"]])
-
-CHECK_EXPR_EVAL([lpad number ltrim lpad rtrim rpad string strunc substr upcase],
-  [[lpad('abc', -1)], [""]],
-  [[lpad('abc', 0)], ["abc"]],
-  [[lpad('abc', 2)], ["abc"]],
-  [[lpad('abc', 3)], ["abc"]],
-  [[lpad('abc', 10)], ["       abc"]],
-  [[lpad('abc', 32768)], [""]],
-  [[lpad('abc', $sysmis)], [""]],
-  [[lpad('abc', -1, '*')], [""]],
-  [[lpad('abc', 0, '*')], ["abc"]],
-  [[lpad('abc', 2, '*')], ["abc"]],
-  [[lpad('abc', 3, '*')], ["abc"]],
-  [[lpad('abc', 10, '*')], ["*******abc"]],
-  [[lpad('abc', 32768, '*')], [""]],
-  [[lpad('abc', $sysmis, '*')], [""]],
-  [[lpad('abc', $sysmis, '')], [""]],
-  [[lpad('abc', $sysmis, 'xy')], [""]],
-  [[lpad(0, 10)], [error],
-   [error: DEBUG EVALUATE: Function invocation lpad(number, number) does not match any known function.  Candidates are:
-LPAD(string, number)
-LPAD(string, number, string).]],
-  [[lpad('abc', 'def')], [error],
-   [error: DEBUG EVALUATE: Function invocation lpad(string, string) does not match any known function.  Candidates are:
-LPAD(string, number)
-LPAD(string, number, string).]],
-  [[lpad(0, 10, ' ')], [error],
-   [error: DEBUG EVALUATE: Function invocation lpad(number, number, string) does not match any known function.  Candidates are:
-LPAD(string, number)
-LPAD(string, number, string).]],
-  [[lpad('abc', 'def', ' ')], [error],
-   [error: DEBUG EVALUATE: Function invocation lpad(string, string, string) does not match any known function.  Candidates are:
-LPAD(string, number)
-LPAD(string, number, string).]],
-  [[lpad('x', 5, 0)], [error],
-   [error: DEBUG EVALUATE: Function invocation lpad(string, number, number) does not match any known function.  Candidates are:
-LPAD(string, number)
-LPAD(string, number, string).]],
-  [[lpad('x', 5, 2)], [error],
-   [error: DEBUG EVALUATE: Function invocation lpad(string, number, number) does not match any known function.  Candidates are:
-LPAD(string, number)
-LPAD(string, number, string).]],
-
-  [[number("123", f3.0)], [123.00]],
-  [[number(" 123", f3.0)], [12.00]],
-  [[number("123", f3.1)], [12.30]],
-  [[number("   ", f3.1)], [sysmis]],
-  [[number("123", a8)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking NUMBER(string, num_input_format) as number(string, format).]],
-dnl CCA is not an input format:
-  [[number("123", cca1.2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking NUMBER(string, num_input_format) as number(string, format).]],
-
-  [[ltrim('   abc')], ["abc"]],
-  [[rtrim('   abc   ')], ["   abc"]],
-  [[ltrim('abc')], ["abc"]],
-  [[ltrim('    abc')], ["      abc"]],
-  [[ltrim('    ')], [""]],
-  [[ltrim('')], [""]],
-  [[ltrim(8)], [error],
-   [error: DEBUG EVALUATE: Function invocation ltrim(number) does not match any known function.  Candidates are:
-LTRIM(string)
-LTRIM(string, string).]],
-  [[ltrim('***abc', '*')], ["abc"]],
-  [[ltrim('abc', '*')], ["abc"]],
-  [[ltrim('*abc', '*')], ["abc"]],
-  [[ltrim('', '*')], [""]],
-  [[ltrim(8, '*')], [error],
-   [error: DEBUG EVALUATE: Function invocation ltrim(number, string) does not match any known function.  Candidates are:
-LTRIM(string)
-LTRIM(string, string).]],
-  [[ltrim(' x', 8)], [error],
-   [error: DEBUG EVALUATE: Function invocation ltrim(string, number) does not match any known function.  Candidates are:
-LTRIM(string)
-LTRIM(string, string).]],
-  [[ltrim(8, 9)], [error],
-   [error: DEBUG EVALUATE: Function invocation ltrim(number, number) does not match any known function.  Candidates are:
-LTRIM(string)
-LTRIM(string, string).]],
-
-  [[rpad('abc', -1)], [""]],
-  [[rpad('abc', 0)], ["abc"]],
-  [[rpad('abc', 2)], ["abc"]],
-  [[rpad('abc', 3)], ["abc"]],
-  [[rpad('abc', 10)], ["abc       "]],
-  [[rpad('abc', 32768)], [""]],
-  [[rpad('abc', $sysmis)], [""]],
-  [[rpad('abc', -1, '*')], [""]],
-  [[rpad('abc', 0, '*')], ["abc"]],
-  [[rpad('abc', 2, '*')], ["abc"]],
-  [[rpad('abc', 3, '*')], ["abc"]],
-  [[rpad('abc', 10, '*')], ["abc*******"]],
-  [[rpad('abc', 32768, '*')], [""]],
-  [[rpad('abc', $sysmis, '*')], [""]],
-  [[rpad('abc', $sysmis, '')], [""]],
-  [[rpad('abc', $sysmis, 'xy')], [""]],
-  [[rpad(0, 10)], [error],
-   [error: DEBUG EVALUATE: Function invocation rpad(number, number) does not match any known function.  Candidates are:
-RPAD(string, number)
-RPAD(string, number, string).]],
-  [[rpad('abc', 'def')], [error],
-   [error: DEBUG EVALUATE: Function invocation rpad(string, string) does not match any known function.  Candidates are:
-RPAD(string, number)
-RPAD(string, number, string).]],
-  [[rpad(0, 10, ' ')], [error],
-   [error: DEBUG EVALUATE: Function invocation rpad(number, number, string) does not match any known function.  Candidates are:
-RPAD(string, number)
-RPAD(string, number, string).]],
-  [[rpad('abc', 'def', ' ')], [error],
-   [error: DEBUG EVALUATE: Function invocation rpad(string, string, string) does not match any known function.  Candidates are:
-RPAD(string, number)
-RPAD(string, number, string).]],
-  [[rpad('x', 5, 0)], [error],
-   [error: DEBUG EVALUATE: Function invocation rpad(string, number, number) does not match any known function.  Candidates are:
-RPAD(string, number)
-RPAD(string, number, string).]],
-  [[rpad('x', 5, 2)], [error],
-   [error: DEBUG EVALUATE: Function invocation rpad(string, number, number) does not match any known function.  Candidates are:
-RPAD(string, number)
-RPAD(string, number, string).]],
-
-  [[rtrim('abc   ')], ["abc"]],
-  [[rtrim('   abc   ')], ["   abc"]],
-  [[rtrim('abc')], ["abc"]],
-  [[rtrim('abc ')], ["abc      "]],
-  [[rtrim('    ')], [""]],
-  [[rtrim('')], [""]],
-  [[rtrim(8)], [error],
-   [error: DEBUG EVALUATE: Function invocation rtrim(number) does not match any known function.  Candidates are:
-RTRIM(string)
-RTRIM(string, string).]],
-  [[rtrim('abc***', '*')], ["abc"]],
-  [[rtrim('abc', '*')], ["abc"]],
-  [[rtrim('abc*', '*')], ["abc"]],
-  [[rtrim('', '*')], [""]],
-  [[rtrim(8, '*')], [error],
-   [error: DEBUG EVALUATE: Function invocation rtrim(number, string) does not match any known function.  Candidates are:
-RTRIM(string)
-RTRIM(string, string).]],
-  [[rtrim(' x', 8)], [error],
-   [error: DEBUG EVALUATE: Function invocation rtrim(string, number) does not match any known function.  Candidates are:
-RTRIM(string)
-RTRIM(string, string).]],
-  [[rtrim(8, 9)], [error],
-   [error: DEBUG EVALUATE: Function invocation rtrim(number, number) does not match any known function.  Candidates are:
-RTRIM(string)
-RTRIM(string, string).]],
+datediff(date.mdy(3,17,92), date.mdy(2,25,96), 'months') => -47.00
 
-  [[string(123.56, f5.1)], ["123.6"]],
-  [[string($sysmis, f5.1)], ["   . "]],
-  [[string("abc", A5)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking STRING(number, num_output_format) as string(string, format).]],
-dnl E has a minimum width of 6 on output:
-  [[string(123, e1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking STRING(number, num_output_format) as string(number, format).]],
-  [[string(123, e6.0)], ["1E+002"]],
-
-  [[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)], [""]],
-  [[strunc('a c   ', -1)], [""]],
-  [[strunc('a c   ', $sysmis)], [""]],
-  [[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)], [""]],
-  [[strunc('  abc  ', -1)], [""]],
-  [[strunc('  abc  ', $sysmis)], [""]],
-
-  [[substr('abcdefgh', -5)], [""]],
-  [[substr('abcdefgh', 0)], [""]],
-  [[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(0, 10)], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(number, number) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr('abcd', 'abc')], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(string, string) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr(0, 'abc')], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(number, string) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-
-  [[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)], [""]],
-  [[substr('abc', 1, 'x')], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(string, number, string) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr(0, 10, 1)], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(number, number, number) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr(0, 10, 'x')], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(number, number, string) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr('abcd', 'abc', 0)], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(string, string, number) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr('abcd', 'abc', 'j')], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(string, string, string) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr(0, 'abc', 4)], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(number, string, number) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-  [[substr(0, 'abc', 'k')], [error],
-   [error: DEBUG EVALUATE: Function invocation substr(number, string, string) does not match any known function.  Candidates are:
-SUBSTR(string, number)
-SUBSTR(string, number, number).]],
-
-  [[upcase('abcdefghijklmnopqrstuvwxyz!@%&*089')], ["ABCDEFGHIJKLMNOPQRSTUVWXYZ!@%&*089"]],
-  [[upcase('')], [""]],
-  [[upcase(1)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking UPCASE(string) as upcase(number).]])
-
-CHECK_EXPR_EVAL([time ctime date yrmoda],
-  [[time.days(1)], [86400.00]],
-  [[time.days(-1)], [-86400.00]],
-  [[time.days(0.5)], [43200.00]],
-  [[time.days('x')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking TIME.DAYS(number) as time.days(string).]],
-  [[time.days($sysmis)], [sysmis]],
-
-  [[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]],
-  [[time.hms(-5, 6, -7)], [sysmis],
-   [warning: DEBUG EVALUATE: TIME.HMS cannot mix positive and negative arguments.]],
-  [[time.hms(-5, 5, -7)], [sysmis],
-   [warning: DEBUG EVALUATE: TIME.HMS cannot mix positive and negative arguments.]],
-  [[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]],
-
-  [[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]],
-  [[ctime.days('a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CTIME.DAYS(number) as ctime.days(string).]],
-  [[ctime.hours('b')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CTIME.HOURS(number) as ctime.hours(string).]],
-  [[ctime.minutes('c')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CTIME.MINUTES(number) as ctime.minutes(string).]],
-  [[ctime.seconds('d')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking CTIME.SECONDS(number) as ctime.seconds(string).]],
-
-  [[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]],
-  [[ctime.days(date.dmy(32,10,1978))], [sysmis],
-   [error: DEBUG EVALUATE: Day 32 is not in acceptable range of 0 to 31.]],
-  [[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]],
-  [[date.dmy('a',1,2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.DMY(number, number, number) as date.dmy(string, number, number).]],
-  [[date.dmy(1,'a',2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.DMY(number, number, number) as date.dmy(number, string, number).]],
-  [[date.dmy(1,2,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.DMY(number, number, number) as date.dmy(number, number, string).]],
-dnl FIXME: check out-of-range and nearly out-of-range values
-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]],
-  [[yrmoda(1978,10,32)], [sysmis],
-   [error: DEBUG EVALUATE: Day 32 is not in acceptable range of 0 to 31.]],
-  [[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]],
-  [[yrmoda('a',1,2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking YRMODA(number, number, number) as yrmoda(string, number, number).]],
-  [[yrmoda(1,'a',2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking YRMODA(number, number, number) as yrmoda(number, string, number).]],
-  [[yrmoda(1,2,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking YRMODA(number, number, number) as yrmoda(number, number, string).]],
-dnl FIXME: check out-of-range and nearly out-of-range values
-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]],
-dnl FIXME: check out-of-range and nearly out-of-range values
-dnl
-  [[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]],
-  [[ctime.days(date.mdy(10,32,1978))], [sysmis],
-   [error: DEBUG EVALUATE: Day 32 is not in acceptable range of 0 to 31.]],
-  [[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]],
-  [[date.mdy('a',1,2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.MDY(number, number, number) as date.mdy(string, number, number).]],
-  [[date.mdy(1,'a',2)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.MDY(number, number, number) as date.mdy(number, string, number).]],
-  [[date.mdy(1,2,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.MDY(number, number, number) as date.mdy(number, number, string).]],
-  [[ctime.days(date.mdy(0,0,0))], [152353.00]],
-  [[ctime.days(date.mdy(0,0,999))], [sysmis],
-   [error: DEBUG EVALUATE: Date 0998-12-0 is before the earliest acceptable date of 1582-10-15.]],
-  [[date.mdy(1,1,1582)], [sysmis],
-   [error: DEBUG EVALUATE: Date 1582-1-1 is before the earliest acceptable date of 1582-10-15.]],
-  [[date.mdy(10,14,1582)], [sysmis],
-   [error: DEBUG EVALUATE: Date 1582-10-14 is before the earliest acceptable date of 1582-10-15.]],
-  [[date.mdy(10,15,1582)], [86400.00]],
-
-  [[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]],
-  [[ctime.days(date.moyr(14,2000))], [sysmis],
-   [error: DEBUG EVALUATE: Month 14 is not in acceptable range of 0 to 13.]],
-  [[ctime.days(date.moyr($sysmis,2000))], [sysmis]],
-  [[ctime.days(date.moyr(1,$sysmis))], [sysmis]],
-  [[ctime.days(date.moyr($sysmis,$sysmis))], [sysmis]],
-  [[date.moyr('a',2000)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.MOYR(number, number) as date.moyr(string, number).]],
-  [[date.moyr(5,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.MOYR(number, number) as date.moyr(number, string).]],
-  [[date.moyr('a','b')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.MOYR(number, number) as date.moyr(string, string).]],
-
-  [[ctime.days(date.qyr(1,2000))], [152385.00]],
-  [[ctime.days(date.qyr(2,2000))], [152476.00]],
-  [[ctime.days(date.qyr(5,2000))], [sysmis],
-   [warning: DEBUG EVALUATE: The first argument to DATE.QYR must be 1, 2, 3, or 4.]],
-  [[ctime.days(date.qyr(6,2000))], [sysmis],
-   [warning: DEBUG EVALUATE: The first argument to DATE.QYR must be 1, 2, 3, or 4.]],
-  [[ctime.days(date.qyr($sysmis,2000))], [sysmis]],
-  [[ctime.days(date.qyr(1,$sysmis))], [sysmis]],
-  [[ctime.days(date.qyr($sysmis,$sysmis))], [sysmis]],
-  [[date.qyr('a',2000)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.QYR(number, number) as date.qyr(string, number).]],
-  [[date.qyr(5,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.QYR(number, number) as date.qyr(number, string).]],
-  [[date.qyr('a','b')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.QYR(number, number) as date.qyr(string, string).]],
-
-  [[ctime.days(date.wkyr(1,2000))], [152385.00]],
-  [[ctime.days(date.wkyr(15,1999))], [152118.00]],
-  [[ctime.days(date.wkyr(36,1999))], [152265.00]],
-  [[ctime.days(date.wkyr(54,1999))], [sysmis],
-   [error: DEBUG EVALUATE: The week argument to DATE.WKYR is outside the acceptable range of 1 to 53.  The result will be system-missing.]],
-  [[ctime.days(date.wkyr($sysmis,1999))], [sysmis]],
-  [[ctime.days(date.wkyr(1,$sysmis))], [sysmis]],
-  [[ctime.days(date.wkyr($sysmis,$sysmis))], [sysmis]],
-  [[date.wkyr('a',1999)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.WKYR(number, number) as date.wkyr(string, number).]],
-  [[date.wkyr(5,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.WKYR(number, number) as date.wkyr(number, string).]],
-  [[date.wkyr('a','b')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.WKYR(number, number) as date.wkyr(string, string).]],
-
-  [[ctime.days(date.yrday(2000,1))], [152385.00]],
-  [[ctime.days(date.yrday(2000,100))], [152484.00]],
-  [[ctime.days(date.yrday(2000,253))], [152637.00]],
-  [[ctime.days(date.yrday(2000,500))], [sysmis],
-   [error: DEBUG EVALUATE: The day argument to DATE.YRDAY is outside the acceptable range of 1 to 366.  The result will be system-missing.]],
-  [[ctime.days(date.yrday(2000,-100))], [sysmis],
-   [error: DEBUG EVALUATE: The day argument to DATE.YRDAY is outside the acceptable range of 1 to 366.  The result will be system-missing.]],
-  [[ctime.days(date.yrday(1999,$sysmis))], [sysmis]],
-  [[ctime.days(date.yrday($sysmis,1))], [sysmis]],
-  [[ctime.days(date.yrday($sysmis,$sysmis))], [sysmis]],
-  [[date.yrday(1999,'a')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.YRDAY(number, number) as date.yrday(number, string).]],
-  [[date.yrday('a',5)], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.YRDAY(number, number) as date.yrday(string, number).]],
-  [[date.yrday('a','b')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking DATE.YRDAY(number, number) as date.yrday(string, string).]])
-
-CHECK_EXPR_EVAL([xdate],
-  [[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]],
-  [[xdate.date('')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking XDATE.DATE(number) as xdate.date(string).]],
-
-  [[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]],
-  [[xdate.hour('')], [error],
-   [error: DEBUG EVALUATE: Type mismatch invoking XDATE.HOUR(number) as xdate.hour(string).]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]])
-
-CHECK_EXPR_EVAL([datediff],
-  [[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,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,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,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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
-
-  [[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]],
+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
-  [[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]])
-
-CHECK_EXPR_EVAL([datesum],
-dnl DATESUM with non-leap year
-  [[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]],
-
-dnl DATESUM with leap year
-  [[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]],
-
-  [[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]],
-
-dnl DATESUM preserves time-of-day for units of days and longer.
-  [[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]])
-
-CHECK_EXPR_EVAL([miscellaneous],
+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.
-  [[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]],
+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)]],
-  [[SYSMIS(1)], [false]],
-  [[SYSMIS($SYSMIS)], [true]],
-  [[SYSMIS(1 + $SYSMIS)], [true]],
 
 dnl FIXME: out-of-range and nearly out-of-range values on dates
 dnl
 dnl Tests correctness of generic optimizations in optimize_tree().
-  [[x + 0], [10.00], [], [(X = 10.00)]],
-  [[x - 0], [-3.00], [], [(X = -3.00)]],
-  [[0 + x], [5.00], [], [(X = 5.00)]],
-  [[x * 1], [10.00], [], [(X = 10.00)]],
-  [[1 * x], [-3.00], [], [(X = -3.00)]],
-  [[x / 1], [5.00], [], [(X = 5.00)]],
-  [[0 * x], [0.00], [], [(X = 10.00)]],
-  [[x * 0], [0.00], [], [(X = -3.00)]],
-  [[0 / x], [0.00], [], [(X = 5.00)]],
-  [[mod(0, x)], [0.00], [], [(X = 5.00)]],
-  [[x ** 1], [5.00], [], [(X = 5.00)]],
-  [[x ** 2], [25.00], [], [(X = 5.00)]])
-
-CHECK_EXPR_EVAL([negative checks],
-  [[$nonexistent], [error], [error: DEBUG EVALUATE: Unknown system variable $nonexistent.]],
-  [[RANGE(1, 2)], [error], [error: DEBUG EVALUATE: RANGE(number, number, number[, number, number]...) must have an odd number of arguments.]],
-  [[CONCAT.1('a', 'b')], [error], [error: DEBUG EVALUATE: CONCAT(string[, string]...) function cannot accept suffix .1 to specify the minimum number of valid arguments.]],
-  [[foobar(x)], [error], [error: DEBUG EVALUATE: No function or vector named foobar.]],
-  [[CONCAT.1('a' b)], [error], [error: DEBUG EVALUATE: Syntax error at `b': expecting `,' or `)'.]],
-  [[NCDF.CHISQ(1, 2, 3)], [error], [error: DEBUG EVALUATE: NCDF.CHISQ(number, number, number) is not available in this version of PSPP.]])
-
-AT_SETUP([LAG function])
+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.
@@ -2037,7 +7594,7 @@ W,X,Y,Z
 ])
 AT_CLEANUP
 
-AT_SETUP([LAG crash bug])
+AT_SETUP([expression - LAG crash])
 AT_DATA([lag.sps], [dnl
 DATA LIST LIST /x.
 BEGIN DATA
@@ -2062,7 +7619,7 @@ hello
 AT_CLEANUP
 
 dnl Tests for a bug which caused UNIFORM(x) to always return zero.
-AT_SETUP([UNIFORM function])
+AT_SETUP([expressions - UNIFORM])
 AT_DATA([uniform.sps], [dnl
 set seed=10.
 input program.
@@ -2104,7 +7661,7 @@ R1
 ])
 AT_CLEANUP
 
-AT_SETUP([VALUELABEL function])
+AT_SETUP([expressions - VALUELABEL])
 AT_DATA([valuelabel.sps], [dnl
 DATA LIST notable /n 1 s 2(a).
 VALUE LABELS /n 0 'Very dissatisfied'
@@ -2148,7 +7705,7 @@ n,s,nlabel,slabel
 ])
 AT_CLEANUP
 
-AT_SETUP([variables in expressions])
+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).
@@ -2197,7 +7754,7 @@ 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
 ])
 AT_CLEANUP
 
-AT_SETUP([vectors in expressions])
+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).