UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

92 lines (91 loc) 3.62 kB
import type { RNumberValue, RStringValue } from '../../../r-bridge/lang-4.x/convert-values'; import type { RLogicalValue } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-logical'; export declare const Top: { type: symbol; }; export declare const Bottom: { type: symbol; }; export type Lift<N> = N | typeof Top | typeof Bottom; export type Unlift<N> = N extends typeof Top ? never : N extends typeof Bottom ? never : N; export interface ValueInterval<Limit extends ValueNumber = ValueNumber> { type: 'interval'; start: Limit; startInclusive: boolean; end: Limit; endInclusive: boolean; } /** * An R vector with either a known set of elements or a known domain. */ export interface ValueVector<Elements extends Lift<unknown[]> = Lift<Value[]>, Domain extends Lift<Value> = Lift<Value>> { type: 'vector'; elements: Elements; /** if we do not know the amount of elements, we can still know the domain */ elementDomain: Domain; } /** describes the static case of we do not know which value */ export interface ValueSet<Elements extends Lift<unknown[]> = Lift<Value[]>> { type: 'set'; elements: Elements; } export interface ValueNumber<Num extends Lift<RNumberValue> = Lift<RNumberValue>> { type: 'number'; value: Num; } export interface ValueString<Str extends Lift<RStringValue> = Lift<RStringValue>> { type: 'string'; value: Str; } export interface ValueNull { type: 'null'; } export interface ValueFunctionDefinition { type: 'function-definition'; } export interface ValueMissing { type: 'missing'; } export type TernaryLogical = RLogicalValue | 'maybe'; export interface ValueLogical { type: 'logical'; value: Lift<TernaryLogical>; } export type Value = Lift<ValueInterval | ValueVector | ValueSet | ValueNumber | ValueString | ValueLogical | ValueMissing | ValueFunctionDefinition | ValueNull>; export type ValueType<V> = V extends { type: infer T; } ? T : never; export type ValueTypes = ValueType<Value>; /** * */ export declare function typeOfValue<V extends Value>(value: V): V['type']; /** Checks whether the given value is the top value */ export declare function isTop<V extends Lift<unknown>>(value: V): value is typeof Top; /** Checks whether the given value is the bottom value */ export declare function isBottom<V extends Lift<unknown>>(value: V): value is typeof Bottom; /** Checks whether the given value is a proper value (neither top nor bottom) */ export declare function isValue<V extends Lift<unknown>>(value: V): value is Unlift<V>; /** * Treat a value as unlifted value, throws if it is top or bottom. */ export declare function asValue<V extends Lift<unknown>>(value: V): Unlift<V>; /** * */ export declare function stringifyValue(value: Lift<Value>): string; /** * Reads the plain TS value a {@link Value} stands for, `undefined` whenever it stands for more than one, for * none, or for another kind. Prefer these over reaching into a value's shape by hand. * * This is the constant-folding view: it answers "is this one known constant" and nothing else. It runs no * fixpoint, knows no control flow, and widens nothing. For an abstract state that does, use the dedicated * abstract interpretation in `src/abstract-interpretation/`. */ export declare const RValue: { readonly name: "RValue"; /** The number the value stands for, collapsing an interval that admits a single one. */ readonly numberOf: (this: void, value: Value) => number | undefined; /** The string the value stands for. */ readonly stringOf: (this: void, value: Value) => string | undefined; };