goscript 0.0.33 → 0.0.34
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 +2 -2
- package/compiler/assignment.go +26 -0
- package/compiler/builtin_test.go +2 -0
- package/compiler/compiler.go +12 -2
- package/compiler/compiler_test.go +0 -53
- package/compiler/expr-call.go +121 -2
- package/compiler/expr.go +66 -1
- package/compiler/lit.go +1 -1
- package/compiler/stmt-assign.go +106 -90
- package/compiler/stmt-for.go +78 -1
- package/compiler/stmt-range.go +333 -461
- package/compiler/stmt.go +20 -0
- package/compiler/type.go +11 -8
- package/dist/gs/builtin/builtin.d.ts +7 -0
- package/dist/gs/builtin/builtin.js +30 -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 +7 -7
- package/dist/gs/builtin/slice.js +19 -9
- package/dist/gs/builtin/slice.js.map +1 -1
- 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.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/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/slices/slices.d.ts +6 -0
- package/dist/gs/slices/slices.js +8 -0
- package/dist/gs/slices/slices.js.map +1 -1
- package/gs/builtin/builtin.ts +38 -0
- package/gs/builtin/map.ts +10 -9
- package/gs/builtin/slice.ts +23 -11
- package/gs/maps/index.ts +2 -0
- package/gs/maps/iter.gs.ts +71 -0
- package/gs/maps/maps.gs.ts +87 -0
- package/gs/slices/slices.ts +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maps.gs.js","sourceRoot":"","sources":["../../../gs/maps/maps.gs.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,3 +6,9 @@ import * as $ from '@goscript/builtin/builtin.js';
|
|
|
6
6
|
* @returns An iterator function that yields index-value pairs
|
|
7
7
|
*/
|
|
8
8
|
export declare function All<T>(s: $.Slice<T>): (yieldFunc: (index: number, value: T) => boolean) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Sort sorts a slice in ascending order.
|
|
11
|
+
* This is equivalent to Go's slices.Sort function.
|
|
12
|
+
* @param s The slice to sort in place
|
|
13
|
+
*/
|
|
14
|
+
export declare function Sort<T extends string | number>(s: $.Slice<T>): void;
|
package/dist/gs/slices/slices.js
CHANGED
|
@@ -17,4 +17,12 @@ export function All(s) {
|
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Sort sorts a slice in ascending order.
|
|
22
|
+
* This is equivalent to Go's slices.Sort function.
|
|
23
|
+
* @param s The slice to sort in place
|
|
24
|
+
*/
|
|
25
|
+
export function Sort(s) {
|
|
26
|
+
$.sortSlice(s);
|
|
27
|
+
}
|
|
20
28
|
//# sourceMappingURL=slices.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slices.js","sourceRoot":"","sources":["../../../gs/slices/slices.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,OAAO,KAAK,CAAC,MAAM,8BAA8B,CAAA;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CACjB,CAAa;IAEb,OAAO,UAAU,MAA4C;QAC3D,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,KAAK,GAAI,CAAS,CAAC,CAAC,CAAM,CAAA,CAAC,2CAA2C;YAC5E,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC,CAAA;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"slices.js","sourceRoot":"","sources":["../../../gs/slices/slices.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,OAAO,KAAK,CAAC,MAAM,8BAA8B,CAAA;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CACjB,CAAa;IAEb,OAAO,UAAU,MAA4C;QAC3D,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,KAAK,GAAI,CAAS,CAAC,CAAC,CAAM,CAAA,CAAC,2CAA2C;YAC5E,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;gBACtB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAA4B,CAAa;IAC3D,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC"}
|
package/gs/builtin/builtin.ts
CHANGED
|
@@ -6,6 +6,10 @@ export * from './map.js'
|
|
|
6
6
|
export * from './slice.js'
|
|
7
7
|
export * from './type.js'
|
|
8
8
|
|
|
9
|
+
// Bytes represents all valid []byte representations in TypeScript
|
|
10
|
+
// This includes Uint8Array (the preferred representation) and $.Slice<number> (which includes null)
|
|
11
|
+
export type Bytes = Uint8Array | import('./slice.js').Slice<number>
|
|
12
|
+
|
|
9
13
|
// int converts a value to a Go int type, handling proper signed integer conversion
|
|
10
14
|
// This ensures that values like 2147483648 (2^31) are properly handled according to Go semantics
|
|
11
15
|
export function int(value: number): number {
|
|
@@ -169,3 +173,37 @@ export function normalizeBytes(
|
|
|
169
173
|
|
|
170
174
|
throw new Error(`Cannot normalize bytes of type ${typeof bytes}: ${bytes}`)
|
|
171
175
|
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* sortSlice sorts a slice in ascending order.
|
|
179
|
+
* Handles all slice types including null, arrays, Uint8Array, and SliceProxy.
|
|
180
|
+
* @param s The slice to sort in place
|
|
181
|
+
*/
|
|
182
|
+
export function sortSlice<T extends string | number>(s: import('./slice.js').Slice<T>): void {
|
|
183
|
+
if (s === null || s === undefined) {
|
|
184
|
+
return // Nothing to sort for nil slice
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (Array.isArray(s)) {
|
|
188
|
+
s.sort()
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (s instanceof Uint8Array) {
|
|
193
|
+
s.sort()
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Handle SliceProxy case - sort the backing array in-place within the slice bounds
|
|
198
|
+
if (s && typeof s === 'object' && '__meta__' in s) {
|
|
199
|
+
const proxy = s as import('./slice.js').SliceProxy<T>
|
|
200
|
+
const meta = proxy.__meta__
|
|
201
|
+
const section = meta.backing.slice(meta.offset, meta.offset + meta.length)
|
|
202
|
+
section.sort()
|
|
203
|
+
// Copy sorted section back to the backing array
|
|
204
|
+
for (let i = 0; i < section.length; i++) {
|
|
205
|
+
meta.backing[meta.offset + i] = section[i]
|
|
206
|
+
}
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
}
|
package/gs/builtin/map.ts
CHANGED
|
@@ -6,18 +6,19 @@ export const makeMap = <K, V>(): Map<K, V> => {
|
|
|
6
6
|
return new Map<K, V>()
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* Gets a value from a map,
|
|
9
|
+
* Gets a value from a map, returning a tuple [value, exists].
|
|
10
10
|
* @param map The map to get from.
|
|
11
11
|
* @param key The key to get.
|
|
12
|
-
* @param defaultValue The default value to return if the key doesn't exist
|
|
13
|
-
* @returns
|
|
12
|
+
* @param defaultValue The default value to return if the key doesn't exist.
|
|
13
|
+
* @returns A tuple [value, exists] where value is the map value or defaultValue, and exists is whether the key was found.
|
|
14
14
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
export function mapGet<K, V, D>(map: Map<K, V>, key: K, defaultValue: D): [V, true] | [D, false] {
|
|
16
|
+
const exists = map.has(key)
|
|
17
|
+
if (exists) {
|
|
18
|
+
return [map.get(key)!, true]
|
|
19
|
+
} else {
|
|
20
|
+
return [defaultValue, false]
|
|
21
|
+
}
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/**
|
package/gs/builtin/slice.ts
CHANGED
|
@@ -910,8 +910,7 @@ export const sliceString = (
|
|
|
910
910
|
// Attempt to decode with strict UTF-8 validation
|
|
911
911
|
const result = new TextDecoder('utf-8', { fatal: true }).decode(slicedBytes)
|
|
912
912
|
return result
|
|
913
|
-
} catch (_e) {
|
|
914
|
-
//eslint-disable-line @typescript-eslint/no-unused-vars
|
|
913
|
+
} catch (_e) { //eslint-disable-line @typescript-eslint/no-unused-vars
|
|
915
914
|
// If we get here, the slice would create invalid UTF-8
|
|
916
915
|
// This is a fundamental limitation of JavaScript string handling
|
|
917
916
|
throw new Error(
|
|
@@ -975,20 +974,20 @@ export function genericBytesOrStringToString(
|
|
|
975
974
|
}
|
|
976
975
|
|
|
977
976
|
/**
|
|
978
|
-
* Indexes into a value that could be either a string or
|
|
977
|
+
* Indexes into a value that could be either a string or bytes.
|
|
979
978
|
* Used for generic type parameters with constraint string | []byte.
|
|
980
979
|
* Both cases return a byte value (number).
|
|
981
|
-
* @param value Value that is either a string or Uint8Array
|
|
980
|
+
* @param value Value that is either a string or bytes (Uint8Array or Slice<number>)
|
|
982
981
|
* @param index The index to access
|
|
983
982
|
* @returns The byte value at the specified index
|
|
984
983
|
*/
|
|
985
984
|
export function indexStringOrBytes(
|
|
986
|
-
value: string |
|
|
985
|
+
value: string | import('./builtin.js').Bytes,
|
|
987
986
|
index: number,
|
|
988
987
|
): number {
|
|
989
988
|
if (typeof value === 'string') {
|
|
990
989
|
return indexString(value, index)
|
|
991
|
-
} else {
|
|
990
|
+
} else if (value instanceof Uint8Array) {
|
|
992
991
|
// For Uint8Array, direct access returns the byte value
|
|
993
992
|
if (index < 0 || index >= value.length) {
|
|
994
993
|
throw new Error(
|
|
@@ -996,19 +995,32 @@ export function indexStringOrBytes(
|
|
|
996
995
|
)
|
|
997
996
|
}
|
|
998
997
|
return value[index]
|
|
998
|
+
} else if (value === null) {
|
|
999
|
+
throw new Error(
|
|
1000
|
+
`runtime error: index out of range [${index}] with length 0`,
|
|
1001
|
+
)
|
|
1002
|
+
} else {
|
|
1003
|
+
// For Slice<number> (including SliceProxy)
|
|
1004
|
+
const length = len(value)
|
|
1005
|
+
if (index < 0 || index >= length) {
|
|
1006
|
+
throw new Error(
|
|
1007
|
+
`runtime error: index out of range [${index}] with length ${length}`,
|
|
1008
|
+
)
|
|
1009
|
+
}
|
|
1010
|
+
return (value as any)[index] as number
|
|
999
1011
|
}
|
|
1000
1012
|
}
|
|
1001
1013
|
|
|
1002
1014
|
/**
|
|
1003
|
-
* Slices a value that could be either a string or
|
|
1015
|
+
* Slices a value that could be either a string or bytes.
|
|
1004
1016
|
* Used for generic type parameters with constraint string | []byte.
|
|
1005
|
-
* @param value Value that is either a string or Uint8Array
|
|
1017
|
+
* @param value Value that is either a string or bytes (Uint8Array or Slice<number>)
|
|
1006
1018
|
* @param low Starting index (inclusive). Defaults to 0.
|
|
1007
1019
|
* @param high Ending index (exclusive). Defaults to length.
|
|
1008
|
-
* @param max Capacity limit (only used for
|
|
1020
|
+
* @param max Capacity limit (only used for bytes, ignored for strings)
|
|
1009
1021
|
* @returns The sliced value of the same type as input
|
|
1010
1022
|
*/
|
|
1011
|
-
export function sliceStringOrBytes<T extends string |
|
|
1023
|
+
export function sliceStringOrBytes<T extends string | import('./builtin.js').Bytes>(
|
|
1012
1024
|
value: T,
|
|
1013
1025
|
low?: number,
|
|
1014
1026
|
high?: number,
|
|
@@ -1018,7 +1030,7 @@ export function sliceStringOrBytes<T extends string | Uint8Array>(
|
|
|
1018
1030
|
// For strings, use sliceString and ignore max parameter
|
|
1019
1031
|
return sliceString(value, low, high) as T
|
|
1020
1032
|
} else {
|
|
1021
|
-
// For Uint8Array, use goSlice
|
|
1033
|
+
// For bytes (Uint8Array or Slice<number>), use goSlice
|
|
1022
1034
|
return goSlice(value as Slice<number>, low, high, max) as T
|
|
1023
1035
|
}
|
|
1024
1036
|
}
|
package/gs/maps/index.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
|
|
3
|
+
import * as iter from "@goscript/iter/index.js"
|
|
4
|
+
|
|
5
|
+
// All returns an iterator over key-value pairs from m.
|
|
6
|
+
// The iteration order is not specified and is not guaranteed
|
|
7
|
+
// to be the same from one call to the next.
|
|
8
|
+
export function All<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq2<K, V> {
|
|
9
|
+
return (_yield: ((p0: K, p1: V) => boolean) | null): void => {
|
|
10
|
+
for (const [k, v] of m.entries()) {
|
|
11
|
+
{
|
|
12
|
+
if (!_yield!(k, v)) {
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Keys returns an iterator over keys in m.
|
|
21
|
+
// The iteration order is not specified and is not guaranteed
|
|
22
|
+
// to be the same from one call to the next.
|
|
23
|
+
export function Keys<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq<K> {
|
|
24
|
+
return (_yield: ((p0: K) => boolean) | null): void => {
|
|
25
|
+
for (const [k, _v] of m.entries()) {
|
|
26
|
+
{
|
|
27
|
+
if (!_yield!(k)) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Values returns an iterator over values in m.
|
|
36
|
+
// The iteration order is not specified and is not guaranteed
|
|
37
|
+
// to be the same from one call to the next.
|
|
38
|
+
export function Values<K extends $.Comparable, V>(m: Map<K, V>): iter.Seq<V> {
|
|
39
|
+
return (_yield: ((p0: V) => boolean) | null): void => {
|
|
40
|
+
for (const [_k, v] of m.entries()) {
|
|
41
|
+
{
|
|
42
|
+
if (!_yield!(v)) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Insert adds the key-value pairs from seq to m.
|
|
51
|
+
// If a key in seq already exists in m, its value will be overwritten.
|
|
52
|
+
export function Insert<K extends $.Comparable, V>(m: Map<K, V>, seq: iter.Seq2<K, V>): void {
|
|
53
|
+
;(() => {
|
|
54
|
+
let shouldContinue = true
|
|
55
|
+
seq!((k, v) => {
|
|
56
|
+
{
|
|
57
|
+
$.mapSet(m, k, v)
|
|
58
|
+
}
|
|
59
|
+
return shouldContinue
|
|
60
|
+
})
|
|
61
|
+
})()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Collect collects key-value pairs from seq into a new map
|
|
65
|
+
// and returns it.
|
|
66
|
+
export function Collect<K extends $.Comparable, V extends any>(seq: iter.Seq2<K, V>): Map<K, V> {
|
|
67
|
+
let m = $.makeMap<K, V>()
|
|
68
|
+
Insert(m, seq)
|
|
69
|
+
return m
|
|
70
|
+
}
|
|
71
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
|
|
3
|
+
import * as _ from "@goscript/unsafe/index.js"
|
|
4
|
+
|
|
5
|
+
// Equal reports whether two maps contain the same key/value pairs.
|
|
6
|
+
// Values are compared using ==.
|
|
7
|
+
export function Equal<K extends $.Comparable, V extends $.Comparable>(m1: Map<K, V>, m2: Map<K, V>): boolean {
|
|
8
|
+
if ($.len(m1) != $.len(m2)) {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
for (const [k, v1] of m1.entries()) {
|
|
12
|
+
{
|
|
13
|
+
{
|
|
14
|
+
let [v2, ok] = $.mapGet(m2, k, null as any)
|
|
15
|
+
if (!ok || v1 != v2) {
|
|
16
|
+
return false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// EqualFunc is like Equal, but compares values using eq.
|
|
25
|
+
// Keys are still compared with ==.
|
|
26
|
+
export function EqualFunc<K extends $.Comparable, V1, V2>(m1: Map<K, V1>, m2: Map<K, V2>, eq: ((p0: V1, p1: V2) => boolean) | null): boolean {
|
|
27
|
+
if ($.len(m1) != $.len(m2)) {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
for (const [k, v1] of m1.entries()) {
|
|
31
|
+
{
|
|
32
|
+
{
|
|
33
|
+
let [v2, ok] = $.mapGet(m2, k, null as any)
|
|
34
|
+
if (!ok || !eq!(v1, v2)) {
|
|
35
|
+
return false
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// clone returns a shallow copy of the map.
|
|
44
|
+
export function clone<K extends $.Comparable, V>(m: Map<K, V> | null): Map<K, V> | null {
|
|
45
|
+
if (m == null) {
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
const result = $.makeMap<K, V>()
|
|
49
|
+
for (const [k, v] of m.entries()) {
|
|
50
|
+
$.mapSet(result, k, v)
|
|
51
|
+
}
|
|
52
|
+
return result
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Clone returns a copy of m. This is a shallow clone:
|
|
56
|
+
// the new keys and values are set using ordinary assignment.
|
|
57
|
+
export function Clone<K extends $.Comparable, V>(m: Map<K, V>): Map<K, V> {
|
|
58
|
+
// Preserve nil in case it matters.
|
|
59
|
+
if (m == null) {
|
|
60
|
+
return null as unknown as Map<K, V>
|
|
61
|
+
}
|
|
62
|
+
return clone(m)!
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Copy copies all key/value pairs in src adding them to dst.
|
|
66
|
+
// When a key in src is already present in dst,
|
|
67
|
+
// the value in dst will be overwritten by the value associated
|
|
68
|
+
// with the key in src.
|
|
69
|
+
export function Copy<K extends $.Comparable, V>(dst: Map<K, V>, src: Map<K, V>): void {
|
|
70
|
+
for (const [k, v] of src.entries()) {
|
|
71
|
+
{
|
|
72
|
+
$.mapSet(dst, k, v)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// DeleteFunc deletes any key/value pairs from m for which del returns true.
|
|
78
|
+
export function DeleteFunc<K extends $.Comparable, V>(m: Map<K, V>, del: ((p0: K, p1: V) => boolean) | null): void {
|
|
79
|
+
for (const [k, v] of m.entries()) {
|
|
80
|
+
{
|
|
81
|
+
if (del!(k, v)) {
|
|
82
|
+
$.deleteMapEntry(m, k)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
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
|
+
}
|