Files
rose-ash/plans/designs/f-breakpoint.md
giles 985671cd76 hs: query targets, prolog hook, loop scripts, new plans, WASM regen
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>
2026-05-06 09:19:56 +00:00

81 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# F-Breakpoint — `breakpoint` command (+2)
**Suite:** `hs-upstream-breakpoint`
**Target:** Both tests are `SKIP (untranslated)`.
## 1. The 2 tests
- `parses as a top-level command`
- `parses inside an event handler`
Both are untranslated — no test body exists. The test names say "parses" — these are parser tests, not runtime tests.
## 2. What upstream checks
From `test/core/breakpoint.js`:
```js
it('parses as a top-level command', () => {
expect(() => _hyperscript.evaluate("breakpoint")).not.toThrow();
});
it('parses inside an event handler', () => {
const el = document.createElement('div');
el.setAttribute('_', 'on click breakpoint');
expect(() => _hyperscript.processNode(el)).not.toThrow();
});
```
Both tests verify that `breakpoint` is accepted by the parser without throwing. Neither test checks that the debugger actually fires. `breakpoint` is a no-op command in production builds — it calls `debugger` in JS, which is a no-op when devtools are closed.
## 3. What's needed
### Parser (`lib/hyperscript/parser.sx`)
Add `breakpoint` to the command dispatch — it should parse as a zero-argument command. The parser's command `cond` (wherever `add`, `remove`, `hide` etc. are dispatched) needs a branch:
```
((= val "breakpoint") (hs-parse-breakpoint))
```
`hs-parse-breakpoint` just returns a `{:cmd "breakpoint"}` AST node (or however commands are represented). It consumes no additional tokens.
### Compiler (`lib/hyperscript/compiler.sx`)
Add a compiler branch for `breakpoint` AST node. Emits a no-op or a `debugger` statement equivalent. Since we're in SX (not JS), a no-op `(do nil)` is correct.
### Generator (`tests/playwright/generate-sx-tests.py`)
The 2 tests are simple — hand-write them:
```lisp
(deftest "parses as a top-level command"
(let ((result (guard (e (true false))
(hs-compile "breakpoint")
true)))
(assert result)))
(deftest "parses inside an event handler"
(hs-cleanup!)
(let ((el (dom-create-element "div")))
(dom-set-attr el "_" "on click breakpoint")
(let ((result (guard (e (true false))
(hs-activate! el)
true)))
(assert result))))
```
## 4. Implementation checklist
1. `sx_find_all` in `lib/hyperscript/parser.sx` for the command dispatch `cond`.
2. Add `breakpoint` branch → `hs-parse-breakpoint` function returning minimal command node.
3. `sx_find_all` in `lib/hyperscript/compiler.sx` for command compilation dispatch.
4. Add `breakpoint` branch → emit no-op.
5. Replace 2 `SKIP` bodies in `spec/tests/test-hyperscript-behavioral.sx` with translated tests above.
6. Run `hs_test_run suite="hs-upstream-breakpoint"` — expect 2/2.
7. Run smoke 0195 — no regressions.
8. Commit: `HS: breakpoint command — parser + no-op compiler (+2)`
## 5. Risk
Very low. Zero-argument no-op command. The only risk is mis-locating the command dispatch branch in the parser.