barefoot_js 0.39.3 → 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.
- checksums.yaml +4 -4
- data/lib/barefoot_js/evaluator.rb +51 -34
- data/lib/barefoot_js.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4c4ebbb9319c464c569e177922099bf053ac8a57173ca1dd51e72ac45e68b27b
|
|
4
|
+
data.tar.gz: f211b6e607b11d954e29967c6cca359aa459853ce61c2979b3e415fb685a0db7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56ad319dee5b7974e917321dce07fef04f435e1a9c1f96ba365930eb0671bc671ba60777bfafb58f128f306d6c6edce9e4b8cf08856f4a37ee7e371693eb1ac1
|
|
7
|
+
data.tar.gz: 4ac7bcb135489b27fa363d9549af7421c1e21108dbb30acbc6292730b6b2460bb7c9167c9d2b8342e91a5d9325da5434525dff64ec9d1143c9af93b52f8bc8bd
|
|
@@ -225,38 +225,67 @@ module BarefootJS
|
|
|
225
225
|
end
|
|
226
226
|
private_class_method :parse_numeric_string
|
|
227
227
|
|
|
228
|
-
# JS Number#toString. Integral finite values (however they
|
|
229
|
-
# Integer or an integral Float) render without a
|
|
230
|
-
# ("1.0" -> "1"); non-finite values use the JS spellings
|
|
231
|
-
# "Infinity" / "-Infinity"), which Ruby's own Float#to_s does
|
|
232
|
-
#
|
|
233
|
-
# (the same
|
|
234
|
-
#
|
|
235
|
-
#
|
|
236
|
-
#
|
|
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 <
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
|
258
278
|
# ---------------------------------------------------------------------
|
|
259
279
|
|
|
280
|
+
# JS `/`: both operands through `to_number` (JS `Number()`), then IEEE
|
|
281
|
+
# Float division, which already gives JS's division-by-zero results
|
|
282
|
+
# (`1 / 0` -> Infinity, `1 / -0` -> -Infinity, `0 / 0` -> NaN). Shared by
|
|
283
|
+
# callback-body evaluation (`binary`) and template-emitted division
|
|
284
|
+
# (`Context#div`), so both coerce and divide identically (#3328).
|
|
285
|
+
def divide(l, r)
|
|
286
|
+
to_number(l).to_f / to_number(r).to_f
|
|
287
|
+
end
|
|
288
|
+
|
|
260
289
|
def binary(op, l, r)
|
|
261
290
|
case op
|
|
262
291
|
when '+'
|
|
@@ -267,19 +296,7 @@ module BarefootJS
|
|
|
267
296
|
to_number(l) + to_number(r)
|
|
268
297
|
when '-' then to_number(l) - to_number(r)
|
|
269
298
|
when '*' then to_number(l) * to_number(r)
|
|
270
|
-
when '/'
|
|
271
|
-
ln = to_number(l).to_f
|
|
272
|
-
rn = to_number(r).to_f
|
|
273
|
-
if rn.zero?
|
|
274
|
-
# JS division by zero is finite-valued, not an error.
|
|
275
|
-
if ln.zero? || ln.nan?
|
|
276
|
-
Float::NAN
|
|
277
|
-
else
|
|
278
|
-
ln.positive? ? Float::INFINITY : -Float::INFINITY
|
|
279
|
-
end
|
|
280
|
-
else
|
|
281
|
-
ln / rn
|
|
282
|
-
end
|
|
299
|
+
when '/' then divide(l, r)
|
|
283
300
|
when '%'
|
|
284
301
|
rn = to_number(r).to_f
|
|
285
302
|
rn.zero? ? Float::NAN : to_number(l).to_f.remainder(rn)
|
data/lib/barefoot_js.rb
CHANGED
|
@@ -521,6 +521,15 @@ module BarefootJS
|
|
|
521
521
|
html_escape(string(value))
|
|
522
522
|
end
|
|
523
523
|
|
|
524
|
+
# JS `/`: always a Number quotient. Ruby's `/` on two Integers is
|
|
525
|
+
# integer division (`1234567890 / 4` -> `308641972`, `-7 / 4` -> `-2`),
|
|
526
|
+
# so template-emitted division goes through the shared evaluator's JS
|
|
527
|
+
# division instead -- JS operand coercion, fractional quotient kept,
|
|
528
|
+
# division by zero yielding Infinity / -Infinity / NaN (#3328).
|
|
529
|
+
def div(left, right)
|
|
530
|
+
Evaluator.divide(left, right)
|
|
531
|
+
end
|
|
532
|
+
|
|
524
533
|
# JS truthiness (falsy: false, nil, 0, NaN, ""). Delegates to the
|
|
525
534
|
# shared evaluator so template-emitted conditionals
|
|
526
535
|
# (`if bf.truthy?(x)`) and callback-body evaluation agree byte-for-byte.
|
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
|
+
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-
|
|
11
|
+
date: 2026-10-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: tzinfo
|