76 lines
3.2 KiB
Plaintext
76 lines
3.2 KiB
Plaintext
;;;; The third element of a defvar, both ways.
|
|
;;;;
|
|
;;;; The rule, 2026-09-20: a type there is the zeroed static global it has
|
|
;;;; always been, and anything else is a dyn global initialised from that
|
|
;;;; expression at startup. So this file is one program holding both kinds
|
|
;;;; side by side, and every line it prints is a claim about which reading
|
|
;;;; one of its declarations got.
|
|
;;;;
|
|
;;;; There is no new lowering under any of it. The dyn half is exactly what
|
|
;;;; [(defvar x dyn <expr>)] already compiled to — the initialiser lifted into
|
|
;;;; the startup function that main calls after the runtime is up, and a
|
|
;;;; collector root pushed for the global before it runs — which is why this
|
|
;;;; program runs identically on both backends and why neither of them
|
|
;;;; learned anything for it.
|
|
|
|
(defstruct Point [x i32 y i32])
|
|
|
|
;; ── The type reading, which is every declaration that worked before ──
|
|
;; A primitive, a fixed array, a struct and a container: all four are types in
|
|
;; the third position, so all four are the zeroed statics they were.
|
|
(defvar current-color i32)
|
|
(defvar grid [2 [3 u32]])
|
|
(defvar origin Point)
|
|
(defvar bytes (Vec u8))
|
|
|
|
;; ── The value reading, which is the new spelling ─────────────────────
|
|
;; None of these names a type, so each is a dyn global holding the value its
|
|
;; expression produced before the program's own code ran.
|
|
(defvar score 0)
|
|
(defvar label "start")
|
|
(defvar config {:level 1 :name "one"})
|
|
(defvar tally seeded)
|
|
|
|
;; A call, which is the shape the author kept writing: the file is read once,
|
|
;; at startup, into a global that outlives main.
|
|
(defn load [] dyn {:rows 3 :cols 4})
|
|
|
|
(defvar game-data (load))
|
|
|
|
;; And the value the bare symbol above was initialised from, declared *below*
|
|
;; it on purpose: which reading a defvar gets is decided with every name in
|
|
;; hand, not in the order the file was written.
|
|
(defvar seeded i64 7)
|
|
|
|
(defn main [] ()
|
|
;; The statics, untouched: zero, zero, zero, and an empty Vec that is a real
|
|
;; empty Vec rather than a placeholder.
|
|
(print current-color) (print " ") (print (at grid 1 2)) (print " ")
|
|
(print (.x origin)) (print " ") (print (len bytes)) (println "")
|
|
|
|
;; The dyn globals, as their initialisers left them.
|
|
(print score) (print " ") (print label) (print " ")
|
|
(print (get config :name)) (print " ") (print tally) (println "")
|
|
(print (get game-data :rows)) (print " ") (print (get game-data :cols))
|
|
(println "")
|
|
|
|
;; They are globals and not constants: each is assigned, and the map is
|
|
;; mutated in place through the same root the startup function filled.
|
|
(set score (+ score 5))
|
|
(set label "done")
|
|
(put config :level 2)
|
|
(set current-color 3)
|
|
(set (at grid 1 2) 9)
|
|
|
|
;; An allocation loop between filling them and reading them back, so the
|
|
;; collector runs with the run's own frames on the stack. A dyn global whose
|
|
;; root was not pushed reads back as a stale word here rather than as what
|
|
;; was stored.
|
|
(dotimes [i 20000]
|
|
(let [junk {:i i :s "forty-seven bytes of text to fatten each row"}]
|
|
(put config :seen (get junk :i))))
|
|
|
|
(print score) (print " ") (print label) (print " ")
|
|
(print (get config :level)) (println "")
|
|
(print current-color) (print " ") (print (at grid 1 2)) (println ""))
|