Document-wide, named formula functions (e.g. MARGE(revenue; cost) = (revenue - cost) / revenue) callable from any cell like a built-in (=MARGE(Umsatz!B2; Umsatz!C2)). Created, edited and deleted only through a new "𝑓 Funktionen" toolbar button -> modal (list + shared edit form), never via JSON handedit. Engine: a call is inlined into the caller's AST at parse time (src/engine/userFunctions.ts's expandUserFunctions), so evaluator.ts and graph.ts need no changes -- dependencies on cells referenced only inside a function body (not in the call) are picked up for free. parser.ts gains an optional paramNames argument to parseFormula() producing a new ParamNode leaf, used only when parsing a function body. Store: addCustomFunction/updateCustomFunction/deleteCustomFunction with inline (not toast) validation -- name/parameter shape, no collision with a built-in or another function, the body parses, and a definition-time cycle check across the whole call graph. Renaming/deleting a function mirrors table rename/delete: existing calls are not rewritten, they become #NAME? on the next rebuild. Fully undo/redo-able and part of the JSON document (customFunctions: [], migrated for v1 and older v2 docs). 178 tests passing (32 new), vue-tsc and eslint clean. Manually verified end-to-end in the running app via Playwright: define/call/recalculate, rename -> #NAME?, a closing cycle rejected inline at save, undo restores the function library. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
51 lines
1.0 KiB
TypeScript
51 lines
1.0 KiB
TypeScript
/**
|
|
* Public surface of the formula engine.
|
|
*
|
|
* Nothing in `./` imports Vue, the DOM or any spreadsheet library. See
|
|
* ./README.md for the grammar (EBNF), the evaluation model and the error model.
|
|
*/
|
|
|
|
export { tokenize, LexError, type Token, type TokenType } from './lexer';
|
|
export {
|
|
parseFormula,
|
|
collectRefs,
|
|
ParseError,
|
|
type Node,
|
|
type CellNode,
|
|
type RangeNode,
|
|
} from './parser';
|
|
export { evaluate } from './evaluator';
|
|
export { DependencyGraph } from './graph';
|
|
export { FUNCTIONS, getFunction, hasFunction } from './functions';
|
|
export {
|
|
colToNumber,
|
|
numberToCol,
|
|
parseA1,
|
|
toA1,
|
|
looksLikeCell,
|
|
expandRange,
|
|
cycleReferenceLocks,
|
|
} from './refs';
|
|
export {
|
|
Workbook,
|
|
literalValue,
|
|
type TableModel,
|
|
} from './workbook';
|
|
export {
|
|
buildFunctionIndex,
|
|
expandUserFunctions,
|
|
collectCalledFunctionNames,
|
|
type FunctionDef,
|
|
} from './userFunctions';
|
|
export {
|
|
FormulaError,
|
|
isError,
|
|
keyOf,
|
|
parseKey,
|
|
ERROR_CODES,
|
|
type ErrorCode,
|
|
type CellValue,
|
|
type Scalar,
|
|
type EngineHost,
|
|
} from './types';
|