debugger: evaluate as a snippet compiled like a REPL entry #39
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Evaluate supports method calls by compiling the expression like a REPL entry (section 12).
Source
Acceptance criteria
tests/debug/Dependencies
None known.
Moved from the planning lists of the docs; the design record stays the specification.
[loop:torbscript] intake: in scope (author orion, label loop). Implements DEBUGGER.md section 20 / section 12 (evaluate compiles the expression like a REPL entry, so method calls work); the design record is the specification, no collision with CONCEPT "Open Questions". Shares the evaluate path with the conditional-breakpoint issue, so the two may need ordering; settled in refine. Touches the debugger and the REPL compile path, seed impact to be confirmed. next: refine (queued)
[loop:torbscript] refine: still queued behind the intake order. next: waiting (ready buffer full: #4, #163, #164, #223 are ready) until 2026-10-10T04:00:00Z
[loop:torbscript] claim refine by session:loop-torbscript-20261022 until 2026-10-23T01:30:00Z
[loop:torbscript] decided by the loop: scope of this issue is the first slice of the snippet evaluator, one PR. Read from DEBUGGER.md sections 12, 15, 20 and REPL.md sections 4, 5, 7.
compiler/src/debugger/evaluate.trb) stays the first path: hover, watch, logpoints and conditions keep their read-only, no-code-runs guarantee (section 7 and 12 rule it for them). Only a debug-consoleevaluate(context: repl) whose textparseWatchrefuses goes to the snippet path. Why: the design record keeps the cheap path for hover and watch, and a hover that runs code would change a stopped program on a mouse move.evaluatenames; deeper frames and statements/declarations are out of this slice (the follow-up is filed when this lands, just in time). Why: that is the case section 20 names ("method calls included") and it keeps the PR to one or two commits.replEntry-style function (constby value; a boxed value is lent, so a method that mutates it is visible, as in any native debugger). A Local whose type cannot be written is left out, and a snippet that names it answers<name> is not available in the snippet.<error: why>; the debugged program stays stopped and intact. Output of the snippet (print) goes to the console as anoutputevent, not into the debuggee's stdout.variablesshows a value (showValue), withtypeand avariablesReferencewhere it has children.evaluate, same response fields; a compile error of the snippet is the response message (success: false) with the checker's text relative to the snippet.[loop:torbscript] refine: brought to the definition of ready (design decisions in the comment above).
Goal. In the debug console,
evaluateruns expressions the restricted evaluator refuses, method and function calls included, by compiling the text like a REPL entry against the stopped frame.Implements. DEBUGGER.md section 20 ("Evaluate as a snippet") / section 12; reuses REPL.md sections 4, 5, 7. Update sections 12, 15 and 20 of DEBUGGER.md in the same PR (the open item moves to built, the unbuilt rest - deeper frames, statements - stays listed).
Seed. No: no syntax, native, driver flag or string-looked-up std name expected. If the work needs a new kernel operation in
runtime/, that is a seed-relevant change and goes in the second commit with the note; the seed refresh stays Torben's.Acceptance criteria
evaluatewithcontext: repland a text the restricted evaluator refuses (e.g.names.length(),point.distance(origin),double(count)) answers the call's value,typeandvariablesReference.hover,watchandclipboardcontexts, logpoints and breakpoint conditions behave exactly as before (existingtests/debug/*.dapsessions unchanged and green).success: falsewith a message; the program stays stopped and a followingvariablesrequest is unchanged.tests/debug/evaluate-snippet.dap+.expected+ program dir covering: a method call, a function call, a call on a boxed record, a panic, a compile error, an unavailable name, and a hover that still takes the restricted path.torb format --checkclean; gates a/b green in forge CI.Size. One PR, one or two Conventional Commits (
feat(debugger): evaluate snippets like a REPL entryplusdocs(design): ...if split). Worker: implementer sonnet/high (compiler/src). If the implementer finds the synthesis cannot be shared withcompiler/src/repl/synthesis.trbwithout a larger refactor, a refactor of that size is acceptable (Torben's standing rule), but report it in the PR.Next: implement. Token usage of this refine worker: about 45k.
[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T04:17:00Z
[loop:torbscript] release implement: worker timed out at the lease end (PR #400 is open, not mergeable against current main, CI running); respawning a fresh worker to rebase and finish.
[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T10:17:00Z
[loop:torbscript] release implement: worker ended at its 30 minute run limit; PR #400 has a review with a real defect (SIGSEGV on the first snippet evaluate, tier A) and red CI. Respawning with a longer run limit.
[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T12:06:00Z
[loop:torbscript] implement: PR #400 fixed on
b78ba7be, CI green (commit messages, gates, bootstrap, tier A, tier B, same-C, playground). next: Argus' re-review of #400.Review 333, three blockers:
names.length()snippet): the snippet's signature wrote the frame's list local as the traitList<String>, a boxed payload with a table, while the frame holds the list's storage words; the nestedexecuteread the words wrong and the debuggee died.writtenTypeNameOf(values.trb) now writes a list, map or set the frame holds as storage as its implementation (ArrayList,TrieMap,TrieSet). The VM-instruction trace commits used to localize it are gone from the history.tests/debug/evaluate-snippet.expectedis filled from a complete session (all 24 requests answered) and reviewed:names.length()3,point.distance(origin)25,double(count)42,counter.bump()1 then 2 andcounter.hits2, the output eventsnippet says hibefore theshout("hi")result, the panic, compile-error and unavailable-name (letters) messages,variablesunchanged after the failures exceptCounter(hits: 2), the program's own line3 3 21 2 3.format --checkis green (thelower.trbline is fixed).Coverage for the crash class: new session
tests/debug/evaluate-snippet-collections(a snippet naming a list, a map and a set local), tier A "tests/debug against .expected" passes with both sessions. History: 6 Conventional Commits on main (301f2149), no merge or revert commits, no kernel operations touched. PR body updated,Closes #39kept.