mathjslab
Version:
MathJSLab - An interpreter with language syntax like MATLAB®/Octave, ISBN 978-65-00-82338-7.
231 lines (230 loc) • 8.98 kB
TypeScript
import type { NodeExpr, NodeFunctionDefinition, NodeIdentifier, NodeInput, NameTable } from './AST';
import { MultiArray } from './AST';
/**
* Interpreter error callback used by pure call helpers.
*/
type ThrowEvalError = (message: string) => never;
/**
* Workspace binding callback used while wiring evaluated inputs and outputs.
*/
type DefineName = (name: string, value: NodeInput) => void;
/**
* Expression evaluator callback supplied by the interpreter.
*/
type EvaluateExpression = (expression: NodeExpr) => NodeInput;
/**
* Default-argument evaluator callback.
*
* The parameter name is passed so interpreter diagnostics can report which
* default expression failed.
*/
type EvaluateDefault = (name: string, expression: NodeExpr) => NodeInput;
/**
* Static input layout derived from a function definition.
*/
type FunctionInputLayout = {
/**
* All declared parameters, including name-value-only parameters and `varargin`.
*/
params: NodeIdentifier[];
/**
* Whether the final declared parameter is `varargin`.
*/
hasVarargin: boolean;
/**
* Number of parameters before `varargin`, if any.
*/
fixedParamCount: number;
/**
* Parameters that accept positional arguments after name-value filtering.
*/
positionalParams: NodeIdentifier[];
/**
* Number of positional parameters after name-value filtering.
*/
positionalParamCount: number;
};
/**
* Static output layout derived from a function definition.
*/
type FunctionReturnLayout = {
/**
* All declared return identifiers, including `varargout`.
*/
returnNames: NodeIdentifier[];
/**
* Whether the final declared return identifier is `varargout`.
*/
hasVarargout: boolean;
/**
* Number of fixed return identifiers before `varargout`, if any.
*/
fixedReturnCount: number;
/**
* Return names as strings for workspace lookup.
*/
names: string[];
};
/**
* Call-site arguments after positional and name-value splitting.
*/
type FunctionCallArguments = {
/**
* Positional argument expressions in call order.
*/
positional: NodeExpr[];
/**
* Name-value argument expressions keyed by option name.
*/
named: Map<string, NodeExpr>;
};
/**
* Complete metadata needed to enter a user-function call.
*/
type PreparedFunctionCall = {
/**
* Prepared input layout.
*/
inputLayout: FunctionInputLayout;
/**
* Prepared output layout.
*/
returnLayout: FunctionReturnLayout;
/**
* Split call-site arguments.
*/
callArguments: FunctionCallArguments;
/**
* Default expressions keyed by parameter name.
*/
inputDefaults: Map<string, NodeExpr>;
/**
* Minimum number of positional arguments required after trailing defaults.
*/
minFixedParamCount: number;
};
/**
* Interpreter services required while preparing a function call.
*/
type FunctionCallPreparationCallbacks = {
/**
* Return the parameters that are bound exclusively through name-value input.
*/
nameValueParameters: (func: NodeFunctionDefinition) => Set<string>;
/**
* Split raw call arguments into positional and named groups.
*/
splitCallArguments: (func: NodeFunctionDefinition, args: NodeExpr[]) => FunctionCallArguments;
/**
* Return default expressions keyed by input parameter name.
*/
inputDefaults: (func: NodeFunctionDefinition) => Map<string, NodeExpr>;
/**
* Raise an interpreter evaluation error.
*/
throwEvalError: ThrowEvalError;
};
/**
* Mechanics for calling MATLAB/Octave-like user functions and lambdas.
*
* The interpreter remains responsible for parsing, expression evaluation, and
* error construction. This class is deliberately a pure helper around layouts,
* arity checks, argument binding, `varargin`, `varargout`, default arguments,
* and lazy return-list construction.
*/
declare class FunctionCall {
/**
* Compute the input layout of a user-defined function.
*
* Name-value option structs declared through `arguments` are excluded from
* the positional parameter list. `varargin` still participates as the final
* catch-all parameter.
*/
static inputLayout(func: NodeFunctionDefinition, nameValueParameters: Set<string>): FunctionInputLayout;
/**
* Compute the fixed/variadic input layout of an anonymous function handle.
*/
static lambdaInputLayout(params: NodeIdentifier[]): Pick<FunctionInputLayout, 'hasVarargin' | 'fixedParamCount'>;
/**
* Compute the return layout, including `varargout`.
*/
static returnLayout(func: NodeFunctionDefinition): FunctionReturnLayout;
/**
* Determine the minimum required positional count after trailing defaults.
*/
static minimumPositionalCount(positionalParams: NodeIdentifier[], inputDefaults: Map<string, NodeExpr>): number;
/**
* Check anonymous-function input arity.
*/
static validateLambdaInputArity(argsLength: number, hasVarargin: boolean, fixedParamCount: number, throwEvalError: ThrowEvalError): void;
/**
* Check user-function input arity after name-value splitting and defaults.
*/
static validateFunctionInputArity(func: NodeFunctionDefinition, positionalLength: number, hasVarargin: boolean, positionalParamCount: number, minFixedParamCount: number, throwEvalError: ThrowEvalError): void;
/**
* Check requested output count before entering the function body.
*/
static validateFunctionOutputArity(returnNames: NodeIdentifier[], hasVarargout: boolean, requestedOutputCount: number, throwEvalError: ThrowEvalError): void;
/**
* Build all static call metadata needed before evaluating arguments.
*/
static prepareFunctionCall(func: NodeFunctionDefinition, args: NodeExpr[], requestedOutputCount: number, callbacks: FunctionCallPreparationCallbacks): PreparedFunctionCall;
/**
* Create a cell row for `varargin`.
*/
static vararginCell(values: NodeInput[]): MultiArray;
/**
* Create the initial `varargout` cell array.
*
* MATLAB permits assigning elements later. The placeholder length is at
* least one so the variable exists even when no extra output is requested.
*/
static emptyVarargoutCell(requestedOutputCount: number, fixedReturnCount: number): MultiArray;
/**
* Predeclare fixed return names in the function workspace.
*
* An empty entry lets the return-list builder distinguish "declared but not
* assigned" from "not a return variable" and produce MATLAB-like undefined
* return errors.
*/
static initializeFixedReturnSlots(returnNames: NodeIdentifier[], nameTable: NameTable): void;
/**
* Attach call-site metadata and evaluate positional arguments.
*/
static evaluateCallArguments(args: NodeExpr[], parent: NodeInput, evaluate: EvaluateExpression, indexOffset?: number): NodeInput[];
/**
* Evaluate already-split name-value arguments.
*/
static evaluateNameValueArguments(named: Map<string, NodeExpr>, parent: NodeInput, evaluate: EvaluateExpression): Map<string, NodeInput>;
/**
* Bind anonymous-function inputs, including `varargin`.
*/
static bindLambdaInputs(params: NodeIdentifier[], args: NodeExpr[], parent: NodeInput, hasVarargin: boolean, fixedParamCount: number, defineName: DefineName, evaluate: EvaluateExpression): void;
/**
* Bind evaluated positional arguments and default values to function inputs.
*/
static bindPositionalInputs(func: NodeFunctionDefinition, inputLayout: FunctionInputLayout, evaluatedArgs: NodeInput[], inputDefaults: Map<string, NodeExpr>, defineName: DefineName, evaluateDefault: EvaluateDefault, throwEvalError: ThrowEvalError): void;
/**
* Bind the remaining evaluated inputs to `varargin`.
*/
static bindVarargin(inputLayout: FunctionInputLayout, evaluatedArgs: NodeInput[], defineName: DefineName): void;
/**
* Initialize `varargout` in the function workspace.
*/
static bindVarargout(returnLayout: FunctionReturnLayout, requestedOutputCount: number, defineName: DefineName): void;
/**
* Create the lazy return list read by assignment and display code.
*
* Values are pulled from the function workspace only when requested. This is
* important for MATLAB/Octave compatibility: requesting one output should
* not force validation of later outputs, while requesting an unassigned
* output must raise an error.
*/
static createReturnList(returnLayout: FunctionReturnLayout, nameTable: NameTable, throwEvalError: ThrowEvalError): NodeExpr;
}
export type { FunctionInputLayout, FunctionReturnLayout, FunctionCallArguments, PreparedFunctionCall };
export { FunctionCall };
declare const _default: {
FunctionCall: typeof FunctionCall;
};
export default _default;