programs/web-files.flan is built for both targets from the same text and neither build reads the target anywhere in parse.ml or check.ml. On the desktop it writes the file and says so; in the browser barf signals a FileError the program handles, naming the file and reason 4, file-unsupported. The whole of the difference is one #ifdef in flan_rt.c, which is where the host ABI is already implemented twice. The web case is run under node rather than inspected. An artifact-shape assertion would say nothing about what decision 2 actually bought — that a program on the web is told its write did not happen instead of quietly losing it — so the test asserts the refusal is printed and that the desktop's success line is absent. A silent no-op would have taken that branch, which is the outcome the decision rules out by name. The same program embeds a file and prints it, because that is the half needing no filesystem and no host ABI: the line is identical on both targets and is the answer for assets a web build has to carry.
36 lines
1.6 KiB
Plaintext
36 lines
1.6 KiB
Plaintext
;;;; The same source on both targets, which is the whole of decision 2.
|
|
;;;;
|
|
;;;; Flan has NO conditional compilation — nothing in parse.ml or check.ml
|
|
;;;; reads the target — so "isolate this to desktop" is not expressible here,
|
|
;;;; and a build-time refusal would therefore be unusable. A silent no-op is
|
|
;;;; worse than either, because that is how a save file disappears with nothing
|
|
;;;; said. So `barf` on the web signals a condition and the program decides,
|
|
;;;; which is the language having something Odin does not: Odin stubs its whole
|
|
;;;; file API on js/wasm to .Unsupported so that importing core:os "panics
|
|
;;;; cleanly", and a panic is not a decision.
|
|
;;;;
|
|
;;;; Built for the desktop this prints that the write worked. Built for the
|
|
;;;; browser it prints that it was refused, and says which file and why. One
|
|
;;;; source, two outcomes, no flag anywhere.
|
|
|
|
(defn main [] i32
|
|
;; Embedding needs no filesystem and no host ABI, so this line is identical
|
|
;; on both targets and is why decision 1 came first.
|
|
(print (embed "assets/a.txt" string))
|
|
|
|
(handler-bind
|
|
[(FileError [c]
|
|
(print "refused: ")
|
|
(print (.path c))
|
|
(print " reason ")
|
|
(println (.reason c))
|
|
(println (= (.reason c) file-unsupported))
|
|
;; There is no restart that means "give up and carry on" — spec-
|
|
;; conditions.md §2 makes `error` diverging, and a handler that returns
|
|
;; normally has not answered it. Leaving is the honest way out of a
|
|
;; save that cannot happen.
|
|
(exit 0))]
|
|
(barf "web-files-out.txt" (bytes "state\n")))
|
|
(println "wrote it")
|
|
0)
|