diff --git a/web/examples/arrays.flan b/web/examples/arrays.flan index 336972f..747eff6 100644 --- a/web/examples/arrays.flan +++ b/web/examples/arrays.flan @@ -9,15 +9,15 @@ (defn main [] (set (at grid 1 2) 7) - (print-i64 (i64 (at grid 1 2))) (newline) ; 7 - (print-i64 (i64 (len palette))) (newline) ; 4 + (print (at grid 1 2)) (println "") ; 7 + (print (len palette)) (println "") ; 4 ;; A slice is ptr+len and non-owning: it views the array, it does not copy it. (let [row (slice (at grid 1) 0 cols)] (set (at row 0) 5) - (print-i64 (i64 (at grid 1 0))) (newline) ; 5 — the same storage - (print-i64 (sum-i32 row)) (newline)) ; 12 + (print (at grid 1 0)) (println "") ; 5 — the same storage + (print (sum-i32 row)) (println "")) ; 12 ;; (zeroed) is a memset, not an allocation. (set grid (zeroed)) - (print-i64 (i64 (at grid 1 2))) (newline)) ; 0 + (print (at grid 1 2)) (println "")) ; 0 diff --git a/web/examples/boom.flan b/web/examples/boom.flan index f4dcbd8..ca75da6 100644 --- a/web/examples/boom.flan +++ b/web/examples/boom.flan @@ -8,5 +8,5 @@ (retry [] 7))) (defn main [] - (print-i64 (i64 (load 1))) - (newline)) + (print (load 1)) + (println "")) diff --git a/web/examples/bounds.flan b/web/examples/bounds.flan index 762b186..853b734 100644 --- a/web/examples/bounds.flan +++ b/web/examples/bounds.flan @@ -5,6 +5,6 @@ ;; catches it — the same message, and the program stops where it happened. (defn main [] (let [i 7] - (print-line "before") - (print-i64 (i64 (at xs i))) - (print-line "unreachable"))) + (println "before") + (print (at xs i)) + (println "unreachable"))) diff --git a/web/examples/bounds.out b/web/examples/bounds.out index fd24439..f57d374 100644 --- a/web/examples/bounds.out +++ b/web/examples/bounds.out @@ -1,3 +1,3 @@ before -bounds.flan:9:28: index 7 is out of bounds for length 3 +bounds.flan:9:19: index 7 is out of bounds for length 3 exit 134 diff --git a/web/examples/breakdemo.flan b/web/examples/breakdemo.flan index 6afd53c..be13438 100644 --- a/web/examples/breakdemo.flan +++ b/web/examples/breakdemo.flan @@ -11,5 +11,5 @@ (defn main [] (agent/start "/tmp/flan-breakdemo.sock") - (print-i64 (i64 (load 1))) - (newline)) + (print (load 1)) + (println "")) diff --git a/web/examples/conds.flan b/web/examples/conds.flan index 0f49b99..75d3589 100644 --- a/web/examples/conds.flan +++ b/web/examples/conds.flan @@ -8,9 +8,9 @@ (defn main [] (load-all) ; no handler: a no-op - (print-i64 seen) (newline) ; 0 + (print seen) (println "") ; 0 ;; A handler that returns normally accumulates and lets the signaller run on. (handler-bind [(AssetMissing [c] (set seen (+ seen (i64 (.id c)))))] (load-all)) - (print-i64 seen) (newline)) ; 3 + (print seen) (println "")) ; 3 diff --git a/web/examples/control.flan b/web/examples/control.flan index 56b4b6c..a99b6db 100644 --- a/web/examples/control.flan +++ b/web/examples/control.flan @@ -9,10 +9,10 @@ (defn countdown [n i32] (let [i n] (while (> i 0) - (print-i64 (i64 i)) - (print-str " ") + (print i) + (print " ") (set i (- i 1))) - (newline))) + (println ""))) (defn first-even [s [i32]] (Option i32) (dotimes [i (len s)] @@ -21,10 +21,10 @@ None) (defn main [] - (print-line (classify -3)) + (println (classify -3)) (countdown 4) (unless false - (print-line "unless runs when the test is false")) + (println "unless runs when the test is false")) (match (first-even (slice nums 0 (len nums))) - (Some n) (do (print-i64 (i64 n)) (newline)) - None (print-line "none"))) + (Some n) (do (print n) (println "")) + None (println "none"))) diff --git a/web/examples/defer.flan b/web/examples/defer.flan index 57cf9cf..d4d3a75 100644 --- a/web/examples/defer.flan +++ b/web/examples/defer.flan @@ -1,11 +1,11 @@ (defn work [n i32] i32 - (defer (print-line "second")) - (defer (print-line "first")) ; innermost-first at exit + (defer (println "second")) + (defer (println "first")) ; innermost-first at exit (when (< n 0) (return 0)) ; runs both defers above it - (print-line "body") + (println "body") n) (defn main [] - (print-i64 (i64 (work 3))) - (newline)) + (print (work 3)) + (println "")) diff --git a/web/examples/enums.flan b/web/examples/enums.flan index 9745ea9..4773ea5 100644 --- a/web/examples/enums.flan +++ b/web/examples/enums.flan @@ -10,5 +10,5 @@ (defn main [] ;; :space resolves against the parameter's enum at compile time. ;; A typo is an error here, not a wrong number later. - (print-line (key-name :space)) - (print-line (key-name :left))) + (println (key-name :space)) + (println (key-name :left))) diff --git a/web/examples/ffi.flan b/web/examples/ffi.flan index 57c2d7a..2c7efb0 100644 --- a/web/examples/ffi.flan +++ b/web/examples/ffi.flan @@ -3,4 +3,4 @@ (declare cos-f64 [x f64] f64 "cos") (defn main [] - (print-f64 (cos-f64 0.0)) (newline)) + (print (cos-f64 0.0)) (println "")) diff --git a/web/examples/globals.flan b/web/examples/globals.flan index 495be74..5b6a5d2 100644 --- a/web/examples/globals.flan +++ b/web/examples/globals.flan @@ -6,7 +6,7 @@ (defvar grid [rows [cols u32]]) ; BSS, rows*cols*4 bytes (defn main [] - (print-i64 (i64 cell-size)) (newline) - (print-f64 (f64 gravity)) (newline) - (print-i64 (i64 current-color)) (newline) - (print-i64 (i64 (at grid 2 3))) (newline)) + (print cell-size) (println "") + (print gravity) (println "") + (print current-color) (println "") + (print (at grid 2 3)) (println "")) diff --git a/web/examples/hello.flan b/web/examples/hello.flan index 118a283..fcef751 100644 --- a/web/examples/hello.flan +++ b/web/examples/hello.flan @@ -1,2 +1,2 @@ (defn main [] - (print-line "hello from flan")) + (println "hello from flan")) diff --git a/web/examples/numbers.flan b/web/examples/numbers.flan index 14c58e2..0fa0a5f 100644 --- a/web/examples/numbers.flan +++ b/web/examples/numbers.flan @@ -2,7 +2,7 @@ (let [n 40 ; i32, inferred big (i64 n) ; every widening is written x 1.5] ; f64 - (print-i64 (+ big 2)) (newline) - (print-f64 (* x 2.5)) (newline) - (print-i64 (i64 (bit-xor (<< 1 8) 255))) (newline) + (print (+ big 2)) (println "") + (print (* x 2.5)) (println "") + (print (bit-xor (<< 1 8) 255)) (println "") 0)) diff --git a/web/examples/option.flan b/web/examples/option.flan index b0db48f..97986f4 100644 --- a/web/examples/option.flan +++ b/web/examples/option.flan @@ -6,8 +6,8 @@ (defn main [] (match (doubled-first (slice nums 0 4)) - (Some i) (do (print-i64 (i64 i)) (newline)) ; 4 - None (print-line "not found")) + (Some i) (do (print i) (println "")) ; 4 + None (println "not found")) (match (index-of-i32 (slice nums 0 4) 99) - (Some i) (do (print-i64 (i64 i)) (newline)) - None (print-line "not found"))) + (Some i) (do (print i) (println "")) + None (println "not found"))) diff --git a/web/examples/pkg.flan b/web/examples/pkg.flan index 3a62201..635493b 100644 --- a/web/examples/pkg.flan +++ b/web/examples/pkg.flan @@ -5,5 +5,5 @@ (defn main [] (let [v (g/add (g/V2 {:x 3.0 :y 0.0}) (g/V2 {:x 0.0 :y 4.0}))] - (print-f64 (f64 (g/length v))) - (newline))) + (print (g/length v)) + (println ""))) diff --git a/web/examples/places.flan b/web/examples/places.flan index 03f3878..913d9b7 100644 --- a/web/examples/places.flan +++ b/web/examples/places.flan @@ -14,7 +14,7 @@ (set (at room 2) 5) ; a fixed array or slice element (set (deref p) (Enemy {:hp 3 :name "wisp"})) ; a whole-object store - (print-i64 (i64 (.hp e))) (newline) - (print-line (.name e)) - (print-i64 (i64 (at room 2))) (newline) - (print-i64 (i64 spawned)) (newline))) + (print (.hp e)) (println "") + (println (.name e)) + (print (at room 2)) (println "") + (print spawned) (println ""))) diff --git a/web/examples/printing.flan b/web/examples/printing.flan new file mode 100644 index 0000000..eab17a2 --- /dev/null +++ b/web/examples/printing.flan @@ -0,0 +1,13 @@ +(defenum Key [space 32 left 263]) +(defstruct Enemy [hp i32 name string key Key]) + +(defn look-up [k Key] (Option i32) + (if (= k :space) (Some 32) None)) + +(defn main [] + (println 42) ; an i32, uncast + (println 1.5) + (println (Enemy {:hp 3 :name "wisp" :key :left})) + (println (look-up :space)) + (println (look-up :left)) + (print "no newline: ") (println true)) diff --git a/web/examples/printing.out b/web/examples/printing.out new file mode 100644 index 0000000..b3ac8a2 --- /dev/null +++ b/web/examples/printing.out @@ -0,0 +1,7 @@ +42 +1.5 +(Enemy {:hp 3 :name "wisp" :key :left}) +(some 32) +none +no newline: true +exit 0 diff --git a/web/examples/quotes.sh b/web/examples/quotes.sh index b0f50b3..b7320be 100644 --- a/web/examples/quotes.sh +++ b/web/examples/quotes.sh @@ -55,7 +55,7 @@ for pair in \ 'handle:(defvar h (Handle i32))' \ 'fnty:(defn f [g (Fn [i32] i32)] i32 (g 1))' \ 'quoted:(defn f [] i32 (quote a))' \ - 'deferblock:(defn f [] i32 (let [x 1] (defer (print-line "a")) x))' \ + 'deferblock:(defn f [] i32 (let [x 1] (defer (println "a")) x))' \ 'i64index:(defconst xs [3 i32] [1 2 3]) (defn main [] i32 (let [i (i64 1)] (at xs i)))' \ 'break:(defn main [] (let [i 0] (while (< i 3) (break))))' do @@ -66,10 +66,13 @@ do done rm -f "$here/.q.flan" -# The cell and the transfer channel, from a real --dev emit of hello.flan. -ir=$("$FLAN" emit --dev "$here/hello.flan" 2>/dev/null) -want "cell global" "$(printf '%s\n' "$ir" | grep '^@"flan.cell.print-line"')" -want "cell load" "$(printf '%s\n' "$ir" | grep 'load ptr, ptr @"flan.cell.print-line"')" +# The cell and the transfer channel, from a real --dev emit. hello.flan cannot +# show a cell any more: println is compiler-provided rather than a Flan +# function, so the smallest program makes no Flan-to-Flan call at all. defer.flan +# is the smallest one on the page that does — its main calls work. +ir=$("$FLAN" emit --dev "$here/defer.flan" 2>/dev/null) +want "cell global" "$(printf '%s\n' "$ir" | grep '^@"flan.cell.work"')" +want "cell load" "$(printf '%s\n' "$ir" | grep 'load ptr, ptr @"flan.cell.work"')" want "xfer channel" "$(printf '%s\n' "$ir" | grep 'define {} @"flan.main"')" # The generated C, from flan shim. diff --git a/web/examples/restart.flan b/web/examples/restart.flan index 5a54698..b60ee75 100644 --- a/web/examples/restart.flan +++ b/web/examples/restart.flan @@ -16,9 +16,9 @@ (retry [] 7))) (defn main [] - (print-i64 (i64 (fetch 1))) (newline) ; 101 — nothing handled it + (print (fetch 1)) (println "") ; 101 — nothing handled it (handler-bind [(AssetMissing [c] (invoke-restart 'use-placeholder))] - (print-i64 (i64 (fetch 2))) (newline)) ; -1 + (print (fetch 2)) (println "")) ; -1 - (print-i64 cleanups) (newline)) ; 2 — the defer ran both times + (print cleanups) (println "")) ; 2 — the defer ran both times diff --git a/web/examples/shimdemo.flan b/web/examples/shimdemo.flan index 4be3119..9863eae 100644 --- a/web/examples/shimdemo.flan +++ b/web/examples/shimdemo.flan @@ -3,5 +3,5 @@ (declare-c get-mouse-position [] Vector2 "GetMousePosition") (defn main [] - (print-f64 (f64 (.x (get-mouse-position)))) - (newline)) + (print (.x (get-mouse-position))) + (println "")) diff --git a/web/examples/structs.flan b/web/examples/structs.flan index e24d6dd..53ea21c 100644 --- a/web/examples/structs.flan +++ b/web/examples/structs.flan @@ -12,6 +12,6 @@ (defn main [] (let [c (Cursor {:src (bytes "hi")})] ; pos omitted, so pos is 0 - (print-i64 (i64 (peek (addr c)))) (newline) + (print (peek (addr c))) (println "") (advance (addr c)) - (print-i64 (i64 (peek (addr c)))) (newline))) + (print (peek (addr c))) (println ""))) diff --git a/web/index.html b/web/index.html index 73e630d..0760c5c 100644 --- a/web/index.html +++ b/web/index.html @@ -200,6 +200,7 @@ footer { margin-top: 3.5rem; padding-top: 1.5rem; border-top: 1px solid var(--ru
run builds to a temporary file and execs it.
The smallest program:
(defn main []
- (print-line "hello from flan"))
+ (println "hello from flan"))
The entry point is (defn main [args [string]] i32). Both the parameter
and the return type are optional: omitting args means the program ignores
@@ -337,10 +338,10 @@ heap is involved.
3
wisp
@@ -361,13 +362,13 @@ wisp
;; catches it — the same message, and the program stops where it happened.
(defn main []
(let [i 7]
- (print-line "before")
- (print-i64 (i64 (at xs i)))
- (print-line "unreachable")))
+ (println "before")
+ (print (at xs i))
+ (println "unreachable")))
$ flan run bounds.flan
before
-bounds.flan:9:28: index 7 is out of bounds for length 3
+bounds.flan:9:19: index 7 is out of bounds for length 3
$ echo $?
134
@@ -408,9 +409,9 @@ have one type, and every conversion is written as a cast:
(let [n 40 ; i32, inferred
big (i64 n) ; every widening is written
x 1.5] ; f64
- (print-i64 (+ big 2)) (newline)
- (print-f64 (* x 2.5)) (newline)
- (print-i64 (i64 (bit-xor (<< 1 8) 255))) (newline)
+ (print (+ big 2)) (println "")
+ (print (* x 2.5)) (println "")
+ (print (bit-xor (<< 1 8) 255)) (println "")
0))
42
@@ -455,9 +456,9 @@ its fields, and omitted fields are zeroed.
(defn main []
(let [c (Cursor {:src (bytes "hi")})] ; pos omitted, so pos is 0
- (print-i64 (i64 (peek (addr c)))) (newline)
+ (print (peek (addr c))) (println "")
(advance (addr c))
- (print-i64 (i64 (peek (addr c)))) (newline)))
+ (print (peek (addr c))) (println "")))
104
105
@@ -466,7 +467,8 @@ its fields, and omitted fields are zeroed.
byte is a u8 — but there is a byte literal, so \h is 104 and
\space is 32, and the prelude's digit? reads as
(and (>= b \0) (<= b \9)). To see a byte as a letter rather than as a
-number, print a slice of them with print-bytes.
+number, print a slice of them: print writes a [u8] as
+its bytes.
An enum is an i32 at run time and its own type in the checker. A
keyword at a call site resolves against the parameter's enum type at compile time, so a
@@ -484,8 +486,8 @@ typo is an error there rather than a wrong number later.
space
an arrow
@@ -515,10 +517,10 @@ functions need no forward declaration. Globals come in two kinds:
(defvar grid [rows [cols u32]]) ; BSS, rows*cols*4 bytes
(defn main []
- (print-i64 (i64 cell-size)) (newline)
- (print-f64 (f64 gravity)) (newline)
- (print-i64 (i64 current-color)) (newline)
- (print-i64 (i64 (at grid 2 3))) (newline))
+ (print cell-size) (println "")
+ (print gravity) (println "")
+ (print current-color) (println "")
+ (print (at grid 2 3)) (println ""))
5
0.05
@@ -551,10 +553,10 @@ whose type matters is named at the top level rather than written inline.
(defn countdown [n i32]
(let [i n]
(while (> i 0)
- (print-i64 (i64 i))
- (print-str " ")
+ (print i)
+ (print " ")
(set i (- i 1)))
- (newline)))
+ (println "")))
(defn first-even [s [i32]] (Option i32)
(dotimes [i (len s)]
@@ -563,13 +565,13 @@ whose type matters is named at the top level rather than written inline.
None)
(defn main []
- (print-line (classify -3))
+ (println (classify -3))
(countdown 4)
(unless false
- (print-line "unless runs when the test is false"))
+ (println "unless runs when the test is false"))
(match (first-even (slice nums 0 (len nums)))
- (Some n) (do (print-i64 (i64 n)) (newline))
- None (print-line "none")))
+ (Some n) (do (print n) (println ""))
+ None (println "none")))
negative
4 3 2 1
@@ -604,11 +606,11 @@ on nothing else today. some unwraps Some and early-ret
(defn main []
(match (doubled-first (slice nums 0 4))
- (Some i) (do (print-i64 (i64 i)) (newline)) ; 4
- None (print-line "not found"))
+ (Some i) (do (print i) (println "")) ; 4
+ None (println "not found"))
(match (index-of-i32 (slice nums 0 4) 99)
- (Some i) (do (print-i64 (i64 i)) (newline))
- None (print-line "not found")))
+ (Some i) (do (print i) (println ""))
+ None (println "not found")))
4
not found
@@ -620,16 +622,16 @@ not found
has not executed yet and must not fire.
(defn work [n i32] i32
- (defer (print-line "second"))
- (defer (print-line "first")) ; innermost-first at exit
+ (defer (println "second"))
+ (defer (println "first")) ; innermost-first at exit
(when (< n 0)
(return 0)) ; runs both defers above it
- (print-line "body")
+ (println "body")
n)
(defn main []
- (print-i64 (i64 (work 3)))
- (newline))
+ (print (work 3))
+ (println ""))
body
first
@@ -660,18 +662,18 @@ It is a place: (set (at grid r c) v) and (addr (at grid r c))
(defn main []
(set (at grid 1 2) 7)
- (print-i64 (i64 (at grid 1 2))) (newline) ; 7
- (print-i64 (i64 (len palette))) (newline) ; 4
+ (print (at grid 1 2)) (println "") ; 7
+ (print (len palette)) (println "") ; 4
;; A slice is ptr+len and non-owning: it views the array, it does not copy it.
(let [row (slice (at grid 1) 0 cols)]
(set (at row 0) 5)
- (print-i64 (i64 (at grid 1 0))) (newline) ; 5 — the same storage
- (print-i64 (sum-i32 row)) (newline)) ; 12
+ (print (at grid 1 0)) (println "") ; 5 — the same storage
+ (print (sum-i32 row)) (println "")) ; 12
;; (zeroed) is a memset, not an allocation.
(set grid (zeroed))
- (print-i64 (i64 (at grid 1 2))) (newline)) ; 0
+ (print (at grid 1 2)) (println "")) ; 0
7
4
@@ -682,17 +684,72 @@ It is a place: (set (at grid r c) v) and (addr (at grid r c))
A reversed range — lo greater than hi — traps, rather than
yielding a huge unsigned length.
+Printing
+
+println prints a value and a newline; print is the same
+walk without the newline. There is one of each and they take any type, but neither is a
+function and neither is overloading: the compiler walks the argument's type where the
+call is written and emits the printing for it. Nothing is decided at run time — a Flan
+value carries no header, so nothing at run time could say what it is — and there is no
+user-supplied printer to choose between.
+
+(defenum Key [space 32 left 263])
+(defstruct Enemy [hp i32 name string key Key])
+
+(defn look-up [k Key] (Option i32)
+ (if (= k :space) (Some 32) None))
+
+(defn main []
+ (println 42) ; an i32, uncast
+ (println 1.5)
+ (println (Enemy {:hp 3 :name "wisp" :key :left}))
+ (println (look-up :space))
+ (println (look-up :left))
+ (print "no newline: ") (println true))
+
+42
+1.5
+(Enemy {:hp 3 :name "wisp" :key :left})
+(some 32)
+none
+no newline: true
+
+The walk covers every integer and float type, bool, Unit,
+string, [u8], enums, Ptr, Option,
+structs, fixed arrays and slices. An enum member comes back as its name: the value is
+an i32 by the time the backend sees it, so the name is recovered here from
+the checker's table, and a value outside the declared members falls through to the
+number, which is what you would want to see. A Ptr prints as
+<ptr> and is never followed — it is the one thing that could make
+the walk cycle, and dereferencing a pointer on someone else's behalf is not safe.
+
+A string prints raw at the top level and quoted-and-escaped inside a structure.
+Those are not in conflict: (println "hello") has to print
+hello or it is useless, and the name field above has to be
+quoted or it could not be told from the punctuation around it.
+
+The walk is bounded in depth and in span, so a deeply nested value or a
+[100 [100 u32]] grid prints ... rather than a screenful — and,
+since the walk is unrolled at compile time, rather than putting ten thousand printing
+sites in the module.
+
+That the walk takes the argument's own type matters more here than it would in a
+language that widens implicitly. Nothing widens implicitly in this one, so a printer
+that named a type would need a cast written at every call — and a u64
+above 263 put through a signed one comes out negative. print
+takes the value as it is and prints the number it holds.
+
The prelude
The prelude is written in Flan, all but one line of it, and prepended to every
-program, so nothing in it needs importing. Printing is deliberately not a primitive:
-write-stdout is the one output primitive and everything above it is
-ordinary Flan.
+program, so nothing in it needs importing. It holds no printing of its own:
+print and println are the compiler's, and
+write-stdout — the one output primitive — is what they are written
+over.
Group Names
-output print-str, print-bytes, print-i64, print-f64, print-line, newline
slices of i32 swap-i32!, reverse-i32!, sort-i32!, index-of-i32, min-i32, max-i32, sum-i32
bytes bytes=?, starts-with?, ends-with?, index-of-byte, index-of-bytes, trim, digit?, space?
parsing parse-i64, parse-f64
@@ -754,8 +811,8 @@ and no ceremony.
(defn main []
(let [v (g/add (g/V2 {:x 3.0 :y 0.0})
(g/V2 {:x 0.0 :y 4.0}))]
- (print-f64 (f64 (g/length v)))
- (newline)))
+ (print (g/length v))
+ (println "")))
5
@@ -827,12 +884,12 @@ normally leaves the signaller to carry on — the accumulation case:
(defn main []
(load-all) ; no handler: a no-op
- (print-i64 seen) (newline) ; 0
+ (print seen) (println "") ; 0
;; A handler that returns normally accumulates and lets the signaller run on.
(handler-bind [(AssetMissing [c] (set seen (+ seen (i64 (.id c)))))]
(load-all))
- (print-i64 seen) (newline)) ; 3
+ (print seen) (println "")) ; 3
0
3
@@ -860,12 +917,12 @@ first, before the clause body starts.
(retry [] 7)))
(defn main []
- (print-i64 (i64 (fetch 1))) (newline) ; 101 — nothing handled it
+ (print (fetch 1)) (println "") ; 101 — nothing handled it
(handler-bind [(AssetMissing [c] (invoke-restart 'use-placeholder))]
- (print-i64 (i64 (fetch 2))) (newline)) ; -1
+ (print (fetch 2)) (println "")) ; -1
- (print-i64 cleanups) (newline)) ; 2 — the defer ran both times
+ (print cleanups) (println "")) ; 2 — the defer ran both times
101
-1
@@ -947,8 +1004,8 @@ and an exit status of 134:
(retry [] 7)))
(defn main []
- (print-i64 (i64 (load 1)))
- (newline))
+ (print (load 1))
+ (println ""))
$ flan run boom.flan
unhandled Missing
@@ -966,7 +1023,7 @@ is generated; a Flan string crosses as ptr+len, exactly as it is stored.
(declare cos-f64 [x f64] f64 "cos")
(defn main []
- (print-f64 (cos-f64 0.0)) (newline))
+ (print (cos-f64 0.0)) (println ""))
1
@@ -1072,20 +1129,22 @@ bound at link time cannot be made to notice one, so a --dev build r
every Flan-to-Flan call through a cell — a mutable global holding the address of the
function that is current.
-Here is the whole of hello.flan through
-flan emit --dev:
+Here is the defer example from above — its
+main calls work — through flan emit --dev:
-@"flan.cell.print-line" = global ptr @"flan.print-line"
+@"flan.cell.work" = global ptr @"flan.work"
define {} @"flan.main"(ptr %xfer) {
entry:
- %t1 = load ptr, ptr @"flan.cell.print-line"
- %t2 = call {} %t1(%slice { ptr @".str.36", i64 15 }, ptr %xfer)
+ %t7 = alloca %slice
+ %t1 = load ptr, ptr @"flan.cell.work"
+ %t2 = call i32 %t1(i32 3, ptr %xfer)
-The call site loads the cell rather than naming @"flan.print-line"
+
The call site loads the cell rather than naming @"flan.work"
directly. The signature carries ptr %xfer — the transfer channel from
conditions, on every Flan function, release builds
-included.
+included. println is not in there: it is not a Flan function, so there is
+no call to route and no cell for it.
Redefinition is then one store, below a microsecond. Three rules follow. A
redefinition module declares every global external, so globals live in the host
@@ -1242,10 +1301,10 @@ module, and the headless sand acceptance program prints the same 64-bit hash und
it does natively:
$ flan run test/programs/sand-headless.flan
--2851001042534928384
+15595743031174623232
$ flan build test/programs/sand-headless.flan --target=wasm32-wasi -o sand.wasm
$ node --no-warnings test/wasm-run.mjs sand.wasm
--2851001042534928384
+15595743031174623232
The RNG is written in Flan rather than called from libc for that number: a grid hash
is only a regression test if the sequence is byte-identical on both targets. It holds at