(def (fr) 1 (return) 0) (assert (void? (fr))) (def (fr) 1 (return 2) 0) (assert (eq? 2 (fr))) (def (fr) 1 (return NIL) 0) (assert (not (fr))) (assert-fail (top-level-value 'unbound-var) unbound-error) (set-top-level-value! 'unbound-var 0) (assert (= 0 unbound-var)) (makunbound 'unbound-var) (def (f) (let ((unbound-var 1)) (set-top-level-value! 'unbound-var 0) (cons unbound-var (top-level-value 'unbound-var)))) (def unbound-var 2) (assert (= 2 (top-level-value 'unbound-var))) (assert (= 2 unbound-var)) (set-top-level-value! 'unbound-var 3) (assert (= 3 (top-level-value 'unbound-var))) (assert (= 3 unbound-var)) (assert (equal? (cons 1 0) (f))) (defmacro (every-int . n) `(list (fixnum ,@n) (s8 ,@n) (u8 ,@n) (s16 ,@n) (u16 ,@n) (s32 ,@n) (u32 ,@n) (p32 ,@n) (s64 ,@n) (u64 ,@n) (p64 ,@n) (f32 ,@n) (f64 ,@n) (bignum ,@n))) (def (every-sint n) (list (fixnum n) (s8 n) (s16 n) (s32 n) (s64 n) (f32 n) (f64 n) (bignum n))) (def (each f l) (if (atom? l) NIL (begin (f (car l)) (each f (cdr l))))) (def (each^2 f l m) (each (λ (o) (each (λ (p) (f o p)) m)) l)) (def (test-lt a b) (each^2 (λ (neg pos) (begin (eval `(assert (= -1 (compare ,neg ,pos)))) (eval `(assert (= 1 (compare ,pos ,neg)))) (eval `(assert (< ,neg ,pos))) (eval `(assert (not (< ,pos ,neg)))))) a b)) (def (test-eq a b) (each^2 (λ (a b) (begin (eval `(assert (= 0 (compare ,a ,b)))))) a b)) (test-lt (every-sint -1) (every-int 1)) (test-lt (every-int 0) (every-int 1)) (test-lt (rune 0) (rune 1)) (test-lt (rune 0) (rune #x10ffff)) (test-eq (every-int 88) (every-int 88)) (test-eq (every-sint -88) (every-sint -88)) (assert (every (λ (x) (= x 0)) (every-int))) (def (test-square a) (each (λ (i) (unless (ptr? i) (eval `(assert (>= (* ,i ,i) 0))))) a)) (test-square (every-sint -67)) (test-square (every-int 3)) (test-square (every-int #x80000000)) (test-square (every-sint #x80000000)) (test-square (every-sint #x-80000000)) (test-square (every-int #x8000000000000000)) (test-square (every-sint #x8000000000000000)) (test-square (every-sint #x-8000000000000000)) (assert (= (* 128 #x02000001) #x100000080)) (assert (= (/ 1) 1)) (assert (= (/ -1) -1)) (assert (= (/ 2.0) 0.5)) (assert (= (/ 2 4 8) 0.0625)) (assert (= (- 4999950000 4999941999) 8001)) (assert (not (eqv? 10 #\newline))) (assert (not (eqv? #\newline 10))) ; tricky cases involving INT32_MIN (assert (< (- #u32(#x80000000)) 0)) (assert (> (- #s32(#x80000000)) 0)) ; same with INT64_MIN (assert (< (- #u64(#x8000000000000000)) 0)) (assert (> (- #s64(#x8000000000000000)) 0)) ; fixnum versions (assert (= (- -536870912) 536870912)) (assert (= (- -2305843009213693952) 2305843009213693952)) (assert (not (equal? #s64(#x8000000000000000) #u64(#x8000000000000000)))) (assert (equal? (+ #s64(#x4000000000000000) #s64(#x4000000000000000)) #u64(#x8000000000000000))) (assert (equal? (* 2 #s64(#x4000000000000000)) #u64(#x8000000000000000))) (assert (equal? (u64 (f64 -123)) #u64(#xffffffffffffff85))) (assert (equal? (str 'sym #\x41 #rune(945) "blah") "symA\u03B1blah")) (assert (= (length (str #\x0)) 1)) (assert (> 9223372036854775808 9223372036854775807)) (assert-fail (fixnum? (- (str-rune "0" 0) #\0))) (assert (= (ash 1 -9999) 0)) (assert (= (ash -1 -9999) -1)) (assert (= (ash #s64(1) -9999) 0)) (assert (= (ash #s64(-1) -9999) -1)) (assert (= (ash #bignum(1) -9999) 0)) (assert (= (ash #bignum(-1) -9999) -1)) ; ptr (assert (not (ptr? #\x))) (assert (not (ptr? 0))) (assert (not (ptr? (u64 #x7fffffffffffffff)))) (assert (not (ptr? ""))) (assert (not (ptr? "1 2 3"))) (assert (not (ptr? #(1 2 3)))) (assert (ptr? (ptr 0))) (assert (ptr? (p32 0))) (assert (ptr? (p64 0))) (assert (ptr? (ptr #xf))) (assert (ptr? (p32 #x7fffffff))) (assert (ptr? (p32 #xffffffff))) (assert (ptr? (p64 #x7fffffffffffffff))) (assert (ptr? (p64 #xffffffffffffffff))) (assert (= #xffffffff (p32 #xffffffff))) (assert (= #xffffffffffffffff (p64 #xffffffffffffffff))) (assert (not (ptr? (u64 0)))) (assert (= #xff (p32 (u8 #xff)))) (assert (= #xff (p32 (bignum #xff)))) (assert (= #xff (p64 (u8 #xff)))) (assert (= #xff (p64 (bignum #xff)))) (assert-fail (p32 "") type-error) (assert-fail (p64 "") type-error) (assert-fail (p32 'a) type-error) (assert-fail (p64 'b) type-error) ; no division and multiplication with pointers (assert-fail (/ (p32 1) 2) type-error) (assert-fail (/ (p64 1) 2) type-error) (assert-fail (/ 2 (p32 1)) type-error) (assert-fail (/ 2 (p64 1)) type-error) (assert-fail (div (p32 1) 2) type-error) (assert-fail (div (p64 1) 2) type-error) (assert-fail (div 2 (p32 1)) type-error) (assert-fail (div 2 (p64 1)) type-error) (assert-fail (div0 (p32 1) 2) type-error) (assert-fail (div0 (p64 1) 2) type-error) (assert-fail (div0 2 (p32 1)) type-error) (assert-fail (div0 2 (p64 1)) type-error) (assert-fail (* (p32 1) 2) type-error) (assert-fail (* (p64 1) 2) type-error) (assert-fail (* 2 (p32 1)) type-error) (assert-fail (* 2 (p64 1)) type-error) ; fixnum + unboxed (assert (= 255 (fixnum (u8 255)))) (assert (= -128 (fixnum (s8 -128)))) (assert (= 12345 (fixnum (bignum 12345)))) (assert-fail (fixnum #\☺) type-error) (assert-fail (fixnum "") type-error) (assert-fail (fixnum #(1 2 3)) type-error) ; conversion to f64 (assert (equal? -1.0 (f64 (s8 -1)))) (assert (equal? -1.0 (f64 (s16 -1)))) (assert (equal? -1.0 (f64 (s32 -1)))) (assert (equal? -1.0 (f64 (s64 -1)))) ; bignum (assert (> #x10000000000000000 #x8fffffffffffffff)) (assert (< #x8fffffffffffffff #x10000000000000000)) (assert (bignum? (ash 2 59))) (def (bignum-on-32? x) (if #.(fixnum? #xffffffff) (not (bignum? x)) (bignum? x))) (assert (bignum-on-32? (- (ash 2 59) 1))) (assert (bignum? 1606938044258990275541962092341162602522202993782792835301376)) (assert (bignum? #xfffffffffffffffff)) (assert (bignum-on-32? #xfffffffffffffff)) (assert (= 4764984380238568507752444984131552966909 (* 66405897020462343733 71755440315342536873))) (assert (= 71755440315342536873 (div 4764984380238568507752444984131552966909 66405897020462343733))) (assert (= 3203431780337 (div 576460752303423487 179951))) (assert (= 3487 (mod 576460752303423487 18000))) (assert (= 7 (mod 576460752303423487 10))) (assert-fail (mod 1 0) divide-error) (assert-fail (div 1 0) divide-error) (assert-fail (div0 1 0) divide-error) (assert (equal? (/ 1 0) +inf.0)) (assert-fail (/ 2 (rune 0)) type-error) (assert-fail (/ (rune 0) 2) type-error) ; eucledian vs truncated quotinent/remainder (assert (= (mod 10 3) 1)) (assert (= (mod -10 3) 2)) (assert (= (mod -10 -3) 2)) (assert (= (mod 10 -3) 1)) (assert (= (mod0 10 3) 1)) (assert (= (mod0 -10 3) -1)) (assert (= (mod0 -10 -3) -1)) (assert (= (mod0 10 -3) 1)) (assert (= (div 10 3) 3)) (assert (= (div -10 3) -4)) (assert (= (div -10 -3) 4)) (assert (= (div 10 -3) -3)) (assert (= (div0 10 3) 3)) (assert (= (div0 -10 3) -3)) (assert (= (div0 -10 -3) 3)) (assert (= (div0 10 -3) -3)) (assert (= 15 (logior 1 2 4 8))) (assert (= -1 (logior 3 -1))) (assert (= 0 (logand 1 2))) (assert (= 12328 (logand 14826 12345))) (assert (= 3 (logand 3 -1))) (assert (= 2515 (logxor 14826 12345))) (assert (= -4 (logxor 3 -1))) (assert (= 0 (logxor 0 0))) (assert (= -11 (lognot 10))) (assert (eq? (s8 -11) (lognot (s8 10)))) (assert (= 10 (lognot -11))) (assert (eq? (s8 10) (lognot (s8 -11)))) (assert (= #x0f (lognot (u8 #xf0)))) (assert (= #xf0 (lognot (u8 #x0f)))) (assert (= #xfffffffffffffffff (logior #xaaaaaaaaaaaaaaaaa #x55555555555555555))) (assert (= #xaaaaaaaaaaaaaaaaa (logxor #xfffffffffffffffff #x55555555555555555))) (assert (= #xaaaaaaaaaaaaaaaaa (logxor #xfffffffffffffffff #x55555555555555555))) (assert (= #xaaaaaaaaa (logand #xaaaaaaaaaaaaaaaaa #x55555555fffffffff))) (assert (= 0 (logand 0 #x55555555555555555))) (assert (= 602394779747 (ash 11112222333344445555666677778888 -64))) (assert (= 204984321473364576635441321909950327706185271083008 (ash 11112222333344445555666677778888 64))) ; const (assert (not (const? 'hello))) (assert (not (const? 'const?))) (assert (const? '+most-positive-fixnum+)) (assert (const? '+most-negative-fixnum+)) (assert (const? '+pi+)) (assert (const? :kw)) ; NaNs (assert (nan? +nan.0)) (assert (nan? -nan.0)) (assert (nan? (f32 +nan.0))) (assert (nan? (f32 -nan.0))) (assert (not (equal? +nan.0 +nan.0))) (assert (not (equal? -nan.0 -nan.0))) (assert (not (equal? (f32 +nan.0) (f32 +nan.0)))) (assert (not (equal? (f32 -nan.0) (f32 -nan.0)))) (assert (not (= +nan.0 +nan.0))) (assert (not (= +nan.0 -nan.0))) (assert (not (= -nan.0 -nan.0))) (assert (not (= (f32 +nan.0) (f32 +nan.0)))) (assert (not (= (f32 +nan.0) (f32 -nan.0)))) (assert (not (= (f32 -nan.0) (f32 -nan.0)))) (assert (equal? (< +nan.0 3) (> 3 +nan.0))) (assert (equal? (< +nan.0 (f64 3)) (> (f64 3) +nan.0))) (assert (equal? (< +nan.0 3) (> (f64 3) +nan.0))) (assert (equal? (< +nan.0 (f64 3)) (> 3 +nan.0))) (assert (equal? (< +nan.0 3) (< +nan.0 (f64 3)))) (assert (equal? (> +nan.0 3) (> +nan.0 (f64 3)))) (assert (equal? (< 3 +nan.0) (> +nan.0 (f64 3)))) (assert (equal? (> 3 +nan.0) (> (f64 3) +nan.0))) (assert (not (>= +nan.0 +nan.0))) (assert (not (<= -nan.0 -nan.0))) (assert (not (>= (f32 +nan.0) (f32 +nan.0)))) (assert (not (<= (f32 -nan.0) (f32 -nan.0)))) ; comparing strings (assert (< "a" "b")) (assert (< "a" "b" "c")) (assert (> "b" "a")) (assert (> "c" "b" "a")) (assert (not (< "a" "a"))) (assert (not (< "a" "a" "a"))) (assert (<= "a" "a")) (assert (<= "a" "a" "a")) (assert (>= "a" "a")) (assert (>= "a" "a" "a")) (assert (>= "ab" "aa")) (assert (>= "ab" "aa" "aa")) ; one or more than two arguments (assert (and (> 0) (< 0) (>= 0) (<= 0))) (assert (and (> 2 1 0) (< 0 1 2) (>= 2 1 0) (<= 0 1 2))) (assert (and (>= 2 1 1) (<= 1 1 2))) (assert (not (and (>= 2 1 2) (<= 2 1 2)))) ; -0.0 etc. (assert (equal? 0.0 0)) (assert (equal? 0.0 0.0)) (assert (equal? -0.0 0.0)) (assert (equal? -0.0 0)) (assert (eqv? 0.0 0)) (assert (eqv? -0.0 0)) (assert (eqv? -0.0 0.0)) (assert (= 0.0 -0.0)) ; same but f32 (assert (equal? 0.0f 0)) (assert (equal? 0.0f 0.0f)) (assert (equal? -0.0f 0.0f)) (assert (equal? -0.0f 0)) (assert (eqv? 0.0f 0)) (assert (eqv? -0.0f 0)) (assert (eqv? -0.0f 0.0f)) (assert (= 0.0f -0.0f)) ; and, or (assert (equal? T (and))) (assert (equal? NIL (or))) (assert (equal? 1 (and '(1) 'x 1))) (assert (equal? 1 (or NIL NIL NIL NIL NIL 1 NIL NIL NIL NIL))) (assert (equal? 2 (if (and '(1) 'x 1) 2 0))) (assert (equal? 2 (if (or NIL NIL NIL NIL NIL 1 NIL NIL NIL NIL) 2 0))) (assert (equal? NIL (and '(1) 1 'x NIL))) (assert (equal? NIL (or NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL))) (assert (equal? 0 (if (and '(1) 1 'x NIL) 2 0))) (assert (equal? 0 (if (or NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) 2 0))) ; bounded length tests (assert (length> #(1) 0)) (assert (not (length> #(1) 1))) (assert (not (length> #() 0))) (assert (length= #() 0)) (assert (not (length= #() 1))) (assert (not (length= #(1) 0))) (assert (length> '(1) 0)) (assert (not (length> '(1) 1))) (assert (not (length> '() 0))) (assert (length= '() 0)) (assert (not (length= '() 1))) (assert (not (length= '(1) 0))) ; proper/dotted/circular list tests (assert (not NIL)) (assert (not (cons? NIL))) (assert (not (not '(1)))) (assert (cons? '(1))) (assert (list? '(1))) (assert (proper-list? '(1))) (assert (list? NIL)) (assert (proper-list? NIL)) (assert (list? '(1 . 2))) (assert (not (proper-list? '(1 . 2)))) (def cl '#0=(1 2 3 . #0#)) (assert (cons? cl)) (assert (list? cl)) (assert (not (proper-list? cl))) ; failing applications (assert-fail ((λ (x) x) 1 2) arity-error) (assert-fail ((λ ((x 0)) x) 1 2) arity-error) (assert-fail ((λ (x (y 0)) x)) arity-error) (assert-fail ((λ (x) x)) arity-error) (assert-fail ((λ (x y . z) z) 1) arity-error) (assert-fail (car 'x) type-error) (assert-fail (cdr 1) type-error) (assert-fail (cadr 1) type-error) (assert-fail (set-car! NIL 1) type-error) (assert-fail (set-cdr! NIL 1) type-error) (assert-fail gjegherqpfdf___trejif unbound-error) (assert-fail (1) type-error) (assert-fail (apply / NIL) arity-error) (assert-fail (apply = NIL) arity-error) (assert-fail (apply eq? NIL) arity-error) (assert-fail (apply eq? '(1)) arity-error) (assert-fail (apply eq? '(1 2 3)) arity-error) (assert-fail (apply apply '(#./ ())) arity-error) (assert-fail (apply + '(1 . 2)) type-error) (assert-fail (= 1 'a) type-error) (assert-fail (= 'a 1) type-error) (assert-fail (= 0 #\nul) type-error) (assert-fail (= #\nul 0) type-error) (for-each (λ (t) (assert-fail ((fn t) "0") type-error) (assert-fail ((fn t) 'a) type-error) (assert-fail ((fn t) 0 0) arity-error)) '(fixnum s8 u8 s16 u16 s32 u32 p32 s64 u64 p64 f32 f64 bignum)) ; long argument lists (assert (= (apply + (iota 100000)) 4999950000)) (def ones (map (λ (x) 1) (iota 80000))) (assert (= (eval `(if (< 2 1) (+ ,@ones) (+ ,@(cdr ones)))) 79999)) (def MAX_ARGS 255) (def as (apply list* (map-int (λ (x) (gensym)) (+ MAX_ARGS 1)))) (def f (compile `(λ ,as ,(last-cdr as)))) (assert (equal? (apply f (iota (+ MAX_ARGS 0))) `())) (assert (equal? (apply f (iota (+ MAX_ARGS 1))) `(,MAX_ARGS))) (assert (equal? (apply f (iota (+ MAX_ARGS 2))) `(,MAX_ARGS ,(+ MAX_ARGS 1)))) (def as (apply list* (map-int (λ (x) (gensym)) (+ MAX_ARGS 100)))) (def ff (compile (macroexpand `(λ ,as (set! ,(car (last-pair as)) 42) ,(car (last-pair as)))))) (assert (equal? (apply ff (iota (+ MAX_ARGS 100))) 42)) (def ff (compile (macroexpand `(λ ,as (set! ,(car (last-pair as)) 42) (λ () ,(car (last-pair as))))))) (assert (equal? ((apply ff (iota (+ MAX_ARGS 100)))) 42)) (def as (map-int (λ (x) (gensym)) 1000)) (def f (compile `(λ ,as ,(car (last-pair as))))) (assert (equal? (apply f (iota 1000)) 999)) (def as (apply list* (map-int (λ (x) (gensym)) 995))) (def f (compile `(λ ,as ,(last-cdr as)))) (assert (equal? (apply f (iota 994)) '())) (assert (equal? (apply f (iota 995)) '(994))) (assert (equal? (apply f (iota 1000)) '(994 995 996 997 998 999))) ; optional arguments (assert (equal? ((λ ((b 0)) b)) 0)) (assert (equal? ((λ (a (b 2)) (list a b)) 1) '(1 2))) (assert (equal? ((λ (a (b 2)) (list a b)) 1 3) '(1 3))) (assert (equal? ((λ (a (b 2) (c 3)) (list a b c)) 1) '(1 2 3))) (assert (equal? ((λ (a (b 2) (c 3)) (list a b c)) 1 8) '(1 8 3))) (assert (equal? ((λ (a (b 2) (c 3)) (list a b c)) 1 8 9) '(1 8 9))) (assert (equal? ((λ ((x 0) . r) (list x r))) '(0 NIL))) (assert (equal? ((λ ((x 0) . r) (list x r)) 1 2 3) '(1 (2 3)))) ; keyword arguments (assert (keyword? :kw)) (assert (eq? :kw ':kw)) (assert-fail (set! :kw 0) const-error) (assert-fail (set-top-level-value! :kw 0) const-error) (assert (not (keyword? 'kw:))) (assert (not (keyword? 'kw))) (assert (not (keyword? ':))) (assert (equal? ((λ (x (a 2) (:b a) . r) (list x a b r)) 1 0 8 4 5) '(1 0 0 (8 4 5)))) (assert (equal? ((λ (x (a 2) (:b a) . r) (list x a b r)) 0 :b 3 1) '(0 2 3 (1)))) (def (keys4 (:a 8) (:b 3) (:c 7) (:d 6)) (list a b c d)) (assert (equal? (keys4 :a 10) '(10 3 7 6))) (assert (equal? (keys4 :b 10) '(8 10 7 6))) (assert (equal? (keys4 :c 10) '(8 3 10 6))) (assert (equal? (keys4 :d 10) '(8 3 7 10))) (assert-fail (keys4 :e 10)) ; unsupported keyword (assert-fail (keys4 :a 1 :b)) ; keyword with no argument (def (keys1 (:a 8)) (+ a 1)) (assert (equal? (keys1 :a 11) 12)) ; cvalues and arrays (assert (equal? (type-of "") 'str)) (assert-fail (aref #(1) 3) bounds-error) (def iarr (arr 's64 32 16 8 7 1)) (assert (equal? (aref iarr 0) 32)) (assert (equal? (aref iarr #s8(3)) 7)) (assert (equal? (aref (arr 'rune #\ß) 0) #\ß)) (assert-fail (arr 'bignum 0)) (assert-fail (arr 'fixnum 0)) (assert-fail (arr 'str 0)) (assert-fail (arr 'io 0)) ; gensyms (assert (gensym? (gensym))) (assert (not (gensym? 'a))) (assert (not (eq? (gensym) (gensym)))) (assert (not (equal? (str (gensym)) (str (gensym))))) (let ((gs (gensym))) (assert (eq? gs gs))) (load "color.sl") (assert (equal? (color-pairs (generate-5x5-pairs) '(a b c d e)) '((23 . a) (9 . a) (22 . b) (17 . d) (14 . d) (8 . b) (21 . e) (19 . b) (16 . c) (13 . c) (11 . b) (7 . e) (24 . c) (20 . d) (18 . e) (15 . a) (12 . a) (10 . e) (6 . d) (5 . c) (4 . e) (3 . d) (2 . c) (0 . b) (1 . a)))) (assert (let ((ts (time->str (time-now)))) (eqv? ts (time->str (str->time ts))))) (assert (= 0 (str->time (time->str 0)))) (assert (= 0 (str->time (time->str (bignum 0))))) (assert (= 0 (str->time (time->str (s32 0))))) (assert (equal? 0.0 (+ 0.0 0))) ; tests that + no longer does inexact->exact (assert (equal? 1.0 (* 1.0 1))) ; tests that * no longer does inexact->exact (let ((c #\a)) (assert (equal? (print-to-str (list c c)) "(#\\a #\\a)"))) (assert-fail (eval '(set! (car (cons 1 2)) 3))) (assert (equal? `(a `(b c)) '(a (quasiquote (b c))))) (assert (equal? ````x '```x)) (assert (equal? (append 1) 1)) (assert (equal? (append NIL 1) 1)) (assert (equal? (append) NIL)) (assert (equal? (append NIL) NIL)) (assert (equal? (append NIL NIL) NIL)) (assert (equal? (append '(1 2)) '(1 2))) (assert (equal? (append '(1 2) '(3 4)) '(1 2 3 4))) (let* {[l1 '(0 1)] [l2 '(2 3)] [a (append l1 l2)]} (assert (equal? a (iota 4))) (aset! l1 1 "hi") (assert (equal? a (iota 4))) (aset! l2 1 "blah") (assert (equal? a '(0 1 2 "blah")))) ;; circular list (def a '#0=(1 . #0#)) (eq? (cdr a) a) (assert (not (length a))) ;; improper list (assert-fail (length '(1 2 . 3)) type-error) ;; unbinding (assert-fail (makunbound :kw) const-error) (def +some-const+ 1) (assert-fail (def +some-const+ 2) const-error) (assert-fail (makunbound '+some-const+) const-error) (def abc 1) (assert (equal? (bound? 'abc) T)) (assert (equal? (eval '(+ abc 1)) 2)) (makunbound 'abc) (assert (equal? (bound? 'abc) NIL)) (assert-fail (eval '(+ abc 1)) unbound-error) ;; c***r of empty list (assert (not (car NIL))) (assert (not (cdr NIL))) (assert (not (cadr NIL))) (assert (not (cdar NIL))) (assert (not (caaar NIL))) (assert (not (cdddr NIL))) (assert (not (cadr '(1)))) ;; for-each with multiple lists (def q NIL) (for-each (λ (x y) (set! q (cons (+ x y) q))) #(1 2 3) #vu8(4 5 6)) (assert (equal? q '(9 7 5))) (def q 0) (for-each (λ (x y) (set! q (+ x y q))) '(1) '(3 9)) (assert (equal? q 4)) (for-each (λ (x y) (set! q (+ x y q))) '(1 2) '(3)) (assert (equal? q 8)) (for-each (λ (x y z) (set! q (+ x y z q))) '(1 2) '(3) '(4 5)) (assert (equal? q 16)) ;; map with multiple lists (assert (equal? (map (λ (x y z) (+ x y z)) '(1 2 3) '(4 5 6) '(7 8 9)) '(12 15 18))) (assert (equal? (map (λ (x y) (+ x y)) '(1) '(3 9)) '(4))) (assert (equal? (map (λ (x y) (+ x y)) '(1 2) '(3)) '(4))) (assert (equal? (map (λ (x y z) (+ x y z)) '(1 2) '(3) '(4 5)) '(8))) ;; not a sequence (assert-fail (map str 'a) type-error) (assert-fail (map str '(1) 'a) type-error) (assert-fail (for-each print 'a) type-error) (assert-fail (for-each print '(1) 'a) type-error) ;; list copying (assert (equal? (copy-list (iota 50)) (iota 50))) (assert (equal? (copy-list (iota 50) 51) (iota 50))) (assert (equal? (copy-list (iota 50) 25) (iota 25))) (assert (not (copy-list NIL 25))) (assert (not (copy-list NIL))) (assert (not (copy-list (iota 50) 0))) (let* {[l (iota 10)] [c (copy-list l)]} (aset! l 3 5) (aset! c 4 23) (assert (= (aref l 3) 5)) (assert (= (aref c 3) 3)) (assert (= (aref l 4) 4)) (assert (= (aref c 4) 23))) ;; vec copying (def v (vec 0 1 2 3)) (def v1 (copy-vec v)) (assert (not (eq? v v1))) (assert (equal? v v1)) (aset! v1 2 "hi") (assert (equal? (vec 0 1 2 3) v)) (assert (equal? (vec 0 1 "hi" 3) v1)) (defstruct blah a b) (assert-fail (copy-vec (make-blah :a 0 :b "hi")) type-error) (assert (equal? (subseq (iota 20) 10) '(10 11 12 13 14 15 16 17 18 19))) (assert (equal? (subseq (iota 20) 10 15) '(10 11 12 13 14))) (assert (equal? (subseq (apply vec (iota 20)) 10) (vec 10 11 12 13 14 15 16 17 18 19))) (assert (equal? (subseq (apply vec (iota 20)) 10 15) (vec 10 11 12 13 14))) (assert (equal? (subseq (apply arr (cons 'u32 (iota 20))) 10) (arr 'u32 10 11 12 13 14 15 16 17 18 19))) (assert (equal? (subseq (apply arr (cons 'u32 (iota 20))) 10 15) (arr 'u32 10 11 12 13 14))) (assert-fail (subseq (iota 10) 11)) (assert-fail (subseq (iota 10) 5 11)) (assert-fail (subseq (iota 10) 6 5)) (assert-fail (subseq (apply vec (iota 10)) 11)) (assert-fail (subseq (apply vec (iota 10)) 5 11)) (assert-fail (subseq (apply vec (iota 10)) 6 5)) (assert (not (subseq (iota 10) 10))) (assert (not (subseq NIL 0))) (assert (equal? (subseq (apply vec (iota 10)) 10) (vec))) (assert (equal? (subseq (vec) 0) (vec))) (assert (equal? (subseq cl 1 8) '(2 3 1 2 3 1 2))) (assert (equal? (subseq "йцукен" 1 4) "цук")) (assert (equal? (subseq "йцукен" 6) "")) (assert-fail (subseq "йцукен" 7)) ;; map with different return types (assert (equal? (map 'vec + '(1 2 3) '(4 5 6) '(7 8 9)) (vec 12 15 18))) (assert (equal? (map '(arr s32) + '(1 2 3) '(4 5 6) '(7 8 9)) (arr 's32 12 15 18))) (def tbl (table "hi" 32 109234 "blah")) (assert (equal? (get (map cons tbl) "hi") 32)) (assert (equal? (get (map cons tbl) 109234) "blah")) (assert (equal? (map + (vec 1 2 3) (vec 4 5 6)) (vec 5 7 9))) (assert-fail (map + (vec 1 2 3) '(4 5 6))) (assert (equal? (map 'vec + (vec 1 2 3) '(4 5 6)) (vec 5 7 9))) (assert (equal? (map 'list + (vec 1 2 3) '(4 5 6)) '(5 7 9))) (assert (equal? (map 'str + (vec 1 2 3) '(4 5 6)) "579")) (assert (equal? (map '(arr s16) + (vec 1 2 3) '(4 5 6)) (arr 's16 5 7 9))) (assert-fail (map 'wrong + (vec 1 2 3))) (assert-fail (map (vec) + (vec 1 2 3))) (assert-fail (map (arr 'u8 1) + (vec 1 2 3))) (let* {[big-s (str-rep "hello йцукен" 100)] [big-s-copy (str-rep "hello йцукен" 100)] [len (length big-s)]} (assert (equal? (map 'list identity big-s) (map-int (λ (i) (str-rune big-s-copy i)) len)))) ;; aref with multiple indices (def a #(#(0 1 2) #(3 (4 5 6) 7))) (assert (equal? 0 (aref a 0 0))) (assert (equal? 0 (apply aref (list a 0 0)))) (assert (equal? 2 (aref a 0 2))) (assert (equal? 3 (aref a (1+ 0) 0))) (assert (equal? 7 (aref a 1 2))) (assert (equal? 5 (aref a 1 (1+ 0) 1))) (assert-fail (aref a 1 1 3) bounds-error) (assert (equal? #\l (rune (aref #("hello") 0 2)))) (assert (equal? #\o (rune (aref #("hello") 0 (1+ 3))))) (assert-fail (aref #("hello") 0 5) bounds-error) (assert-fail (aref #("hello") 1 0) bounds-error) (assert-fail (aref '(NIL) 0 0)) (assert-fail (apply aref '((NIL) 0 0))) ;; aset with multiple indices (def a #(#(0 1 2) #(3 (4 5 6) 7))) (assert (equal? 8 (apply aset! (list a 0 0 8)))) (assert (equal? 9 (aset! a 1 1 (1+ 1) 9))) (assert (equal? "hello" (aset! a (1+ 0) 2 "hello"))) (assert-fail (aset! a 1 1 3 "nope")) (assert (equal? a #(#(8 1 2) #(3 (4 5 9) "hello")))) (assert-fail (aset! '(NIL) 0 0 1)) (assert-fail (apply aset! '((NIL) 0 0 1))) ;; apply with multiple args (assert (equal? 15 (apply + 1 2 '(3 4 5)))) (assert-fail (apply + 1 2 3)) ; last arg not a list ;; make many initialized tables large enough not to be stored in-line (for 0 100 (λ (i) (table eq? 2 eqv? 2 equal? 2 atom? 1 not 1 nan? 1 cons? 1 sym? 1 num? 1 bound? 1 cons? 1 builtin? 1 vec? 1 fixnum? 1 cons 2 car 1 cdr 1 set-car! 2 set-cdr! 2 = 2 < 2 compare 2 aref 2 aset! 3 div0 2 'hello 4 'goodbye 5 'foo 6 'bar 7))) ;; now allocate enough to trigger GC (for 0 8000000 (λ (i) (cons 1 2))) ;; brieflz bindings (let* ((s (file "unit.sl")) (in (io-read-all s))) (princ "lz packing (" (size-of in) " bytes):") (for -1 12 (λ (level) (let* ((packed (lz-pack in level)) (unpacked (lz-unpack packed :size (size-of in))) (unpacked2 (arr-alloc 'u8 (size-of in) 0))) (assert (< (size-of packed) (size-of in))) (assert (equal? in unpacked)) (assert (eq? unpacked2 (lz-unpack packed :to unpacked2))) (assert (equal? in unpacked2)) (princ " [" level "→" (size-of packed) "]")))) (io-close s) (newline)) (assert (equal? #vu8(39) (lz-unpack (lz-pack (u8 39)) :size 1))) (def i (arr 'u64 0 1 2 3)) (def p (lz-pack i)) (assert (> (size-of i) (size-of p))) (assert (equal? (type-of p) '(arr u8))) (def d (arr-alloc 'u64 (length i) 0)) (assert (eq? d (lz-unpack p :to d))) (assert (equal? i d)) (assert-fail (lz-pack) arity-error) (assert-fail (lz-pack "" 0 0) arity-error) (assert-fail (lz-unpack) arity-error) (assert-fail (lz-unpack (arr 'u8)) arity-error) (assert-fail (lz-unpack (arr 'u8) :size) arity-error) (assert-fail (lz-unpack (arr 'u8) :to) arity-error) (assert-fail (lz-unpack (arr 'u8) :size 0 0) arity-error) (assert-fail (lz-unpack (arr 'u8) :size 1) arg-error) (assert-fail (lz-unpack (arr 'u8) :blah 0) arg-error) (assert-fail (lz-unpack (vec 0) :size 1) type-error) ;; macro vs function priority (def (!! x y) (- x y)) (assert (eq? 3 (!! 5 2))) (defmacro (!! x y z) (+ z (apply !! (list x y)))) (assert (eq? 4 (!! 5 2 1))) (def s "привет\0пока") (def s2 "hello \t \n world\n ") (assert (eq? 21 (size-of s))) (assert (eq? 11 (length s))) (def a (arr 'u16 1 2 3)) (assert (eq? 6 (size-of a))) (assert (eq? 3 (length a))) (assert (equal? "акоп\0тевирп" (str-reverse s))) (assert (equal? "" (str-reverse ""))) (assert (equal? "й" (str-reverse "й"))) (assert (equal? "wб☺🡷⁹гq" (str-reverse "qг⁹🡷☺бw"))) (assert (str-utf8? "")) (assert (str-utf8? "wб☺🡷⁹гq")) (assert (not (str-utf8? "\xfffe"))) (assert (equal? (with-output (b) (with-output-to b (for-each print "йцукен"))) «#\й#\ц#\у#\к#\е#\н»)) (assert (equal? (with-output (b) (write "a\x0a\x09\\\x07\x08\x1b\x0c\x0d\x0b" b)) «"a\n\t\\\a\b\e\f\r\v"»)) (defmacro (print-with-length n . args) `(with-bindings ((*print-length* ,n)) (print-to-str ,@args))) (assert (equal? (print-with-length 2 '(1)) "(1)")) (assert (equal? (print-with-length 2 '(1 2)) "(1 2)")) (assert (equal? (print-with-length 2 '(1 2 3)) "(1 2 ...)")) (assert (equal? (print-with-length 2 '(1 2 3 4)) "(1 2 ...)")) (assert (equal? (print-with-length 2 #(1)) "#(1)")) (assert (equal? (print-with-length 2 #(1 2)) "#(1 2)")) (assert (equal? (print-with-length 2 #(1 2 3)) "#(1 2 ...)")) (assert (equal? (print-with-length 2 #(1 2 3 4)) "#(1 2 ...)")) (assert (equal? (print-with-length 2 (arr 'u8 1)) "#vu8(1)")) (assert (equal? (print-with-length 2 (arr 'u8 1 2)) "#vu8(1 2)")) (assert (equal? (print-with-length 2 (arr 'u8 1 2 3)) "#vu8(1 2 ...)")) (assert (equal? (print-with-length 2 (arr 'u8 1 2 3 4)) "#vu8(1 2 ...)")) (assert (equal? (print-to-str) "")) (assert (= 10 (str-width s))) (assert (= 2 (str-width (str "a" (rune #x200d) "bc")))) ; zero width join (assert (= 3 (str-width "a☃b"))) (assert (= 4 (str-width (str "a☃" (rune #xfe0f) "b")))) ; vs16 (assert (= 0 (str-width ""))) (assert (= 1 (str-width #\q))) (assert (= 1 (str-width #\й))) (assert (= 0 (str-width #\nul))) (assert (not (str-width #\newline))) (assert (not (str-width "hello\r"))) (assert (not (str-width "bye\1"))) (assert (not (str-width "\xe2\x98"))) (assert (not (str-width "\xfe\xff\xfe\xff"))) (assert-fail (str-width 123)) (assert-fail (str-width 'blah)) (assert-fail (str-width str-width)) (defmacro (print-with-width n . args) `(with-bindings ((*print-width* ,n)) (print-to-str ,@args))) (defmacro (princ-with-width n . args) `(with-bindings ((*print-width* ,n)) (princ-to-str ,@args))) (assert (equal? (print-with-width NIL "hello") "\"hello\"")) (assert (equal? (princ-with-width NIL "hello") "hello")) (assert (equal? (princ-with-width 3 "hello") "hel...")) (assert (equal? (princ-with-width 5 "hello") "hello")) (assert (equal? (princ-with-width 0 "hello") "...")) (assert (equal? (print-with-width 3 "hello") "\"hel...\"")) (assert (equal? (print-with-width 3 '("hello" "world")) "(\"hel...\" \"wor...\")")) (assert (equal? (princ-with-width 2 "ab𲎿c") "ab...")) (assert (equal? (princ-with-width 3 "ab𲎿c") "ab...")) (assert (equal? (princ-with-width 4 "ab𲎿c") "ab𲎿...")) (assert (equal? (princ-with-width 5 "ab𲎿c") "ab𲎿c")) ; cluster can't be split; vs16/vs15; 🗑︎ vs🗑️ (width 1 vs 2) (assert (equal? (princ-with-width 3 (str (rune #x1f5d1) (rune #xfe0f) "!")) "🗑️!")) (assert (equal? (princ-with-width 2 (str (rune #x1f5d1) (rune #xfe0f) "!")) "🗑️...")) (assert (equal? (princ-with-width 2 (str (rune #x1f5d1) (rune #xfe0e) "!")) "🗑︎!")) (assert (equal? (princ-with-width 1 (str (rune #x1f5d1) (rune #xfe0e) "!")) "🗑︎...")) ; cluster can't be split; ZWJ (assert (equal? (princ-with-width 2 "\U1faf1\U1f3fe\U200d\U1faf2\U1f3ff") "🫱🏾‍🫲🏿")) (assert (equal? (princ-with-width 1 "\U1faf1\U1f3fe\U200d\U1faf2\U1f3ff") "...")) (assert (equal? (princ-with-width 3 (arr 'rune #\a #\b #\c #\d)) "abc...")) (assert (equal? (princ-with-width 2 (arr 'rune #\a #\b #\c)) "ab...")) (assert (equal? (princ-with-width 1 (arr 'rune #\a #\𲎿 #\b)) "a...")) (assert (equal? (princ-with-width 3 (arr 'rune #\a #\𲎿 #\b)) "a𲎿...")) ; control char - print in full (assert (equal? (princ-with-width 2 "ab\ncd") "ab\ncd")) (assert (equal? '("привет" "пока") (str-split s "\0"))) (assert (equal? '("пр" "вет" "пок" "") (str-split s "аи\0"))) (assert (equal? '("" "") (str-split "1" "1"))) (assert (equal? '("hello" "world") (str-split s2 :trim T))) (assert (equal? '("hello" "\t" "\n" "world\n") (str-split s2 " " :trim T))) (assert (equal? (list s2) (str-split s2 "X" :trim T))) (assert (equal? (list s2) (str-split s2 "X"))) (assert (equal? #\а (str-rune s 10))) (assert (equal? #\nul (str-rune s 6))) (assert-fail (str-rune s 11)) (def big-s (str-rep "пbиlеa" 100)) (for 0 100 (λ (i) (assert (equal? #\п (str-rune big-s (* 6 i)))))) (for 0 100 (λ (i) (assert (equal? #\l (str-rune big-s (+ (* 6 i) 3)))))) (def big-s (str-rep s 100)) (for 0 100 (λ (i) (assert (equal? #\п (str-rune big-s (* 11 i)))))) (for 0 100 (λ (i) (assert (equal? #\п (str-rune big-s (* 11 (- 99 i))))))) (for 0 100 (λ (i) (assert (equal? #\а (str-rune big-s (+ (* 11 i) 10)))))) (for 0 100 (λ (i) (assert (equal? #\nul (str-rune big-s (+ (* 11 i) 6)))))) (for 0 100 (λ (i) (assert (equal? s (str-sub big-s (* 11 i) (+ (* 11 i) 11)))))) (assert (equal? #\W (rune-upcase #\w))) (assert (equal? #\П (rune-upcase #\п))) (assert (equal? #\nul (rune-upcase #\nul))) (assert (rune-upper-case? #\W)) (assert (rune-upper-case? #\П)) (assert (not (rune-upper-case? #\nul))) (assert (not (rune-upper-case? #\w))) (assert (not (rune-upper-case? #\п))) (assert (not (rune-upper-case? #\nul))) (assert (equal? #\w (rune-downcase #\W))) (assert (equal? #\п (rune-downcase #\П))) (assert (equal? #\nul (rune-downcase #\nul))) (assert (rune-lower-case? #\w)) (assert (rune-lower-case? #\п)) (assert (not (rune-lower-case? #\nul))) (assert (not (rune-lower-case? #\W))) (assert (not (rune-lower-case? #\П))) (assert (not (rune-lower-case? #\nul))) (assert (rune-numeric? #\0)) (assert (rune-numeric? #\9)) (assert (not (rune-numeric? #\⁰))) (assert (not (rune-numeric? #\q))) (assert (rune-whitespace? #\space)) (assert (rune-whitespace? #\tab)) (assert (rune-whitespace? #\vtab)) (assert (rune-whitespace? #\newline)) (assert (rune-whitespace? #\x00a0)) (assert (rune-whitespace? #\x3000)) (assert (not (rune-whitespace? #\x200b))) (assert (rune-alphabetic? #\q)) (assert (rune-alphabetic? #\й)) (assert (not (rune-alphabetic? #\⁰))) (assert (not (rune-alphabetic? #\0))) (assert (not (rune-title-case? #\DŽ))) (assert (equal? #\Dž (rune-titlecase #\DŽ))) (assert (rune-title-case? #\Dž)) (assert-fail (rune "") type-error) (assert-fail (rune 'a) type-error) (assert-fail (rune 1 2) arity-error) (assert (= (rune->codepoint (rune)) #xfffd)) (def s "hello й goodbye") (assert (= 4 (str-find s #\o))) (assert (= 9 (str-find s #\o 5))) (assert (= 10 (str-find s #\o 10))) (assert (not (str-find s #\o 11))) (assert (not (str-find s #\o 15))) (assert (= 4 (str-find s "o"))) (assert (= 2 (str-find s "ll"))) (assert (not (str-find s "ll" 3))) (assert (= 0 (str-find s ""))) (assert (= 7 (str-find s "" 7))) (assert (= 6 (str-find s #\й))) (assert (= 6 (str-find s #\й 6))) (assert-fail (str-find s #\o -1)) (assert-fail (str-find s #\o 16)) (assert-fail (str-find s 0)) (assert-fail (str-find s (utf8 #\o))) (def big-s (str-rep s 100)) (for 0 100 (λ (i) (assert (= (+ (* (length s) i) 4) (str-find big-s #\o (* (length s) i)))))) (assert (not (str-find "" "1"))) (assert (not (str-find "1" "11"))) (assert (equal? "1.5" (num->str 1.5))) (assert (equal? "-3039" (num->str (s16 -12345) :base 16))) (assert (equal? "111111111111111111111111111111111" (num->str 111111111111111111111111111111111))) (assert (equal? "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" (num->str #xfffffffffffffffffffffffffffffffff :base 16))) (assert-fail (num->str 1.5 :base 16)) (assert-fail (num->str (bignum 0) :base 36)) (assert (= 1.5 (str->num "1.5"))) (assert (= -12345 (str->num "-3039" :base 16))) (assert (= 111111111111111111111111111111111 (str->num "111111111111111111111111111111111"))) (assert (= #xfffffffffffffffffffffffffffffffff (str->num "fffffffffffffffffffffffffffffffff" :base 16))) (assert (= (size-of 'rune) 4)) (assert (= (size-of #\я) 2)) (assert (= (size-of #\⁹) 3)) (assert (= (size-of '(arr rune 3)) 12)) (assert (= (size-of (u8 0)) 1)) (assert (= (size-of 'u8) 1)) (assert (= (size-of '(arr u8 5)) 5)) (assert (= (size-of (u16 0)) 2)) (assert (= (size-of 'u16) 2)) (assert (= (size-of '(arr u16 5)) 10)) (assert (= (size-of (u32 0)) 4)) (assert (= (size-of 'u32) 4)) (assert (= (size-of '(arr u32 5)) 20)) (assert (= (size-of (u64 0)) 8)) (assert (= (size-of 'u64) 8)) (assert (= (size-of '(arr u64 5)) 40)) (assert-fail (size-of (bignum 0)) type-error) (assert-fail (size-of 'bignum) type-error) (assert-fail (size-of '(arr bignum 8)) type-error) (assert-fail (= (length #\я) 2)) (assert-fail (= (length #\⁹) 3)) (assert-fail (= (length (u8 0)) 1)) (assert-fail (= (length (u16 0)) 2)) (assert-fail (= (length (u32 0)) 4)) (assert-fail (= (length (u64 0)) 8)) (assert-fail (= (length (bignum 0)) 0)) (def blah T) (assert (eq? (sym 'blah) 'blah)) (def hitheresymbol123 NIL) (assert (eq? (sym "hi" "there" 'symbol 123) 'hitheresymbol123)) (assert-fail (sym) arity-error) (assert-fail (exit "error" 2 0) arity-error) (assert (not (int-valued? T))) (assert (not (int-valued? NIL))) (assert (not (int-valued? #\x))) (assert (not (int-valued? -nan.0))) (assert (not (int-valued? +inf.0))) (assert (int-valued? 1.0)) (assert (int-valued? -1.0)) (assert (int-valued? 1.0f)) (assert (int-valued? -1.0f)) (assert (int-valued? (u8 1))) (assert (int-valued? (p32 1))) (assert (int-valued? (p64 #x7fffffffffff))) (assert (int-valued? (bignum 0))) (assert (int-valued? (f32 (ash 1 127)))) (assert (int-valued? (f32 (ash -1 127)))) (assert (int-valued? (f64 (ash 1 1023)))) (assert (int-valued? (f64 (ash -1 1023)))) (assert (num? 1.3)) (assert (num? -1.3)) (assert (num? 1.3f)) (assert (num? -1.3f)) (assert (not (num? #\я))) (assert (int? 0)) (assert (int? (bignum 0))) (assert (= 12345 (fixnum (bignum 12345)))) (assert (= -12345 (fixnum (bignum -12345)))) (assert (= 1.0 (truncate 1.3))) (assert (= -1.0 (truncate -1.3))) (assert (= 1.0 (truncate 1.3))) (assert (= -1.0 (truncate -1.3))) (assert (= 1.0 (truncate 1.3f))) (assert (= -1.0 (truncate -1.3f))) (assert (= 1.0 (truncate 1.3f))) (assert (= -1.0 (truncate -1.3f))) (assert (= 1 (truncate (bignum 1)))) (assert (= -1 (truncate (bignum -1)))) (assert (= 123 (truncate (s64 123)))) (assert (= -123 (truncate (s8 -123)))) (assert (< +most-positive-fixnum+ (truncate (f64 (* 2 +most-positive-fixnum+))))) (assert (> +most-negative-fixnum+ (truncate (f64 (* 2 +most-negative-fixnum+))))) (assert (= -18446744073709551616 (truncate (f64 -18446744073709551616)))) (assert (= -18446744073709551616 (truncate (f64 (ash -1 64))))) (assert (= -36893488147419103232 (truncate (f64 -36893488147419103232)))) (assert (= -36893488147419103232 (truncate (f64 (ash -1 65))))) (assert (= (ash 1 1023) (truncate (f64 (ash 1 1023))))) (assert (= (ash -1 1023) (truncate (f64 (ash -1 1023))))) (assert (= 1 (ash (truncate (f64 (ash 1 1023))) -1023))) (assert (equal? +inf.0 (truncate +inf.0))) (assert (equal? -inf.0 (truncate -inf.0))) (assert (nan? (truncate -nan.0))) (assert (nan? (truncate +nan.0))) (assert-fail (truncate "blah")) (assert-fail (truncate 'blah)) (assert-fail (truncate truncate)) (assert (= 0 (sin 0))) (assert (= 0 (sin 0.0))) (assert (= 0 (sin 0.0f))) (assert (= 0 (sin (s64 0)))) (assert (= 0 (sin (bignum 0)))) (let ((x (cos 0))) (assert (and (>= x 0.999999999999999) (<= x 1.0)))) (assert (= 3 (sqrt 9))) (assert (= 3 (log 1000 10))) (assert (= 0 (log 1))) (assert (= 1 (exp 0))) (assert (= 1 (log (exp 1)))) (assert-fail (acos acos) type-error) (assert-fail (asin asin) type-error) (assert-fail (atan atan) type-error) (assert-fail (ceiling ceiling) type-error) (assert-fail (cos cos) type-error) (assert-fail (cosh cosh) type-error) (assert-fail (exp exp) type-error) (assert-fail (expt expt expt) type-error) (assert-fail (floor floor) type-error) (assert-fail (log log) type-error) (assert-fail (sin sin) type-error) (assert-fail (sinh sinh) type-error) (assert-fail (sqrt sqrt) type-error) (assert-fail (tan tan) type-error) (assert-fail (tanh tanh) type-error) (assert-fail (acos (rune 0)) type-error) (assert (= (length (table "hello" "goodbye" 123 456)) 2)) (assert-fail (table 1)) (assert-fail (table 1 2 3)) (def ta (table 1 2 "3" 4 'foo 'bar)) (assert (= (length ta) 3)) (def b (buffer)) (write ta b) (io-pos! b 0) (assert (equal? (read b) #table(1 2 foo bar "3" 4))) (assert (table? ta)) (assert (not (table? "nope"))) (assert-fail (get ta 3)) (assert-fail (get ta "foo")) (assert-fail (get ta 1+)) (assert (= 2 (get ta 1))) (assert (= 4 (get ta "3"))) (def tb (copy-table ta)) (assert (not (eq? ta tb))) (assert (eqv? ta tb)) (assert (equal? ta tb)) (assert (has? ta 'foo)) (assert (eq? 'bar (get ta 'foo))) (assert (eq? ta (del! ta 'foo))) (assert (not (has? ta 'foo))) (assert-fail (get ta 'foo)) (assert (= (length ta) 2)) (assert (del! ta 'foo)) (assert (= (length ta) 2)) (assert (eq? ta (put! ta 'foo 'bar))) (assert (= (length ta) 3)) (assert (eq? 'bar (get ta 'foo))) (assert-fail (get "blah" 0)) (assert-fail (get (list 0 1) 0)) (assert (equal? (list 1 1 1) #0=(list 1 #1=1 #1#))) (assert-fail (sleep 1 2)) (sleep) (sleep 0) (def t₀ (nanoseconds-monotonic)) (sleep 1) (def t₁ (nanoseconds-monotonic)) (def Δt (- t₁ t₀)) (assert (and (< Δt 1050000000 ) (> Δt 995000000))) (gc) ;; auto gensym (defmacro (f2 x) `(begin (set-top-level-value! 'a# (* ,x ,x)) (+ a# ,x))) (defmacro (g2 x) `(begin (set-top-level-value! 'a# ,x) (+ (f2 ,x) a#))) (assert (= (f2 3) 12)) (assert (= (g2 3) 15)) (defmacro (f x) `(let ((a# 1)) (list a# ,x))) (defmacro (g x) `(let ((a# 2)) (list a# ,x))) (assert (equal? '(1 (2 3)) (f (g 3)))) ; a-supplied is NIL (assert-fail (eval '(def (f (a 0 NIL)) NIL))) (assert (= 0 (length NIL))) ; os-getenv + os-setenv (assert (not (os-getenv "thisenvvarisnotdefined"))) (assert (str? (os-getenv (if (equal? +os-name+ "plan9") "path" "PATH")))) (assert (not (os-getenv "thisvarisdefined"))) (assert (os-setenv "thisvarisdefined" "a value")) (assert (equal? (os-getenv "thisvarisdefined") "a value")) (assert (os-setenv "thisvarisdefined" NIL)) (assert (not (os-getenv "thisvarisdefined"))) (assert-fail (os-getenv)) (assert-fail (os-getenv "abc" "def") arity-error) (assert-fail (os-setenv) arity-error) (assert-fail (os-setenv "" "def") arg-error) (if (equal? +os-name+ "plan9") (begin (assert-fail (os-setenv ".." "def")) (assert (not (os-getenv "..")))) (begin (assert-fail (os-setenv "a=b" "def")) (assert (not (os-getenv "a=b"))))) ; env variable value is copied (def e "test") (os-setenv e "blah1") (def v (os-getenv e)) (dotimes (i 1024) (assert (equal? v "blah1")) (os-setenv e NIL) (assert (equal? v "blah1")) (os-setenv e (str i))) (assert (int? +most-positive-fixnum+)) (assert (> +most-positive-fixnum+ 0)) (assert (int? +most-negative-fixnum+)) (assert (< +most-negative-fixnum+ 0)) (assert (equal? (remove-duplicates '(a 0 b c1 a b 3 c 5)) '(a 0 b c1 3 c 5))) (assert (equal? (str-trim "1λ1 hello 1λ11" NIL (λ (r) (str-find "1 λ" r))) "1λ1 hello")) (assert (equal? (str-trim "1λ1 hello 1λ11" (λ (r) (str-find "1 λ" r)) NIL) "hello 1λ11")) (assert (equal? (str-trim "1λ1 hello 1λ11" (λ (r) (str-find "1 λ" r))) "hello")) (assert (equal? (str-trim " \t\nhello\v\f\r") "hello")) (assert (rune #xd7ff)) (assert-fail (rune #xd800) arg-error) (assert-fail (rune #xdfff) arg-error) (assert (rune #xe000)) (assert (rune #x10ffff)) (assert-fail (rune #x110000) arg-error) (assert-fail (eval '(set! undefined-variable 0))) (assert-fail (eval '(set! "invalid name" 0))) (assert-fail (eval '(set!))) (def a NIL) (def b NIL) (def c NIL) (def d NIL) (set! a 0) (set! b a c b a 1 d a) (assert (= a 1)) (assert (= b 0)) (assert (= c 0)) (assert (= d 1)) (assert-fail (eval '(set! a 0 b 0 c)) arg-error) (assert (equal? "»«" «\»«»)) (assert (equal? "«»" ««\»»)) ;; type-of (assert (eq? (type-of '(1)) 'cons)) (assert (eq? (type-of NIL) 'null)) (assert (eq? (type-of T) 'bool)) (assert (eq? (type-of 0) 'fixnum)) (assert (eq? (type-of 'blah) 'sym)) (assert (eq? (type-of (void)) (void))) (assert (eq? (type-of (read (buffer))) (read (buffer)))) ; eof (assert (eq? (type-of (vec)) 'vec)) (assert (eq? (type-of #\x) 'rune)) (assert (eq? (type-of (u32 12345)) 'u32)) (assert (eq? (type-of 1.2345f) 'f32)) (assert (eq? (type-of 1.2345) 'f64)) (assert (eq? (type-of (p32 123)) 'p32)) (assert (eq? (type-of (p64 123)) 'p64)) (assert (eq? (type-of type-of) 'fn)) (assert (eq? (type-of sort) 'fn)) (assert (equal? (type-of (arr 'rune #\x)) '(arr rune))) (assert (equal? (type-of (arr 'u8)) '(arr u8))) (assert (equal? (type-of (arr 'f32)) '(arr f32))) ;; different bases (assert (equal? (num->str 12345) "12345")) (assert (equal? (num->str 12345 :base 32) "GA4Q")) (assert (equal? (num->str 12345 :base 16) "3039")) (assert (equal? (num->str 12345 :base 2) "11000000111001")) (assert (= (str->num "3039" :base 16) 12345)) (assert (= (str->num "#x3039") 12345)) (assert (= (str->num "#X3039") 12345)) (assert (= (str->num "#d3039") 3039)) (assert (= (str->num "#b11000000111001") 12345)) (assert (= (str->num "#32rGA4Q") 12345)) ;; folding (assert (equal? (reverse! (iota 5)) (foldl cons NIL (iota 5)))) (assert (equal? (iota 5) (foldr cons NIL (iota 5)))) (assert (equal? (reverse! (iota 5)) (foldl cons NIL (apply vec (iota 5))))) (assert (equal? (iota 5) (foldr cons NIL (apply vec (iota 5))))) (assert (equal? (map 'list identity (str-reverse "hello йцукен")) (foldl cons NIL "hello йцукен"))) (assert (equal? (map 'list identity "hello йцукен") (foldr cons NIL "hello йцукен"))) ;; random (assert-fail (random-state?) arity-error) (assert-fail (random-state? NIL NIL) arity-error) (assert (not (random-state? (list 'pcg32x2 0 1 2 3)))) (assert (not (random-state? (cons 'pcg32x2 #arr(u64 0 1 2))))) (assert (not (random-state? (cons 'pcg32x2 #arr(u32 0 1 2 3))))) (assert (not (random-state? (cons 'blah #arr(u64 0 1 2 3))))) (assert-fail (make-random-state 0) type-error) (assert-fail (make-random-state T 1) arity-error) (assert (not *random-state*)) (assert (not (random-state? *random-state*))) (def x (make-random-state T)) (assert x) (assert (random-state? x)) (assert (not *random-state*)) ; T does not change current state (assert (not (random-state? *random-state*))) (def y (make-random-state T)) (assert (random-state? y)) (assert (not (eq? x y))) ; different state (assert (not (equal? x y))) ; different state (def y (make-random-state x)) (assert (random-state? y)) (assert (not (eq? x y))) ; different state (assert (equal? x y)) ; but is a copy (def x (make-random-state)) (assert (random-state? x)) (assert *random-state*) ; no longer NIL (assert (random-state? *random-state*)) (assert (not (eq? x *random-state*))) ; different state (assert (equal? x *random-state*)) ; but is a copy (def y (make-random-state x)) (assert (random-state? y)) (random 10 x) (assert (random-state? x)) (assert (not (equal? x y))) ; state x changed (assert (not (equal? x *random-state*))) ; ditto (random 10 y) (assert (equal? x y)) ; arriving to the same state since it was a copy (assert (random-state? y)) (let ((ru32 (table)) (ru64 (table)) (rf64 (table)) (rf32 (table))) (dotimes (i 100) (put! ru32 (u32 (random #xffffffff)) 1) (put! ru64 (u64 (random #xffffffffffffffff)) 1) (put! rf64 (random 1.0) 1) (put! rf32 (random 1.0f) 1)) (assert (< 90 (length ru32))) (assert (< 90 (length ru64))) (assert (< 90 (length rf64))) (assert (< 90 (length rf32)))) (for 0 100 (λ (i) (let ((i (random 10)) (f (random 10.0)) (f2 (random 10.0f)) (b (random 10000000000000000000000000000)) (fix (random +most-positive-fixnum+)) (s8 (random (s8 5))) (f32 (random 1.0f)) (s64 (random (s64 9223372036854775807))) (sfix (random (s64 +most-positive-fixnum+))) (z (+ (random (bignum 1)) (random (u64 1)) (random (f32 1)) (random (s32 1)))) (f64 (random 1.0))) (assert (and (not (int? f32)) (>= f32 0.0) (<= f32 1.0))) (assert (and (not (int? f64)) (>= f64 0.0) (<= f64 1.0))) (assert (and (>= b 0) (or (fixnum? b) (and (bignum? b) (> b +most-positive-fixnum+) (<= b 10000000000000000000000000000))))) (assert (and (>= fix 0) (<= fix +most-positive-fixnum+))) (assert (and (int? s8) (>= s8 0) (<= s8 5))) (assert (and (int? i) (>= i 0) (<= i 10))) (assert (and (not (int? f)) (>= f 0.0) (<= f 10.0))) (assert (and (>= s64 0) (or (fixnum? s64) (and (bignum? s64) (> s64 +most-positive-fixnum+))) (<= s64 9223372036854775807))) (assert (and (>= sfix 0) (or (fixnum? sfix) (and (bignum? sfix) (> sfix +most-positive-fixnum+))) (<= sfix +most-positive-fixnum+))) (assert (and (>= z 0) (<= z 4))) (assert (and (not (int? f2)) (>= f2 0.0) (<= f2 10.0)))))) (assert-fail (random) arity-error) (assert-fail (random 1 *random-state* 2) arity-error) (assert-fail (random NIL) type-error) (assert-fail (random 'a) type-error) (assert-fail (random "blah") type-error) (assert-fail (random 1 2) type-error) (assert-fail (random 1 NIL) type-error) (assert-fail (random 1 T) type-error) (assert-fail (random 0) arg-error) (assert-fail (random 0.0) arg-error) (assert-fail (random 0.0f) arg-error) (assert-fail (random -0.1) arg-error) (assert-fail (random -0.1f) arg-error) (assert-fail (random -1) arg-error) (assert-fail (random (bignum -1)) arg-error) (assert-fail (random (s8 -1)) arg-error) (assert-fail (random (s64 -9223372036854775808)) arg-error) (assert (and (bound? T) (bound? NIL))) (assert (apply = '(1))) (assert (apply = '(1 1))) (assert (apply = '(1 1 1))) (assert (not (apply = '(1 1.1)))) (assert (not (nconc))) (assert (not (nconc NIL))) (assert (not (nconc NIL NIL))) (assert-fail (nconc NIL (vec 1) NIL) type-error) (let {[lst '#0=(1 2 3 . #0#)]} (with-bindings ((*print-length* 5)) (with-bindings ((*print-circle* T)) (assert (equal? (print-to-str lst) "#0=(1 2 3 . #0#)")) (assert (equal? (princ-to-str lst) "#0=(1 2 3 . #0#)"))) (with-bindings ((*print-circle* NIL)) (assert (equal? (print-to-str lst) "(1 2 3 1 2 ...)")) (assert (equal? (princ-to-str lst) "(1 2 3 1 2 ...)"))))) (assert (void? (let (a) a))) (assert (void? (let* (a) a))) (assert (void? (letrec (a) a))) (assert-fail (macroexpand `(let ((a)) a))) (assert-fail (macroexpand `(let* ((a)) a))) (assert-fail (macroexpand `(letrec ((a)) a))) (assert-fail (macroexpand `(let (a b a) b))) (assert (void? (let* (a b a) a))) (assert-fail (macroexpand `(letrec (a b a) b))) ;; re-defining constants is allowed if the binding is the same (eqv?) (def +a-fixnum-constant+ 1) (set! +a-fixnum-constant+ 1) (assert-fail (set! +a-fixnum-constant+ 1.0) const-error) (def +a-string-constant+ "blah") (def +a-string-constant+ (str #\b #\l #\a #\h)) (assert-fail (set! +a-string-constant+ (str #\b #\l #\a #\h #\nul)) const-error)