import { BinaryPrefix, MetricPrefix } from './utils'; import { Pythagorean, AbsolutePitch } from './pythagorean'; import { AbsoluteMosPitch, MosStep } from './diamond-mos'; import { Fraction } from 'xen-dev-utils'; /** * Comma sets for Functional Just System. * * '': FloraC's tweak to FJS * * 'c': Classic FJS * * 'f': FloraC's version of FJS with semiapotomic radius of tolerance * * 'n': Neutral FJS expanded to generic bridging commas by Lumi Pakkanen * * 'l': Lumi's irrational self-insert. Hi there! <3 Happy coding! <3 * * 'h': Helmholtz-Ellis 2020 * * 'm': Helmholtz-Ellis-Wolf-(M)onzo 53-limit * * 's': Syntonic rastmic subchroma commas by Aura * * 'q': Semiquartal analogue of Neutral FJS by Lumi Pakkanen * * 't': Tone-splitter analogue of Neutral FJS by Lumi Pakkanen */ export type FJSFlavor = '' | 'n' | 'l' | 'h' | 'm' | 's' | 'c' | 'f' | 'q' | 't'; export type FJSInflection = [number, FJSFlavor]; /** * Numeric flavor of a {@link DecimalLiteral}. * * '': Rational number with a power of ten denominator. (Requires a decimal comma or an explicit exponent to use.) * * 'r': Real (non-algebraic) number. * * 'e': Rational number with a power of ten denominator. (Indicates an exponent of 0.) * * 'E': Rational number with a power of ten denominator. (Indicates an exponent of 0.) * * 'z': Absolute frequency that is a decimal multiple of 1 Hz. */ export type NumericFlavor = '' | 'r' | 'e' | 'E' | 'z'; export type Sign = '' | '+' | '-'; export type BasisFraction = { radical: boolean; numerator: number; denominator: number | null; }; export type WartBasisElement = BasisFraction | ''; export type ValBasisElement = WartBasisElement | 's' | 'Hz' | 'hz'; export type BasisElement = ValBasisElement | 'rc' | 'r¢' | 'inf' | '1°' | 'deg'; export type Identifier = { type: 'Identifier'; id: string; }; export type ValBasisLiteral = { type: 'ValBasisLiteral'; basis: ValBasisElement[] | Identifier; }; export type IntegerLiteral = { type: 'IntegerLiteral'; value: bigint; }; export type DecimalLiteral = { type: 'DecimalLiteral'; sign: Sign; whole: bigint; fractional: string; exponent: number | null; flavor: NumericFlavor; }; export type FractionLiteral = { type: 'FractionLiteral'; numerator: bigint; denominator: bigint; }; /** * A synthetic AST node for formatting expressions like 2^3/5. */ export type RadicalLiteral = { type: 'RadicalLiteral'; argument: Fraction; exponent: Fraction; }; export type StepLiteral = { type: 'StepLiteral'; count: number; }; export type NedjiLiteral = { type: 'NedjiLiteral'; numerator: number; denominator: number; equaveNumerator: number | null; equaveDenominator: number | null; }; export type CentsLiteral = { type: 'CentsLiteral'; sign: Sign; whole: bigint; fractional: string; exponent: number | null; real: boolean; }; export type CentLiteral = { type: 'CentLiteral'; real: boolean; }; export type ReciprocalCentLiteral = { type: 'ReciprocalCentLiteral'; }; export type HertzLiteral = { type: 'HertzLiteral'; prefix: MetricPrefix | BinaryPrefix; }; export type SecondLiteral = { type: 'SecondLiteral'; prefix: MetricPrefix | BinaryPrefix; }; export type ReciprocalLogarithmicHertzLiteral = { type: 'ReciprocalLogarithmicHertzLiteral'; }; export type NotANumberLiteral = { type: 'NotANumberLiteral'; }; export type InfinityLiteral = { type: 'InfinityLiteral'; }; export type FJS = { type: 'FJS'; ups: number; lifts: number; pythagorean: Pythagorean; superscripts: FJSInflection[]; subscripts: FJSInflection[]; }; /** * Placeholder AST node for FJS of unknown formatting. * The result of FJS addition or a context shift caused by up or lift declaration. */ export type AspiringFJS = { type: 'AspiringFJS'; flavor: FJSFlavor; }; export type AbsoluteFJS = { type: 'AbsoluteFJS'; ups: number; lifts: number; pitch: AbsolutePitch | AbsoluteMosPitch; superscripts: FJSInflection[]; subscripts: FJSInflection[]; }; /** * Placeholder AST node for AbsoluteFJS of unknown formatting. * The result of FJS addition or a context shift caused by up or lift declaration. */ export type AspiringAbsoluteFJS = { type: 'AspiringAbsoluteFJS'; flavor: FJSFlavor; }; export type MosStepLiteral = { type: 'MosStepLiteral'; ups: number; lifts: number; mosStep: MosStep; superscripts: FJSInflection[]; subscripts: FJSInflection[]; }; export type WartsLiteral = { type: 'WartsLiteral'; equave: string; divisions: number; warts: string[]; basis: WartBasisElement[] | Identifier; }; export type PatentTweak = { element: BasisFraction; tweak: number; }; export type SparseOffsetVal = { type: 'SparseOffsetVal'; equave: BasisFraction | ''; divisions: number; tweaks: PatentTweak[]; basis: WartBasisElement[] | Identifier; }; export type VectorComponent = { sign: Sign; left: number; separator?: '/' | '.'; right: string; exponent: number | null; }; export type MonzoLiteral = { type: 'MonzoLiteral'; components: VectorComponent[]; ups: number; lifts: number; basis: BasisElement[] | Identifier; }; export type ValLiteral = { type: 'ValLiteral'; components: VectorComponent[]; basis: ValBasisElement[] | Identifier; }; export type SquareSuperparticular = { type: 'SquareSuperparticular'; start: bigint; end: bigint | null; }; /** * AST node produced by the parser or a synthetic one used for formatting. */ export type IntervalLiteral = IntegerLiteral | DecimalLiteral | FractionLiteral | RadicalLiteral | StepLiteral | NedjiLiteral | CentsLiteral | CentLiteral | NotANumberLiteral | InfinityLiteral | FJS | AspiringFJS | AbsoluteFJS | AspiringAbsoluteFJS | MosStepLiteral | HertzLiteral | SecondLiteral | MonzoLiteral | SquareSuperparticular; export type CoIntervalLiteral = ValLiteral | SparseOffsetVal | WartsLiteral | ReciprocalCentLiteral | ReciprocalLogarithmicHertzLiteral; /** * Validate AST literal for display formatting. * @param node Interval literal to validate. * @throws An error if the literal is too complex to display. * @hidden */ export declare function validateNode(node?: IntervalLiteral): void; /** * Infer the FJS flavor of an AST node or a pair of AST nodes. * @param a First node. * @param b Second node (optional). * @returns The FJS flavor that best corresponds to the input(s). */ export declare function inferFJSFlavor(a: FJS | AspiringFJS | AbsoluteFJS | AspiringAbsoluteFJS, b?: FJS | AspiringFJS | AbsoluteFJS | AspiringAbsoluteFJS): FJSFlavor; /** * Compute the node corresponding to the multiplicative inverse of the input (ignoring domain). * @param node AST node to find the inverse of. * @returns The inverse node or `undefined` if default formatting is enough. * @hidden */ export declare function uniformInvertNode(node?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function negNode(node?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function invertNode(node?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function absNode(node?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function pitchAbsNode(node?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function sqrtNode(node?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function addNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function subNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function modNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function roundToNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function divNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function mulNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function projectNodes(octaves?: IntervalLiteral, base?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function powNodes(a?: IntervalLiteral, b?: IntervalLiteral): IntervalLiteral | undefined; /** @hidden */ export declare function ipowNodes(a?: IntervalLiteral, b?: IntervalLiteral): undefined; /** @hidden */ export declare function logNodes(a?: IntervalLiteral, b?: IntervalLiteral): undefined; /** @hidden */ export declare function lensAddNodes(a?: IntervalLiteral, b?: IntervalLiteral): undefined; /** @hidden */ export declare function lensSubNodes(a?: IntervalLiteral, b?: IntervalLiteral): undefined; /** @hidden */ export declare function pitchRoundToNodes(a?: IntervalLiteral, b?: IntervalLiteral): undefined; /** @hidden */ export declare function formatAbsoluteFJS(literal: AbsoluteFJS, octaves?: boolean): string; /** @hidden */ export declare function formatComponent(component: VectorComponent): string; /** * Convert an AST node to a string representation. * @param literal Interval literal to convert. * @returns Text representation of the literal. */ export declare function literalToString(literal: IntervalLiteral | CoIntervalLiteral | ValBasisLiteral): string; /** * Convert a floating point number or a Fraction instance to a decimal literal. * @param num Number to convert. Fractions should have a power of ten denominator unless flavor is 'r'. * @param flavor Numeric flavor of the literal. * @returns Virtual AST node representing a decimal literal. */ export declare function numberToDecimalLiteral(num: number | Fraction, flavor: NumericFlavor): DecimalLiteral; export declare function fractionToVectorComponent(fraction: Fraction): VectorComponent; export declare function integerToVectorComponent(num: number): VectorComponent; export declare function literalToJSON(literal?: IntervalLiteral | CoIntervalLiteral | ValBasisLiteral): any; export declare function intervalLiteralFromJSON(object: any): IntervalLiteral | undefined;