diff --git a/src/core/function/typed.js b/src/core/function/typed.js index 883484aced..80e1c6155b 100644 --- a/src/core/function/typed.js +++ b/src/core/function/typed.js @@ -91,7 +91,8 @@ const dependencies = [ '?BigNumber', '?Complex', '?DenseMatrix', - '?Fraction' + '?Fraction', + '?ConstantNode' ] /** @@ -99,7 +100,7 @@ const dependencies = [ * @param {Object} dependencies Object with data types like Complex and BigNumber * @returns {Function} */ -export const createTyped = /* #__PURE__ */ factory('typed', dependencies, function createTyped ({ BigNumber, Complex, DenseMatrix, Fraction }) { +export const createTyped = /* #__PURE__ */ factory('typed', dependencies, function createTyped ({ BigNumber, Complex, DenseMatrix, Fraction, ConstantNode }) { // TODO: typed-function must be able to silently ignore signatures with unknown data types // get a new instance of typed-function @@ -333,6 +334,16 @@ export const createTyped = /* #__PURE__ */ factory('typed', dependencies, functi convert: function (matrix) { return matrix.valueOf() } + }, { + from: 'number', + to: 'Node', + convert: function (x) { + if (!ConstantNode) { + throwNoConstantNode() + } + + return new ConstantNode(x) + } } ] @@ -354,3 +365,7 @@ function throwNoMatrix () { function throwNoFraction (x) { throw new Error(`Cannot convert value ${x} into a Fraction, no class 'Fraction' provided.`) } + +function throwNoConstantNode (x) { + throw new Error(`Cannot convert value ${x} into a ConstantNode, no class 'ConstantNode' provided.`) +} diff --git a/src/function/arithmetic/addScalar.js b/src/function/arithmetic/addScalar.js index c91e6d2201..6957c28851 100644 --- a/src/function/arithmetic/addScalar.js +++ b/src/function/arithmetic/addScalar.js @@ -2,9 +2,9 @@ import { factory } from '../../utils/factory' import { addNumber } from '../../plain/number' const name = 'addScalar' -const dependencies = ['typed'] +const dependencies = ['typed', 'OperatorNode'] -export const createAddScalar = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { +export const createAddScalar = /* #__PURE__ */ factory(name, dependencies, ({ typed, OperatorNode }) => { /** * Add two scalar values, `x + y`. * This function is meant for internal use: it is used by the public function @@ -42,6 +42,10 @@ export const createAddScalar = /* #__PURE__ */ factory(name, dependencies, ({ ty res.value = addScalar(res.value, y.value) res.fixPrefix = false return res + }, + + 'Node, Node': function (x, y) { + return new OperatorNode('+', name, [x, y]) } }) diff --git a/test/unit-tests/function/arithmetic/addScalar.test.js b/test/unit-tests/function/arithmetic/addScalar.test.js index f14b0e9610..32cfc2e4e9 100644 --- a/test/unit-tests/function/arithmetic/addScalar.test.js +++ b/test/unit-tests/function/arithmetic/addScalar.test.js @@ -116,6 +116,17 @@ describe('addScalar', function () { approx.deepEqual(add(math.unit(math.complex(-3, 2), 'g'), math.unit(math.complex(5, -6), 'g')).toString(), '(2 - 4i) g') }) + it('should parse two expression nodes', function () { + const a = new math.ConstantNode(2) + const b = new math.ConstantNode(3) + const expr = math.parse('4 * 5') + + assert.deepStrictEqual(math.add(a, b), new math.OperatorNode('+', 'addScalar', [a, b])) + assert.deepStrictEqual(math.add(a, 3), new math.OperatorNode('+', 'addScalar', [a, b])) + assert.deepStrictEqual(math.add(2, b), new math.OperatorNode('+', 'addScalar', [a, b])) + assert.deepStrictEqual(math.add(2, expr), new math.OperatorNode('+', 'addScalar', [a, expr])) + }) + it('should throw an error for two measures of different units', function () { assert.throws(function () { add(math.unit(5, 'km'), math.unit(100, 'gram'))