/**
 * MATLAB®/Octave like syntax parser/interpreter/compiler.
 */
import type { NodeInput, NodeExpr, NodeIdentifier, NodeFunctionDefinition, NodeBuiltInFunction, NameEntry, NameTable, FunctionTable, AliasNameTable, BuiltInFunctionTable, CommandWordListTable, UndefinedReferenceTable } from './AST';
import { ComplexType, FunctionHandle } from './AST';
import type { MathObject, UnaryMathOperation, BinaryMathOperation, KeyOfTypeOfMathOperation } from './MathOperation';
/**
 * `response` type
 */
type ExitStatus = number;
type ExitStatusValues = Record<string, ExitStatus>;
/**
 * # Scope
 *
 * Represents a **lexical scope**.
 *
 * A `Scope` stores:
 * - variable bindings (`nameTable`)
 * - function bindings (`functionTable`)
 * - unresolved references for forward reference resolution (`undefinedReferenceTable`)
 *
 * Scopes are organized in a **parent chain**, forming a lexical environment.
 *
 * ---
 *
 * ## Resolution Model
 *
 * Name and function resolution follow this order:
 *
 * 1. Current scope
 * 2. Parent scope
 * 3. Recursively upward
 *
 * ---
 *
 * ## Mutation Semantics
 *
 * - `define*` → affects **current scope only**
 * - `remove*` → removes from **current scope only**
 * - `clear*` → removes from **entire scope chain**
 *
 * ---
 *
 * ## Notes
 *
 * - Tables use `Object.create(null)` to avoid prototype pollution.
 * - Resolution is read-only (no mutation).
 * - Supports shadowing (local overrides parent).
 */
declare class Scope {
    parent?: Scope | undefined;
    nameTable: NameTable;
    functionTable: FunctionTable;
    undefinedReferenceTable: UndefinedReferenceTable;
    /**
     * Private constructor.
     *
     * Use {@link Scope.create}.
     *
     * @param parent - Parent scope (optional)
     * @param nameTable - Variable table
     * @param functionTable - Function table
     * @param undefinedReferenceTable - Undefined references table
     */
    private constructor();
    /**
     * Factory method for creating a new scope.
     *
     * @param parent - Parent scope (optional)
     * @returns New Scope instance
     */
    static readonly create: (parent?: Scope) => Scope;
    /**
     * Defines a variable in the current scope.
     *
     * Overwrites existing local definition if present.
     *
     * @param name - Identifier
     * @param node - Value node
     * @param undefinedReference - Optional unresolved reference tag
     * @returns Created/updated entry
     */
    defineName(name: string, node: NodeInput, undefinedReference?: string): NameEntry;
    /**
     * Defines multiple variables in the current scope.
     *
     * @param table - Map of name → node
     */
    defineNameTable(table: Record<string, NodeInput>): void;
    /**
     * Resolves a variable using lexical lookup.
     *
     * @param name - Identifier
     * @returns First matching entry or `undefined`
     */
    resolveName(name: string): NameEntry | undefined;
    /**
     * Checks if a variable exists in the current scope.
     *
     * @param name - Identifier
     * @returns `true` if exists locally
     */
    hasLocalName(name: string): boolean;
    /**
     * Removes a variable from the current scope only.
     *
     * @param name - Identifier
     */
    removeName(name: string): void;
    /**
     * Removes a variable from the entire scope chain.
     *
     * @param name - Identifier
     */
    clearName(name: string): void;
    /**
     * Defines a function in the current scope.
     *
     * @param name - Function name
     * @param func - Function definition
     * @returns Stored function
     */
    defineFunction(name: string, func: NodeFunctionDefinition): NodeFunctionDefinition;
    /**
     * Defines multiple functions in the current scope.
     *
     * @param table - Function table
     */
    defineFunctionTable(table: FunctionTable): void;
    /**
     * Resolves a function using lexical lookup.
     *
     * @param name - Function name
     * @returns Function or `undefined`
     */
    resolveFunction(name: string): NodeFunctionDefinition | NodeBuiltInFunction | undefined;
    /**
     * Checks if a function exists in the current scope.
     *
     * @param name - Function name
     * @returns `true` if exists locally
     */
    hasLocalFunction(name: string): boolean;
    /**
     * Removes a function from the current scope only.
     *
     * @param name - Function name
     */
    removeFunction(name: string): void;
    /**
     * Removes a function from the entire scope chain.
     *
     * @param name - Function name
     */
    clearFunction(name: string): void;
    /**
     * Binds parameters to arguments in the current scope.
     *
     * No validation is performed.
     *
     * @param names - Parameter names
     * @param args - Argument expressions
     */
    bindParameters(names: string[], args: NodeExpr[]): void;
    /**
     * Binds parameters to arguments with arity checking.
     *
     * Throws an error if the number of arguments does not match
     * the number of parameters.
     *
     * @param names - Parameter names
     * @param args - Argument expressions
     * @throws Error if arity mismatch
     */
    bindParametersChecked(names: string[], args: NodeExpr[]): void;
    /**
     * Registers an unresolved reference (forward reference).
     *
     * @param name - Identifier
     * @param undefinedReference - Reference id
     * @returns Updated reference list
     */
    defineUndefinedReference(name: string, undefinedReference: string): string[];
    /**
     * Resolves unresolved references using lexical lookup.
     *
     * @param name - Identifier
     * @returns Array of references or `undefined`
     */
    resolveUndefinedReference(name: string): string[] | undefined;
    /**
     * Removes unresolved references from the current scope only.
     *
     * @param name - Identifier
     */
    removeUndefinedReference(name: string): void;
    /**
     * Removes unresolved references from the entire scope chain.
     *
     * @param name - Identifier
     */
    clearUndefinedReference(name: string): void;
}
/**
 * # Callable
 *
 * Discriminated union representing any **callable entity** in the engine.
 *
 * A callable is anything that can be invoked during evaluation.
 *
 * ---
 *
 * ## Variants
 *
 * - `BUILTIN` → Built-in function implemented in the runtime
 * - `LAMBDA` → Anonymous function (function handle with expression)
 * - `FCNDEF` → User-defined function (declared with `function`)
 *
 * ---
 *
 * ## Design Notes
 *
 * This abstraction allows the evaluator to treat all callable entities
 * uniformly, while preserving their specific execution semantics.
 *
 * Each variant wraps a different underlying AST/runtime representation.
 */
type Callable = BuiltinCallable | LambdaCallable | FunctionDefinitionCallable;
/**
 * Represents a **built-in callable function**.
 *
 * Built-in functions are implemented directly in the runtime
 * (e.g., `sin`, `cos`, `exp`).
 */
interface BuiltinCallable {
    /**
     * Discriminator tag.
     */
    type: 'BUILTIN';
    /**
     * AST node representing the built-in function.
     */
    node: NodeBuiltInFunction;
}
/**
 * Represents an **anonymous function (lambda)**.
 *
 * This wraps a {@link FunctionHandle} whose `id` is `undefined`
 * and contains:
 * - parameter list
 * - expression body
 * - optional closure
 */
interface LambdaCallable {
    /**
     * Discriminator tag.
     */
    type: 'LAMBDA';
    /**
     * Function handle representing the lambda.
     */
    node: FunctionHandle & {
        id: undefined;
    };
}
/**
 * Represents a **defined function**.
 *
 * Typically declared using a function definition construct.
 */
interface FunctionDefinitionCallable {
    /**
     * Discriminator tag.
     */
    type: 'FCNDEF';
    /**
     * AST node representing the function definition.
     */
    node: NodeFunctionDefinition;
}
/**
 * # CallFrame
 *
 * Represents a **function call frame** in the evaluation stack ({@link EvaluatorWorkspace.callStack}).
 *
 * A call frame encapsulates:
 * - the **execution scope** for the call
 * - the **callable being executed**
 * - a link to the **caller frame** (stack chain)
 *
 * ---
 *
 * ## Role in Evaluation
 *
 * During function invocation, a new `CallFrame` is created:
 *
 * 1. A new `Scope` is created (child of the defining scope or global scope)
 * 2. Parameters are bound in that scope
 * 3. The callable is associated with the frame
 * 4. The frame is pushed onto the call stack
 *
 * This enables:
 * - proper lexical scoping
 * - recursion
 * - nested calls
 * - stack trace reconstruction
 *
 * ---
 *
 * ## Stack Structure
 *
 * Frames form a linked structure:
 *
 * ```text
 * currentFrame → parentFrame → parentFrame → ...
 * ```
 *
 * ---
 *
 * ## Debugging Support
 *
 * Additional metadata is stored to support stack traces:
 *
 * - `callSite` → AST node where the call occurred
 * - `name` → human-readable function name
 *
 * ---
 *
 * ## Notes
 *
 * - `func` may be `undefined` for temporary frames
 * - `parentFrame` should be consistent with the call stack array
 */
declare class CallFrame {
    /**
     * Execution {@link Scope} for this frame.
     */
    scope: Scope;
    /**
     * {@link Callable} being executed in this frame.
     */
    func?: Callable | undefined;
    /**
     * AST node where the function call originated.
     *
     * Useful for error reporting (line/column in future).
     */
    callSite?: NodeExpr | undefined;
    /**
     * Human-readable function name.
     *
     * Examples:
     * - "sin"
     * - "f"
     * - "@(x)x^2"
     */
    name?: string | undefined;
    /**
     * Parent frame in the call stack.
     */
    parentFrame?: CallFrame | undefined;
    /**
     * Creates a new call frame.
     *
     * @param scope - Execution {@link Scope} for this frame
     * @param func - Callable associated with this frame (optional)
     * @param parentFrame - Caller frame (optional)
     * @param callSite - {@link AST} node representing the call site (optional)
     * @param name - Human-readable function name (optional)
     */
    constructor(
    /**
     * Execution {@link Scope} for this frame.
     */
    scope: Scope, 
    /**
     * {@link Callable} being executed in this frame.
     */
    func?: Callable | undefined, 
    /**
     * AST node where the function call originated.
     *
     * Useful for error reporting (line/column in future).
     */
    callSite?: NodeExpr | undefined, 
    /**
     * Human-readable function name.
     *
     * Examples:
     * - "sin"
     * - "f"
     * - "@(x)x^2"
     */
    name?: string | undefined, 
    /**
     * Parent frame in the call stack.
     */
    parentFrame?: CallFrame | undefined);
}
/**
 * # EvaluatorError
 *
 * Base class for all evaluation-related errors.
 *
 * This class extends the native `Error` and adds optional
 * support for stack trace frames (`CallFrame[]`), enabling
 * MATLAB/Octave-like error reporting.
 *
 * ---
 *
 * ## Design Goals
 *
 * - Backward compatible with existing `throw new Error(...)`
 * - Allows incremental adoption of stack traces
 * - Provides a unified error hierarchy
 *
 * ---
 *
 * ## Notes
 *
 * - `stackFrames` is optional to support legacy code paths
 * - Formatting is deferred to `toString()` / `format()`
 */
declare class EvaluatorError extends Error {
    /**
     * Optional call stack snapshot.
     *
     * Top frame should be the first element.
     */
    readonly stackFrames?: CallFrame[];
    /**
     * Creates a new EvaluatorError.
     *
     * @param message - Error message
     * @param stackFrames - Optional stack trace snapshot
     */
    constructor(message: string, stackFrames?: CallFrame[]);
    /**
     * Formats the error message with optional stack trace.
     *
     * @returns Formatted error string
     */
    format(): string;
    /**
     * Derives a human-readable name for a frame.
     */
    protected getFrameName(frame: CallFrame): string;
    /**
     * Default string representation.
     */
    toString(): string;
}
declare class EvaluatorWorkspace {
    /**
     * Evaluator instance associated to this workspace.
     */
    evaluator?: Evaluator | undefined;
    /**
     * Global scope.
     */
    globalScope?: Scope | undefined;
    /**
     * Function call stack.
     */
    callStack: CallFrame[];
    /**
     * Built-in function table.
     */
    builtInFunctionTable: Record<string, NodeBuiltInFunction>;
    /**
     * Allow forward reference flag.
     */
    allowForwardReference: boolean;
    /**
     *
     * @param globalScope
     * @param callStack
     */
    loadEvaluatorWorkspace(globalScope?: Scope, callStack?: CallFrame[]): void;
    /**
     * Private constructor (only used by `create` static method).
     * @param globalScope Optional global scope reference.
     * @param callStack Optional function call stack reference.
     */
    private constructor();
    /**
     * Create {@link EvaluatorWorkspace} object.
     * @param globalScope Optional global scope reference.
     * @param callStack Optional function call stack reference.
     * @returns
     */
    static readonly create: (evaluator?: Evaluator, globalScope?: Scope, callStack?: CallFrame[]) => EvaluatorWorkspace;
    /**
     * Native name table. It's inserted in nameTable when Evaluator constructor executed.
     */
    nativeNameTable: Record<string, ComplexType>;
    /**
     * Native name table list.
     */
    nativeNameTableList: string[];
    /**
     * Alias name table.
     */
    private aliasNameTable;
    /**
     * Alias name function. This property is set at Evaluator instantiation.
     * @param name Alias name.
     * @returns Canonical name.
     */
    aliasNameFunction: (name: string) => string;
    /**
     * Alias table setup
     * @param aliasNameTable
     */
    setAliasNameTable(aliasNameTable?: AliasNameTable): void;
    /**
     * Get a list of names of defined functions in builtInFunctionTable.
     */
    get builtInFunctionList(): string[];
    /**
     * Current frame (top of call stack) getter.
     */
    get currentFrame(): CallFrame | undefined;
    /**
     * Current scope (top of call stack) getter.
     */
    get currentScope(): Scope;
    /**
     * Name resolver.
     * @param name
     * @returns
     */
    resolveName(name: string): NameEntry | undefined;
    resolveFunction(name: string): NodeFunctionDefinition | NodeBuiltInFunction | undefined;
    assignName(name: string, value: NodeInput): void;
    assignFunction(name: string, func: NodeFunctionDefinition): void;
    createChildScope(parent?: Scope): Scope;
    resolveCallable(expr: NodeExpr): Callable | undefined;
    resolveIdentifier(tree: NodeInput, scope: Scope): NodeExpr;
    private evaluateArgs;
    private error;
    private resolveCallSite;
    callCallable(callable: Callable, args: NodeExpr[], parent: NodeInput): NodeExpr;
    apply(expr: NodeExpr, args: NodeExpr[], parent: NodeInput): NodeExpr;
    /**
     * Define function in builtInFunctionTable.
     * @param id Name of function.
     * @param func Function body.
     * @param map `true` if function is a mapper function.
     * @param ev A `boolean` array indicating which function argument should
     * be evaluated before executing the function. If array is zero-length all
     * arguments are evaluated.
     */
    defineBuiltInFunction(id: string, func: Function, mapper?: boolean, ev?: boolean[]): void;
    /**
     *
     * @param table
     */
    assignBuiltInFunctionTable(table?: Record<string, NodeBuiltInFunction>): void;
    /**
     * Define unary operator function in builtInFunctionTable.
     * @param id Name of function.
     * @param func Function body.
     */
    defineUnaryOperatorFunction(id: KeyOfTypeOfMathOperation, func: UnaryMathOperation): void;
    /**
     * Define binary operator function in builtInFunctionTable.
     * @param id Name of function.
     * @param func Function body.
     */
    defineBinaryOperatorFunction(id: KeyOfTypeOfMathOperation, func: BinaryMathOperation): void;
    /**
     * Define define two-or-more operand function in builtInFunctionTable.
     * @param name
     * @param func
     */
    defineLeftAssociativeMultipleOperationFunction(id: KeyOfTypeOfMathOperation, func: BinaryMathOperation): void;
    /**
     * Push a new frame onto the call stack.
     *
     * @param frame - CallFrame to push
     */
    pushCallStackFrame(frame: CallFrame): void;
    /**
     * Pop the current frame from the call stack.
     *
     * @returns Removed frame
     */
    popCallStackFrame(): CallFrame | undefined;
    /**
     * Returns a snapshot of the current stack trace.
     *
     * Top frame is the first element.
     */
    private getStackTrace;
}
/**
 * EvaluatorConfig type.
 */
type EvaluatorConfig = {
    aliasNameTable?: AliasNameTable;
    externalFunctionTable?: BuiltInFunctionTable;
    externalCmdWListTable?: CommandWordListTable;
};
/**
 * Increment and decrement operator handler type.
 */
type IncDecOperator = (tree: NodeIdentifier) => MathObject;
/**
 * Evaluator instance interface.
 */
interface EvaluatorInterface {
    debug: boolean;
    workspace: EvaluatorWorkspace;
    exitStatus: ExitStatus;
    precedenceTable: {
        [key: string]: number;
    };
    Parse(input: string): NodeInput;
    Restart(): void;
    Clear(...names: string[]): void;
    Evaluator(tree: NodeInput, scope?: Scope): NodeInput;
    Evaluate(tree: NodeInput): NodeInput;
    Unparse(tree: NodeInput, parentPrecedence?: number): string;
    UnparserMathML(tree: NodeInput, parentPrecedence: number): string;
    UnparseMathML(tree: NodeInput, display: 'inline' | 'block'): string;
    ToMathML(input: string, display: 'inline' | 'block'): string;
}
/**
 * `Evaluator` object.
 */
declare class Evaluator implements EvaluatorInterface {
    /**
     * After run `Evaluate` method, the `exitStatus` property will contains
     * exit state of evaluation.
     */
    static readonly response: ExitStatusValues;
    /**
     * Private debug flag.
     */
    private _debug;
    /**
     * `debug` getter.
     */
    get debug(): boolean;
    /**
     * `debug` setter.
     */
    set debug(value: boolean);
    /**
     * Evaluator workspace.
     */
    workspace: EvaluatorWorkspace;
    /**
     * Command word list table.
     */
    private commandWordListTable;
    /**
     * Evaluator exit status.
     */
    private _exitStatus;
    /**
     * Evaluator exit status getter.
     */
    get exitStatus(): ExitStatus;
    /**
     * Increment and decrement operator
     * @param pre `true` if prefixed. `false` if postfixed.
     * @param operation Operation (`'plus'` or `'minus'`).
     * @returns Operator function with signature `(tree: NodeIdentifier) => MathObject`.
     */
    private incDecOpFactory;
    /**
     * Operator table.
     */
    private readonly opTable;
    /**
     * Precedence definitions.
     */
    private static readonly precedence;
    /**
     * Operator precedence table.
     */
    precedenceTable: {
        [key: string]: number;
    };
    /**
     * Get tree node precedence.
     * @param tree Tree node.
     * @returns Node precedence.
     */
    private nodePrecedence;
    /**
     * User functions.
     */
    private readonly functions;
    /**
     * Special functions MathML unparser.
     */
    private readonly unparseMathMLFunctions;
    /**
     * Load the `Evaluator`.
     * @param config
     */
    private loadEvaluator;
    /**
     * `Evaluator` object private constructor
     */
    private constructor();
    /**
     * Creates an instance of the `Evaluator` object.
     * @param config
     * @returns
     */
    static readonly Create: (config?: EvaluatorConfig, workspace?: EvaluatorWorkspace) => Evaluator;
    /**
     * Parse input string.
     * @param input String to parse.
     * @returns Abstract syntax tree of input.
     */
    Parse(input: string): NodeInput;
    /**
     * Native name table factory.
     * @returns Native name table with actual `Complex` facade.
     */
    private static readonly nativeNameTableFactory;
    /**
     * Restart evaluator.
     */
    Restart(): void;
    /**
     * Clear variables. If names is 0 lenght restart evaluator.
     * @param names Variable names to clear in nameTable and builtInFunctionTable.
     */
    Clear(...names: string[]): void;
    /**
     * Validate left side of assignment node.
     * @param tree Left side of assignment node.
     * @param shallow True if tree is a left root of assignment.
     * @returns An object with four properties: `left`, `id`, `args` and `field`.
     */
    private validateAssignment;
    /**
     *
     * @param tree
     * @returns
     */
    private toBoolean;
    /**
     *
     * @param id
     */
    private solveUndefined;
    /**
     * Expression tree recursive evaluator.
     * @param tree Expression to evaluate.
     * @param scope Scope of execution.
     * @returns Expression `tree` evaluated.
     */
    Evaluator(tree: NodeInput, scope?: Scope): NodeInput;
    /**
     * Evaluate expression `tree`.
     * @param tree Expression to evaluate.
     * @returns Expression `tree` evaluated.
     */
    Evaluate(tree: NodeInput): NodeInput;
    /**
     * Executes the `Parse` and `Evaluate` methods on an input string, returning the computed result.
     * @param input String to parse and evaluate.
     * @returns Computed result of input.
     */
    Execute(input: string): NodeInput;
    /**
     * Unparse expression `tree`.
     * @param tree Expression to unparse.
     * @returns Expression `tree` unparsed.
     */
    Unparse(tree: NodeInput, parentPrecedence?: number): string;
    /**
     * Unparse recursively expression tree generating MathML representation.
     * @param tree Expression tree.
     * @returns String of expression `tree` unparsed as MathML language.
     */
    UnparserMathML(tree: NodeInput, parentPrecedence?: number): string;
    /**
     * Unparse Expression tree in MathML.
     * @param tree Expression tree.
     * @returns String of expression unparsed as MathML language.
     */
    UnparseMathML(tree: NodeInput, display?: 'inline' | 'block'): string;
    /**
     * Generates MathML representation of input without evaluation.
     * @param input Input to parse and generate MathML representation.
     * @param display `'inline'` or `'block'`.
     * @returns MathML representation of input.
     */
    ToMathML(input: string, display?: 'inline' | 'block'): string;
}
export type { EvaluatorConfig, IncDecOperator };
export { Scope, CallFrame, EvaluatorError, EvaluatorWorkspace, Evaluator };
declare const _default: {
    Scope: typeof Scope;
    CallFrame: typeof CallFrame;
    EvaluatorError: typeof EvaluatorError;
    EvaluatorWorkspace: typeof EvaluatorWorkspace;
    Evaluator: typeof Evaluator;
};
export default _default;
