import type { ExpressionBoundaryValue, FunctionTable, NameEntry, NameTable, NodeFunctionDefinition, NodeInput, RuntimeExpressionValue } from './AST';
import { CharString } from './CharString';
type WorkspaceScope = {
    parent?: WorkspaceScope;
    nameTable: NameTable;
    functionTable: FunctionTable;
    resolveParentNames: boolean;
    defineName(name: string, node: NodeInput): NameEntry;
    hasLocalName(name: string): boolean;
};
type RuntimeNameWriter = {
    nameTable?: NameTable;
    defineName(name: string, node: RuntimeExpressionValue): NameEntry;
};
type ThrowSyntaxError = (message: string) => never;
type EvaluateInScope = (source: string, scope: WorkspaceScope) => NodeInput;
type UnparseInputArgument = (arg: ExpressionBoundaryValue) => string;
type IsCatchableError = (error: unknown) => boolean;
type OnCatchError = (error: unknown) => void;
/**
 * Workspace helpers shared by function calls and MATLAB/Octave workspace
 * built-ins.
 *
 * This module owns the non-parser parts of `persistent`, `global`, `inputname`,
 * `eval`, `evalin`, and `assignin`. Keeping these operations outside
 * `Interpreter.ts` makes the execution rules visible and testable without
 * requiring a full interpreter instance.
 */
declare class FunctionWorkspace {
    /**
     * Ensure that a function definition has its persistent-variable table.
     *
     * Persistent storage lives on the function definition node itself, matching
     * the lifetime of a parsed function definition. Call scopes receive copies
     * when the function is entered and write values back when it returns.
     */
    static ensurePersistentTable(func: NodeFunctionDefinition): Record<string, RuntimeExpressionValue>;
    /**
     * Copy all variable/function entries visible from `source` into `target`.
     *
     * The copy walks from outermost to innermost scope so local entries shadow
     * parent entries. It stops when a scope disables parent-name resolution,
     * preserving detached closure snapshots.
     */
    static copyVisibleScopeEntries(target: Pick<WorkspaceScope, 'nameTable' | 'functionTable'>, source?: WorkspaceScope): void;
    /**
     * Implement `inputname(n[, onlyVariableNames])`.
     *
     * With the default `onlyVariableNames = true`, MATLAB/Octave return an
     * empty string unless the selected argument is a plain variable name. When
     * `onlyVariableNames` is false, the original caller expression is returned
     * when an unparser is supplied.
     */
    static inputName(inputArgs: ExpressionBoundaryValue[], indexNode: NodeInput, throwSyntaxError: ThrowSyntaxError, onlyVariableNames?: boolean, unparse?: UnparseInputArgument): CharString;
    /**
     * Resolve `base` and `caller` workspace names for `evalin` and `assignin`.
     *
     * External files are intentionally not handled here; the browser UI owns
     * external-file access, so this helper only models in-memory workspaces.
     */
    static resolveWorkspace(name: string, baseScope: WorkspaceScope, callerScope: WorkspaceScope, throwSyntaxError: ThrowSyntaxError): WorkspaceScope;
    /**
     * Evaluate source in a target workspace, optionally running a catch string.
     *
     * This models the two-argument `eval`/three-argument `evalin` form while
     * leaving parsing and execution to the callback supplied by the interpreter.
     * The optional predicate lets the interpreter keep control-flow signals
     * such as `return`, `break`, and `continue` out of the catch string path.
     * The optional catch hook records the original error before catch source
     * execution so `lasterr`/`lasterror` see the same state as `try/catch`.
     */
    static evaluateWithCatch(scope: WorkspaceScope, source: string, catchSource: string | undefined, evaluate: EvaluateInScope, isCatchableError?: IsCatchableError, onCatchError?: OnCatchError): NodeInput;
    /**
     * Implement `assignin` after the interpreter has resolved the workspace.
     *
     * Values are copied before storage to avoid aliasing the caller's AST node.
     * The result is `VOID` because assignment-by-side-effect should not display
     * an answer in the command UI.
     */
    static assignIn(scope: RuntimeNameWriter, name: string, value: RuntimeExpressionValue): NodeInput;
    /**
     * Declare or initialize a persistent variable for a function call.
     *
     * A declaration without initializer creates an empty-array persistent value
     * on first use. A declaration with initializer only initializes the table if
     * the name has not been seen before, matching MATLAB/Octave persistent
     * semantics.
     */
    static declarePersistent(name: string, value: RuntimeExpressionValue | undefined, func: NodeFunctionDefinition, scope: RuntimeNameWriter): void;
    /**
     * Load all persistent variables into a fresh function-call scope.
     */
    static loadPersistentVariables(func: NodeFunctionDefinition, scope: RuntimeNameWriter): void;
    /**
     * Store changed persistent variables back into the function definition.
     *
     * Only names known to the persistent table are saved. This prevents ordinary
     * local variables from becoming persistent accidentally.
     */
    static storePersistentVariables(func: NodeFunctionDefinition, scope: Pick<WorkspaceScope, 'hasLocalName' | 'nameTable'>): void;
    /**
     * Declare a global binding in the current scope.
     *
     * Local and global scopes share the same `NameEntry` object. Mutating one
     * side therefore updates the other, which is the behavior expected by
     * MATLAB/Octave-like `global` declarations.
     *
     * Octave-style `global name = value` initializes a global binding only once
     * through declaration syntax. Later global declarations for the same name
     * reattach the existing binding without overwriting user changes.
     */
    static declareGlobal(name: string, value: RuntimeExpressionValue | undefined, globalNameSet: Set<string>, globalNameTable: NameTable, scopeNameTable: NameTable, globalInitializedNameSet?: Set<string>): void;
    /**
     * Clear global variables from global, active, and captured scopes.
     *
     * Function handles and nested functions can keep references to defining
     * scopes. The recursive walk follows those defining scopes so `clear global`
     * does not leave stale global aliases hidden in closures.
     *
     * @param globalNameSet Names currently declared as global.
     * @param globalScope Base global scope.
     * @param callScopes Active call scopes that may contain global aliases.
     * @param requestedNames Optional subset of global names to remove.
     */
    static clearGlobalVariables(globalNameSet: Set<string>, globalScope: WorkspaceScope | undefined, callScopes: WorkspaceScope[], requestedNames?: string[]): void;
}
export type { WorkspaceScope };
export { FunctionWorkspace };
declare const _default: {
    FunctionWorkspace: typeof FunctionWorkspace;
};
export default _default;
