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

2.9 KiB
Raw Blame History

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:

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:

(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.