goscript 0.0.33 → 0.0.35
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.
- package/compiler/analysis.go +30 -22
- package/compiler/analysis_test.go +14 -0
- package/compiler/assignment.go +45 -7
- package/compiler/builtin_test.go +2 -0
- package/compiler/compiler.go +15 -89
- package/compiler/compiler_test.go +0 -53
- package/compiler/composite-lit.go +60 -17
- package/compiler/decl.go +1 -1
- package/compiler/expr-call.go +347 -30
- package/compiler/expr-selector.go +28 -2
- package/compiler/expr.go +79 -38
- package/compiler/lit.go +112 -3
- package/compiler/primitive.go +6 -6
- package/compiler/protobuf.go +0 -5
- package/compiler/sanitize.go +101 -0
- package/compiler/spec-value.go +25 -18
- package/compiler/stmt-assign.go +128 -91
- package/compiler/stmt-for.go +78 -1
- package/compiler/stmt-range.go +333 -461
- package/compiler/stmt.go +46 -9
- package/compiler/type.go +14 -11
- package/dist/gs/builtin/builtin.d.ts +8 -0
- package/dist/gs/builtin/builtin.js +31 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/map.d.ts +4 -4
- package/dist/gs/builtin/map.js +12 -6
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +14 -8
- package/dist/gs/builtin/slice.js +131 -31
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.d.ts +13 -0
- package/dist/gs/github.com/pkg/errors/errors.js +232 -0
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/go113.d.ts +4 -0
- package/dist/gs/github.com/pkg/errors/go113.js +34 -0
- package/dist/gs/github.com/pkg/errors/go113.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/index.d.ts +3 -0
- package/dist/gs/github.com/pkg/errors/index.js +4 -0
- package/dist/gs/github.com/pkg/errors/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/stack.d.ts +32 -0
- package/dist/gs/github.com/pkg/errors/stack.js +111 -0
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -0
- package/dist/gs/maps/index.d.ts +2 -0
- package/dist/gs/maps/index.js +3 -0
- package/dist/gs/maps/index.js.map +1 -0
- package/dist/gs/maps/iter.d.ts +7 -0
- package/dist/gs/maps/iter.gs.d.ts +7 -0
- package/dist/gs/maps/iter.gs.js +65 -0
- package/dist/gs/maps/iter.gs.js.map +1 -0
- package/dist/gs/maps/iter.js +57 -0
- package/dist/gs/maps/iter.js.map +1 -0
- package/dist/gs/maps/maps.d.ts +7 -0
- package/dist/gs/maps/maps.gs.d.ts +7 -0
- package/dist/gs/maps/maps.gs.js +79 -0
- package/dist/gs/maps/maps.gs.js.map +1 -0
- package/dist/gs/maps/maps.js +67 -0
- package/dist/gs/maps/maps.js.map +1 -0
- package/dist/gs/math/abs.gs.d.ts +1 -0
- package/dist/gs/math/abs.gs.js +10 -0
- package/dist/gs/math/abs.gs.js.map +1 -0
- package/dist/gs/math/acosh.gs.d.ts +2 -0
- package/dist/gs/math/acosh.gs.js +14 -0
- package/dist/gs/math/acosh.gs.js.map +1 -0
- package/dist/gs/math/asin.gs.d.ts +4 -0
- package/dist/gs/math/asin.gs.js +24 -0
- package/dist/gs/math/asin.gs.js.map +1 -0
- package/dist/gs/math/asinh.gs.d.ts +2 -0
- package/dist/gs/math/asinh.gs.js +14 -0
- package/dist/gs/math/asinh.gs.js.map +1 -0
- package/dist/gs/math/atan.gs.d.ts +4 -0
- package/dist/gs/math/atan.gs.js +22 -0
- package/dist/gs/math/atan.gs.js.map +1 -0
- package/dist/gs/math/atan2.gs.d.ts +2 -0
- package/dist/gs/math/atan2.gs.js +30 -0
- package/dist/gs/math/atan2.gs.js.map +1 -0
- package/dist/gs/math/atanh.gs.d.ts +2 -0
- package/dist/gs/math/atanh.gs.js +16 -0
- package/dist/gs/math/atanh.gs.js.map +1 -0
- package/dist/gs/math/bits.gs.d.ts +5 -0
- package/dist/gs/math/bits.gs.js +46 -0
- package/dist/gs/math/bits.gs.js.map +1 -0
- package/dist/gs/math/cbrt.gs.d.ts +2 -0
- package/dist/gs/math/cbrt.gs.js +14 -0
- package/dist/gs/math/cbrt.gs.js.map +1 -0
- package/dist/gs/math/const.gs.d.ts +30 -0
- package/dist/gs/math/const.gs.js +61 -0
- package/dist/gs/math/const.gs.js.map +1 -0
- package/dist/gs/math/copysign.gs.d.ts +1 -0
- package/dist/gs/math/copysign.gs.js +20 -0
- package/dist/gs/math/copysign.gs.js.map +1 -0
- package/dist/gs/math/dim.gs.d.ts +5 -0
- package/dist/gs/math/dim.gs.js +69 -0
- package/dist/gs/math/dim.gs.js.map +1 -0
- package/dist/gs/math/erf.gs.d.ts +4 -0
- package/dist/gs/math/erf.gs.js +336 -0
- package/dist/gs/math/erf.gs.js.map +1 -0
- package/dist/gs/math/erfinv.gs.d.ts +2 -0
- package/dist/gs/math/erfinv.gs.js +118 -0
- package/dist/gs/math/erfinv.gs.js.map +1 -0
- package/dist/gs/math/exp.gs.d.ts +5 -0
- package/dist/gs/math/exp.gs.js +30 -0
- package/dist/gs/math/exp.gs.js.map +1 -0
- package/dist/gs/math/expm1.gs.d.ts +2 -0
- package/dist/gs/math/expm1.gs.js +17 -0
- package/dist/gs/math/expm1.gs.js.map +1 -0
- package/dist/gs/math/floor.gs.d.ts +8 -0
- package/dist/gs/math/floor.gs.js +75 -0
- package/dist/gs/math/floor.gs.js.map +1 -0
- package/dist/gs/math/fma.gs.d.ts +1 -0
- package/dist/gs/math/fma.gs.js +8 -0
- package/dist/gs/math/fma.gs.js.map +1 -0
- package/dist/gs/math/frexp.gs.d.ts +2 -0
- package/dist/gs/math/frexp.gs.js +28 -0
- package/dist/gs/math/frexp.gs.js.map +1 -0
- package/dist/gs/math/gamma.gs.d.ts +3 -0
- package/dist/gs/math/gamma.gs.js +149 -0
- package/dist/gs/math/gamma.gs.js.map +1 -0
- package/dist/gs/math/hypot.gs.d.ts +2 -0
- package/dist/gs/math/hypot.gs.js +16 -0
- package/dist/gs/math/hypot.gs.js.map +1 -0
- package/dist/gs/math/index.d.ts +44 -0
- package/dist/gs/math/index.js +45 -0
- package/dist/gs/math/index.js.map +1 -0
- package/dist/gs/math/j0.gs.d.ts +4 -0
- package/dist/gs/math/j0.gs.js +228 -0
- package/dist/gs/math/j0.gs.js.map +1 -0
- package/dist/gs/math/j1.gs.d.ts +4 -0
- package/dist/gs/math/j1.gs.js +211 -0
- package/dist/gs/math/j1.gs.js.map +1 -0
- package/dist/gs/math/jn.gs.d.ts +2 -0
- package/dist/gs/math/jn.gs.js +412 -0
- package/dist/gs/math/jn.gs.js.map +1 -0
- package/dist/gs/math/ldexp.gs.d.ts +2 -0
- package/dist/gs/math/ldexp.gs.js +20 -0
- package/dist/gs/math/ldexp.gs.js.map +1 -0
- package/dist/gs/math/lgamma.gs.d.ts +2 -0
- package/dist/gs/math/lgamma.gs.js +243 -0
- package/dist/gs/math/lgamma.gs.js.map +1 -0
- package/dist/gs/math/log.gs.d.ts +2 -0
- package/dist/gs/math/log.gs.js +16 -0
- package/dist/gs/math/log.gs.js.map +1 -0
- package/dist/gs/math/log10.gs.d.ts +4 -0
- package/dist/gs/math/log10.gs.js +17 -0
- package/dist/gs/math/log10.gs.js.map +1 -0
- package/dist/gs/math/log1p.gs.d.ts +2 -0
- package/dist/gs/math/log1p.gs.js +17 -0
- package/dist/gs/math/log1p.gs.js.map +1 -0
- package/dist/gs/math/logb.gs.d.ts +3 -0
- package/dist/gs/math/logb.gs.js +43 -0
- package/dist/gs/math/logb.gs.js.map +1 -0
- package/dist/gs/math/mod.gs.d.ts +2 -0
- package/dist/gs/math/mod.gs.js +26 -0
- package/dist/gs/math/mod.gs.js.map +1 -0
- package/dist/gs/math/modf.gs.d.ts +2 -0
- package/dist/gs/math/modf.gs.js +24 -0
- package/dist/gs/math/modf.gs.js.map +1 -0
- package/dist/gs/math/nextafter.gs.d.ts +2 -0
- package/dist/gs/math/nextafter.gs.js +66 -0
- package/dist/gs/math/nextafter.gs.js.map +1 -0
- package/dist/gs/math/pow.gs.d.ts +3 -0
- package/dist/gs/math/pow.gs.js +40 -0
- package/dist/gs/math/pow.gs.js.map +1 -0
- package/dist/gs/math/pow10.gs.d.ts +1 -0
- package/dist/gs/math/pow10.gs.js +14 -0
- package/dist/gs/math/pow10.gs.js.map +1 -0
- package/dist/gs/math/remainder.gs.d.ts +2 -0
- package/dist/gs/math/remainder.gs.js +25 -0
- package/dist/gs/math/remainder.gs.js.map +1 -0
- package/dist/gs/math/signbit.gs.d.ts +1 -0
- package/dist/gs/math/signbit.gs.js +5 -0
- package/dist/gs/math/signbit.gs.js.map +1 -0
- package/dist/gs/math/sin.gs.d.ts +4 -0
- package/dist/gs/math/sin.gs.js +29 -0
- package/dist/gs/math/sin.gs.js.map +1 -0
- package/dist/gs/math/sincos.gs.d.ts +1 -0
- package/dist/gs/math/sincos.gs.js +11 -0
- package/dist/gs/math/sincos.gs.js.map +1 -0
- package/dist/gs/math/sinh.gs.d.ts +4 -0
- package/dist/gs/math/sinh.gs.js +27 -0
- package/dist/gs/math/sinh.gs.js.map +1 -0
- package/dist/gs/math/sqrt.gs.d.ts +2 -0
- package/dist/gs/math/sqrt.gs.js +15 -0
- package/dist/gs/math/sqrt.gs.js.map +1 -0
- package/dist/gs/math/tan.gs.d.ts +2 -0
- package/dist/gs/math/tan.gs.js +17 -0
- package/dist/gs/math/tan.gs.js.map +1 -0
- package/dist/gs/math/tanh.gs.d.ts +2 -0
- package/dist/gs/math/tanh.gs.js +17 -0
- package/dist/gs/math/tanh.gs.js.map +1 -0
- package/dist/gs/math/trig_reduce.gs.d.ts +1 -0
- package/dist/gs/math/trig_reduce.gs.js +62 -0
- package/dist/gs/math/trig_reduce.gs.js.map +1 -0
- package/dist/gs/math/unsafe.gs.d.ts +4 -0
- package/dist/gs/math/unsafe.gs.js +47 -0
- package/dist/gs/math/unsafe.gs.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +6 -0
- package/dist/gs/slices/slices.js +8 -0
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/strconv/atob.gs.d.ts +4 -0
- package/dist/gs/strconv/atob.gs.js +42 -0
- package/dist/gs/strconv/atob.gs.js.map +1 -0
- package/dist/gs/strconv/atof.gs.d.ts +2 -0
- package/dist/gs/strconv/atof.gs.js +51 -0
- package/dist/gs/strconv/atof.gs.js.map +1 -0
- package/dist/gs/strconv/atoi.gs.d.ts +33 -0
- package/dist/gs/strconv/atoi.gs.js +200 -0
- package/dist/gs/strconv/atoi.gs.js.map +1 -0
- package/dist/gs/strconv/doc.gs.d.ts +1 -0
- package/dist/gs/strconv/doc.gs.js +2 -0
- package/dist/gs/strconv/doc.gs.js.map +1 -0
- package/dist/gs/strconv/ftoa.gs.d.ts +3 -0
- package/dist/gs/strconv/ftoa.gs.js +58 -0
- package/dist/gs/strconv/ftoa.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +6 -0
- package/dist/gs/strconv/index.js +7 -0
- package/dist/gs/strconv/index.js.map +1 -0
- package/dist/gs/strconv/itoa.gs.d.ts +6 -0
- package/dist/gs/strconv/itoa.gs.js +37 -0
- package/dist/gs/strconv/itoa.gs.js.map +1 -0
- package/dist/gs/strconv/quote.gs.d.ts +19 -0
- package/dist/gs/strconv/quote.gs.js +217 -0
- package/dist/gs/strconv/quote.gs.js.map +1 -0
- package/dist/gs/strings/index.d.ts +3 -0
- package/dist/gs/strings/index.js +4 -0
- package/dist/gs/strings/index.js.map +1 -1
- package/dist/gs/strings/replace.d.ts +0 -74
- package/dist/gs/strings/replace.js +6 -204
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/search.d.ts +0 -1
- package/dist/gs/strings/search.js +0 -21
- package/dist/gs/strings/search.js.map +1 -1
- package/gs/builtin/builtin.ts +40 -0
- package/gs/builtin/map.ts +12 -7
- package/gs/builtin/slice.ts +174 -34
- package/gs/github.com/pkg/errors/errors.ts +307 -0
- package/gs/github.com/pkg/errors/go113.ts +39 -0
- package/gs/github.com/pkg/errors/index.ts +3 -0
- package/gs/github.com/pkg/errors/stack.ts +127 -0
- package/gs/maps/index.ts +2 -0
- package/gs/maps/iter.ts +67 -0
- package/gs/maps/maps.ts +89 -0
- package/gs/math/TODO.md +156 -0
- package/gs/math/abs.gs.test.ts +29 -0
- package/gs/math/abs.gs.ts +13 -0
- package/gs/math/acosh.gs.test.ts +39 -0
- package/gs/math/acosh.gs.ts +21 -0
- package/gs/math/asin.gs.test.ts +66 -0
- package/gs/math/asin.gs.ts +27 -0
- package/gs/math/asinh.gs.test.ts +37 -0
- package/gs/math/asinh.gs.ts +21 -0
- package/gs/math/atan.gs.test.ts +49 -0
- package/gs/math/atan.gs.ts +27 -0
- package/gs/math/atan2.gs.test.ts +55 -0
- package/gs/math/atan2.gs.ts +37 -0
- package/gs/math/atanh.gs.test.ts +47 -0
- package/gs/math/atanh.gs.ts +21 -0
- package/gs/math/bits.gs.test.ts +88 -0
- package/gs/math/bits.gs.ts +61 -0
- package/gs/math/cbrt.gs.test.ts +57 -0
- package/gs/math/cbrt.gs.ts +20 -0
- package/gs/math/const.gs.test.ts +54 -0
- package/gs/math/const.gs.ts +93 -0
- package/gs/math/copysign.gs.test.ts +44 -0
- package/gs/math/copysign.gs.ts +27 -0
- package/gs/math/dim.gs.test.ts +102 -0
- package/gs/math/dim.gs.ts +84 -0
- package/gs/math/erf.gs.test.ts +92 -0
- package/gs/math/erf.gs.ts +409 -0
- package/gs/math/erfinv.gs.test.ts +104 -0
- package/gs/math/erfinv.gs.ts +169 -0
- package/gs/math/exp.gs.test.ts +82 -0
- package/gs/math/exp.gs.ts +39 -0
- package/gs/math/expm1.gs.test.ts +48 -0
- package/gs/math/expm1.gs.ts +23 -0
- package/gs/math/floor.gs.test.ts +146 -0
- package/gs/math/floor.gs.ts +88 -0
- package/gs/math/fma.gs.test.ts +83 -0
- package/gs/math/fma.gs.ts +7 -0
- package/gs/math/frexp.gs.test.ts +146 -0
- package/gs/math/frexp.gs.ts +37 -0
- package/gs/math/gamma.gs.test.ts +66 -0
- package/gs/math/gamma.gs.ts +158 -0
- package/gs/math/hypot.gs.test.ts +73 -0
- package/gs/math/hypot.gs.ts +23 -0
- package/gs/math/index.ts +44 -0
- package/gs/math/j0.gs.test.ts +74 -0
- package/gs/math/j0.gs.ts +257 -0
- package/gs/math/j1.gs.test.ts +81 -0
- package/gs/math/j1.gs.ts +231 -0
- package/gs/math/jn.gs.test.ts +133 -0
- package/gs/math/jn.gs.ts +447 -0
- package/gs/math/ldexp.gs.test.ts +128 -0
- package/gs/math/ldexp.gs.ts +28 -0
- package/gs/math/lgamma.gs.test.ts +102 -0
- package/gs/math/lgamma.gs.ts +251 -0
- package/gs/math/log.gs.test.ts +40 -0
- package/gs/math/log.gs.ts +21 -0
- package/gs/math/log10.gs.test.ts +80 -0
- package/gs/math/log10.gs.ts +25 -0
- package/gs/math/log1p.gs.test.ts +55 -0
- package/gs/math/log1p.gs.ts +24 -0
- package/gs/math/logb.gs.test.ts +87 -0
- package/gs/math/logb.gs.ts +54 -0
- package/gs/math/mod.gs.test.ts +64 -0
- package/gs/math/mod.gs.ts +36 -0
- package/gs/math/modf.gs.test.ts +80 -0
- package/gs/math/modf.gs.ts +32 -0
- package/gs/math/nextafter.gs.test.ts +107 -0
- package/gs/math/nextafter.gs.ts +71 -0
- package/gs/math/pow.gs.test.ts +103 -0
- package/gs/math/pow.gs.ts +55 -0
- package/gs/math/pow10.gs.test.ts +58 -0
- package/gs/math/pow10.gs.ts +19 -0
- package/gs/math/remainder.gs.test.ts +70 -0
- package/gs/math/remainder.gs.ts +33 -0
- package/gs/math/signbit.gs.test.ts +33 -0
- package/gs/math/signbit.gs.ts +8 -0
- package/gs/math/sin.gs.test.ts +83 -0
- package/gs/math/sin.gs.ts +38 -0
- package/gs/math/sincos.gs.test.ts +91 -0
- package/gs/math/sincos.gs.ts +15 -0
- package/gs/math/sinh.gs.test.ts +66 -0
- package/gs/math/sinh.gs.ts +34 -0
- package/gs/math/sqrt.gs.test.ts +49 -0
- package/gs/math/sqrt.gs.ts +20 -0
- package/gs/math/tan.gs.test.ts +50 -0
- package/gs/math/tan.gs.ts +23 -0
- package/gs/math/tanh.gs.test.ts +52 -0
- package/gs/math/tanh.gs.ts +23 -0
- package/gs/math/trig_reduce.gs.ts +66 -0
- package/gs/math/unsafe.gs.ts +52 -0
- package/gs/slices/slices.ts +9 -0
- package/gs/strconv/atob.gs.ts +45 -0
- package/gs/strconv/atof.gs.ts +60 -0
- package/gs/strconv/atoi.gs.ts +243 -0
- package/gs/strconv/doc.gs.ts +2 -0
- package/gs/strconv/ftoa.gs.ts +66 -0
- package/gs/strconv/index.ts +6 -0
- package/gs/strconv/itoa.gs.ts +41 -0
- package/gs/strconv/quote.gs.ts +245 -0
- package/gs/strings/index.ts +4 -0
- package/gs/strings/replace.ts +9 -237
- package/gs/strings/search.ts +0 -28
- package/package.json +1 -1
- package/gs/stringslite/godoc.txt +0 -17
- package/gs/stringslite/index.ts +0 -1
- package/gs/stringslite/strings.ts +0 -82
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { IsInf, IsNaN, NaN } from "./bits.gs.js";
|
|
3
|
+
import { trigReduce } from "./trig_reduce.gs.js";
|
|
4
|
+
|
|
5
|
+
let _tanP = $.arrayToSlice<number>([-1.30936939181383777646e4, 1.15351664838587416140e6, -1.79565251976484877988e7])
|
|
6
|
+
|
|
7
|
+
let _tanQ = $.arrayToSlice<number>([1.00000000000000000000e0, 1.36812963470692954678e4, -1.32089234440210967447e6, 2.50083801823357915839e7, -5.38695755929454629881e7])
|
|
8
|
+
|
|
9
|
+
// Tan returns the tangent of the radian argument x.
|
|
10
|
+
//
|
|
11
|
+
// Special cases are:
|
|
12
|
+
//
|
|
13
|
+
// Tan(±0) = ±0
|
|
14
|
+
// Tan(±Inf) = NaN
|
|
15
|
+
// Tan(NaN) = NaN
|
|
16
|
+
export function Tan(x: number): number {
|
|
17
|
+
return Math.tan(x)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function tan(x: number): number {
|
|
21
|
+
return Math.tan(x)
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { Tanh, tanh } from './tanh.gs.js'
|
|
3
|
+
|
|
4
|
+
describe('Tanh', () => {
|
|
5
|
+
it('should return correct hyperbolic tangent values', () => {
|
|
6
|
+
expect(Tanh(0)).toBe(0)
|
|
7
|
+
expect(Tanh(-0)).toBe(-0)
|
|
8
|
+
expect(Tanh(1)).toBeCloseTo(0.7615941559557649, 14)
|
|
9
|
+
expect(Tanh(-1)).toBeCloseTo(-0.7615941559557649, 14)
|
|
10
|
+
expect(Tanh(2)).toBeCloseTo(0.9640275800758169, 14)
|
|
11
|
+
expect(Tanh(-2)).toBeCloseTo(-0.9640275800758169, 15)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('should approach ±1 for large values', () => {
|
|
15
|
+
// Relax tolerance for large values due to JavaScript precision limits
|
|
16
|
+
expect(Tanh(10)).toBeCloseTo(1, 8)
|
|
17
|
+
expect(Tanh(-10)).toBeCloseTo(-1, 8)
|
|
18
|
+
expect(Tanh(100)).toBeCloseTo(1, 8)
|
|
19
|
+
expect(Tanh(-100)).toBeCloseTo(-1, 8)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('should handle special values', () => {
|
|
23
|
+
expect(Tanh(Number.POSITIVE_INFINITY)).toBe(1)
|
|
24
|
+
expect(Tanh(Number.NEGATIVE_INFINITY)).toBe(-1)
|
|
25
|
+
expect(Number.isNaN(Tanh(Number.NaN))).toBe(true)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should handle edge cases', () => {
|
|
29
|
+
expect(Tanh(Number.MAX_VALUE)).toBe(1)
|
|
30
|
+
expect(Tanh(-Number.MAX_VALUE)).toBe(-1)
|
|
31
|
+
expect(Tanh(Number.MIN_VALUE)).toBeCloseTo(Number.MIN_VALUE, 14)
|
|
32
|
+
expect(Tanh(-Number.MIN_VALUE)).toBeCloseTo(-Number.MIN_VALUE, 14)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should be bounded between -1 and 1', () => {
|
|
36
|
+
const testValues = [-100, -10, -1, -0.5, 0, 0.5, 1, 10, 100]
|
|
37
|
+
for (const x of testValues) {
|
|
38
|
+
const result = Tanh(x)
|
|
39
|
+
expect(result).toBeGreaterThanOrEqual(-1)
|
|
40
|
+
expect(result).toBeLessThanOrEqual(1)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('tanh', () => {
|
|
46
|
+
it('should work the same as Tanh', () => {
|
|
47
|
+
expect(tanh(0)).toBe(Tanh(0))
|
|
48
|
+
expect(tanh(1)).toBe(Tanh(1))
|
|
49
|
+
expect(tanh(-1)).toBe(Tanh(-1))
|
|
50
|
+
expect(tanh(Number.POSITIVE_INFINITY)).toBe(Tanh(Number.POSITIVE_INFINITY))
|
|
51
|
+
})
|
|
52
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { Abs } from "./abs.gs.js";
|
|
3
|
+
import { Exp } from "./exp.gs.js";
|
|
4
|
+
|
|
5
|
+
let tanhP = $.arrayToSlice<number>([-9.64399179425052238628e-1, -9.92877231001918586564e1, -1.61468768441708447952e3])
|
|
6
|
+
|
|
7
|
+
let tanhQ = $.arrayToSlice<number>([1.12811678491632931402e2, 2.23548839060100448583e3, 4.84406305325125486048e3])
|
|
8
|
+
|
|
9
|
+
// Tanh returns the hyperbolic tangent of x.
|
|
10
|
+
//
|
|
11
|
+
// Special cases are:
|
|
12
|
+
//
|
|
13
|
+
// Tanh(±0) = ±0
|
|
14
|
+
// Tanh(±Inf) = ±1
|
|
15
|
+
// Tanh(NaN) = NaN
|
|
16
|
+
export function Tanh(x: number): number {
|
|
17
|
+
return Math.tanh(x)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function tanh(x: number): number {
|
|
21
|
+
return Math.tanh(x)
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { Float64bits, Float64frombits } from "./unsafe.gs.js";
|
|
3
|
+
|
|
4
|
+
import * as bits from "@goscript/math/bits/index.js"
|
|
5
|
+
|
|
6
|
+
let reduceThreshold: number = (1 << 29)
|
|
7
|
+
|
|
8
|
+
// trigReduce implements Payne-Hanek range reduction by Pi/4
|
|
9
|
+
// for x > 0. It returns the integer part mod 8 (j) and
|
|
10
|
+
// the fractional part (z) of x / (Pi/4).
|
|
11
|
+
// The implementation is based on:
|
|
12
|
+
// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
|
|
13
|
+
// K. C. Ng et al, March 24, 1992
|
|
14
|
+
// The simulated multi-precision calculation of x*B uses 64-bit integer arithmetic.
|
|
15
|
+
export function trigReduce(x: number): [number, number] {
|
|
16
|
+
let j: number = 0
|
|
17
|
+
let z: number = 0
|
|
18
|
+
{
|
|
19
|
+
let PI4: number = 3.14159 / 4
|
|
20
|
+
if (x < 0.785398) {
|
|
21
|
+
return [0, x]
|
|
22
|
+
}
|
|
23
|
+
// Extract out the integer and exponent such that,
|
|
24
|
+
// x = ix * 2 ** exp.
|
|
25
|
+
let ix = Float64bits(x)
|
|
26
|
+
let exp = $.int(((ix >> 52) & 2047)) - 1023 - 52
|
|
27
|
+
ix &= ~(2047 << 52)
|
|
28
|
+
ix |= (1 << 52)
|
|
29
|
+
// Use the exponent to extract the 3 appropriate uint64 digits from mPi4,
|
|
30
|
+
// B ~ (z0, z1, z2), such that the product leading digit has the exponent -61.
|
|
31
|
+
// Note, exp >= -53 since x >= PI4 and exp < 971 for maximum float64.
|
|
32
|
+
let [digit, bitshift] = [$.int((exp + 61) / 64), (exp + 61) % 64]
|
|
33
|
+
let z0 = (((mPi4![digit] << bitshift)) | ((mPi4![digit + 1] >> (64 - bitshift))))
|
|
34
|
+
let z1 = (((mPi4![digit + 1] << bitshift)) | ((mPi4![digit + 2] >> (64 - bitshift))))
|
|
35
|
+
let z2 = (((mPi4![digit + 2] << bitshift)) | ((mPi4![digit + 3] >> (64 - bitshift))))
|
|
36
|
+
// Multiply mantissa by the digits and extract the upper two digits (hi, lo).
|
|
37
|
+
let [z2hi, ] = bits.Mul64(BigInt(z2), BigInt(ix))
|
|
38
|
+
let [z1hi, z1lo] = bits.Mul64(BigInt(z1), BigInt(ix))
|
|
39
|
+
let z0lo = BigInt(z0 * ix)
|
|
40
|
+
let [lo, c] = bits.Add64(z1lo, z2hi, 0n)
|
|
41
|
+
let [hi, ] = bits.Add64(z0lo, z1hi, c)
|
|
42
|
+
// The top 3 bits are j.
|
|
43
|
+
j = Number(hi >> 61n)
|
|
44
|
+
// Extract the fraction and find its magnitude.
|
|
45
|
+
hi = ((hi << 3n) | (lo >> 61n))
|
|
46
|
+
let lz = bits.LeadingZeros64(hi)
|
|
47
|
+
let e = 1023 - (lz + 1)
|
|
48
|
+
// Clear implicit mantissa bit and shift into place.
|
|
49
|
+
hi = (((hi << BigInt(lz + 1))) | ((lo >> BigInt(64 - (lz + 1)))))
|
|
50
|
+
hi >>= 64n - 52n
|
|
51
|
+
// Include the exponent and convert to a float.
|
|
52
|
+
hi |= BigInt(e) << 52n
|
|
53
|
+
z = Float64frombits(Number(hi))
|
|
54
|
+
// Map zeros to origin.
|
|
55
|
+
if ((j & 1) == 1) {
|
|
56
|
+
j++
|
|
57
|
+
j &= 7
|
|
58
|
+
z--
|
|
59
|
+
}
|
|
60
|
+
// Multiply the fractional part by pi/4.
|
|
61
|
+
return [j, z * 0.785398]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let mPi4 = $.arrayToSlice<number>([0x0000000000000001, 0x45f306dc9c882a53, 0xf84eafa3ea69bb81, 0xb6c52b3278872083, 0xfca2c757bd778ac3, 0x6e48dc74849ba5c0, 0x0c925dd413a32439, 0xfc3bd63962534e7d, 0xd1046bea5d768909, 0xd338e04d68befc82, 0x7323ac7306a673e9, 0x3908bf177bf25076, 0x3ff12fffbc0b301f, 0xde5e2316b414da3e, 0xda6cfd9e4f96136e, 0x9e8c7ecd3cbfd45a, 0xea4f758fd7cbe2f6, 0x7a0e73ef14a525d4, 0xd7f6bf623f1aba10, 0xac06608df8f6d757])
|
|
66
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
|
|
3
|
+
// Float32bits returns the IEEE 754 binary representation of f,
|
|
4
|
+
// with the sign bit of f and the result in the same bit position.
|
|
5
|
+
// Float32bits(Float32frombits(x)) == x.
|
|
6
|
+
export function Float32bits(f: number): number {
|
|
7
|
+
const buffer = new ArrayBuffer(4);
|
|
8
|
+
const view = new DataView(buffer);
|
|
9
|
+
view.setFloat32(0, f, true); // little endian
|
|
10
|
+
return view.getUint32(0, true);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Float32frombits returns the floating-point number corresponding
|
|
14
|
+
// to the IEEE 754 binary representation b, with the sign bit of b
|
|
15
|
+
// and the result in the same bit position.
|
|
16
|
+
// Float32frombits(Float32bits(x)) == x.
|
|
17
|
+
export function Float32frombits(b: number): number {
|
|
18
|
+
const buffer = new ArrayBuffer(4);
|
|
19
|
+
const view = new DataView(buffer);
|
|
20
|
+
view.setUint32(0, b, true); // little endian
|
|
21
|
+
return view.getFloat32(0, true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Float64bits returns the IEEE 754 binary representation of f,
|
|
25
|
+
// with the sign bit of f and the result in the same bit position,
|
|
26
|
+
// and Float64bits(Float64frombits(x)) == x.
|
|
27
|
+
export function Float64bits(f: number): number {
|
|
28
|
+
const buffer = new ArrayBuffer(8);
|
|
29
|
+
const view = new DataView(buffer);
|
|
30
|
+
view.setFloat64(0, f, true); // little endian
|
|
31
|
+
// JavaScript numbers are limited to 53-bit precision, so we need to handle this carefully
|
|
32
|
+
const low = view.getUint32(0, true);
|
|
33
|
+
const high = view.getUint32(4, true);
|
|
34
|
+
// Combine into a single number (may lose precision for very large values)
|
|
35
|
+
return high * 0x100000000 + low;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Float64frombits returns the floating-point number corresponding
|
|
39
|
+
// to the IEEE 754 binary representation b, with the sign bit of b
|
|
40
|
+
// and the result in the same bit position.
|
|
41
|
+
// Float64frombits(Float64bits(x)) == x.
|
|
42
|
+
export function Float64frombits(b: number): number {
|
|
43
|
+
const buffer = new ArrayBuffer(8);
|
|
44
|
+
const view = new DataView(buffer);
|
|
45
|
+
// Split the number into high and low 32-bit parts
|
|
46
|
+
const low = b & 0xFFFFFFFF;
|
|
47
|
+
const high = Math.floor(b / 0x100000000);
|
|
48
|
+
view.setUint32(0, low, true); // little endian
|
|
49
|
+
view.setUint32(4, high, true);
|
|
50
|
+
return view.getFloat64(0, true);
|
|
51
|
+
}
|
|
52
|
+
|
package/gs/slices/slices.ts
CHANGED
|
@@ -20,3 +20,12 @@ export function All<T>(
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sort sorts a slice in ascending order.
|
|
26
|
+
* This is equivalent to Go's slices.Sort function.
|
|
27
|
+
* @param s The slice to sort in place
|
|
28
|
+
*/
|
|
29
|
+
export function Sort<T extends string | number>(s: $.Slice<T>): void {
|
|
30
|
+
$.sortSlice(s)
|
|
31
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { syntaxError } from "./atoi.gs.js";
|
|
3
|
+
|
|
4
|
+
// ParseBool returns the boolean value represented by the string.
|
|
5
|
+
// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
|
|
6
|
+
// Any other value returns an error.
|
|
7
|
+
export function ParseBool(str: string): [boolean, $.GoError] {
|
|
8
|
+
switch (str) {
|
|
9
|
+
case "1":
|
|
10
|
+
case "t":
|
|
11
|
+
case "T":
|
|
12
|
+
case "true":
|
|
13
|
+
case "TRUE":
|
|
14
|
+
case "True":
|
|
15
|
+
return [true, null]
|
|
16
|
+
break
|
|
17
|
+
case "0":
|
|
18
|
+
case "f":
|
|
19
|
+
case "F":
|
|
20
|
+
case "false":
|
|
21
|
+
case "FALSE":
|
|
22
|
+
case "False":
|
|
23
|
+
return [false, null]
|
|
24
|
+
break
|
|
25
|
+
}
|
|
26
|
+
return [false, syntaxError("ParseBool", str)]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// FormatBool returns "true" or "false" according to the value of b.
|
|
30
|
+
export function FormatBool(b: boolean): string {
|
|
31
|
+
if (b) {
|
|
32
|
+
return "true"
|
|
33
|
+
}
|
|
34
|
+
return "false"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// AppendBool appends "true" or "false", according to the value of b,
|
|
38
|
+
// to dst and returns the extended buffer.
|
|
39
|
+
export function AppendBool(dst: $.Bytes, b: boolean): $.Bytes {
|
|
40
|
+
if (b) {
|
|
41
|
+
return $.append(dst, ...$.stringToBytes("true"))
|
|
42
|
+
}
|
|
43
|
+
return $.append(dst, ...$.stringToBytes("false"))
|
|
44
|
+
}
|
|
45
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { ErrSyntax, ErrRange, NumError } from "./atoi.gs.js";
|
|
3
|
+
|
|
4
|
+
// ParseFloat converts the string s to a floating-point number
|
|
5
|
+
// with the precision specified by bitSize: 32 for float32, or 64 for float64.
|
|
6
|
+
// When bitSize=32, the result still has type float64, but it will be
|
|
7
|
+
// convertible to float32 without changing its value.
|
|
8
|
+
export function ParseFloat(s: string, bitSize: number): [number, $.GoError] {
|
|
9
|
+
if (s === "") {
|
|
10
|
+
return [0, new NumError({Func: "ParseFloat", Num: s, Err: ErrSyntax})];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Validate bitSize
|
|
14
|
+
if (bitSize !== 32 && bitSize !== 64) {
|
|
15
|
+
return [0, new NumError({Func: "ParseFloat", Num: s, Err: ErrSyntax})];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Handle special cases
|
|
19
|
+
const lower = s.toLowerCase();
|
|
20
|
+
switch (lower) {
|
|
21
|
+
case "+inf":
|
|
22
|
+
case "inf":
|
|
23
|
+
case "+infinity":
|
|
24
|
+
case "infinity":
|
|
25
|
+
return [Infinity, null];
|
|
26
|
+
case "-inf":
|
|
27
|
+
case "-infinity":
|
|
28
|
+
return [-Infinity, null];
|
|
29
|
+
case "nan":
|
|
30
|
+
return [NaN, null];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Remove underscores if present (Go allows them in numeric literals)
|
|
34
|
+
let cleanS = s;
|
|
35
|
+
if (s.includes('_')) {
|
|
36
|
+
cleanS = s.replace(/_/g, '');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Use JavaScript's parseFloat
|
|
40
|
+
const result = parseFloat(cleanS);
|
|
41
|
+
|
|
42
|
+
if (isNaN(result)) {
|
|
43
|
+
return [0, new NumError({Func: "ParseFloat", Num: s, Err: ErrSyntax})];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check for range errors based on bitSize
|
|
47
|
+
if (bitSize === 32) {
|
|
48
|
+
const maxFloat32 = 3.4028234663852886e+38;
|
|
49
|
+
const minFloat32 = 1.175494351e-38;
|
|
50
|
+
|
|
51
|
+
if (isFinite(result) && Math.abs(result) > maxFloat32) {
|
|
52
|
+
return [result > 0 ? Infinity : -Infinity, new NumError({Func: "ParseFloat", Num: s, Err: ErrRange})];
|
|
53
|
+
}
|
|
54
|
+
if (isFinite(result) && result !== 0 && Math.abs(result) < minFloat32) {
|
|
55
|
+
return [0, new NumError({Func: "ParseFloat", Num: s, Err: ErrRange})];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return [result, null];
|
|
60
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import * as errors from "@goscript/errors/index.js";
|
|
3
|
+
|
|
4
|
+
export let ErrRange: $.GoError = errors.New("value out of range");
|
|
5
|
+
export let ErrSyntax: $.GoError = errors.New("invalid syntax");
|
|
6
|
+
|
|
7
|
+
export class NumError {
|
|
8
|
+
// the failing function (ParseBool, ParseInt, ParseUint, ParseFloat, ParseComplex)
|
|
9
|
+
public get Func(): string {
|
|
10
|
+
return this._fields.Func.value;
|
|
11
|
+
}
|
|
12
|
+
public set Func(value: string) {
|
|
13
|
+
this._fields.Func.value = value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// the input
|
|
17
|
+
public get Num(): string {
|
|
18
|
+
return this._fields.Num.value;
|
|
19
|
+
}
|
|
20
|
+
public set Num(value: string) {
|
|
21
|
+
this._fields.Num.value = value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
|
|
25
|
+
public get Err(): $.GoError {
|
|
26
|
+
return this._fields.Err.value;
|
|
27
|
+
}
|
|
28
|
+
public set Err(value: $.GoError) {
|
|
29
|
+
this._fields.Err.value = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public _fields: {
|
|
33
|
+
Func: $.VarRef<string>;
|
|
34
|
+
Num: $.VarRef<string>;
|
|
35
|
+
Err: $.VarRef<$.GoError>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
constructor(init?: Partial<{Err?: $.GoError, Func?: string, Num?: string}>) {
|
|
39
|
+
this._fields = {
|
|
40
|
+
Func: $.varRef(init?.Func ?? ""),
|
|
41
|
+
Num: $.varRef(init?.Num ?? ""),
|
|
42
|
+
Err: $.varRef(init?.Err ?? null)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public clone(): NumError {
|
|
47
|
+
const cloned = new NumError();
|
|
48
|
+
cloned._fields = {
|
|
49
|
+
Func: $.varRef(this._fields.Func.value),
|
|
50
|
+
Num: $.varRef(this._fields.Num.value),
|
|
51
|
+
Err: $.varRef(this._fields.Err.value)
|
|
52
|
+
};
|
|
53
|
+
return cloned;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public Error(): string {
|
|
57
|
+
const e = this;
|
|
58
|
+
return "strconv." + e.Func + ": " + "parsing " + JSON.stringify(e.Num) + ": " + e.Err!.Error();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public Unwrap(): $.GoError {
|
|
62
|
+
const e = this;
|
|
63
|
+
return e.Err;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Register this type with the runtime type system
|
|
67
|
+
static __typeInfo = $.registerStructType(
|
|
68
|
+
'NumError',
|
|
69
|
+
new NumError(),
|
|
70
|
+
[{ name: "Error", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }] }, { name: "Unwrap", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }],
|
|
71
|
+
NumError,
|
|
72
|
+
{"Func": { kind: $.TypeKind.Basic, name: "string" }, "Num": { kind: $.TypeKind.Basic, name: "string" }, "Err": { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] }}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function syntaxError(fn: string, str: string): NumError {
|
|
77
|
+
return new NumError({Func: fn, Num: str, Err: ErrSyntax});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function rangeError(fn: string, str: string): NumError {
|
|
81
|
+
return new NumError({Func: fn, Num: str, Err: ErrRange});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function baseError(fn: string, str: string, base: number): NumError {
|
|
85
|
+
return new NumError({Func: fn, Num: str, Err: errors.New("invalid base " + base)});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function bitSizeError(fn: string, str: string, bitSize: number): NumError {
|
|
89
|
+
return new NumError({Func: fn, Num: str, Err: errors.New("invalid bit size " + bitSize)});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export let IntSize: number = 64;
|
|
93
|
+
|
|
94
|
+
// lower(c) is a lower-case letter if and only if
|
|
95
|
+
// c is either that lower-case letter or the equivalent upper-case letter.
|
|
96
|
+
function lower(c: number): number {
|
|
97
|
+
return (c | (120 - 88));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ParseUint is like ParseInt but for unsigned numbers.
|
|
101
|
+
// A sign prefix is not permitted.
|
|
102
|
+
export function ParseUint(s: string, base: number, bitSize: number): [number, $.GoError] {
|
|
103
|
+
if (s === "") {
|
|
104
|
+
return [0, syntaxError("ParseUint", s)];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const base0 = base === 0;
|
|
108
|
+
const s0 = s;
|
|
109
|
+
|
|
110
|
+
// Handle base validation
|
|
111
|
+
if (base < 0 || base === 1 || base > 36) {
|
|
112
|
+
return [0, baseError("ParseUint", s0, base)];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Handle base inference
|
|
116
|
+
if (base === 0) {
|
|
117
|
+
base = 10;
|
|
118
|
+
if (s.length >= 3) {
|
|
119
|
+
if (s[0] === '0') {
|
|
120
|
+
const prefix = s[1].toLowerCase();
|
|
121
|
+
if (prefix === 'b') {
|
|
122
|
+
base = 2;
|
|
123
|
+
s = s.slice(2);
|
|
124
|
+
} else if (prefix === 'o') {
|
|
125
|
+
base = 8;
|
|
126
|
+
s = s.slice(2);
|
|
127
|
+
} else if (prefix === 'x') {
|
|
128
|
+
base = 16;
|
|
129
|
+
s = s.slice(2);
|
|
130
|
+
} else {
|
|
131
|
+
base = 8;
|
|
132
|
+
s = s.slice(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else if (s.length >= 2 && s[0] === '0') {
|
|
136
|
+
base = 8;
|
|
137
|
+
s = s.slice(1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Validate bitSize
|
|
142
|
+
if (bitSize === 0) {
|
|
143
|
+
bitSize = 64;
|
|
144
|
+
} else if (bitSize < 0 || bitSize > 64) {
|
|
145
|
+
return [0, bitSizeError("ParseUint", s0, bitSize)];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Check for underscores only if base0 (auto-detected base)
|
|
149
|
+
if (base0 && s.includes('_')) {
|
|
150
|
+
if (!underscoreOK(s)) {
|
|
151
|
+
return [0, syntaxError("ParseUint", s0)];
|
|
152
|
+
}
|
|
153
|
+
s = s.replace(/_/g, '');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Use JavaScript's parseInt
|
|
157
|
+
const result = parseInt(s, base);
|
|
158
|
+
|
|
159
|
+
if (isNaN(result) || !isFinite(result)) {
|
|
160
|
+
return [0, syntaxError("ParseUint", s0)];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (result < 0) {
|
|
164
|
+
return [0, syntaxError("ParseUint", s0)];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Check range for the specified bit size
|
|
168
|
+
const maxVal = (1 << bitSize) - 1;
|
|
169
|
+
if (result > maxVal) {
|
|
170
|
+
return [0, rangeError("ParseUint", s0)];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return [result, null];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ParseInt interprets a string s in the given base (0, 2 to 36) and
|
|
177
|
+
// bit size (0 to 64) and returns the corresponding value i.
|
|
178
|
+
export function ParseInt(s: string, base: number, bitSize: number): [number, $.GoError] {
|
|
179
|
+
if (s === "") {
|
|
180
|
+
return [0, syntaxError("ParseInt", s)];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let neg = false;
|
|
184
|
+
if (s[0] === '+' || s[0] === '-') {
|
|
185
|
+
neg = s[0] === '-';
|
|
186
|
+
s = s.slice(1);
|
|
187
|
+
if (s.length < 1) {
|
|
188
|
+
return [0, syntaxError("ParseInt", s)];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Convert to unsigned first
|
|
193
|
+
const [un, err] = ParseUint(s, base, bitSize);
|
|
194
|
+
if (err !== null) {
|
|
195
|
+
const numErr = err as NumError;
|
|
196
|
+
numErr.Func = "ParseInt";
|
|
197
|
+
return [0, err];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (bitSize === 0) {
|
|
201
|
+
bitSize = 64;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const cutoff = 1 << (bitSize - 1);
|
|
205
|
+
if (!neg && un >= cutoff) {
|
|
206
|
+
return [0, rangeError("ParseInt", s)];
|
|
207
|
+
}
|
|
208
|
+
if (neg && un > cutoff) {
|
|
209
|
+
return [0, rangeError("ParseInt", s)];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const result = neg ? -un : un;
|
|
213
|
+
return [result, null];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Atoi is equivalent to ParseInt(s, 10, 0), converted to type int.
|
|
217
|
+
export function Atoi(s: string): [number, $.GoError] {
|
|
218
|
+
const [i64, err] = ParseInt(s, 10, 0);
|
|
219
|
+
return [i64, err];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// underscoreOK reports whether the underscores in s are allowed.
|
|
223
|
+
function underscoreOK(s: string): boolean {
|
|
224
|
+
// Simplified validation for underscores
|
|
225
|
+
if (s.length === 0) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Can't start or end with underscore
|
|
230
|
+
if (s[0] === '_' || s[s.length - 1] === '_') {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Can't have consecutive underscores
|
|
235
|
+
for (let i = 0; i < s.length - 1; i++) {
|
|
236
|
+
if (s[i] === '_' && s[i + 1] === '_') {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
|
|
3
|
+
// FormatFloat converts the floating-point number f to a string,
|
|
4
|
+
// according to the format fmt and precision prec. It rounds the
|
|
5
|
+
// result assuming that the original was obtained from a floating-point
|
|
6
|
+
// value of bitSize bits (32 for float32, 64 for float64).
|
|
7
|
+
export function FormatFloat(f: number, fmt: number, prec: number, bitSize: number): string {
|
|
8
|
+
const fmtChar = String.fromCharCode(fmt);
|
|
9
|
+
|
|
10
|
+
// Handle special cases
|
|
11
|
+
if (isNaN(f)) {
|
|
12
|
+
return "NaN";
|
|
13
|
+
}
|
|
14
|
+
if (f === Infinity) {
|
|
15
|
+
return "+Inf";
|
|
16
|
+
}
|
|
17
|
+
if (f === -Infinity) {
|
|
18
|
+
return "-Inf";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Convert to appropriate precision for float32
|
|
22
|
+
if (bitSize === 32) {
|
|
23
|
+
f = Math.fround(f);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
switch (fmtChar.toLowerCase()) {
|
|
27
|
+
case 'e':
|
|
28
|
+
// Exponential notation
|
|
29
|
+
if (prec < 0) {
|
|
30
|
+
return f.toExponential();
|
|
31
|
+
}
|
|
32
|
+
return f.toExponential(prec);
|
|
33
|
+
|
|
34
|
+
case 'f':
|
|
35
|
+
// Fixed-point notation
|
|
36
|
+
if (prec < 0) {
|
|
37
|
+
return f.toString();
|
|
38
|
+
}
|
|
39
|
+
return f.toFixed(prec);
|
|
40
|
+
|
|
41
|
+
case 'g':
|
|
42
|
+
// Use the more compact of 'e' or 'f'
|
|
43
|
+
if (prec < 0) {
|
|
44
|
+
return f.toPrecision();
|
|
45
|
+
}
|
|
46
|
+
return f.toPrecision(prec + 1);
|
|
47
|
+
|
|
48
|
+
case 'x':
|
|
49
|
+
// Hexadecimal notation (simplified)
|
|
50
|
+
return f.toString(16);
|
|
51
|
+
|
|
52
|
+
default:
|
|
53
|
+
// Default to 'g' format
|
|
54
|
+
if (prec < 0) {
|
|
55
|
+
return f.toString();
|
|
56
|
+
}
|
|
57
|
+
return f.toPrecision(prec + 1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// AppendFloat appends the string form of the floating-point number f,
|
|
62
|
+
// as generated by FormatFloat, to dst and returns the extended buffer.
|
|
63
|
+
export function AppendFloat(dst: $.Bytes, f: number, fmt: number, prec: number, bitSize: number): $.Bytes {
|
|
64
|
+
const str = FormatFloat(f, fmt, prec, bitSize);
|
|
65
|
+
return $.append(dst, ...$.stringToBytes(str)!);
|
|
66
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AppendBool, FormatBool, ParseBool } from "./atob.gs.js"
|
|
2
|
+
export { ParseFloat } from "./atof.gs.js"
|
|
3
|
+
export { Atoi, ErrRange, ErrSyntax, IntSize, NumError, ParseInt, ParseUint } from "./atoi.gs.js"
|
|
4
|
+
export { AppendFloat, FormatFloat } from "./ftoa.gs.js"
|
|
5
|
+
export { AppendInt, AppendUint, FormatInt, FormatUint, Itoa } from "./itoa.gs.js"
|
|
6
|
+
export { AppendQuote, AppendQuoteRune, AppendQuoteRuneToASCII, AppendQuoteRuneToGraphic, AppendQuoteToASCII, AppendQuoteToGraphic, CanBackquote, IsGraphic, IsPrint, Quote, QuoteRune, QuoteRuneToASCII, QuoteRuneToGraphic, QuoteToASCII, QuoteToGraphic, QuotedPrefix, Unquote, UnquoteChar } from "./quote.gs.js"
|