flan/test/programs/json-provide.flan
Joseph Ferano 2e203f64b8 bytes copies, bytes-view aliases, and a dev-session segfault parks
The INSERTIONSORT crash, all three rulings (FIX.org 2026-09-20):

- (bytes s) allocates a writable copy through the allocator surface —
  context or (bytes s a), StorageExhausted with retry, a registry note in
  dev builds (flan_bytes_dup, lowered like vec-new). (bytes-view s) is the
  old zero-cost reinterpret, renamed, read-only by convention; every
  in-repo reader swept over to it. (string b) unchanged.
- String constants were already read-only on both backends at -O0; now
  pinned — bytes-copy.flan rows on LLVM/-O0/--x86, and dies_segv rows
  asserting the write-through-view trap on both backends.
- A dev build installs a SIGSEGV/SIGBUS handler by the same dev-only
  constructor slot that arms the registry: one line naming the address and
  the innermost frame, then the trap-hook park — stopped, not dead, the
  daemon serving. No agent: message and re-raise. Release builds untouched.
  Pinned by trap_park over dev-segv.flan.
2026-09-20 23:12:42 +07:00

54 lines
2.2 KiB
Plaintext

;;;; defjson over a config file, and the escape that says it is not defedn.
;;;;
;;;; The same idea as edn-provide.flan and a different package: json depends on
;;;; edn for nothing and this program imports only json.
;;;;
;;;; "name" is the line that matters. Its value in the file is written
;;;; "tileset\nrunner", and JSON's `.text` is the RAW interior — escapes
;;;; undecoded — so a reader built on `.text` prints one line with a backslash
;;;; and an n in it. This prints two lines, which is `string-of` having been
;;;; used where a field is filled.
(import json "vendor:json")
(json/defjson Config "assets/json/config.json")
(defconst config (embed "assets/json/config.json"))
(defn main [] i32
(let [a (heap-allocator)
cfg (Config-of-bytes config a)]
;; Two lines, not one with a backslash in it.
(println (.name cfg))
(println (.port cfg))
(println (.scale cfg))
(println (if (.debug cfg) "yes" "no"))
(println (len (.layers cfg)))
;; 3 + 1 + 4 + 1 + 5. A length alone would pass on a Vec that was allocated
;; and never filled, so the sum is the claim.
(let [total (i64 0)]
(dotimes [i (len (.layers cfg))]
(set total (+ total (at (.layers cfg) i))))
(println total))
;; The nested structs, by the names the paths give them: Config-window and
;; Config-window-origin. Ordinary field loads, two deep.
(println (.w (.window cfg)))
(println (.h (.window cfg)))
(println (.x (.origin (.window cfg))))
(println (.y (.origin (.window cfg))))
(println "")
;; Drift, the same contract defedn's reader carries: the struct says "port"
;; and these bytes do not, and they carry a "host" it has never heard of.
(handler-bind
[(json/SchemaDrift [d]
(do (print (if (.extra? d) "extra " "missing "))
(print (.field d))
(print " in ")
(println (.struct d))))]
(let [c2 (Config-of-bytes
(bytes-view "{\"name\":\"x\",\"host\":\"h\",\"scale\":2.0,\"debug\":false,\"layers\":[1],\"window\":{\"w\":1,\"h\":1,\"origin\":{\"x\":0,\"y\":0}}}")
a)]
(println (.name c2))
(println (.port c2)))))
0)