import { CharString, StringQuoteCharacter } from './CharString';
import { ComplexType } from './Complex';
import { Scope } from './Evaluator';
import { FunctionHandle } from './FunctionHandle';
import { type ElementType, MultiArray } from './MultiArray';
/**
 * AST (Abstract Syntax Tree).
 */
/**
 * Operator type.
 */
type OperatorType = '+' | '-' | '.*' | '*' | './' | '/' | '.\\' | '\\' | '.^' | '^' | '.**' | '**' | '<' | '<=' | '==' | '>=' | '>' | '!=' | '~=' | '&' | '|' | '&&' | '||' | '=' | '+=' | '-=' | '*=' | '/=' | '\\=' | '^=' | '**=' | '.*=' | './=' | '.\\=' | '.^=' | '.**=' | '&=' | '|=' | '()' | '!' | '~' | '+_' | '-_' | '++_' | '--_' | ".'" | "'" | '_++' | '_--';
type IndexingDelimiterType = '()' | '{}';
/**
 * NodeType
 */
type NodeType = 'IDENT' | 'CMDWLIST' | 'IDX' | 'RANGE' | 'ENDRANGE' | 'LIST' | '.' | ':' | '<~>' | 'VOID' | 'UNPARSE' | 'RETLIST' | 'FCNDEF' | 'USERFCN' | 'BUILTIN' | 'ARGVALID' | 'ARGS' | 'GLOBAL' | 'PERSIST' | 'IF' | 'ELSEIF' | 'ELSE' | OperatorType;
type AliasNameTable = Record<string, RegExp>;
/**
 * Node base.
 */
interface NodeBase {
    type: NodeType | number;
    parent?: any;
    index?: number;
    omitOutput?: boolean;
    omitAnswer?: boolean;
    start?: {
        line: number;
        column: number;
    };
    stop?: {
        line: number;
        column: number;
    };
}
interface NodeVoid extends NodeBase {
    type: 'VOID';
}
type NodeInput = NodeExpr | NodeList | NodeDeclaration | NodeIf;
/**
 * Expression node.
 */
type NodeExpr = ElementType | NodeIdentifier | NodeIndexExpr | NodeOperation | NodeRange | NodeIndirectRef | NodeReturnList | any;
/**
 * Reserved node.
 */
interface NodeReserved extends NodeBase {
}
/**
 * Literal node.
 */
interface NodeLiteral extends NodeBase {
}
/**
 * Name node.
 */
interface NodeIdentifier extends NodeBase {
    type: 'IDENT';
    id: string;
}
/**
 * Command word list node.
 */
interface NodeCmdWList extends NodeBase {
    type: 'CMDWLIST';
    id: string;
    args: CharString[];
}
/**
 * Expression and arguments node.
 */
interface NodeIndexExpr extends NodeBase {
    type: 'IDX';
    expr: NodeExpr;
    exprEvaluated?: NodeExpr;
    args: NodeExpr[];
    delim: IndexingDelimiterType;
}
/**
 * Range node.
 */
interface NodeRange extends NodeBase {
    type: 'RANGE';
    start_: NodeExpr | null;
    stop_: NodeExpr | null;
    stride_: NodeExpr | null;
}
interface NodeColon extends NodeBase {
    type: ':';
}
interface NodeEndRange extends NodeBase {
    type: 'ENDRANGE';
}
/**
 * Operation node.
 */
type NodeOperation = UnaryOperation | BinaryOperation;
/**
 * Unary operation node.
 */
type UnaryOperation = UnaryOperationL | UnaryOperationR;
/**
 * Right unary operation node.
 */
interface UnaryOperationR extends NodeBase {
    right: NodeExpr;
}
/**
 * Left unary operation node.
 */
interface UnaryOperationL extends NodeBase {
    left: NodeExpr;
}
/**
 * Binary operation.
 */
interface BinaryOperation extends NodeBase {
    left: NodeExpr;
    right: NodeExpr;
}
interface NodeIgnoredTarget extends NodeBase {
    type: '<~>';
}
/**
 * List node
 */
interface NodeList extends NodeBase {
    type: 'LIST';
    list: NodeInput[];
}
interface NodeIndirectRef extends NodeBase {
    type: '.';
    obj: NodeExpr;
    field: (string | NodeExpr)[];
}
type ReturnHandlerResult = {
    length: number;
} & Record<string, NodeExpr>;
type ReturnSelector = (evaluated: ReturnHandlerResult, index: number) => NodeExpr;
type ReturnHandler = (length: number) => ReturnHandlerResult;
/**
 * Return list node
 */
interface NodeReturnList extends NodeBase {
    type: 'RETLIST';
    selector: ReturnSelector;
    handler: ReturnHandler;
}
interface NodeFunction extends NodeBase {
    type: 'FCNDEF' | 'BUILTIN';
    id: string;
    mapper: boolean;
    ev: boolean[];
    func: Function;
    definingScope?: Scope;
    attributes?: {
        persistent?: Set<string>;
    };
}
interface NodeFunctionDefinition extends NodeFunction {
    type: 'FCNDEF';
    /**
     * Return variables (IDENT nodes)
     * Example: function [a,b] = f(x)
     */
    return: NodeList;
    /**
     * Formal parameters (IDENT nodes)
     */
    parameter: NodeList;
    /**
     * Argument validation blocks (MATLAB-style)
     * NOT used by evaluator yet
     */
    arguments: NodeList;
    /**
     * Function body statements
     */
    statements: NodeList;
}
interface NodeBuiltInFunction extends NodeFunction {
    type: 'BUILTIN';
    UnparserMathML?: (tree: NodeInput) => string;
}
/**
 * `builtInFunctionTable` type.
 */
type BuiltInFunctionTable = Record<string, NodeBuiltInFunction>;
type FunctionTable = Record<string, NodeFunctionDefinition>;
type NameEntry = {
    undefinedReference?: string;
    node?: NodeInput;
};
type NameTable = Record<string, NameEntry>;
type UndefinedReferenceTable = Record<string, string[]>;
/**
 * `commandWordListFunction` type.
 */
type CommandWordListFunction = (...args: string[]) => any;
/**
 * `commandWordListTable` entry type.
 */
type CommandWordListEntry = {
    func: CommandWordListFunction;
};
/**
 * `commandWordListTable` type.
 */
type CommandWordListTable = Record<string, CommandWordListEntry>;
interface NodeArgumentValidation extends NodeBase {
    type: 'ARGVALID';
    name: NodeIdentifier;
    size: NodeInput[];
    class: NodeIdentifier | null;
    functions: NodeInput[];
    default: NodeExpr;
}
interface NodeArguments extends NodeBase {
    type: 'ARGS';
    attribute: NodeIdentifier | null;
    validation: NodeArgumentValidation[];
}
interface NodeDeclaration extends NodeBase {
    type: 'GLOBAL' | 'PERSIST';
    list: NodeExpr[];
}
interface NodeIf extends NodeBase {
    type: 'IF';
    expression: NodeExpr[];
    then: NodeList[];
    else: NodeList | null;
}
interface NodeElseIf extends NodeBase {
    type: 'ELSEIF';
    expression: NodeExpr;
    then: NodeList;
}
interface NodeElse extends NodeBase {
    type: 'ELSE';
    else: NodeList;
}
/**
 * AST (Abstract Syntax Tree) node factory methods.
 */
declare abstract class AST {
    /**
     * External node factory methods.
     */
    static nodeString: (str: string, quote?: StringQuoteCharacter) => CharString;
    static nodeNumber: (value: string) => ComplexType;
    static firstRow: (row: ElementType[], iscell?: boolean) => MultiArray;
    static appendRow: (M: MultiArray, row: ElementType[]) => MultiArray;
    static emptyArray: (iscell?: boolean | undefined) => MultiArray;
    /**
     * Reload external node factory methods.
     */
    static readonly reload: () => void;
    /**
     * It makes a shallow copy of the node.
     * @param node AST node to copy.
     * @returns Shallow copy of `node`.
     */
    static readonly nodeCopy: <T = object>(node: T) => T;
    static readonly nodeVoid: () => NodeVoid;
    /**
     * Create name node.
     * @param nodeid
     * @returns
     */
    static readonly nodeIdentifier: (id: string) => NodeIdentifier;
    /**
     * Create command word list node.
     * @param nodename
     * @param nodelist
     * @returns
     */
    static readonly nodeCmdWList: (nodename: NodeIdentifier, nodelist: NodeList) => NodeCmdWList;
    /**
     * Create expression and arguments node.
     * @param nodeexpr
     * @param nodelist
     * @returns
     */
    static readonly nodeIndexExpr: (nodeexpr: NodeExpr, nodelist?: NodeList | null, delimiter?: IndexingDelimiterType) => NodeIndexExpr;
    /**
     * Create range node.
     * @param start_
     * @param stop_
     * @param stride_
     * @returns NodeRange.
     */
    static readonly nodeRange: (start_: NodeExpr, stop_: NodeExpr, stride_?: NodeExpr) => NodeRange;
    static readonly nodeColon: () => NodeColon;
    static readonly nodeEndRange: () => NodeEndRange;
    /**
     * Node types that, by definition, should omit writing to the `ans`
     * variable.
     */
    private static readonly omitAnswerNodeOperation;
    /**
     * Create operator node.
     * @param op
     * @param data1
     * @param data2
     * @returns
     */
    static readonly nodeOperation: (op: OperatorType, data1: NodeExpr, data2?: NodeExpr) => NodeOperation;
    static readonly nodeIgnoredTarget: () => NodeIgnoredTarget;
    /**
     * Create first element of list node.
     * @param node First element of list node.
     * @returns A NodeList.
     */
    static readonly nodeListFirst: (node?: NodeInput) => NodeList;
    /**
     * Append node to list node.
     * @param lnode NodeList.
     * @param node Element to append to list.
     * @returns NodeList with element appended.
     */
    static readonly appendNodeList: (lnode: NodeList, node: NodeInput) => NodeList;
    /**
     *
     * @param list
     * @returns
     */
    static readonly nodeList: (list: NodeInput[]) => NodeList;
    /**
     * Create first row of a MultiArray.
     * @param row
     * @returns
     */
    static readonly nodeFirstRow: (row?: NodeList | null, iscell?: boolean) => MultiArray;
    /**
     * Append row to MultiArray.
     * @param M
     * @param row
     * @returns
     */
    static readonly nodeAppendRow: (M: MultiArray, row?: NodeList | null) => MultiArray;
    /**
     *
     * @param left
     * @param right
     * @returns
     */
    static readonly nodeIndirectRef: (left: NodeExpr, right: string | NodeExpr) => NodeIndirectRef;
    /**
     * Creates NodeReturnList (multiple assignment)
     * @param selector Left side selector function.
     * @param handler A handler that returns an object containing the length
     * of the multiple assignment and the values evaluated by the function in
     * a single execution. The `selector` function uses these values.
     * @returns Return list node.
     */
    static readonly nodeReturnList: (selector: ReturnSelector, handler?: ReturnHandler) => NodeReturnList;
    static readonly ensureReturnList: (node: NodeExpr) => NodeReturnList;
    /**
     * Throws error if left hand side length of multiple assignment greater
     * than maximum length (to be used in ReturnSelector functions).
     * @param maxLength Maximum length of return list.
     * @param currentLength Requested length of return list.
     */
    static readonly throwErrorIfGreaterThanReturnList: (maxLength: number, currentLength: number) => void | never;
    /**
     * Tests if it is a NodeReturnList and if so reduces it to its first
     * element.
     * @param value A node.
     * @returns Reduced node if `tree` is a NodeReturnList.
     */
    static readonly reduceToFirstIfReturnList: (tree: NodeInput) => NodeInput;
    /**
     * Throw invalid call error if (optional) test is true.
     * @param name
     */
    static readonly throwInvalidCallError: (name: string, test?: boolean) => void | never;
    /**
     *
     * @param id
     * @param parameter_list
     * @param expression
     * @returns
     */
    static readonly nodeFunctionHandle: (id?: NodeIdentifier | null, parameter_list?: NodeList | null, expression?: NodeExpr) => FunctionHandle;
    /**
     *
     * @param id
     * @param return_list
     * @param parameter_list
     * @param arguments_list
     * @param statements_list
     * @returns
     */
    static readonly nodeFunctionDefinition: (id: NodeIdentifier, return_list: NodeList, parameter_list: NodeList, arguments_list: NodeList, statements_list: NodeList) => NodeFunctionDefinition;
    /**
     *
     * @param name
     * @param size
     * @param cl
     * @param functions
     * @param dflt
     * @returns
     */
    static readonly nodeArgumentValidation: (name: NodeIdentifier, size: NodeList, cl: (NodeIdentifier | null) | undefined, functions: NodeList, dflt?: NodeExpr) => NodeArgumentValidation;
    /**
     *
     * @param attribute
     * @param validationList
     * @returns
     */
    static readonly nodeArguments: (attribute: NodeIdentifier | null, validationList: NodeList) => NodeArguments;
    /**
     *
     * @param type
     * @returns
     */
    static readonly nodeDeclarationFirst: (type: "GLOBAL" | "PERSIST") => NodeDeclaration;
    /**
     *
     * @param node
     * @param declaration
     * @returns
     */
    static readonly nodeAppendDeclaration: (node: NodeDeclaration, declaration: NodeExpr) => NodeDeclaration;
    /**
     *
     * @param expression
     * @param then
     * @returns
     */
    static readonly nodeIfBegin: (expression: NodeExpr, then: NodeList) => NodeIf;
    /**
     *
     * @param nodeIf
     * @param nodeElse
     * @returns
     */
    static readonly nodeIfAppendElse: (nodeIf: NodeIf, nodeElse: NodeElse) => NodeIf;
    /**
     *
     * @param nodeIf
     * @param nodeElseIf
     * @returns
     */
    static readonly nodeIfAppendElseIf: (nodeIf: NodeIf, nodeElseIf: NodeElseIf) => NodeIf;
    /**
     *
     * @param expression
     * @param then
     * @returns
     */
    static readonly nodeElseIf: (expression: NodeExpr, then: NodeList) => NodeElseIf;
    /**
     *
     * @param elseStmt
     * @returns
     */
    static readonly nodeElse: (elseStmt: NodeList) => NodeElse;
}
export type { OperatorType, IndexingDelimiterType, NodeType, AliasNameTable, NodeBase, NodeInput, NodeExpr, NodeReserved, NodeLiteral, NodeIdentifier, NodeCmdWList, NodeIndexExpr, NodeRange, NodeColon, NodeEndRange, NodeOperation, UnaryOperation, UnaryOperationR, UnaryOperationL, BinaryOperation, NodeIgnoredTarget, NodeList, NodeIndirectRef, ReturnHandlerResult, ReturnHandler, ReturnSelector, NodeReturnList, NodeFunction, NodeFunctionDefinition, NodeBuiltInFunction, BuiltInFunctionTable, FunctionTable, NameEntry, NameTable, UndefinedReferenceTable, CommandWordListFunction, CommandWordListEntry, CommandWordListTable, NodeArgumentValidation, NodeArguments, NodeDeclaration, NodeIf, NodeElseIf, NodeElse, };
export { AST };
declare const _default: {
    AST: typeof AST;
};
export default _default;
/**
 * External exports.
 */
export type { SingleQuoteCharacter, DoubleQuoteCharacter, StringQuoteCharacter } from './CharString';
export { singleQuoteCharacter, doubleQuoteCharacter, stringClass, CharString } from './CharString';
export type { Decimal, RealType, NumberObjectType, RealTypeDescriptor, ComplexType } from './Complex';
export { Complex } from './Complex';
export type { ElementType } from './MultiArray';
export { MultiArray } from './MultiArray';
export { Structure } from './Structure';
export { FunctionHandle } from './FunctionHandle';
