print-str, print-i64, print-f64, print-bytes, print-line and newline leave the prelude. print and println are the whole printing surface now, and print is the better call at every one of the sites that used them: it is the same structural walk without the newline, so the no-newline case the family was kept for is covered, and it takes the value as it is. The old print-i64 forced an explicit (i64 x) at every call site, because this language widens nothing implicitly; that cast is gone from 127 places. Dropping it moves one answer. hash-grid returns u64, and the cast through the signed printer showed sand-headless's hash as -2851001042534928384. print routes a u64 through flan_u64_to_bytes, so it now prints 15595743031174623232 — the same 64 bits, read as the unsigned number they are. The pinned expectation follows the correction. test-flan-dev.el and test_session.ml both reached for print-line as "a name the prelude has"; they reach for rand-seed instead.
83 lines
3.4 KiB
Plaintext
83 lines
3.4 KiB
Plaintext
;;;; The prelude's in-place slice algorithms.
|
|
;;;;
|
|
;;;; Every input here is chosen so that a wrong implementation passes nothing.
|
|
;;;; The sort input is unsorted, has duplicates, has negatives and has an odd
|
|
;;;; length, so a comparison with the wrong sense, an off-by-one that drops the
|
|
;;;; last element, and a swap that loses an equal key all show up. The second
|
|
;;;; sort is reverse-sorted, which is the worst case for insertion sort and the
|
|
;;;; case a no-op comparison would pass. The third sorts a *subslice* and then
|
|
;;;; prints the whole owning array: a slice is ptr+len into its owner, so the
|
|
;;;; five elements inside the range must be sorted and the three outside it
|
|
;;;; must be untouched. That last one is the property that dies silently if a
|
|
;;;; slice parameter ever starts being copied.
|
|
|
|
(defvar xs [7 i32])
|
|
(defvar ys [5 i32])
|
|
(defvar zs [8 i32])
|
|
|
|
(defn show [s [i32]]
|
|
(dotimes [i (len s)]
|
|
(when (> i 0) (print " "))
|
|
(print (at s i)))
|
|
(println ""))
|
|
|
|
(defn load-xs []
|
|
(set (at xs 0) 5)
|
|
(set (at xs 1) -3)
|
|
(set (at xs 2) 5)
|
|
(set (at xs 3) 0)
|
|
(set (at xs 4) 12)
|
|
(set (at xs 5) -3)
|
|
(set (at xs 6) 7))
|
|
|
|
(defn main [] i32
|
|
(load-xs)
|
|
(show (slice xs 0 (len xs))) ; 5 -3 5 0 12 -3 7
|
|
|
|
;; Reading the whole slice, before anything reorders it.
|
|
(print (sum-i32 (slice xs 0 (len xs)))) (println "") ; 23
|
|
(print (match (min-i32 (slice xs 0 (len xs))) (Some v) v None 99))
|
|
(println "") ; -3
|
|
(print (match (max-i32 (slice xs 0 (len xs))) (Some v) v None 99))
|
|
(println "") ; 12
|
|
;; First index, not the last: 5 appears at 0 and at 2.
|
|
(print (match (index-of-i32 (slice xs 0 (len xs)) 5) (Some v) v None -1))
|
|
(println "") ; 0
|
|
(print (match (index-of-i32 (slice xs 0 (len xs)) 4) (Some v) v None -1))
|
|
(println "") ; -1
|
|
;; An empty slice has no least element, and None is the answer.
|
|
(print (match (min-i32 (slice xs 3 3)) (Some v) v None 99))
|
|
(println "") ; 99
|
|
|
|
;; Reverse of an odd-length slice: the middle element stays put.
|
|
(reverse-i32! (slice xs 0 (len xs)))
|
|
(show (slice xs 0 (len xs))) ; 7 -3 12 0 5 -3 5
|
|
;; And of a two-element one, the smallest case that can actually move.
|
|
(reverse-i32! (slice xs 0 2))
|
|
(show (slice xs 0 (len xs))) ; -3 7 12 0 5 -3 5
|
|
|
|
(load-xs)
|
|
(sort-i32! (slice xs 0 (len xs)))
|
|
(show (slice xs 0 (len xs))) ; -3 -3 0 5 5 7 12
|
|
|
|
;; Reverse-sorted: the case a comparison that never fires would pass.
|
|
(set (at ys 0) 5) (set (at ys 1) 4) (set (at ys 2) 3)
|
|
(set (at ys 3) 2) (set (at ys 4) 1)
|
|
(sort-i32! (slice ys 0 (len ys)))
|
|
(show (slice ys 0 (len ys))) ; 1 2 3 4 5
|
|
|
|
;; A subslice, with the elements on both sides left alone.
|
|
(set (at zs 0) 100) (set (at zs 1) 9) (set (at zs 2) -1)
|
|
(set (at zs 3) 9) (set (at zs 4) 4) (set (at zs 5) 0)
|
|
(set (at zs 6) 200) (set (at zs 7) 300)
|
|
(sort-i32! (slice zs 1 6))
|
|
(show (slice zs 0 (len zs))) ; 100 -1 0 4 9 9 200 300
|
|
|
|
;; Degenerate lengths must do nothing rather than run off an end.
|
|
(sort-i32! (slice zs 0 0))
|
|
(reverse-i32! (slice zs 0 0))
|
|
(sort-i32! (slice zs 2 3))
|
|
(reverse-i32! (slice zs 2 3))
|
|
(show (slice zs 0 (len zs))) ; 100 -1 0 4 9 9 200 300
|
|
0)
|