3 var common = require('../common');
4 var Type = require('../type');
6 var YAML_FLOAT_PATTERN = new RegExp(
7 // 2.5e4, 2.5 and integers
8 '^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +
10 // special case, seems not from spec
11 '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +
13 '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
15 '|[-+]?\\.(?:inf|Inf|INF)' +
17 '|\\.(?:nan|NaN|NAN))$');
19 function resolveYamlFloat(data) {
20 if (data === null) return false;
22 if (!YAML_FLOAT_PATTERN.test(data) ||
23 // Quick hack to not allow integers end with `_`
24 // Probably should update regexp & check speed
25 data[data.length - 1] === '_') {
32 function constructYamlFloat(data) {
33 var value, sign, base, digits;
35 value = data.replace(/_/g, '').toLowerCase();
36 sign = value[0] === '-' ? -1 : 1;
39 if ('+-'.indexOf(value[0]) >= 0) {
40 value = value.slice(1);
43 if (value === '.inf') {
44 return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
46 } else if (value === '.nan') {
49 } else if (value.indexOf(':') >= 0) {
50 value.split(':').forEach(function (v) {
51 digits.unshift(parseFloat(v, 10));
57 digits.forEach(function (d) {
65 return sign * parseFloat(value, 10);
69 var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
71 function representYamlFloat(object, style) {
76 case 'lowercase': return '.nan';
77 case 'uppercase': return '.NAN';
78 case 'camelcase': return '.NaN';
80 } else if (Number.POSITIVE_INFINITY === object) {
82 case 'lowercase': return '.inf';
83 case 'uppercase': return '.INF';
84 case 'camelcase': return '.Inf';
86 } else if (Number.NEGATIVE_INFINITY === object) {
88 case 'lowercase': return '-.inf';
89 case 'uppercase': return '-.INF';
90 case 'camelcase': return '-.Inf';
92 } else if (common.isNegativeZero(object)) {
96 res = object.toString(10);
98 // JS stringifier can build scientific format without dots: 5e-100,
99 // while YAML requres dot: 5.e-100. Fix it with simple hack
101 return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
104 function isFloat(object) {
105 return (Object.prototype.toString.call(object) === '[object Number]') &&
106 (object % 1 !== 0 || common.isNegativeZero(object));
109 module.exports = new Type('tag:yaml.org,2002:float', {
111 resolve: resolveYamlFloat,
112 construct: constructYamlFloat,
114 represent: representYamlFloat,
115 defaultStyle: 'lowercase'