| import { num, dim } from '../node.js'; | |
| import { baseOf, convert } from '../convertUnits.js'; | |
| /** @typedef {import('../node.js').Node} Node */ | |
| /** @typedef {import('../node.js').Num} Num */ | |
| /** @typedef {import('../node.js').Dim} Dim */ | |
| /** @typedef {import('../convertUnits.js').BaseType} BaseType */ | |
| /** | |
| * Construct a Num or Dim node from a folded result. | |
| * @param {{ unit: string }} fold | |
| * @param {number} value | |
| * @return {Num | Dim} | |
| */ | |
| function foldResult(fold, value) { | |
| return fold.unit === '' ? num(value) : dim(value, fold.unit); | |
| } | |
| /** | |
| * @param {Node[]} args | |
| * @return {{ values: number[], unit: string } | null} | |
| */ | |
| function foldConstArgs(args) { | |
| if (args.length === 0) { | |
| return null; | |
| } | |
| const first = args[0]; | |
| if (first.type === 'Num') { | |
| return foldNumberArgs(args); | |
| } | |
| if (first.type === 'Dim') { | |
| const b = first.unit === '%' ? null : baseOf(first.unit); | |
| if (!b) { | |
| return null; | |
| } | |
| return foldDimArgs(args, first.unit, b); | |
| } | |
| return null; | |
| } | |
| /** | |
| * @param {Node[]} args | |
| * @return {{ values: number[], unit: '' } | null} | |
| */ | |
| function foldNumberArgs(args) { | |
| /** @type {number[]} */ const values = []; | |
| for (const a of args) { | |
| if (a.type !== 'Num') { | |
| return null; | |
| } | |
| values.push(a.value); | |
| } | |
| return { values, unit: '' }; | |
| } | |
| /** | |
| * @param {Node[]} args | |
| * @param {string} unit | |
| * @param {BaseType} base | |
| * @return {{ values: number[], unit: string } | null} | |
| */ | |
| function foldDimArgs(args, unit, base) { | |
| /** @type {number[]} */ const values = []; | |
| for (const a of args) { | |
| if (a.type !== 'Dim' || a.unit === '%' || baseOf(a.unit) !== base) { | |
| return null; | |
| } | |
| const converted = convert(a.value, a.unit, unit); | |
| if (converted === null) { | |
| return null; | |
| } | |
| values.push(converted); | |
| } | |
| return { values, unit }; | |
| } | |
| export { foldConstArgs, foldResult }; |