test.c (28587B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <assert.h> 3 #include <stdio.h> 4 #include <stdarg.h> 5 #include <string.h> 6 #include <unistd.h> 7 8 #include "tisp.h" 9 #include "tibs.tsp.h" 10 11 tsp_include_tib(math); 12 tsp_include_tib(string); 13 14 #define LEN(X) (sizeof(X) / sizeof((X)[0])) 15 16 char *tests[][2] = { 17 18 { "self", NULL }, 19 { "1", "1" }, 20 { "2", "2" }, 21 { "0", "0" }, 22 { "30", "30" }, 23 { "12", "12" }, 24 { "-4", "-4" }, 25 { "-083", "-83" }, 26 { "-0", "0" }, 27 { "+4", "4" }, 28 { "+123", "123" }, 29 { "12.0", "12.0" }, 30 { "08", "8" }, 31 { "+12.34", "12.34" }, 32 { ".34", "0.34" }, 33 { "2.", "2.0" }, 34 { "1e0", "1" }, 35 { "1E+0", "1" }, 36 { "1e-0", "1" }, 37 { "1E4", "10000" }, 38 { ".1e-4", "1e-05" }, 39 { "-5.0e006", "-5000000.0" }, 40 { "-5.E+16", "-5e+16" }, 41 { "-.05", "-0.05" }, 42 { "-.0", "-0.0" }, 43 { "-1.e6", "-1000000.0" }, 44 { "3/4", "3/4" }, 45 { "4/3", "4/3" }, 46 { "+1/2", "1/2" }, 47 { "2/1", "2" }, 48 { "8/+1", "8" }, 49 { "8/4", "2" }, 50 { "4/8", "1/2" }, 51 { "02384/7238", "1192/3619" }, 52 { "-1/2", "-1/2" }, 53 { "1/-2", "-1/2" }, 54 { "-6/3", "-2" }, 55 { "-6/-3", "2" }, 56 { "\"foo\"", "foo" }, 57 { "\"foo bar\"", "foo bar" }, 58 { "True", "True" }, 59 { "()", "Nil" }, 60 { "Nil", "Nil" }, 61 62 { "comments", NULL }, 63 { "; commment", "Void" }, 64 { "; (+ 1 1)", "Void" }, 65 { "(+ 1 ; more comments\n1)", "2" }, 66 67 { "whitespace", NULL }, 68 { "\t \n \n\n\t\n \t\n", "Void" }, 69 { "\t \t(+ \t\t5 \n \n5 \n\t)", "10" }, 70 71 { "quote", NULL }, 72 { "(quote 1)", "1" }, 73 { "(quote 9234)", "9234" }, 74 { "(quote \"foo\")", "foo" }, 75 { "(quote bar)", "bar" }, 76 { "(quote (1 2 3 4))", "(1 2 3 4)" }, 77 { "(quote (quote 1))", "(quote 1)" }, 78 { "(quote (+ 2 2))", "(+ 2 2)" }, 79 { "'12", "12" }, 80 { "'foo", "foo" }, 81 { "'(1 2 3 4)", "(1 2 3 4)" }, 82 83 { "cons", NULL }, 84 { "(cons 1 2)", "(1 . 2)" }, 85 { "(cons 1 (cons 2 3))", "(1 2 . 3)" }, 86 { "(cons 1 (cons 2 (cons 3 4)))", "(1 2 3 . 4)" }, 87 { "(cons \"foo\" \"bar\")", "(foo . bar)" }, 88 { "(cons (+ 1 2) 3)", "(3 . 3)" }, 89 { "(cons (cons 1 2) (cons 3 4))", "((1 . 2) 3 . 4)" }, 90 91 { "cxr", NULL }, 92 { "(car (cons 1 2))", "1" }, 93 { "(cdr (cons 1 2))", "2" }, 94 { "(car (quote (1 2 3 4)))", "1" }, 95 { "(car (cdr (quote (1 2 3 4))))", "2" }, 96 { "(car (cdr (cdr (quote (1 2 3 4)))))", "3" }, 97 { "(car (cdr (cdr (cdr (quote (1 2 3 4))))))", "4" }, 98 { "(cdr (quote (1 2 3 4)))", "(2 3 4)" }, 99 { "(cdr (cdr (quote (1 2 3 4))))", "(3 4)" }, 100 { "(car (cons 1 (cons 2 3)))", "1" }, 101 { "(cdr (cons 1 (cons 2 3)))", "(2 . 3)" }, 102 { "(cdr (cdr (cons 1 (cons 2 3))))", "3" }, 103 104 { "void", NULL }, 105 { "Void", "Void" }, 106 107 { "do", NULL }, 108 { "(do (+ 1 2) (+ 2 2))", "4" }, 109 { "(do (+ -4 8) (- 1 2) (* 80 0) (+ 39 -3))", "36" }, 110 { "(do (mod 80 2) (/ 4 2) Void)", "Void" }, 111 112 { "eval", NULL }, 113 { "(eval ''hey)", "hey" }, 114 { "(eval \"sup\")", "sup" }, 115 { "(eval (+ 1 2))", "3" }, 116 { "(eval '(- 4 3))", "1" }, 117 { "(eval ''(mod 9 3))", "(mod 9 3)" }, 118 { "(do (def bar '(/ 25 5)) (eval bar))", "5" }, 119 120 { "cond", NULL }, 121 { "(cond)", "Void" }, 122 { "(cond (True 1))", "1" }, 123 { "(cond ((= 1 1) 1) ((= 1 2) 2) (True 3))", "1" }, 124 { "(cond ((= 1 2) 1) ((= 1 2) 2) (else (+ 1 2)))", "3" }, 125 { "(cond ((= 1 2) 1) ((= 1 1) 2) (else 3))", "2" }, 126 { "(cond ((= 1 2) 1) ((= 1 3) 2))", "Void" }, 127 { "(cond ((= 1 2) 1) (\"foo\" 2) (else 3))", "2" }, 128 { "(cond (() (+ 1 2)))", "Void" }, 129 130 { "get", NULL }, 131 { "(get \"hello\" 'len)", "5" }, 132 { "(get 'drinky-poo 'len)", "10" }, 133 { "(get (cons 1 2) 'car)", "1" }, 134 { "(get (cons 'jamie 'mr-t) 'cdr)", "mr-t" }, 135 { "(get '(dirty-burger freedom-35) 'cdr)", "(freedom-35)" }, 136 { "(get '(1 2 3 4) 'cdr)", "(2 3 4)" }, 137 { "(get '(2 4 6) 'car)", "2" }, 138 { "(get 3 'numerator)", "3" }, 139 { "(get 83 'denominator)", "1" }, 140 { "(get 3/2 'denominator)", "2" }, 141 { "(get 10/15 'denominator)", "3" }, 142 { "(get 9/2 'numerator)", "9" }, 143 144 { "eq", NULL }, 145 { "(=)", "True" }, 146 { "(= 1)", "True" }, 147 { "(= \"foo\")", "True" }, 148 { "(= 1 1)", "True" }, 149 { "(= 1 1 1 1 1 1)", "True" }, 150 { "(= 1 2)", "Nil" }, 151 { "(= 1 1 2 1 1 1)", "Nil" }, 152 { "(= 1 1 1 1 1 2)", "Nil" }, 153 { "(= 2 1 1 1 1 1)", "Nil" }, 154 { "(= 4/5 4/5)", "True" }, 155 { "(= 2/1 2)", "True" }, 156 { "(= 2/4 1/2)", "True" }, 157 { "(= 2/4 1/2 4/8 3/6)", "True" }, 158 { "(= 1/2 4/5)", "Nil" }, 159 { "(= 5/4 4/5)", "Nil" }, 160 { "(= 3 3/2)", "Nil" }, 161 { "(= 3 3/2 3 3 3)", "Nil" }, 162 { "(= (+ 1 1) (+ 2 0))", "True" }, 163 { "(= \"foo\" \"foo\")", "True" }, 164 { "(= \"foo\" \"bar\")", "Nil" }, 165 { "(= \"foo\" 'foo)", "Nil" }, 166 { "(= 'bar 'bar)", "True" }, 167 { "(= \"foo\" \"foo\" \"foo\" \"foo\" \"foo\")", "True" }, 168 { "(= \"foo\" \"bar\" \"foo\" \"foo\" \"foo\")", "Nil" }, 169 { "(= \"foo\" 3)", "Nil" }, 170 { "(= \"foo\" \"foo\" 4 \"foo\" \"foo\")", "Nil" }, 171 { "(= \"foo\" \"FOO\")", "Nil" }, 172 { "(= True True)", "True" }, 173 { "(= car car)", "True" }, 174 { "(= car cdr)", "Nil" }, 175 { "(= quote quote quote)", "True" }, 176 { "(= '(1 2 3) (list 1 2 3))", "True" }, 177 { "(= '(a b c) '(a b c))", "True" }, 178 { "(= '(a b c) '(a b d))", "Nil" }, 179 { "(= '(1 2 3) '(1 2))", "Nil" }, 180 { "(= '(1 2 3) '(1))", "Nil" }, 181 { "(= '((1 2) 3 4) '((1 2) 3 4))", "True" }, 182 { "(= '((1 b) 3 4) '((1 2) 3 4))", "Nil" }, 183 { "(= (Func (it) it) @it)", "True" }, 184 { "(= @it (Func (x) x))", "Nil" }, 185 { "(/=)", "Nil" }, 186 { "(/= 'a)", "Nil" }, 187 { "(/= '(1 . 2) (list* 1 2))", "Nil" }, 188 { "(/= 1 2)", "True" }, 189 { "(/= 1 1 2 1 1 1)", "True" }, 190 { "(/= \"foo\" \"bar\")", "True" }, 191 { "(/= 'greg 'greg 'greg 'greg)", "Nil" }, 192 193 { "def", NULL }, 194 { "(def foo 4)", "Void" }, 195 { "foo", "4" }, 196 { "(def bar foo)", "Void" }, 197 { "bar", "4" }, 198 { "(set! foo 5)", "5" }, 199 { "foo", "5" }, 200 { "(set! foo (+ foo bar))", "9" }, 201 { "foo", "9" }, 202 { "(def add +)", "Void" }, 203 { "(add foo bar)", "13" }, 204 { "(def (one x) (add x 1))", "Void" }, 205 { "(one foo)", "10" }, 206 { "(def (more x)" 207 " (def term 3)" 208 " (+ x term))", "Void" }, 209 { "(more 8)", "11" }, 210 { "(def (add2 x)" 211 " (+ x 1) (+ x 2))", "Void" }, 212 { "(add2 2)", "4" }, 213 { "(set! add2 2)", "2" }, 214 { "add2", "2" }, 215 { "(set! add2 \"2\")", "2" }, 216 { "add2", "2" }, 217 { "defined?", NULL }, 218 { "(defined? invalid-var)", "Nil" }, 219 { "(defined? defined?)", "True" }, 220 { "(defined? car)", "True" }, 221 { "(defined? when)", "True" }, 222 { "(defined? apply)", "True" }, 223 224 { "Func", NULL }, 225 { "((Func (x) x) 3)", "3" }, 226 { "((Func (x) x) (+ 1 2))", "3" }, 227 { "((Func (x) (+ x 1)) 8)", "9" }, 228 { "((Func (a b) (+ a b)) 2 2)", "4" }, 229 { "((Func () 5))", "5" }, 230 231 { "control", NULL }, 232 { "(if True 1 2)", "1" }, 233 { "(if () 1 2)", "2" }, 234 { "(if (integer? 3) True ())", "True" }, 235 { "(if (ratio? car) (cons 1 2) (car '(1 2)))", "1" }, 236 { "(when True 'foo)", "foo" }, 237 { "(when () 'b ar)", "Void" }, 238 { "(when (= 1 1) 4)", "4" }, 239 { "(unless True 'foo)", "Void" }, 240 { "(unless () 'bar)", "bar" }, 241 { "(unless 3 4)", "Void" }, 242 { "(unless (< 5 4) 7)", "7" }, 243 { "(switch 5 (3 'yes) (5 'no))", "no" }, 244 { "(switch (+ 1 2) ((mod 8 5) 'yes) (err 'no))", "yes" }, 245 { "(switch 2 (3 'yes) (5 'no))", "Void" }, 246 { "(switch \"foo\" (e \"bar\") (\"foo\" 'zar) ('baz 3))", "zar" }, 247 248 /* TODO other syms as well */ 249 { "logic", NULL }, 250 { "(not ())", "True" }, 251 { "(not True)", "Nil" }, 252 { "(and () ())", "Nil" }, 253 { "(and True ())", "Nil" }, 254 { "(and () True)", "Nil" }, 255 { "(and True True)", "True" }, 256 { "(nand () ())", "True" }, 257 { "(nand True ())", "True" }, 258 { "(nand () True)", "True" }, 259 { "(nand True True)", "Nil" }, 260 { "(or () ())", "Nil" }, 261 { "(or True ())", "True" }, 262 { "(or () True)", "True" }, 263 { "(or True True)", "True" }, 264 { "(nor () ())", "True" }, 265 { "(nor True ())", "Nil" }, 266 { "(nor () True)", "Nil" }, 267 { "(nor True True)", "Nil" }, 268 269 { "list", NULL }, 270 { "(list 1 2 3)", "(1 2 3)" }, 271 { "(list (* 2 2) (+ 2 3))", "(4 5)" }, 272 { "(list 'a 'b 'c 'd 'e 'f)", "(a b c d e f)" }, 273 { "(list \"foo\")", "(foo)" }, 274 { "(list)", "Nil" }, 275 { "(list 1/2 2/8 . 1/8)", "(1/2 1/4 . 1/8)" }, 276 { "(list* .5 .25 .125)", "(0.5 0.25 . 0.125)" }, 277 { "(list* 1 2 3 4 5 6)", "(1 2 3 4 5 . 6)" }, 278 { "(list* (sqr 3) (cube 4))", "(9 . 64)" }, 279 { "(list* 5/4)", "5/4" }, 280 281 { "list get", NULL }, 282 { "(last '(1 2 3))", "3" }, 283 { "(last (list 4 5))", "5" }, 284 { "(last '(a b c d e f))", "f" }, 285 { "(last (cons 1 (cons 2 ())))", "2" }, 286 { "(length '(1 2 3))", "3" }, 287 { "(length (list .3 -3/2 12 5))", "4" }, 288 { "(length '(a b))", "2" }, 289 { "(length (list list))", "1" }, 290 { "(length ())", "0" }, 291 { "(length Nil)", "0" }, 292 { "(nth '(1 2 3) 1)", "2" }, 293 { "(nth (list 3 5/2 .332 -2) 2)", "0.332" }, 294 { "(nth '(a b c) 0)", "a" }, 295 { "(nth (list 'foo 'bar 'zar 'baz) 3)", "baz" }, 296 { "(head '(1.2 1.3 1.4 1.5) 2)", "(1.2 1.3)" }, 297 { "(head '(1 1e1 1e2 1e3) 3)", "(1 10 100)" }, 298 { "(head '(1 2 3) 1)", "(1)" }, 299 { "(head '(1 2) 0)", "Nil" }, 300 { "(tail '(randy bobandy lahey bubs) 3)", "(bubs)" }, 301 { "(tail (list 1/2 1/3 1/4) 0)", "(1/2 1/3 1/4)" }, 302 { "(tail '(2 4 9 16 25 36) 2)", "(9 16 25 36)" }, 303 { "(count 3 '(1 2 3 4))", "1" }, 304 { "(count 1/2 (list 1/2 1/3 2/4 8 9.0))", "2" }, 305 { "(count 'a '(b c a a f h a b c a))", "4" }, 306 { "(count 3.2 Nil)", "0" }, 307 { "(count \"Bobandy\" '(1/2 1/4 \"Jim\"))", "0" }, 308 309 { "list proc", NULL }, 310 { "(apply list '(1 2 3))", "(1 2 3)" }, 311 { "(apply + '(2 90))", "92" }, 312 { "(apply list '(a b c d e))", "(a b c d e)" }, 313 { "(map car '((1 a) (2 b) (3 c)))", "(1 2 3)" }, 314 { "(map cdr '((1 a) (2 b) (3 c)))", "((a) (b) (c))" }, 315 { "(map (Func (x) (car (cdr x))) '((1 a) (2 b) (3 c)))", "(a b c)" }, 316 { "(map cadr '((1/2 .5) (\"conky\" .25) ('bubbles .125)))", "(0.5 0.25 0.125)" }, 317 { "(map inc (list 2 4 8 (^ 2 4)))", "(3 5 9 17)" }, 318 { "(convert 1 2 '(1 2 3 1 1 4 5 6 7 1))", "(2 2 3 2 2 4 5 6 7 2)" }, 319 { "(convert 'hey 'hello '(hi sup hey hey hello hola))", 320 "(hi sup hello hello hello hola)" }, 321 { "((compose - sqrt) 9)", "-3" }, 322 { "((compose / sqrt sqr) 18)", "1/18" }, 323 { "((compose - sqrt cube) 4)", "-8" }, 324 { "((compose -) 5/3)", "-5/3" }, 325 { "((compose - +) 5 6)", "-11" }, 326 { "((compose sqrt Int *) 4.5 2)", "3" }, 327 /* { "(foldr + 0 '(1 2 4 5))", "12" }, */ 328 /* { "(foldr list 0 '(1 2 3 4))", "((((0 1) 2) 3) 4)" }, */ 329 330 { "list filter", NULL }, 331 { "(filter positive? '(1 2 -4 5 -9 10))", "(1 2 5 10)" }, 332 { "(filter odd? '(8 6 17 9 82 34 27))", "(17 9 27)" }, 333 { "(filter integer? (list 1/2 3.e-2 9/3 3.2 0.0 8 17))", "(3 8 17)" }, 334 { "(keep '+ '(+ * - - + + - / sqrt))", "(+ + +)" }, 335 { "(keep 5 (list (+ 1 2) (- 10 5) 3/2 5 (/ 15 5))))", "(5 5)" }, 336 { "(keep 3.2 '(3. 3 3.02 3.12 3.20 3.7))", "(3.2)" }, 337 { "(keep 'a '('a b c d e))", "Nil" }, 338 { "(remove 1/2 (list 3/4 4/8 6/7 19/17 6/8 1/2))", "(3/4 6/7 19/17 3/4)" }, 339 { "(remove 2 '(1 3 4 5))", "(1 3 4 5)" }, 340 { "(remove \"greg\" '(greg 'greg \"wirt\" beatrice))", 341 "(greg (quote greg) wirt beatrice)" }, 342 343 { "list mod", NULL }, 344 { "(reverse '(1 2 3 4 5))", "(5 4 3 2 1)" }, 345 { "(reverse (list -20 5/2 .398))", "(0.398 5/2 -20)" }, 346 { "(reverse '(a b))", "(b a)" }, 347 { "(reverse (list \"foo\" \"bar\" \"baz\"))", "(baz bar foo)" }, 348 { "(reverse (cons 1/2 Nil))", "(1/2)" }, 349 { "(reverse ())", "Nil" }, 350 { "(append '(1 2 3) '(4 5 6))", "(1 2 3 4 5 6)" }, 351 { "(append (list (+ 1 2) 4) '(a b c))", "(3 4 a b c)" }, 352 353 { "assoc", NULL }, 354 { "(zip '(1 2 3 4) '(a b c d))", 355 "((1 . a) (2 . b) (3 . c) (4 . d))" }, 356 { "(zip (list 'ricky 'lahey) (list \"julian\" \"randy\"))", 357 "((ricky . julian) (lahey . randy))" }, 358 { "(assoc 'baz '((foo . 3) (bar . 8) (baz . 14)))", "(baz . 14)" }, 359 { "(assoc 'a '((a b) (3 2.1) (3.2 4/3) (3.2 3.2)))", "(a b)" }, 360 { "(assoc 3 '((1 b)))", "Nil" }, 361 { "(assoc 4/3 (list (list 1 pi) (list 4/3 1/2 3) (list 2 3)))", "(4/3 1/2 3)" }, 362 363 { "list member", NULL }, 364 { "(memp even? (list 1 3 19 4 7 8 2))", "(4 7 8 2)" }, 365 { "(memp negative? (list 1/3 pi 3.2e-9 0 4 -7 2))", "(-7 2)" }, 366 { "(memp (Func (x) (> x 8)) '(1/3 1/2 5/3 8 9))", "(9)" }, 367 { "(memp (Func (x) (= x \"fry\")) " 368 "'(\"fry\" \"nibbler\" \"prof\"))", "(fry nibbler prof)" }, 369 { "(member 'foo '(foo bar baz))", "(foo bar baz)" }, 370 { "(member 'bar '(foo bar baz))", "(bar baz)" }, 371 { "(member 4 '(12 38 4 8))", "(4 8)" }, 372 { "(member 3.2 '(4/3 2 8 2 3.14 3.2))", "(3.2)" }, 373 { "(member \"quux\" (list 4.2 3 'quux))", "Nil" }, 374 { "(member 'qux '(foo bar baz))", "Nil" }, 375 { "(everyp? even? '(2 4 10 18))", "True" }, 376 { "(everyp? odd? '(1 2 3 9 10))", "Nil" }, 377 { "(everyp? integer? '(1. 2/3 3.14 4/5))", "Nil" }, 378 { "(every? 'foo '(foo bar baz))", "Nil" }, 379 { "(every? \"a\" '(a 'a \"a\"))", "Nil" }, 380 { "(every? 3 (list 3 (+ 1 2) (- 5 2)))", "True" }, 381 382 { "quasiquote", NULL }, 383 { "`7.2", "7.2" }, 384 { "`cory", "cory" }, 385 { "`,foo", "9" }, 386 { "`(1 2 3)", "(1 2 3)" }, 387 { "`(\"sunnyvale\")", "(sunnyvale)" }, 388 { "`(1/2 . 2/1)", "(1/2 . 2)" }, 389 { "`(cory trevor)", "(cory trevor)" }, 390 { "`(foo bar quax)", "(foo bar quax)" }, 391 { "`(,foo ,bar)", "(9 4)" }, 392 { "`(,foo . ,bar)", "(9 . 4)" }, 393 { "`(,foo . ,bar)", "(9 . 4)" }, 394 { "`(foo bar ,foo fry)", "(foo bar 9 fry)" }, 395 { "`(1 ,(+ 1 2) 5 ,(- 9 2))", "(1 3 5 7)" }, 396 { "`(1 ,@(list 4 9))", "(1 4 9)" }, 397 { "`(3 ,@foo)", "(3 . 9)" }, 398 { "`(a b c ,@foo)", "(a b c . 9)" }, 399 { "`(0 ,@(list 1 2) 3 4)", "(0 1 2 3 4)" }, 400 401 { "stack", NULL }, 402 { "(peek '(1 2 3 4 5 6))", "1" }, 403 { "(peek (list 'a 'b 'c))", "a" }, 404 { "(pop (list 1/2 1/4))", "(1/4)" }, 405 { "(pop '(\"foo\" \"bar\" \"baz\"))", "(bar baz)" }, 406 { "(push '(6 3 5/3 .38) .5)", "(0.5 6 3 5/3 0.38)" }, 407 { "(push (list \"ni\" 'shrubbery) (* 3 2))", "(6 ni shrubbery)" }, 408 { "(swap '(1 2 3 5 7 11))", "(2 1 3 5 7 11)" }, 409 { "(swap (list 1/2 1/4 1/9 1/16))", "(1/4 1/2 1/9 1/16)" }, 410 411 { "stack!", NULL }, 412 { "(def s '(1 2 3 4 5))", "Void" }, 413 { "(peek s)", "1" }, 414 { "(pop! s)", "1" }, 415 { "s", "(2 3 4 5)" }, 416 { "(pop! s)", "2" }, 417 { "s", "(3 4 5)" }, 418 { "(push! s 3/2)", "(3/2 3 4 5)" }, 419 { "s", "(3/2 3 4 5)" }, 420 { "(push! s (- (/ 2)))", "(-1/2 3/2 3 4 5)" }, 421 { "s", "(-1/2 3/2 3 4 5)" }, 422 { "(swap! s)", "(3/2 -1/2 3 4 5)" }, 423 { "s", "(3/2 -1/2 3 4 5)" }, 424 { "(swap! s)", "(-1/2 3/2 3 4 5)" }, 425 { "s", "(-1/2 3/2 3 4 5)" }, 426 427 { "numbers", NULL }, 428 { "(Dec 1/2)", "0.5" }, 429 { "(Dec 3/-2)", "-1.5" }, 430 { "(Dec 1)", "1.0" }, 431 { "(Dec 3.14)", "3.14" }, 432 { "(Int 1/2)", "0" }, 433 { "(Int 3/-2)", "-1" }, 434 { "(Int 1)", "1" }, 435 { "(Int 3.14)", "3" }, 436 437 { "round", NULL }, 438 { "(round 7/3)", "2" }, 439 { "(round -3/4)", "-1" }, 440 { "(round 6.3)", "6.0" }, 441 { "(round -8.1)", "-8.0" }, 442 { "(round 3)", "3" }, 443 { "(round -81)", "-81" }, 444 { "(round 0)", "0" }, 445 { "(floor 5/3)", "1" }, 446 { "(floor -9/4)", "-3" }, 447 { "(floor 6.3)", "6.0" }, 448 { "(floor -8.1)", "-9.0" }, 449 { "(floor 3)", "3" }, 450 { "(floor -81)", "-81" }, 451 { "(floor 0)", "0" }, 452 { "(ceil 1/2)", "1" }, 453 { "(ceil -8/5)", "-1" }, 454 { "(ceil pi)", "4.0" }, 455 { "(ceil (- .2))", "-0.0" }, 456 { "(ceil 128)", "128" }, 457 { "(ceil -2)", "-2" }, 458 { "(ceil 0)", "0" }, 459 { "(truncate (/ 17 2))", "8" }, 460 { "(truncate -12/5)", "-2" }, 461 { "(truncate (exp 2.))", "7.0" }, 462 { "(truncate 124.1380)", "124.0" }, 463 { "(truncate 8)", "8" }, 464 { "(truncate -5)", "-5" }, 465 { "(truncate 0)", "0" }, 466 467 { "arithmetic", NULL }, 468 { "(+ 1 1)", "2" }, 469 { "(+ 1 (+ 1 2))", "4" }, 470 { "(+ 1029 283)", "1312" }, 471 { "(+ 204 8.3)", "212.3" }, 472 { "(+ 33 3/4)", "135/4" }, 473 { "(+ 1/3 5)", "16/3" }, 474 { "(+ 7/4 pi)", "4.89159265358979" }, 475 { "(+ 2/5 3/2)", "19/10" }, 476 { "(+ 2.1 2)", "4.1" }, 477 { "(+ 8.6 5.3)", "13.9" }, 478 { "(+ 3.7 1/8)", "3.825" }, 479 { "(- 3)", "-3" }, 480 { "(- +3)", "-3" }, 481 { "(- -289)", "289" }, 482 { "(- 7/8)", "-7/8" }, 483 { "(- -6.412E2)", "641.2" }, 484 { "(- 5 4)", "1" }, 485 { "(- 53 88)", "-35" }, 486 { "(- 204 8.3)", "195.7" }, 487 { "(- 33 3/4)", "129/4" }, 488 { "(- 1/3 5)", "-14/3" }, 489 { "(- 7/4 pi)", "-1.39159265358979" }, 490 { "(- 2/5 3/2)", "-11/10" }, 491 { "(- 2.1 2)", "0.1" }, 492 { "(- 8.6 5.3)", "3.3" }, 493 { "(- 3.7 1/8)", "3.575" }, 494 { "(* 3 2)", "6" }, 495 { "(* -2 8.89)", "-17.78" }, 496 { "(* 6 3/4)", "9/2" }, 497 { "(* 1.004 8)", "8.032" }, 498 { "(* 1.34e3 .0012)", "1.608" }, 499 { "(* e -5/2)", "-6.79570457114761" }, 500 { "(* 1/3 6)", "2" }, 501 { "(* 5/2 14.221)", "35.5525" }, 502 { "(* 6/8 8/7)", "6/7" }, 503 { "(/ 1 2)", "1/2" }, 504 { "(/ 8 4)", "2" }, 505 { "(/ 6 2.1)", "2.85714285714286" }, 506 { "(/ 4 4/3)", "3" }, 507 { "(/ 5)", "1/5" }, 508 { "(/ 4473)", "1/4473" }, 509 { "(/ 10.42 5)", "2.084" }, 510 { "(/ 1.34e-2 4.3332)", "0.0030924028431644" }, 511 { "(/ 1.04 -15/4)", "-0.277333333333333" }, 512 { "(/ 4/3 7)", "4/21" }, 513 { "(/ 5/4 3.2)", "0.390625" }, 514 { "(/ 1/3 5/4)", "4/15" }, 515 { "(mod 10 3)", "1" }, 516 { "(mod -11 3)", "-2" }, 517 { "(mod 10 -3)", "1" }, 518 { "(mod -10 -3)", "-1" }, 519 { "(mod 10 5)", "0" }, 520 { "(mod 7 2)", "1" }, 521 { "(mod 8 5)", "3" }, 522 523 { "compare", NULL }, 524 { "(< 2 3)", "True" }, 525 { "(< 3 3)", "Nil" }, 526 { "(< 4 3)", "Nil" }, 527 { "(<= -2 +4)", "True" }, 528 { "(<= -2 -2)", "True" }, 529 { "(<= 4 -2)", "Nil" }, 530 { "(> 89 34)", "True" }, 531 { "(> 48 48)", "Nil" }, 532 { "(> 98 183)", "Nil" }, 533 { "(>= +4 -282)", "True" }, 534 { "(>= 39 39)", "True" }, 535 { "(>= -32 -30)", "Nil" }, 536 537 { "abs", NULL }, 538 { "(abs 4)", "4" }, 539 { "(abs -3/5)", "3/5" }, 540 { "(abs 0.0)", "0.0" }, 541 542 { "sgn", NULL }, 543 { "(sgn 239)", "1" }, 544 { "(sgn -3)", "-1" }, 545 { "(sgn 5/4)", "1" }, 546 { "(sgn -1/7)", "-1" }, 547 { "(sgn 3.17)", "1.0" }, 548 { "(sgn -.457)", "-1.0" }, 549 { "(sgn 0)", "0" }, 550 { "(sgn 0.0)", "0.0" }, 551 552 { "max/min", NULL }, 553 { "(max 9346 13297)", "13297" }, 554 { "(max -3 8)", "8" }, 555 { "(max 3/2 1/2)", "3/2" }, 556 { "(max 0 -.5)", "0" }, 557 { "(min 4 48)", "4" }, 558 { "(min -80 -148)", "-148" }, 559 { "(min 7/2 -3)", "-3" }, 560 { "(min 1/2 1/3)", "1/3" }, 561 { "(min .05 .06)", "0.05" }, 562 563 { NULL, NULL }, 564 }; 565 566 int 567 tisp_test(Tsp st, const char *input, const char *expect, int output) 568 { 569 Val v; 570 FILE *f; 571 size_t nread; 572 char buf[BUFSIZ] = {0}; 573 574 if (!(st->file = strdup(input))) 575 return 0; 576 st->filec = 0; 577 if (!(v = tisp_read(st))) 578 return 0; 579 if (!(v = tisp_eval(st, st->global, v))) { 580 if (output) 581 putchar('\n'); 582 return 0; 583 } 584 585 f = fopen("test.out", "w"); 586 tisp_print(f, v); 587 fclose(f); 588 589 f = fopen("test.out", "r"); 590 while ((nread = fread(buf, 1, sizeof(buf), f)) > 0) ; 591 fclose(f); 592 remove("test.out"); 593 594 if (output) 595 printf("%s\n", buf); 596 return strcmp(buf, expect) == 0; 597 } 598 599 int 600 main(void) 601 { 602 int correct = 0, total = 0, seccorrect = 0, sectotal = 0, last = 1; 603 int errors[LEN(tests)] = {0}; 604 Tsp st = tisp_env_init(1024); 605 tib_env_math(st); 606 tib_env_string(st); 607 tisp_env_lib(st, tibs); 608 609 for (int i = 0; ; i++) { 610 if (!tests[i][1]) { 611 if (i != 0) { 612 printf("%d/%d\n", seccorrect, sectotal); 613 for (int j = last; j < i; j++) 614 if (!tests[j][1]) { 615 printf("%-10s\n", tests[j][0]); 616 } else if (errors[j]) { 617 printf(" input: %s\n" 618 " expect: %s\n" 619 " output: ", tests[j][0], tests[j][1]); 620 tisp_test(st, tests[j][0], tests[j][1], 1); 621 } 622 last = i + 1; 623 } 624 if (!tests[i][0]) 625 break; 626 printf("%-10s ", tests[i][0]); 627 seccorrect = 0; 628 sectotal = 0; 629 } else { 630 if (tisp_test(st, tests[i][0], tests[i][1], 0)) { 631 correct++; 632 seccorrect++; 633 } else { 634 errors[i] = 1; 635 } 636 total++; 637 sectotal++; 638 } 639 } 640 printf("%-10s %d/%d\n", "total", correct, total); 641 642 return correct != total; 643 }