barefoot_js 0.39.4 → 0.39.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/barefoot_js/evaluator.rb +41 -21
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c580c611349599cee9196a947d183ff3db8bf9e686cddb22f2a89db07b0756f9
4
- data.tar.gz: 8ca4936908abe8290062b911284be9a88dd1eee21dc24661104b7f54c412425d
3
+ metadata.gz: 4c4ebbb9319c464c569e177922099bf053ac8a57173ca1dd51e72ac45e68b27b
4
+ data.tar.gz: f211b6e607b11d954e29967c6cca359aa459853ce61c2979b3e415fb685a0db7
5
5
  SHA512:
6
- metadata.gz: 5b682cfb8e51594866f226b62adc416fc0e35b45c1f20b6500e73670f6c71bf86cfa2da104c465ad5f8227d83e1aaee347606abbf8bef141938e75283d72109c
7
- data.tar.gz: 8e43ed9624e01bba9b63ac69872e46a45632f7bb9807c9e70b4ed98c1d0e043ab2c0709eb38857e182de4c9ea5e07e006f0d9d4e9d56ee02c4fddacf9c1e1e56
6
+ metadata.gz: 56ad319dee5b7974e917321dce07fef04f435e1a9c1f96ba365930eb0671bc671ba60777bfafb58f128f306d6c6edce9e4b8cf08856f4a37ee7e371693eb1ac1
7
+ data.tar.gz: 4ac7bcb135489b27fa363d9549af7421c1e21108dbb30acbc6292730b6b2460bb7c9167c9d2b8342e91a5d9325da5434525dff64ec9d1143c9af93b52f8bc8bd
@@ -225,33 +225,53 @@ module BarefootJS
225
225
  end
226
226
  private_class_method :parse_numeric_string
227
227
 
228
- # JS Number#toString. Integral finite values (however they arrived --
229
- # Integer or an integral Float) render without a decimal point
230
- # ("1.0" -> "1"); non-finite values use the JS spellings ("NaN" /
231
- # "Infinity" / "-Infinity"), which Ruby's own Float#to_s does not use.
232
- # Non-integral floats fall back to Ruby's shortest-round-trip Float#to_s
233
- # (the same class of algorithm V8 uses), reformatted to JS's exponent
234
- # style. This is not the full ECMA-262 Number::toString grammar (no
235
- # attempt to match JS's exact exponential-notation thresholds), but it
236
- # is exact for every value the golden vectors exercise.
228
+ # JS Number#toString. Integral finite values below 2**53 (however they
229
+ # arrived -- Integer or an integral Float) render exactly, without a
230
+ # decimal point ("1.0" -> "1"); non-finite values use the JS spellings
231
+ # ("NaN" / "Infinity" / "-Infinity"), which Ruby's own Float#to_s does
232
+ # not use. Everything else takes Ruby's shortest-round-trip Float#to_s
233
+ # digits (the same digits V8 picks) re-spelled with ECMA-262's notation
234
+ # rules: decimal within [1e-6, 1e21), otherwise an unpadded lower-case
235
+ # exponent (`1.23456789e-7`, `1.23456789e+21`) -- Ruby switches to an
236
+ # exponent below 1e-4 and pads it (`1.23456789e-06`) (#3380).
237
237
  def number_to_string(n)
238
238
  f = n.to_f
239
239
  return 'NaN' if f.nan?
240
240
  return f.negative? ? '-Infinity' : 'Infinity' if f.infinite?
241
241
  return '0' if f.zero?
242
- return n.to_i.to_s if f == f.to_i && f.abs < 1e21
243
-
244
- s = f.to_s
245
- if s.include?('e')
246
- mantissa, exp = s.split('e')
247
- mantissa = mantissa.sub(/\.0\z/, '')
248
- sign = exp.start_with?('-') ? '-' : '+'
249
- digits = exp.sub(/\A[+-]/, '').sub(/\A0+(?=\d)/, '')
250
- "#{mantissa}e#{sign}#{digits}"
251
- else
252
- s
253
- end
242
+ return n.to_i.to_s if f == f.to_i && f.abs < 2**53
243
+
244
+ js_notation(f.to_s)
245
+ end
246
+
247
+ # Re-spell a shortest round-trip decimal (`[-]d[.ddd][e[+-]x]`) with the
248
+ # ECMA-262 Number::toString notation rules: `digits` holds the
249
+ # significant digits, `point` where the decimal point falls in them.
250
+ def js_notation(shortest)
251
+ sign = shortest.start_with?('-') ? '-' : ''
252
+ mantissa, exp = shortest.delete_prefix('-').downcase.split('e', 2)
253
+ int_part, frac_part = mantissa.split('.', 2)
254
+ raw = int_part + (frac_part || '')
255
+ point = int_part.length + (exp ? exp.to_i : 0)
256
+ digits = raw.sub(/\A0+/, '')
257
+ point -= raw.length - digits.length
258
+ digits = digits.sub(/0+\z/, '')
259
+ digits = '0' if digits.empty?
260
+ k = digits.length
261
+ out =
262
+ if k <= point && point <= 21
263
+ digits + ('0' * (point - k))
264
+ elsif point.positive? && point <= 21
265
+ "#{digits[0, point]}.#{digits[point..]}"
266
+ elsif point > -6 && point <= 0
267
+ "0.#{'0' * -point}#{digits}"
268
+ else
269
+ e = point - 1
270
+ "#{digits[0]}#{k > 1 ? ".#{digits[1..]}" : ''}e#{e >= 0 ? '+' : '-'}#{e.abs}"
271
+ end
272
+ sign + out
254
273
  end
274
+ private_class_method :js_notation
255
275
 
256
276
  # ---------------------------------------------------------------------
257
277
  # Operators
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: barefoot_js
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.4
4
+ version: 0.39.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - kobaken
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-08 00:00:00.000000000 Z
11
+ date: 2026-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo