Hyperscript compiler/runtime:
- query target support in set/fire/put commands
- hs-set-prolog-hook! / hs-prolog-hook / hs-prolog in runtime
- runtime log-capture cleanup
Scripts: sx-loops-up/down, sx-hs-e-up/down, sx-primitives-down
Plans: datalog, elixir, elm, go, koka, minikanren, ocaml, hs-bucket-f,
designs (breakpoint, null-safety, step-limit, tell, cookies, eval,
plugin-system)
lib/prolog/hs-bridge.sx: initial hook-based bridge draft
lib/common-lisp/tests/runtime.sx: CL runtime tests
WASM: regenerate sx_browser.bc.js from updated hs sources
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
82 lines
4.1 KiB
Markdown
82 lines
4.1 KiB
Markdown
# F2 — `tell` Semantics Fix (+3)
|
||
|
||
**Suite:** `hs-upstream-tell`
|
||
**Target:** 3 failing tests out of 10. 7 already pass.
|
||
|
||
## 1. Failing tests
|
||
|
||
### "attributes refer to the thing being told"
|
||
```
|
||
on click tell #d2 then put @foo into me
|
||
```
|
||
d2 has attribute `foo="bar"`. After click, d1's text content should be `"bar"`.
|
||
`@foo` is an attribute ref — it should resolve against the **told element** (d2), not the event target (d1).
|
||
Currently gets `""` — attribute resolves against d1, which has no `foo` attribute.
|
||
|
||
### "your symbol represents the thing being told"
|
||
```
|
||
on click tell #d2 then put your innerText into me
|
||
```
|
||
d2 has innerText `"foo"`. After click, d1's text content should be `"foo"`.
|
||
`your` is the possessive of `you` — inside a `tell` block, `you`/`your` should bind to the told element.
|
||
Currently gets `""`.
|
||
|
||
### "does not overwrite the me symbol"
|
||
```
|
||
on click add .foo then tell #d2 then add .bar to me
|
||
```
|
||
After click: d1 should have both `.foo` and `.bar`; d2 should have neither.
|
||
`me` inside the `tell` block must still refer to d1 (the original event target).
|
||
Currently: assertion fails — `.bar` is going to d2 instead of d1.
|
||
|
||
## 2. What the 7 passing tests reveal about current behaviour
|
||
|
||
The passing tests include:
|
||
- `you symbol represents the thing being told` — `add .bar to you` adds to d2 ✓
|
||
- `establishes a proper beingTold symbol` — bare `add .bar` (no target) adds to the told element ✓
|
||
- `restores a proper implicit me symbol` — after `tell` block ends, bare commands target d1 again ✓
|
||
- `yourself attribute also works` — `remove yourself` inside tell removes d2 ✓
|
||
|
||
So `you`, `yourself`, and bare implicit target all work. The three bugs are:
|
||
1. Attribute refs (`@foo`) don't resolve against the told element
|
||
2. `your` (possessive of `you`) doesn't resolve
|
||
3. `me` is being rebound to the told element instead of kept as d1
|
||
|
||
## 3. Root cause analysis
|
||
|
||
Inside a `tell X` block, the runtime sets the implicit target to X. The three failures suggest:
|
||
|
||
**Bug A — attribute refs:** `@foo` resolves via a property-access path that reads from the *current event target* (`me`/`self`), not from the *implicit tell target*. The tell block sets implicit target but the attribute ref lookup skips it.
|
||
|
||
**Bug B — `your`:** `your` is parsed as a possessive modifier expecting `you` to be bound. If `you` is not bound in the tell scope (and only the implicit target is set), `your X` fails to resolve.
|
||
|
||
**Bug C — `me` rebinding:** The tell command saves/restores `me` but the save/restore is either not happening or is restoring the wrong value. `me` inside the block should remain d1 while the implicit default target is d2.
|
||
|
||
## 4. Fix
|
||
|
||
In `lib/hyperscript/runtime.sx`, find the `tell` command handler (search for `hs-tell` or the tell dispatch branch).
|
||
|
||
The correct semantics:
|
||
- Save current `me` value
|
||
- Set implicit target (used by bare commands like `add .bar`) to the told element
|
||
- Bind `you` = told element (so `you`, `your`, `yourself` work)
|
||
- Do **not** rebind `me` — keep it as the original event target
|
||
- Restore implicit target and unbind `you` after the block
|
||
|
||
For attribute refs (`@foo`): resolve against the current *implicit target* (told element), not against `me`. Find where `@attr` expressions are evaluated and ensure they read from the implicit target when inside a tell block.
|
||
|
||
## 5. Implementation checklist
|
||
|
||
1. `sx_find_all` in `lib/hyperscript/runtime.sx` for tell handler.
|
||
2. `sx_read_subtree` on the tell handler — verify save/restore of `me` vs implicit target.
|
||
3. Fix `me` rebinding: save old implicit target, set new one, do NOT touch `me`.
|
||
4. Bind `you`/`your`/`yourself` to told element in the tell scope env.
|
||
5. Find attribute ref (`@`) evaluation — ensure it reads from implicit target.
|
||
6. Run `hs_test_run suite="hs-upstream-tell"` — expect 10/10.
|
||
7. Run smoke 0–195 — no regressions.
|
||
8. Commit: `HS: tell — fix me rebinding, your/attribute-ref resolution (+3)`
|
||
|
||
## 6. Risk
|
||
|
||
Medium. The 7 passing tests constrain what can change — the fix must preserve `you`, `yourself`, bare implicit target, and restore-after-tell semantics. The three bugs are independent enough that they can be fixed one at a time and verified after each.
|