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.
Files changed (92) hide show
  1. package/README.md +62 -46
  2. package/compiler/analysis.go +621 -19
  3. package/compiler/analysis_test.go +3 -3
  4. package/compiler/assignment.go +100 -0
  5. package/compiler/builtin_test.go +1 -1
  6. package/compiler/compiler.go +76 -16
  7. package/compiler/compiler_test.go +9 -9
  8. package/compiler/composite-lit.go +29 -8
  9. package/compiler/decl.go +20 -11
  10. package/compiler/expr-call-async.go +26 -1
  11. package/compiler/expr-call-builtins.go +60 -4
  12. package/compiler/expr-call-type-conversion.go +37 -5
  13. package/compiler/expr-call.go +26 -6
  14. package/compiler/expr-selector.go +35 -2
  15. package/compiler/expr-type.go +12 -2
  16. package/compiler/expr.go +61 -0
  17. package/compiler/index.test.ts +3 -1
  18. package/compiler/lit.go +13 -4
  19. package/compiler/spec-struct.go +30 -8
  20. package/compiler/spec-value.go +2 -2
  21. package/compiler/spec.go +23 -4
  22. package/compiler/stmt-assign.go +124 -0
  23. package/compiler/stmt-range.go +2 -2
  24. package/compiler/stmt.go +160 -14
  25. package/compiler/type-info.go +3 -5
  26. package/compiler/type-utils.go +40 -1
  27. package/compiler/type.go +52 -14
  28. package/dist/gs/builtin/builtin.d.ts +8 -1
  29. package/dist/gs/builtin/builtin.js +26 -1
  30. package/dist/gs/builtin/builtin.js.map +1 -1
  31. package/dist/gs/builtin/errors.d.ts +1 -0
  32. package/dist/gs/builtin/errors.js +8 -0
  33. package/dist/gs/builtin/errors.js.map +1 -1
  34. package/dist/gs/builtin/slice.d.ts +5 -4
  35. package/dist/gs/builtin/slice.js +88 -51
  36. package/dist/gs/builtin/slice.js.map +1 -1
  37. package/dist/gs/builtin/type.d.ts +23 -2
  38. package/dist/gs/builtin/type.js +125 -0
  39. package/dist/gs/builtin/type.js.map +1 -1
  40. package/dist/gs/builtin/varRef.d.ts +3 -0
  41. package/dist/gs/builtin/varRef.js +6 -1
  42. package/dist/gs/builtin/varRef.js.map +1 -1
  43. package/dist/gs/bytes/reader.gs.d.ts +1 -1
  44. package/dist/gs/bytes/reader.gs.js +1 -1
  45. package/dist/gs/bytes/reader.gs.js.map +1 -1
  46. package/dist/gs/reflect/index.d.ts +2 -2
  47. package/dist/gs/reflect/index.js +1 -1
  48. package/dist/gs/reflect/index.js.map +1 -1
  49. package/dist/gs/reflect/map.d.ts +3 -2
  50. package/dist/gs/reflect/map.js +37 -3
  51. package/dist/gs/reflect/map.js.map +1 -1
  52. package/dist/gs/reflect/type.d.ts +53 -12
  53. package/dist/gs/reflect/type.js +906 -31
  54. package/dist/gs/reflect/type.js.map +1 -1
  55. package/dist/gs/reflect/types.d.ts +11 -12
  56. package/dist/gs/reflect/types.js +26 -15
  57. package/dist/gs/reflect/types.js.map +1 -1
  58. package/dist/gs/reflect/value.d.ts +4 -4
  59. package/dist/gs/reflect/value.js +8 -2
  60. package/dist/gs/reflect/value.js.map +1 -1
  61. package/dist/gs/slices/slices.d.ts +21 -0
  62. package/dist/gs/slices/slices.js +48 -0
  63. package/dist/gs/slices/slices.js.map +1 -1
  64. package/dist/gs/strconv/atoi.gs.js +20 -2
  65. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  66. package/dist/gs/sync/atomic/type.gs.d.ts +3 -3
  67. package/dist/gs/sync/atomic/type.gs.js +13 -7
  68. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  69. package/dist/gs/unicode/utf8/utf8.d.ts +2 -2
  70. package/dist/gs/unicode/utf8/utf8.js +10 -6
  71. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  72. package/go.mod +6 -6
  73. package/go.sum +12 -8
  74. package/gs/builtin/builtin.ts +27 -2
  75. package/gs/builtin/errors.ts +12 -0
  76. package/gs/builtin/slice.ts +126 -55
  77. package/gs/builtin/type.ts +159 -2
  78. package/gs/builtin/varRef.ts +8 -2
  79. package/gs/bytes/reader.gs.ts +2 -2
  80. package/gs/math/hypot.gs.test.ts +3 -1
  81. package/gs/math/pow10.gs.test.ts +5 -4
  82. package/gs/reflect/index.ts +3 -2
  83. package/gs/reflect/map.test.ts +7 -6
  84. package/gs/reflect/map.ts +49 -7
  85. package/gs/reflect/type.ts +1150 -57
  86. package/gs/reflect/types.ts +34 -21
  87. package/gs/reflect/value.ts +12 -6
  88. package/gs/slices/slices.ts +55 -0
  89. package/gs/strconv/atoi.gs.ts +18 -2
  90. package/gs/sync/atomic/type.gs.ts +15 -10
  91. package/gs/unicode/utf8/utf8.ts +12 -8
  92. 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
- 🔬 **Experimental features being developed:**
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
- ⚠️ **Current development status:**
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
- **Known limitations in this preview:**
39
- - Uses JavaScript `number` type (64-bit float, not Go's int types)
40
- - No pointer arithmetic (`uintptr`) or `unsafe` package
41
- - No complex numbers
42
- - Limited standard library (working on it)
43
- - Performance not yet optimized
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
- **This is a prototype!** Expect bugs and missing features. Please contribute!
40
+ **🚧 In progress:**
46
41
 
47
- ### ⚠️ Development Preview
42
+ - Reflection support
43
+ - Standard library coverage
44
+ - Generics
48
45
 
49
- **This project is currently in active development and should be considered experimental.** GoScript is a work-in-progress prototype that may have bugs, incomplete features, and breaking changes. We're actively iterating on the compiler and welcome your feedback!
46
+ **Known limitations:**
50
47
 
51
- 🐛 **Found an issue?** Please [open an issue](https://github.com/aperturerobotics/goscript/issues) and we'll fix it.
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
- 🤖 **AI** This prototype is heavily AI-written, but I plan to manually rewrite the codebase by hand once it reaches a working state for advanced use cases. AI Producer, human Reducer.
52
+ 📖 **Learn more:** [Design document](./design/DESIGN.md) | [Architecture explainer](./docs/explainer.md) | [Compliance tests](./tests/README.md)
54
53
 
55
- 📖 **Learn more:** [Design document](./design/DESIGN.md) | [Compliance tests](./compliance/COMPLIANCE.md)
54
+ 🐛 **Found an issue?** Please [open an issue](https://github.com/aperturerobotics/goscript/issues).
56
55
 
57
56
  ## 🚀 Try It
58
57
 
59
- > **Warning:** This is experimental software. Features may be incomplete or broken. Please report any issues!
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
- > **Disclaimer:** These examples represent the target functionality. Your mileage may vary with the current development preview.
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 !== "" && u.Email !== ""
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, "Alice", "alice@example.com"),
261
- NewUser(2, "Bob", "bob@example.com")
273
+ NewUser(1, 'Alice', 'alice@example.com'),
274
+ NewUser(2, 'Bob', 'bob@example.com'),
262
275
  ]
263
276
 
264
- const alice = FindUserByEmail(users, "alice@example.com")
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 = "" + m
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(["hello", "world", "goscript"])
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](./compliance/COMPLIANCE.md) for current progress
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