diff --git a/lib/util/typed.js b/lib/util/typed.js new file mode 100644 index 000000000..e069db654 --- /dev/null +++ b/lib/util/typed.js @@ -0,0 +1,100 @@ +var typed = require('typed-function'); +var digits = require('./number').digits; + +/** + * Factory function for creating a new typed instance + * @param {Object} math + * @returns {function} + */ +exports.create = function create(math) { + // TODO: must create a separate instance of typed, with custom config. + // TODO: typed-function must be able to silently ignore signatures with unknown data types + + // configure typed functions + typed.types['Complex'] = function (x) { return x instanceof math.type.Complex; }; + typed.types['Range'] = function (x) { return x instanceof math.type.Range; }; + typed.types['Index'] = function (x) { return x instanceof math.type.Index; }; + typed.types['Matrix'] = function (x) { return x instanceof math.type.Matrix; }; + typed.types['Unit'] = function (x) { return x instanceof math.type.Unit; }; + typed.types['Help'] = function (x) { return x instanceof math.type.Help; }; + typed.types['ResultSet'] = function (x) { return x instanceof math.type.ResultSet; }; + typed.types['BigNumber'] = function (x) { return x instanceof math.type.BigNumber; }; + + typed.conversions = [ + { + from: 'number', + to: 'BigNumber', + convert: function (x) { + // note: conversion from number to BigNumber can fail if x has >15 digits + if (digits(x) > 15) { + throw new TypeError('Cannot implicitly convert a number with >15 significant digits to BigNumber ' + + '(value: ' + x + '). ' + + 'Use function bignumber(x) to convert to BigNumber.'); + } + return new math.type.BigNumber(x); + } + }, { + from: 'number', + to: 'Complex', + convert: function (x) { + return new math.type.Complex(x, 0); + } + }, { + from: 'number', + to: 'string', + convert: function (x) { + return x + ''; + } + }, { + from: 'BigNumber', + to: 'Complex', + convert: function (x) { + return new math.type.Complex(x.toNumber(), 0); + } + }, { + from: 'boolean', + to: 'number', + convert: function (x) { + return +x; + } + }, { + from: 'boolean', + to: 'BigNumber', + convert: function (x) { + return new math.type.BigNumber(+x); + } + }, { + from: 'boolean', + to: 'string', + convert: function (x) { + return +x; + } + }, { + from: 'null', + to: 'number', + convert: function () { + return 0; + } + }, { + from: 'null', + to: 'string', + convert: function () { + return 'null'; + } + }, { + from: 'null', + to: 'BigNumber', + convert: function () { + return new math.type.BigNumber(0); + } + }, { + from: 'Array', + to: 'Matrix', + convert: function (array) { + return new math.type.Matrix(array); + } + } + ]; + + return typed; +}; diff --git a/loader.js b/loader.js index 140df240c..4c6892da2 100644 --- a/loader.js +++ b/loader.js @@ -1,5 +1,4 @@ -var object = require('./lib/util/object'); -var digits = require('./lib/util/number').digits; +var isFactory = require('./lib/util/object').isFactory; /** * Math.js loader. Creates a new, empty math.js instance @@ -22,9 +21,8 @@ exports.create = function create () { type: {} }; - var typed = require('typed-function'); - // TODO: must create a separate instance of typed, with custom config. - // TODO: typed-function must be able to silently ignore signatures with unknown data types + // create a new typed instance + var typed = require('./lib/util/typed').create(math); // create configuration options. These are private var _config = { @@ -50,7 +48,7 @@ exports.create = function create () { * @returns {*} */ function load (factory) { - if (!object.isFactory(factory)) { + if (!isFactory(factory)) { throw new Error('Factory object with properties `type`, `name`, and `factory` expected'); } @@ -82,92 +80,6 @@ exports.create = function create () { // constants, and types math['import'] = load(require('./lib/function/utils/import')); - // configure typed functions - typed.types['Complex'] = function (x) { return x instanceof math.type.Complex; }; - typed.types['Range'] = function (x) { return x instanceof math.type.Range; }; - typed.types['Index'] = function (x) { return x instanceof math.type.Index; }; - typed.types['Matrix'] = function (x) { return x instanceof math.type.Matrix; }; - typed.types['Unit'] = function (x) { return x instanceof math.type.Unit; }; - typed.types['Help'] = function (x) { return x instanceof math.type.Help; }; - typed.types['ResultSet'] = function (x) { return x instanceof math.type.ResultSet; }; - typed.types['BigNumber'] = function (x) { return x instanceof math.type.BigNumber; }; - - typed.conversions = [ - { - from: 'number', - to: 'BigNumber', - convert: function (x) { - // note: conversion from number to BigNumber can fail if x has >15 digits - if (digits(x) > 15) { - throw new TypeError('Cannot implicitly convert a number with >15 significant digits to BigNumber ' + - '(value: ' + x + '). ' + - 'Use function bignumber(x) to convert to BigNumber.'); - } - return new math.type.BigNumber(x); - } - }, { - from: 'number', - to: 'Complex', - convert: function (x) { - return new math.type.Complex(x, 0); - } - }, { - from: 'number', - to: 'string', - convert: function (x) { - return x + ''; - } - }, { - from: 'BigNumber', - to: 'Complex', - convert: function (x) { - return new math.type.Complex(x.toNumber(), 0); - } - }, { - from: 'boolean', - to: 'number', - convert: function (x) { - return +x; - } - }, { - from: 'boolean', - to: 'BigNumber', - convert: function (x) { - return new math.type.BigNumber(+x); - } - }, { - from: 'boolean', - to: 'string', - convert: function (x) { - return +x; - } - }, { - from: 'null', - to: 'number', - convert: function () { - return 0; - } - }, { - from: 'null', - to: 'string', - convert: function () { - return 'null'; - } - }, { - from: 'null', - to: 'BigNumber', - convert: function () { - return new math.type.BigNumber(0); - } - }, { - from: 'Array', - to: 'Matrix', - convert: function (array) { - return new math.type.Matrix(array); - } - } - ]; - // FIXME: load constants via math.import() like all functions (problem: it must be reloaded when config changes) // constants require('./lib/constants')(math, _config);