/**
 * THE BINDING RULE — which shell names a command text binds, and to what, read off the one lexer's facts and the
 * program read model's roles. A word that expands a name (`"$F"`, `${F}`, a `~` reading `HOME`) names a path only
 * through what the text bound that name to; this module answers "what may `F` hold here", and nothing else.
 *
 * Two halves:
 *  · {@link bindingEffectOf} — what ONE segment does to the names: binds a name to a value (an assignment statement, a
 *    declaration builtin's `NAME=value`, a `for` list), makes a name unknown (a builtin whose operand role binds a name,
 *    an assigning expansion `${N:=…}`, an arithmetic assignment, a code body that runs later), gives a name an ATTRIBUTE
 *    (integer, a case change, an array, read-only: a later assignment to it stores something other than its text, or
 *    nothing), or makes EVERY name unknown (a name reference, `eval`, `source`, a computed name, an unquoted
 *    here-document `${`), and resets every name to the state it starts the text in (a function body: it runs at its
 *    call, against that table);
 *  · {@link BindingThread} — the effects threaded through the segments the way the plan threads the working directory
 *    (`shell-read-plan.ts`), in their ORDERED state: a binding is one for a reader only where it may run before the
 *    reader in the same shell — not one written after it, inside a subshell the reader is not in (a closed `( … )`, a
 *    pipeline member that is not the last, a background job) or in a function body (it runs at a call: a call the plan
 *    sees makes every name a body binds unknown from there). A value bound in a segment that may not have run before
 *    a reader (an `&&` / `||` run, a branch, a loop body, the last pipeline member) joins the values the name held
 *    before instead of replacing them. A reader in a function body loses every name another body binds — unless the
 *    body declared it with a plain `local`. `PWD` / `OLDPWD` start from what the working-directory thread says.
 *    An attribute and a name reference hold for every segment they may RUN before: a later one, one in a function body
 *    (it runs at its call), one in the same loop body (a later beat).
 *
 * A name the text does not settle is UNKNOWN, and a word expanding an unknown name stays a word the shell rewrites (its
 * read cannot be established). `HOME` is an ordinary name whose state at the start of a text is the declared home.
 * The shell's own variables (the ones bash sets, holds read-only or evaluates itself) are never bound from text.
 */
import { type LexedRedirect, type LexedSegment, type LexedToken, type LexedWord } from "../../shell/lex.js";
import { type DeclaredAttribute } from "./program-read-model.js";
import { type BuiltinState } from "./shell-read-builtins.js";
/** A value a name may hold — the text the program receives ({@link spelled}: what a shell re-parsing it reads), literal
 *  throughout, or a PATTERN whose matches are the values (a `for` list word the shell globs before the loop binds it;
 *  `spelled` is then the pattern as the program receives it where it matches nothing): `glob`, with its `parts` — the
 *  value in runs: a literal run (quoted or literal text, a settled value) and a pattern run (glob pieces as written,
 *  quoting kept, and as a reader judges them — {@link WordExpansion.pattern}). The one producer is the piece walk
 *  ({@link valueOf}). */
export type BoundValue = {
    readonly spelled: string;
    readonly glob?: never;
    readonly parts?: never;
    readonly fields?: readonly string[];
} | {
    readonly spelled: string;
    readonly glob: true;
    readonly parts: readonly ValuePart[];
    readonly fields?: never;
};
/** One run of a pattern {@link BoundValue}: literal text, or a pattern — the shell expands its characters — `text` as
 *  written (what a shell re-reading it matches by), `judged` as a reader judges the names it matches. */
export type ValuePart = {
    readonly text: string;
    readonly pattern: false;
} | {
    readonly text: string;
    readonly pattern: true;
    readonly judged: string;
};
/** A spelling the deny judge alone reads ({@link Binding.floor}, {@link wordFloorValues}): a value, or a word as written
 *  where its names are unknown — nothing re-reads it, so a pattern says no more than that it is one. */
export interface FloorValue {
    readonly spelled: string;
    readonly glob?: true;
    /** A pattern's spelling as a reader judges the names it matches, where it is not `spelled` ({@link judgedSpellingOf}). */
    readonly pattern?: string;
}
/** A pattern value's names as a reader judges them, where that is not its spelling: its runs, a class the judge widens
 *  as `?` (the lexer's `WordExpansion.pattern.judged`), a leading `~` the literal tilde it is. */
export declare function judgedSpellingOf(v: BoundValue): string | undefined;
/** A value as a deny-floor spelling, its judged spelling with it. */
export declare function floorOf(v: BoundValue): FloorValue;
/** The values a name may hold where the text settles it. */
export type NameValues = readonly BoundValue[];
/** What a name holds at one point of a text: its possible values, or `"unknown"`. (The values are a NAMED arm: the
 *  release manifest reads a union that spells a word as a vocabulary, and a `readonly …[]` arm beside the word is a shape
 *  it cannot enumerate — it would then publish the set unreadable.) */
export type NameState = NameValues | "unknown";
/**
 * The variables bash keeps itself — it sets them (`PWD`, `REPLY`, `OPTARG`, `BASH_REMATCH`, …), holds them read-only
 * (`SHELLOPTS`, `BASHOPTS`, `BASH_VERSINFO`: an assignment to one is refused), or evaluates every value assigned to them
 * as ARITHMETIC (the integer variables: `OPTIND`, `RANDOM`, `LINENO`, `HISTCMD`, `BASHPID`, …; the reference
 * implementation's table of them, `zsh`'s included, is read whole: a member that is not one in this shell costs a
 * question, never a read). Their value is never the text that bound it.
 */
export declare const SHELL_INTEGER_VARIABLES: ReadonlySet<string>;
/** Is this a variable bash keeps itself ({@link SHELL_INTEGER_VARIABLES}, or one it sets)? The working-directory names
 *  ({@link WORKING_DIRECTORY_NAMES}) are not: their value is the working-directory thread's ({@link WorkingDirectoryState}). */
export declare function shellKeepsName(name: string): boolean;
/** The names bash sets when the working directory moves: `PWD` (where the shell stands, as the move spelled it) and
 *  `OLDPWD` (the `PWD` it stood in before the last move — `cd -` goes there). A text may assign them too. */
export declare const WORKING_DIRECTORY_NAMES: readonly ["PWD", "OLDPWD"];
export type WorkingDirectoryName = (typeof WORKING_DIRECTORY_NAMES)[number];
/** What the working-directory thread (`shell-read-plan.ts`) says the two names hold at one segment, before anything the
 *  text assigns them: the bases it may stand in (`PWD`) and the ones it stood in before its last move (`OLDPWD`) —
 *  `unknown` where it lost track, the move's spelling is not the base (a physical move), or the shell inherited it. */
export type WorkingDirectoryState = {
    readonly [K in WorkingDirectoryName]: NameState;
} & {
    /** The last segment before the reader whose move the thread applied or lost track at (-1: none in this text). */
    readonly movedAt: number;
};
/** The POSIX special builtins: a prefix assignment to one stays after it, and one runs before a function of its name
 *  (in POSIX mode, which an inherited environment can turn on unseen). */
export declare const SPECIAL_BUILTINS: ReadonlySet<string>;
export declare const functionKey: (name: string) => string;
/** What a function name is at a reader: `defined` — it certainly is one; `absent` — it certainly is not; `maybe` — a branch,
 *  a loop, a body that may not have run, a removal that may not have found it. */
export type FunctionState = "defined" | "maybe" | "absent";
/** One binding a segment makes: a name and what it now holds (`unknown` = made unknown). `prefix`: a binding that may or
 *  may not take effect (a prefix assignment to a special builtin, which may or may not outlive its command; an `unset` of a
 *  function, which a read-only function refuses). `loopVar`: a `for` loop's variable, held through its body. */
export interface Binding {
    readonly name: string;
    readonly state: NameState;
    readonly prefix?: true;
    readonly loopVar?: true;
    /** `local`: a plain `local NAME…` — in a function body the name is the body's own and never leaves it. `unread`: a
     *  declaration builtin with an option word (`declare -g`, `local -p`, `local -r`): which scope it binds in is not
     *  read, so it is neither the body's own name nor covered by an earlier `local`. */
    readonly scope?: "local" | "unread";
    /** Spellings the name may hold that the deny judge still reads where the name is otherwise unknown (an array's
     *  elements: what `${A[k]}` expands to is one of them). */
    readonly floor?: readonly FloorValue[];
}
/** An attribute a declaration gives a name — or every name (`name` absent: the declaration computed it): a later
 *  assignment to it is evaluated as arithmetic (`integer`), stores a case change or an array element (`transformed`), or
 *  is refused (`frozen`) — it binds something other than its text. */
export interface NameAttribute {
    readonly name?: string;
    readonly kind: Exclude<DeclaredAttribute, "reference" | "unsettled">;
}
/** What ONE segment does to the names. `all`: every name made unknown (`unknown`), or reset to its state at the start
 *  of the text (`reset` — a function body). `attributes`: the attributes it gives ({@link NameAttribute}). `references`:
 *  a name reference was declared — from here on an assignment to any name may write through it, so no name holds what
 *  the text assigned. `inFunction`: the builtin assigns only inside a function body (`local`) — outside one bash refuses
 *  the command, and its bindings hold nothing the text says. */
export interface BindingEffect {
    readonly bindings: readonly Binding[];
    readonly all?: "unknown" | "reset";
    readonly attributes?: readonly NameAttribute[];
    readonly references?: true;
    readonly inFunction?: true;
}
/** How one value word reads against the table, the earlier assignments of the same segment applied (bash assigns left
 *  to right): its possible values, or `unknown`. */
export type ValueReader = (word: Pick<LexedWord, "pieces">, quoted: boolean, overlay: ReadonlyMap<string, NameState>) => NameState;
/** The segment's shape the effect needs beside its words: the functions whose definition heads were dropped from it. */
export interface SegmentShape {
    readonly defines: readonly string[];
}
/** The argv projection of a lexed segment: structure that names nothing that runs here is dropped — a subshell
 *  parenthesis, a bare `{` / `}`, a function definition's head (`NAME ()`, and `function NAME [()]` with a name of
 *  any spelling, {@link dropDefinitionHeads}), a `case` arm's pattern ({@link dropCasePattern}), and the block words
 *  at the head. */
export interface ProjectedSegment extends SegmentShape {
    readonly argv: readonly LexedWord[];
    readonly redirects: readonly LexedRedirect[];
    readonly grouped: boolean;
}
export declare function projectSegment(segment: LexedSegment): ProjectedSegment;
/** A function definition's head names nothing that runs here and is dropped from a segment's tokens, in place:
 *  `NAME ( )` ({@link isDefinitionName}), and `function NAME [( )]` — a bare `function` at command position, a name of any
 *  spelling. The lexer puts the body's compound command back at command position after the head, so a definition
 *  nested in a body is dropped the same way; after a drop the token that moved up is looked at again. Answers where the
 *  heads stood: entry `k` names the functions whose heads were dropped right before the token now at `k` (the last entry,
 *  past the last token, a head whose body opens in a later segment). */
export declare function dropDefinitionHeads(tokens: LexedToken[]): readonly (readonly string[])[];
/**
 * What a word holds through the names it refers to — `$NAME`, `${NAME}`, a leading `~` (the value of `HOME`): `undefined`
 * where it refers to no name (it reads as written), else {@link valueOf}. `table.stateOf` is read after `overlay` (the
 * names the same segment bound earlier).
 */
export declare function wordValues(word: Pick<LexedWord, "pieces">, table: BindingTable | undefined, quoted: boolean, overlay?: ReadonlyMap<string, NameState>, split?: boolean): readonly BoundValue[] | "unknown" | undefined;
/** The names a word's expansions read as values — a bare `$NAME` / `${NAME}`, and one written inside a bracket the shell
 *  forms its class from after expanding it ({@link valueOf}) — in the order they stand. */
export declare function namesIn(word: Pick<LexedWord, "pieces">): string[];
/**
 * What a VALUE word holds (an assignment's value, a `for` list word, a word handed to a program) — THE piece walk, the one
 * producer of {@link BoundValue}s: every combination of the values its pieces take, each field's pattern formed once the
 * whole field has expanded ({@link formedField}) — a literal piece its text, a glob piece its pattern as written (a bracket
 * holding an expansion its brackets and its body, the body's names substituted in place), `~` and `$NAME` the values the
 * table gives:
 *  · its values — a field the shell globs makes the value a pattern;
 *  · `"unknown"` — a name it refers to is not settled here, it carries an expansion no name answers (a modifier, a
 *    substitution, a brace list, `~user`), an UNQUOTED expansion's value is no {@link READABLE_VALUE} (or holds
 *    whitespace outside `split`), `IFS` may have changed (`quoted` = the whole word is read as one value: an assignment's
 *    value, which is never split), a field is not formed or a split one forms a pattern, or it would list more than
 *    {@link WORD_VALUES_MAX} values.
 * `split` = the word is read as the ARGUMENTS it becomes: an unquoted value is split into its words on the default `IFS`
 * (a value then carries its {@link BoundValue} `fields`).
 */
export declare function valueOf(word: Pick<LexedWord, "pieces">, table: BindingTable | undefined, quoted: boolean, overlay?: ReadonlyMap<string, NameState>, split?: boolean): NameState;
/**
 * The spellings a word the table leaves unknown may still take through the deny floors of the names it refers to
 * ({@link BindingTable.floorOf}) — `${A[k]}`, `${A[@]}`, `$A` reading an array's elements — or through their values where
 * known: for the deny judge alone. Empty where some name it refers to leaves neither.
 */
export declare function wordFloorValues(word: Pick<LexedWord, "pieces">, table: BindingTable | undefined): readonly FloorValue[];
/** Where a segment's argv heads a `for` / `select` loop: the index of that bare word, at the segment's start or past the
 *  bare control words in front of it (`do for x in …`, `then for …` — a loop nested in a body or a branch); `undefined`
 *  for any other segment. */
export declare function loopListHeadAt(argv: readonly LexedWord[]): number | undefined;
/**
 * What ONE segment does to the names (see the module header). `argv` = the segment's argv projection (structure
 * dropped); `readValue` folds a value word against the table (a reader that answers `unknown` gives the names alone).
 * `shadow`: the word the shell looks up first is a function of the text where the segment stands (`named`: it is one, the
 * builtin of its name does not run — the call's effect is the body's; `maybe`: it may be one, so what the builtin binds is one
 * more value its names may hold). `availability`: whether the builtin of a name runs by it where the segment stands
 * ({@link BuiltinState}) — `disabled`: the word finds no command and binds nothing, `maybe`: as a function that may stand.
 */
export declare function bindingEffectOf(segment: LexedSegment, argv: readonly LexedWord[], shape: SegmentShape, readValue: ValueReader, shadow?: "named" | "maybe", availability?: (builtin: string) => BuiltinState): BindingEffect;
/**
 * The names an ARITHMETIC text may assign: every identifier in a text that carries an assignment operator (`=` that is no
 * comparison, `+=` and its kin, `++`, `--`) — read whole, not parsed: a name only compared there is made unknown too.
 */
export declare function arithmeticAssignedNames(text: string): string[];
/** The names a text binds anywhere (every segment, every name the binding rule reads), or `all` where it may bind any
 *  name — for a body that runs later. Unreadable text binds any. */
export declare function namesBoundIn(text: string, depth?: number): ReadonlySet<string> | "all";
/**
 * Does this text bind `HOME` anywhere (or every name)? — the question a reader that spells the declared home for `~` /
 * `$HOME` asks of a text it reads as ONE unit (the read-only classifier's segments). The read station asks the
 * threaded question instead ({@link BindingThread}).
 */
export declare function textBindsHome(text: string): boolean;
/** What a name holds at one point of a text, asked by name ({@link BindingTable.stateOf}). */
export type NameReader = (name: string) => NameState;
/** What holds for the names where a nested text starts, given by the text around it: the attributes
 *  ({@link NameAttribute}) and whether a name reference was declared — a substitution body starts with what may run
 *  before its segment, a text run later or elsewhere (a code body, `eval`'s text, a child shell's `-c`) with all the
 *  text around it gives. */
export interface InheritedNames {
    readonly attributes: readonly NameAttribute[];
    readonly references: boolean;
    /** The deny floors a name starts the text with ({@link BindingTable.floorOf}): what the words handing it this text as
     *  written may name there — or, for a substitution body, the floors its segment reads. */
    readonly floors?: ReadonlyMap<string, readonly FloorValue[]>;
    /** The names something before the nested text may have changed — a change that can reach where it starts, and the
     *  names its own segment's command environment sets (`TMPDIR=… bash -c …`): there such a name no longer holds what the
     *  shell provides ({@link BindingTable.providedByShell}). `all`: any name. Absent: none. */
    readonly rebound?: ReadonlySet<string> | "all";
}
/** The function and builtin keys of the shell a text runs in — a literal `eval` text, a substitution body (a fork): what each key
 *  holds where the text starts (the outer table's answer for it), and the names a call to one of the outer functions may change. */
export interface InheritedFunctions {
    readonly start: (key: string) => NameState;
    readonly bound: ReadonlySet<string> | "all";
}
/** Two rebound sets as one. */
export declare function joinRebound(a: ReadonlySet<string> | "all" | undefined, b: Iterable<string> | "all" | undefined): ReadonlySet<string> | "all";
/** What the thread answers for one reader: what a name may hold, and whether a name carries the integer attribute. */
export interface BindingTable {
    stateOf(name: string): NameState;
    /** Values assigned to this name are evaluated as arithmetic. */
    isInteger(name: string): boolean;
    /** The text may have changed `IFS` before this point: an unquoted expansion is split on what the text does not say. */
    readonly ifsTouched: boolean;
    /** `HOME` may hold something other than the declared home here. */
    readonly homeTouched: boolean;
    /** Every spelling any binding of this name before here left for the deny judge alone ({@link Binding.floor}). */
    floorOf(name: string): readonly FloorValue[];
    /** What a substitution body here starts with. */
    readonly inherited: InheritedNames;
    /** The names a change that can reach this point touched — a binding, or a name made unknown, that may run before it in
     *  this shell (the thread's order: {@link BindingThread}) — and the names its start says were rebound; `all`: any. */
    readonly rebound: ReadonlySet<string> | "all";
    /** Does this name still hold what the shell provides here: no change that can reach this point touched it? */
    providedByShell(name: string): boolean;
    /** What a function of this name is here: the one ordered rule that answers a variable's value answers it
     *  ({@link FunctionState}). A name the text never defines is `absent` to the caller's own filter, not to this thread. */
    functionState(name: string): FunctionState;
    /** Whether the builtin of this name runs by it here: the same ordered rule ({@link BuiltinState}). */
    builtinState(name: string): BuiltinState;
}
/**
 * The effects of a text's segments, threaded the way the plan threads its working directory: a reader at segment `j`
 * sees the latest binding of a name, and, where that binding may not have run before `j`, the bindings before it too.
 * A binding is CERTAIN for `j` when no block holding it (a branch, a loop, a group) closes or switches branch between it
 * and `j` — a block it precedes may come and go — its segment is no pipeline member, background job or prefix
 * assignment, and — reached through `&&` / `||` — it lies in `j`'s own `&&` run (`andRunStart`: the same index the
 * working-directory thread reads).
 *
 * A binding exists for a reader only where it may run before the reader IN THE SAME SHELL — the ordered state: one
 * written after the reader, one inside a subshell the reader is not in (a `( … )` group that closed before it, a
 * pipeline member that is not the last, a background job — a substitution body is a text of its own) and one in a
 * function body is NOT a binding for it. A function body runs at its call: a call the plan can see (a program word
 * naming one of the text's functions, a code body a builtin runs later, which may name one) makes every name a body
 * binds unknown from that segment on ({@link functionBound}); a text the plan does not read (`eval`, `source`, a
 * computed program word) already makes every name unknown. The last member of a pipeline may or may not run in this
 * shell: its bindings join the values before them. A body's own readers follow its own order; a reader in another body
 * loses a name any other body binds ({@link Unreadable}). A name the body declares with a plain `local` (before the
 * binding, where the declaration certainly ran) never leaves it.
 *
 * An attribute ({@link NameAttribute}) and a name reference hold for every segment they may RUN before — a later one,
 * one in a function body, one in the same loop body: an assignment there binds something other than its text.
 */
export declare class BindingThread {
    private readonly segments;
    /** What each segment binds, its names alone (a value is the reader's to read). */
    private readonly named;
    /** The state a name starts the text in (and is reset to by a function body): the declared home for `HOME`. */
    private readonly initial;
    /** Names any segment of the text binds (a function body run later reads a `HOME` bound anywhere as unknown). */
    private readonly boundAnywhere;
    /** Each loop head's segment and its matching `done`'s. */
    private readonly loops;
    /** `HOME` may already hold something other than the declared home where the text starts (a substitution body
     *  inside a text that bound it). */
    private readonly homeStartsTouched;
    /** The functions the shell that runs this text (a literal `eval` text) already holds. */
    private readonly inheritedFunctions?;
    private readonly entries;
    /** The `local` declarations the walk applied as certain ({@link apply}), each where it stands. */
    private readonly localDeclarations;
    /** The attributes the text gives ({@link BindingEffect.attributes}), and where — read off its names alone, before any
     *  reader: one given later in the text may run first. */
    private readonly attributesAt;
    /** Names no assignment makes readable again ({@link Unreadable}). */
    private readonly unreadable;
    /** The block nesting each segment moves ({@link blockStructure}). */
    private readonly blocks;
    /** Segments that END in a pipe or a `&`: the command that closes them is a pipeline member that is not the last, or a
     *  background job — a subshell of its own ({@link ownSubshellAt}: which of the segment's bindings that is). */
    private readonly ownSubshell;
    /** The floors the names start the text with ({@link InheritedNames.floors}). */
    private readonly startFloors;
    /** The names rebound where the text starts ({@link InheritedNames.rebound}). */
    private readonly startRebound;
    /** Where a function body runs ({@link runsBodies}): the last segment that can call one, and the command environment of each call. */
    private bodyRuns;
    constructor(segments: readonly LexedSegment[], 
    /** What each segment binds, its names alone (a value is the reader's to read). */
    named: readonly BindingEffect[], 
    /** The state a name starts the text in (and is reset to by a function body): the declared home for `HOME`. */
    initial: (name: string) => NameState, 
    /** Names any segment of the text binds (a function body run later reads a `HOME` bound anywhere as unknown). */
    boundAnywhere: (name: string) => boolean, 
    /** Each loop head's segment and its matching `done`'s. */
    loops: ReadonlyMap<number, number>, 
    /** `HOME` may already hold something other than the declared home where the text starts (a substitution body
     *  inside a text that bound it). */
    homeStartsTouched?: boolean, 
    /** What holds where the text starts: given before its first segment. */
    inherited?: InheritedNames, 
    /** The functions the shell that runs this text (a literal `eval` text) already holds. */
    inheritedFunctions?: InheritedFunctions | undefined);
    /** What a text nested at segment `j` starts with ({@link InheritedNames}) — `j` absent: a text run later, which every
     *  segment may run before (in whatever shell: a later text may run inside a subshell or a body, so every change
     *  counts). */
    inheritedAt(j?: number): InheritedNames;
    /** What a name holds where the text starts: a function name unbound, a builtin enabled (what the shell around an `eval` text, a
     *  substitution body or a text run later holds, if it says); a variable as the plan says. */
    private startOf;
    /** Does any segment of this text bind the name (or every name)? */
    private bindsInText;
    /** What a text this one runs at some later point (a `trap` action) finds each function and builtin key: the point is not ordered
     *  against the segments (it may fire after any of them, inside any body or subshell), so a key holds what the text starts it with
     *  and every value any segment binds it ({@link InheritedFunctions}). */
    heldAnywhere(): InheritedFunctions;
    /** Tell the thread where function bodies run: `runs[si]` — segment `si` may run one (a call, a text the plan does not
     *  read); `atEnd` — a code body may run at the text's end or at any point (`trap`); `environment[si]` — what a call's own
     *  command environment sets. A call inside a loop may run again after a later segment of the loop. The last run point
     *  bounds what can precede a body: a binding after it never does. A name a body that makes a call binds — `local` too:
     *  the shell's scope is dynamic, the callee runs inside it — is unreadable to a reader in any other body. */
    runsBodies(runs: readonly boolean[], atEnd: boolean, environment: readonly (ReadonlySet<string> | "all" | undefined)[]): void;
    /** The names a reader that runs LATER than it stands may find rebound by segments after it: a reader in a function body
     *  runs at each call, so every segment up to the last run point (and a call's own command environment) may run before it;
     *  a text handed to run later (`j` absent) at any point. A reader that runs where it stands has none: the effects the walk
     *  has applied so far are the ones that precede it. A `local` counts like any binding: it shortens a name's life, not the
     *  view of a reader that runs inside its extent (a body called from there, a `trap` text it sets). */
    private boundLater;
    /** Does a binding segment `at` makes, standing at `standing`, run in a subshell of its own — a pipeline member that is
     *  not the last, a background job? A segment's closing pipe or `&` ends ITS LAST command, at the depth that command
     *  stands: a binding that stands shallower (a function definition's head, in front of the block its body opens in the
     *  same segment: `f(){ ls | head; … }`) is not that member — the pipe closes a command inside the body, and the
     *  definition is the shell's own. */
    private ownSubshellAt;
    /** Is a binding segment `at` makes one no later reader may count on as certain: made in a pipeline member (it follows a
     *  `|`, or it is {@link ownSubshellAt}) or a background job? */
    private detachedAt;
    /** Can a binding segment `at` makes exist for a reader at segment `j` (`j` absent: a reader at the text's end, outside
     *  every body and subshell)? Not where `at` stands in a function body the reader is not in (the body runs at its call),
     *  runs in a subshell of its own (a pipeline member that is not the last, a background job), or stands in a `( … )`
     *  group the reader is not in. */
    private visible;
    /** Where the binding `name` of segment `at` is made: the segment's own place, or — a function definition — where its head
     *  stands. */
    private standingOf;
    /** The names any of the text's function bodies binds — what a call to one of them may change — or `all` where a body
     *  may bind any name. A name the body keeps `local` ({@link leavesBody}) stays in it. */
    functionBound(): ReadonlySet<string> | "all";
    /** The function body a binding segment `at` makes belongs to, where the name can outlive it: the body it stands in — a
     *  plain `local NAME` is the body's own and never leaves it (an optioned declaration, `declare -g` / `local -p`, reads no
     *  scope, so it can). What a reader in ANOTHER body loses ({@link unreadableBy}); a call to the body changes it unless a
     *  declaration the body certainly ran covers the name ({@link functionBound}). */
    private bodyBinding;
    /** Does segment `at` stand in a function body (it runs at a call, not here)? */
    inFunctionBody(at: number): boolean;
    /** Does segment `at` run in a subshell (a `( … )` group, a pipeline member that is not the last, a background job) or a
     *  function body — whatever it changes, the shell that runs the next segment may not see? */
    runsApart(at: number): boolean;
    /** Segment `at` hands this shell a body it runs at ANY later point (a `trap` action, an alias value): every name the
     *  body may bind (`all`: any) is unreadable to every reader after `at`, whatever is assigned to it in between. */
    runsLater(at: number, names: ReadonlySet<string> | "all"): void;
    /** What segment `at` makes unreadable: in a function body, the names it binds (a plain `local` stays in it) — every name
     *  where it may bind any; a name reference, every name. Read before any segment is applied, so it does not ask which
     *  declarations certainly ran: a name a body assigns after its own `local` is lost to a reader in another body all the same
     *  (more questions, never fewer). */
    private unreadableBy;
    /** May segment `x` run before segment `e` runs (`x` being `e`: before a later run of it): `x` comes first in the text,
     *  `e` stands in a function body (the body runs at its call, after any segment, and may run again), or both stand in
     *  one loop's body (a later beat runs `x` again first). */
    private mayRunBefore;
    /** Did the body certainly declare this name `local` before segment `at`: an earlier segment of the body, run on its own
     *  (no `&&` / `||`, no pipeline member or background job), in a block still open at `at`, whose declaration the walk
     *  APPLIED as certain — the shell ran its word as the builtin: no function of that name standing, no launcher, path or
     *  redirection in the way, and the builtin enabled where the body runs (what {@link bindingEffectOf} concluded, the ordered
     *  state of {@link BindingTable.functionState} and {@link BindingTable.builtinState}; recorded by {@link apply}). */
    private declaredLocal;
    /** Does the block that holds a binding's words stay open (no closing word, no switch of branch) through `j`? */
    private heldThrough;
    /** Apply segment `at`'s effect. `andRun`: the segment was reached through `&&` / `||`. `loopEnd`: for a loop variable,
     *  the index of the loop's end. */
    apply(at: number, effect: BindingEffect, andRun: boolean, loopEnd?: number): void;
    /** Does a reader at segment `j` lose the name `u` makes unreadable: past a name reference it may run after, or in a
     *  function body other than the one that binds it? */
    private lostAt;
    /** Make these names unknown from segment `at` on (a loop body that binds them may have run before any of its beats; a
     *  call runs a body that binds them). */
    kill(at: number, names: Iterable<string> | "all"): void;
    /** The table a reader at segment `j` sees; `andRunStart` = the first segment of `j`'s `&&` run; `where` = what the
     *  working-directory thread says `PWD` / `OLDPWD` hold there (absent: it does not say — both unknown). */
    tableAt(j: number, andRunStart: number, where?: WorkingDirectoryState): BindingTable;
}
/** A segment that opens with `((`: an arithmetic command (or a subshell in a subshell — the tokens are the same). */
export declare function isArithmeticCommand(segment: LexedSegment): boolean;
/** The `[[` operators whose operands the arithmetic evaluator reads (`[[ x -eq y ]]`; `[` / `test` compare integers
 *  without evaluating them). */
export declare const ARITHMETIC_TEST_OPERATORS: ReadonlySet<string>;
/** The substitutions a parameter expansion's body hands the arithmetic evaluator: its subscript (`${a[…]}`) and the
 *  offset and length of a substring expansion (`${x:off:len}` — the shell expands them, then evaluates them). */
export declare function parameterBodySubstitutions(name: string, body: string, table: BindingTable | undefined): string[];
/**
 * The substitutions the shell's ARITHMETIC evaluator runs while it evaluates `text`: every `$(…)`, backquote or process
 * substitution inside an array SUBSCRIPT of it (`a[$(…)]` — quoted or not: the evaluator re-reads the text it is
 * handed), and — for each name the text refers to whose value the table holds — the same of that value (the evaluator
 * evaluates a variable's value as arithmetic too, through any chain of names). A name the table does not settle
 * contributes the literal values its bindings left (an array's elements) and nothing else: any other value is data the
 * text does not hold. A name already on the chain is a cycle (bash refuses
 * it). Each body is shell text the evaluator re-enters; past the reader's budget of values the text itself is handed
 * back as a body, so the segment re-enters text it did not follow (unestablished, never silent).
 */
export declare function arithmeticSubstitutions(text: string, table: BindingTable | undefined, chain?: ReadonlySet<string>, budget?: {
    left: number;
}): string[];
/** The text of every `[…]` subscript in an arithmetic text (nested brackets balanced; an unclosed one runs to the end). */
export declare function subscriptsOf(text: string): string[];
