aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-16 15:49:07 +0200
committeruser <user@clank>2026-08-16 15:49:07 +0200
commit7cd9de2c15f5b00b99ea8d974a4c73f0c2d4f972 (patch)
tree476b659e7f5b54b0511b1b5e4dd9a559fa7230bf /docs
parentsl0ppty: zero strength is not a pass (diff)
downloadslosh-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.md1
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 |