(node, options)
| 353 | |
| 354 | // destroys the original node and returns a folded one |
| 355 | function foldFraction (node, options) { |
| 356 | switch (node.type) { |
| 357 | case 'SymbolNode': |
| 358 | return node |
| 359 | case 'ConstantNode': |
| 360 | switch (typeof node.value) { |
| 361 | case 'number': return _toNumber(node.value, options) |
| 362 | case 'bigint': return _toNumber(node.value, options) |
| 363 | case 'string': return node.value |
| 364 | default: |
| 365 | if (!isNaN(node.value)) return _toNumber(node.value, options) |
| 366 | } |
| 367 | return node |
| 368 | case 'FunctionNode': |
| 369 | if (mathWithTransform[node.name] && mathWithTransform[node.name].rawArgs) { |
| 370 | return node |
| 371 | } |
| 372 | { |
| 373 | // Process operators as OperatorNode |
| 374 | const operatorFunctions = ['add', 'multiply'] |
| 375 | if (!operatorFunctions.includes(node.name)) { |
| 376 | const args = node.args.map(arg => foldFraction(arg, options)) |
| 377 | |
| 378 | // If all args are numbers |
| 379 | if (!args.some(isNode)) { |
| 380 | try { |
| 381 | return _eval(node.name, args, options) |
| 382 | } catch (ignoreandcontinue) { } |
| 383 | } |
| 384 | |
| 385 | // Size of a matrix does not depend on entries |
| 386 | if (node.name === 'size' && |
| 387 | args.length === 1 && |
| 388 | isArrayNode(args[0])) { |
| 389 | const sz = [] |
| 390 | let section = args[0] |
| 391 | while (isArrayNode(section)) { |
| 392 | sz.push(section.items.length) |
| 393 | section = section.items[0] |
| 394 | } |
| 395 | return matrix(sz) |
| 396 | } |
| 397 | |
| 398 | // Convert all args to nodes and construct a symbolic function call |
| 399 | return new FunctionNode(node.name, args.map(_ensureNode)) |
| 400 | } else { |
| 401 | // treat as operator |
| 402 | } |
| 403 | } |
| 404 | /* falls through */ |
| 405 | case 'OperatorNode': |
| 406 | { |
| 407 | const fn = node.fn.toString() |
| 408 | let args |
| 409 | let res |
| 410 | const makeNode = createMakeNodeFunction(node) |
| 411 | if (isOperatorNode(node) && node.isUnary()) { |
| 412 | args = [foldFraction(node.args[0], options)] |
no test coverage detected
searching dependent graphs…