test.lisp @ 37b7eecfdf6e

Add conditionals
author Steve Losh <steve@stevelosh.com>
date Thu, 04 Mar 2021 20:25:44 -0500
parents 87674bc4c220
children 01ba812a486a
(ql:quickload '(:1am :losh :alexandria))

(load (compile-file "iacc.lisp"))

(defpackage :iacc/test
  (:use :cl :losh)
  (:use :iacc)
  (:export horrifying-repl))

(in-package :iacc/test)

(defun run (program)
  (iacc:compile-program program)
  (losh:sh '("make" "prog"))
  (string-trim '(#\newline) (losh:sh "./prog" :result-type 'string)))

(defun repl ()
  (loop :for program = (progn (write-string "> ")
                              (force-output)
                              (read))
        :until (equal program 'q)
        :do (write-line (run program))))

(defun reload ()
  (load (compile-file "test.lisp")))


(defmacro define-test (name &body body)
  `(1am:test ,(intern (concatenate 'string (symbol-name 'test/) (symbol-name name)))
    (let ((*package* ,*package*))
      ,@body)))

(defmacro check (program expected)
  `(1am:is (string= ,expected (run ,program))))

(define-test fixnums
  (check 0 "0")
  (check 1 "1")
  (check -1 "-1")
  (check 10 "10")
  (check -10 "-10")
  (check 2736 "2736")
  (check -2736 "-2736")
  (check 536870911 "536870911")
  (check -536870912 "-536870912"))

(define-test booleans
  (check :true "#t")
  (check :false "#f"))

(define-test null
  (check nil "()"))

(define-test characters
  (check #\a "#\\a")
  (check #\A "#\\A")
  (check #\space "#\\ "))

(define-test primitives/fxadd1
  (check '(fxadd1 0) "1")
  (check '(fxadd1 99) "100")
  (check '(fxadd1 (fxadd1 202)) "204")
  (check '(fxadd1 (fxadd1 -6)) "-4"))

(define-test primitives/fxsub1
  (check '(fxsub1 1) "0")
  (check '(fxsub1 0) "-1")
  (check '(fxsub1 99) "98")
  (check '(fxsub1 (fxsub1 202)) "200")
  (check '(fxsub1 (fxadd1 -6)) "-6"))
(define-test primitives/fxlognot
  (check '(fxlognot 0) "-1")
  (check '(fxlognot -1) "0")
  (check '(fxlognot 1) "-2")
  (check '(fxlognot -2) "1")
  (check '(fxlognot 536870911) "-536870912")
  (check '(fxlognot -536870912) "536870911")
  (check '(fxlognot (fxlognot 237463)) "237463"))

(define-test primitives/char-fixnum-conversion
  (check '(char->fixnum #\A) "65")
  (check '(fixnum->char 65) "#\\A")
  (check '(fixnum->char (fxadd1 (char->fixnum #\A))) "#\\B"))

(define-test primitives/fixnum?
  (check '(fixnum? 1)      "#t")
  (check '(fixnum? 0)      "#t")
  (check '(fixnum? -1)     "#t")
  (check '(fixnum? nil)    "#f")
  (check '(fixnum? :true)  "#f")
  (check '(fixnum? :false) "#f")
  (check '(fixnum? #\A)    "#f"))

(define-test primitives/boolean?
  (check '(boolean? 1)      "#f")
  (check '(boolean? 0)      "#f")
  (check '(boolean? -1)     "#f")
  (check '(boolean? nil)    "#f")
  (check '(boolean? :true)  "#t")
  (check '(boolean? :false) "#t")
  (check '(boolean? #\A)    "#f"))

(define-test primitives/char?
  (check '(char? 1)      "#f")
  (check '(char? 0)      "#f")
  (check '(char? -1)     "#f")
  (check '(char? nil)    "#f")
  (check '(char? :true)  "#f")
  (check '(char? :false) "#f")
  (check '(char? #\A)    "#t"))

(define-test primitives/null?
  (check '(null? 1)      "#f")
  (check '(null? 0)      "#f")
  (check '(null? -1)     "#f")
  (check '(null? nil)    "#t")
  (check '(null? :true)  "#f")
  (check '(null? :false) "#f")
  (check '(null? #\A)    "#f"))

(define-test primitives/fxzero?
  (check '(fxzero? 1)      "#f")
  (check '(fxzero? 0)      "#t")
  (check '(fxzero? -1)     "#f")
  (check '(fxzero? nil)    "#f")
  (check '(fxzero? :true)  "#f")
  (check '(fxzero? :false) "#f")
  (check '(fxzero? #\A)    "#f"))

(define-test primitives/not
  (check '(not 1)      "#f")
  (check '(not 0)      "#f")
  (check '(not -1)     "#f")
  (check '(not nil)    "#f")
  (check '(not :true)  "#f")
  (check '(not :false) "#t")
  (check '(not #\A)    "#f"))

(define-test if
  (check '(if :true 1 2) "1")
  (check '(if :false 1 2) "2")
  (check '(if nil 1 2) "1"))

(define-test if/predicate-fusion
  (check '(if (null? nil) 1 2) "1")
  (check '(if (null? 1) 1 2) "2")
  (check '(if (char? nil) 1 2) "2")
  (check '(if (char? #\A) 1 2) "1")
  (check '(if (boolean? :true) 1 2) "1")
  (check '(if (boolean? :false) 1 2) "1")
  (check '(if (boolean? nil) 1 2) "2")
  (check '(if (boolean? 999) 1 2) "2")
  (check '(if (fixnum? 0) 1 2) "1")
  (check '(if (fixnum? #\x) 1 2) "2")
  (check '(if (fxzero? 0) 1 2) "1")
  (check '(if (fxzero? 99) 1 2) "2")
  (check '(if (not :false) 1 2) "1")
  (check '(if (not :true) 1 2) "2")
  (check '(if (not nil) 1 2) "2")
  (check '(if (not (fixnum? 0)) 1 2) "2")
  (check '(if (not (fixnum? #\x)) 1 2) "1"))

(define-test primitives/simple-combos
  (check '(fxzero? (fxsub1 (fxadd1 0))) "#t")
  (check '(boolean? (fixnum? 1)) "#t")
  (check '(boolean? (boolean? 1)) "#t")
  (check '(fixnum? (char->fixnum #\A)) "#t")
  (check '(char? (fixnum->char (fxadd1 65))) "#t")
  (check '(boolean? (not 1)) "#t")
  (check '(not (boolean? (not 1))) "#f")
  (check '(not (not (boolean? (not 1)))) "#t"))