mathjslab
Version:
MathJSLab - An interpreter with language syntax like MATLAB®/Octave, ISBN 978-65-00-82338-7.
1,244 lines • 89 kB
TypeScript
/**
* MATLAB®/Octave like syntax parser/interpreter/compiler.
*/
import type { NodeInput, NodeExpr, NodeFunctionDefinition, NodeBuiltInFunction, AliasNameTable, BuiltInFunctionTable, CommandWordListTable, ExpressionBoundaryValue } from './AST';
import { ClassDefinition } from './ClassDefinition';
import { ClassInstance } from './ClassInstance';
import { ClassStaticMethod } from './ClassStaticMethod';
import { Scope } from './Scope';
import { CallFrame } from './CallFrame';
import type { SourceEntry, SourceProvider, SourceResolver, SourceTable } from './SourceResolver';
import { Context } from './Context';
import { CircularReferenceError, EvalError, InterpreterError, ReferenceError, SyntaxError, UndefinedReferenceError } from './InterpreterError';
import type { CallArgumentValue } from './FunctionCall';
/**
* Numeric exit status used by the public `exitStatus` property.
*/
type ExitStatus = number;
/** Named exit status table. */
type ExitStatusValues = Record<string, ExitStatus>;
/** Host-provided class source entry. */
type ClassSource = SourceEntry;
/** Host-provided function-file source entry. */
type FunctionSource = SourceEntry;
/** Host-provided script-file source entry. */
type ScriptSource = SourceEntry;
/** Callback used to provide classdef source for a class name. */
type ClassSourceProvider = SourceProvider;
/** Table of host-provided class sources keyed by class name. */
type ClassSourceTable = SourceTable;
/** Callback used to provide function-file source for a function name. */
type FunctionSourceProvider = SourceProvider;
/** Table of host-provided function-file sources keyed by primary function name. */
type FunctionSourceTable = SourceTable;
/** Callback used to provide script-file source for a script name. */
type ScriptSourceProvider = SourceProvider;
/** Table of host-provided script-file sources keyed by script name. */
type ScriptSourceTable = SourceTable;
/**
* Interpreter construction options.
*
* All extension points are explicit so the engine remains browser-compatible:
* callers can inject aliases, built-ins, command-form functions, and class
* sources without requiring ambient filesystem or module loading.
*/
type InterpreterConfig = {
/** Lexer/parser alias table for symbolic names. */
aliasNameTable?: AliasNameTable;
/** Additional built-in functions registered at startup. */
externalFunctionTable?: BuiltInFunctionTable;
/** Additional command-form functions registered at startup. */
externalCmdWListTable?: CommandWordListTable;
/** Unified virtual `.m` source resolver. */
sourceResolver?: SourceResolver;
/** Host predicate used by `mustBeFile` argument/property validation. */
fileExists?: (path: string) => boolean;
/** Host predicate used by `mustBeFolder` argument/property validation. */
folderExists?: (path: string) => boolean;
/** Host-provided function-file source strings. */
functionSourceTable?: FunctionSourceTable;
/** Lazy host-provided function-file source callback. */
functionSourceProvider?: FunctionSourceProvider;
/** Host-provided script-file source strings. */
scriptSourceTable?: ScriptSourceTable;
/** Lazy host-provided script-file source callback. */
scriptSourceProvider?: ScriptSourceProvider;
/** Host-provided class source strings. */
classSourceTable?: ClassSourceTable;
/** Lazy host-provided class source callback. */
classSourceProvider?: ClassSourceProvider;
/**
* Compatibility alias for early class-loader experiments. Prefer
* `classSourceTable` for browser/host-provided class sources.
*/
externalClassSourceTable?: Record<string, string>;
/**
* Compatibility alias for early function-loader experiments. Prefer
* `functionSourceTable` for browser/host-provided function sources.
*/
externalFunctionSourceTable?: Record<string, string>;
/**
* Compatibility alias for early script-loader experiments. Prefer
* `scriptSourceTable` for browser/host-provided script sources.
*/
externalScriptSourceTable?: Record<string, string>;
};
/**
* Increment and decrement operator handler type.
*/
type IncDecOperator = (tree: NodeExpr, scope: Scope) => NodeInput;
/**
* Full parse/evaluate/unparse bundle returned by `Interprets`.
*/
type InterpretsResult = {
/** Original input string. */
input: string;
/** AST produced from the original input. */
inputParsed: NodeInput;
/** Textual unparse of the evaluated input. */
inputUnparsed: string;
/** MathML rendering of the evaluated input. */
inputUnparsedMathML: string;
/** Evaluated runtime value or AST result. */
evaluated: NodeInput;
/** Textual unparse of the evaluated result. */
evaluatedUnparsed: string;
/** MathML rendering of the evaluated result. */
evaluatedUnparsedMathML: string;
};
/**
* Interpreter instance interface.
*/
interface InterpreterInterface {
/** Whether debug diagnostics and fallback tracing are enabled. */
debug: boolean;
/** Runtime context owned by this interpreter. */
context: Context;
/** Last public execution status. */
exitStatus: ExitStatus;
/** Operator precedence table used by unparsers. */
precedenceTable: {
[key: string]: number;
};
/** Parse source text into an AST/runtime node. */
Parse(input: string): NodeInput;
/** Reset runtime state while preserving constructor-level configuration defaults. */
Restart(): void;
/** Clear variables/functions, or reset the interpreter when no names are supplied. */
Clear(...names: string[]): void;
/** Evaluate one AST/runtime node in a scope. */
Evaluator(tree: NodeInput, scope?: Scope): NodeInput;
/** Evaluate one parsed AST from the public top-level entry point. */
Evaluate(tree: NodeInput): NodeInput;
/** Parse and evaluate source text in one call. */
Execute(input: string): NodeInput;
/** Convert a runtime/AST node back to normalized source-like text. */
Unparse(tree: NodeInput, parentPrecedence?: number): string;
/** Convert a runtime/AST node to a MathML fragment. */
UnparserMathML(tree: NodeInput, parentPrecedence: number): string;
/** Convert a runtime/AST node to a complete MathML string. */
UnparseMathML(tree: NodeInput, display: 'inline' | 'block' | 'none'): string;
/** Parse source text and render its AST as MathML. */
ToMathML(input: string, display: 'inline' | 'block' | 'none'): string;
/** Return parsed/evaluated/unparsed forms for host diagnostics and demos. */
Interprets(input: string, display: 'inline' | 'block' | 'none'): InterpretsResult;
}
/**
* MATLAB/Octave-like parser, evaluator, unparser, and host integration point.
*
* `Interpreter` owns the ANTLR parser pipeline, runtime context, built-in
* tables, command-form functions, class loading contracts, and display
* unparsers. Most semantic helpers are delegated to smaller modules; this
* class coordinates them around one active `Context`.
*/
declare class Interpreter implements InterpreterInterface {
/** MATLAB-compatible maximum identifier length exposed by `namelengthmax`. */
private static readonly nameLengthMax;
/** Sorted language keywords as recognized by the lexer. */
private static readonly keywordNames;
/** Keyword lookup set used by `iskeyword` and `isvarname`. */
private static readonly keywordNameSet;
/** Public MATLAB validator functions backed by the `arguments` validator engine. */
private static readonly publicArgumentValidators;
/**
* 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);
/**
* Interpreter context.
*/
context: Context;
/**
* Command word list table.
*/
private commandWordListTable;
private commandWordListNameSet;
private assignmentSensitiveCommandNameSet;
/**
* Unified virtual source resolver for browser/host-provided `.m` files.
*/
private sourceResolver;
/** Host path predicates used by MATLAB-style file/folder validators. */
private pathValidationCallbacks;
/**
* Refresh lexer-facing command-name sets after command table changes.
*/
private refreshCommandWordListNames;
/**
* Function names currently being loaded, used to avoid recursive loader loops.
*/
private loadingFunctionNames;
/**
* Class names currently being loaded, used to avoid recursive loader loops.
*/
private loadingClassNames;
/**
* Class method names currently being loaded, used to avoid recursive loader loops.
*/
private loadingClassMethodNames;
/**
* Nesting level of host-provided script execution.
*
* A script is not a function frame, but MATLAB/Octave still allow `return`
* to stop the current script. Keeping that state in the interpreter lets
* interactive/top-level `return` remain invalid while scripts loaded
* through the browser-safe source APIs can exit early.
*/
private scriptExecutionDepth;
/**
* Virtual source identities for currently executing scripts.
*
* Script-local functions are ordinary function definitions registered
* temporarily in the caller workspace; this stack lets that registration
* attach the surrounding script's browser-hosted source identity.
*/
private scriptSourceNameStack;
/**
* Interpreter exit status.
*/
private _exitStatus;
/**
* Last uncaught public evaluation error, exposed through `lasterror`.
*/
private lastError?;
/**
* Last warning state exposed through `lastwarn`.
*
* Warning emission is still intentionally conservative, but keeping the
* state here gives the public API a stable MATLAB/Octave-like contract.
*/
private lastWarning;
/**
* Global warning state used by `warning("on"|"off"|"error")`.
*/
private globalWarningState;
/**
* Per-identifier warning emission overrides.
*/
private warningIdentifierStates;
/**
* Interpreter 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 that updates an assignable expression.
*/
private incDecOpFactory;
/**
* Operator table.
*/
private readonly opTable;
private static readonly binaryOperatorMethodTable;
private static readonly unaryOperatorMethodTable;
/**
* 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 functionArityCallable;
private functionArgumentArity;
private functionOutputArity;
/**
* Parse or resolve a textual function-handle source.
*/
private functionHandleFromString;
/**
* Resolve a runtime symbol through the interpreter-owned lookup facade.
*
* Keeping this indirection inside `Interpreter` prevents parser/evaluator
* code from depending directly on the exact `Context.resolveSymbol` option
* shape and gives lookup-sensitive features one place to evolve.
*
* @param name Name requested by source text.
* @param scope Lookup scope.
* @param options Resolution switches.
* @returns Structured symbol resolution, if any.
*/
private resolveRuntimeSymbol;
/** Resolve a function-like runtime symbol without considering variables or classes. */
private resolveRuntimeFunction;
/** Resolve a class runtime symbol without considering variables or functions. */
private resolveRuntimeClass;
/**
* Create a named function handle using the current structured lookup layer.
*
* Qualified names and aliases are normalized to their runtime spelling.
* Simple imported names keep their source spelling and rely on the captured
* import table, matching MATLAB/Octave display behavior for `@name`.
* When requested, user-function handles keep a lexical overlay so returned
* handles remain bound to local/nested functions and in-scope imports.
*
* @param name Function name supplied by source text or a character string.
* @param scope Lookup scope used to resolve imports and local functions.
* @param parent Optional AST parent for the new handle.
* @param captureLexical Whether to capture a lexical overlay for user functions.
* @returns Named function handle.
*/
private createResolvedFunctionHandle;
private localFunctionHandles;
/**
* Copy and validate one captured workspace value before exposing it through
* the MATLAB/Octave `functions(handle).workspace` metadata struct.
*/
private functionHandleWorkspaceValue;
private functionHandleWorkspaceInfo;
private staticMethodInfo;
private dbstackResult;
/**
* Return the MATLAB/Octave `mfilename` value for the current function.
*
* When a browser-hosted source provides a virtual path, plain `mfilename`
* reports the file basename without the `.m` suffix while
* `mfilename("fullpath")` keeps the complete virtual identity.
*/
private currentMFilename;
/**
* Return the MATLAB/Octave `mfilename("fullpath")` identity.
*
* For browser-hosted code, "fullpath" means the complete virtual source
* identity supplied by the host resolver. Unlike plain `mfilename`, this
* intentionally keeps the configured `.m`-like suffix because source
* metadata, `functions`, and stack display share that identity.
*/
private currentMFilenameFullPath;
/**
* Return the best virtual source identity for a handle created now.
*/
private currentHandleSourceName;
/**
* Return the class context that should be captured by a handle created now.
*/
private currentHandleClassName;
/**
* Convert a native or interpreter error into the struct shape used by
* MATLAB/Octave-style `catch ME` and `lasterror`.
*
* `InterpreterError.stackFrames` stores the most recent frame first, while
* `dbstackResult` expects the live call-stack order and reverses it during
* formatting. The local reversal preserves the captured thrown stack instead
* of rebuilding it from the current catch/evaluation context.
*
* @param error Error object or thrown value.
* @returns Structure with `message`, `identifier`, and `stack` fields.
*/
private exceptionToStruct;
/**
* Return the current `lasterror` value.
*
* MATLAB/Octave keep the last uncaught error until it is replaced or the
* interpreter state is reset. When no error has escaped yet, the empty
* structure uses the same fields so callers can index it without special
* casing the initial state.
*
* @returns MATLAB-like last-error structure.
*/
private lastErrorStruct;
/**
* Return the default `lasterror` structure.
*/
private emptyLastErrorStruct;
/**
* Reset `lasterror` to its initial state.
*/
private resetLastError;
/**
* Store an error as the current MATLAB/Octave last-error state.
*
* Caught errors must be visible to `lasterr`/`lasterror` while the `catch`
* block executes, matching Octave's documented try/catch behavior and the
* legacy MATLAB diagnostic APIs.
*/
private rememberLastError;
/**
* Normalize a user-provided error structure for storage in `lasterror`.
*
* MATLAB/Octave accept structures with any subset of the public fields and
* fill missing fields with defaults. Present `message` and `identifier`
* fields must still be character values because they are consumed by
* `rethrow` and catch-state introspection.
*/
private normalizeLastErrorStruct;
/**
* Implement `lasterror`, `lasterror("reset")`, and `lasterror(err)`.
*/
private lastErrorResult;
/**
* Implement `lasterr`, the message/id companion to `lasterror`.
*/
private lastErrorMessageResult;
/**
* Store the warning state returned by `lastwarn`.
*
* @param message Warning message.
* @param identifier Optional warning identifier.
*/
private setLastWarning;
/**
* Reset warning state to the MATLAB/Octave default.
*/
private resetWarningState;
/**
* Return the effective warning state for an identifier.
*/
private warningState;
/**
* Test whether a string is a supported warning state.
*/
private isWarningState;
/**
* Build the structure returned by `warning("query", id)`.
*/
private warningStateStruct;
/**
* Build a MATLAB/Octave warning-state snapshot.
*
* The first element always represents the global `all` state. Additional
* entries record warning identifiers that differ from the global default or
* that were explicitly modified during this interpreter session, matching
* the save/restore workflow of `s = warning; warning(s)`.
*/
private warningStateSnapshot;
/**
* Read a MATLAB/Octave warning-state structure.
*/
private warningStateStructParts;
/**
* Restore one warning state entry.
*/
private restoreWarningState;
/**
* Restore warning state from a MATLAB/Octave-style structure scalar or array.
*/
private restoreWarningStateStruct;
/**
* Apply `warning` state/query commands when the argument pattern matches.
*/
private warningControlResult;
/**
* Split diagnostic arguments into optional identifier, format, and values.
*
* A leading string containing `:` is treated as a message identifier when a
* second string is present. Otherwise the first string is the message format.
*/
private diagnosticMessageParts;
/**
* Convert command-form diagnostic words to function-form arguments.
*
* `warning id:tag message words` and `error id:tag message words` map to
* identifier/message calls, while ordinary words map to one message string.
*/
private diagnosticCommandArguments;
/**
* Implement the public `warning` built-in subset.
*
* The current browser-first runtime records warning state instead of
* writing to a console or warning manager. This supports the common message
* and identifier/message forms, a small diagnostic formatting subset, and
* the common `on`/`off`/`query` state controls.
*
* @param args Evaluated built-in arguments.
* @returns Void node because warnings do not produce expression output.
*/
private warningResult;
/**
* Implement the public `error` built-in subset.
*
* Supported MATLAB/Octave forms are `error(message)`,
* `error(identifier, message)`, and formatted variants of those forms. The
* thrown error keeps the current call stack through `Context.throwEvalError`,
* and the optional identifier is attached for `catch ME` and `lasterror`.
*
* @param args Evaluated error arguments.
*/
private errorResult;
/**
* Decide whether an `assert` call is the condition/message form.
*/
private assertUsesDiagnosticForm;
/**
* Extract numeric elements for tolerance-based `assert` comparison.
*/
private assertNumericElements;
/**
* Test numerical equality using Octave-style absolute/relative tolerance.
*/
private assertValuesEqualWithinTolerance;
/**
* Split comparison-form `assert` arguments into comparison and diagnostic
* parts.
*/
private assertComparisonParts;
/**
* Implement `assert(actual, expected[, tolerance][, message...])`.
*/
private assertComparisonResult;
/**
* Implement the public `assert` built-in subset.
*
* MATLAB/Octave treat a false condition as an error and pass the remaining
* arguments through the same identifier/format pipeline used by `error`.
*/
private assertResult;
/**
* Extract MATLAB text-list arguments accepted by validation functions.
*
* The documented APIs accept a character vector, string scalar, string
* array, or cell array of character vectors. The interpreter stores each as
* `CharString` elements, so this helper normalizes the public forms without
* losing order.
*/
private validationTextList;
/**
* Extract one text item from a mixed MATLAB validation cell array.
*/
private validationTextItem;
/**
* Return raw validation-list items, preserving non-text parameters.
*/
private validationListItems;
/**
* Implement MATLAB's unique-prefix, case-insensitive `validatestring`.
*/
private validatestringResult;
/**
* Build the optional function/variable context used by `validatestring`.
*/
private validatestringDiagnosticPrefix;
/**
* Map public `validateattributes` attribute names to shared validator keys.
*/
private validateattributesValidator;
/**
* Return dimensions as `validateattributes` should see them.
*
* The runtime stores both character vectors and string scalars in
* `CharString`; MATLAB treats string scalars as `1x1`, while character
* vectors remain `1xN`.
*/
private validateattributesDimensions;
/**
* Return real numeric elements for attributes that inspect values directly.
*/
private validateattributesRealNumericElements;
/**
* Extract a real numeric scalar used as a `validateattributes` parameter.
*/
private validateattributesNumericScalar;
/**
* Extract a real numeric vector used by `validateattributes('size', ...)`.
*/
private validateattributesNumericVector;
/**
* Test all numeric elements of a value against a scalar comparison.
*/
private validateattributesNumericComparison;
/**
* Test MATLAB/Octave monotonic attributes independently for each stored
* column. `MultiArray` stacks pages in the physical row axis, so each
* page-stride row group represents the rows of one logical page.
*/
private validateattributesMonotonicColumns;
/**
* Test non-parameterized `validateattributes` attributes not covered by the
* shared validator table.
*/
private validateattributesSpecialAttribute;
/**
* Test one shared `validateattributes` validator with public string-scalar
* shape semantics.
*/
private validateattributesMatchesValidator;
/**
* Apply one parameterized `validateattributes` attribute.
*/
private validateattributesParameterizedAttribute;
/**
* Build the subject text used by `validateattributes` diagnostics.
*/
private validateattributesSubject;
/**
* Test a `validateattributes` class constraint against runtime values.
*/
private validateattributesMatchesClass;
/**
* Implement the common MATLAB/Octave `validateattributes` forms.
*
* The browser runtime has no sparse storage type; sparse-compatible APIs are
* kept explicit through the shared validator, where `sparse` always fails
* and `nonsparse` always succeeds.
*/
private validateattributesResult;
/**
* Return supported public `mustBe*` call arity limits.
*/
private mustBeArity;
/**
* Implement public MATLAB `mustBe*` validator functions.
*/
private mustBeResult;
/**
* Build registry entries for public `mustBe*` validators.
*/
private mustBeFunctionEntries;
/**
* Normalize command-form results returned by host-provided integrations.
*
* External command handlers often return plain JavaScript primitives. The
* interpreter boundary converts those values into ordinary runtime nodes so
* command-form parsing can be used safely by browser-hosted commands such
* as `help`.
*/
private commandWordListResult;
/**
* Implement `rethrow(ME)` for MATLAB/Octave-style caught error structs.
*
* The current runtime represents `catch ME` as a structure with `message`,
* `identifier`, and `stack` fields. `rethrow` validates that shape and
* raises a new evaluation error while preserving the public message and
* identifier fields used by subsequent `catch` blocks and `lasterror`.
*
* @param errorStruct Error structure captured by a `catch` identifier.
*/
private rethrowResult;
/**
* Implement `lastwarn` getter/setter behavior.
*
* With no arguments it returns the current message and identifier. With one
* or two string arguments it updates the stored warning state before
* returning it, matching the MATLAB/Octave convention used by tests and
* user code.
*
* @param args Optional message and identifier setter arguments.
* @returns Comma-separated return list `[message, identifier]`.
*/
private lastWarningResult;
/**
* Implement MATLAB/Octave `deal` output distribution.
*
* With one input, every requested output receives that value. With multiple
* inputs, a scalar-output call returns the first value; multiple-output
* calls must match the input count and distribute values positionally.
*/
private dealResult;
/**
* Read one positive integer index for output-selection helpers.
*/
private positiveIntegerIndex;
/**
* Read scalar or vector output indexes for `nthargout`.
*/
private nthargoutIndexes;
/**
* Resolve the callable argument accepted by `nthargout`.
*/
private nthargoutCallable;
/**
* Implement Octave-compatible `nthargout`.
*/
private nthargoutResult;
/**
* Validate one evaluated value before exposing it as an ordinary expression.
*/
private expressionValue;
/**
* Validate an evaluated value that must be stored in runtime data
* containers such as structures.
*/
private runtimeExpressionValue;
/**
* Evaluate an expression, reduce return-list carriers, and validate the
* resulting value before it crosses an interpreter expression boundary.
*/
private evaluatedExpressionValue;
/**
* Evaluate one executable AST node and normalize lazy return-list carriers.
*
* This is intentionally broader than `evaluatedExpressionValue`: block and
* top-level execution may legitimately produce `LIST`, `VOID`, or control
* carrier nodes that are not ordinary expression values.
*/
private evaluatedExecutionResult;
/**
* Read a scope entry and validate it before reusing it as an expression.
*/
private scopedExpressionValue;
/**
* Read a scope entry that must contain a native array value.
*/
private scopedMultiArrayValue;
/**
* Validate evaluated variadic call arguments before forwarding them.
*
* @param values Runtime arguments after ordinary evaluator reduction.
* @param prefix Diagnostic prefix used to identify the failing argument.
* @returns Arguments narrowed to expression values.
*/
private callArgumentValues;
/**
* Validate a built-in control argument that must be a character string.
*
* @param value Candidate argument.
* @param name Diagnostic role name.
* @returns Validated character string.
*/
private charControlArgument;
/**
* Validate a list whose elements must all be character strings.
*
* MATLAB Set/Get APIs accept property-name cell arrays. This helper keeps
* the cell-content validation explicit after `MultiArray.linearize`.
*
* @param values Candidate cell contents.
* @param name Diagnostic role name.
* @returns The same values narrowed to character strings.
*/
private charStringList;
/**
* Validate a built-in control argument that must be a function handle.
*
* @param value Candidate argument.
* @param name Diagnostic role name.
* @returns Validated function handle.
*/
private functionHandleControlArgument;
/**
* Validate an optional boolean-like control argument.
*
* @param value Candidate argument.
* @param name Diagnostic role name.
* @returns JavaScript boolean following MATLAB/Octave truthiness.
*/
private booleanControlArgument;
/**
* Validate worker-count expressions accepted by sequential parallel fallbacks.
*
* MATLAB requires `parfor(..., M)` to use a nonnegative integer worker
* limit. `spmd(n)` and `spmd(m,n)` use the same numeric count shape, with
* zero selecting local execution in environments without workers.
*
* @param value Evaluated worker-count expression.
* @param name Diagnostic role name.
* @returns Validated worker count.
*/
private workerCountControlArgument;
/**
* Validate runtime values before forwarding them to user-defined class methods.
*/
private classMethodArgumentValues;
/**
* Invoke one class instance method and reduce lazy return-list carriers at
* the class-dispatch boundary.
*/
private reducedClassMethodResult;
/**
* Invoke one class method with an explicit output count and reduce the
* scalar result expected by helper protocols such as `numArgumentsFromSubscript`.
*/
private reducedClassMethodResultWithOutputCount;
/**
* Validate the object returned by class `subsasgn` overloads.
*/
private classSubsasgnResult;
/**
* Normalize a value produced by assignment RHS evaluation before storing it
* into a name, field, or object property.
*/
private reducedAssignmentValue;
/**
* Normalize and validate an assignment RHS before storing it in a runtime
* structure field.
*/
private structureAssignmentValue;
/**
* Store a field-assignment value, scattering compound structure-array
* results when the operation produced one value per target element.
*/
private assignStructureFieldValue;
/**
* Reduce values produced by scalar indexing/dispatch paths before checking
* their runtime shape or class.
*/
private reducedIndexingResult;
/**
* Validate and linearize values before assigning them to object arrays.
*/
private assignmentValues;
/**
* Validate a sequence before storing it in an AST expression list.
*/
private expressionList;
/**
* Validate and linearize an expression value without crossing the generic
* `MathObject` operation surface.
*/
private linearExpressionValues;
/**
* Validate and copy one expression value through the runtime copy protocol.
*/
private copyExpressionValue;
/**
* Expand a `for` loop expression into the sequence assigned to the target.
*
* MATLAB/Octave `for` assignment iterates over columns. Numeric row vectors
* and scalars produce scalar loop values, while matrices and cell arrays
* produce one column value per iteration. Cell columns remain cell arrays;
* their contents are not unwrapped by the loop assignment.
*
* @param value Evaluated loop expression.
* @param target Loop assignment target.
* @returns Values assigned on each loop iteration.
*/
private forLoopValues;
/**
* Build the value assigned by one `for` iteration.
*
* Scalar targets receive a copied expression value. Row-vector targets use
* a lazy return list so multi-target loop assignments can request each
* element independently, matching the same comma-separated-list machinery
* used elsewhere in the interpreter.
*
* @param target Loop assignment target.
* @param value Iteration value to assign.
* @returns Scalar assignment value or lazy return-list carrier.
*/
private forLoopAssignmentValue;
/**
* Validate the subset of MATLAB `parfor` semantics that remains meaningful
* for the browser's sequential fallback execution.
*
* Unlike ordinary `for`, MATLAB `parfor` uses a simple loop variable and a
* consecutive integer iteration vector. The runtime still executes
* sequentially, but it rejects shapes that would not be valid parallel loop
* headers.
*
* @param target Loop assignment target from the parser.
* @param value Evaluated loop expression.
*/
private validateParforHeader;
/**
* Validate `parfor` body restrictions that can be checked from the AST.
*
* The sequential browser fallback keeps execution deterministic, but the
* accepted source must still respect MATLAB `parfor` structural rules so
* code does not become valid here and invalid in MATLAB/Octave-compatible
* environments.
*
* @param body Loop body to inspect.
* @param loopVariable Simple loop variable name.
*/
private validateParforBody;
/**
* Validate `spmd` body restrictions that remain relevant for the browser's
* single-worker fallback.
*
* MATLAB rejects several control-flow and parallel constructs inside
* `spmd` blocks because workers execute separately from the client
* workspace. MathJSLab executes the block sequentially, but preserving the
* structural restrictions prevents non-portable code from being accepted.
*
* @param body SPMD body to inspect before execution.
*/
private validateSpmdBody;
/**
* Clone an assignment target while preserving only expression-compatible shapes.
*
* Assignment lowering can duplicate identifiers, indexing chains, indirect
* references, and runtime values before the actual write occurs. Every
* cloned branch is routed back through the expression boundary so malformed
* statement/control-flow nodes cannot enter the assignment pipeline.
*
* @param target Assignment target or runtime value to clone.
* @returns Copied target constrained to expression position.
*/
private cloneAssignmentTarget;
/**
* Validate values before exposing them through an interpreter-owned comma
* separated return list.
*/
private returnListValue;
/**
* Create a lazy comma-separated return list from already evaluated values.
*
* Values are validated only when selected so the return list can honor the
* caller-requested output count while still rejecting non-expression values
* before they cross an expression boundary.
*
* @param values Candidate output values.
* @returns Lazy comma-separated return list.
*/
private valueReturnList;
/**
* Convert comma-separated values into a row vector for scalar operations.
*
* Native brace and structure-field descriptor chains may return a lazy
* comma-separated list. Compound assignments need an expression value that
* can participate in `+`, `-`, etc., so the selected list is materialized in
* the same row-vector shape used by explicit concatenation contexts.
*/
private compoundAssignmentOperand;
/**
* Read the assigned value from an internal assignment-result list.
*/
private nestedAssignmentValue;
/**
* Parse and evaluate source text in a specific scope.
*
* This is shared by `eval`/`evalin` and deliberately creates a transient
* call-stack frame so introspection and argument helpers observe the scope
* in which the string is evaluated.
*
* @param source Source code to parse.
* @param scope Scope used for evaluation.
* @returns Evaluated result tree or runtime value.
*/
private evalStringInScope;
/**
* Determine whether an error can be handled by an `eval` catch string.
*
* MATLAB/Octave control-flow signals must propagate through `eval`; only
* ordinary runtime errors are catchable by the optional catch source.
*
* @param error Error or control-flow signal thrown by evaluation.
* @returns `true` when the catch string may handle the error.
*/
private isEvalCatchableError;
/**
* Evaluate source like `eval` while returning captured display text first.
*
* MATLAB `evalc` returns command-window output in the first result and the
* evaluated expression outputs in subsequent result slots. The engine has
* no separate command-window stream, so capture uses the same textual
* representation that top-level evaluation would expose through `Unparse`.
*
* @param source Source code to parse and evaluate.
* @param catchSource Optional catch source evaluated after ordinary errors.
* @returns Captured output string, optionally followed by evaluated outputs.
*/
private evalcResult;
/**
* Extract top-level class definitions from a parsed source tree.
*
* Host-provided class sources are parsed as ordinary snippets; this helper
* isolates classdef nodes without executing unrelated statements.
*
* @param tree Parsed source tree.
* @returns Top-level class definitions in source order.
*/
private topLevelClassDefinitions;
/**
* Extract top-level function definitions from a parsed source tree.
*
* This is used by function-file loading and script-local function
* pre-registration, keeping MATLAB/Octave function discovery separate from
* statement execution.
*
* @param tree Parsed source tree.
* @returns Top-level function definitions in source order.
*/
private topLevelFunctionDefinitions;
/**
* Parse a host-provided function-file source.
*
* The selected primary function is renamed to the requested canonical name
* so package/import aliases can load source supplied under a fully
* qualified runtime name while preserving MATLAB/Octave function-file
* lookup behavior.
*
* @param name Canonical function name requested by lookup.
* @param source Source text containing one primary function and optional subfunctions.
* @returns Primary function plus private subfunctions.
*/
private parseFunctionSource;
/**
* Resolve function-file source through the configured host tables/providers.
*
* @param name Canonical function name requested by lookup.
* @returns Normalized source entry, if the host can supply one.
*/
private resolveFunctionSource;
/**
* Test whether a semantically valid host-provided function source exists.
*
* The probe parses and validates the source without registering it, so
* introspection such as `exist` and `which` cannot mutate the runtime.
*
* @param name Function name requested by lookup.
* @returns `true` when a loadable function source is available.
*/
private hasFunctionSource;
/**
* Resolve and validate a function source without registering it.
*
* This mirrors the static checks performed by lazy function loading:
* primary-function matching, declaration placement, signature validation,
* `arguments` blocks, and duplicate subfunction names.
*
* @param name Function name requested by lookup.
* @returns Normalized source entry, or `undefined` when unavailable/invalid.
*/
private validFunctionSource;
/**
* Validate a parsed function file before it is reported or registered.
*
* Host probes and lazy loading both use this single gate so externally
* supplied primary functions, subfunctions, and class method files obey the
* same signature and `arguments`-block rules.
*
* @param primary Primary function selected from the file.
* @param subfunctions Private top-level subfunctions from the same source.
* @param duplicateContext Source label used in duplicate-function diagnostics.
*/
private validateFunctionFileDefinitions;
/**
* Register a parsed function-file definition in a target scope.
*
* The primary function is visible from the caller scope. Subfunctions are
* stored in the primary function's file scope so they remain private to the
* loaded function file, which matches MATLAB/Octave file scoping.
*
* @param primary Primary function definition.
* @param subfunctions Private top-level subfunctions from the same source.
* @param scope Scope receiving the primary function.
* @returns Registered primary function definition.
*/
private registerFunctionFileDefinition;
/**
* Load a MATLAB/Octave-like function file from host-provided source text.
*
* The primary function is exported to the target scope. Additional
* top-level function definitions become private subfunctions visible only
* through the primary function's file scope.
*
* @param name Canonical primary function name.
* @param source Source text containing the function file.
* @param scope Scope that receives the primary function.
* @returns Registered primary function definition.
*/
LoadFunctionFile(name: string, source: string, scope?: Scope, sourceName?: string): NodeFunctionDefinition;
/**
* Resolve and register a function definition through host-provided sources.
*
* @param name Function name requested by lookup.
* @param scope Scope that should receive the loaded primary function.
* @returns Registered function definition, or `undefined` when unavailable.
*/
loadFunctionDefinition(name: string, scope: Scope): NodeFunctionDefinition | undefined;
/**
* Resolve script source through the configured host tables/providers.
*
* @param name Script name requested by lookup.
* @returns Normalized source entry, if the host can supply one.
*/
private resolveScriptSource;
/**
* Test whether a semantically valid host-provided script source exists.
*
* The script is parsed and checked for declaration-placement violations,
* but it is not executed and script-local functions are not registered.
*
* @param name Script name requested by lookup.
* @returns `true` when a runnable script source is available.
*/
private hasScriptSource;
/**
* Resolve and validate a script source without executing it.
*
* @param name Script name requested by lookup.
* @returns Normalized source entry, or `undefined` when unavailable/invalid.
*/
private validScriptSource;
/**
* Execute a parsed script while temporarily exposing script-local functions.
*
* @param tree Parsed script source tree.
* @param scope Workspace where script statements execute.
* @returns Evaluated script result.
*/
private executeScriptTree;
/**
* Execute MATLAB/Octave-like script source in a workspace.
*
* Script-local functions are visible while the script executes and hidden
* afterward. Function handles created by the script keep captured closures,
* so they remain callable even after the temporary function table is
* restored.
*
* @param name Script name used for diagnostics.
* @param source Source text containing the script.
* @param scope Workspace where script statements execute.
* @param sourceName Optional virtual source identity for script-local functions.
* @returns Evaluated script result.
*/
LoadScriptFile(name: string, source: string, scope?: Scope, sourceName?: string): NodeInput;
/**
* Resolve and execute a host-provided script file by name.
*
* @param name Script name or `.m` filename.
* @param scope Workspace where script statements execute.
* @returns Evaluated script result.
*/
RunScriptFile(name: string, scope?: Scope): NodeInput;
/**
* Parse a host-provided class source and select the requested classdef.
*
* @param name Canonical class name requested by lookup.
* @param source Source text containing the classdef.
* @returns Classdef AST node with canonical runtime name.
*/
private parseClassSource;
/**
* Parse a class source if it contains the requested classdef.
*
* @param name Canonical class name requested by lookup.
* @param source Source text containing a possible classdef.
* @returns Matching classdef AST node, or `undefined` when the source is not a classdef file.
*/
private tryParseClassSource;
/**
* Test whether source text looks like a function/method file rather than a classdef file.
*
* Class lookup probes can reach sibling `@Class/method.m` files while
* resolving qualified member chains. Function-only sources should decline
* class loading quietly so the shorter class prefix can be selected.
*
* @param source Source text to inspect.
* @returns `true` when the source contains top-level functions and no classdef.
*/
private isFunctionOnlySource;
/**
* Parse a host-provided class method source selected by a classdef prototype.
*
* MATLAB/Octave allow classdef files to declare method signatures while
* concrete bodies live in sibling `@Class/method.m` files. The primary
* function is stored under the prototype method name so class metadata and
* stack traces keep the source-level method spelling.
*
* @param className Canonical class name that owns the prototype.
* @param methodName Method name declared in the classdef prototype.
* @param sourceName Canonical source entry name resolved by the host.
* @param source Source text containing one method function and optional private subfunctions.
* @returns Primary method plus private subfunctions.
*/
private parseClassMethodSource;
/**
* Resolve class source through the configured host tables/providers.
*
* @param name Canonical class name requested by lookup.
* @returns Normalized source entry, if the host can supply one.
*/
private resolveClassSource;
/**
* Test whether a host class source is available without parsing/registering it.
*
* Lookup helpers such as `exist` and `which` should report browser-provided
* class sources without mutating the runtime class registry, otherwise a
* metadata query can change later function/class precedence.
*
* @param name Canonical class name requested by lookup.
* @returns `true` when the configured resolver can provide class source.
*/
private hasClassSource;
/**
* Resolve and validate a class source without registering it.
*
* The check is intentionally local: it rejects malformed classdef metadata
* while avoiding superclass resolution, dependency loading, and mutations
* to the class registry.
*
* @param name Class name requested by lookup.
* @returns Normalized source entry, or `undefined` when unavailable/invalid.
*/
private validClassSource;
/**
* Attach a virtual source identity to methods declared inside a loaded classdef.
*
* External `@Class/method.m` files receive their own identity when they are
* materialized. Inline methods in a host-provided classdef share the class
* file identity, matching MATLAB/Octave source-level introspection.
*/
private attachClassDefinitionSourceName;
/**
* Resolve and register a class definition through host-provided sources.
*
* @param name Class name requested by lookup.
* @param scope Scope used to resolve superclass dependencies.
* @returns Loaded class definition, or `undefined` when unavailable.
*/
loadClassDefinition(name: string, scope: Scope): ClassDefinition | undefined;
/**
* Resolve a concrete method body for a classdef prototype.
*
* The lookup key is `ClassName.methodName`, which maps naturally to
* browser-hosted paths such as `+pkg/@Class/method.m` through the shared
* class-source resolver.
*
* @param className Canonical class name.
* @param methodName Method prototype name.
* @param scope Scope used as parent for the method-file private scope.
* @returns Loaded method body, or `undefined` when no external method file exists.
*/
loadClassMethodDefinition(className: string, methodName: string, scope: Scope): NodeFunctionDefinition | undefined;
/**
* Convert a dotted identifier chain into name parts when it is purely symbolic.
*
* @param tree Dotted reference node.
* @returns Qualified name parts, or `undefined` for dynamic field access.
*/
private qualifiedReferenceParts;
/**
* Resolve static class members, constants, and enumeration members.
*
* @param definition Class definition that matched the qualified prefix.
* @param fields Remaining field chain after the class name.
* @param scope Evaluation scope for constant defaults and enumeration arguments.
* @returns Runtim