UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

73 lines (72 loc) 4.4 kB
import type { DeepReadonly } from 'ts-essentials'; import type { RNode } from '../model'; import type { RNumber } from '../nodes/r-number'; import type { RString } from '../nodes/r-string'; import type { RLogical } from '../nodes/r-logical'; import type { RSymbol } from '../nodes/r-symbol'; import type { RAccess } from '../nodes/r-access'; import type { RBinaryOp } from '../nodes/r-binary-op'; import type { RPipe } from '../nodes/r-pipe'; import type { RUnaryOp } from '../nodes/r-unary-op'; import type { RFunctionCall } from '../nodes/r-function-call'; import { EmptyArgument } from '../nodes/r-function-call'; import type { RForLoop } from '../nodes/r-for-loop'; import type { RWhileLoop } from '../nodes/r-while-loop'; import type { RRepeatLoop } from '../nodes/r-repeat-loop'; import type { RNext } from '../nodes/r-next'; import type { RBreak } from '../nodes/r-break'; import type { RComment } from '../nodes/r-comment'; import type { RLineDirective } from '../nodes/r-line-directive'; import type { RIfThenElse } from '../nodes/r-if-then-else'; import type { RExpressionList } from '../nodes/r-expression-list'; import type { RFunctionDefinition } from '../nodes/r-function-definition'; import type { RArgument } from '../nodes/r-argument'; import type { RParameter } from '../nodes/r-parameter'; /** * Called during the down-pass, will pe propagated to children and used in the up-pass (see {@link StatefulFoldFunctions}). * <p> * Exists for leafs as well for consistency reasons. */ export type DownFold<Info, Down> = (node: RNode<Info>, down: Down) => Down; /** * All fold functions besides `down` are called after the down-pass in conventional fold-fashion. * The `down` argument holds information obtained during the down-pass, issued by the `down` function. */ export interface StatefulFoldFunctions<Info, Down, Up> { down: DownFold<Info, Down>; foldNumber: (num: RNumber<Info>, down: Down) => Up; foldString: (str: RString<Info>, down: Down) => Up; foldLogical: (logical: RLogical<Info>, down: Down) => Up; foldSymbol: (symbol: RSymbol<Info>, down: Down) => Up; foldAccess: (node: RAccess<Info>, name: Up, access: readonly (typeof EmptyArgument | Up)[], down: Down) => Up; foldBinaryOp: (op: RBinaryOp<Info>, lhs: Up, rhs: Up, down: Down) => Up; foldPipe: (op: RPipe<Info>, lhs: Up, rhs: Up, down: Down) => Up; foldUnaryOp: (op: RUnaryOp<Info>, operand: Up, down: Down) => Up; loop: { foldFor: (loop: RForLoop<Info>, variable: Up, vector: Up, body: Up, down: Down) => Up; foldWhile: (loop: RWhileLoop<Info>, condition: Up, body: Up, down: Down) => Up; foldRepeat: (loop: RRepeatLoop<Info>, body: Up, down: Down) => Up; foldNext: (next: RNext<Info>, down: Down) => Up; foldBreak: (next: RBreak<Info>, down: Down) => Up; }; other: { foldComment: (comment: RComment<Info>, down: Down) => Up; foldLineDirective: (comment: RLineDirective<Info>, down: Down) => Up; }; /** The `otherwise` argument is `undefined` if the `else` branch is missing */ foldIfThenElse: (ifThenExpr: RIfThenElse<Info>, cond: Up, then: Up, otherwise: Up | undefined, down: Down) => Up; foldExprList: (exprList: RExpressionList<Info>, grouping: [start: Up, end: Up] | undefined, expressions: Up[], down: Down) => Up; functions: { foldFunctionDefinition: (definition: RFunctionDefinition<Info>, params: Up[], body: Up, down: Down) => Up; /** folds named and unnamed function calls */ foldFunctionCall: (call: RFunctionCall<Info>, functionNameOrExpression: Up, args: (Up | typeof EmptyArgument)[], down: Down) => Up; /** The `name` is `undefined` if the argument is unnamed, the value, if we have something like `x=,...` */ foldArgument: (argument: RArgument<Info>, name: Up | undefined, value: Up | undefined, down: Down) => Up; /** The `defaultValue` is `undefined` if the argument was not initialized with a default value */ foldParameter: (parameter: RParameter<Info>, name: Up, defaultValue: Up | undefined, down: Down) => Up; }; } /** * Folds in old functional-fashion over the AST structure but allowing for a down function which can pass context to child nodes. */ export declare function foldAstStateful<Info, Down, Up>(ast: RNode<Info>, down: Down, folds: DeepReadonly<StatefulFoldFunctions<Info, Down, Up>>): Up;