UNPKG

mathjslab

Version:

MathJSLab - An interpreter with language syntax like MATLAB®/Octave, ISBN 978-65-00-82338-7.

974 lines (973 loc) 39.7 kB
import type { AliasNameTable, BuiltInFunctionInputSignature, BuiltInFunctionSignature, ExpressionBoundaryValue, NameEntry, NodeBuiltInFunction, NodeExpr, NodeInput, NodeFunctionDefinition, RuntimeExpressionValue } from './AST'; import type { ClassMethodDefinition as ClassMethodDefinitionBase } from './ClassMember'; import { CharString } from './CharString'; import { type ComplexType } from './Complex'; import { MultiArray } from './MultiArray'; import { ClassDefinition } from './ClassDefinition'; import { ClassInstance } from './ClassInstance'; import { ClassBoundMethod } from './ClassBoundMethod'; import { ClassStaticMethod } from './ClassStaticMethod'; import { ClassEmptyMethod } from './ClassEmptyMethod'; import type { BinaryMathOperation, KeyOfTypeOfMathOperation, UnaryMathOperation } from './MathOperation'; import { Scope } from './Scope'; import { CallFrame } from './CallFrame'; import { type Callable } from './Callable'; import type { CallArgumentValue } from './FunctionCall'; type ClassMethodDefinition = ClassMethodDefinitionBase<ClassDefinition>; /** * Interpreter services used by `Context`. * * Keeping this as a narrow structural interface avoids a hard cycle between the * execution context and the full interpreter implementation while still letting * the context call back into parsing/evaluation-sensitive operations. */ interface ContextInterpreter { /** Whether debug tracing is enabled for call/index dispatch. */ debug: boolean; /** Evaluate one AST/runtime node in a scope. */ Evaluator(tree: NodeInput, scope?: Scope): NodeInput; /** Return parameters backed exclusively by name-value declarations. */ getFunctionNameValueParameters(func: NodeFunctionDefinition): Set<string>; /** Split call-site expressions into positional and name-value groups. */ splitFunctionCallNameValueArguments(func: NodeFunctionDefinition, args: CallArgumentValue[]): { positional: CallArgumentValue[]; named: Map<string, CallArgumentValue>; }; /** Return default input expressions keyed by parameter name. */ getFunctionInputArgumentDefaults(func: NodeFunctionDefinition): Map<string, NodeExpr>; /** Return the `arguments (Output,Repeating)` output name, when present. */ getFunctionOutputRepeatingName(func: NodeFunctionDefinition): string | undefined; /** Bind evaluated name-value arguments into a function call scope. */ bindFunctionNameValueArguments(func: NodeFunctionDefinition, scope: Scope, values: Map<string, ExpressionBoundaryValue>): void; /** Preprocess imports that apply to an entire script/function scope. */ applyScopedImports(tree: NodeInput, scope: Scope): void; /** Register nested functions visible from a function body. */ registerNestedFunctions(func: NodeFunctionDefinition, scope: Scope): void; /** Validate input `arguments` blocks after inputs are bound. */ validateFunctionInputArguments(func: NodeFunctionDefinition, scope: Scope): void; /** Validate `arguments (Repeating)` declarations against `varargin`. */ validateFunctionRepeatingArguments(func: NodeFunctionDefinition, scope: Scope, values: ExpressionBoundaryValue[]): void; /** Validate output `arguments` blocks after the body executes. */ validateFunctionOutputArguments(func: NodeFunctionDefinition, scope: Scope, requestedOutputCount: number, outputMask?: boolean[]): void; /** Validate property defaults for a newly instantiated class object. */ validateClassInstancePropertyDefaults(instance: ClassInstance, scope: Scope): void; /** Resolve a function source through the configured function provider API. */ loadFunctionDefinition(name: string, scope: Scope): NodeFunctionDefinition | undefined; /** Resolve a class source through the configured class provider API. */ loadClassDefinition(name: string, scope: Scope): ClassDefinition | undefined; /** Resolve a class method source for a prototype declared in a classdef block. */ loadClassMethodDefinition(className: string, methodName: string, scope: Scope): NodeFunctionDefinition | undefined; /** Resolve a static class method selected by qualified name or visible imports. */ resolveStaticMethod(name: string, scope: Scope): ClassStaticMethod | undefined; /** Dispatch a functional operator call through class overload semantics, when applicable. */ callFunctionalOperatorOverload(node: NodeBuiltInFunction, args: CallArgumentValue[], parent: NodeInput): NodeExpr | undefined; /** Convert object values used as native array indices through `subsindex`. */ convertIndexArgument(value: NodeInput, parent: NodeInput): NodeInput; } /** * Kinds of MATLAB/Octave symbols that can be resolved from a name. */ type SymbolResolutionKind = 'variable' | 'class' | 'function' | 'builtin' | 'script' | 'directory'; /** * Source tier that produced a resolved symbol. */ type SymbolResolutionSource = 'local' | 'import' | 'builtin'; /** * Options that tune name lookup while keeping the default MATLAB/Octave * precedence intact. */ type SymbolResolutionOptions = { /** Whether variable bindings should be considered. */ variables?: boolean; /** Whether class definitions should be considered. */ classes?: boolean; /** Whether class source providers may be loaded as part of class lookup. */ loadClasses?: boolean; /** Whether function source providers may be loaded as part of function lookup. */ loadFunctions?: boolean; /** Whether user functions and built-ins should be considered. */ functions?: boolean; /** Whether imported simple-name candidates may be considered. */ imports?: boolean; }; /** * Structured result for one resolved name. */ type SymbolResolution = { /** Symbol category selected by name precedence. */ kind: SymbolResolutionKind; /** Name requested by the caller. */ name: string; /** Canonical name actually resolved after aliases/imports. */ resolvedName: string; /** Lookup tier that produced the result. */ source: SymbolResolutionSource; /** Variable entry when {@link kind} is `variable`. */ entry?: NameEntry; /** Class definition when {@link kind} is `class`. */ classDefinition?: ClassDefinition; /** Function node when {@link kind} is `function` or `builtin`. */ functionDefinition?: NodeFunctionDefinition | NodeBuiltInFunction; /** Virtual `.m` source identity when lookup only materialized source metadata. */ sourceName?: string; }; /** * Kinds of call/index dispatch selected after a callee expression is evaluated. */ type CallDispatchKind = 'callable' | 'bound-method' | 'bound-method-array' | 'static-method' | 'empty-method' | 'constructor' | 'functional-class-method' | 'undefined-function' | 'indexing'; /** * Structured call/index dispatch decision. */ type CallDispatch = { kind: 'callable'; callable: Callable; expr: NodeExpr; } | { kind: 'bound-method'; expr: ClassBoundMethod; } | { kind: 'bound-method-array'; expr: MultiArray; } | { kind: 'static-method'; expr: ClassStaticMethod; } | { kind: 'empty-method'; expr: ClassEmptyMethod; } | { kind: 'constructor'; expr: ClassDefinition; } | { kind: 'functional-class-method'; expr: NodeExpr; functionalName: string; functionalReceiver: NodeInput; } | { kind: 'undefined-function'; expr: NodeExpr; functionalName: string; } | { kind: 'indexing'; expr: NodeExpr; }; /** * Internal control-flow signal used to leave a function body on `return`. */ declare class ReturnSignal extends Error { constructor(); } /** * Internal control-flow signal used to leave loop bodies on `break`. */ declare class BreakSignal extends Error { constructor(); } /** * Internal control-flow signal used to continue loop bodies on `continue`. */ declare class ContinueSignal extends Error { constructor(); } /** * Execution context for MathJSLab evaluation. * * `Context` owns the call stack, global workspace, built-in table, arity state, * comma-separated-list expansion state, class access stack, and MATLAB-like * workspace helpers. The interpreter owns AST traversal and delegates runtime * mechanics here so function calls, built-ins, class dispatch, and diagnostics * share one consistent state model. */ declare class Context { /** * Interpreter instance associated to this context. */ interpreter?: ContextInterpreter | undefined; /** * Global scope. */ globalScope?: Scope | undefined; /** * Built-in function table. */ builtInFunctionTable: Record<string, NodeBuiltInFunction>; /** * Whether assignments may keep unresolved identifiers for later resolution. */ allowForwardReference: boolean; /** * Names declared as global in the current context. */ globalNameSet: Set<string>; /** * Global names initialized by Octave-style `global name = value` * declarations during this context lifetime. */ globalInitializedNameSet: Set<string>; /** * Assignment targets whose right-hand side is currently being evaluated. * * This stack lets undefined-reference handling distinguish a local * forward reference from a dependency cycle such as `A -> B -> A`. */ private forwardReferenceTargetStack; /** * Requested output counts for expressions currently being evaluated. */ private requestedOutputCountStack; /** * Per-output request masks for expressions currently being evaluated. */ private requestedOutputMaskStack; /** * Whether the current evaluation context should expand comma-separated lists. */ private commaListExpansionStack; /** * Classes whose method bodies are currently executing. */ private classAccessStack; /** Built-ins that MATLAB/Octave users commonly invoke without parentheses. */ private static readonly bareZeroArgumentBuiltins; /** * Built-in function names that are also operator method names. * * Direct calls such as `lt(a,b)` and handles such as `f = @plus; f(a,b)` * must give class operands the same overload opportunity as symbolic * operators (`a < b`, `a + b`). Keeping the list here avoids importing * `MathOperation` as a runtime value into `Context`. */ private static readonly operatorFunctionNames; /** * Built-ins whose MATLAB class implementations are ordinary instance * methods when the first argument is an object. */ private static readonly classBuiltinMethodFunctionNames; /** * Function call stack. */ callStack: CallFrame[]; /** * Reset the execution context to a provided scope/stack or to a fresh global state. * * @param globalScope Optional global scope to install. * @param callStack Optional call stack to install. */ loadContext(globalScope?: Scope, callStack?: CallFrame[]): void; /** * Private constructor (only used by `create` static method). * @param globalScope Optional global scope reference. * @param callStack Optional function call stack reference. */ private constructor(); /** * Create {@link Context} object. * @param interpreter Optional interpreter instance associated with the context. * @param globalScope Optional global scope reference. * @param callStack Optional function call stack reference. * @returns New interpreter context. */ static readonly create: (interpreter?: ContextInterpreter, globalScope?: Scope, callStack?: CallFrame[]) => Context; /** * Native constants inserted into the global name table during interpreter loading. */ nativeNameTable: Record<string, ComplexType>; /** * Names provided by {@link nativeNameTable}. */ nativeNameSet: Set<string>; /** * Alias name table. */ private aliasNameTable; /** * Alias name function. This property is set at Interpreter instantiation. * @param name Alias name. * @returns Canonical name. */ aliasNameFunction: (name: string) => string; /** * Configure aliases that map alternative spellings to canonical function names. * @param aliasNameTable Alias patterns keyed by canonical names. */ setAliasNameTable(aliasNameTable?: AliasNameTable): void; /** * Get a list of names of defined functions in builtInFunctionTable. */ get builtInFunctionList(): string[]; /** * Current frame (top of call stack) getter. */ get currentFrame(): CallFrame | undefined; /** * Current scope (top of call stack) getter. */ get currentScope(): Scope; /** * Resolve a variable name from the current scope chain. * @param name Identifier to resolve. * @returns Matching name entry, or `undefined` when not found. */ resolveName(name: string): NameEntry | undefined; /** * Resolve a name using the current MATLAB/Octave-like precedence model. * * The default order is variable, registered class, local/provider function, * host-loadable class, explicit/wildcard imports for class/function * candidates, and finally built-ins. Returning a structured result keeps * this order visible to dispatch, `exist`, `which`, and future * filesystem-like lookup work. * * @param name Name requested by source code. * @param scope Lookup scope. * @param options Optional switches for focused lookup callers. * @returns Structured resolution result, if any. */ resolveSymbol(name: string, scope?: Scope, options?: SymbolResolutionOptions): SymbolResolution | undefined; /** * Resolve a function by name from lexical scope, provider API, or built-ins. * * @param name Function name or alias. * @param scope Lookup scope, defaulting to the current scope. * @returns User-defined or built-in function node, if found. */ resolveFunction(name: string, scope?: Scope): NodeFunctionDefinition | NodeBuiltInFunction | undefined; /** * Resolve a class definition by name. * * In-memory class definitions are stored as names. Provider-loaded classes * are registered into the global scope so later lookups reuse the same * metadata object. * * @param name Class name. * @param scope Lookup scope, defaulting to the current scope. * @returns Class definition, if found. */ resolveClassDefinition(name: string, scope?: Scope): ClassDefinition | undefined; private resolveClassDefinitionByExactName; /** * Register one package/class import in a scope. * * @param qualifiedName Fully qualified import name. * @param scope Scope receiving the import. */ defineImport(qualifiedName: string, scope?: Scope): void; /** * Define or replace a variable in the current scope. * * @param name Variable name. * @param value Value to store. */ assignName(name: string, value: NodeInput): void; /** * Validate a resolved variable value before exposing it as an identifier expression. */ private resolvedIdentifierExpression; /** * Keep an unresolved identifier as a call target placeholder. */ private unresolvedCallTargetExpression; /** * Define or replace a user function in the current scope. * * @param name Function name. * @param func Function definition node. */ assignFunction(name: string, func: NodeFunctionDefinition): void; /** * Register a class definition as a named runtime value. * * @param definition Class metadata to register. * @param scope Scope that should receive the class name. * @returns The same class definition for fluent callers. */ defineClassDefinition(definition: ClassDefinition, scope?: Scope): ClassDefinition; /** * Create a child lexical scope. * * @param parent Parent scope, defaulting to the current scope. * @returns New child scope. */ createChildScope(parent?: Scope): Scope; /** * Track assignment targets while their right-hand side is evaluated. * @param targets Assignment target identifiers. */ pushForwardReferenceTargets(targets: string[]): void; /** * Stop tracking the current right-hand-side assignment targets. * @returns Removed target list, if any. */ popForwardReferenceTargets(): string[] | undefined; /** * Track how many outputs the current expression context asks from a call. * @param count Requested output count. */ pushRequestedOutputCount(count: number): void; /** * Stop tracking the current requested output count. * @returns Removed requested output count, if any. */ popRequestedOutputCount(): number | undefined; /** * Track which requested outputs are actually assigned by the caller. * * A `false` entry corresponds to a `~` placeholder in a multiple-output * assignment and is exposed inside user functions through `isargout`. * * @param mask Per-output assignment flags. */ pushRequestedOutputMask(mask: boolean[]): void; /** * Stop tracking the current requested-output mask. * * @returns Removed output mask, if any. */ popRequestedOutputMask(): boolean[] | undefined; /** * Output count requested by the nearest evaluation context. */ get requestedOutputCount(): number; /** * Return per-output assignment flags for the current expression context. * * Contexts without an explicit mask behave as though all requested outputs * were assigned. * * @param count Output count to materialize. * @returns Boolean request mask. */ requestedOutputMask(count?: number): boolean[]; /** * Enter a context where comma-separated lists should expand. * * @param enabled Whether expansion is enabled for the nested evaluation. */ pushCommaListExpansion(enabled?: boolean): void; /** * Leave the current comma-separated-list expansion context. * * @returns Removed expansion flag, if any. */ popCommaListExpansion(): boolean | undefined; /** * Whether the current evaluation context expands comma-separated lists. */ get commaListExpansionEnabled(): boolean; /** * Test class member access against the active class access stack. * * @param classDefinition Class that owns the member. * @param access Effective access string (`public`, `protected`, `private`, or friend list). * @returns `true` when the current class execution context may access the member. */ canAccessClassMember(classDefinition: ClassDefinition, access?: string): boolean; /** * Return the innermost class currently granting method-access privileges. * * This is used by public introspection built-ins such as * `mfilename("class")`; it intentionally exposes only the class name, not * the mutable access stack itself. * * @returns Current executing class name, or an empty string outside class methods. */ currentClassAccessName(): string; private withClassAccess; private get currentForwardReferenceTargets(); /** * Follow unresolved-reference metadata to build a dependency chain. * * Pending expressions can be partially re-linked while forward references * are resolved, so this also inspects the stored expression tree to retain * useful chains such as `A -> B -> C -> A`. */ private getUndefinedReferenceChain; private getNextUndefinedReference; /** * Find the next pending identifier inside a stored expression tree. */ private findPendingIdentifier; /** * Throw when resolving `name` would close an unresolved-reference cycle. */ private throwIfCircularReference; /** * Resolve a value expression to a callable wrapper when possible. * * @param expr Evaluated expression that may be a function handle. * @returns Callable wrapper for function handles, or `undefined`. */ resolveCallable(expr: NodeExpr): Callable | undefined; /** * Resolve an identifier according to MATLAB/Octave name precedence. * * Variables are preferred, followed by call-frame metadata such as * `nargin`, class definitions, functions, and finally undefined-reference * handling. When the identifier is part of a call expression, unresolved * names may remain as call targets for later dispatch. * * @param tree Identifier node. * @param scope Scope used for lookup. * @returns Resolved runtime value or callable placeholder. */ resolveIdentifier(tree: NodeInput, scope: Scope): NodeExpr; /** * Expand a comma-separated return list into individual values. * * Non-list values are reduced to their first return value and wrapped in a * single-element array. This mirrors MATLAB/Octave behavior for cell and * struct comma-separated lists in calls and assignments. * * @param value Evaluated value or return list. * @returns Expanded values. */ expandCommaSeparatedList(value: NodeInput): NodeInput[]; /** * Reduce a non-comma-list value before treating it as one scalar expansion * item. */ private reducedCommaListScalar; /** * Evaluate one call/assignment expression with comma-list expansion enabled. * * @param arg Expression to evaluate. * @returns Expanded values produced by the expression. */ evaluateCommaListExpression(arg: NodeExpr): NodeInput[]; /** * Evaluate and expand a list of positional call arguments. * * @param args Argument expressions. * @returns Expanded argument values retyped for call helpers. */ expandCommaListArguments(args: CallArgumentValue[]): CallArgumentValue[]; /** * Evaluate one call argument with comma-list expansion and expression * validation. */ private evaluateExpandedArgument; private evaluateArgs; /** * Evaluate built-in arguments while preserving MATLAB SetGet `Name=Value` * syntax for the public `set` function. * * General built-ins receive evaluated positional values. `set` is special: * MATLAB treats top-level `Name=Value` arguments as property/value pairs, * not as ordinary assignment expressions. Keeping the conversion here keeps * the behavior local to the built-in dispatch path. * * @param node Built-in function node. * @param args Raw call argument expressions. * @param parent Call-site node used for diagnostics. * @returns Evaluated argument values. */ evaluateBuiltInArgs(node: NodeBuiltInFunction, args: CallArgumentValue[], parent: NodeInput): ExpressionBoundaryValue[]; /** * Throw an evaluation error annotated with the current stack trace. * * @param message Error message. */ throwEvalError(message: string): never; /** * Throw a reference error annotated with the current stack trace. * * @param message Error message. */ throwReferenceError(message: string): never; /** * Throw an undefined-reference error annotated with the current stack trace. * * @param identifier Missing identifier. */ throwUndefinedReferenceError(identifier: string): never; /** * Throw a circular-reference error annotated with the current stack trace. * * @param chain Dependency chain that closes the cycle. */ throwCircularReferenceError(chain: string[]): never; /** * Throw a syntax error annotated with the current stack trace. * * @param message Error message. */ throwSyntaxError(message: string): never; private getCurrentFunctionDefinition; /** * Return whether execution is currently inside a user-defined function. * * Built-in helper frames and temporary eval frames may sit on top of the * stack, so this intentionally searches the stack instead of inspecting * only the current top frame. */ isInsideUserFunction(): boolean; /** * Return the virtual source name of the current user-defined callable. */ currentFunctionSourceName(): string; private getCurrentFunctionCountFrame; private getCallerWorkspace; /** * Resolve a MATLAB-like workspace selector. * * @param name Workspace name such as `base` or `caller`. * @param forAssignment Whether the resolved workspace will be assigned into. * @returns Target scope. */ resolveWorkspace(name: string, forAssignment?: boolean): Scope; /** * Return the current function's input argument count. * * @param name Built-in name used for diagnostics. * @returns Numeric scalar count. */ currentFunctionArgumentCount(name: 'nargin' | 'nargout'): ComplexType; /** * Return the current function's input count, or zero outside a function. */ currentFunctionArgumentCountOrZero(): ComplexType; /** * Return the output count requested from the current function. * * @param name Built-in name used for diagnostics. * @returns Numeric scalar count. */ currentFunctionOutputCount(name: 'nargin' | 'nargout'): ComplexType; /** * Return the current requested output count, or zero outside a function. */ currentFunctionOutputCountOrZero(): ComplexType; /** * Return whether one or more current function outputs are requested. * * `isargout` is true only for output positions within `nargout` whose * caller-side target was not `~`. * * @param indexNode One-based output index or numeric array of indexes. * @returns Logical scalar or array matching the input shape. */ currentFunctionOutputIsRequested(indexNode: NodeInput): NodeInput; /** * Implement `inputname` for the current function frame. * * @param indexNode One-based argument index. * @returns Original caller expression text when available. */ currentFunctionInputName(indexNode: NodeInput, onlyVariableNames?: boolean, unparse?: (arg: ExpressionBoundaryValue) => string): CharString; /** * Return the current function display name. */ currentFunctionName(): string; /** * Declare a persistent variable in the current function. * * @param name Variable name. * @param value Initial value, when supplied by the declaration. * @param scope Function scope receiving the live binding. */ declarePersistent(name: string, value: RuntimeExpressionValue | undefined, scope: Scope): void; /** * Load persistent variables into a function call scope. * * @param func Function definition whose persistent storage should be loaded. * @param scope Function call scope. */ loadPersistentVariables(func: NodeFunctionDefinition, scope: Scope): void; /** * Store persistent variables after a function call completes. * * @param func Function definition whose persistent storage should be updated. * @param scope Function call scope. */ storePersistentVariables(func: NodeFunctionDefinition, scope: Scope): void; /** * Declare a variable as global in a scope. * * @param name Global variable name. * @param value Optional initial value. * @param scope Scope that should reference the global binding. */ declareGlobal(name: string, value: RuntimeExpressionValue | undefined, scope: Scope): void; /** * Clear global bindings from the global scope and active frames. * * @param names Optional subset of global names to clear. */ clearGlobalVariables(names?: string[]): void; /** * Clear loaded class definitions from the global scope and active frames. * * Host/source resolvers are intentionally left untouched so qualified or * imported class names can be loaded again after `clear classes`. */ clearClassDefinitions(): void; /** * Clear ordinary variables from the current workspace. * * Native constants and class definitions are intentionally preserved. The * latter are runtime type metadata rather than user workspace variables. */ clearCurrentVariables(names?: string[]): void; private resolveCallSite; private static debugIdentifier; /** * Return normalized input signatures for a built-in node. * * @param node Built-in function node. * @returns Input signature overloads. */ builtInInputSignatures(node: NodeBuiltInFunction): BuiltInFunctionInputSignature[]; /** * Return normalized output signatures for a built-in node. * * @param node Built-in function node. * @returns Output signature overloads. */ builtInOutputSignatures(node: NodeBuiltInFunction): BuiltInFunctionInputSignature[]; /** * Compute the MATLAB-like declared arity for built-in signatures. * * @param signatures Input or output signature overloads. * @returns Fixed or negative variadic arity, when declared. */ builtInDeclaredArity(signatures: BuiltInFunctionInputSignature[]): number | undefined; validateBuiltInInputArity(node: NodeBuiltInFunction, argCount: number): void; validateBuiltInInputParameters(node: NodeBuiltInFunction, args: NodeInput[]): void; private valueDimensions; private sizeReturnList; /** * Give scalar class objects the normal MATLAB overload opportunity for * selected built-ins before the native implementation runs. * * @param node Built-in function node being invoked. * @param evaluatedArgs Already evaluated call arguments. * @param parent Call-site node used for diagnostics. * @returns Class method result when an accessible overload exists. */ private callClassBuiltinMethod; private callFunctionDefinition; private instantiateClassDefaults; private constructClassInstance; constructSuperclassInstance(instance: ClassInstance, superclassDefinition: ClassDefinition, args: CallArgumentValue[], parent: NodeInput): ClassInstance; private constructClassInstanceWithInstance; /** * Call an instance method with class access and value/handle receiver rules. * * @param instance Receiver object. * @param method Method metadata selected from the class hierarchy. * @param args Explicit method arguments, excluding the receiver. * @param parent Call-site node used for stack traces. * @returns Method return expression or return list. */ callClassInstanceMethod(instance: ClassInstance, method: ClassMethodDefinition, args: CallArgumentValue[], parent: NodeInput): NodeExpr; /** * Validate the implicit object argument passed to instance method bodies. */ private classMethodReceiverArgument; /** * Call a static class method with class access enabled. * * @param method Static method metadata. * @param args Method argument expressions. * @param parent Call-site node used for stack traces. * @returns Method return expression or return list. */ callClassStaticMethod(method: ClassMethodDefinition, args: CallArgumentValue[], parent: NodeInput): NodeExpr; /** * Materialize a concrete class method body from an external method file. * * @param method Method metadata whose AST node may still be a classdef prototype. */ private ensureConcreteClassMethod; private validateLoadedClassMethodSignature; private callClassEmptyMethod; /** * Validate expanded positional argument values. */ private expressionValues; /** * Validate one value before exposing it as an ordinary argument expression. */ private expressionValue; /** * Validate one evaluated value before storing it in runtime-owned state. */ private runtimeExpressionValue; /** * Evaluate one AST node through the interpreter and reduce lazy return-list * carriers without applying expression-only validation. */ private evaluatedExecutionResult; /** * Evaluate one AST node without reducing comma-separated return-list * carriers, for contexts that must expand them explicitly. */ private rawEvaluationResult; /** * Evaluate one AST expression and validate the reduced value before it * crosses a context-owned argument/default/receiver boundary. */ private evaluatedExpressionValue; /** * Validate values that are exposed through lazy return-list helpers. */ private returnExpression; /** * Validate several values before exposing them through lazy return lists. */ private returnExpressions; /** * Reduce a class-dispatch result array to its scalar/array return value and * validate scalar 1x1 contents before exposing them as expression results. */ private scalarArrayReturnExpression; /** * Invoke one class method expecting a single output and reduce lazy * return-list carriers before storing the result in array dispatch paths. */ private reducedClassMethodResult; /** * Read one class-instance element from an object array. */ private classInstanceArrayElement; /** * Invoke each bound method stored in an object array. * * MATLAB/Octave dot access can produce arrays of method handles. Calling * that array evaluates each bound method with one requested output and then * normalizes the scalar array result through the shared return-expression * boundary before exposing it to the caller. * * @param expr Array containing bound method runtime values. * @param args Call arguments. * @param parent AST node that owns the call. * @returns Scalar or array expression result. */ private callClassBoundMethodArray; private callFunctionalClassMethodArray; /** * Delete a handle class instance, honoring an overloadable `delete` method. * * @param instance Handle instance to delete. * @param parent Call-site node used for stack traces. * @returns Void node. */ deleteClassInstance(instance: ClassInstance, parent: NodeInput): NodeExpr; private evaluateFunctionalClassMethodReceiver; private isFunctionalClassMethodReceiver; private callFunctionalClassMethod; /** * Dispatch a built-in, anonymous function, or user-defined function call. * * @param callable Resolved callable wrapper. * @param args Raw call argument expressions. * @param parent Call-site node used for metadata and stack traces. * @returns Call result. */ callCallable(callable: Callable, args: CallArgumentValue[], parent: NodeInput): NodeExpr; private valueReturnList; private callFunctionalOperatorOverload; /** * Dispatch built-in operator functions reached without an index-expression * wrapper, such as `feval('plus', obj, obj)`. */ private callCallableFunctionalOperatorOverload; /** * Classify an evaluated expression before applying call/index syntax. * * This helper keeps MATLAB/Octave dispatch precedence visible in one * place: callable handles/functions first, class method wrappers next, * constructors and functional method syntax after that, and native indexing * as the final fallback. * * @param expr Evaluated callee or indexed expression. * @param parent Index expression node carrying delimiter metadata. * @param args Raw call/index arguments, used only to classify functional method calls. * @returns Structured dispatch decision. */ resolveCallDispatch(expr: NodeExpr, parent: NodeInput, args?: CallArgumentValue[]): CallDispatch; /** * Execute one non-indexing call dispatch decision. * * @param dispatch Structured dispatch decision. * @param args Raw call argument expressions. * @param parent Index expression node carrying delimiter metadata. * @returns Call result, or `undefined` when native indexing should handle it. */ private applyCallDispatch; /** * Apply native MATLAB/Octave indexing after call dispatch declines. * * @param expr Evaluated indexed expression. * @param args Raw index expressions. * @param parent Index expression node carrying delimiter metadata. * @returns Indexed value or comma-separated return list. */ private applyNativeIndexing; /** * Apply call or indexing syntax to an evaluated expression. * * MATLAB/Octave use the same parentheses for function calls and array * indexing. This dispatcher first attempts callable/class dispatch and then * falls back to array/cell indexing, including comma-separated-list rules. * * @param expr Evaluated callee/indexed expression. * @param args Raw index or call argument expressions. * @param parent Index expression node carrying delimiter metadata. * @returns Call or indexing result. */ apply(expr: NodeExpr, args: CallArgumentValue[], parent: NodeInput): NodeExpr; /** * Define function in builtInFunctionTable. * @param id Name of function. * @param func Function body. * @param map `true` if function is a mapper function. * @param ev A `boolean` array indicating which function argument should * be evaluated before executing the function. If array is zero-length all * arguments are evaluated. */ defineBuiltInFunction(id: string, func: Function, mapper?: boolean, ev?: boolean[], signature?: BuiltInFunctionSignature): void; /** * Merge external built-in functions into the current built-in table. * @param table Built-in functions to add or override. */ assignBuiltInFunctionTable(table?: Record<string, NodeBuiltInFunction>): void; /** * Define unary operator function in builtInFunctionTable. * @param id Name of function. * @param func Function body. */ defineUnaryOperatorFunction(id: KeyOfTypeOfMathOperation, func: UnaryMathOperation): void; /** * Define binary operator function in builtInFunctionTable. * @param id Name of function. * @param func Function body. */ defineBinaryOperatorFunction(id: KeyOfTypeOfMathOperation, func: BinaryMathOperation): void; /** * Define a left-associative operator function that accepts two or more operands. * @param id Operator name. * @param func Binary operation used to fold the operands. */ defineLeftAssociativeMultipleOperationFunction(id: KeyOfTypeOfMathOperation, func: BinaryMathOperation): void; /** * Push a new frame onto the call stack. * * @param frame - CallFrame to push */ pushCallStackFrame(frame: CallFrame): void; /** * Pop the current frame from the call stack. * * @returns Removed frame */ popCallStackFrame(): CallFrame | undefined; /** * Returns a snapshot of the current stack trace. * * Top frame is the first element. */ private getStackTrace; } export type { CallDispatch, CallDispatchKind, SymbolResolution, SymbolResolutionKind, SymbolResolutionOptions, SymbolResolutionSource }; export { Context, ReturnSignal, BreakSignal, ContinueSignal }; export default Context;