import type { RedirectResult } from '../../context/session_context.ts';
import type { ByteSource } from '../../io/types.ts';
import { IOResult } from '../../io/types.ts';
import type { Decisions } from '../../policy/decisions.ts';
import { type Policies } from '../../policy/index.ts';
import type { HandOff } from '../../policy/types.ts';
import type { CallStack } from '../../shell/call_stack.ts';
import { type JobConsole } from '../../shell/console/index.ts';
import { ExitSignal, ReturnSignal } from '../../shell/errors.ts';
import type { JobTable } from '../../shell/job_table/index.ts';
import { type TSNodeLike } from '../../shell/types.ts';
import type { PathSpec } from '../../types.ts';
import type { EvaluationContext } from '../evaluation.ts';
import type { SessionState } from '../session/session.ts';
import type { ExecuteStringFn } from './builtins/types.ts';
import type { ExecuteNodeFn } from './command/types.ts';
import { fd0Binding } from './statement.ts';
/** Runs a list of statements: `executeBody` bound to the walk. */
export type BodyRun = (nodes: readonly TSNodeLike[], bound?: ReturnType<typeof fd0Binding>) => Promise<RedirectResult>;
export declare class LoopSignal extends Error {
    stdout: ByteSource | null;
    io: IOResult;
    levels: number;
    constructor(stdout?: ByteSource | null, io?: IOResult, levels?: number);
}
export declare class BreakSignal extends LoopSignal {
}
export declare class ContinueSignal extends LoopSignal {
}
/**
 * Execute a list of statements in order: a group, a loop or `if` body, a
 * `case` arm, a function body.
 *
 * A statement ending in `&` is launched as a job through `runStatement`
 * rather than run inline; `jobTable` is the job plane it needs. The ERR
 * action answers a failing statement, its output landed
 * through `sink` when the body writes to one, and `set -e` stops the list.
 * `bound` is `fd0Binding` as the construct running the list started, so an
 * `exec <&-` in a loop body reaches the next test. A comment leaves `$?` as
 * it was, and a `break` or `continue` records its own status as it leaves
 * (bash leaves `${PIPESTATUS[@]}` at `0`).
 */
export declare function executeBody(executeNode: ExecuteNodeFn, body: readonly TSNodeLike[], context: EvaluationContext, stdin: ByteSource | null, callStack: CallStack | null, jobTable: JobTable | null, handed: HandOff | null, decisions: Decisions | null, executeFn?: ExecuteStringFn | null, sink?: JobConsole | null, bound?: ReturnType<typeof fd0Binding>): Promise<RedirectResult>;
export type Unwinding = LoopSignal | ReturnSignal | ExitSignal;
export declare function isUnwinding(err: unknown): err is Unwinding;
/**
 * An unwinding `break`, `continue`, `return` or `exit` with the output the
 * construct it leaves had produced put in front of its own, which that
 * construct would otherwise drop on the way out (bash wrote it as it went).
 * Mirrors Python's carried.
 */
export declare function carried(sig: Unwinding, stdout: ByteSource | null, io: IOResult): Promise<Unwinding>;
/**
 * Put what an unwinding construct's process substitutions wrote as they
 * finished behind the output the signal already carries. Mirrors Python's
 * trailed.
 */
export declare function trailed(sig: Unwinding, stdout: Uint8Array, stderr: Uint8Array): Promise<void>;
/**
 * What a function or a sourced file gives back as it returns: its output and
 * status, with what its RETURN action wrote after the output. A `return` in
 * a function's action returns from the function with its status. A sourced
 * file has returned by the time its action runs, so a `return` there leaves
 * the function around it, or only complains at the top level. An `exit`,
 * or that `return`, leaves with the output in front of its own. Mirrors
 * Python's returning.
 */
export declare function returning(executeFn: ExecuteStringFn | null, session: SessionState, stdin: ByteSource | null, callStack: CallStack, stdout: ByteSource | null, io: IOResult, sink?: JobConsole | null): Promise<[ByteSource | null, IOResult]>;
/**
 * What a child shell reports when an `Unwinding` ends it: what it wrote, its
 * diagnostic, and its status, `exit`'s contained one, `return`'s own, or that
 * of `break` or `continue`. A child running one simple command is the shell
 * `exit` ends (`simple`), so it reports `exit`'s own status (`: ${U?} | cat`
 * is 127, `( : ${U?} ) | cat` is 1), unless the signal left text `eval` or
 * `source` ran. Mirrors Python's ended.
 */
export declare function ended(sig: Unwinding, simple?: boolean): IOResult;
/**
 * Take what a nested line wrote before it left (an `exec`'d command, an ERR
 * or RETURN action), for the redirects it ran under to route. An EXIT
 * action's output, the `cleanup` at its end, goes around them, and what the
 * other unwinding signals carry went through them already. Mirrors Python's
 * take_stdout.
 */
export declare function takeStdout(sig: Unwinding): Promise<Uint8Array>;
/**
 * Take the diagnostic an `Unwinding` carries, for the redirects it was
 * written under to route. Mirrors Python's take_stderr.
 */
export declare function takeStderr(sig: Unwinding): Promise<Uint8Array>;
export declare function handleIf(run: BodyRun, branches: readonly [TSNodeLike[], TSNodeLike[]][], elseBody: TSNodeLike[] | null, session: SessionState): Promise<RedirectResult>;
export declare function handleFor(run: BodyRun, variable: string, values: readonly (string | PathSpec)[], body: readonly TSNodeLike[], context: EvaluationContext, policies?: Policies | null): Promise<RedirectResult>;
export declare function handleWhile(run: BodyRun, test: readonly TSNodeLike[], body: readonly TSNodeLike[], session: SessionState, until?: boolean): Promise<RedirectResult>;
export type CforEval = (exprs: readonly TSNodeLike[], dflt: number) => Promise<number>;
/**
 * Run bash's C-style for: ((init; cond; update)) around a body.
 *
 * `evalExpr` evaluates one expression slot to its integer value (the
 * default when the slot is empty) and throws ArithError with the
 * offending expression text on an invalid expression, or ReadonlyVariableError
 * when it assigns to a readonly variable; bash aborts the loop with
 * status 1, keeping the output of iterations that ran. The update
 * expression still runs after `continue`, per bash. A PolicyDenied is a
 * header expression assigning a hidden name.
 */
export declare function handleCfor(run: BodyRun, exprs: readonly (readonly TSNodeLike[])[], body: readonly TSNodeLike[], evalExpr: CforEval, session: SessionState): Promise<RedirectResult>;
/**
 * Run the first arm whose pattern matches `word`, and after it the arms its
 * terminator reaches: `;&` falls into the next arm's body untested, `;;&`
 * tests the rest, `;;` stops.
 */
export declare function handleCase(run: BodyRun, word: string, items: readonly [readonly TSNodeLike[], readonly TSNodeLike[], string][], session: SessionState, expand: (node: TSNodeLike) => Promise<string>): Promise<RedirectResult>;
/**
 * Run bash's select loop: menu to stderr, choice read from stdin. Each
 * iteration prompts with `$PS3` (`#? ` when unset), takes a line the way a
 * bare `read` does into REPLY, and sets the variable to the chosen entry
 * (empty for an out-of-range or non-numeric reply, like bash). An empty
 * reply redisplays the menu without running the body, and so does a body
 * that empties REPLY; end of input prints a newline and ends the loop with
 * status 1. An empty list runs nothing. `sink` is where the body's
 * statements write as they finish, so the loop's own newline lands in
 * order.
 */
export declare function handleSelect(run: BodyRun, variable: string, values: readonly (string | PathSpec)[], body: readonly TSNodeLike[], context: EvaluationContext, stdin?: ByteSource | null, policies?: Policies | null, signal?: AbortSignal, sink?: JobConsole): Promise<RedirectResult>;
//# sourceMappingURL=control.d.ts.map