goscript 0.0.50 → 0.0.52
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 +513 -325
- package/compiler/compiler.go +39 -6
- package/compiler/expr-call-async.go +90 -23
- package/compiler/expr.go +0 -44
- package/compiler/sanitize.go +1 -2
- package/compiler/spec-struct.go +3 -3
- package/compiler/spec.go +0 -21
- package/compiler/stmt-assign.go +0 -6
- package/compiler/stmt-select.go +52 -1
- package/compiler/type-assert.go +6 -6
- package/compiler/type.go +3 -3
- package/dist/gs/builtin/builtin.d.ts +0 -1
- package/dist/gs/builtin/builtin.js +0 -9
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +5 -3
- package/dist/gs/builtin/channel.js +14 -17
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/context/context.js +2 -2
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/runtime/runtime.d.ts +1 -1
- package/dist/gs/runtime/runtime.js +1 -1
- package/dist/gs/syscall/constants.d.ts +24 -0
- package/dist/gs/syscall/constants.js +27 -0
- package/dist/gs/syscall/constants.js.map +1 -0
- package/dist/gs/syscall/env.d.ts +6 -0
- package/dist/gs/syscall/env.js +43 -0
- package/dist/gs/syscall/env.js.map +1 -0
- package/dist/gs/syscall/errors.d.ts +111 -0
- package/dist/gs/syscall/errors.js +547 -0
- package/dist/gs/syscall/errors.js.map +1 -0
- package/dist/gs/syscall/fs.d.ts +29 -0
- package/dist/gs/syscall/fs.js +53 -0
- package/dist/gs/syscall/fs.js.map +1 -0
- package/dist/gs/syscall/index.d.ts +6 -80
- package/dist/gs/syscall/index.js +12 -168
- package/dist/gs/syscall/index.js.map +1 -1
- package/dist/gs/syscall/rawconn.d.ts +7 -0
- package/dist/gs/syscall/rawconn.js +19 -0
- package/dist/gs/syscall/rawconn.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +12 -0
- package/dist/gs/syscall/types.js +2 -0
- package/dist/gs/syscall/types.js.map +1 -0
- package/dist/gs/time/time.d.ts +2 -2
- package/dist/gs/time/time.js +12 -9
- package/dist/gs/time/time.js.map +1 -1
- package/go.mod +1 -1
- package/gs/builtin/builtin.ts +0 -11
- package/gs/builtin/channel.ts +39 -17
- package/gs/context/context.ts +6 -2
- package/gs/context/meta.json +16 -0
- package/gs/runtime/runtime.ts +1 -1
- package/gs/syscall/constants.ts +29 -0
- package/gs/syscall/env.ts +47 -0
- package/gs/syscall/errors.ts +658 -0
- package/gs/syscall/fs.ts +62 -0
- package/gs/syscall/index.ts +12 -207
- package/gs/syscall/rawconn.ts +23 -0
- package/gs/syscall/types.ts +18 -0
- package/gs/time/meta.json +6 -0
- package/gs/time/time.ts +16 -13
- package/gs/unicode/meta.json +24 -0
- package/package.json +1 -1
- package/gs/unicode/unicode.go +0 -38
package/gs/builtin/channel.ts
CHANGED
|
@@ -88,7 +88,7 @@ export interface SelectCase<T> {
|
|
|
88
88
|
channel: Channel<any> | ChannelRef<any> | null // Allow null and ChannelRef
|
|
89
89
|
value?: any // Value to send for send cases
|
|
90
90
|
// Optional handlers for when this case is selected
|
|
91
|
-
onSelected?: (result: SelectResult<T>) => Promise<
|
|
91
|
+
onSelected?: (result: SelectResult<T>) => Promise<any>
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
@@ -99,14 +99,14 @@ export interface SelectCase<T> {
|
|
|
99
99
|
* @param hasDefault Whether there is a default case
|
|
100
100
|
* @returns A promise that resolves with the result of the selected case
|
|
101
101
|
*/
|
|
102
|
-
export async function selectStatement<T>(
|
|
102
|
+
export async function selectStatement<T, V = void>(
|
|
103
103
|
cases: SelectCase<T>[],
|
|
104
104
|
hasDefault: boolean = false,
|
|
105
|
-
): Promise<
|
|
105
|
+
): Promise<[boolean, V]> {
|
|
106
106
|
if (cases.length === 0 && !hasDefault) {
|
|
107
107
|
// Go spec: If there are no cases, the select statement blocks forever.
|
|
108
108
|
// Emulate blocking forever with a promise that never resolves.
|
|
109
|
-
return new Promise<
|
|
109
|
+
return new Promise<[boolean, V]>(() => {}) // Promise never resolves
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
// 1. Check for ready (non-blocking) operations
|
|
@@ -143,19 +143,23 @@ export async function selectStatement<T>(
|
|
|
143
143
|
selectedCase.id,
|
|
144
144
|
)
|
|
145
145
|
if (selectedCase.onSelected) {
|
|
146
|
-
await selectedCase.onSelected(
|
|
146
|
+
const handlerResult = await selectedCase.onSelected(
|
|
147
|
+
result as SelectResult<T>,
|
|
148
|
+
)
|
|
149
|
+
return [handlerResult !== undefined, handlerResult as V]
|
|
147
150
|
}
|
|
148
151
|
} else {
|
|
149
152
|
const result = await selectedCase.channel.selectReceive(selectedCase.id)
|
|
150
153
|
if (selectedCase.onSelected) {
|
|
151
|
-
await selectedCase.onSelected(result)
|
|
154
|
+
const handlerResult = await selectedCase.onSelected(result)
|
|
155
|
+
return [handlerResult !== undefined, handlerResult as V]
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
158
|
} else {
|
|
155
159
|
// This case should ideally not happen if channel is required for non-default cases
|
|
156
160
|
console.error('Selected case without a channel:', selectedCase)
|
|
157
161
|
}
|
|
158
|
-
return // Return after executing a ready case
|
|
162
|
+
return [false, undefined as V] // Return after executing a ready case
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
// 2. If no operations are ready and there's a default case, select default
|
|
@@ -164,13 +168,14 @@ export async function selectStatement<T>(
|
|
|
164
168
|
const defaultCase = cases.find((c) => c.id === -1)
|
|
165
169
|
if (defaultCase && defaultCase.onSelected) {
|
|
166
170
|
// Execute the onSelected handler for the default case
|
|
167
|
-
await defaultCase.onSelected({
|
|
171
|
+
const handlerResult = await defaultCase.onSelected({
|
|
168
172
|
value: undefined,
|
|
169
173
|
ok: false,
|
|
170
174
|
id: -1,
|
|
171
|
-
} as SelectResult<T>)
|
|
175
|
+
} as SelectResult<T>)
|
|
176
|
+
return [handlerResult !== undefined, handlerResult as V]
|
|
172
177
|
}
|
|
173
|
-
return // Return after executing the default case
|
|
178
|
+
return [false, undefined as V] // Return after executing the default case
|
|
174
179
|
}
|
|
175
180
|
|
|
176
181
|
// 3. If no operations are ready and no default case, block until one is ready
|
|
@@ -190,16 +195,19 @@ export async function selectStatement<T>(
|
|
|
190
195
|
// If all non-default cases have nil channels, we effectively block forever
|
|
191
196
|
if (blockingPromises.length === 0) {
|
|
192
197
|
// No valid channels to operate on, block forever (unless there's a default)
|
|
193
|
-
return new Promise<
|
|
198
|
+
return new Promise<[boolean, V]>(() => {}) // Promise never resolves
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
const result = await Promise.race(blockingPromises)
|
|
197
202
|
// Execute onSelected handler for the selected case
|
|
198
203
|
const selectedCase = cases.find((c) => c.id === result.id)
|
|
199
204
|
if (selectedCase && selectedCase.onSelected) {
|
|
200
|
-
await selectedCase.onSelected(result)
|
|
205
|
+
const handlerResult = await selectedCase.onSelected(result)
|
|
206
|
+
return [handlerResult !== undefined, handlerResult as V]
|
|
201
207
|
}
|
|
208
|
+
|
|
202
209
|
// No explicit return needed here, as the function will implicitly return after the await
|
|
210
|
+
return [false, undefined as V]
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
/**
|
|
@@ -259,18 +267,32 @@ export async function chanRecvWithOk<T>(
|
|
|
259
267
|
* @param direction Optional direction for the channel. Default is 'both' (bidirectional).
|
|
260
268
|
* @returns A new channel instance or channel reference.
|
|
261
269
|
*/
|
|
262
|
-
export
|
|
270
|
+
export function makeChannel<T>(
|
|
271
|
+
bufferSize: number,
|
|
272
|
+
zeroValue: T,
|
|
273
|
+
direction: 'send',
|
|
274
|
+
): SendOnlyChannelRef<T>
|
|
275
|
+
export function makeChannel<T>(
|
|
276
|
+
bufferSize: number,
|
|
277
|
+
zeroValue: T,
|
|
278
|
+
direction: 'receive',
|
|
279
|
+
): ReceiveOnlyChannelRef<T>
|
|
280
|
+
export function makeChannel<T>(
|
|
281
|
+
bufferSize: number,
|
|
282
|
+
zeroValue: T,
|
|
283
|
+
direction?: 'both',
|
|
284
|
+
): Channel<T>
|
|
285
|
+
export function makeChannel<T>(
|
|
263
286
|
bufferSize: number,
|
|
264
287
|
zeroValue: T,
|
|
265
288
|
direction: 'send' | 'receive' | 'both' = 'both',
|
|
266
|
-
): Channel<T> | ChannelRef<T>
|
|
289
|
+
): Channel<T> | ChannelRef<T> {
|
|
267
290
|
const channel = new BufferedChannel<T>(bufferSize, zeroValue)
|
|
268
291
|
|
|
269
|
-
// Wrap the channel with the appropriate ChannelRef based on direction
|
|
270
292
|
if (direction === 'send') {
|
|
271
|
-
return new SendOnlyChannelRef<T>(channel)
|
|
293
|
+
return new SendOnlyChannelRef<T>(channel)
|
|
272
294
|
} else if (direction === 'receive') {
|
|
273
|
-
return new ReceiveOnlyChannelRef<T>(channel)
|
|
295
|
+
return new ReceiveOnlyChannelRef<T>(channel)
|
|
274
296
|
} else {
|
|
275
297
|
return channel
|
|
276
298
|
}
|
package/gs/context/context.ts
CHANGED
|
@@ -343,7 +343,7 @@ export function WithTimeout(
|
|
|
343
343
|
parent: Context,
|
|
344
344
|
timeout: number,
|
|
345
345
|
): [ContextNonNil, CancelFunc] {
|
|
346
|
-
return WithDeadline(parent, new Date(Date.now() + timeout))
|
|
346
|
+
return WithDeadline(parent, new Date(Date.now() + timeout / 1000000))
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
// WithTimeoutCause is like WithTimeout but also sets the cause
|
|
@@ -352,7 +352,11 @@ export function WithTimeoutCause(
|
|
|
352
352
|
timeout: number,
|
|
353
353
|
cause: $.GoError,
|
|
354
354
|
): [ContextNonNil, CancelFunc] {
|
|
355
|
-
return WithDeadlineCause(
|
|
355
|
+
return WithDeadlineCause(
|
|
356
|
+
parent,
|
|
357
|
+
new Date(Date.now() + timeout / 1000000),
|
|
358
|
+
cause,
|
|
359
|
+
)
|
|
356
360
|
}
|
|
357
361
|
|
|
358
362
|
// WithValue returns a copy of parent with the value associated with key
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"asyncMethods": {
|
|
3
|
+
"Background": false,
|
|
4
|
+
"TODO": false,
|
|
5
|
+
"WithCancel": false,
|
|
6
|
+
"WithCancelCause": false,
|
|
7
|
+
"WithDeadline": false,
|
|
8
|
+
"WithDeadlineCause": false,
|
|
9
|
+
"WithTimeout": false,
|
|
10
|
+
"WithTimeoutCause": false,
|
|
11
|
+
"WithValue": false,
|
|
12
|
+
"WithoutCancel": false,
|
|
13
|
+
"Cause": false,
|
|
14
|
+
"AfterFunc": false
|
|
15
|
+
}
|
|
16
|
+
}
|
package/gs/runtime/runtime.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Essential syscall constants
|
|
2
|
+
export const O_RDONLY = 0
|
|
3
|
+
export const O_WRONLY = 1
|
|
4
|
+
export const O_RDWR = 2
|
|
5
|
+
export const O_APPEND = 8
|
|
6
|
+
export const O_CREATE = 64
|
|
7
|
+
export const O_EXCL = 128
|
|
8
|
+
export const O_SYNC = 256
|
|
9
|
+
export const O_TRUNC = 512
|
|
10
|
+
|
|
11
|
+
export const Stdin = 0
|
|
12
|
+
export const Stdout = 1
|
|
13
|
+
export const Stderr = 2
|
|
14
|
+
|
|
15
|
+
export const SIGINT = 2
|
|
16
|
+
export const SIGTERM = 15
|
|
17
|
+
|
|
18
|
+
// File mode constants
|
|
19
|
+
export const S_IFMT = 0o170000
|
|
20
|
+
export const S_IFREG = 0o100000
|
|
21
|
+
export const S_IFDIR = 0o040000
|
|
22
|
+
export const S_IFLNK = 0o120000
|
|
23
|
+
export const S_IFBLK = 0o060000
|
|
24
|
+
export const S_IFCHR = 0o020000
|
|
25
|
+
export const S_IFIFO = 0o010000
|
|
26
|
+
export const S_IFSOCK = 0o140000
|
|
27
|
+
export const S_ISUID = 0o004000
|
|
28
|
+
export const S_ISGID = 0o002000
|
|
29
|
+
export const S_ISVTX = 0o001000
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
|
|
3
|
+
// Environment variable functions using Node.js/browser APIs
|
|
4
|
+
export function Getenv(key: string): [string, boolean] {
|
|
5
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
6
|
+
const value = process.env[key]
|
|
7
|
+
return value !== undefined ? [value, true] : ['', false]
|
|
8
|
+
}
|
|
9
|
+
return ['', false]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function Setenv(key: string, value: string): $.GoError {
|
|
13
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
14
|
+
process.env[key] = value
|
|
15
|
+
return null
|
|
16
|
+
}
|
|
17
|
+
return { Error: () => 'setenv not supported' }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function Unsetenv(key: string): $.GoError {
|
|
21
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
22
|
+
delete process.env[key]
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
return { Error: () => 'unsetenv not supported' }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function Clearenv(): void {
|
|
29
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
30
|
+
for (const key in process.env) {
|
|
31
|
+
delete process.env[key]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function Environ(): $.Slice<string> {
|
|
37
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
38
|
+
const env: string[] = []
|
|
39
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
40
|
+
if (value !== undefined) {
|
|
41
|
+
env.push(`${key}=${value}`)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return $.arrayToSlice(env)
|
|
45
|
+
}
|
|
46
|
+
return $.arrayToSlice([])
|
|
47
|
+
}
|