mathjslab
Version:
MathJSLab - An interpreter with language syntax like MATLAB®/Octave, ISBN 978-65-00-82338-7.
1,425 lines • 52.5 kB
TypeScript
import { CharString, StringQuoteCharacter } from './CharString';
import { ComplexType } from './Complex';
import { FunctionHandle } from './FunctionHandle';
import { type ElementType, MultiArray } from './MultiArray';
/**
* Normalized AST and runtime node contracts used by parser, evaluator,
* unparser, MathML rendering, and diagnostics.
*
* Parser actions should create nodes through `AST` factory methods whenever
* possible. The factories encode parent-pointer conventions, output/answer
* suppression flags, and MATLAB/Octave-specific structural choices such as
* return lists, command-form calls, `arguments` blocks, and `classdef` sections.
*/
/**
* Operators accepted by the normalized expression AST.
*
* Suffix/prefix encodings such as `+_`, `_++`, and `.'` disambiguate source
* syntax that shares a token but has different precedence or operand position.
*/
type OperatorType = '+' | '-' | '.*' | '*' | './' | '/' | '.\\' | '\\' | '.^' | '^' | '.**' | '**' | '<' | '<=' | '==' | '>=' | '>' | '!=' | '~=' | '&' | '|' | '&&' | '||' | '=' | '+=' | '-=' | '*=' | '/=' | '\\=' | '^=' | '**=' | '.*=' | './=' | '.\\=' | '.^=' | '.**=' | '&=' | '|=' | '()' | '!' | '~' | '+_' | '-_' | '++_' | '--_' | ".'" | "'" | '_++' | '_--';
/**
* Delimiter used by an index expression.
*
* Parentheses mean ordinary array/function indexing; braces mean cell-array
* content indexing.
*/
type IndexingDelimiterType = '()' | '{}';
/**
* Discriminant values for AST nodes and runtime objects that participate in
* generic interpreter dispatch.
*
* Numeric runtime tags are used by value classes such as `Complex`,
* `MultiArray`, and class infrastructure objects. String tags are reserved for
* parser-created AST nodes.
*/
type NodeType = 'IDENT' | 'CMDWLIST' | 'IDX' | 'RANGE' | 'ENDRANGE' | 'LIST' | '.' | ':' | '<~>' | 'VOID' | 'RETLIST' | 'FCNDEF' | 'USERFCN' | 'BUILTIN' | 'ARGVALID' | 'ARGS' | 'GLOBAL' | 'PERSIST' | 'IMPORT' | 'RETURN' | 'BREAK' | 'CONTINUE' | 'IF' | 'ELSEIF' | 'ELSE' | 'SWITCH' | 'CASE' | 'WHILE' | 'DO_UNTIL' | 'FOR' | 'SPMD' | 'TRY' | 'UNWIND_PROTECT' | 'CLASSDEF' | 'CLASS_SECTION' | 'CLASS_PROPERTY' | 'CLASS_EVENT' | 'CLASS_ENUMERATION' | 'CLASS_ATTRIBUTE' | 'SUPERCLASS_CTOR' | 'METACLASS' | OperatorType;
/**
* Table of symbolic aliases recognized by the lexer/parser layer.
*/
type AliasNameTable = Record<string, RegExp>;
type DefiningScope = unknown;
/**
* Common metadata carried by all AST nodes.
*
* `parent` and `index` are best-effort navigation aids; evaluation logic should
* not require them for correctness. `omitOutput` models MATLAB/Octave semicolon
* suppression, while `omitAnswer` prevents helper statements such as
* declarations and function definitions from updating `ans`.
*/
interface NodeBase {
/** Node discriminant. */
type: NodeType | number;
/** Parent AST node or runtime wrapper, when known. */
parent?: NodeBase;
/** Index inside a parent list, when the node belongs to a list. */
index?: number;
/** Whether evaluation output should be suppressed. */
omitOutput?: boolean;
/** Whether the result should avoid assignment to `ans`. */
omitAnswer?: boolean;
/** Source start position, when supplied by the parser. */
start?: {
line: number;
column: number;
};
/** Source stop position, when supplied by the parser. */
stop?: {
line: number;
column: number;
};
}
/**
* Explicit "no value" node.
*/
interface NodeVoid extends NodeBase {
type: 'VOID';
}
/**
* Executable statement nodes recognized by the interpreter.
*/
type NodeStatement = NodeDeclaration | NodeImport | NodeReturn | NodeBreak | NodeContinue | NodeIf | NodeSwitch | NodeWhile | NodeDoUntil | NodeFor | NodeSpmd | NodeTry | NodeUnwindProtect | NodeFunctionDefinition | NodeClassDef;
/**
* Class-body nodes that are parsed as members or section metadata.
*/
type NodeClassMember = NodeClassSection | NodeClassProperty | NodeClassEvent | NodeClassEnumeration | NodeClassAttribute;
/**
* Nodes accepted inside concrete classdef sections.
*/
type NodeClassSectionMember = NodeClassProperty | NodeFunctionDefinition | NodeClassEvent | NodeClassEnumeration;
/**
* Root forms that can appear as direct interpreter input.
*/
type NodeProgramElement = NodeExpr | NodeStatement | NodeClassMember;
/**
* Any AST node that can be used as an executable/evaluable input.
*/
type NodeInput = NodeProgramElement | NodeList;
/**
* AST node that can appear in expression position.
*
* Runtime value shape accepted by expression evaluation before it is wrapped
* into parser-created AST containers.
*/
type RuntimeExpressionValue = Exclude<ElementType, null | undefined>;
/**
* AST node that can appear in expression position.
*
* Strict expression shape used by new code that can stay inside the typed AST
* and runtime-value surface.
*/
type StrictNodeExpr = RuntimeExpressionValue | NodeVoid | NodeIdentifier | NodeCmdWList | NodeIndexExpr | NodeSuperclassConstructor | NodeMetaClass | NodeRange | NodeColon | NodeEndRange | NodeOperation | NodeIgnoredTarget | NodeIndirectRef | NodeImport | NodeReturnList;
/**
* Non-expression AST nodes that are stored in `NodeList` while a surrounding
* builder assembles a larger statement node.
*/
type NodeListElement = NodeExpr | NodeElseIf | NodeElse | NodeSwitchCase | NodeFunctionDefinition | NodeArgumentValidation | NodeArguments | NodeClassSection | NodeClassProperty | NodeClassEvent | NodeClassEnumeration | NodeClassAttribute;
/**
* AST node that can appear in expression position.
*
* Generated ANTLR actions and a few evaluator reducers still route mixed AST
* shapes through `NodeExpr`. This carrier keeps that migration boundary
* explicit while stricter hand-written code uses `StrictNodeExpr`,
* `ExpressionBoundaryValue`, and AST guards.
*/
type LegacyNodeExprCarrier = any;
/**
* AST node that can appear in expression position.
*
* The strict branch documents the intended expression domain. The legacy
* carrier is a named migration boundary for generated parser actions and old
* evaluator paths that still carry broader AST shapes through expression
* slots.
*/
type NodeExpr = StrictNodeExpr | LegacyNodeExprCarrier;
/**
* Value accepted after an explicit expression-boundary validation.
*
* `NodeList` is included only as an execution-result carrier for paths such as
* `eval`/`evalin` and lazy return lists. New ordinary expression slots should
* prefer `StrictNodeExpr` when they do not need that carrier.
*/
type ExpressionBoundaryValue = StrictNodeExpr | NodeList;
/**
* 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: ExpressionBoundaryValue[];
delim: IndexingDelimiterType;
}
/**
* Explicit superclass constructor call, e.g. `obj@Base(args...)`.
*/
interface NodeSuperclassConstructor extends NodeBase {
type: 'SUPERCLASS_CTOR';
instance: NodeExpr;
superclass: NodeIdentifier;
args: ExpressionBoundaryValue[];
}
/**
* Metaclass literal, e.g. `?ClassName`.
*/
interface NodeMetaClass extends NodeBase {
type: 'METACLASS';
className: NodeIdentifier;
}
/**
* Range node.
*/
interface NodeRange extends NodeBase {
type: 'RANGE';
start_: NodeExpr;
stop_: NodeExpr;
stride_: NodeExpr | null;
}
/**
* Colon token node used by ranges and indexing.
*/
interface NodeColon extends NodeBase {
type: ':';
}
/**
* `end` token node used inside indexing ranges.
*/
interface NodeEndRange extends NodeBase {
type: 'ENDRANGE';
}
/**
* Operation node.
*/
type NodeOperation = UnaryOperation | BinaryOperation;
/**
* Unary operation node.
*/
type UnaryOperation = UnaryOperationL | UnaryOperationR;
/**
* Prefix unary operation with its operand stored on `right`.
*/
type PrefixUnaryOperation = UnaryOperationR;
/**
* Postfix unary operation with its operand stored on `left`.
*/
type PostfixUnaryOperation = UnaryOperationL;
/**
* 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;
}
/**
* Ignored return target (`~`) in a return or assignment list.
*/
interface NodeIgnoredTarget extends NodeBase {
type: '<~>';
}
/**
* Return-list entry accepted by MATLAB/Octave function definitions.
*/
type NodeFunctionReturn = NodeIdentifier | NodeIgnoredTarget;
/**
* Declaration entry accepted by `global` and `persistent` declarations.
*/
type NodeDeclarationElement = NodeIdentifier | NodeDefaultedParameter;
/**
* Parameter-list entry accepted by MATLAB/Octave function definitions.
*/
type NodeFunctionParameter = NodeIdentifier | NodeIgnoredTarget | NodeOperation;
/**
* Defaulted parameter form accepted in MATLAB/Octave function headers.
*/
type NodeDefaultedParameter = BinaryOperation & {
type: '=';
left: NodeIdentifier;
right: NodeExpr;
};
/**
* Left-hand-side expression forms accepted by assignment validation.
*/
type NodeAssignmentTarget = NodeIdentifier | NodeIgnoredTarget | NodeIndexExpr | NodeIndirectRef | MultiArray;
/**
* List node
*/
interface NodeList extends NodeBase {
type: 'LIST';
list: NodeListElement[];
}
/**
* Dot-reference node for structures and chained field access.
*/
interface NodeIndirectRef extends NodeBase {
type: '.';
obj: NodeExpr;
field: (string | NodeExpr)[];
}
/**
* Lazily evaluated return values keyed by result name.
*
* `length` is metadata, while dynamic output fields hold expression values.
*/
type ReturnHandlerResult = {
length: number;
[name: string]: NodeExpr | number | undefined;
};
/**
* Select a single output from a realized return handler result.
*/
type ReturnSelector = (evaluated: ReturnHandlerResult, index: number) => NodeExpr;
/**
* Materialize the outputs requested by a caller.
*/
type ReturnHandler = (length: number) => ReturnHandlerResult;
/**
* Error callback used by AST helpers that should not depend on Interpreter.
*/
type ThrowError = (message: string) => never;
/**
* Callable implementation stored in built-in registration tables.
*
* The concrete built-ins use specialized parameter and return types, so the
* registry keeps only the common "callable" shape and lets the interpreter
* perform the runtime dispatch.
*/
type BuiltInFunctionImplementation = Function;
/**
* Lazy multi-output return-list node.
*/
interface NodeReturnList extends NodeBase {
type: 'RETLIST';
/** Select one materialized output by zero-based index. */
selector: ReturnSelector;
/** Materialize the caller-requested output arity. */
handler: ReturnHandler;
/** Marks values that should expand as a MATLAB/Octave comma-separated list. */
commaSeparated?: boolean;
/** Number of comma-separated elements available without forcing the handler. */
returnListLength?: number;
}
/**
* Common fields shared by user-defined and built-in functions.
*/
interface NodeFunction extends NodeBase {
type: 'FCNDEF' | 'BUILTIN';
id: string;
mapper: boolean;
ev: boolean[];
func: Function | null;
definingScope?: DefiningScope;
/**
* Canonical virtual source name for function-file backed definitions.
*
* The browser runtime has no ambient filesystem, so this stores the
* resolver-provided `.m` source identity used by `mfilename("fullpath")`
* and stack/introspection helpers.
*/
sourceName?: string;
attributes?: {
/**
* Per-function persistent variable storage.
*
* Values are copied into the call scope at function entry and copied
* back after execution. The table lives on the function node so it
* survives between calls while the definition remains registered.
*/
persistent?: Record<string, RuntimeExpressionValue>;
/**
* Marks function definitions registered from inside another function.
*
* Nested functions share selected parent-scope bindings and are reported
* as nested by introspection helpers such as `which` and `functions`.
*/
nested?: boolean;
/**
* Marks a classdef method declaration without an inline function body.
*/
prototype?: boolean;
/**
* Marks a subfunction registered from a function-file source.
*
* Function-file subfunctions share the file function table with the
* primary function, but they are not exported to the caller/base scope.
*/
subfunction?: boolean;
};
}
/**
* AST node for a MATLAB/Octave-like user function definition.
*/
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).
*
* These blocks are validated during definition registration and function
* calls. They support Input, Output, Repeating, defaults, name-value
* declarations, size/class declarations, and supported validator functions.
*/
arguments: NodeList;
/**
* Function body statements
*/
statements: NodeList;
}
/**
* Declarative arity shape for built-ins.
*
* `arity < 0` denotes a variadic signature. The absolute value is the 1-based
* position where variadic arguments begin, matching the convention used by
* MATLAB/Octave `nargin`/`nargout` introspection.
*/
interface BuiltInFunctionArity {
arity: number;
min?: number;
max?: number;
}
/**
* Supported declarative validators for built-in function parameters.
*/
type BuiltInFunctionParameterValidator = 'numeric' | 'float' | 'numericOrLogical' | 'text' | 'textScalar' | 'nonzeroLengthText' | 'validVariableName' | 'scalar' | 'scalarOrEmpty' | 'scalarOrVector' | 'empty' | 'matrix2d' | 'squareMatrix' | 'vector' | 'rowVector' | 'columnVector' | 'twoElement' | 'oneOrTwoElement' | 'dimension' | 'dimensionGreaterThanOne' | 'dimensionVector' | 'reshapeDimension' | 'reshapeDimensionVector' | 'nonempty' | 'positive' | 'nonnegative' | 'negative' | 'nonpositive' | 'nonzero' | 'nonnan' | 'nonmissing' | 'nonsparse' | 'sparse' | 'zeroOrOne' | 'integer' | 'finite' | 'real';
/**
* One declarative built-in parameter.
*
* The signature validator uses these records to replace ad hoc argument checks
* inside individual built-ins.
*/
interface BuiltInFunctionParameter {
name: string;
classes?: string[];
validators?: BuiltInFunctionParameterValidator[];
allowedStrings?: string[];
identifier?: boolean;
alternatives?: BuiltInFunctionParameter[];
variadicGroup?: BuiltInFunctionParameter[];
allowInfinity?: boolean;
optional?: boolean;
variadic?: boolean;
}
/**
* One input overload for a built-in function.
*/
interface BuiltInFunctionInputSignature extends BuiltInFunctionArity {
parameters?: BuiltInFunctionParameter[];
}
/**
* Declarative built-in signature metadata.
*/
interface BuiltInFunctionSignature {
inputs?: BuiltInFunctionInputSignature | BuiltInFunctionInputSignature[];
outputs?: BuiltInFunctionArity | BuiltInFunctionArity[];
}
interface FunctionSignatureEntry {
func: BuiltInFunctionImplementation;
signature: BuiltInFunctionSignature;
}
/**
* Built-in function node registered by the runtime.
*/
interface NodeBuiltInFunction extends NodeFunction {
type: 'BUILTIN';
/** Concrete implementation for the registered built-in. */
func: BuiltInFunctionImplementation;
/**
* Optional declarative call signature used by the shared validator.
*/
signature?: BuiltInFunctionSignature;
UnparserMathML?: (tree: NodeInput) => string;
}
/**
* `builtInFunctionTable` type.
*/
type BuiltInFunctionTable = Record<string, NodeBuiltInFunction>;
/**
* User-defined function table keyed by function name.
*/
type FunctionTable = Record<string, NodeFunctionDefinition>;
/**
* One variable binding in a scope name table.
*/
type NameEntry = {
/**
* Identifier that blocked evaluation when forward references are enabled.
*/
undefinedReference?: string;
/**
* Bound value, if the entry has been assigned.
*/
node?: NodeInput;
/**
* Marks shared entries created by `global`.
*/
global?: boolean;
/**
* Tracks whether an Octave-style `global name = value` declaration has
* already initialized this global binding.
*/
globalInitialized?: boolean;
/**
* Marks function-local entries loaded from a function persistent table.
*/
persistent?: boolean;
};
/**
* Variable binding table keyed by identifier.
*/
type NameTable = Record<string, NameEntry>;
/**
* Forward-reference dependency table keyed by identifier.
*/
type UndefinedReferenceTable = Record<string, Set<string>>;
/**
* Command-form external function.
*
* Returning `undefined` leaves evaluation with the original command-word-list
* node; returning a value supplies the evaluated result. Host integrations may
* return primitive values, which the interpreter normalizes to runtime values.
*/
type CommandWordListFunction = (...args: string[]) => NodeInput | string | number | boolean | void;
/**
* `commandWordListTable` entry type.
*/
type CommandWordListEntry = {
func: CommandWordListFunction;
/**
* Keep this command name as an ordinary identifier when it is followed by
* an assignment operator. This is needed for built-ins such as `run` and
* `source`, which support command-form calls but are also common variable
* names in MATLAB/Octave code.
*/
preserveAssignment?: boolean;
};
/**
* `commandWordListTable` type.
*/
type CommandWordListTable = Record<string, CommandWordListEntry>;
/**
* One declaration inside an `arguments` block.
*/
interface NodeArgumentValidation extends NodeBase {
type: 'ARGVALID';
/**
* Identifier or name-value target such as `opts.Name`.
*/
name: NodeExpr;
/**
* Literal/symbolic size declaration.
*/
size: ExpressionBoundaryValue[];
/**
* Class declaration. May be a single identifier or a list.
*/
class: NodeInput | null;
/**
* Validator function declarations.
*/
functions: ExpressionBoundaryValue[];
/**
* Default expression, when declared for an input argument.
*/
default: NodeExpr | null;
}
/**
* `arguments` block node.
*/
interface NodeArguments extends NodeBase {
type: 'ARGS';
/**
* First block attribute kept for compatibility with existing single-attribute code paths.
*/
attribute: NodeIdentifier | null;
/**
* Full MATLAB-like block attribute list, for example `Input,Repeating`.
*/
attributes: NodeIdentifier[];
validation: NodeArgumentValidation[];
}
/**
* Declaration node for `global` and `persistent`.
*/
interface NodeDeclaration extends NodeBase {
type: 'GLOBAL' | 'PERSIST';
list: NodeExpr[];
}
/**
* MATLAB-style package/class import declaration or import-list query.
*/
interface NodeImport extends NodeBase {
type: 'IMPORT';
/**
* Fully qualified class/package imports. An empty list represents bare
* `import`, which queries the currently visible imports.
*/
imports: NodeIdentifier[];
}
/**
* `return` statement node.
*/
interface NodeReturn extends NodeBase {
type: 'RETURN';
}
/**
* `break` statement node.
*/
interface NodeBreak extends NodeBase {
type: 'BREAK';
}
/**
* `continue` statement node.
*/
interface NodeContinue extends NodeBase {
type: 'CONTINUE';
}
/**
* `if` statement node.
*/
interface NodeIf extends NodeBase {
type: 'IF';
expression: NodeExpr[];
then: NodeList[];
else: NodeList | null;
}
/**
* `elseif` clause node.
*/
interface NodeElseIf extends NodeBase {
type: 'ELSEIF';
expression: NodeExpr;
then: NodeList;
}
/**
* `else` clause node.
*/
interface NodeElse extends NodeBase {
type: 'ELSE';
else: NodeList;
}
/**
* `case` clause node.
*/
interface NodeSwitchCase extends NodeBase {
type: 'CASE';
expression: NodeExpr;
then: NodeList;
}
/**
* `switch` statement node.
*/
interface NodeSwitch extends NodeBase {
type: 'SWITCH';
expression: NodeExpr;
cases: NodeSwitchCase[];
otherwise: NodeList | null;
}
/**
* `while` statement node.
*/
interface NodeWhile extends NodeBase {
type: 'WHILE';
expression: NodeExpr;
body: NodeList;
}
/**
* `do ... until` statement node.
*/
interface NodeDoUntil extends NodeBase {
type: 'DO_UNTIL';
body: NodeList;
expression: NodeExpr;
}
/**
* `for` statement node.
*/
interface NodeFor extends NodeBase {
type: 'FOR';
target: NodeExpr;
expression: NodeExpr;
workers: NodeExpr | null;
body: NodeList;
parallel: boolean;
}
/**
* `spmd` statement node.
*/
interface NodeSpmd extends NodeBase {
type: 'SPMD';
workers: NodeList | null;
body: NodeList;
}
/**
* `try ... catch` statement node.
*/
interface NodeTry extends NodeBase {
type: 'TRY';
body: NodeList;
catchIdentifier: NodeIdentifier | null;
catchBody: NodeList | null;
}
/**
* `unwind_protect ... unwind_protect_cleanup` statement node.
*/
interface NodeUnwindProtect extends NodeBase {
type: 'UNWIND_PROTECT';
body: NodeList;
cleanup: NodeList;
}
/**
* Supported `classdef` section kinds.
*/
type ClassSectionKind = 'PROPERTIES' | 'METHODS' | 'EVENTS' | 'ENUMERATION';
/**
* Duplicate-preserving class attribute table keyed by attribute name.
*
* MATLAB/Octave diagnostics need to distinguish a repeated attribute from an
* effective attribute value, so the AST keeps the full list for each key.
*/
type ClassAttributeTable = Record<string, NodeClassAttribute[]>;
/**
* `classdef` declaration node.
*/
interface NodeClassDef extends NodeBase {
type: 'CLASSDEF';
/** Class name declared after `classdef`. */
id: string;
/** Attribute nodes declared in the class header. */
attributes: NodeClassAttribute[];
/** Attribute nodes grouped by name while preserving duplicates. */
attributeTable: ClassAttributeTable;
/** Direct superclass identifiers from the `< A & B` clause. */
superclasses: NodeIdentifier[];
/** Ordered `properties`, `methods`, `events`, and `enumeration` sections. */
sections: NodeClassSection[];
}
/**
* Section inside a `classdef` block.
*/
interface NodeClassSection extends NodeBase {
type: 'CLASS_SECTION';
/** Section kind, normalized independently from the concrete end keyword. */
kind: ClassSectionKind;
/** Section-level attributes such as `Access`, `Static`, or `Hidden`. */
attributes: NodeClassAttribute[];
/** Section attributes grouped by name while preserving duplicates. */
attributeTable: ClassAttributeTable;
/** Member list for this section. */
members: NodeList;
}
/**
* Property declaration inside a `properties` section.
*/
interface NodeClassProperty extends NodeBase {
type: 'CLASS_PROPERTY';
/** Property name as source text. */
id: string;
/**
* Canonical argument-validation-shaped declaration.
*
* Class property declarations reuse MATLAB's `arguments` validation syntax,
* so downstream code can validate size, class, and `mustBe*` functions
* through the same infrastructure used for function arguments.
*/
validation: NodeArgumentValidation;
/** Identifier node for diagnostics and metadata construction. */
name: NodeIdentifier;
/** Literal/symbolic size validation list. */
size: ExpressionBoundaryValue[];
/** Class validation node, or an empty list/null when absent. */
class: NodeInput | null;
/** Validator function declarations. */
functions: ExpressionBoundaryValue[];
/** Default value expression, when declared. */
defaultValue: NodeExpr | null;
}
/**
* Event declaration inside an `events` section.
*/
interface NodeClassEvent extends NodeBase {
type: 'CLASS_EVENT';
/** Event name. */
id: string;
}
/**
* Enumeration declaration inside an `enumeration` section.
*/
interface NodeClassEnumeration extends NodeBase {
type: 'CLASS_ENUMERATION';
/** Enumeration member name. */
id: string;
/** Constructor-like arguments attached to the member declaration. */
args: ExpressionBoundaryValue[];
}
/**
* Attribute declaration for `classdef`, `properties`, and `methods`.
*/
interface NodeClassAttribute extends NodeBase {
type: 'CLASS_ATTRIBUTE';
/** Attribute name as declared in source. */
id: string;
/** Optional attribute value, including identifiers, strings, cells, or negated markers. */
value: NodeExpr | null;
}
/**
* AST (Abstract Syntax Tree) node factory methods.
*/
declare abstract class AST {
/**
* External node factory methods.
*/
static nodeString: (str: string, quote?: StringQuoteCharacter) => CharString;
/**
* External number factory, rebound by `reload`.
*/
static nodeNumber: (value: string) => ComplexType;
/**
* External first-row matrix factory, rebound by `reload`.
*/
static firstRow: <ELEMENT>(row: ElementType<ELEMENT>[], iscell?: boolean) => MultiArray<ELEMENT>;
/**
* External row-append matrix factory, rebound by `reload`.
*/
static appendRow: <ELEMENT>(M: MultiArray<ELEMENT>, row: ElementType<ELEMENT>[]) => MultiArray<ELEMENT>;
/**
* External empty-array factory, rebound by `reload`.
*/
static emptyArray: <ELEMENT>(iscell?: boolean | undefined) => MultiArray<ELEMENT>;
/**
* 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;
/**
* Test whether an unknown value has the common AST/runtime node shape.
*/
static readonly isNodeBase: (value: unknown) => value is NodeBase;
/**
* Test whether an unknown value is an identifier node.
*/
static readonly isNodeIdentifier: (value: unknown) => value is NodeIdentifier;
/**
* Test whether an unknown value is a list node.
*/
static readonly isNodeList: (value: unknown) => value is NodeList;
/**
* Test whether an unknown value is a command-form call node.
*/
static readonly isNodeCmdWList: (value: unknown) => value is NodeCmdWList;
/**
* Test whether an unknown value is an index expression node.
*/
static readonly isNodeIndexExpr: (value: unknown) => value is NodeIndexExpr;
/**
* Test whether an unknown value is an explicit superclass constructor call.
*/
static readonly isNodeSuperclassConstructor: (value: unknown) => value is NodeSuperclassConstructor;
/**
* Test whether an unknown value is a range expression node.
*/
static readonly isNodeRange: (value: unknown) => value is NodeRange;
/**
* Test whether an unknown value is a colon token node.
*/
static readonly isNodeColon: (value: unknown) => value is NodeColon;
/**
* Test whether an unknown value is an `end` token node for indexing ranges.
*/
static readonly isNodeEndRange: (value: unknown) => value is NodeEndRange;
/**
* Test whether an unknown value is a dot-reference node.
*/
static readonly isNodeIndirectRef: (value: unknown) => value is NodeIndirectRef;
/**
* Test whether an unknown value is a lazy return-list node.
*/
static readonly isNodeReturnList: (value: unknown) => value is NodeReturnList;
/**
* Test whether an unknown value is an ignored target (`~`) node.
*/
static readonly isNodeIgnoredTarget: (value: unknown) => value is NodeIgnoredTarget;
/**
* Test whether an unknown value is an operator expression node.
*/
static readonly isNodeOperation: (value: unknown) => value is NodeOperation;
/**
* Test whether an unknown value is a binary operator expression.
*/
static readonly isNodeBinaryOperation: (value: unknown) => value is BinaryOperation;
/**
* Test whether an unknown value is a prefix unary operator expression.
*/
static readonly isNodePrefixOperation: (value: unknown) => value is PrefixUnaryOperation;
/**
* Test whether an unknown value is a postfix unary operator expression.
*/
static readonly isNodePostfixOperation: (value: unknown) => value is PostfixUnaryOperation;
/**
* Test whether an unknown value is a function return-list entry.
*/
static readonly isNodeFunctionReturn: (value: unknown) => value is NodeFunctionReturn;
/**
* Test whether an unknown value is a declaration-list entry.
*/
static readonly isNodeDeclarationElement: (value: unknown) => value is NodeDeclarationElement;
/**
* Test whether an unknown value is a defaulted function parameter.
*/
static readonly isNodeDefaultedParameter: (value: unknown) => value is NodeDefaultedParameter;
/**
* Test whether an unknown value is a function parameter-list entry.
*/
static readonly isNodeFunctionParameter: (value: unknown) => value is NodeFunctionParameter;
/**
* Test whether an unknown value is an assignment target expression.
*/
static readonly isNodeAssignmentTarget: (value: unknown) => value is NodeAssignmentTarget;
/**
* Test whether an unknown value is a declaration statement.
*/
static readonly isNodeDeclaration: (value: unknown) => value is NodeDeclaration;
/**
* Test whether an unknown value is an import declaration.
*/
static readonly isNodeImport: (value: unknown) => value is NodeImport;
/**
* Test whether an unknown value is a control-flow or block statement.
*/
static readonly isNodeStatement: (value: unknown) => value is NodeStatement;
/**
* Test whether an unknown value is a parsed class body member.
*/
static readonly isNodeClassMember: (value: unknown) => value is NodeClassMember;
/**
* Test whether an unknown value can appear as a top-level or block body element.
*/
static readonly isNodeProgramElement: (value: unknown) => value is NodeProgramElement;
/**
* Test whether an unknown value is a function definition node.
*/
static readonly isNodeFunctionDefinition: (value: unknown) => value is NodeFunctionDefinition;
/**
* Test whether an unknown value is a class definition node.
*/
static readonly isNodeClassDef: (value: unknown) => value is NodeClassDef;
/**
* Test whether an unknown value is a metaclass literal node.
*/
static readonly isNodeMetaClass: (value: unknown) => value is NodeMetaClass;
/**
* Test whether an unknown value is a runtime value allowed in expression position.
*/
static readonly isRuntimeExpressionValue: (value: unknown) => value is RuntimeExpressionValue;
/**
* Test whether an unknown value belongs to the strict expression contract.
*/
static readonly isStrictNodeExpr: (value: unknown) => value is StrictNodeExpr;
/**
* Test whether an unknown value has passed an expression-boundary shape.
*
* This accepts strict expression values plus `NodeList` execution-result
* carriers used by `eval`/`evalin` and comma-separated return paths.
*/
static readonly isExpressionBoundaryValue: (value: unknown) => value is ExpressionBoundaryValue;
/**
* Validate and narrow an unknown parser/runtime value to the strict expression shape.
*
* @param value Candidate expression value.
* @param role Human-readable role used in diagnostics.
* @returns The same value narrowed to `StrictNodeExpr`.
* @throws TypeError When `value` is a statement, list, or other non-expression carrier.
*/
static readonly requireStrictNodeExpr: (value: unknown, role?: string) => StrictNodeExpr;
/**
* Test whether an unknown value is an `arguments` block node.
*/
static readonly isNodeArguments: (value: unknown) => value is NodeArguments;
/**
* Test whether an unknown value is one declaration inside an `arguments` block.
*/
static readonly isNodeArgumentValidation: (value: unknown) => value is NodeArgumentValidation;
/**
* Test whether an unknown value is a `case` clause node.
*/
static readonly isNodeSwitchCase: (value: unknown) => value is NodeSwitchCase;
/**
* Test whether an unknown value is a class section node.
*/
static readonly isNodeClassSection: (value: unknown) => value is NodeClassSection;
/**
* Test whether an unknown value is a class attribute node.
*/
static readonly isNodeClassAttribute: (value: unknown) => value is NodeClassAttribute;
/**
* Test whether an unknown value is a class property member node.
*/
static readonly isNodeClassProperty: (value: unknown) => value is NodeClassProperty;
/**
* Test whether an unknown value is a class event member node.
*/
static readonly isNodeClassEvent: (value: unknown) => value is NodeClassEvent;
/**
* Test whether an unknown value is a class enumeration member node.
*/
static readonly isNodeClassEnumeration: (value: unknown) => value is NodeClassEnumeration;
/**
* Create an explicit no-value node.
*/
static readonly nodeVoid: () => NodeVoid;
/**
* Create name node.
* @param nodeid
* @returns
*/
static readonly nodeIdentifier: (id: string) => NodeIdentifier;
/**
* Create a metaclass literal node (`?ClassName`).
*/
static readonly nodeMetaClass: (className: NodeIdentifier) => NodeMetaClass;
/**
* Validate one value before storing it in an AST expression slot.
*
* Parser actions still type several intermediate values as `NodeExpr`; this
* guard keeps hand-written factories from preserving control-flow or block
* nodes in expression-only fields.
*/
private static readonly factoryExpression;
/**
* Validate a parser list before storing it as expression arguments.
*/
private static readonly factoryExpressionList;
/**
* Validate a parser list before storing it as command-word arguments.
*/
private static readonly factoryCommandWordList;
/**
* Validate a parser list before storing it as a typed AST child array.
*/
private static readonly factoryNodeList;
/**
* Validate a statement/body list without changing the list object stored by the parser.
*/
private static readonly factoryProgramElementList;
/**
* Validate matrix/cell row elements while preserving the existing delayed-evaluation carrier.
*/
private static readonly factoryArrayElementList;
/**
* Validate an optional class declaration in `arguments` and class property syntax.
*/
private static readonly factoryArgumentClass;
/**
* Create a command-form call node.
*
* Word-list commands pass their arguments as literal character strings,
* preserving the command-line spelling rather than evaluating them as
* expressions.
*
* @param nodename Registered command name.
* @param nodelist Raw command argument words.
* @returns Command-form AST node.
*/
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 an explicit superclass constructor call node.
*/
static readonly nodeSuperclassConstructor: (instance: NodeExpr, superclass: NodeIdentifier, args?: NodeList | null) => NodeSuperclassConstructor;
/**
* Create range node.
* @param start_
* @param stop_
* @param stride_
* @returns NodeRange.
*/
static readonly nodeRange: (start_: NodeExpr, stop_: NodeExpr, stride_?: NodeExpr) => NodeRange;
/**
* Create a colon token node.
*/
static readonly nodeColon: () => NodeColon;
/**
* Create an `end` token node for indexing ranges.
*/
static readonly nodeEndRange: () => NodeEndRange;
/**
* Node types that, by definition, should omit writing to the `ans`
* variable.
*/
private static readonly omitAnswerNodeOperation;
/**
* Assignment-like operations whose right side may temporarily carry a
* `NodeList` execution-result value produced by `eval`/`evalin`.
*/
private static readonly assignmentNodeOperation;
/**
* Operations that MATLAB/Octave reject inside anonymous function bodies.
*/
private static readonly anonymousFunctionForbiddenOperation;
/**
* Validate the complete expression subtree of an anonymous function body.
*/
private static readonly assertAnonymousFunctionExpression;
/**
* Validate anonymous function parameters at the AST construction boundary.
*/
private static readonly assertFunctionSignatureList;
/**
* Validate anonymous function parameters at the AST construction boundary.
*/
private static readonly assertAnonymousFunctionParameters;
/**
* Create operator node.
* @param op
* @param data1
* @param data2
* @returns
*/
static readonly nodeOperation: (op: OperatorType, data1: NodeExpr, data2?: NodeExpr) => NodeOperation;
/**
* Create a defaulted declaration/parameter entry.
*
* MATLAB/Octave use the assignment token in function parameter lists and
* persistent declarations. This helper preserves the regular binary
* operation shape while exposing the narrower AST contract consumed by
* declaration and parameter-list factories.
*
* @param id Declared identifier.
* @param value Default expression.
* @returns Defaulted parameter/declaration node.
*/
static readonly nodeDefaultedParameter: (id: NodeIdentifier, value: NodeExpr) => NodeDefaultedParameter;
/**
* Create an ignored return/assignment target node.
*/
static readonly nodeIgnoredTarget: () => NodeIgnoredTarget;
/**
* Create first element of list node.
* @param node First element of list node.
* @returns A NodeList.
*/
static readonly nodeListFirst: (node?: NodeListElement) => 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: NodeListElement) => NodeList;
/**
*
* @param list
* @returns
*/
static readonly nodeList: (list: NodeListElement[]) => NodeList;
/**
* Create first row of a MultiArray.
* @param row
* @returns
*/
static readonly nodeFirstRow: (row?: NodeList | null, iscell?: boolean) => MultiArray<ExpressionBoundaryValue>;
/**
* Append row to MultiArray.
* @param M
* @param row
* @returns
*/
static readonly nodeAppendRow: (M: MultiArray<ExpressionBoundaryValue>, row?: NodeList | null) => MultiArray<ExpressionBoundaryValue>;
/**
*
* @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;
/**
* Create a return-list node that represents a comma-separated list.
*
* Runtime producers such as brace indexing, structure field expansion, and
* built-ins like `deal` use this marker so callers can distinguish ordinary
* lazy multi-output values from values that should expand across argument or
* assignment positions.
*
* @param returnListLength Number of elements available in the comma-separated list.
* @param selector Output selector for materialized handler results.
* @param handler Optional materializer for requested output counts.
* @returns Comma-separated lazy return-list node.
*/
static readonly nodeCommaSeparatedReturnList: (returnListLength: number, selector: ReturnSelector, handler?: ReturnHandler) => NodeReturnList;
/**
* Create a return-list node with a fixed maximum output count.
*
* Many MATLAB/Octave built-ins return a lazy list whose values are only
* computed after the caller-selected arity is known. This helper keeps the
* standard "element number N undefined in return list" diagnostic in one
* place for those bounded return lists.
*
* @param maxLength Maximum number of outputs supported by the list.
* @param selector Output selector for valid indexes.
* @param handler Optional materializer for valid output counts.
* @param throwError Optional callback used to rethrow through interpreter diagnostics.
* @returns Bounded lazy return-list node.
*/
static readonly nodeBoundedReturnList: (maxLength: number, selector: ReturnSelector, handler?: ReturnHandler, throwError?: ThrowError) => NodeReturnList;
/**
* Ensures that the node is of type `NodeReturnList`.
* @param node A `NodeExpr`
* @returns A lazy return-list wrapper for `node`.
*/
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, throwError?: ThrowError) => 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, throwError?: ThrowError) => void | never;
/**
*
* @param id
* @param parameter_list
* @param expression
* @returns
*/
static readonly nodeFunctionHandle: (id?: NodeIdentifier | null, parameter_list?: NodeList | null, expression?: NodeExpr | null) => 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;
/**
* Build a name-keyed view of class attributes while preserving duplicates.
*/
private static readonly nodeClassAttributeTable;
/**
* Select the member guard required by each concrete classdef section.
*/
private static readonly nodeClassSectionMemberGuard;
/**
* Create one `arguments` block declaration.
*
* @param name Identifier or name-value field target.
* @param size Size declaration list.
* @param cl Class declaration node.
* @param functions Validator function list.
* @param dflt Default expression.
* @returns Argument validation node.
*/
static readonly nodeArgumentValidation: (name: NodeExpr, size: NodeList, cl: (NodeInput | null) | undefined, functions: NodeList, dflt?: NodeExpr | null) => NodeArgumentValidation;
/**
* Create an `arguments` block.
*
* @param attribute Optional block attribute or attribute list (`Input`, `Output`, `Repeating`).
* @param validationList Declaration list.
* @returns Arguments block node.
*/
static readonly nodeArguments: (attribute: NodeIdentifier | NodeList | null, validationList: NodeList) => NodeArguments;
/**
* Create the first node for a `global` or `persistent` declaration list.
*/
static readonly nodeDeclarationFirst: (type: "GLOBAL" | "PERSIST") => NodeDeclaration;
/**
* Create a `return` statement node.
*/
static readonly nodeReturn: () => NodeReturn;
/**
* Create a `break` statement node.
*/
static readonly nodeBreak: () => NodeBreak;
/**
* Create a `continue` statement node.
*/
static readonly nodeContinue: () => NodeContinue;
/**
* Normalize declaration list entries.
*
* Older generated parser code may append the parser context instead of
* the AST node itself; in that case the actual node is stored in `.node`.
*
* @param declaration Declaration list entry.
* @returns AST node for the declaration entry.
*/
static readonly getDeclarationNode: (declaration: NodeExpr | {
node: NodeExpr;
}) => NodeExpr;
/**
*
* @param node
* @param declaration
* @returns
*/
static readonly nodeAppendDeclaration: (node: NodeDeclaration, declaration: NodeExpr) => NodeDeclaration;
/**
* Create a bare MATLAB-style `import` query node.
*
* @returns Import node with no declared names.
*/
static readonly nodeImport: () => NodeImport;
/**
* Create the first node for a MATLAB-style `import` declaration.
*
* @param importName Fully qualified class/package name, optionally ending in `.*`.
* @returns Import declaration node.
*/
static readonly nodeImportFirst: (importName: NodeIdentifier) => NodeImport;
/**
* Append one fully qualified import name to an `import` declaration.
*
* @param node Import declaration to extend.
* @param importName Fully qualified class/package name.
* @returns The same import declaration node.
*/
static readonly nodeAppendImport: (node: NodeImport, importName: NodeIdentifier) => NodeImport;
/**
*
* @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;
/**
* Create a `switch` statement node.
*/
static readonly nodeSwitch: (expression: NodeExpr, cases: NodeList, otherwise?: NodeList | null) => NodeSwitch;
/**
* Create a `case` clause node.
*/
static readonly nodeSwitchCase: (expression: NodeExpr, then: NodeList) => NodeSwitchCase;
/**
* Create a `while` statement node.
*/
static readonly nodeWhile: (expression: NodeExpr, body: NodeList) => NodeWhile;
/**
* Create a `do ... until` statement node.
*/
static readonly nodeDoUntil: (body: NodeList, expression: NodeExpr) => NodeDoUntil;
/**
* Create a `for` statement node.
*/
static readonly nodeFor: (target: NodeExpr, expression: NodeExpr, body: NodeList, parallel?: boolean, workers?: NodeExpr | null) => NodeFor;
/**
* Create an `spmd` statement node.
*/
static readonly nodeSpmd: (body: NodeList, workers?: NodeList | null) => NodeSpmd;
/**
* Create a `try ... catch` statement node.
*/
static readonly nodeTry: (body: NodeList, catchBody?: NodeList | null, catchIdentifier?: NodeIdentifier | null) => NodeTry;
/**
* Create an `unwind_protect ... unwind_protect_cleanup` statement node.
*/
static readonly nodeUnwindProtect: (body: NodeList, cleanup: NodeList) => NodeUnwindProtect;
/**
* Create a minimal `classdef` node.
*/
static readonly nodeClassDef: (id: NodeIdentifier, sections: NodeList, attributes?: NodeList, superclasses?: NodeList) => NodeClassDef;
/**
* Create a `properties` or `methods` section.
*