(string b) is the mirror of (bytes s) and costs nothing: emit.ml already
lowers Types.String and Types.Slice _ to the same %slice, 16 bytes at
align 8, so a string and a [u8] are the identical value at run time and
both directions emit as the argument itself. What changes is only what
the checker will let the value be passed to — which was the whole gap.
Two decisions, both written into check.ml's comment.
It does not check UTF-8, because `string` does not claim UTF-8. The
prelude settles it: valid-utf8? is an ordinary function you call when you
care, decode-rune / rune-at / rune-count all take [u8] and not string,
and decode-rune answers {:ok false :width 1} on a malformed byte rather
than assuming well-formed input. The one place the runtime treats a
string differently from a byte slice is flan_escape_bytes, for a string
nested in a printed structure, and that is a byte-wise escape table with
no decoding in it. A check here would be the only enforcement point in
the language, which is a claim the rest of it does not make.
It does not widen the literal-write hole. That hole is the other
direction — (bytes "Hi") hands back a writable-looking slice over
constant data — and this direction only loses the ability to write, so
the result reaches strictly fewer stores than its argument could.
Provenance is still what the other direction needs; nothing here waits
on it.
The one sharp edge is not new but is easier to trip over now, and is
recorded in both the checker and digits.flan: i64->bytes, f64->bytes and
u64->bytes all view the same static buffer in the runtime, overwritten
by the next call, and calling it a string does not copy it. Format, draw,
then format the next one.
examples/digits.flan keeps its three signatures and loses its middle: the
[10 string] table, the per-glyph pen and the digit arithmetic are gone,
and draw-int is one draw-text. What survives is the part (string ...)
does not answer — i64->bytes has no field width, so "%03i" is still
assembled, and f64->bytes is "%g", so fixed decimal places are still a
split into two integers. core-input-multitouch and
core-input-virtual-controls ignored the width they were given, so both
inline the draw and stop importing digits.flan entirely.
test/programs/string-of-bytes.flan at -O2 and -O0: a number round-tripped,
an empty slice, sub-views whose length is not the underlying storage's,
and the result across a declare-c boundary. The last is the one that
could have been wrong — "hello world" cut to five bytes has a space where
C wants a NUL, so a shim that trusted the bytes would print all eleven.
56 lines
2.0 KiB
Plaintext
56 lines
2.0 KiB
Plaintext
;;;; raylib [core] example - input mouse wheel
|
|
;;;;
|
|
;;;; examples/core/core_input_mouse_wheel.c. Needed get-mouse-wheel-move, now
|
|
;;;; bound.
|
|
;;;;
|
|
;;;; This is the first example with a `TextFormat` in it. The C draws
|
|
;;;;
|
|
;;;; DrawText(TextFormat("Box position Y: %03i", boxPositionY), ...)
|
|
;;;;
|
|
;;;; and the number half of that is now sayable: (string (i64->bytes n)).
|
|
;;;; What is not is the "%03" — i64->bytes has no field width — so the label
|
|
;;;; is drawn with draw-text and the number with draw-int-padded from
|
|
;;;; examples/digits.flan, which draws the leading zeroes itself and then the
|
|
;;;; number in one call. A number wider than three digits is drawn in full,
|
|
;;;; exactly as printf's minimum-width means.
|
|
;;;;
|
|
;;;; The position is signed and goes negative as soon as the box scrolls past
|
|
;;;; the top, which is why draw-int-padded handles a sign at all.
|
|
|
|
(import rl "vendor:raylib")
|
|
(import d "digits.flan")
|
|
|
|
(defconst screen-width 800)
|
|
(defconst screen-height 450)
|
|
|
|
(defconst scroll-speed 4)
|
|
|
|
(defvar box-y i32)
|
|
|
|
(defn main []
|
|
(rl/init-window screen-width screen-height
|
|
"raylib [core] example - input mouse wheel")
|
|
(defer (rl/close-window))
|
|
|
|
(set box-y (- (/ screen-height 2) 40))
|
|
|
|
(rl/set-target-fps 60)
|
|
|
|
(until (rl/window-should-close?)
|
|
;; Update. The wheel reading is a per-frame delta, so it is 0.0 on every
|
|
;; frame the wheel did not turn and this is a no-op then.
|
|
(set box-y (- box-y (i32 (* (rl/get-mouse-wheel-move) (f32 scroll-speed)))))
|
|
|
|
;; Draw
|
|
(rl/begin-drawing)
|
|
(rl/clear-background rl/raywhite)
|
|
(rl/draw-rectangle (- (/ screen-width 2) 40) box-y 80 80 rl/maroon)
|
|
(rl/draw-text "Use mouse wheel to move the cube up and down!" 10 10 20
|
|
rl/gray)
|
|
;; The two halves of the C's one TextFormat call: the literal, measured,
|
|
;; and then the number starting where it ended.
|
|
(rl/draw-text "Box position Y: " 10 40 20 rl/lightgray)
|
|
(d/draw-int-padded box-y 3 (+ 10 (rl/measure-text "Box position Y: " 20))
|
|
40 20 rl/lightgray)
|
|
(rl/end-drawing)))
|