goscript 0.0.60 → 0.0.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +9 -0
  2. package/compiler/analysis.go +974 -369
  3. package/compiler/assignment.go +72 -0
  4. package/compiler/compiler.go +74 -15
  5. package/compiler/composite-lit.go +29 -8
  6. package/compiler/decl.go +67 -98
  7. package/compiler/expr-call-async.go +26 -1
  8. package/compiler/expr-call-builtins.go +60 -4
  9. package/compiler/expr-call-helpers.go +182 -0
  10. package/compiler/expr-call-type-conversion.go +37 -5
  11. package/compiler/expr-call.go +25 -33
  12. package/compiler/expr-selector.go +71 -1
  13. package/compiler/expr-type.go +49 -3
  14. package/compiler/expr.go +37 -28
  15. package/compiler/index.test.ts +3 -1
  16. package/compiler/lit.go +13 -4
  17. package/compiler/spec-struct.go +42 -9
  18. package/compiler/spec-value.go +2 -2
  19. package/compiler/spec.go +42 -5
  20. package/compiler/stmt-assign.go +71 -0
  21. package/compiler/stmt-range.go +2 -2
  22. package/compiler/stmt.go +130 -10
  23. package/compiler/type-utils.go +40 -16
  24. package/compiler/type.go +50 -12
  25. package/dist/gs/builtin/builtin.d.ts +8 -1
  26. package/dist/gs/builtin/builtin.js +26 -1
  27. package/dist/gs/builtin/builtin.js.map +1 -1
  28. package/dist/gs/builtin/errors.d.ts +1 -0
  29. package/dist/gs/builtin/errors.js +8 -0
  30. package/dist/gs/builtin/errors.js.map +1 -1
  31. package/dist/gs/builtin/slice.d.ts +5 -4
  32. package/dist/gs/builtin/slice.js +51 -21
  33. package/dist/gs/builtin/slice.js.map +1 -1
  34. package/dist/gs/builtin/type.d.ts +28 -2
  35. package/dist/gs/builtin/type.js +132 -0
  36. package/dist/gs/builtin/type.js.map +1 -1
  37. package/dist/gs/bytes/reader.gs.d.ts +1 -1
  38. package/dist/gs/bytes/reader.gs.js +1 -1
  39. package/dist/gs/bytes/reader.gs.js.map +1 -1
  40. package/dist/gs/internal/byteorder/index.d.ts +6 -0
  41. package/dist/gs/internal/byteorder/index.js +34 -0
  42. package/dist/gs/internal/byteorder/index.js.map +1 -1
  43. package/dist/gs/reflect/index.d.ts +3 -3
  44. package/dist/gs/reflect/index.js +2 -2
  45. package/dist/gs/reflect/index.js.map +1 -1
  46. package/dist/gs/reflect/map.d.ts +3 -2
  47. package/dist/gs/reflect/map.js +37 -3
  48. package/dist/gs/reflect/map.js.map +1 -1
  49. package/dist/gs/reflect/type.d.ts +55 -8
  50. package/dist/gs/reflect/type.js +889 -23
  51. package/dist/gs/reflect/type.js.map +1 -1
  52. package/dist/gs/reflect/types.d.ts +11 -12
  53. package/dist/gs/reflect/types.js +26 -15
  54. package/dist/gs/reflect/types.js.map +1 -1
  55. package/dist/gs/reflect/value.d.ts +4 -4
  56. package/dist/gs/reflect/value.js +8 -2
  57. package/dist/gs/reflect/value.js.map +1 -1
  58. package/dist/gs/slices/slices.d.ts +32 -0
  59. package/dist/gs/slices/slices.js +81 -0
  60. package/dist/gs/slices/slices.js.map +1 -1
  61. package/dist/gs/sync/atomic/type.gs.d.ts +2 -2
  62. package/dist/gs/sync/atomic/type.gs.js +12 -2
  63. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  64. package/dist/gs/unicode/utf8/utf8.d.ts +2 -2
  65. package/dist/gs/unicode/utf8/utf8.js +10 -6
  66. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  67. package/go.mod +4 -4
  68. package/go.sum +8 -16
  69. package/gs/builtin/builtin.ts +27 -2
  70. package/gs/builtin/errors.ts +12 -0
  71. package/gs/builtin/slice.ts +77 -14
  72. package/gs/builtin/type.ts +167 -2
  73. package/gs/bytes/reader.gs.ts +2 -2
  74. package/gs/internal/byteorder/index.ts +40 -0
  75. package/gs/math/hypot.gs.test.ts +3 -1
  76. package/gs/math/pow10.gs.test.ts +5 -4
  77. package/gs/reflect/index.ts +6 -3
  78. package/gs/reflect/map.test.ts +7 -6
  79. package/gs/reflect/map.ts +49 -7
  80. package/gs/reflect/type.ts +1139 -43
  81. package/gs/reflect/types.ts +34 -21
  82. package/gs/reflect/value.ts +12 -6
  83. package/gs/slices/slices.ts +92 -0
  84. package/gs/sync/atomic/type.gs.ts +14 -5
  85. package/gs/sync/meta.json +1 -1
  86. package/gs/unicode/utf8/utf8.ts +12 -8
  87. package/package.json +13 -13
@@ -41,10 +41,10 @@ import { Type, Kind, Value, Kind_String, ChanDir } from './type.js'
41
41
  export class StructField {
42
42
  public Name: string = ''
43
43
  public Type!: Type
44
- public Tag?: StructTag
45
- public Offset?: uintptr
46
- public Index?: number[]
47
- public Anonymous?: boolean
44
+ public Tag: StructTag = new StructTag('')
45
+ public Offset: uintptr = 0
46
+ public Index: number[] = []
47
+ public Anonymous: boolean = false
48
48
 
49
49
  constructor(init?: Partial<StructField>) {
50
50
  if (init) {
@@ -58,10 +58,14 @@ export class StructField {
58
58
  Type: this.Type,
59
59
  Tag: this.Tag,
60
60
  Offset: this.Offset,
61
- Index: this.Index ? [...this.Index] : undefined,
61
+ Index: [...this.Index],
62
62
  Anonymous: this.Anonymous,
63
63
  })
64
64
  }
65
+
66
+ public IsExported(): boolean {
67
+ return this.Name !== '' && this.Name[0] !== '_'
68
+ }
65
69
  }
66
70
 
67
71
  // Struct tag type
@@ -88,6 +92,14 @@ export class StructTag {
88
92
  }
89
93
  }
90
94
 
95
+ // Wrapper function for GoScript naming convention
96
+ export function StructTag_Get(tag: StructTag | undefined, key: string): string {
97
+ if (!tag) {
98
+ return ''
99
+ }
100
+ return tag.Get(key)
101
+ }
102
+
91
103
  // Method representation
92
104
  export interface Method {
93
105
  Name: string
@@ -106,24 +118,24 @@ export interface Channel<T = unknown> {
106
118
  }
107
119
 
108
120
  // Select case for channel operations
109
- export interface SelectCase {
110
- Dir: SelectDir
111
- Chan?: Value // Value representing a channel - optional since default cases don't need it
112
- Send?: Value // Value to send (if Dir is SendDir) - optional since only needed for send cases
113
- }
121
+ export class SelectCase {
122
+ public Dir!: SelectDir
123
+ public Chan?: Value // Value representing a channel - optional since default cases don't need it
124
+ public Send?: Value // Value to send (if Dir is SendDir) - optional since only needed for send cases
114
125
 
115
- // Select direction constants
116
- export class SelectDir {
117
- constructor(private _value: number) {}
118
-
119
- valueOf(): number {
120
- return this._value
126
+ constructor(init?: Partial<SelectCase>) {
127
+ if (init) {
128
+ Object.assign(this, init)
129
+ }
121
130
  }
122
131
  }
123
132
 
124
- export const SelectSend = new SelectDir(1)
125
- export const SelectRecv = new SelectDir(2)
126
- export const SelectDefault = new SelectDir(3)
133
+ // Select direction constants - SelectDir is just an int in Go
134
+ export type SelectDir = number
135
+
136
+ export const SelectSend: SelectDir = 1
137
+ export const SelectRecv: SelectDir = 2
138
+ export const SelectDefault: SelectDir = 3
127
139
 
128
140
  // Slice header (internal representation)
129
141
  export interface SliceHeader {
@@ -139,12 +151,13 @@ export interface StringHeader {
139
151
  }
140
152
 
141
153
  // Map iterator with proper typing
154
+ // Key() and Value() return reflect.Value to match Go's reflect.MapIter
142
155
  export interface MapIter<K = unknown, V = unknown> {
143
156
  map: Map<K, V>
144
157
  iterator: Iterator<[K, V]>
145
158
  current: IteratorResult<[K, V]> | null
146
- Key(): K | null
147
- Value(): V | null
159
+ Key(): Value
160
+ Value(): Value
148
161
  Next(): boolean
149
162
  Reset(m: Map<K, V>): void
150
163
  }
@@ -34,7 +34,10 @@ interface ChannelObject {
34
34
  }
35
35
 
36
36
  // Zero returns a Value representing the zero value for the specified type.
37
- export function Zero(typ: Type): Value {
37
+ export function Zero(typ: Type | null): Value {
38
+ if (typ === null) {
39
+ return new Value() // Return invalid value for null type
40
+ }
38
41
  let zeroValue: ReflectValue
39
42
 
40
43
  switch (typ.Kind()) {
@@ -129,7 +132,10 @@ export function Indirect(v: Value): Value {
129
132
  }
130
133
 
131
134
  // New returns a Value representing a pointer to a new zero value for the specified type.
132
- export function New(typ: Type): Value {
135
+ export function New(typ: Type | null): Value {
136
+ if (typ === null) {
137
+ return new Value() // Return invalid value for null type
138
+ }
133
139
  const ptrType = PointerTo(typ)
134
140
  // For the pointer value, we'll use the zero value but with pointer type
135
141
  // In a real implementation, this would be a pointer to the zero value
@@ -137,8 +143,8 @@ export function New(typ: Type): Value {
137
143
  }
138
144
 
139
145
  // MakeSlice returns a Value representing a new slice with the specified type, length, and capacity.
140
- export function MakeSlice(typ: Type, len: number, _cap: number): Value {
141
- if (typ.Kind() !== Slice) {
146
+ export function MakeSlice(typ: Type | null, len: number, _cap: number): Value {
147
+ if (typ === null || typ.Kind() !== Slice) {
142
148
  throw new Error('reflect.MakeSlice of non-slice type')
143
149
  }
144
150
 
@@ -156,8 +162,8 @@ export function MakeSlice(typ: Type, len: number, _cap: number): Value {
156
162
  }
157
163
 
158
164
  // MakeMap returns a Value representing a new map with the specified type.
159
- export function MakeMap(typ: Type): Value {
160
- if (typ.Kind() !== Map) {
165
+ export function MakeMap(typ: Type | null): Value {
166
+ if (typ === null || typ.Kind() !== Map) {
161
167
  throw new Error('reflect.MakeMap of non-map type')
162
168
  }
163
169
 
@@ -1,5 +1,45 @@
1
1
  // TypeScript implementation of Go's slices package
2
2
  import * as $ from '@goscript/builtin/index.js'
3
+ import * as cmp from '../cmp/index.js'
4
+
5
+ /**
6
+ * Compare compares the elements of s1 and s2 using cmp.Compare.
7
+ * The elements are compared sequentially, starting at index 0,
8
+ * until one element is not equal to the other.
9
+ * The result of comparing the first non-matching elements is returned.
10
+ * If both slices are equal until one of them ends, the shorter slice is
11
+ * considered less than the longer one.
12
+ * The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
13
+ * @param s1 First slice
14
+ * @param s2 Second slice
15
+ * @returns -1, 0, or 1
16
+ */
17
+ export function Compare<T extends string | number>(
18
+ s1: $.Slice<T>,
19
+ s2: $.Slice<T>,
20
+ ): number {
21
+ const len1 = $.len(s1)
22
+ const len2 = $.len(s2)
23
+ const minLen = len1 < len2 ? len1 : len2
24
+
25
+ for (let i = 0; i < minLen; i++) {
26
+ const v1 = (s1 as any)[i] as T
27
+ const v2 = (s2 as any)[i] as T
28
+ const result = cmp.Compare(v1, v2)
29
+ if (result !== 0) {
30
+ return result
31
+ }
32
+ }
33
+
34
+ // All elements are equal up to minLen, compare lengths
35
+ if (len1 < len2) {
36
+ return -1
37
+ }
38
+ if (len1 > len2) {
39
+ return 1
40
+ }
41
+ return 0
42
+ }
3
43
 
4
44
  /**
5
45
  * All returns an iterator over index-value pairs in the slice.
@@ -62,6 +102,58 @@ export function Delete<T>(s: $.Slice<T>, i: number, j: number): $.Slice<T> {
62
102
  return $.goSlice(s, 0, length - deleteCount) as $.Slice<T>
63
103
  }
64
104
 
105
+ /**
106
+ * Grow increases the slice's capacity, if necessary, to guarantee space for
107
+ * another n elements. After Grow(n), at least n elements can be appended
108
+ * to the slice without another allocation. If n is negative or too large to
109
+ * allocate the memory, Grow panics.
110
+ * This is equivalent to Go's slices.Grow function.
111
+ * @param s The slice to grow
112
+ * @param n The number of additional elements to guarantee space for
113
+ * @returns The slice with increased capacity
114
+ */
115
+ export function Grow<T>(s: $.Slice<T>, n: number): $.Slice<T> {
116
+ if (n < 0) {
117
+ throw new Error(`slices.Grow: negative n: ${n}`)
118
+ }
119
+ const currentLen = $.len(s)
120
+ const currentCap = $.cap(s)
121
+ const neededCap = currentLen + n
122
+
123
+ if (neededCap <= currentCap) {
124
+ return s
125
+ }
126
+
127
+ // Create new slice with increased capacity
128
+ // Go's growth strategy typically doubles capacity when needed
129
+ let newCap = currentCap * 2
130
+ if (newCap < neededCap) {
131
+ newCap = neededCap
132
+ }
133
+
134
+ const newSlice = $.makeSlice<T>(currentLen, newCap)
135
+ for (let i = 0; i < currentLen; i++) {
136
+ ;(newSlice as any)[i] = (s as any)[i]
137
+ }
138
+
139
+ return newSlice
140
+ }
141
+
142
+ /**
143
+ * SortFunc sorts the slice using the provided comparison function.
144
+ * The comparison function should return a negative number if a < b, zero if a == b, or a positive number if a > b.
145
+ * This is equivalent to Go's slices.SortFunc function.
146
+ * @param s The slice to sort in place
147
+ * @param cmp Comparison function
148
+ */
149
+ export function SortFunc<T>(s: $.Slice<T>, cmp: (a: T, b: T) => number): void {
150
+ if (s === null || s === undefined) {
151
+ return
152
+ }
153
+ const arr = s as any as T[]
154
+ arr.sort(cmp)
155
+ }
156
+
65
157
  /**
66
158
  * BinarySearchFunc works like BinarySearch, but uses a custom comparison function.
67
159
  * The slice must be sorted in increasing order, where "increasing" is defined by cmp.
@@ -106,15 +106,24 @@ export class Pointer<T> {
106
106
  }
107
107
 
108
108
  // Store atomically stores val into x.
109
- public Store(val: T): void {
110
- const x = this
111
- const varRef = $.varRef(val)
112
- StorePointer(x._fields.v, unsafe.Pointer(varRef))
109
+ // In Go, this takes *T which can be nil, so we accept T | null
110
+ public Store(val: T | null): void {
111
+ const x = this
112
+ if (val === null) {
113
+ StorePointer(x._fields.v, null)
114
+ } else {
115
+ const varRef = $.varRef(val)
116
+ StorePointer(x._fields.v, unsafe.Pointer(varRef))
117
+ }
113
118
  }
114
119
 
115
120
  // Swap atomically stores new into x and returns the previous value.
116
- public Swap(_new: T): $.VarRef<T> | null {
121
+ // In Go, this takes *T which can be nil, so we accept T | null
122
+ public Swap(_new: T | null): $.VarRef<T> | null {
117
123
  const x = this
124
+ if (_new === null) {
125
+ return SwapPointer(x._fields.v, null) as $.VarRef<T> | null
126
+ }
118
127
  const varRef = $.varRef(_new)
119
128
  return SwapPointer(x._fields.v, unsafe.Pointer(varRef)) as $.VarRef<T> | null
120
129
  }
package/gs/sync/meta.json CHANGED
@@ -16,4 +16,4 @@
16
16
  "Map.Range": true,
17
17
  "Map.Store": true
18
18
  }
19
- }
19
+ }
@@ -15,12 +15,13 @@ export const MaxRune = 0x10ffff
15
15
  export const UTFMax = 4
16
16
 
17
17
  // AppendRune appends the UTF-8 encoding of r to the end of p and returns the extended buffer.
18
- export function AppendRune(p: Uint8Array, r: number): Uint8Array {
18
+ export function AppendRune(p: $.Bytes, r: number): Uint8Array {
19
+ const bytes = $.normalizeBytes(p)
19
20
  const temp = new Uint8Array(UTFMax)
20
21
  const n = EncodeRune(temp, r)
21
- const result = new Uint8Array(p.length + n)
22
- result.set(p)
23
- result.set(temp.slice(0, n), p.length)
22
+ const result = new Uint8Array(bytes.length + n)
23
+ result.set(bytes)
24
+ result.set(temp.slice(0, n), bytes.length)
24
25
  return result
25
26
  }
26
27
 
@@ -90,18 +91,21 @@ export function DecodeRune(p: $.Bytes): [number, number] {
90
91
  }
91
92
 
92
93
  // DecodeRuneInString is like DecodeRune but its input is a string.
93
- export function DecodeRuneInString(s: string): [number, number] {
94
- if (s.length === 0) {
94
+ // Also accepts Bytes for Go's []byte to string conversion pattern.
95
+ export function DecodeRuneInString(s: string | $.Bytes): [number, number] {
96
+ // Convert Bytes to string if necessary
97
+ const str = typeof s === 'string' ? s : $.bytesToString(s)
98
+ if (str.length === 0) {
95
99
  return [RuneError, 0]
96
100
  }
97
101
 
98
- const c = s.charCodeAt(0)
102
+ const c = str.charCodeAt(0)
99
103
  if (c < RuneSelf) {
100
104
  return [c, 1]
101
105
  }
102
106
 
103
107
  // Use JavaScript's built-in Unicode handling
104
- const codePoint = s.codePointAt(0) || RuneError
108
+ const codePoint = str.codePointAt(0) || RuneError
105
109
  const char = String.fromCodePoint(codePoint)
106
110
  const encoder = new TextEncoder()
107
111
  const encoded = encoder.encode(char)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "goscript",
3
3
  "description": "Go to TypeScript transpiler",
4
- "version": "0.0.60",
4
+ "version": "0.0.62",
5
5
  "author": {
6
6
  "name": "Aperture Robotics LLC.",
7
7
  "email": "support@aperture.us",
@@ -58,7 +58,7 @@
58
58
  "release:minor": "npm run release:version:minor && npm run release:commit",
59
59
  "release:version": "npm version patch -m \"release: v%s\" --no-git-tag-version",
60
60
  "release:version:minor": "npm version minor -m \"release: v%s\" --no-git-tag-version",
61
- "release:commit": "git reset && git add package.json && git commit -s -m \"release: v$npm_package_version\" && git tag v$npm_package_version",
61
+ "release:commit": "git reset && git add package.json && git commit -s -m \"release: v$(node -p \"require('./package.json').version\")\" && git tag v$(node -p \"require('./package.json').version\")",
62
62
  "release:publish": "git push && git push --tags && npm run build && npm publish",
63
63
  "lint": "npm run lint:go && npm run lint:js",
64
64
  "lint:go": "golangci-lint run .",
@@ -85,19 +85,19 @@
85
85
  },
86
86
  "devDependencies": {
87
87
  "@aptre/protobuf-es-lite": "^0.5.2",
88
- "@eslint/js": "^9.31.0",
89
- "@types/node": "^24.0.13",
90
- "@typescript-eslint/eslint-plugin": "^8.36.0",
91
- "@typescript-eslint/parser": "^8.36.0",
92
- "@typescript/native-preview": "^7.0.0-dev.20250711.1",
93
- "eslint": "^9.31.0",
88
+ "@eslint/js": "^9.39.2",
89
+ "@types/node": "^25.0.3",
90
+ "@typescript-eslint/eslint-plugin": "^8.50.1",
91
+ "@typescript-eslint/parser": "^8.50.1",
92
+ "@typescript/native-preview": "^7.0.0-dev.20251226.1",
93
+ "eslint": "^9.39.2",
94
94
  "eslint-config-prettier": "^10.0.2",
95
95
  "husky": "^9.1.7",
96
- "lint-staged": "^16.0.0",
97
- "prettier": "^3.6.2",
98
- "tsx": "^4.0.0",
96
+ "lint-staged": "^16.2.7",
97
+ "prettier": "^3.7.4",
98
+ "tsx": "^4.21.0",
99
99
  "typescript": "^5.8.3",
100
- "typescript-eslint": "^8.36.0",
101
- "vitest": "^4.0.0"
100
+ "typescript-eslint": "^8.50.1",
101
+ "vitest": "^4.0.16"
102
102
  }
103
103
  }