goscript 0.1.0 → 0.1.1
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/README.md +267 -255
- package/cmd/goscript/cmd-test.go +193 -0
- package/cmd/goscript/cmd-test_test.go +76 -0
- package/cmd/goscript/main.go +1 -0
- package/compiler/build-flags.go +38 -0
- package/compiler/compile-request.go +2 -0
- package/compiler/compliance_test.go +0 -8
- package/compiler/gotest/owner.go +24 -0
- package/compiler/gotest/package-result.go +67 -0
- package/compiler/gotest/request.go +145 -0
- package/compiler/gotest/result.go +28 -0
- package/compiler/gotest/runner.go +588 -0
- package/compiler/gotest/runner_test.go +627 -0
- package/compiler/gotest/test.go +9 -0
- package/compiler/index.test.ts +1 -1
- package/compiler/lowered-program.go +71 -19
- package/compiler/lowering.go +5065 -569
- package/compiler/override-facts.go +307 -0
- package/compiler/override-registry.go +50 -189
- package/compiler/override-registry_test.go +47 -0
- package/compiler/package-graph.go +50 -27
- package/compiler/package-graph_test.go +37 -2
- package/compiler/package-test-function.go +9 -0
- package/compiler/package-test-graph-package.go +40 -0
- package/compiler/package-test-graph-variant.go +105 -0
- package/compiler/package-test-graph.go +117 -0
- package/compiler/package-test-graph_test.go +144 -0
- package/compiler/runtime-contract.go +189 -29
- package/compiler/runtime-contract_test.go +44 -30
- package/compiler/semantic-model-types.go +9 -6
- package/compiler/semantic-model.go +538 -38
- package/compiler/semantic-model_test.go +55 -0
- package/compiler/service.go +1 -1
- package/compiler/skeleton_test.go +679 -49
- package/compiler/tsworkspace/owner.go +334 -0
- package/compiler/tsworkspace/owner_test.go +93 -0
- package/compiler/tsworkspace/result.go +17 -0
- package/compiler/typescript-emitter.go +459 -82
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +61 -11
- package/compiler/wasm_api.go +172 -7
- package/dist/gs/builtin/builtin.d.ts +20 -2
- package/dist/gs/builtin/builtin.js +194 -6
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +8 -0
- package/dist/gs/builtin/channel.js +12 -0
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +22 -2
- package/dist/gs/builtin/slice.js +216 -44
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +5 -2
- package/dist/gs/builtin/type.js +83 -24
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +5 -0
- package/dist/gs/builtin/varRef.js +23 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +48 -44
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +20 -18
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/context/context.d.ts +5 -4
- package/dist/gs/context/context.js +10 -10
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
- package/dist/gs/embed/index.d.ts +7 -0
- package/dist/gs/embed/index.js +16 -0
- package/dist/gs/embed/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +1 -0
- package/dist/gs/encoding/json/index.js +18 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +4 -0
- package/dist/gs/errors/errors.js +81 -0
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +4 -4
- package/dist/gs/fmt/fmt.js +42 -11
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +35 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +211 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
- package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
- package/dist/gs/go/internal/scannerhooks/index.js +5 -0
- package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
- package/dist/gs/go/scanner/index.d.ts +13 -0
- package/dist/gs/go/scanner/index.js +35 -0
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.d.ts +156 -0
- package/dist/gs/go/token/index.js +500 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/internal/abi/index.d.ts +4 -0
- package/dist/gs/internal/abi/index.js +10 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.d.ts +2 -0
- package/dist/gs/internal/bytealg/index.js +14 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +8 -2
- package/dist/gs/internal/byteorder/index.js +56 -25
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/godebug/index.d.ts +12 -0
- package/dist/gs/internal/godebug/index.js +30 -0
- package/dist/gs/internal/godebug/index.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +1 -0
- package/dist/gs/io/fs/index.js +1 -0
- package/dist/gs/io/fs/index.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +8 -0
- package/dist/gs/io/fs/readlink.js +64 -0
- package/dist/gs/io/fs/readlink.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +3 -3
- package/dist/gs/io/fs/walk.js +7 -7
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.d.ts +40 -6
- package/dist/gs/io/io.js +151 -26
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +3 -3
- package/dist/gs/maps/iter.js +3 -3
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +2 -2
- package/dist/gs/maps/maps.js +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +13 -4
- package/dist/gs/math/bits/index.js +66 -34
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/const.gs.d.ts +5 -5
- package/dist/gs/math/const.gs.js +4 -4
- package/dist/gs/math/const.gs.js.map +1 -1
- package/dist/gs/mime/index.d.ts +1 -0
- package/dist/gs/mime/index.js +50 -0
- package/dist/gs/mime/index.js.map +1 -0
- package/dist/gs/net/http/httptest/index.d.ts +11 -0
- package/dist/gs/net/http/httptest/index.js +21 -0
- package/dist/gs/net/http/httptest/index.js.map +1 -0
- package/dist/gs/net/http/index.d.ts +27 -0
- package/dist/gs/net/http/index.js +61 -0
- package/dist/gs/net/http/index.js.map +1 -0
- package/dist/gs/os/dir_unix.gs.js +2 -2
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +165 -3
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +3 -1
- package/dist/gs/path/filepath/path.js +133 -4
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/path.d.ts +4 -1
- package/dist/gs/path/path.js +16 -4
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +1 -1
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +3 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +7 -4
- package/dist/gs/reflect/type.js +148 -7
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +2 -0
- package/dist/gs/runtime/debug/index.js +8 -0
- package/dist/gs/runtime/debug/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +35 -3
- package/dist/gs/runtime/runtime.js +72 -0
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +24 -5
- package/dist/gs/slices/slices.js +214 -5
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +3 -3
- package/dist/gs/sort/slice.gs.js +6 -6
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/sort/sort.gs.d.ts +4 -4
- package/dist/gs/sort/sort.gs.js +11 -8
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strings/builder.d.ts +1 -1
- package/dist/gs/strings/builder.js +3 -2
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
- package/dist/gs/sync/atomic/type.gs.js +0 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -0
- package/dist/gs/sync/sync.js +27 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/constants.d.ts +36 -24
- package/dist/gs/syscall/constants.js +12 -0
- package/dist/gs/syscall/constants.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +2 -0
- package/dist/gs/syscall/errors.js +8 -0
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +43 -0
- package/dist/gs/syscall/fs.js +102 -0
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.d.ts +90 -0
- package/dist/gs/syscall/js/index.js +375 -0
- package/dist/gs/syscall/js/index.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +22 -0
- package/dist/gs/syscall/types.js +45 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/index.d.ts +1 -0
- package/dist/gs/testing/index.js +2 -0
- package/dist/gs/testing/index.js.map +1 -0
- package/dist/gs/testing/testing.d.ts +77 -0
- package/dist/gs/testing/testing.js +301 -0
- package/dist/gs/testing/testing.js.map +1 -0
- package/dist/gs/time/time.d.ts +41 -4
- package/dist/gs/time/time.js +205 -36
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.d.ts +23 -1
- package/dist/gs/unicode/unicode.js +79 -10
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
- package/dist/gs/unicode/utf8/utf8.js +24 -11
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unique/index.d.ts +11 -0
- package/dist/gs/unique/index.js +71 -0
- package/dist/gs/unique/index.js.map +1 -0
- package/go.sum +9 -0
- package/gs/builtin/builtin.ts +239 -8
- package/gs/builtin/channel.ts +22 -0
- package/gs/builtin/runtime-contract.test.ts +126 -0
- package/gs/builtin/slice.ts +259 -50
- package/gs/builtin/type.ts +109 -34
- package/gs/builtin/varRef.ts +38 -1
- package/gs/bytes/buffer.gs.ts +48 -44
- package/gs/bytes/meta.json +8 -3
- package/gs/bytes/reader.gs.ts +20 -19
- package/gs/context/context.test.ts +41 -0
- package/gs/context/context.ts +22 -26
- package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
- package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
- package/gs/embed/index.ts +20 -0
- package/gs/embed/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +15 -1
- package/gs/encoding/json/index.ts +24 -0
- package/gs/errors/errors.test.ts +82 -0
- package/gs/errors/errors.ts +104 -0
- package/gs/fmt/fmt.ts +56 -16
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +73 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +297 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
- package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
- package/gs/go/internal/scannerhooks/index.test.ts +14 -0
- package/gs/go/internal/scannerhooks/index.ts +9 -0
- package/gs/go/scanner/index.test.ts +22 -0
- package/gs/go/scanner/index.ts +47 -0
- package/gs/go/token/index.test.ts +47 -1
- package/gs/go/token/index.ts +570 -4
- package/gs/internal/abi/index.test.ts +18 -0
- package/gs/internal/abi/index.ts +14 -0
- package/gs/internal/bytealg/index.test.ts +18 -0
- package/gs/internal/bytealg/index.ts +16 -0
- package/gs/internal/byteorder/index.test.ts +39 -0
- package/gs/internal/byteorder/index.ts +100 -27
- package/gs/internal/godebug/index.test.ts +16 -0
- package/gs/internal/godebug/index.ts +35 -0
- package/gs/io/fs/index.ts +1 -0
- package/gs/io/fs/meta.json +5 -0
- package/gs/io/fs/readlink.test.ts +43 -0
- package/gs/io/fs/readlink.ts +77 -0
- package/gs/io/fs/walk.test.ts +61 -0
- package/gs/io/fs/walk.ts +9 -9
- package/gs/io/io.ts +174 -31
- package/gs/io/meta.json +10 -2
- package/gs/maps/iter.ts +12 -6
- package/gs/maps/maps.ts +8 -6
- package/gs/math/bits/index.ts +103 -47
- package/gs/math/const.gs.test.ts +11 -5
- package/gs/math/const.gs.ts +5 -6
- package/gs/mime/index.ts +54 -0
- package/gs/net/http/httptest/index.ts +25 -0
- package/gs/net/http/index.test.ts +20 -0
- package/gs/net/http/index.ts +81 -0
- package/gs/os/dir_unix.gs.ts +2 -3
- package/gs/os/types_js.gs.ts +2 -2
- package/gs/path/filepath/match.test.ts +31 -12
- package/gs/path/filepath/match.ts +178 -3
- package/gs/path/filepath/path.test.ts +25 -0
- package/gs/path/filepath/path.ts +159 -5
- package/gs/path/path.ts +20 -5
- package/gs/reflect/index.ts +1 -0
- package/gs/reflect/map.test.ts +19 -0
- package/gs/reflect/map.ts +4 -0
- package/gs/reflect/type.ts +197 -17
- package/gs/runtime/debug/index.test.ts +24 -0
- package/gs/runtime/debug/index.ts +8 -0
- package/gs/runtime/runtime.test.ts +19 -0
- package/gs/runtime/runtime.ts +98 -3
- package/gs/slices/slices.test.ts +94 -0
- package/gs/slices/slices.ts +245 -5
- package/gs/sort/meta.json +7 -0
- package/gs/sort/slice.gs.ts +16 -7
- package/gs/sort/sort.gs.ts +16 -13
- package/gs/strings/builder.ts +4 -3
- package/gs/sync/atomic/type.gs.ts +13 -14
- package/gs/sync/meta.json +3 -1
- package/gs/sync/sync.test.ts +13 -1
- package/gs/sync/sync.ts +27 -0
- package/gs/syscall/constants.ts +39 -24
- package/gs/syscall/errors.ts +10 -0
- package/gs/syscall/fs.ts +195 -0
- package/gs/syscall/js/index.ts +458 -0
- package/gs/syscall/js/meta.json +4 -0
- package/gs/syscall/net.test.ts +85 -0
- package/gs/syscall/types.ts +56 -0
- package/gs/testing/index.ts +1 -0
- package/gs/testing/meta.json +5 -0
- package/gs/testing/testing.test.ts +90 -0
- package/gs/testing/testing.ts +382 -0
- package/gs/time/time.test.ts +106 -0
- package/gs/time/time.ts +278 -57
- package/gs/unicode/unicode.test.ts +25 -0
- package/gs/unicode/unicode.ts +119 -9
- package/gs/unicode/utf8/utf8.test.ts +13 -0
- package/gs/unicode/utf8/utf8.ts +28 -16
- package/gs/unique/index.ts +91 -0
- package/package.json +2 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Compiler,
|
|
5
|
+
FuncForPC,
|
|
6
|
+
ReadTrace,
|
|
7
|
+
StartTrace,
|
|
8
|
+
StopTrace,
|
|
9
|
+
} from './runtime.js'
|
|
10
|
+
|
|
11
|
+
describe('runtime override', () => {
|
|
12
|
+
it('exposes stack and trace compatibility helpers', () => {
|
|
13
|
+
expect(Compiler).toBe('gc')
|
|
14
|
+
expect(FuncForPC(0)).toBeNull()
|
|
15
|
+
expect(StartTrace()).toBeNull()
|
|
16
|
+
expect(ReadTrace()).toBeNull()
|
|
17
|
+
expect(() => StopTrace()).not.toThrow()
|
|
18
|
+
})
|
|
19
|
+
})
|
package/gs/runtime/runtime.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
|
|
1
3
|
// Runtime constants for the JavaScript/WebAssembly target
|
|
2
|
-
export const GOOS = 'js'
|
|
3
|
-
export const GOARCH = 'wasm'
|
|
4
|
+
export const GOOS: string = 'js'
|
|
5
|
+
export const GOARCH: string = 'wasm'
|
|
6
|
+
export const Compiler: string = 'gc'
|
|
4
7
|
|
|
5
8
|
// Version returns the Go version as a string
|
|
6
|
-
export const GOVERSION = 'go1.25.3'
|
|
9
|
+
export const GOVERSION: string = 'go1.25.3'
|
|
7
10
|
export function Version(): string {
|
|
8
11
|
return GOVERSION
|
|
9
12
|
}
|
|
@@ -79,6 +82,79 @@ export function Caller(_skip: number): [number, string, number, boolean] {
|
|
|
79
82
|
return [pc, file, line, ok]
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
// Func represents metadata for a function in a stack frame.
|
|
86
|
+
export class Func {
|
|
87
|
+
public Entry(): number {
|
|
88
|
+
return 0
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public FileLine(_pc: number): [string, number] {
|
|
92
|
+
return ['', 0]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public Name(): string {
|
|
96
|
+
return ''
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// FuncForPC returns function metadata for a program counter.
|
|
101
|
+
export function FuncForPC(_pc: number): Func | null {
|
|
102
|
+
return null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// StartTrace enables execution tracing.
|
|
106
|
+
export function StartTrace(): $.GoError {
|
|
107
|
+
return null
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// StopTrace stops execution tracing.
|
|
111
|
+
export function StopTrace(): void {}
|
|
112
|
+
|
|
113
|
+
// ReadTrace returns the next execution trace chunk.
|
|
114
|
+
export function ReadTrace(): $.Slice<number> {
|
|
115
|
+
return null
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Frame represents a single call frame.
|
|
119
|
+
export class Frame {
|
|
120
|
+
public PC = 0
|
|
121
|
+
public Func: Func | null = null
|
|
122
|
+
public Function = ''
|
|
123
|
+
public File = ''
|
|
124
|
+
public Line = 0
|
|
125
|
+
public Entry = 0
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Frames iterates over call frames.
|
|
129
|
+
export class Frames {
|
|
130
|
+
private readonly frames: Frame[]
|
|
131
|
+
private index = 0
|
|
132
|
+
|
|
133
|
+
constructor(frames: Frame[] = []) {
|
|
134
|
+
this.frames = frames
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public Next(): [Frame, boolean] {
|
|
138
|
+
if (this.index >= this.frames.length) {
|
|
139
|
+
return [new Frame(), false]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const frame = this.frames[this.index]
|
|
143
|
+
this.index++
|
|
144
|
+
return [frame, this.index < this.frames.length]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Callers fills pc with return program counters from the current stack.
|
|
149
|
+
export function Callers(_skip: number, _pc: $.Slice<number>): number {
|
|
150
|
+
return 0
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// CallersFrames returns an iterator over call frames for pcs.
|
|
154
|
+
export function CallersFrames(_callers: $.Slice<number>): Frames {
|
|
155
|
+
return new Frames()
|
|
156
|
+
}
|
|
157
|
+
|
|
82
158
|
// Stack returns a formatted stack trace of the calling goroutine.
|
|
83
159
|
// In JavaScript, we use Error.stack
|
|
84
160
|
export function Stack(): Uint8Array {
|
|
@@ -167,6 +243,25 @@ export function SetFinalizer(
|
|
|
167
243
|
)
|
|
168
244
|
}
|
|
169
245
|
|
|
246
|
+
// Cleanup is a handle to a cleanup call for a specific object.
|
|
247
|
+
export class Cleanup {
|
|
248
|
+
public Stop(): void {}
|
|
249
|
+
|
|
250
|
+
public clone(): Cleanup {
|
|
251
|
+
return new Cleanup()
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// AddCleanup registers cleanup to run when ptr is no longer reachable.
|
|
256
|
+
export function AddCleanup<T, S>(
|
|
257
|
+
_ptr: T,
|
|
258
|
+
_cleanup: (arg: S) => void | Promise<void>,
|
|
259
|
+
_arg: S,
|
|
260
|
+
): Cleanup {
|
|
261
|
+
// JavaScript runtimes do not provide Go's cleanup scheduling contract here.
|
|
262
|
+
return new Cleanup()
|
|
263
|
+
}
|
|
264
|
+
|
|
170
265
|
// KeepAlive keeps obj reachable until the point where KeepAlive is called
|
|
171
266
|
export function KeepAlive(obj: any): void {
|
|
172
267
|
// In JavaScript, just accessing the object keeps it alive for this call
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Backward,
|
|
7
|
+
IsSorted,
|
|
8
|
+
IsSortedFunc,
|
|
9
|
+
Max,
|
|
10
|
+
Sorted,
|
|
11
|
+
SortStableFunc,
|
|
12
|
+
} from './slices.js'
|
|
13
|
+
|
|
14
|
+
describe('slices.SortStableFunc', () => {
|
|
15
|
+
it('preserves original order for equal elements', () => {
|
|
16
|
+
const values = $.arrayToSlice([
|
|
17
|
+
{ group: 2, label: 'a' },
|
|
18
|
+
{ group: 1, label: 'b' },
|
|
19
|
+
{ group: 2, label: 'c' },
|
|
20
|
+
{ group: 1, label: 'd' },
|
|
21
|
+
])
|
|
22
|
+
|
|
23
|
+
SortStableFunc(values, (a, b) => a.group - b.group)
|
|
24
|
+
|
|
25
|
+
expect(values?.map((value) => value.label)).toEqual(['b', 'd', 'a', 'c'])
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe('slices.Sorted', () => {
|
|
30
|
+
it('collects and sorts iterator values', () => {
|
|
31
|
+
const values = Sorted<string>((yieldValue) => {
|
|
32
|
+
yieldValue('c')
|
|
33
|
+
yieldValue('a')
|
|
34
|
+
yieldValue('b')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
expect(values).toEqual(['a', 'b', 'c'])
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe('slices.Backward', () => {
|
|
42
|
+
it('yields index-value pairs from the end', () => {
|
|
43
|
+
const visited: Array<[number, string]> = []
|
|
44
|
+
Backward($.arrayToSlice(['a', 'b', 'c']))((index, value) => {
|
|
45
|
+
visited.push([index, value])
|
|
46
|
+
return true
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
expect(visited).toEqual([
|
|
50
|
+
[2, 'c'],
|
|
51
|
+
[1, 'b'],
|
|
52
|
+
[0, 'a'],
|
|
53
|
+
])
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('accepts async yield callbacks', async () => {
|
|
57
|
+
const visited: Array<[number, string]> = []
|
|
58
|
+
await Backward($.arrayToSlice(['a', 'b', 'c']))(async (index, value) => {
|
|
59
|
+
visited.push([index, value])
|
|
60
|
+
return index > 1
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
expect(visited).toEqual([
|
|
64
|
+
[2, 'c'],
|
|
65
|
+
[1, 'b'],
|
|
66
|
+
])
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
describe('slices.IsSorted', () => {
|
|
71
|
+
it('reports ordered and unordered slices', () => {
|
|
72
|
+
expect(IsSorted($.arrayToSlice([1, 2, 3]))).toBe(true)
|
|
73
|
+
expect(IsSorted($.arrayToSlice([1, 3, 2]))).toBe(false)
|
|
74
|
+
expect(
|
|
75
|
+
IsSortedFunc($.arrayToSlice(['aa', 'b']), (a, b) => a.length - b.length),
|
|
76
|
+
).toBe(false)
|
|
77
|
+
expect(
|
|
78
|
+
IsSortedFunc($.arrayToSlice(['b', 'aa']), (a, b) => a.length - b.length),
|
|
79
|
+
).toBe(true)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
describe('slices.Max', () => {
|
|
84
|
+
it('returns the greatest ordered value', () => {
|
|
85
|
+
expect(Max($.arrayToSlice([3, 1, 4, 2]))).toBe(4)
|
|
86
|
+
expect(Max($.arrayToSlice(['beta', 'alpha', 'gamma']))).toBe('gamma')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('panics for empty slices', () => {
|
|
90
|
+
expect(() => Max($.arrayToSlice<number>([]))).toThrow(
|
|
91
|
+
'slices.Max: empty list',
|
|
92
|
+
)
|
|
93
|
+
})
|
|
94
|
+
})
|
package/gs/slices/slices.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// TypeScript implementation of Go's slices package
|
|
2
2
|
import * as $ from '@goscript/builtin/index.js'
|
|
3
3
|
import * as cmp from '../cmp/index.js'
|
|
4
|
+
import * as iter from '../iter/index.js'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Compare compares the elements of s1 and s2 using cmp.Compare.
|
|
@@ -41,6 +42,22 @@ export function Compare<T extends string | number>(
|
|
|
41
42
|
return 0
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Clone returns a shallow copy of s while preserving nilness.
|
|
47
|
+
* @param s The slice to clone
|
|
48
|
+
* @returns A new slice with the same elements, or null for a nil slice
|
|
49
|
+
*/
|
|
50
|
+
export function Clone<T>(s: $.Slice<T>): $.Slice<T> {
|
|
51
|
+
if (s == null) {
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
const out = $.makeSlice<T>($.len(s))
|
|
55
|
+
for (let i = 0; i < $.len(s); i++) {
|
|
56
|
+
;(out as any)[i] = (s as any)[i] as T
|
|
57
|
+
}
|
|
58
|
+
return out
|
|
59
|
+
}
|
|
60
|
+
|
|
44
61
|
/**
|
|
45
62
|
* All returns an iterator over index-value pairs in the slice.
|
|
46
63
|
* This is equivalent to Go's slices.All function.
|
|
@@ -61,15 +78,79 @@ export function All<T>(
|
|
|
61
78
|
}
|
|
62
79
|
}
|
|
63
80
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
export function Backward<T>(
|
|
82
|
+
s: $.Slice<T>,
|
|
83
|
+
): (
|
|
84
|
+
_yield: (index: number, value: T) => boolean | globalThis.Promise<boolean>
|
|
85
|
+
) => void | globalThis.Promise<void> {
|
|
86
|
+
return function (
|
|
87
|
+
_yield: (index: number, value: T) => boolean | globalThis.Promise<boolean>,
|
|
88
|
+
): void | globalThis.Promise<void> {
|
|
89
|
+
const walk = (i: number): void | globalThis.Promise<void> => {
|
|
90
|
+
for (; i >= 0; i--) {
|
|
91
|
+
const keepGoing = _yield(i, (s as any)[i] as T)
|
|
92
|
+
if (keepGoing instanceof Promise) {
|
|
93
|
+
return keepGoing.then((next) => {
|
|
94
|
+
if (next) {
|
|
95
|
+
return walk(i - 1)
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
if (!keepGoing) {
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const length = $.len(s)
|
|
105
|
+
if (length === 0) {
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
return walk(length - 1)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
69
112
|
export function Sort<T extends string | number>(s: $.Slice<T>): void {
|
|
70
113
|
$.sortSlice(s)
|
|
71
114
|
}
|
|
72
115
|
|
|
116
|
+
export function IsSorted<T extends string | number>(x: $.Slice<T>): boolean {
|
|
117
|
+
for (let i = $.len(x) - 1; i > 0; i--) {
|
|
118
|
+
if (cmp.Compare((x as any)[i] as T, (x as any)[i - 1] as T) < 0) {
|
|
119
|
+
return false
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function Max<T extends cmp.Ordered>(x: $.Slice<T>): T {
|
|
126
|
+
if ($.len(x) === 0) {
|
|
127
|
+
throw new Error('slices.Max: empty list')
|
|
128
|
+
}
|
|
129
|
+
let max = (x as any)[0] as T
|
|
130
|
+
for (let i = 1; i < $.len(x); i++) {
|
|
131
|
+
const value = (x as any)[i] as T
|
|
132
|
+
if (cmp.Compare(max, value) < 0) {
|
|
133
|
+
max = value
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return max
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function Collect<T>(seq: iter.Seq<T>): $.Slice<T> {
|
|
140
|
+
const out: T[] = []
|
|
141
|
+
seq((value) => {
|
|
142
|
+
out.push(value)
|
|
143
|
+
return true
|
|
144
|
+
})
|
|
145
|
+
return out.length === 0 ? null : out
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function Sorted<T extends string | number>(seq: iter.Seq<T>): $.Slice<T> {
|
|
149
|
+
const out = Collect(seq)
|
|
150
|
+
Sort(out)
|
|
151
|
+
return out
|
|
152
|
+
}
|
|
153
|
+
|
|
73
154
|
/**
|
|
74
155
|
* Delete removes the elements s[i:j] from s, returning the modified slice.
|
|
75
156
|
* Delete panics if j > len(s) or s[i:j] is not a valid slice of s.
|
|
@@ -102,6 +183,112 @@ export function Delete<T>(s: $.Slice<T>, i: number, j: number): $.Slice<T> {
|
|
|
102
183
|
return $.goSlice(s, 0, length - deleteCount) as $.Slice<T>
|
|
103
184
|
}
|
|
104
185
|
|
|
186
|
+
export function DeleteFunc<T>(
|
|
187
|
+
s: $.Slice<T>,
|
|
188
|
+
del: (value: T) => boolean,
|
|
189
|
+
): $.Slice<T> {
|
|
190
|
+
if (s === null || s === undefined) {
|
|
191
|
+
return s
|
|
192
|
+
}
|
|
193
|
+
let w = 0
|
|
194
|
+
for (let i = 0; i < s.length; i++) {
|
|
195
|
+
const value = s[i] as T
|
|
196
|
+
if (!del(value)) {
|
|
197
|
+
;(s as any)[w] = value
|
|
198
|
+
w++
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
for (let i = w; i < s.length; i++) {
|
|
202
|
+
;(s as any)[i] = clearValue(s)
|
|
203
|
+
}
|
|
204
|
+
return $.goSlice(s, 0, w) as $.Slice<T>
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function Equal<T>(s1: $.Slice<T>, s2: $.Slice<T>): boolean {
|
|
208
|
+
const len1 = $.len(s1)
|
|
209
|
+
if (len1 !== $.len(s2)) {
|
|
210
|
+
return false
|
|
211
|
+
}
|
|
212
|
+
for (let i = 0; i < len1; i++) {
|
|
213
|
+
if ((s1 as any)[i] !== (s2 as any)[i]) {
|
|
214
|
+
return false
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return true
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function EqualFunc<T, U>(
|
|
221
|
+
s1: $.Slice<T>,
|
|
222
|
+
s2: $.Slice<U>,
|
|
223
|
+
eq: (v1: T, v2: U) => boolean,
|
|
224
|
+
): boolean {
|
|
225
|
+
const len1 = $.len(s1)
|
|
226
|
+
if (len1 !== $.len(s2)) {
|
|
227
|
+
return false
|
|
228
|
+
}
|
|
229
|
+
for (let i = 0; i < len1; i++) {
|
|
230
|
+
if (!eq((s1 as any)[i] as T, (s2 as any)[i] as U)) {
|
|
231
|
+
return false
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return true
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function Index<T>(s: $.Slice<T>, v: T): number {
|
|
238
|
+
for (let i = 0; i < $.len(s); i++) {
|
|
239
|
+
if ((s as any)[i] === v) {
|
|
240
|
+
return i
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return -1
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function IndexFunc<T>(s: $.Slice<T>, f: (v: T) => boolean): number {
|
|
247
|
+
for (let i = 0; i < $.len(s); i++) {
|
|
248
|
+
if (f((s as any)[i] as T)) {
|
|
249
|
+
return i
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return -1
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function Contains<T>(s: $.Slice<T>, v: T): boolean {
|
|
256
|
+
return Index(s, v) >= 0
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function ContainsFunc<T>(s: $.Slice<T>, f: (v: T) => boolean): boolean {
|
|
260
|
+
return IndexFunc(s, f) >= 0
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function Insert<T>(s: $.Slice<T>, i: number, ...v: T[]): $.Slice<T> {
|
|
264
|
+
const length = $.len(s)
|
|
265
|
+
if (i < 0 || i > length) {
|
|
266
|
+
throw new Error(`slice bounds out of range [${i}:${i}] with length ${length}`)
|
|
267
|
+
}
|
|
268
|
+
if (v.length === 0) {
|
|
269
|
+
return s
|
|
270
|
+
}
|
|
271
|
+
const out = $.makeSlice<T>(length + v.length)
|
|
272
|
+
for (let idx = 0; idx < i; idx++) {
|
|
273
|
+
;(out as any)[idx] = (s as any)[idx]
|
|
274
|
+
}
|
|
275
|
+
for (let idx = 0; idx < v.length; idx++) {
|
|
276
|
+
;(out as any)[i + idx] = v[idx]
|
|
277
|
+
}
|
|
278
|
+
for (let idx = i; idx < length; idx++) {
|
|
279
|
+
;(out as any)[idx + v.length] = (s as any)[idx]
|
|
280
|
+
}
|
|
281
|
+
return out
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function Reverse<T>(s: $.Slice<T>): void {
|
|
285
|
+
for (let i = 0, j = $.len(s) - 1; i < j; i++, j--) {
|
|
286
|
+
const tmp = (s as any)[i]
|
|
287
|
+
;(s as any)[i] = (s as any)[j]
|
|
288
|
+
;(s as any)[j] = tmp
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
105
292
|
/**
|
|
106
293
|
* Grow increases the slice's capacity, if necessary, to guarantee space for
|
|
107
294
|
* another n elements. After Grow(n), at least n elements can be appended
|
|
@@ -154,6 +341,59 @@ export function SortFunc<T>(s: $.Slice<T>, cmp: (a: T, b: T) => number): void {
|
|
|
154
341
|
arr.sort(cmp)
|
|
155
342
|
}
|
|
156
343
|
|
|
344
|
+
export function IsSortedFunc<T>(
|
|
345
|
+
x: $.Slice<T>,
|
|
346
|
+
cmp: (a: T, b: T) => number,
|
|
347
|
+
): boolean {
|
|
348
|
+
for (let i = $.len(x) - 1; i > 0; i--) {
|
|
349
|
+
if (cmp((x as any)[i] as T, (x as any)[i - 1] as T) < 0) {
|
|
350
|
+
return false
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return true
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export function SortStableFunc<T>(
|
|
357
|
+
s: $.Slice<T>,
|
|
358
|
+
cmp: (a: T, b: T) => number,
|
|
359
|
+
): void {
|
|
360
|
+
if (s === null || s === undefined) {
|
|
361
|
+
return
|
|
362
|
+
}
|
|
363
|
+
const sorted = (s as any as T[])
|
|
364
|
+
.map((value, index) => ({ value, index }))
|
|
365
|
+
.sort((a, b) => {
|
|
366
|
+
const result = cmp(a.value, b.value)
|
|
367
|
+
if (result !== 0) {
|
|
368
|
+
return result
|
|
369
|
+
}
|
|
370
|
+
return a.index - b.index
|
|
371
|
+
})
|
|
372
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
373
|
+
;(s as any)[i] = sorted[i].value
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function clearValue<T>(s: $.Slice<T>): T | null {
|
|
378
|
+
if (s instanceof Uint8Array) {
|
|
379
|
+
return 0 as T
|
|
380
|
+
}
|
|
381
|
+
for (const value of s ?? []) {
|
|
382
|
+
if (value !== null && value !== undefined) {
|
|
383
|
+
switch (typeof value) {
|
|
384
|
+
case 'number':
|
|
385
|
+
return 0 as T
|
|
386
|
+
case 'string':
|
|
387
|
+
return '' as T
|
|
388
|
+
case 'boolean':
|
|
389
|
+
return false as T
|
|
390
|
+
}
|
|
391
|
+
break
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return null
|
|
395
|
+
}
|
|
396
|
+
|
|
157
397
|
/**
|
|
158
398
|
* BinarySearchFunc works like BinarySearch, but uses a custom comparison function.
|
|
159
399
|
* The slice must be sorted in increasing order, where "increasing" is defined by cmp.
|
package/gs/sort/slice.gs.ts
CHANGED
|
@@ -27,25 +27,31 @@ function swapInSlice<T>(slice: $.Slice<T>, i: number, j: number): void {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// Slice sorts the slice x given the provided less function
|
|
30
|
-
export function Slice(
|
|
30
|
+
export async function Slice(
|
|
31
|
+
x: $.Slice<any>,
|
|
32
|
+
less: (i: number, j: number) => boolean | globalThis.Promise<boolean>
|
|
33
|
+
): globalThis.Promise<void> {
|
|
31
34
|
if (!x) return
|
|
32
35
|
|
|
33
36
|
// Simple insertion sort using the provided less function
|
|
34
37
|
const n = $.len(x)
|
|
35
38
|
for (let i = 1; i < n; i++) {
|
|
36
|
-
for (let j = i; j > 0 && less(j, j - 1); j--) {
|
|
39
|
+
for (let j = i; j > 0 && await less(j, j - 1); j--) {
|
|
37
40
|
swapInSlice(x, j, j - 1)
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
// SliceIsSorted reports whether the slice x is sorted according to the provided less function
|
|
43
|
-
export function SliceIsSorted(
|
|
46
|
+
export async function SliceIsSorted(
|
|
47
|
+
x: $.Slice<any>,
|
|
48
|
+
less: (i: number, j: number) => boolean | globalThis.Promise<boolean>
|
|
49
|
+
): globalThis.Promise<boolean> {
|
|
44
50
|
if (!x) return true
|
|
45
51
|
|
|
46
52
|
const n = $.len(x)
|
|
47
53
|
for (let i = n - 1; i > 0; i--) {
|
|
48
|
-
if (less(i, i - 1)) {
|
|
54
|
+
if (await less(i, i - 1)) {
|
|
49
55
|
return false
|
|
50
56
|
}
|
|
51
57
|
}
|
|
@@ -53,7 +59,10 @@ export function SliceIsSorted(x: $.Slice<any>, less: (i: number, j: number) => b
|
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
// SliceStable sorts the slice x while keeping the original order of equal elements
|
|
56
|
-
export function SliceStable(
|
|
62
|
+
export async function SliceStable(
|
|
63
|
+
x: $.Slice<any>,
|
|
64
|
+
less: (i: number, j: number) => boolean | globalThis.Promise<boolean>
|
|
65
|
+
): globalThis.Promise<void> {
|
|
57
66
|
// For simplicity, use the same sort - can be improved later
|
|
58
|
-
Slice(x, less)
|
|
59
|
-
}
|
|
67
|
+
await Slice(x, less)
|
|
68
|
+
}
|
package/gs/sort/sort.gs.ts
CHANGED
|
@@ -94,27 +94,29 @@ export class StringSlice {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// Sort sorts data in ascending order as determined by the Less method
|
|
97
|
-
export function Sort(data: Interface): void {
|
|
97
|
+
export function Sort(data: Interface | null): void {
|
|
98
|
+
const sortData = $.pointerValue(data)
|
|
98
99
|
// Use a simple insertion sort for now - can be optimized later
|
|
99
|
-
const n =
|
|
100
|
+
const n = sortData.Len()
|
|
100
101
|
for (let i = 1; i < n; i++) {
|
|
101
|
-
for (let j = i; j > 0 &&
|
|
102
|
-
|
|
102
|
+
for (let j = i; j > 0 && sortData.Less(j, j - 1); j--) {
|
|
103
|
+
sortData.Swap(j, j - 1)
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
// Stable sorts data while keeping the original order of equal elements
|
|
108
|
-
export function Stable(data: Interface): void {
|
|
109
|
+
export function Stable(data: Interface | null): void {
|
|
109
110
|
// For simplicity, use the same sort - can be improved later
|
|
110
111
|
Sort(data)
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
// IsSorted reports whether data is sorted
|
|
114
|
-
export function IsSorted(data: Interface): boolean {
|
|
115
|
-
const
|
|
115
|
+
export function IsSorted(data: Interface | null): boolean {
|
|
116
|
+
const sortData = $.pointerValue(data)
|
|
117
|
+
const n = sortData.Len()
|
|
116
118
|
for (let i = n - 1; i > 0; i--) {
|
|
117
|
-
if (
|
|
119
|
+
if (sortData.Less(i, i - 1)) {
|
|
118
120
|
return false
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -122,11 +124,12 @@ export function IsSorted(data: Interface): boolean {
|
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
// Reverse returns the reverse order for data
|
|
125
|
-
export function Reverse(data: Interface): Interface {
|
|
127
|
+
export function Reverse(data: Interface | null): Interface {
|
|
128
|
+
const sortData = $.pointerValue(data)
|
|
126
129
|
return {
|
|
127
|
-
Len: () =>
|
|
128
|
-
Less: (i: number, j: number) =>
|
|
129
|
-
Swap: (i: number, j: number) =>
|
|
130
|
+
Len: () => sortData.Len(),
|
|
131
|
+
Less: (i: number, j: number) => sortData.Less(j, i),
|
|
132
|
+
Swap: (i: number, j: number) => sortData.Swap(i, j)
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
135
|
|
|
@@ -224,4 +227,4 @@ export function StringsAreSorted(x: $.Slice<string>): boolean {
|
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
return true
|
|
227
|
-
}
|
|
230
|
+
}
|
package/gs/strings/builder.ts
CHANGED
|
@@ -60,12 +60,13 @@ export class Builder {
|
|
|
60
60
|
|
|
61
61
|
// Write appends the contents of p to b's buffer.
|
|
62
62
|
// Write always returns len(p), nil.
|
|
63
|
-
public Write(p:
|
|
63
|
+
public Write(p: $.Bytes): [number, $.GoError] {
|
|
64
64
|
this.copyCheck()
|
|
65
65
|
// Convert byte array to string
|
|
66
|
-
const
|
|
66
|
+
const bytes = $.bytesToUint8Array(p)
|
|
67
|
+
const str = new TextDecoder('utf-8').decode(bytes)
|
|
67
68
|
this._content += str
|
|
68
|
-
return [p
|
|
69
|
+
return [$.len(p), null]
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
// WriteByte appends the byte c to b's buffer.
|