;;;; println, one row per arm of the structural printer. ;;;; ;;;; The walk in render.ml is shared with the REPL, but until now its only ;;;; coverage was the REPL tests -- and those run a dev build, where the pieces ;;;; go to flan_dev_emit. println is the same walk with the other emitter, in ;;;; an ordinary build, so every arm needs saying again here: the two emitters ;;;; are the one thing the shared module does *not* make identical. ;;;; ;;;; Run at -O0 as well as -O2. The slice arm emits a loop over slots taken ;;;; from the enclosing function's frame, and mem2reg is exactly the pass that ;;;; would launder a slot mistake into working code. (defstruct V [x f32 y f32]) (defstruct Blob [id i32 name string pos V tags [3 i32]]) (defenum Colour [red 0 green 1 blue 2]) ;; Five deep, so the walk hits max_depth (4) and prints "..." rather than ;; descending forever. A self-containing struct is the case this cap exists ;; for; five nested ones are the same shape without needing a pointer. (defstruct D5 [n i32]) (defstruct D4 [d D5]) (defstruct D3 [d D4]) (defstruct D2 [d D3]) (defstruct D1 [d D2]) (defvar b Blob) (defvar col Colour) (defvar big u64) (defvar small u64) (defvar arr [4 i32]) (defvar wide [10 i32]) (defvar deep D1) (defvar n i32) (defstruct Long [s string]) (defvar long-one Long) (defn nothing [] ) (defn find-it [s [i32] k i32] (Option i32) (dotimes [i (len s)] (when (= (at s i) k) (return (Some i)))) None) (defn main [] i32 ;; A string at top level prints raw. Anywhere else it is quoted, which the ;; Blob row below shows -- the two are the same value printed two ways on ;; purpose, and that difference is the thing most likely to be "fixed". (println "plain string") (println (bytes "plain bytes")) (println 42) (println -7) (set small 5) (println small) ;; The u64 row. Through the signed printer this reads -1, which is the one ;; way println could disagree with the REPL about a value both can hold. (set big 0xFFFFFFFFFFFFFFFF) (println big) (println 3.5) (println -0.25) (println true) (println false) ;; Unit is evaluated and *then* reported: a Unit expression is a call made ;; for its effect, so emitting () without running it would be a lie. (println (nothing)) (set col :green) (println col) ;; red is 0, which is also the zero value, so this row says the chain of ;; comparisons reaches the *first* member and does not fall through to the ;; number it is erased to. (set col :red) (println col) ;; A pointer is its shape and is never followed -- the only thing that could ;; make this walk cycle. (set n 3) (println (addr n)) (println (find-it (slice wide 0 10) 0)) (println (find-it (slice wide 0 10) 99)) (set (.id b) 7) (set (.name b) "sandy \"quoted\"") (set (.x (.pos b)) 1.5) (set (.y (.pos b)) -2.0) (set (at (.tags b) 1) 42) (println b) (set (at arr 2) 9) (println arr) ;; Ten elements against a span cap of eight: eight, then "...". (set (at wide 9) 1) (println wide) ;; A slice's length is not known until it runs, so this is the arm that ;; emits a loop rather than unrolling. (println (slice arr 1 4)) (set (.n (.d (.d (.d (.d deep))))) 5) (println deep) ;; Two slice printlns in one function, and one inside a loop: the slots the ;; loop needs are allocated per *call site* at check time, not per iteration. (dotimes [i 2] (println (slice arr 0 2))) (println (slice arr 2 4)) ;; A nested string longer than the escape buffer. Escaping is the one ;; conversion whose output is not a bounded handful of characters, so it ;; truncates -- with an ellipsis inside the quotes, because a value that ;; prints as a shorter value is the failure nobody notices. (set (.s long-one) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") (println long-one) ;; print is println without the newline. (print "a") (print "b") (println "c") 0)