UNPKG

mathjslab

Version:

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

231 lines (230 loc) 8.98 kB
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;