Reset scratch per line and unwind dead scopes in host function calls
akbasic_runtime_call_function()'s body loop drives process_line_run() directly, skipping the per-line prologue akbasic_runtime_step() provides. The call environment's value scratch therefore accumulated across the whole body, and any body past about ten real lines died with 'Maximum values per line reached' -- a limit that is supposed to be per line. The loop now runs the same prologue step() does. A body that died also left its call scopes active: nothing popped them, so a host absorbing script errors drained the twelve-slot environment pool after twelve dead calls. The loop now unwinds to the caller's environment on every exit path. New: akbasic_runtime_clear_error(), the missing half of host revival. A run's first BASIC-level error latches deliberately, and set_mode(RUN) alone cannot un-decide that; a host that absorbed the error calls this beside it. Both defects and the revival dance are pinned in tests/user_functions.c. Co-authored-by: andrew <andrew@aklabs.net> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XiGgpHuXUm2mR4Wzndw3dc
This commit is contained in:
@@ -632,6 +632,27 @@ akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_println(akbasic_Runtime *obj,
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_set_mode(akbasic_Runtime *obj, int mode);
|
||||
|
||||
/**
|
||||
* @brief Forgive the last BASIC-level error, so a host may call again.
|
||||
*
|
||||
* A program run latches its first runtime error and ends -- deliberately, and
|
||||
* a host cannot un-decide that with akbasic_runtime_set_mode() alone: the
|
||||
* latch survives the mode change, every later line is skipped, and every
|
||||
* later akbasic_runtime_call_function() answers a stale value after walking
|
||||
* the whole source table doing nothing.
|
||||
*
|
||||
* A host that absorbed a script error -- reported through the sink, actor
|
||||
* marked dumb, frame preserved -- calls this beside
|
||||
* `akbasic_runtime_set_mode(obj, AKBASIC_MODE_RUN)` to put the runtime back
|
||||
* in service. It is for hosts between calls, not for verbs during a run: a
|
||||
* running program's first error still ends it, exactly once, with one line.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_clear_error(akbasic_Runtime *obj);
|
||||
|
||||
/**
|
||||
* @brief Evaluate one AST leaf, drawing scratch values from the environment.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
|
||||
Reference in New Issue
Block a user