mathjslab
Version:
MathJSLab - An interpreter with language syntax like MATLAB®/Octave. ISBN 978-65-00-82338-7
465 lines (464 loc) • 13.6 kB
TypeScript
/**
* MATLAB®/Octave like syntax parser/interpreter/compiler.
*/
import { CharString } from './char-string';
import { ComplexDecimal } from './complex-decimal';
import { MultiArray } from './multi-array';
/**
* Operator type.
*/
export type TOperator = '+' | '-' | '.*' | '*' | './' | '/' | '.\\' | '\\' | '.^' | '^' | '.**' | '**' | '<' | '<=' | '==' | '>=' | '>' | '!=' | '~=' | '&' | '|' | '&&' | '||' | '=' | '+=' | '-=' | '*=' | '/=' | '\\=' | '^=' | '**=' | '.*=' | './=' | '.\\=' | '.^=' | '.**=' | '&=' | '|=' | '()' | '!' | '~' | '+_' | '-_' | '++_' | '--_' | ".'" | "'" | '_++' | '_--';
/**
* aliasNameTable type.
*/
export type TAliasNameTable = Record<string, RegExp>;
/**
* baseFunctionTable type.
*/
export type TBaseFunctionTableEntry = {
mapper?: boolean;
ev: boolean[];
func: Function;
unparserMathML?: (tree: any) => string;
};
export type TBaseFunctionTable = Record<string, TBaseFunctionTableEntry>;
/**
* nameTable type.
*/
export type TNameTableEntry = {
args: Array<any>;
expr: any;
};
export type TNameTable = Record<string, TNameTableEntry>;
/**
* commandWordListTable type.
*/
export type TCommandWordListFunction = (...args: string[]) => void;
export type TCommandWordListTableEntry = {
func: TCommandWordListFunction;
};
export type TCommandWordListTable = Record<string, TCommandWordListTableEntry>;
/**
* TEvaluatorConfig type.
*/
export type TEvaluatorConfig = {
aliasTable?: TAliasNameTable;
externalFunctionTable?: TBaseFunctionTable;
externalCmdWListTable?: TCommandWordListTable;
};
/**
* AST (Abstract Syntax Tree) nodes.
*/
/**
* Common primary node.
*/
interface PrimaryNode {
type: string | number;
parent?: any;
index?: number;
}
/**
* Expression node.
*/
export type NodeExpr = NodeName | NodeArgExpr | NodeOperation | NodeList | NodeRange | NodeReturnList | MultiArray | ComplexDecimal;
/**
* Reserved node.
*/
interface NodeReserved extends PrimaryNode {
}
/**
* Name node.
*/
export interface NodeName extends PrimaryNode {
type: 'NAME';
id: string;
}
/**
* Command word list node.
*/
interface NodeCmdWList extends PrimaryNode {
type: 'CmdWList';
id: string;
args: Array<CharString>;
}
/**
* Expression and arguments node.
*/
export interface NodeArgExpr extends PrimaryNode {
type: 'ARG';
expr: NodeExpr;
args: Array<NodeExpr>;
}
/**
* Range node.
*/
interface NodeRange extends PrimaryNode {
type: 'RANGE';
start: NodeExpr | null;
stop: NodeExpr | null;
stride: NodeExpr | null;
}
/**
* Operation node.
*/
export type NodeOperation = UnaryOperation | BinaryOperation;
/**
* Unary operation node.
*/
type UnaryOperation = UnaryOperationL | UnaryOperationR;
/**
* Right unary operation node.
*/
interface UnaryOperationR extends PrimaryNode {
right: NodeExpr;
}
/**
* Left unary operation node.
*/
interface UnaryOperationL extends PrimaryNode {
left: NodeExpr;
}
/**
* Binary operation.
*/
interface BinaryOperation extends PrimaryNode {
left: NodeExpr;
right: NodeExpr;
}
/**
* List node
*/
export interface NodeList extends PrimaryNode {
type: 'LIST';
list: Array<NodeExpr>;
}
export type ReturnSelector = (length: number, index: number) => any;
/**
* Return list node
*/
export interface NodeReturnList extends PrimaryNode {
type: 'RETLIST';
selector: ReturnSelector;
}
/**
* External parser declarations (defined in parser body)
*/
declare global {
var EvaluatorPointer: Evaluator;
var commandsTable: string[];
}
/**
* Evaluator object.
* It is implemented as a class but cannot be instantiated more than one time
* simultaneously. Instance is given by `Evaluator.initialize` static method
* or global variable global.EvaluatorPointer.
*/
export declare class Evaluator {
/**
* After run Parser or Evaluate method, the exitStatus property will contains
* exit state of method.
*/
static response: {
EXTERNAL: number;
WARNING: number;
OK: number;
LEX_ERROR: number;
PARSER_ERROR: number;
EVAL_ERROR: number;
};
/**
* Debug flag, setter and getter.
*/
private _debug;
get debug(): boolean;
set debug(value: boolean);
/**
* Native name table. It's inserted in nameTable when
* `Evaluator.initialize` executed.
*/
private readonly nativeNameTable;
/**
* Name table.
*/
nameTable: TNameTable;
readonlyNameTable: string[];
/**
* Alias table.
*/
private aliasTable;
/**
* Base function table.
*/
baseFunctionTable: TBaseFunctionTable;
/**
* Get a list of names of defined functions in baseFunctionTable.
*/
get baseFunctionList(): string[];
/**
* Local table.
*/
localTable: Record<string, any>;
/**
* Command word list table.
*/
commandWordListTable: TCommandWordListTable;
/**
* Parser (generated by Jison).
*/
private readonly parser;
/**
* Evaluator exit status.
*/
exitStatus: number;
/**
* Increment and decrement operator
* @param pre `true` if prefixed. `false` if postfixed.
* @param operation Operation (`'plus'` or `'minus'`).
* @returns Operator function with signature `(tree: any) => any`.
*/
private incDecOp;
/**
* Operator table.
*/
private readonly opTable;
/**
* User functions.
*/
private readonly functions;
/**
* Parser AST (Abstract Syntax Tree) constructor methods.
*/
readonly nodeString: typeof CharString.parse;
readonly isString: typeof CharString.isThis;
readonly unparseString: typeof CharString.unparse;
readonly unparseStringMathML: typeof CharString.unparseMathML;
readonly removeQuotes: typeof CharString.removeQuotes;
readonly nodeNumber: typeof ComplexDecimal.parse;
readonly newNumber: typeof ComplexDecimal.newThis;
readonly isNumber: typeof ComplexDecimal.isThis;
readonly unparseNumber: typeof ComplexDecimal.unparse;
readonly unparseNumberMathML: typeof ComplexDecimal.unparseMathML;
readonly isTensor: typeof MultiArray.isThis;
readonly isRowVector: typeof MultiArray.isRowVector;
readonly unparseTensor: typeof MultiArray.unparse;
readonly unparseTensorMathML: typeof MultiArray.unparseMathML;
readonly evaluateTensor: typeof MultiArray.evaluate;
readonly mapTensor: typeof MultiArray.map;
readonly getElements: typeof MultiArray.getElements;
readonly getElementsLogical: typeof MultiArray.getElementsLogical;
readonly setElements: typeof MultiArray.setElements;
readonly setElementsLogical: typeof MultiArray.setElementsLogical;
readonly expandRange: typeof MultiArray.expandRange;
readonly firstRow: typeof MultiArray.firstRow;
readonly appendRow: typeof MultiArray.appendRow;
readonly tensor0x0: typeof MultiArray.array_0x0;
readonly linearize: typeof MultiArray.linearize;
readonly toTensor: typeof MultiArray.scalarToMultiArray;
readonly linearLength: typeof MultiArray.linearLength;
readonly getDimension: typeof MultiArray.getDimension;
/**
* Special functions MathML unparser.
*/
private readonly unparseMathMLFunctions;
/**
* Evaluator object constructor
*/
private constructor();
/**
* Evaluator initialization.
* @param config Evaluator configuration.
* @returns Evaluator instance.
*/
static initialize(config?: TEvaluatorConfig): Evaluator;
/**
* Alias name function. This property is set when running Evaluator.initialize.
* @param name Alias name.
* @returns Canonical name.
*/
aliasName: (name: string) => string;
/**
* Load native name table in name table.
*/
private loadNativeTable;
/**
* Restart evaluator.
*/
Restart(): void;
/**
* Clear variables. If names is 0 lenght restart evaluator.
* @param names Variable names to clear in nameTable and basFunctionTable.
*/
Clear(...names: string[]): void;
/**
* Parse input.
* @param input Input string
* @returns Parsed input.
*/
Parse(input: string): any;
/**
* Create reserved node.
* @param nodeid
* @returns
*/
nodeReserved(nodeid: string): NodeReserved;
/**
* Create name node.
* @param nodeid
* @returns
*/
nodeName(nodeid: string): NodeName;
/**
* Create command word list node.
* @param nodename
* @param nodelist
* @returns
*/
nodeCmdWList(nodename: NodeName, nodelist: NodeList): NodeCmdWList;
/**
* Create expression and arguments node.
* @param nodeexpr
* @param nodelist
* @returns
*/
nodeArgExpr(nodeexpr: any, nodelist?: any): NodeArgExpr;
/**
* Create range node. If two arguments are passed then it is 'start' and
* 'stop' of range. If three arguments are passed then it is 'start',
* 'stride' and 'stop'.
* @param args 'start' and 'stop' or 'start', 'stride' and 'stop'.
* @returns NodeRange.
*/
nodeRange(...args: any): NodeRange;
/**
* Create operator node.
* @param op
* @param data1
* @param data2
* @returns
*/
nodeOp(op: TOperator, data1: any, data2?: any): NodeOperation;
/**
* Create first element of list node.
* @param node First element of list node.
* @returns A NodeList.
*/
nodeListFirst(node?: any): NodeList;
/**
* Append node to list node.
* @param lnode NodeList.
* @param node Element to append to list.
* @returns NodeList with element appended.
*/
nodeList(lnode: NodeList, node: any): NodeList;
/**
* Create first row of a MultiArray.
* @param row
* @returns
*/
nodeFirstRow(row: NodeList): MultiArray;
/**
* Append row to MultiArray.
* @param M
* @param row
* @returns
*/
nodeAppendRow(M: MultiArray, row: NodeList): MultiArray;
/**
* Creates NodeReturnList (multiple assignment)
* @param selector Left side selector function.
* @returns Return list node.
*/
nodeReturnList(selector: ReturnSelector): NodeReturnList;
/**
* Throws error if left hand side length of multiple assignment greater
* than maximum length (to be used in ReturnSelector functions).
* @param maxLength Maximum length of return list.
* @param currentLength Requested length of return list.
*/
throwErrorIfGreaterThanReturnList(maxLength: number, currentLength: number): void;
/**
* Tests if it is a NodeReturnList and if so reduces it to its first
* element.
* @param value A node.
* @returns Reduced node if `tree` is a NodeReturnList.
*/
reduceIfReturnList(tree: any): any;
/**
* Validate left side of assignment node.
* @param tree Left side of assignment node
* @param shallow True if tree is a left root of assignment.
* @returns An object with three properties: `left`, `id` and `args`.
*/
validateAssignment(tree: any, shallow?: boolean): {
left: any;
id: string;
args: any[];
}[];
/**
* Define function in baseFunctionTable.
* @param name 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.
*/
private defineFunction;
/**
* Define unary operator function in baseFunctionTable.
* @param name Name of function.
* @param func Function body.
*/
private defineUnaryOperatorFunction;
/**
* Define binary operator function in baseFunctionTable.
* @param name Name of function.
* @param func Function body.
*/
private defineBinaryOperatorFunction;
/**
* Define define two-or-more operand function in baseFunctionTable.
* @param name
* @param func
*/
private defineTwoOrMoreOperandFunction;
/**
* Expression tree recursive evaluator.
* @param tree Expression to evaluate.
* @param local Set `true` if evaluating function.
* @param fname Function name if evaluating function.
* @returns Expression `tree` evaluated.
*/
Evaluator(tree: any, local?: boolean, fname?: string): any;
/**
* Evaluate expression `tree`.
* @param tree Expression to evaluate.
* @returns Expression `tree` evaluated.
*/
Evaluate(tree: any): any;
/**
* Unparse expression `tree`.
* @param tree Expression to unparse.
* @returns Expression `tree` unparsed.
*/
Unparse(tree: any): string;
/**
* Unparse recursively expression tree generating MathML representation.
* @param tree Expression tree.
* @returns String of expression `tree` unparsed as MathML language.
*/
unparserMathML(tree: any): string;
/**
* Unparse Expression tree in MathML.
* @param tree Expression tree.
* @returns String of expression unparsed as MathML language.
*/
UnparseMathML(tree: any, display?: 'inline' | 'block'): string;
/**
* Generates MathML representation of input without evaluation.
* @param input Input to parse and generate MathML representation.
* @param display `'inline'` or `'block'`.
* @returns MathML representation of input.
*/
toMathML(input: string, display?: 'inline' | 'block'): string;
}
export {};