diff --git a/BUILT.md b/BUILT.md index 60c69ec..4476e0c 100644 --- a/BUILT.md +++ b/BUILT.md @@ -2073,7 +2073,7 @@ rule here is that what is not supported is rejected explicitly with the reason. reason, on the construction side and on the destructuring side, which is what stops the colon drifting back. **The sweep is a tool, not a one-off.** `tools/colon-to-dot.py` converted 681 labels across 45 `.flan` files, -`vendor/`, and the Flan embedded in `lib/prelude.ml` and the tests. It works on *forms*, not on text: a keyword +`vendor/` included, and 94 more in the Flan embedded in `lib/prelude.ml` and the tests. It works on *forms*, not on text: a keyword becomes a dot only where it sits in a field-label position inside a brace, so an enum member in value position (`{.k :hi}`), a genuine EDN map inside a string (`test/programs/edn.flan`), and a type-position `{K V}` are all left alone. It was kept in the tree because several lanes branched before it and their Flan needs the same pass at merge. diff --git a/NEXT.md b/NEXT.md index 1f82cee..62fb3a1 100644 --- a/NEXT.md +++ b/NEXT.md @@ -280,13 +280,15 @@ length is not known until the file is read and therefore cannot exist before an ~~**6. A field label is written with a dot, not a colon, and the colon is reserved for keys.**~~ **Done.** `{.x 1.0 .y 2.0}` is struct construction and `{inner .field}` is destructuring; the old spelling is refused, and the refusal names the new one. `:keys` kept its colon — it names no field, so leaving it alone is what lets the dot mean -exactly one thing. 681 labels across 45 `.flan` files, `vendor/` and the Flan embedded in `lib/prelude.ml` and the -tests. `Map` is now free to take `{:key value}` without colliding with struct literals. See BUILT.md, "The colon -belongs to keys". +exactly one thing. 681 labels across 45 `.flan` files including `vendor/`, plus 94 more in the Flan embedded in +`lib/prelude.ml` and the tests. `Map` is now free to take `{:key value}` without colliding with struct literals. See +BUILT.md, "The colon belongs to keys". -**Two things it left behind.** `render.ml` still *prints* a struct with colons, deliberately: -`emacs/flan-inspect.el:165` parses that output and hard-codes the colon, so the printer has to move with its reader -and that belongs to the Emacs lane. `emacs/MANUAL.md` and `flan-mode.el`'s font-lock also still show the colon. +**What it left for the Emacs lane, both verified.** `render.ml` still *prints* a struct with colons, deliberately: +`emacs/flan-inspect.el:165` parses that output and hard-codes the colon when it reads a field out, so the printer +has to move in the same commit as its reader. And `flan-mode.el:61` font-locks `:name` as a constant with nothing +matching `.name`, so a field label is now unfontified where it used to be coloured. Neither is urgent; both belong +with whoever next opens `emacs/`. **7. `Map` follows Odin's implementation.** Read `base/runtime/dynamic_map_internal.odin` before writing any of it; the checkout is at `~/Repositories/Odin`. Three properties are the ones worth copying, and they are stated in its own diff --git a/lib/check.ml b/lib/check.ml index 3a26a5d..f2773a5 100644 --- a/lib/check.ml +++ b/lib/check.ml @@ -1384,7 +1384,7 @@ and fold_left_prim ctx ~want loc name p ok what args = No allocating operation returns an error and none can fail silently. When the allocator cannot satisfy a request the operation signals - (StorageExhausted {:bytes n :align a :allocator id}) + (StorageExhausted {.bytes n .align a .allocator id}) with [error] — whose type is Never — inside a [restart-case] offering [retry]. That is one rule over every allocating operation, which is what @@ -2309,7 +2309,7 @@ and named_call ctx ~want loc name args = 1. It does NOT check UTF-8, because `string` does not claim UTF-8. The prelude settles this: valid-utf8? is an ordinary function you call when you care, decode-rune/rune-at/rune-count all take [u8] rather than - string, and decode-rune answers {:ok false :width 1} on a malformed + string, and decode-rune answers {.ok false .width 1} on a malformed byte rather than assuming its input is well-formed. 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