diff options
| author | user <user@clank> | 2026-08-16 15:49:07 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-16 15:49:07 +0200 |
| commit | 7cd9de2c15f5b00b99ea8d974a4c73f0c2d4f972 (patch) | |
| tree | 476b659e7f5b54b0511b1b5e4dd9a559fa7230bf /docs | |
| parent | sl0ppty: zero strength is not a pass (diff) | |
| download | slosh-7cd9de2c15f5b00b99ea8d974a4c73f0c2d4f972.tar.gz slosh-7cd9de2c15f5b00b99ea8d974a4c73f0c2d4f972.tar.xz slosh-7cd9de2c15f5b00b99ea8d974a4c73f0c2d4f972.zip | |
sl0ppty: bits
`&` `|` `^` `~` `<<` `>>`, on the 32-bit value the VM already used. There was
nothing: `x & 7` answered `unexpected trailing input at offset 2` and
`(x ^ y) % 16 < 2` answered `expected ) at offset 3`, which is a fair
description of a parser that had never heard of either.
`^` is the reason to bother. `(x ^ y) & 1` is the cheapest interesting texture
there is, and the language could express a sweep, a ramp and a comparison but
not one bit of pattern without `%` gymnastics.
**Bits bind tighter than comparison, which is not what C does.** `x & 7 == 0`
means `x & (7 == 0)` in C -- a precedence Ritchie put on record as a mistake,
kept for a decade of compatibility that a shader expression in a config file
does not have. Here it asks what it looks like it asks. Among themselves the
usual `&` then `^` then `|`; shifts stay where C has them, just under `+ -`.
`&&` and `||` still parse as themselves: the bitwise rungs decline the first
character when a second one follows it.
Semantics are JavaScript's, deliberately and to the letter -- the shift count
masked to five bits (`1 << 33` is 2), `>>` keeping the sign (`-8 >> 1` is -4).
Not taste: `contrib/shadertoy.html` reimplements this language in JS so the
preview can run in a browser, and `tests/test_shadertoy.py` compares the two on
every expression it can think of. Anything C leaves implementation-defined had
to be pinned to what JS would show, so the signed right shift is written out in
the VM rather than left to the compiler.
Verified: 22 new cases in `tests/expr_test.c` covering the operators, both
precedence questions, the sign, and the masked count; the preview learned the
same six operators and the same ladder, and the cross-check now agrees with the
compiler on 564 evaluations, including generated ones that reach for bits. Then
seven bitwise chains in a real pane -- an XOR texture, a drifting one, a stepped
pulse that walks eight shades of `t >> 7 & 7` and needs no `abs`.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/shaders.md | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/docs/shaders.md b/docs/shaders.md index bb0221d..aa332e5 100644 --- a/docs/shaders.md +++ b/docs/shaders.md @@ -61,6 +61,7 @@ shaders { | | `since` — milliseconds the pane has been in its current state | | operators | `+ - * / %` (integer; division by zero is 0, not a crash) | | | `< > <= >= == != && \|\| !` give 0 or 1, so `(x < 10) * 200` is a rule | +| | `& \| ^ ~ << >>` on the 32-bit value, binding **tighter** than comparison — so `x & 7 == 0` asks what it looks like, unlike C | | | `a ? b : c` — both sides are evaluated, then one is chosen | | functions | `min(a,b)` `max(a,b)` `abs(a)` `clamp(v,lo,hi)` | | | `dist(x1,y1,x2,y2)` — counts a row double, because a cell is about twice as tall as it is wide | |
