;;;; (string b) — a [u8] seen as a string. ;;;; ;;;; The conversion emits no instructions: String and Slice _ are both %slice, ;;;; 16 bytes at align 8. So what is worth testing is not arithmetic, it is the ;;;; four places a zero-instruction reinterpretation could still be wrong about ;;;; the *length* or about who owns the bytes. ;;;; ;;;; Run at -O2 and at -O0. The pair matters here for the same reason it ;;;; matters for the literal-write sharp edge: a conversion that accidentally ;;;; produced undefined behaviour would be a SIGSEGV at one level and a silent ;;;; deletion at the other, and agreeing at one level alone proves nothing. ;; puts and not a Flan printer: the point of this declaration is the *shim*, ;; which takes ptr+len and NUL-terminates a copy. A shim that instead trusted ;; the bytes to already be terminated would print the rest of the buffer for ;; every sub-view below, and nothing inside Flan would notice. ;; ;; Its return is C's "some nonnegative value", not a number worth printing, so ;; it is only shown as a sign — and it is printed through Flan's own writer, ;; which shares stdout's buffer with puts, so the interleaving is stable. (declare-c c-puts [s string] i32 "puts") (defn shows [s string] () (print "[") (print s) (print "] ") (print (len (bytes s))) (println "")) (defn main [] i32 ;; A number. The gap this closes: i64->bytes answers a [u8], every text ;; parameter wants a string, and until now nothing joined them. (shows (string (i64->bytes 42))) (shows (string (i64->bytes -7))) (shows (string (i64->bytes 0))) ;; An empty slice. Length 0, and no read of the pointer. (shows (string (slice (bytes "abc") 1 1))) ;; A sub-view, whose length is not the underlying storage's. The bytes after ;; index 5 are still there and must not appear. (let [s (bytes "hello world")] (shows (string (slice s 0 5))) (shows (string (slice s 6 11))) (shows (string (slice s 11 11)))) ;; Round trip: (bytes (string b)) is b, and both directions are the identity. (let [b (i64->bytes 1234567)] (print (len (bytes (string b)))) (println "")) ;; Across the declare-c boundary. The first is a sub-view — five bytes out of ;; eleven, the sixth of which is a space and not a NUL — so a shim that did ;; not copy would print "hello world" here. (let [s (bytes "hello world")] (print (if (>= (c-puts (string (slice s 0 5))) 0) "ok" "no")) (println "")) (print (if (>= (c-puts (string (i64->bytes 12345))) 0) "ok" "no")) (println "") ;; And an empty one: the shim's copy of a zero-length slice is "". (print (if (>= (c-puts (string (slice (bytes "abc") 1 1))) 0) "ok" "no")) (println "") 0)