diff --git a/README.md b/README.md
index 28161a4b..836afe5f 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ dune exec ./bin/main.exe -- build web/examples/hello.flan -o hello
The falling-sand demo uses raylib:
```sh
-dune exec ./bin/main.exe -- run sand.flan
+dune exec ./bin/main.exe -- run sand.fln
```
Once you are iterating regularly, put the built executable on your `PATH` if
@@ -77,7 +77,7 @@ you want to use the shorter `flan` commands shown below.
Start a long-lived development session:
```sh
-flan dev sand.flan
+flan dev sand.fln
```
The program runs normally and publishes a local socket beside the source file.
diff --git a/examples/core-2d-camera.fln b/examples/core-2d-camera.fln
index 07a4a6ce..e88eca53 100644
--- a/examples/core-2d-camera.fln
+++ b/examples/core-2d-camera.fln
@@ -2,22 +2,22 @@
;;;;
;;;; examples/core/core_2d_camera.c. Needed no new binding at all, which is
;;;; the reason to port it: Camera2D, begin-mode-2d and end-mode-2d have been
-;;;; in vendor/raylib/raylib.flan since the beginning and nothing in the
+;;;; in vendor/raylib/raylib.fln since the beginning and nothing in the
;;;; corpus had ever passed a whole Camera2D across the FFI on a frame's path.
;;;; Two Vector2s, a float and a float, by value, sixty times a second — the
;;;; acceptance table pins that layout with get-screen-to-world-2d, and this
;;;; is the same struct going into the call that actually draws with it.
;;;;
-;;;; The hundred buildings are a `defonce` of fixed arrays rather than a Vec:
+;;;; The hundred buildings are a `once` of fixed arrays rather than a Vec:
;;;; a global cannot hold a Vec (docs/PORTING.md §3) and does not need to here,
-;;;; because the count is a constant in the C too. `(array n T)` is the zeroed
+;;;; because the count is a constant in the C too. `array(n, T)` is the zeroed
;;;; fixed array, and the C's `= { 0 }` is exactly that.
;;;;
;;;; get-random-value comes from the generated half of the bindings. It is on
;;;; no frame's path — it runs once, before the loop — and its Flan face is
;;;; the C one, so docs/PORTING.md §1's rule does not reach it.
;;;;
-;;;; One deliberate difference from the C: `(- camera.rotation 1.0)` and the
+;;;; One deliberate difference from the C: `camera.rotation - 1.0` and the
;;;; clamp after it are written with the prelude's `clamp` macro rather than
;;;; two ifs. It is the same arithmetic; the C spells it out because C has no
;;;; clamp.
@@ -38,7 +38,7 @@ fn main() -> ()
rl/init-window(screen-width, screen-height,
"raylib [core] example - 2d camera")
defer rl/close-window()
- player = rl/Rectangle{.x 400.0 .y 280.0 .width 40.0 .height 40.0}
+ player = rl/Rectangle{.x 400.0, .y 280.0, .width 40.0, .height 40.0}
buildings = array(max-buildings, rl/Rectangle)
build-colors = array(max-buildings, rl/Color)
;; The skyline: each building is as wide as the last one left room for, so
@@ -47,13 +47,13 @@ fn main() -> ()
for i in range(max-buildings)
let w = f32(rl/get-random-value(50, 200))
h = f32(rl/get-random-value(100, 800))
- buildings[i] = rl/Rectangle({.x -6000.0 + f32(spacing), .y (f32(screen-height) - 130.0) - h, .width w, .height h})
+ buildings[i] = rl/Rectangle{.x -6000.0 + f32(spacing), .y (f32(screen-height) - 130.0) - h, .width w, .height h}
spacing += i32(w)
- build-colors[i] = rl/Color({.r u8(rl/get-random-value(200, 240)) .g u8(rl/get-random-value(200, 240)) .b u8(rl/get-random-value(200, 250)) .a 255})
+ build-colors[i] = rl/Color{.r u8(rl/get-random-value(200, 240)) .g u8(rl/get-random-value(200, 240)) .b u8(rl/get-random-value(200, 250)) .a 255}
;; A fresh Camera2D is all zeroes and a zoom of 0 makes the transform
- ;; singular, so the zoom is the one field that must be set — raylib.flan's
+ ;; singular, so the zoom is the one field that must be set — raylib.fln's
;; own comment on the struct says so.
- camera = rl/Camera2D({.offset rl/Vector2{.x f32(screen-width) / 2.0, .y f32(screen-height) / 2.0} .target rl/Vector2{.x player.x + 20.0, .y player.y + 20.0} .rotation 0.0 .zoom 1.0})
+ camera = rl/Camera2D{.offset rl/Vector2{.x f32(screen-width) / 2.0, .y f32(screen-height) / 2.0} .target rl/Vector2{.x player.x + 20.0, .y player.y + 20.0} .rotation 0.0 .zoom 1.0}
rl/set-target-fps(60)
until rl/window-should-close()
;; Update
@@ -61,16 +61,14 @@ fn main() -> ()
;; right, which is the else-if and not an accident.
if rl/is-key-down(:key-right)
player.x += 2.0
- else
- if rl/is-key-down(:key-left)
- player.x -= 2.0
+ elif rl/is-key-down(:key-left)
+ player.x -= 2.0
;; The camera follows the player's centre.
camera.target = rl/Vector2{.x player.x + 20.0, .y player.y + 20.0}
if rl/is-key-down(:key-a)
camera.rotation -= 1.0
- else
- if rl/is-key-down(:key-s)
- camera.rotation += 1.0
+ elif rl/is-key-down(:key-s)
+ camera.rotation += 1.0
camera.rotation = clamp(camera.rotation, -40.0, 40.0)
camera.zoom += rl/get-mouse-wheel-move() * 0.05
camera.zoom = clamp(camera.zoom, 0.1, 3.0)
diff --git a/examples/core-3d-picking.fln b/examples/core-3d-picking.fln
index 708c2eb3..ffdcc627 100644
--- a/examples/core-3d-picking.fln
+++ b/examples/core-3d-picking.fln
@@ -5,7 +5,7 @@
;;;; anywhere upstream that uses Ray and RayCollision without also loading a
;;;; Model, so it is the only way those two structs get a caller at all.
;;;;
-;;;; Picking is the round trip the corpus was missing. core-world-screen.flan
+;;;; Picking is the round trip the corpus was missing. core-world-screen.fln
;;;; already runs get-world-to-screen — a point in the scene to a pixel. This
;;;; is the inverse and it is a different shape: a pixel does not name a
;;;; point, it names a *line* through the scene, which is what a Ray is, and
@@ -13,7 +13,7 @@
;;;; something, which is what a RayCollision is. Two structs the package could
;;;; not describe, for one operation that cannot be written without them.
;;;;
-;;;; What was added, all in vendor/raylib/raylib.flan:
+;;;; What was added, all in vendor/raylib/raylib.fln:
;;;;
;;;; - `Ray` — two Vector3s, origin and direction.
;;;; - `RayCollision` — a C `bool`, a float and two Vector3s. This is the
@@ -21,7 +21,7 @@
;;;; `hit` is one byte and `distance` is four, so there are three padding
;;;; bytes between them that a permutation destroys. BoundingBox's two
;;;; Vector3s are interchangeable and nothing would catch swapping them.
-;;;; - `BoundingBox` — shared with examples/models-box-collisions.flan.
+;;;; - `BoundingBox` — shared with examples/models-box-collisions.fln.
;;;; - get-screen-to-world-ray and draw-ray, hand-written beside
;;;; get-world-to-screen and the cube draws for the reasons `bindings`
;;;; gives: the first reads the same camera as its inverse, and the second
@@ -53,12 +53,12 @@ once ray: rl/Ray
once collision: rl/RayCollision
;; The same centre/size to min/max conversion as in
-;; examples/models-box-collisions.flan. Written out here rather than shared
+;; examples/models-box-collisions.fln. Written out here rather than shared
;; because an example is a single file the reader can follow end to end.
;;
;; It used to be eight expressions of field arithmetic; it is the half-extent
;; subtracted and added, which is what the C means, now that the package
-;; carries vector arithmetic — see vendor/raylib/vector.flan. That file
+;; carries vector arithmetic — see vendor/raylib/vector.fln. That file
;; exists because raymath is `static inline` and has no symbol to bind, so
;; v3-sub and v3-add are Flan and not C.
fn box-around(centre: rl/Vector3, size: rl/Vector3) -> rl/BoundingBox
@@ -69,14 +69,14 @@ fn main() -> ()
rl/init-window(screen-width, screen-height,
"raylib [core] example - 3d picking")
defer rl/close-window()
- camera = rl/Camera3D({.position rl/Vector3{.x 10.0 .y 10.0 .z 10.0} .target rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .up rl/Vector3{.x 0.0 .y 1.0 .z 0.0} .fovy 45.0 .projection :projection-perspective})
+ camera = rl/Camera3D{.position rl/Vector3{.x 10.0 .y 10.0 .z 10.0} .target rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .up rl/Vector3{.x 0.0 .y 1.0 .z 0.0} .fovy 45.0 .projection :projection-perspective}
cube-position = rl/Vector3{.x 0.0 .y 1.0 .z 0.0}
cube-size = rl/Vector3{.x 2.0 .y 2.0 .z 2.0}
;; Both start zeroed, which is the C's `= { 0 }`. A zero Ray draws as a
;; degenerate line at the origin and a zero RayCollision has hit false, so
;; neither needs a "not yet" flag beside it.
- ray = rl/Ray({.position rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .direction rl/Vector3{.x 0.0 .y 0.0 .z 0.0}})
- collision = rl/RayCollision({.hit false .distance 0.0 .point rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .normal rl/Vector3{.x 0.0 .y 0.0 .z 0.0}})
+ ray = rl/Ray{.position rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .direction rl/Vector3{.x 0.0 .y 0.0 .z 0.0}}
+ collision = rl/RayCollision{.hit false .distance 0.0 .point rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .normal rl/Vector3{.x 0.0 .y 0.0 .z 0.0}}
rl/set-target-fps(60)
until rl/window-should-close()
;; Update. The first-person controls only run while the cursor is
diff --git a/examples/core-basic-window.fln b/examples/core-basic-window.fln
index 5a663392..61050807 100644
--- a/examples/core-basic-window.fln
+++ b/examples/core-basic-window.fln
@@ -6,7 +6,7 @@
;;;;
;;;; The one structural difference from the C is the loop: the C writes
;;;; `while (!WindowShouldClose())` and Flan has `until`, which is the same
-;;;; thing without the negation. sand.flan does likewise.
+;;;; thing without the negation. sand.fln does likewise.
;;;;
;;;; `defer` closes the window. It is function-scoped — it runs when `main`
;;;; returns and not at the end of any inner block — which is exactly what the
diff --git a/examples/core-delta-time.fln b/examples/core-delta-time.fln
index 7a2aeb79..f7a341f0 100644
--- a/examples/core-delta-time.fln
+++ b/examples/core-delta-time.fln
@@ -19,7 +19,7 @@
;;;; here rather than instead of it, so the file is not quietly asserting that
;;;; the original was right.
;;;;
-;;;; The two circle positions are `defonce`s for the usual reason: they are
+;;;; The two circle positions are `once`s for the usual reason: they are
;;;; state between frames and a `let` inside the loop would reset them.
import rl "vendor:raylib"
diff --git a/examples/core-input-gamepad.fln b/examples/core-input-gamepad.fln
index 4ffa356d..e9b40bd8 100644
--- a/examples/core-input-gamepad.fln
+++ b/examples/core-input-gamepad.fln
@@ -21,7 +21,7 @@
;;;; branches that matched on it are the artwork's and are gone with it.
;;;;
;;;; **The VIBRATE button is drawn and inert.** SetGamepadVibration is the one
-;;;; call in the C this refuses to bind, and vendor/raylib/raylib.flan already
+;;;; call in the C this refuses to bind, and vendor/raylib/raylib.fln already
;;;; carries the paragraph saying why: its arity differs between raylib
;;;; versions with no 5.5 header here to settle it, so a guess is a corrupted
;;;; stack frame rather than a link error — and the symbol in libraylib.so.550
@@ -51,7 +51,7 @@ fn deadzone(v: f32, limit: f32) -> f32
if v > 0.0 - limit and v < limit then 0.0 else v
;; The triggers rest at -1 rather than 0, which raylib does not normalise —
-;; see the note on GamepadAxis in vendor/raylib/raylib.flan. So their deadzone
+;; see the note on GamepadAxis in vendor/raylib/raylib.fln. So their deadzone
;; is a floor near the resting end and not a band around the middle.
fn trigger-deadzoned(v: f32) -> f32
if v < trigger-deadzone then -1.0 else v
@@ -162,7 +162,7 @@ fn main() -> ()
if rl/is-key-pressed(:key-right)
gamepad += 1
let axis-count = min(6, rl/get-gamepad-axis-count(gamepad))
- let vibrate-rect = rl/Rectangle({.x 10.0, .y 90.0 + 20.0 * f32(axis-count), .width 75.0, .height 24.0})
+ let vibrate-rect = rl/Rectangle{.x 10.0, .y 90.0 + 20.0 * f32(axis-count), .width 75.0, .height 24.0}
;; Draw
rl/with-drawing:
rl/clear-background(rl/raywhite)
@@ -225,7 +225,7 @@ fn main() -> ()
;; has type i32 while its sibling has type () and the `if` will not
;; typecheck — "expected i32, found ()". Both arms end in a
;; draw-text here, which is the tidy way out; where that is awkward a
- ;; trailing `(do)` is the other.
+ ;; trailing `()` is the other.
let b = rl/get-gamepad-button-pressed()
if b >= 0
rl/draw-text("DETECTED BUTTON: ", 10, 430, 10, rl/red)
diff --git a/examples/core-input-gestures-testbed.fln b/examples/core-input-gestures-testbed.fln
index efc95e60..33d8bc69 100644
--- a/examples/core-input-gestures-testbed.fln
+++ b/examples/core-input-gestures-testbed.fln
@@ -24,11 +24,11 @@
;;;; The rule the refusal came from is unchanged and worth keeping: an enum is
;;;; its own type in the checker, so `:tpa` is an error at the call site
;;;; instead of a number that is wrong later, and a bare integer still does not
-;;;; fit an `rl/Gesture` parameter. `(i32 g)` does not weaken that — it is
+;;;; fit an `rl/Gesture` parameter. `i32(g)` does not weaken that — it is
;;;; named, and it is at the site. The rule was "an integer must not arrive
;;;; silently", not "an integer is dangerous".
;;;;
-;;;; The `!= 4` stays a keyword comparison, `(not (= g :gesture-hold))`. That
+;;;; The `!= 4` stays a keyword comparison, `not g == :gesture-hold`. That
;;;; one was never a range test; it is a single member, and the C's 4 is a
;;;; magic number the keyword reads better than.
;;;;
@@ -48,9 +48,9 @@
;;;;
;;;; **No local fixed arrays.** The C declares `char gestureLog[20][12]` and
;;;; `Vector2 touchPosition[32]` inside main. A `let` binding takes no type
-;;;; annotation, so a fixed array can only be a top-level `defonce` or a literal
+;;;; annotation, so a fixed array can only be a top-level `once` or a literal
;;;; with every element written out — thirty-two Vector2s, here. They are
-;;;; `defonce`s, which is what the C's storage amounts to anyway.
+;;;; `once`s, which is what the C's storage amounts to anyway.
;;;;
;;;; The log itself came out simpler than the C's: the names are compile-time
;;;; literals, so a slot holds a `string` and there is no TextCopy and no
diff --git a/examples/core-input-gestures.fln b/examples/core-input-gestures.fln
index 703d6eb9..b0c4dd64 100644
--- a/examples/core-input-gestures.fln
+++ b/examples/core-input-gestures.fln
@@ -18,7 +18,7 @@
;;;; has nothing to catch.
;;;;
;;;; A slot that has not been written yet holds a zero-length string, because a
-;;;; `defonce` with no initialiser is all-bytes-zero and a string is ptr+len —
+;;;; `once` with no initialiser is all-bytes-zero and a string is ptr+len —
;;;; a null pointer with a length of 0. draw-text draws nothing for it. That is
;;;; the C's `{ "" }` initialiser arriving by a different route, and it is why
;;;; resetting the log below only has to reset the counter.
@@ -67,7 +67,7 @@ fn main() -> ()
"raylib [core] example - input gestures")
defer rl/close-window()
rl/set-target-fps(60)
- let touch-area = rl/Rectangle({.x 220.0, .y 10.0, .width f32(screen-width) - 230.0, .height f32(screen-height) - 20.0})
+ let touch-area = rl/Rectangle{.x 220.0, .y 10.0, .width f32(screen-width) - 230.0, .height f32(screen-height) - 20.0}
until rl/window-should-close()
;; Update
last-gesture = current-gesture
diff --git a/examples/core-input-keys.fln b/examples/core-input-keys.fln
index 5cec7bc9..1f872cd5 100644
--- a/examples/core-input-keys.fln
+++ b/examples/core-input-keys.fln
@@ -5,13 +5,13 @@
;;;;
;;;; The C moves the ball by writing `ballPosition.x += 2.0f` on a local
;;;; struct. Flan has the same thing — a local IS an assignable place
-;;;; (spec-memory.md) — but the local has to be a `defonce` here rather than a
+;;;; (spec-memory.md) — but the local has to be a `once` here rather than a
;;;; `let` inside the loop, because a `let` binding is rebound every iteration
;;;; and the position has to survive between frames. The C's variable is
;;;; outside its while loop for the same reason; this is that, spelled with the
;;;; storage the language has.
;;;;
-;;;; `(set (.x ball) ...)` works on a struct field of a global: a field of an
+;;;; `ball.x = ...` works on a struct field of a global: a field of an
;;;; assignable place is itself one.
import rl "vendor:raylib"
diff --git a/examples/core-input-mouse.fln b/examples/core-input-mouse.fln
index 24d2141a..192c3c0a 100644
--- a/examples/core-input-mouse.fln
+++ b/examples/core-input-mouse.fln
@@ -9,7 +9,7 @@
;;;; matters in both — two buttons pressed on the same frame give the earlier
;;;; one, which is the C's behaviour and not an accident of the port.
;;;;
-;;;; The colour has to be a `defonce` rather than a `let`, for the reason
+;;;; The colour has to be a `once` rather than a `let`, for the reason
;;;; core-input-keys' position does: it is state between frames.
import rl "vendor:raylib"
diff --git a/examples/core-input-multitouch.fln b/examples/core-input-multitouch.fln
index a2757a80..d39cf16f 100644
--- a/examples/core-input-multitouch.fln
+++ b/examples/core-input-multitouch.fln
@@ -1,19 +1,19 @@
;;;; raylib [core] example - input multitouch
;;;;
;;;; examples/core/core_input_multitouch.c. No new bindings: the whole touch
-;;;; surface was already there for sand.flan's read-out.
+;;;; surface was already there for sand.fln's read-out.
;;;;
;;;; The C keeps `Vector2 touchPositions[MAX_TOUCH_POINTS]`, and this is the
;;;; first example that needs a fixed array whose element type is a STRUCT
;;;; rather than a number. That works — `[10 rl/Vector2]` is ten Vector2s laid
-;;;; out flat, no headers, and `(at touch-positions i)` is a place that can be
+;;;; out flat, no headers, and `touch-positions[i]` is a place that can be
;;;; assigned a whole struct. Nothing in the repository used one before, so it
;;;; is worth saying that it does.
;;;;
-;;;; It is a top-level `defonce` and not a local, which is NOT a stylistic
+;;;; It is a top-level `once` and not a local, which is NOT a stylistic
;;;; choice. A `let` binding takes no type annotation, so the only way to make
;;;; a fixed array inside a function is to initialise it from a literal with
-;;;; every element written out — ten `(rl/Vector2 {.x 0.0 .y 0.0})`s here, and
+;;;; every element written out — ten `rl/Vector2{.x 0.0 .y 0.0}`s here, and
;;;; thirty-two in the gestures testbed. A zeroed local array of a given type
;;;; cannot be spelled. Static storage is what the C's `= { 0 }` gets anyway.
;;;;
diff --git a/examples/core-input-virtual-controls.fln b/examples/core-input-virtual-controls.fln
index e69eaa91..fa0bb74b 100644
--- a/examples/core-input-virtual-controls.fln
+++ b/examples/core-input-virtual-controls.fln
@@ -2,7 +2,7 @@
;;;;
;;;; examples/core/core_input_virtual_controls.c. No new bindings.
;;;;
-;;;; Split the way sand.flan is split: everything above the second banner is
+;;;; Split the way sand.fln is split: everything above the second banner is
;;;; arithmetic with no raylib calls in it, so test/programs/virtual-controls-
;;;; headless.flan can import this file as a package, drive the pointer over a
;;;; scripted path and hash where the player ended up. That is the only one of
@@ -18,7 +18,7 @@
;;;;
;;;; for (i = 0; i < BUTTON_MAX; i++) { if (...) { pressedButton = i; break; } }
;;;;
-;;;; and `(break)` is refused: "break is not implemented yet (see the build
+;;;; and `break()` is refused: "break is not implemented yet (see the build
;;;; sequence in plan.org)". `return` from the function works and is what this
;;;; uses — which is why the search is its own `defn` and not written inline
;;;; the way the C has it. That is not a loss: the function is the thing the
@@ -26,14 +26,14 @@
;;;; function, the shape left is a flag and a compound loop condition.
;;;;
;;;; **No `fabsf`.** The prelude has sqrt-f32 and sign-f32 but no absolute
-;;;; value for floats, and the comment there says why for integers. `(max v
-;;;; (- 0.0 v))` is it, and unlike the integer case it has no edge: there is no
-;;;; float whose negation is itself except -0.0, whose absolute value is 0.0
-;;;; either way.
+;;;; value for floats, and the comment there says why for integers.
+;;;; `max(v, 0.0 - v)` is it, and unlike the integer case it has no edge: there
+;;;; is no float whose negation is itself except -0.0, whose absolute value is
+;;;; 0.0 either way.
;;;;
-;;;; The button geometry is `defconst` arrays of struct literals. That works —
+;;;; The button geometry is `const` arrays of struct literals. That works —
;;;; and it is the only way a fixed array can be made inside anything but a
-;;;; top-level `defonce`, since a `let` binding takes no type annotation.
+;;;; top-level `once`, since a `let` binding takes no type annotation.
import rl "vendor:raylib"
@@ -41,7 +41,7 @@ const screen-width = 800
const screen-height = 450
;; The C's PadButton enum. -1 is BUTTON_NONE and the four directions are 0..3,
-;; in the order the arrays below are written. A `defenum` would not help: the
+;; in the order the arrays below are written. An `enum` would not help: the
;; value is used as an index and an enum does not convert to an integer
;; ("i32 converts a number, found ..."), so it would have to be turned back
;; into one at every use.
@@ -56,7 +56,7 @@ const button-radius: f32 = 30.0
;; padPosition is {100, 350} and the buttons sit a radius and a half away from
;; it on each axis. The C computes these at run time from padPosition; they are
-;; written out here because a defconst is compile-time and the numbers are.
+;; written out here because a const is compile-time and the numbers are.
const button-positions: [button-max rl/Vector2] = [rl/Vector2{.x 100.0 .y 305.0} ; up
; left
; right
diff --git a/examples/core-scissor-test.fln b/examples/core-scissor-test.fln
index 74070788..a6f32c2a 100644
--- a/examples/core-scissor-test.fln
+++ b/examples/core-scissor-test.fln
@@ -1,7 +1,7 @@
;;;; raylib [core] example - scissor test
;;;;
;;;; examples/core/core_scissor_test.c. Needed begin-scissor-mode and
-;;;; end-scissor-mode, now hand-written in vendor/raylib/raylib.flan: they are
+;;;; end-scissor-mode, now hand-written in vendor/raylib/raylib.fln: they are
;;;; a begin/end pair inside a frame, which is the class docs/PORTING.md §1 says
;;;; belongs in the hand-written half and not in the importer's. get-mouse-x
;;;; and get-mouse-y come from the generated half — their Flan face is the C
diff --git a/examples/core-window-flags.fln b/examples/core-window-flags.fln
index a16845d6..6cfdf12f 100644
--- a/examples/core-window-flags.fln
+++ b/examples/core-window-flags.fln
@@ -1,14 +1,14 @@
;;;; raylib [core] example - window flags
;;;;
;;;; examples/core/core_window_flags.c. The reason to port this one is the
-;;;; flags themselves: raylib.flan carried four of ConfigFlags' sixteen
-;;;; members — the four sand.flan sets before the window exists — and this
+;;;; flags themselves: raylib.fln carried four of ConfigFlags' sixteen
+;;;; members — the four sand.fln sets before the window exists — and this
;;;; example reads and writes eleven of them after it exists. All sixteen are
-;;;; in raylib.flan now, read off raylib.h 5.5, in the header's order and not
+;;;; in raylib.fln now, read off raylib.h 5.5, in the header's order and not
;;;; in bit order (FLAG_VSYNC_HINT is 0x40 and FLAG_FULLSCREEN_MODE is 0x02,
;;;; which is the kind of thing nobody remembers correctly).
;;;;
-;;;; They are `defconst u32`s and not a `defenum` for the reason the file
+;;;; They are `const u32`s and not an `enum` for the reason the file
;;;; already gives about gestures: raylib wants the OR of several and a
;;;; keyword can only ever name one member.
;;;;
@@ -16,7 +16,7 @@
;;;; minimize-window, maximize-window and restore-window all come from the
;;;; generated half. That is the line drawn in vendor/raylib/bindings and it
;;;; is worth saying why it falls here: the rule in docs/PORTING.md §1 exists so
-;;;; that a build with no header set can still draw, and generated.flan is
+;;;; that a build with no header set can still draw, and generated.fln is
;;;; committed, so it can. What a hand-written line adds on top of that is a
;;;; Flan face the C signature does not have — a Key instead of an int, a
;;;; (Ptr Camera3D) instead of a raw pointer — and these seven have no such
@@ -71,7 +71,7 @@ fn main() -> ()
rl/init-window(screen-width, screen-height,
"raylib [core] example - window flags")
defer rl/close-window()
- ball-pos = rl/Vector2({.x f32(rl/get-screen-width()) / 2.0, .y f32(rl/get-screen-height()) / 2.0})
+ ball-pos = rl/Vector2{.x f32(rl/get-screen-width()) / 2.0, .y f32(rl/get-screen-height()) / 2.0}
ball-speed = rl/Vector2{.x 5.0 .y 4.0}
;; No set-target-fps, as in the C: with FLAG_VSYNC_HINT among the flags the
;; example toggles, a frame limiter on top of it would hide what V-Sync
diff --git a/examples/core-window-should-close.fln b/examples/core-window-should-close.fln
index 22bfd1a1..2cb008c2 100644
--- a/examples/core-window-should-close.fln
+++ b/examples/core-window-should-close.fln
@@ -1,22 +1,22 @@
;;;; raylib [core] example - window should close
;;;;
;;;; examples/core/core_window_should_close.c. Needed set-exit-key, and one
-;;;; enum member to go with it: raylib.flan's `Key` now has `null 0`, read off
+;;;; enum member to go with it: raylib.fln's `Key` now has `null 0`, read off
;;;; KEY_NULL in raylib.h. The binding is hand-written rather than taken from
;;;; the generated half because the Flan face differs — raylib declares
;;;; `void SetExitKey(int key)` and the generated line therefore takes an i32,
-;;;; where this one takes a Key, so `(rl/set-exit-key :key-null)` is checked
+;;;; where this one takes a Key, so `rl/set-exit-key(:key-null)` is checked
;;;; against the enum and `:nul` is a compile error instead of a 0.
;;;;
;;;; The whole example is about what window-should-close means. It is not a
;;;; flag raylib latches: it is "the close button was clicked, or the exit key
;;;; is down", recomputed each frame, and it goes back to false on its own.
;;;; That is what lets this program ask for confirmation and then carry on —
-;;;; and it is also why the loop is driven by a `defonce` of its own rather
+;;;; and it is also why the loop is driven by a `once` of its own rather
;;;; than by the predicate, which is the one structural difference from every
;;;; other example in this directory.
;;;;
-;;;; `(set-exit-key :null)` takes ESC away from raylib so the program can read
+;;;; `set-exit-key(:null)` takes ESC away from raylib so the program can read
;;;; it itself. The window's X button still works and is still what
;;;; window-should-close reports.
@@ -47,9 +47,8 @@ fn main() -> ()
if exit-requested
if rl/is-key-pressed(:key-y)
exiting = true
- else
- if rl/is-key-pressed(:key-n)
- exit-requested = false
+ elif rl/is-key-pressed(:key-n)
+ exit-requested = false
;; Draw
rl/with-drawing:
rl/clear-background(rl/raywhite)
diff --git a/examples/core-world-screen.fln b/examples/core-world-screen.fln
index 24e0c0a9..2e6cfe1a 100644
--- a/examples/core-world-screen.fln
+++ b/examples/core-world-screen.fln
@@ -8,7 +8,7 @@
;;;; none of them, and the generated half grew the cubes, spheres, cylinders
;;;; and billboards along with the eight lines this example needs.
;;;;
-;;;; Hand-written in raylib.flan rather than generated, and why each:
+;;;; Hand-written in raylib.fln rather than generated, and why each:
;;;;
;;;; begin-mode-3d / end-mode-3d a begin/end pair inside a frame, the
;;;; class docs/PORTING.md §1 names, and taken
@@ -51,7 +51,7 @@ fn main() -> ()
;; enum's members right here and a misspelt projection is a compile error
;; rather than a 0. raylib's field is `int` and the layout is unchanged —
;; an enum is four bytes either way.
- camera = rl/Camera3D({.position rl/Vector3{.x 10.0 .y 10.0 .z 10.0} .target rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .up rl/Vector3{.x 0.0 .y 1.0 .z 0.0} .fovy 45.0 .projection :projection-perspective})
+ camera = rl/Camera3D{.position rl/Vector3{.x 10.0 .y 10.0 .z 10.0} .target rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .up rl/Vector3{.x 0.0 .y 1.0 .z 0.0} .fovy 45.0 .projection :projection-perspective}
cube = rl/Vector3{.x 0.0 .y 0.0 .z 0.0}
;; The mouse becomes the camera's, not a pointer's.
rl/disable-cursor()
diff --git a/examples/digits.fln b/examples/digits.fln
index c4d8e8ce..611b14b7 100644
--- a/examples/digits.fln
+++ b/examples/digits.fln
@@ -7,12 +7,12 @@
;;;; allocator to build one in. So a number was drawn one glyph at a time out
;;;; of a `[10 string]` table.
;;;;
-;;;; `(string b)` closed that. It is the mirror of `(bytes-view s)` and costs no
+;;;; `string(b)` closed that. It is the mirror of `bytes-view(s)` and costs no
;;;; instructions — a `string` and a `[u8]` are the same 16-byte %slice — so
-;;;; `(string (i64->bytes n))` draws in one call and the table, the per-glyph
+;;;; `string(i64->bytes(n))` draws in one call and the table, the per-glyph
;;;; pen and the digit arithmetic behind them are gone.
;;;;
-;;;; What is left is the part `(string ...)` does not answer, which is
+;;;; What is left is the part `string(...)` does not answer, which is
;;;; *formatting*: `i64->bytes` has no field width, so "%03i" still has to be
;;;; assembled, and `f64->bytes` is `%g` and not "%.02f", so a fixed number of
;;;; decimal places still has to be split and drawn in two pieces. Those two
@@ -25,8 +25,8 @@
;;;; name anyway.
;;;;
;;;; `i64->bytes` and `f64->bytes` put their text in the temp allocator, where
-;;;; it lasts until the next `(free-temp)`. A program drawing these every frame
-;;;; calls `(free-temp)` once per frame, after drawing, and clones any text it
+;;;; it lasts until the next `free-temp()`. A program drawing these every frame
+;;;; calls `free-temp()` once per frame, after drawing, and clones any text it
;;;; keeps longer.
;;;;
;;;; Everything here needs a window: `measure-text` answers 0 for every string
diff --git a/examples/models-box-collisions.fln b/examples/models-box-collisions.fln
index 520125b4..1fd87926 100644
--- a/examples/models-box-collisions.fln
+++ b/examples/models-box-collisions.fln
@@ -10,11 +10,11 @@
;;;;
;;;; That aggregate is BoundingBox, and it is two Vector3s and nothing else —
;;;; no owned pointer, no array, no lifetime. One `defstruct` in
-;;;; vendor/raylib/raylib.flan un-refuses four raylib functions at once
+;;;; vendor/raylib/raylib.fln un-refuses four raylib functions at once
;;;; (CheckCollisionBoxes, CheckCollisionBoxSphere, DrawBoundingBox and
;;;; GetRayCollisionBox), and that is the cheapest widening of the 3D surface
;;;; available anywhere in the tree. Ray and RayCollision went in beside it
-;;;; for examples/core-3d-picking.flan and for the same reason.
+;;;; for examples/core-3d-picking.fln and for the same reason.
;;;;
;;;; So the answer to "is a models example just a binding exercise" is: the
;;;; ones that need Model are, and this one is the counterexample. What
@@ -57,7 +57,7 @@ const enemy-sphere-size: f32 = 1.5
;;
;; It used to be eight expressions of field arithmetic here too; it is the
;; half-extent subtracted and added now that the package carries vector
-;; arithmetic — see vendor/raylib/vector.flan, which is Flan and not C
+;; arithmetic — see vendor/raylib/vector.fln, which is Flan and not C
;; because raymath is `static inline` and has no symbol to bind.
fn box-around(centre: rl/Vector3, size: rl/Vector3) -> rl/BoundingBox
let half = rl/v3-scale(size, 0.5)
@@ -68,9 +68,9 @@ fn main() -> ()
"raylib [models] example - box collisions")
defer rl/close-window()
;; The C writes this camera as a brace initialiser with a trailing 0 for the
- ;; projection, which is CAMERA_PERSPECTIVE. Named here, because the defenum
+ ;; projection, which is CAMERA_PERSPECTIVE. Named here, because the enum
;; exists precisely so that the 0 does not have to be remembered.
- camera = rl/Camera3D({.position rl/Vector3{.x 0.0 .y 10.0 .z 10.0} .target rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .up rl/Vector3{.x 0.0 .y 1.0 .z 0.0} .fovy 45.0 .projection :projection-perspective})
+ camera = rl/Camera3D{.position rl/Vector3{.x 0.0 .y 10.0 .z 10.0} .target rl/Vector3{.x 0.0 .y 0.0 .z 0.0} .up rl/Vector3{.x 0.0 .y 1.0 .z 0.0} .fovy 45.0 .projection :projection-perspective}
player-position = rl/Vector3{.x 0.0 .y 1.0 .z 2.0}
player-size = rl/Vector3{.x 1.0 .y 2.0 .z 1.0}
player-color = rl/green
diff --git a/examples/shapes-basic-shapes.fln b/examples/shapes-basic-shapes.fln
index c8c73906..af34d674 100644
--- a/examples/shapes-basic-shapes.fln
+++ b/examples/shapes-basic-shapes.fln
@@ -7,17 +7,17 @@
;;;; poly draws — in one frame, beside the four the core examples already
;;;; exercise. Every one of them came out of the generated half of the
;;;; bindings and none needed a new line anywhere; that is the result worth
-;;;; recording, because the whole point of a committed generated.flan is that
+;;;; recording, because the whole point of a committed generated.fln is that
;;;; a build with no FLAN_RAYLIB_H set can draw with all of it.
;;;;
;;;; What it is actually a test of. The gradient calls are the first thing in
;;;; the corpus to pass *two* Colors in one call, and draw-triangle is the
;;;; first to pass three Vector2s. A struct argument crosses the FFI by
-;;;; pointer into a generated shim (vendor/raylib/raylib.flan's header note),
+;;;; pointer into a generated shim (vendor/raylib/raylib.fln's header note),
;;;; so the arity of that copying is what a call with several small structs in
;;;; a row puts under load. Nothing here can be asserted headless — every line
;;;; needs a GL context — so the check is the link and the screen, which is
-;;;; what the Shapes comment in raylib.flan already says about this family.
+;;;; what the Shapes comment in raylib.fln already says about this family.
;;;;
;;;; The one deliberate difference from the C: the C writes `screenWidth/4*2`
;;;; and `screenWidth/4.0f*3.0f` for the same column and gets 400 and 600 out
diff --git a/examples/shapes-collision-area.fln b/examples/shapes-collision-area.fln
index 7709409c..183939ba 100644
--- a/examples/shapes-collision-area.fln
+++ b/examples/shapes-collision-area.fln
@@ -40,9 +40,9 @@ fn main() -> ()
rl/init-window(screen-width, screen-height,
"raylib [shapes] example - collision area")
defer rl/close-window()
- box-a = rl/Rectangle({.x 10.0, .y f32(screen-height) / 2.0 - 50.0, .width 200.0, .height 100.0})
+ box-a = rl/Rectangle{.x 10.0, .y f32(screen-height) / 2.0 - 50.0, .width 200.0, .height 100.0}
box-a-speed-x = 4
- box-b = rl/Rectangle({.x f32(screen-width) / 2.0 - 30.0, .y f32(screen-height) / 2.0 - 30.0, .width 60.0, .height 60.0})
+ box-b = rl/Rectangle{.x f32(screen-width) / 2.0 - 30.0, .y f32(screen-height) / 2.0 - 30.0, .width 60.0, .height 60.0}
;; A fresh Rectangle is four zeroes, which is the C's `= { 0 }`. It is never
;; drawn before the first collision sets it.
box-collision = rl/Rectangle{.x 0.0 .y 0.0 .width 0.0 .height 0.0}
@@ -63,14 +63,12 @@ fn main() -> ()
box-b.y = f32(rl/get-mouse-y()) - box-b.height / 2.0
if box-b.x + box-b.width >= f32(rl/get-screen-width())
box-b.x = f32(rl/get-screen-width()) - box-b.width
- else
- if box-b.x <= 0.0
- box-b.x = 0.0
+ elif box-b.x <= 0.0
+ box-b.x = 0.0
if box-b.y + box-b.height >= f32(rl/get-screen-height())
box-b.y = f32(rl/get-screen-height()) - box-b.height
- else
- if box-b.y <= f32(screen-upper-limit)
- box-b.y = f32(screen-upper-limit)
+ elif box-b.y <= f32(screen-upper-limit)
+ box-b.y = f32(screen-upper-limit)
collision = rl/check-collision-recs(box-a, box-b)
;; Only meaningful while they touch: raylib answers a zero rectangle for
;; two boxes that do not, and the C leaves the previous one in place
diff --git a/examples/shapes-following-eyes.fln b/examples/shapes-following-eyes.fln
index fd9683f1..de59be58 100644
--- a/examples/shapes-following-eyes.fln
+++ b/examples/shapes-following-eyes.fln
@@ -18,7 +18,7 @@
;;;; file.
;;;;
;;;; That measurement is what decided the answer, and the answer landed:
-;;;; vendor/raylib/vector.flan is raymath written in Flan, since a C shim
+;;;; vendor/raylib/vector.fln is raymath written in Flan, since a C shim
;;;; re-exporting the inlines would have bought identical arithmetic at the
;;;; price of a compilation unit and a second place raylib's semantics live.
;;;; The measurement is left standing rather than rewritten away — one
@@ -69,7 +69,7 @@ fn track(mouse: rl/Vector2, centre: rl/Vector2) -> rl/Vector2
else
let d = rl/v2-sub(mouse, centre)
angle = atan2-f32(d.y, d.x)
- rl/Vector2({.x centre.x + limit * cos-f32(angle), .y centre.y + limit * sin-f32(angle)})
+ rl/Vector2{.x centre.x + limit * cos-f32(angle), .y centre.y + limit * sin-f32(angle)}
fn main() -> ()
rl/init-window(screen-width, screen-height,
@@ -78,8 +78,8 @@ fn main() -> ()
;; The C reads these off get-screen-width/get-screen-height after the window
;; is open rather than off the constants, and so does this: on a high-DPI
;; display the two can differ.
- sclera-left = rl/Vector2({.x f32(rl/get-screen-width()) / 2.0 - 100.0, .y f32(rl/get-screen-height()) / 2.0})
- sclera-right = rl/Vector2({.x f32(rl/get-screen-width()) / 2.0 + 100.0, .y f32(rl/get-screen-height()) / 2.0})
+ sclera-left = rl/Vector2{.x f32(rl/get-screen-width()) / 2.0 - 100.0, .y f32(rl/get-screen-height()) / 2.0}
+ sclera-right = rl/Vector2{.x f32(rl/get-screen-width()) / 2.0 + 100.0, .y f32(rl/get-screen-height()) / 2.0}
iris-left = sclera-left
iris-right = sclera-right
rl/set-target-fps(60)
diff --git a/examples/text-codepoints-loading.fln b/examples/text-codepoints-loading.fln
index feb51819..2709bf20 100644
--- a/examples/text-codepoints-loading.fln
+++ b/examples/text-codepoints-loading.fln
@@ -19,7 +19,7 @@
;;;; come back out of LoadCodepoints as the right 54, and as 49 distinct ones.
;;;; Nothing in the
;;;; language claims to know what a character is — a `string` is bytes and a
-;;;; `[u8]` is the same bytes, which `(string ...)` and `(bytes-view ...)` say in
+;;;; `[u8]` is the same bytes, which `string(...)` and `bytes-view(...)` say in
;;;; both directions — and that turns out to be exactly the right amount of
;;;; opinion for this. The count below is a count of codepoints because raylib
;;;; decoded them, not because Flan did.
@@ -37,7 +37,7 @@
;;;; the bytes in front of that pointer belong to the allocator and not
;;;; to the text. It did not crash; it read rubbish and answered 0, which
;;;; is the worst of the available outcomes. The repair is a binding that
-;;;; says `(Ptr u8)` and means it, which the header check refused until
+;;;; says `Ptr(u8)` and means it, which the header check refused until
;;;; lib/cimport.ml's `agrees` grew the pointer arm its own comment had
;;;; been promising. `rl/get-codepoint-previous` is that binding and
;;;; `step-back` below is now one call to it.
@@ -126,7 +126,7 @@ fn collect-unique(codepoints: [i32]) -> ()
;; The codepoint starting at `off`, and its size in bytes through `size-out`.
;;
-;; `(string (slice b off (length b)))` is the whole of what the C's `ptr`
+;; `string(slice(b, off, length(b)))` is the whole of what the C's `ptr`
;; is: the tail of the text from here on. It costs nothing to say — a `string` and a
;; `[u8]` are the same two words — and the shim NUL-terminates a copy of it
;; for the duration of the call, which is all GetCodepointNext wants, because
@@ -160,7 +160,7 @@ fn step-forward(off: i32) -> i32
;; string — which reaches C as a copy — is the one thing it must not be
;; handed. `rl/get-codepoint-previous` takes the bytes and an offset instead
;; and builds the interior pointer itself; see the note beside it in
-;; vendor/raylib/raylib.flan. What comes back through `size` is the length of
+;; vendor/raylib/raylib.fln. What comes back through `size` is the length of
;; the codepoint *behind* `off`, so the previous offset is the difference.
;;
;; This used to be a hand-written walk over continuation bytes — step back one
@@ -179,7 +179,7 @@ fn step-back(off: i32) -> i32
once font: rl/Font
-;; Whether the TTF was there, asked once. A `defonce` and not the call itself
+;; Whether the TTF was there, asked once. A `once` and not the call itself
;; in the draw loop: is-path-file is a stat, and a syscall per frame to answer a
;; question whose answer cannot change while the program runs is exactly what
;; the per-frame rule in docs/PORTING.md is about.
diff --git a/examples/text-input-box.fln b/examples/text-input-box.fln
index b2a4ce66..a1fcc0ce 100644
--- a/examples/text-input-box.fln
+++ b/examples/text-input-box.fln
@@ -13,7 +13,7 @@
;;;; the second character of a fast pair.
;;;;
;;;; raylib says "empty" by answering 0, and rl/get-char-pressed is now a
-;;;; Flan wrapper that says it with None instead — see raylib.flan, "Draining
+;;;; Flan wrapper that says it with None instead — see raylib.fln, "Draining
;;;; raylib's two input queues". What that buys is visible below: the C
;;;; shape, which this file had, reads the queue in *two* places, once to
;;;; prime the loop and once at the bottom of the body, and a `> 0` in
@@ -21,9 +21,9 @@
;;;; Option shape reads it in one place, and the case where there is no
;;;; character is a branch the checker knows about rather than a comparison.
;;;;
-;;;; The second is set-mouse-cursor, which needed a new defenum. raylib's
+;;;; The second is set-mouse-cursor, which needed a new enum. raylib's
;;;; header says `int cursor` and means one of eleven MOUSE_CURSOR_ values, so
-;;;; the Flan face is `MouseCursor` — hand-written in raylib.flan beside the
+;;;; the Flan face is `MouseCursor` — hand-written in raylib.fln beside the
;;;; other cursor calls, excluded from the generated half, and mapped in
;;;; `bindings` so the eleven members are checked against the header. See the
;;;; comment there: this call is made on every frame off a hover test, and the
@@ -66,7 +66,7 @@ fn main() -> ()
defer rl/close-window()
name = array(max-input-chars, u8)
letter-count = 0
- text-box = rl/Rectangle({.x f32(screen-width) / 2.0 - 100.0, .y 180.0, .width 225.0, .height 50.0})
+ text-box = rl/Rectangle{.x f32(screen-width) / 2.0 - 100.0, .y 180.0, .width 225.0, .height 50.0}
mouse-on-text = false
frames-counter = 0
rl/set-target-fps(60)
diff --git a/examples/text-rectangle-bounds.fln b/examples/text-rectangle-bounds.fln
index 6f995874..2c2f86d4 100644
--- a/examples/text-rectangle-bounds.fln
+++ b/examples/text-rectangle-bounds.fln
@@ -5,9 +5,9 @@
;;;; form was built rather than an application found for it afterwards.
;;;;
;;;; Its inner loop reads `font.recs[index]` and `font.glyphs[index]`. Both
-;;;; fields are `(Ptr T)` — that is what raylib hands back and there is nothing
+;;;; fields are `Ptr(T)` — that is what raylib hands back and there is nothing
;;;; else it could hand back — and a pointer from C carries no length, so
-;;;; `(at (.recs font) i)` answered `(Ptr rl/Rectangle) cannot be indexed` and
+;;;; `font.recs[i]` answered `Ptr(rl/Rectangle) cannot be indexed` and
;;;; the whole example stopped there. Element 0 through `deref` was the entire
;;;; readable surface of a two-hundred-glyph array.
;;;;
@@ -35,7 +35,7 @@
;;;; wrap, which is the thing the example is about.
;;;;
;;;; - `GetCodepoint` wants a pointer into the middle of the text, and Flan has
-;;;; the operation the C is spelling by hand: `(string (slice b i n))` is the
+;;;; the operation the C is spelling by hand: `string(slice(b, i, n))` is the
;;;; tail from `i` with no copy and no pointer arithmetic. It is not free:
;;;; the shim NUL-terminates a copy on the way into C, into a 256-byte stack
;;;; buffer or a malloc when the tail is longer — and this message is 284
@@ -158,7 +158,7 @@ fn main() -> ()
let text = bytes-view(message)
is-resizing = false
is-word-wrap = true
- let container = rl/Rectangle({.x 25.0, .y 25.0, .width f32(screen-width) - 50.0, .height f32(screen-height) - 250.0})
+ let container = rl/Rectangle{.x 25.0, .y 25.0, .width f32(screen-width) - 50.0, .height f32(screen-height) - 250.0}
let resizer = rl/Rectangle{.x 0.0 .y 0.0 .width 14.0 .height 14.0}
let min-width = f32(60.0)
min-height = f32(60.0)
@@ -185,9 +185,8 @@ fn main() -> ()
let h = container.height + (mouse.y - last-mouse.y)
container.width = clamp(w, min-width, max-width)
container.height = clamp(h, min-height, max-height)
- else
- if rl/is-mouse-button-down(:mouse-left) and rl/check-collision-point-rec(mouse, resizer)
- is-resizing = true
+ elif rl/is-mouse-button-down(:mouse-left) and rl/check-collision-point-rec(mouse, resizer)
+ is-resizing = true
resizer.x = container.x + container.width - 17.0
resizer.y = container.y + container.height - 17.0
last-mouse = mouse
diff --git a/examples/text-writing-anim.fln b/examples/text-writing-anim.fln
index fd52795b..2d3ac3e6 100644
--- a/examples/text-writing-anim.fln
+++ b/examples/text-writing-anim.fln
@@ -6,14 +6,14 @@
;;;; DrawText(TextSubtext(message, 0, framesCounter/10), ...)
;;;;
;;;; TextSubtext is in raylib.h and is not in the bindings, on the rule
-;;;; raylib.flan states for the whole Text* family: it answers a `char *` into
+;;;; raylib.fln states for the whole Text* family: it answers a `char *` into
;;;; a rotating static buffer, and declare-c refuses a returned pointer to
;;;; memory the caller does not own. There is no missing line to add — the
;;;; binding would be wrong at any signature.
;;;;
;;;; And it does not matter, because Flan has the operation as a primitive.
-;;;; `(slice a lo hi)` takes a view of an array, `(string b)` reinterprets the
-;;;; bytes as a string at no cost, and `(string (slice message 0 n))` is
+;;;; `slice(a, lo, hi)` takes a view of an array, `string(b)` reinterprets the
+;;;; bytes as a string at no cost, and `string(slice(message, 0, n))` is
;;;; TextSubtext with the static buffer removed — no copy, no shared state, no
;;;; rotation to run out of. Porting the example is therefore how the gap gets
;;;; *closed* rather than reported: the C's workaround for not having slices
@@ -28,8 +28,8 @@
;;;; the C's, and it costs one `min`.
;;;;
;;;; The message is a `[u8]` and not a `string` because `slice` takes an array
-;;;; or a slice; `(bytes-view "…")` is the bridge in the other direction from
-;;;; `(string …)` and costs nothing either. The embedded newline is written as
+;;;; or a slice; `bytes-view("…")` is the bridge in the other direction from
+;;;; `string(…)` and costs nothing either. The embedded newline is written as
;;;; an escape, and raylib's draw-text breaks the line on it.
import rl "vendor:raylib"
diff --git a/examples/textures-fog-of-war.fln b/examples/textures-fog-of-war.fln
index b8f25460..29011030 100644
--- a/examples/textures-fog-of-war.fln
+++ b/examples/textures-fog-of-war.fln
@@ -8,8 +8,8 @@
;;;; bilinear sampler doing the interpolation. With the default
;;;; :filter-point the same program draws 32-pixel squares.
;;;;
-;;;; That is what needed adding: `TextureFilter`, a new defenum in
-;;;; vendor/raylib/raylib.flan, with set-texture-filter moved from the
+;;;; That is what needed adding: `TextureFilter`, a new enum in
+;;;; vendor/raylib/raylib.fln, with set-texture-filter moved from the
;;;; generated half to the hand-written one and mapped in `bindings` so its
;;;; six members are checked against raylib.h. The header says `int filter`
;;;; and there is nothing in an `int` to say that 1 is the interesting value;
@@ -117,14 +117,14 @@ fn main() -> ()
;; Light the square around the player, skipping anything off the map.
;; Without that test this reads and writes outside the array, which in the
;; C is undefined and here is a bounds trap — the same bug, reported.
- let y-2 = player-tile-y - player-tile-visibility
- while y-2 < player-tile-y + player-tile-visibility
+ let vis-y = player-tile-y - player-tile-visibility
+ while vis-y < player-tile-y + player-tile-visibility
let x = player-tile-x - player-tile-visibility
while x < player-tile-x + player-tile-visibility
- if x >= 0 and x < tiles-x and y-2 >= 0 and y-2 < tiles-y
- tile-fog[y-2 * tiles-x + x] = 1
+ if x >= 0 and x < tiles-x and vis-y >= 0 and vis-y < tiles-y
+ tile-fog[vis-y * tiles-x + x] = 1
x += 1
- y-2 += 1
+ vis-y += 1
;; Draw the fog into its own little target first, at one pixel per tile.
;; blank is alpha 0, so a tile that is neither unseen nor remembered
;; leaves nothing behind and the map below shows through unmodified.
diff --git a/examples/textures-image-generation.fln b/examples/textures-image-generation.fln
index fba55d12..4d1c992c 100644
--- a/examples/textures-image-generation.fln
+++ b/examples/textures-image-generation.fln
@@ -8,7 +8,7 @@
;;;; of its pixels.
;;;;
;;;; What it puts under load that nothing else does. An Image is the one
-;;;; struct in raylib.flan that carries a pointer to memory raylib owns —
+;;;; struct in raylib.fln that carries a pointer to memory raylib owns —
;;;; `data (Ptr u8)` — and it is returned by value, so every one of these nine
;;;; calls hands back a 24-byte aggregate through the shim's out-pointer with
;;;; a live heap block inside it. The corpus had crossed an Image before
diff --git a/examples/textures-image-processing.fln b/examples/textures-image-processing.fln
index dfcf3973..d5d12931 100644
--- a/examples/textures-image-processing.fln
+++ b/examples/textures-image-processing.fln
@@ -9,16 +9,16 @@
;;;; had ever handed raylib a buffer and asked it to rewrite the buffer.
;;;;
;;;; What that puts under load, and it is a different thing from the nine
-;;;; Gen* calls in examples/textures-image-generation.flan: **in-place
+;;;; Gen* calls in examples/textures-image-generation.fln: **in-place
;;;; mutation of an Image through a (Ptr Image)**. Eight of the nine filters
;;;; take the image by pointer and change `data` under the caller —
;;;; image-format and image-blur-gaussian *reallocate* it, so the pointer the
-;;;; caller held before the call is freed by it. raylib.flan's Images section
+;;;; caller held before the call is freed by it. raylib.fln's Images section
;;;; already says that the by-value/by-pointer split is raylib's own and is
;;;; kept deliberately so a caller can see which calls change what they are
;;;; given; this is the example that depends on it being right.
;;;;
-;;;; What needed adding: `PixelFormat`, a defenum in vendor/raylib/raylib.flan,
+;;;; What needed adding: `PixelFormat`, a enum in vendor/raylib/raylib.fln,
;;;; with image-format moved from the generated half to the hand-written one
;;;; and mapped in `bindings` so its twenty-four members are checked against
;;;; raylib.h. The C's line is
@@ -67,9 +67,9 @@ const screen-height = 450
const num-processes = 9
-;; The C's ImageProcess enum. Flan's defenum lowers to an i32 for C's benefit
-;; and these never cross to C, so they are defconsts — the same choice
-;; examples/textures-image-generation.flan made for its texture index.
+;; The C's ImageProcess enum. Flan's enum lowers to an i32 for C's benefit
+;; and these never cross to C, so they are consts — the same choice
+;; examples/textures-image-generation.fln made for its texture index.
const proc-none = 0
const proc-color-grayscale = 1
const proc-color-tint = 2
@@ -109,7 +109,7 @@ fn make-source-image() -> rl/Image
img
;; The C's `switch (currentProcess)`. A cond here, as in
-;; examples/textures-image-generation.flan, and for the same reason: Flan has
+;; examples/textures-image-generation.fln, and for the same reason: Flan has
;; no switch and the chain reads the same.
;;
;; Every arm takes the image by pointer and every arm rewrites the buffer the
@@ -188,14 +188,14 @@ fn main() -> ()
mouse-hover-rec = -1
toggle-recs = array(num-processes, rl/Rectangle)
for i in range(num-processes)
- toggle-recs[i] = rl/Rectangle({.x 40.0 .y f32(50 + 32 * i) .width 150.0 .height 30.0})
+ toggle-recs[i] = rl/Rectangle{.x 40.0 .y f32(50 + 32 * i) .width 150.0 .height 30.0}
rl/set-target-fps(60)
until rl/window-should-close()
;; Update
;;
;; The C computes mouseHoverRec with a loop whose `else` clause resets it
;; on every miss and whose `break` leaves it set on a hit. As in
- ;; examples/textures-mouse-painting.flan the reset is lifted out in front
+ ;; examples/textures-mouse-painting.fln the reset is lifted out in front
;; and the loop only ever sets it, which is the same answer said plainly —
;; the nine rectangles do not overlap, so there is no first-hit-wins rule
;; to preserve.
diff --git a/examples/textures-mouse-painting.fln b/examples/textures-mouse-painting.fln
index 60fcaa06..799ec463 100644
--- a/examples/textures-mouse-painting.fln
+++ b/examples/textures-mouse-painting.fln
@@ -7,14 +7,14 @@
;;;; load-image-from-texture → image-flip-vertical → export-image
;;;;
;;;; Nothing in the corpus had run it. image-from-image has a headless
-;;;; acceptance case and sand.flan loads images the other way, but the path
+;;;; acceptance case and sand.fln loads images the other way, but the path
;;;; that reads a render target's pixels back into CPU memory, corrects for
;;;; GL's bottom-up rows and encodes a PNG had never been exercised at all.
;;;; All three came out of the generated half of the bindings; nothing needed
;;;; adding for this file.
;;;;
;;;; The flip is the same fact as the negative source height in
-;;;; examples/textures-fog-of-war.flan, met from the other side: on screen the
+;;;; examples/textures-fog-of-war.fln, met from the other side: on screen the
;;;; canvas is drawn with a negative-height source rectangle so GL's bottom-up
;;;; rows come out the right way up, and on save there is no source rectangle
;;;; to negate, so the pixels are turned over in memory instead. A program
@@ -92,7 +92,7 @@ fn main() -> ()
;; 30 wide with a 2-pixel gap, starting 10 from the left.
colors-recs = array(max-colors-count, rl/Rectangle)
for i in range(max-colors-count)
- colors-recs[i] = rl/Rectangle({.x 10.0 + 32.0 * f32(i), .y 10.0, .width 30.0, .height 30.0})
+ colors-recs[i] = rl/Rectangle{.x 10.0 + 32.0 * f32(i), .y 10.0, .width 30.0, .height 30.0}
color-selected = 0
color-selected-prev = 0
color-mouse-hover = 0
@@ -117,9 +117,8 @@ fn main() -> ()
let mouse-pos = rl/get-mouse-position()
if rl/is-key-pressed(:key-right)
color-selected += 1
- else
- if rl/is-key-pressed(:key-left)
- color-selected -= 1
+ elif rl/is-key-pressed(:key-left)
+ color-selected -= 1
color-selected = clamp(color-selected, 0, max-colors-count - 1)
;; Which swatch the pointer is over, or -1. See the header comment: the
;; reset is here rather than in an else branch inside the loop.
@@ -156,10 +155,9 @@ fn main() -> ()
if mouse-pos.y > 50.0
rl/draw-circle(i32(mouse-pos.x), i32(mouse-pos.y), brush-size,
colors[0])
- else
- if rl/is-mouse-button-released(:mouse-right) and mouse-was-pressed
- color-selected = color-selected-prev
- mouse-was-pressed = false
+ elif rl/is-mouse-button-released(:mouse-right) and mouse-was-pressed
+ color-selected = color-selected-prev
+ mouse-was-pressed = false
btn-save-mouse-hover = rl/check-collision-point-rec(mouse-pos, btn-save-rec)
;; The round trip. See the header comment for why the flip is here and
;; not on the draw.
diff --git a/lib/build.ml b/lib/build.ml
index af69d4be..af4f255f 100644
--- a/lib/build.ml
+++ b/lib/build.ml
@@ -919,7 +919,7 @@ let executable ?(opts = default) ?(csrcs = []) ?(lflags = []) ?(pnames = [])
a release build calls into it — the compiler only emits a registry lookup
for a name the host was not built with, which cannot arise without cells —
but the agent package's C refers to it, and a package's C sources are
- collected whatever [main] does. Leaving it out made [flan build sand.flan]
+ collected whatever [main] does. Leaving it out made [flan build sand.fln]
fail at the link with an undefined symbol, which reads as a compiler bug
rather than as a missing flag. The table is BSS, so this costs address
space and not binary size, and [-rdynamic] and the cells are still what
diff --git a/lib/dev.ml b/lib/dev.ml
index 6897d2a8..de4aa469 100644
--- a/lib/dev.ml
+++ b/lib/dev.ml
@@ -1427,7 +1427,7 @@ let eval_expr_at t ~code ~origin ~pause ~at =
and its only other reader is the select in [accept_loop] —
which is not running, because it is further up this very call
stack, inside [serve]. A program that prints as it goes (and a
- game loop prints as it goes; sand.flan does) fills those 64K
+ game loop prints as it goes; sand.fln does) fills those 64K
while the module below was being built, and the game thread is
then stopped inside [flan_write_stdout], in an [fwrite] that
will not return until somebody reads. It never reaches the
@@ -3344,7 +3344,7 @@ let reg_listing t ~verb ~note =
Locals were the half the shadow stack was built for; these are arguably the
more useful half in this language. A game keeps most of its state in
- top-level [defonce]s and sand.flan holds its entire grid that way, so "what
+ top-level [defonce]s and sand.fln holds its entire grid that way, so "what
is the program's state right now" is a question about globals and there was
nowhere to ask it.
diff --git a/lib/load.ml b/lib/load.ml
index 1ac7734c..95420256 100644
--- a/lib/load.ml
+++ b/lib/load.ml
@@ -45,7 +45,7 @@ type t = {
owns. A file on disk does not say what it is called from outside — the
*importer* chooses that — so this is the only place the answer exists, and
a REPL editing a package's source needs it to know that [poll] typed in
- vendor/agent/agent.flan means [agent/poll] to the running program. *)
+ vendor/agent/agent.fln means [agent/poll] to the running program. *)
pkgs : pkg list;
(* Every [defmacro] the imported packages declare, qualified under the alias
each was imported as and quasiquote-desugared, ready for
@@ -95,7 +95,7 @@ let rec find_collection dir name =
if String.equal parent dir then None else find_collection parent name
(* A package is a directory, or a single source file named outright. The file
- form is for the program that is also a library: sand.flan sits beside three
+ form is for the program that is also a library: sand.fln sits beside three
other loose .flan files, so naming its directory would import all four, and
moving it into one of its own would be arranging the tree around a
limitation. A file carries no [.c] and no [link] — those belong to a
diff --git a/lib/prelude.ml b/lib/prelude.ml
index 8a227ded..d2f0041a 100644
--- a/lib/prelude.ml
+++ b/lib/prelude.ml
@@ -106,7 +106,7 @@ let source = {flan|
;; what it buys is a *different element*, silently.
;;
;; The restarts that matter are the ones the program already established — a
-;; frame loop's `continue`, sand.flan's shape — and they are on the restart
+;; frame loop's `continue`, sand.fln's shape — and they are on the restart
;; stack and reachable from a handler or from the break loop without anything
;; being pushed here. That is plan.org's "restarts go at the resync point,
;; once", with allocation and file failure as the named exceptions and this on
@@ -985,7 +985,7 @@ let source = {flan|
;;
;; They are here anyway, because the alternative on offer today is worse: a
;; caller that wants an angle writes the same two `declare` lines at the top
-;; of its own file (examples/core-input-gestures-testbed.flan did, before
+;; of its own file (examples/core-input-gestures-testbed.fln did, before
;; this), which is the identical libm call with the identical caveat and
;; nobody's name on it. One copy with the caveat written down beats a copy per
;; file with none.
@@ -1217,7 +1217,7 @@ let source = {flan|
;; **Which face to use.** The i64 of nanoseconds is exact and is what a
;; difference should be taken in. The f64 of seconds is what a frame loop
;; wants, and it is the shape raylib's `get-time` already answers with
-;; (vendor/raylib/raylib.flan, `(declare-c get-time [] f64 "GetTime")`), so the
+;; (vendor/raylib/raylib.fln, `(declare-c get-time [] f64 "GetTime")`), so the
;; two mix without a conversion at every site. The monotonic origin is latched
;; at the first read rather than being boot — see runtime/flan_rt.c — so that
;; the f64 stays integer-exact in nanoseconds for a hundred days of process
@@ -2469,7 +2469,7 @@ let source = {flan|
;; Whether a form is the empty list, (). [form-items] cannot answer this: it
;; returns the empty slice for a non-list too, so "no items" and "not a list"
;; arrive the same. A macro that has to tell `()` from a name needs the
-;; difference — see vendor/raylib/modes.flan, where a lone () argument is a
+;; difference — see vendor/raylib/modes.fln, where a lone () argument is a
;; body that was not written rather than a body of one form.
(defn is-form-empty-list [f Form] bool
(match f
diff --git a/lib/session.ml b/lib/session.ml
index 30f426b2..54910f12 100644
--- a/lib/session.ml
+++ b/lib/session.ml
@@ -398,7 +398,7 @@ let package_decls t =
(* Which package a file being edited belongs to, if any.
- A form typed into vendor/agent/agent.flan declares [poll], but the running
+ A form typed into vendor/agent/agent.fln declares [poll], but the running
program only ever knew it as [agent/poll]: the alias is chosen by whatever
imported the directory, and is written nowhere in the file itself. Without
this the form splices as a brand-new unrelated name, the evaluation reports
diff --git a/runtime/flan_dyn.c b/runtime/flan_dyn.c
index d3c8fcbf..6c72f526 100644
--- a/runtime/flan_dyn.c
+++ b/runtime/flan_dyn.c
@@ -116,7 +116,7 @@ int8_t flan_vec_push(void *v, const void *elem, int64_t size, int64_t align,
*
* NaN-boxed, in a word. A double is *itself*: the 2^64 minus a NaN's worth of
* bit patterns that are not quiet NaNs are read straight back as f64, at no
- * cost, which is what a language where f64 is first class and where sand.flan
+ * cost, which is what a language where f64 is first class and where sand.fln
* runs a physics loop wants. Everything else hides inside the quiet-NaN space.
*
* The box is sign bit + all-ones exponent + quiet bit, which is
@@ -2927,7 +2927,7 @@ uint8_t flan_dyn_need_bool(flan_dyn v) {
* box's kind was not what the program apparently expected.
*
* Once per *site*, not per value. These casts sit in per-cell-per-frame
- * loops — sand.flan runs at 120fps — and a per-occurrence line would be a
+ * loops — sand.fln runs at 120fps — and a per-occurrence line would be a
* flood rather than a diagnostic. The site is the [loc] text [check.ml]
* passes in, and the table below is keyed on its *bytes* rather than its
* address: the two backends emit their own constants for it and neither
diff --git a/sand.fln b/sand.fln
index 0489adb7..552c7817 100644
--- a/sand.fln
+++ b/sand.fln
@@ -64,8 +64,10 @@ fn settle(row: i32, col: i32) -> ()
1
elif not is-right
-1
+ elif f32(rand()) < 0.5
+ 1
else
- if f32(rand()) < 0.5 then 1 else -1
+ -1
grid[y, col + side] = grid[row, col]
grid[row, col] = 0
velocity[y, col + side] = vel
diff --git a/test/programs/pkg-hidden-main.flan b/test/programs/pkg-hidden-main.flan
index 7d247f31..084ed18c 100644
--- a/test/programs/pkg-hidden-main.flan
+++ b/test/programs/pkg-hidden-main.flan
@@ -1,11 +1,11 @@
;;;; A name the import did not bring.
;;;;
-;;;; sand.flan declares a main and this imports it, so sand/main is a name
+;;;; sand.fln declares a main and this imports it, so sand/main is a name
;;;; somebody might reasonably write — and is not one. Left to the checker it
;;;; would be "unknown name", which is true and unhelpful; the refusal has to
;;;; say the name is missing on purpose. Never built: the refusal is the test.
-(import sand "../../sand.flan")
+(import sand "../../sand.fln")
(defn main [] i32
(sand/main)
diff --git a/test/programs/pkg-shared.flan b/test/programs/pkg-shared.flan
index 4f52442a..31691b8f 100644
--- a/test/programs/pkg-shared.flan
+++ b/test/programs/pkg-shared.flan
@@ -1,11 +1,11 @@
;;;; One package reached along two routes.
;;;;
-;;;; raylib is imported here and again by sand.flan, which this also imports.
+;;;; raylib is imported here and again by sand.fln, which this also imports.
;;;; Loading it twice would declare every binding twice and be refused as a
;;;; collision, so a directory is read once and keyed by its real path. Nothing
;;;; calls into raylib, so nothing links it either.
-(import sand "../../sand.flan")
+(import sand "../../sand.fln")
(import rl "vendor:raylib")
(defn main [] i32
diff --git a/test/programs/raylib-codepoints.flan b/test/programs/raylib-codepoints.flan
index f76b44fb..57a33b7f 100644
--- a/test/programs/raylib-codepoints.flan
+++ b/test/programs/raylib-codepoints.flan
@@ -36,7 +36,7 @@
;;;;
;;;; Nothing here draws, so nothing here needs the TTF the example looks for.
-(import cp "../../examples/text-codepoints-loading.flan")
+(import cp "../../examples/text-codepoints-loading.fln")
(import rl "vendor:raylib")
(defconst max-walk 128)
diff --git a/test/programs/raylib-image-processing.flan b/test/programs/raylib-image-processing.flan
index 4e8de18f..815ff862 100644
--- a/test/programs/raylib-image-processing.flan
+++ b/test/programs/raylib-image-processing.flan
@@ -37,7 +37,7 @@
;;;; at all, so there is nothing in them for an implementation to have an
;;;; opinion about.
-(import ip "../../examples/textures-image-processing.flan")
+(import ip "../../examples/textures-image-processing.fln")
(import rl "vendor:raylib")
;; Three probes, chosen so that between them every shape and the background
diff --git a/test/programs/virtual-controls-headless.flan b/test/programs/virtual-controls-headless.flan
index 80ace528..58fd906b 100644
--- a/test/programs/virtual-controls-headless.flan
+++ b/test/programs/virtual-controls-headless.flan
@@ -26,7 +26,7 @@
;;;; the four directions move the player the four different ways. A crossed
;;;; axis anywhere in nearest-button or move-player changes the hash.
-(import vc "../../examples/core-input-virtual-controls.flan")
+(import vc "../../examples/core-input-virtual-controls.fln")
(import rl "vendor:raylib")
;; A sixtieth of a second, fixed. The real program uses get-frame-time, which
diff --git a/test/test_acceptance.ml b/test/test_acceptance.ml
index eb42c7ab..2d608e3e 100644
--- a/test/test_acceptance.ml
+++ b/test/test_acceptance.ml
@@ -278,28 +278,21 @@ module Pool = struct
done
end
-(* sand.flan is the workspace's own program, edited by hand and not by this
- suite, and three cases here compile it. It still calls the randomness
- functions by names the prelude does not have, so those three cannot check
- until it is brought up to date — and the fixture, rather than a comment, is
- what says so: the moment sand.flan calls (rand) every case below runs again
- with nothing to undo. The one thing that is not automatic is the sand hash,
- which is stale whatever happens because the generator now answers 64 bits
- per draw; its row says so where the number is. *)
+(* sand.fln is the workspace's own program, edited by hand and not by this
+ suite, and several cases here compile it. It once called randomness
+ functions by names the prelude did not have, and was skipped until it
+ called real ones; it now calls `rand`, which the prelude does have, so
+ these cases run unconditionally. The one thing that is not automatic is
+ the sand hash, which is stale whatever happens because the generator now
+ answers 64 bits per draw; its row says so where the number is. *)
let sand_checks =
- match In_channel.with_open_bin "../sand.flan" In_channel.input_all with
- (* The open paren is the test and not the bare name: sand.flan explains
- itself in a comment that says rand-f32 too, and a guard that matched that
- would go on skipping after the calls were fixed — a guard that can never
- release is worse than no guard. *)
- | src -> not (contains src "(rand-f32")
+ match In_channel.with_open_bin "../sand.fln" In_channel.input_all with
+ | _ -> true
| exception _ -> false
let () =
if not sand_checks then
- print_endline
- "acceptance: skipping the cases that compile sand.flan — it calls \
- rand-f32, which is not a name";
+ print_endline "acceptance: skipping the cases that compile sand.fln — it is not there";
match Sys.command "command -v clang > /dev/null 2>&1" with
| 0 ->
let exe = compile "../calc-me.flan" in
@@ -2778,9 +2771,9 @@ let () =
This used to be skipped without FLAN_RAYLIB_H, because the generated
bindings only existed when a header was read. They are committed now —
- vendor/raylib/generated.flan — so it runs on the same terms as every
+ vendor/raylib/generated.fln — so it runs on the same terms as every
other raylib case here: libraylib linkable, and no raylib-devel. That is
- the change stated as a test rather than as a claim. If generated.flan
+ the change stated as a test rather than as a claim. If generated.fln
were ever regenerated empty or stale, this is what would say so, and it
would say so on an ordinary machine rather than only on one with a
header exported. *)
@@ -3126,7 +3119,7 @@ let () =
Texture2D notes above say it: glyph-padding is read by nothing raylib
computes on the CPU, offset-y only moves a glyph when it is drawn, and
of each atlas rectangle only `width` is ever looked at. Those four
- fields rest on the header agreeing with raylib's and on sand.flan
+ fields rest on the header agreeing with raylib's and on sand.fln
looking right, and on nothing else. *)
let raylib_font_out =
"valid yes\n\
@@ -3150,7 +3143,7 @@ let () =
(* Again at -O0. Everything above runs through mem2reg, which launders a
sloppy alloca; -O0 tests the IR actually emitted, so a disagreement
between the two points at undefined behaviour rather than a typo. *)
- (* sand.flan's simulation, headless. This is the milestone-4 acceptance
+ (* sand.fln's simulation, headless. This is the milestone-4 acceptance
case: N frames from a seeded PRNG, one hash. It imports the sim package
and not raylib, deliberately — a program that imports raylib links
libraylib on every target, and this one is the version meant to run on
@@ -3686,7 +3679,7 @@ let () =
outputs "an imported package nothing calls, -O0" ~opt:"-O0"
"programs/pkg-unused.flan" "ok\n";
(* A package may import a package, and one reached along two routes is read
- once: pkg-shared imports sand.flan, which imports raylib, and imports
+ once: pkg-shared imports sand.fln, which imports raylib, and imports
raylib itself. Loading it twice would declare every binding twice. *)
if sand_checks then
outputs "a package reached along two routes" "programs/pkg-shared.flan"
@@ -4022,7 +4015,7 @@ let () =
"programs/generic-map-reject.flan" "at $t = f64";
(* This one is refused either way, so the guard is about *which* refusal:
- with sand.flan out of date the file stops at the import and the needle
+ with sand.fln out of date the file stops at the import and the needle
below would pass on the wrong error. *)
if sand_checks then
refuses "a package's main is not visible" "programs/pkg-hidden-main.flan"
@@ -6291,7 +6284,7 @@ level "1"
of the program's three cross-kind cast *sites*, the third being the
(f32 int-box) after the loop. That count is the whole reason the
runtime carries a table of sites at all: these casts live in frame
- loops, sand.flan's at 120fps, and a flood is not a diagnostic.
+ loops, sand.fln's at 120fps, and a flood is not a diagnostic.
[run] merges stderr into stdout, so the warnings and the numbers come
back in one string and the count is a count over it. *)
diff --git a/test/test_dev.ml b/test/test_dev.ml
index e7940991..89ba8cb1 100644
--- a/test/test_dev.ml
+++ b/test/test_dev.ml
@@ -670,13 +670,13 @@ let () =
either. The daemon derives the package from the path, so
the file this is sent with is the one the import qualified. *)
let agent_file =
- let p = "../vendor/agent/agent.flan" in
+ let p = "../vendor/agent/agent.fln" in
try Unix.realpath p with Unix.Unix_error _ -> p
in
let r =
request c
(Printf.sprintf
- "(:op \"eval\" :code \"(defstruct Blob [id i32])\" :file %s)"
+ "(:op \"eval\" :code \"struct Blob(id: i32)\" :file %s)"
(Wire.quote agent_file))
in
if status r <> "ok" then
@@ -8924,7 +8924,7 @@ let () =
half of the same claim and lives where it always did. *)
(* ── A program that starts its agent late ──────────────────────────
- The shape a real one has: sand.flan opens a window and starts the
+ The shape a real one has: sand.fln opens a window and starts the
agent afterwards, so the program's own [(agent/start ...)] is seconds
into the run. The merged session used to wait up to ten seconds for the
socket *before* running its accept loop, which charged those seconds to
diff --git a/test/test_flan.ml b/test/test_flan.ml
index 59b8221e..bfdd2a08 100644
--- a/test/test_flan.ml
+++ b/test/test_flan.ml
@@ -860,8 +860,9 @@ let () =
Printf.printf "FAIL %s does not parse: %s: %s\n"
path (Loc.to_string loc) msg)
(* dune runs tests in _build/default/test/; the corpus is declared as a
- dep in test/dune and lands at the build root. *)
- [ "../calc-me.flan"; "../sand.flan" ];
+ dep in test/dune and lands at the build root. sand is .fln now
+ (decision 130), so it is not here — this reads the paren syntax only. *)
+ [ "../calc-me.flan" ];
Test_support.report ~label:"parse" ()
diff --git a/test/test_session.ml b/test/test_session.ml
index f7bbcc17..7924856b 100644
--- a/test/test_session.ml
+++ b/test/test_session.ml
@@ -16,19 +16,15 @@ let () = Watchdog.arm ~seconds:600 "test_session"
let fail fmt = Test_support.fail fmt
let has = Test_support.contains
-(* sand.flan is the workspace's own program, edited by hand and not by this
+(* sand.fln is the workspace's own program, edited by hand and not by this
suite, and three cases below read it: it is the file with imports, and it is
- the single-file package. While it calls the randomness functions by names
- the prelude does not have it does not check at all, and those three would be
- reporting that rather than anything about a session. The fixture decides,
- so there is nothing to undo once sand.flan is brought up to date. *)
+ the single-file package. It once called randomness functions by names the
+ prelude did not have; it now calls `rand`, which the prelude does have, so
+ these cases run unconditionally — see test_acceptance.ml, which guards on
+ the same file for the same reason. *)
let sand_checks =
- match In_channel.with_open_bin "../sand.flan" In_channel.input_all with
- (* The open paren and not the bare name — see test_acceptance.ml, which
- guards on the same file for the same reason: sand.flan names rand-f32 in
- a comment as well, and matching that would leave these skipped for ever.
- *)
- | src -> not (has src "(rand-f32")
+ match In_channel.with_open_bin "../sand.fln" In_channel.input_all with
+ | _ -> true
| exception _ -> false
(* Every rejection is asserted on its reason, not just on the failure: the
@@ -760,23 +756,24 @@ let () =
keeps the *expanded* declarations, so the package's names are replaced in
place rather than appended a second time and rejected as duplicates. *)
if not sand_checks then
- print_endline
- "session: skipping the cases that read sand.flan — it calls rand-f32, \
- which is not a name"
+ print_endline "session: skipping the cases that read sand.fln — it is not there"
else begin
- let t, _ = Session.create ~file:"../sand.flan" () in
- let src = In_channel.with_open_bin "../sand.flan" In_channel.input_all in
+ let t, _ = Session.create ~file:"../sand.fln" () in
+ let src = In_channel.with_open_bin "../sand.fln" In_channel.input_all in
(* [~origin] is the buffer's own path and both editor paths send it
(flan.el's `:file (or buffer-file-name "headers file naming the library's own C heade
flan generate-c <package-dir> reads it with
clang -Xclang -ast-dump=json, turns every function it can represent into
the same declare-c line a person would have written, and writes them to
-generated.flan in the package — which is committed.
generated.fln in the package — which is committed.
$ flan generate-c vendor/raylib
-wrote vendor/raylib/generated.flan: 268 declarations, 117 refused, of 581 functions
+wrote vendor/raylib/generated.fln: 318 declarations, 61 refused, of 581 functions
in vendor/raylib/raylib-5.5.h.
Every defstruct, every hand-written declare-c and every mapped
constant agrees with it.