goscript 0.0.61 → 0.0.63
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 +62 -46
- package/compiler/analysis.go +621 -19
- package/compiler/analysis_test.go +3 -3
- package/compiler/assignment.go +100 -0
- package/compiler/builtin_test.go +1 -1
- package/compiler/compiler.go +76 -16
- package/compiler/compiler_test.go +9 -9
- package/compiler/composite-lit.go +29 -8
- package/compiler/decl.go +20 -11
- package/compiler/expr-call-async.go +26 -1
- package/compiler/expr-call-builtins.go +60 -4
- package/compiler/expr-call-type-conversion.go +37 -5
- package/compiler/expr-call.go +26 -6
- package/compiler/expr-selector.go +35 -2
- package/compiler/expr-type.go +12 -2
- package/compiler/expr.go +61 -0
- package/compiler/index.test.ts +3 -1
- package/compiler/lit.go +13 -4
- package/compiler/spec-struct.go +30 -8
- package/compiler/spec-value.go +2 -2
- package/compiler/spec.go +23 -4
- package/compiler/stmt-assign.go +124 -0
- package/compiler/stmt-range.go +2 -2
- package/compiler/stmt.go +160 -14
- package/compiler/type-info.go +3 -5
- package/compiler/type-utils.go +40 -1
- package/compiler/type.go +52 -14
- package/dist/gs/builtin/builtin.d.ts +8 -1
- package/dist/gs/builtin/builtin.js +26 -1
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/errors.d.ts +1 -0
- package/dist/gs/builtin/errors.js +8 -0
- package/dist/gs/builtin/errors.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +5 -4
- package/dist/gs/builtin/slice.js +88 -51
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +23 -2
- package/dist/gs/builtin/type.js +125 -0
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +3 -0
- package/dist/gs/builtin/varRef.js +6 -1
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/reader.gs.d.ts +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +2 -2
- package/dist/gs/reflect/index.js +1 -1
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.d.ts +3 -2
- package/dist/gs/reflect/map.js +37 -3
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +53 -12
- package/dist/gs/reflect/type.js +906 -31
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +11 -12
- package/dist/gs/reflect/types.js +26 -15
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -4
- package/dist/gs/reflect/value.js +8 -2
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +21 -0
- package/dist/gs/slices/slices.js +48 -0
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +20 -2
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +3 -3
- package/dist/gs/sync/atomic/type.gs.js +13 -7
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +2 -2
- package/dist/gs/unicode/utf8/utf8.js +10 -6
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/go.mod +6 -6
- package/go.sum +12 -8
- package/gs/builtin/builtin.ts +27 -2
- package/gs/builtin/errors.ts +12 -0
- package/gs/builtin/slice.ts +126 -55
- package/gs/builtin/type.ts +159 -2
- package/gs/builtin/varRef.ts +8 -2
- package/gs/bytes/reader.gs.ts +2 -2
- package/gs/math/hypot.gs.test.ts +3 -1
- package/gs/math/pow10.gs.test.ts +5 -4
- package/gs/reflect/index.ts +3 -2
- package/gs/reflect/map.test.ts +7 -6
- package/gs/reflect/map.ts +49 -7
- package/gs/reflect/type.ts +1150 -57
- package/gs/reflect/types.ts +34 -21
- package/gs/reflect/value.ts +12 -6
- package/gs/slices/slices.ts +55 -0
- package/gs/strconv/atoi.gs.ts +18 -2
- package/gs/sync/atomic/type.gs.ts +15 -10
- package/gs/unicode/utf8/utf8.ts +12 -8
- package/package.json +23 -14
package/README.md
CHANGED
|
@@ -19,53 +19,61 @@ GoScript is an experimental **Go to TypeScript compiler** that translates Go cod
|
|
|
19
19
|
|
|
20
20
|
Write once, run everywhere. Share your Go algorithms, business logic, and data structures seamlessly between your backend and frontend without maintaining two codebases.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
**Use cases:**
|
|
23
|
+
|
|
23
24
|
- Sharing business logic between Go services and web apps
|
|
24
25
|
- Porting Go algorithms to run in browsers
|
|
25
26
|
- Building TypeScript libraries from existing Go code
|
|
26
27
|
|
|
27
28
|
Go has powerful concurrency support and an excellent standard library. GoScript brings these capabilities to TypeScript with as simple and readable of a translation as possible.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
GoScript is working on compiling a subset of Go:
|
|
31
|
-
- ✅ Basic structs, interfaces, methods, and functions
|
|
32
|
-
- ✅ Channels and goroutines (translating to async/await)
|
|
33
|
-
- ✅ Slice semantics, maps, and built-in types
|
|
34
|
-
- ✅ Standard control flow (if, for, switch, select, range, etc.)
|
|
35
|
-
- 🚧 Basic reflection support
|
|
36
|
-
- 🚧 Standard library support
|
|
30
|
+
**✅ What works:**
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
32
|
+
- Structs, interfaces, methods, and functions with full value semantics
|
|
33
|
+
- Channels and goroutines (translated to async/await with function coloring)
|
|
34
|
+
- Pointers and addressability (via VarRef system)
|
|
35
|
+
- Slices, maps, and built-in types
|
|
36
|
+
- Control flow (if, for, switch, select, range, defer, etc.)
|
|
37
|
+
- Type assertions and interface implementations
|
|
38
|
+
- Closures and anonymous functions
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
**🚧 In progress:**
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
- Reflection support
|
|
43
|
+
- Standard library coverage
|
|
44
|
+
- Generics
|
|
48
45
|
|
|
49
|
-
**
|
|
46
|
+
**Known limitations:**
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
- Uses JavaScript `number` type (64-bit float, not Go's int types)
|
|
49
|
+
- No pointer arithmetic (`uintptr`) or `unsafe` package
|
|
50
|
+
- No complex numbers
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
📖 **Learn more:** [Design document](./design/DESIGN.md) | [Architecture explainer](./docs/explainer.md) | [Compliance tests](./tests/README.md)
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
🐛 **Found an issue?** Please [open an issue](https://github.com/aperturerobotics/goscript/issues).
|
|
56
55
|
|
|
57
56
|
## 🚀 Try It
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
### Prerequisites
|
|
59
|
+
|
|
60
|
+
GoScript requires [Bun](https://bun.sh) to be installed for running compliance tests:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Install Bun
|
|
64
|
+
curl -fsSL https://bun.sh/install | bash
|
|
65
|
+
```
|
|
60
66
|
|
|
61
67
|
### Installation
|
|
62
68
|
|
|
63
69
|
**Option 1: Go Install**
|
|
70
|
+
|
|
64
71
|
```bash
|
|
65
72
|
go install github.com/aperturerobotics/goscript/cmd/goscript@latest
|
|
66
73
|
```
|
|
67
74
|
|
|
68
75
|
**Option 2: NPM** (if available)
|
|
76
|
+
|
|
69
77
|
```bash
|
|
70
78
|
npm install -g goscript
|
|
71
79
|
```
|
|
@@ -77,8 +85,6 @@ npm install -g goscript
|
|
|
77
85
|
goscript compile --package . --output ./dist
|
|
78
86
|
```
|
|
79
87
|
|
|
80
|
-
**Note:** Many Go packages may not compile successfully yet. Start with simple code and gradually test more complex features.
|
|
81
|
-
|
|
82
88
|
## 📦 Using Generated Code in Your Project
|
|
83
89
|
|
|
84
90
|
After compiling your Go code to TypeScript, you'll need to set up your project appropriately.
|
|
@@ -107,6 +113,7 @@ Create or update your `tsconfig.json` with these settings:
|
|
|
107
113
|
```
|
|
108
114
|
|
|
109
115
|
**Important requirements:**
|
|
116
|
+
|
|
110
117
|
- **`target: "ES2022"` or newer** - Required for `Disposable` and other features
|
|
111
118
|
- **`lib: ["esnext.disposable"]`** - Enables TypeScript's disposable types for resource management
|
|
112
119
|
- **`baseUrl` and `paths`** - Allows TypeScript to resolve `@goscript/*` imports
|
|
@@ -123,12 +130,14 @@ goscript compile --package ./my-go-code --output ./dist
|
|
|
123
130
|
```
|
|
124
131
|
|
|
125
132
|
**Options:**
|
|
133
|
+
|
|
126
134
|
- `--package <path>` - Go package to compile (default: ".")
|
|
127
135
|
- `--output <dir>` - Output directory for TypeScript files
|
|
128
136
|
|
|
129
137
|
### Programmatic API
|
|
130
138
|
|
|
131
139
|
**Go:**
|
|
140
|
+
|
|
132
141
|
```go
|
|
133
142
|
import "github.com/aperturerobotics/goscript/compiler"
|
|
134
143
|
|
|
@@ -138,24 +147,26 @@ _, err = comp.CompilePackages(ctx, "your/package/path")
|
|
|
138
147
|
```
|
|
139
148
|
|
|
140
149
|
**Node.js:**
|
|
150
|
+
|
|
141
151
|
```typescript
|
|
142
152
|
import { compile } from 'goscript'
|
|
143
153
|
|
|
144
154
|
await compile({
|
|
145
155
|
pkg: './my-go-package',
|
|
146
|
-
output: './dist'
|
|
156
|
+
output: './dist',
|
|
147
157
|
})
|
|
148
158
|
```
|
|
149
159
|
|
|
150
160
|
### Frontend Frameworks
|
|
151
161
|
|
|
152
162
|
**React + GoScript:**
|
|
163
|
+
|
|
153
164
|
```typescript
|
|
154
165
|
import { NewCalculator } from '@goscript/myapp/calculator'
|
|
155
166
|
|
|
156
167
|
function CalculatorApp() {
|
|
157
168
|
const [calc] = useState(() => NewCalculator())
|
|
158
|
-
|
|
169
|
+
|
|
159
170
|
const handleAdd = () => {
|
|
160
171
|
const result = calc.Add(5, 3)
|
|
161
172
|
setResult(result)
|
|
@@ -166,13 +177,12 @@ function CalculatorApp() {
|
|
|
166
177
|
```
|
|
167
178
|
|
|
168
179
|
**Vue + GoScript:**
|
|
180
|
+
|
|
169
181
|
```vue
|
|
170
182
|
<script setup lang="ts">
|
|
171
183
|
import { NewUser, FindUserByEmail } from '@goscript/myapp/user'
|
|
172
184
|
|
|
173
|
-
const users = ref([
|
|
174
|
-
NewUser(1, "Alice", "alice@example.com")
|
|
175
|
-
])
|
|
185
|
+
const users = ref([NewUser(1, 'Alice', 'alice@example.com')])
|
|
176
186
|
|
|
177
187
|
const searchUser = (email: string) => {
|
|
178
188
|
return FindUserByEmail(users.value, email)
|
|
@@ -180,14 +190,14 @@ const searchUser = (email: string) => {
|
|
|
180
190
|
</script>
|
|
181
191
|
```
|
|
182
192
|
|
|
183
|
-
|
|
184
193
|
## 💡 See It In Action
|
|
185
194
|
|
|
186
|
-
|
|
195
|
+
See the [example/app](./example/app) for a full todo list application using GoScript with tRPC, Drizzle ORM, and React, or [example/simple](./example/simple) for a comprehensive demo of language features.
|
|
187
196
|
|
|
188
197
|
### Example: User Management
|
|
189
198
|
|
|
190
199
|
**Go Code** (`user.go`):
|
|
200
|
+
|
|
191
201
|
```go
|
|
192
202
|
package main
|
|
193
203
|
|
|
@@ -216,20 +226,22 @@ func FindUserByEmail(users []*User, email string) *User {
|
|
|
216
226
|
```
|
|
217
227
|
|
|
218
228
|
**Compile it:**
|
|
229
|
+
|
|
219
230
|
```bash
|
|
220
231
|
goscript compile --package . --output ./dist
|
|
221
232
|
```
|
|
222
233
|
|
|
223
234
|
**Generated TypeScript** (`user.gs.ts`):
|
|
235
|
+
|
|
224
236
|
```typescript
|
|
225
237
|
export class User {
|
|
226
238
|
public ID: number = 0
|
|
227
|
-
public Name: string =
|
|
228
|
-
public Email: string =
|
|
239
|
+
public Name: string = ''
|
|
240
|
+
public Email: string = ''
|
|
229
241
|
|
|
230
242
|
public IsValid(): boolean {
|
|
231
243
|
const u = this
|
|
232
|
-
return u.Name !==
|
|
244
|
+
return u.Name !== '' && u.Email !== ''
|
|
233
245
|
}
|
|
234
246
|
|
|
235
247
|
constructor(init?: Partial<User>) {
|
|
@@ -252,26 +264,28 @@ export function FindUserByEmail(users: User[], email: string): User | null {
|
|
|
252
264
|
```
|
|
253
265
|
|
|
254
266
|
**Use in your frontend:**
|
|
267
|
+
|
|
255
268
|
```typescript
|
|
256
269
|
import { NewUser, FindUserByEmail } from '@goscript/myapp/user'
|
|
257
270
|
|
|
258
271
|
// Same logic, now in TypeScript!
|
|
259
272
|
const users = [
|
|
260
|
-
NewUser(1,
|
|
261
|
-
NewUser(2,
|
|
273
|
+
NewUser(1, 'Alice', 'alice@example.com'),
|
|
274
|
+
NewUser(2, 'Bob', 'bob@example.com'),
|
|
262
275
|
]
|
|
263
276
|
|
|
264
|
-
const alice = FindUserByEmail(users,
|
|
277
|
+
const alice = FindUserByEmail(users, 'alice@example.com')
|
|
265
278
|
console.log(alice?.IsValid()) // true
|
|
266
279
|
```
|
|
267
280
|
|
|
268
281
|
### Example: Async Processing with Channels
|
|
269
282
|
|
|
270
283
|
**Go Code:**
|
|
284
|
+
|
|
271
285
|
```go
|
|
272
286
|
func ProcessMessages(messages []string) chan string {
|
|
273
287
|
results := make(chan string, len(messages))
|
|
274
|
-
|
|
288
|
+
|
|
275
289
|
for _, msg := range messages {
|
|
276
290
|
go func(m string) {
|
|
277
291
|
// Simulate processing
|
|
@@ -279,34 +293,36 @@ func ProcessMessages(messages []string) chan string {
|
|
|
279
293
|
results <- processed
|
|
280
294
|
}(msg)
|
|
281
295
|
}
|
|
282
|
-
|
|
296
|
+
|
|
283
297
|
return results
|
|
284
298
|
}
|
|
285
299
|
```
|
|
286
300
|
|
|
287
301
|
**Generated TypeScript:**
|
|
302
|
+
|
|
288
303
|
```typescript
|
|
289
304
|
export function ProcessMessages(messages: string[]): $.Channel<string> {
|
|
290
|
-
let results = $.makeChannel<string>(messages.length,
|
|
291
|
-
|
|
305
|
+
let results = $.makeChannel<string>(messages.length, '')
|
|
306
|
+
|
|
292
307
|
for (let msg of messages) {
|
|
293
308
|
queueMicrotask(async (m: string) => {
|
|
294
|
-
let processed =
|
|
309
|
+
let processed = '✓ ' + m
|
|
295
310
|
await results.send(processed)
|
|
296
311
|
})(msg)
|
|
297
312
|
}
|
|
298
|
-
|
|
313
|
+
|
|
299
314
|
return results
|
|
300
315
|
}
|
|
301
316
|
```
|
|
302
317
|
|
|
303
318
|
**Use with async/await:**
|
|
319
|
+
|
|
304
320
|
```typescript
|
|
305
321
|
import { ProcessMessages } from '@goscript/myapp/processor'
|
|
306
322
|
|
|
307
323
|
async function handleMessages() {
|
|
308
|
-
const channel = ProcessMessages([
|
|
309
|
-
|
|
324
|
+
const channel = ProcessMessages(['hello', 'world', 'goscript'])
|
|
325
|
+
|
|
310
326
|
// Receive processed messages
|
|
311
327
|
for (let i = 0; i < 3; i++) {
|
|
312
328
|
const result = await channel.receive()
|
|
@@ -318,7 +334,7 @@ async function handleMessages() {
|
|
|
318
334
|
## 🤝 How You Can Help
|
|
319
335
|
|
|
320
336
|
- Try GoScript on your code and [report issues](https://github.com/aperturerobotics/goscript/issues)
|
|
321
|
-
- Check the [compliance tests](./
|
|
337
|
+
- Check the [compliance tests](./tests/README.md) for current progress
|
|
322
338
|
- Contribute test cases for edge cases you discover
|
|
323
339
|
|
|
324
340
|
## License
|