Skip to content

Debugger - #38

Merged
adh merged 13 commits into
mainfrom
debugger
Sep 4, 2026
Merged

adh merged 13 commits into
mainfrom
debugger

Conversation

@adh

@adh adh commented Sep 4, 2026

Copy link
Copy Markdown
Owner

No description provided.

Copilot AI lite review requested due to automatic review settings September 4, 2026 17:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The interactive debugger currently can’t pass arguments to restarts and the new interactive CLI test assertions are fragile against prompt/EOF output, so behavior and tests need tightening before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR introduces an interactive debugger for ListTalk conditions, adds a per-thread debugger hook mechanism, and expands the restart/correctable-error facilities so evaluation and REPL flows can recover from certain errors (e.g., unbound symbols) instead of hard-aborting.

Changes:

  • Add a new ListTalkDebugger library with an interactive debugger REPL and object inspector, plus CLI integration (-d/--debug and auto-enable for interactive top-level).
  • Introduce debugger hook support in thread state and condition signaling paths, and extend stack trace printing with a “skip frames” variant for cleaner debugger backtraces.
  • Add new restarts/correctable error support (LT_cerror, unbound-symbol restarts), adjust static restart naming to keyword symbols, and expand tests accordingly.
File summaries
File Description
tests/listtalk_cli_test.py Adds CLI coverage for -d/--debug and an interactive REPL syntax-error recovery case.
tests/conditions_test.c Adds tests for debugger hook scoping/disablement, unbound-symbol restarts, and LT_cerror continue restart behavior.
tests/c_api_test.c Adds environment slot behavior test and expands static restart behavior checks (keyword naming + invocation).
src/vm/thread_state.c Initializes new per-thread debugger_hook state.
src/vm/stack_trace.c Adds LT_stack_trace_print_skipping and keeps LT_stack_trace_print as a wrapper.
src/vm/reader.c Invokes debugger on unrecoverable reader errors before aborting.
src/vm/eval.c Adds unbound-symbol restarts (use-value, define-variable) and catch/throw-based resumption logic.
src/vm/error.c Invokes debugger for fatal errors and adds correctable error API (LT_cerror) with a :continue restart.
src/vm/conditions.c Adds debugger hook storage + LT_invoke_debugger implementation.
src/debugger/debugger.c New interactive debugger/inspector implementation and debugger hook primitive.
src/classes/Restart.c Changes static restart naming to keyword symbols and defers materialization.
src/classes/Package.c Adds predefined ListTalk-debug package and wires package use relationships.
src/classes/Environment.c Exposes parent slot via a native-pointer slot type (NULL → NIL).
src/classes/Class.c Introduces LT_SlotType_ReadonlyNativeObjectPointer.
src/bin/listtalk/main.c Adds -d/--debug, enables debugger at interactive top-level, and updates REPL loop control flow with a toplevel restart.
meson.build Builds/installs ListTalkDebugger and links it into the listtalk executable; generates pkg-config metadata.
ListTalk/vm/thread_state.h Adds debugger_hook field to thread state struct.
ListTalk/vm/stack_trace.h Declares LT_stack_trace_print_skipping.
ListTalk/vm/error.h Declares LT_cerror public API.
ListTalk/vm/conditions.h Declares debugger hook APIs and adds LT_WITH_DEBUGGER_HOOK macro.
ListTalk/debugger/debugger.h New public debugger API header.
ListTalk/classes/Restart.h Updates static-restart macro to register a materialization constructor.
ListTalk/classes/Package.h Exposes LT_PACKAGE_LISTTALK_DEBUG.
ListTalk/classes/Class.h Declares new readonly native-pointer slot type.
Review details
  • Files reviewed: 23/24 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/debugger/debugger.c
Comment on lines +260 to +284
static void debugger_repl_object(LT_Value object, void* opaque){
DebuggerContext* context = opaque;
LT_Value restart_value = debugger_restart_selected(object, context->restarts);
LT_Value returned_to_debugger = LT_NIL;

if (debugger_keyword_selected(object, "inspect-condition")){
LT_Debugger_inspect(context->condition);
return;
}
if (debugger_keyword_selected(object, "inspect-backtrace")){
LT_Debugger_inspect(context->backtrace);
return;
}

if (restart_value != LT_INVALID){
LT_Restart* restart = LT_Restart_from_value(restart_value);
LT_apply(
LT_Restart_callable(restart),
LT_NIL,
LT_NIL,
LT_NIL,
NULL
);
return;
}
Comment thread tests/listtalk_cli_test.py Outdated
Comment on lines +88 to +94
if not completed.stdout.rstrip().endswith("9"):
sys.stderr.write(
"FAIL: top-level REPL did not recover from syntax error\n{0}".format(
completed.stdout
)
)
return 1
adh and others added 3 commits September 4, 2026 19:56
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…gement; add tests for restart behavior and banner display

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The new interactive CLI tests use brittle stdout.rstrip().endswith(...) assertions that are likely to fail because the REPL prints prompts even when stdin is a pipe.

Review details

Suppressed comments (2)

tests/listtalk_cli_test.py:92

  • The REPL prints prompts even when stdin is a pipe (see src/repl/repl.c:429-439), so completed.stdout.rstrip().endswith("9") can fail because output often ends with a final listtalk> prompt on EOF. Prefer asserting that the expected result appears somewhere in stdout (or strip trailing prompts) instead of requiring it to be the very last character.
    if not completed.stdout.rstrip().endswith("9"):

tests/listtalk_cli_test.py:120

  • Similar to the syntax-error case, the interactive REPL session will typically emit a trailing listtalk> prompt before exiting on EOF, so checking endswith(expected_result) is brittle and can fail depending on the REPL implementation/back-end. Consider checking for the result token/line within stdout instead.
    if not completed.stdout.rstrip().endswith(expected_result):
  • Files reviewed: 23/24 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@adh
adh merged commit c41143c into main Sep 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants