goscript 0.0.2
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/.aider-prompt +11 -0
- package/LICENSE +21 -0
- package/README.md +427 -0
- package/builtin/builtin.ts +507 -0
- package/cmd/goscript/cmd_compile.go +59 -0
- package/cmd/goscript/main.go +23 -0
- package/compiler/compile.go +183 -0
- package/compiler/compile_comment.go +41 -0
- package/compiler/compile_decls.go +72 -0
- package/compiler/compile_expr.go +831 -0
- package/compiler/compile_field.go +89 -0
- package/compiler/compile_spec.go +256 -0
- package/compiler/compile_stmt.go +1509 -0
- package/compiler/compiler.go +81 -0
- package/compiler/config.go +32 -0
- package/compiler/context.go +9 -0
- package/compiler/file_compiler.go +80 -0
- package/compiler/output_path.go +31 -0
- package/compiler/pkg_compiler.go +73 -0
- package/compiler/writer.go +90 -0
- package/compliance/COMPLIANCE.md +133 -0
- package/compliance/compliance.go +313 -0
- package/compliance/compliance_test.go +57 -0
- package/compliance/tests/array_literal/array_literal.go +15 -0
- package/compliance/tests/array_literal/array_literal.gs.ts +19 -0
- package/compliance/tests/array_literal/expected.log +3 -0
- package/compliance/tests/async_basic/async_basic.go +26 -0
- package/compliance/tests/async_basic/async_basic.gs.ts +30 -0
- package/compliance/tests/async_basic/expected.log +1 -0
- package/compliance/tests/basic_arithmetic/basic_arithmetic.go +15 -0
- package/compliance/tests/basic_arithmetic/basic_arithmetic.gs.ts +19 -0
- package/compliance/tests/basic_arithmetic/expected.log +5 -0
- package/compliance/tests/boolean_logic/boolean_logic.go +13 -0
- package/compliance/tests/boolean_logic/boolean_logic.gs.ts +17 -0
- package/compliance/tests/boolean_logic/expected.log +3 -0
- package/compliance/tests/channel_basic/channel_basic.go +12 -0
- package/compliance/tests/channel_basic/channel_basic.gs.ts +18 -0
- package/compliance/tests/channel_basic/expected.log +1 -0
- package/compliance/tests/composite_literal_assignment/composite_literal_assignment.go +20 -0
- package/compliance/tests/composite_literal_assignment/composite_literal_assignment.gs.ts +27 -0
- package/compliance/tests/composite_literal_assignment/expected.log +2 -0
- package/compliance/tests/constants/constants.go +18 -0
- package/compliance/tests/constants/constants.gs.ts +22 -0
- package/compliance/tests/constants/expected.log +3 -0
- package/compliance/tests/copy_independence/copy_independence.go +29 -0
- package/compliance/tests/copy_independence/copy_independence.gs.ts +36 -0
- package/compliance/tests/copy_independence/expected.log +4 -0
- package/compliance/tests/float64/expected.log +6 -0
- package/compliance/tests/float64/float64.go +28 -0
- package/compliance/tests/float64/float64.gs.ts +32 -0
- package/compliance/tests/for_loop_basic/expected.log +5 -0
- package/compliance/tests/for_loop_basic/for_loop_basic.go +9 -0
- package/compliance/tests/for_loop_basic/for_loop_basic.gs.ts +13 -0
- package/compliance/tests/for_loop_condition_only/expected.log +5 -0
- package/compliance/tests/for_loop_condition_only/main.go +9 -0
- package/compliance/tests/for_loop_condition_only/main.gs.ts +13 -0
- package/compliance/tests/for_range/expected.log +9 -0
- package/compliance/tests/for_range/for_range.go +26 -0
- package/compliance/tests/for_range/for_range.gs.ts +45 -0
- package/compliance/tests/for_range_index_use/expected.log +6 -0
- package/compliance/tests/for_range_index_use/for_range_index_use.go +11 -0
- package/compliance/tests/for_range_index_use/for_range_index_use.gs.ts +18 -0
- package/compliance/tests/func_literal/expected.log +1 -0
- package/compliance/tests/func_literal/func_literal.go +10 -0
- package/compliance/tests/func_literal/func_literal.gs.ts +15 -0
- package/compliance/tests/function_call_result_assignment/expected.log +2 -0
- package/compliance/tests/function_call_result_assignment/function_call_result_assignment.go +24 -0
- package/compliance/tests/function_call_result_assignment/function_call_result_assignment.gs.ts +31 -0
- package/compliance/tests/if_statement/expected.log +1 -0
- package/compliance/tests/if_statement/if_statement.go +11 -0
- package/compliance/tests/if_statement/if_statement.gs.ts +15 -0
- package/compliance/tests/interface_to_interface_type_assertion/expected.log +1 -0
- package/compliance/tests/interface_to_interface_type_assertion/interface_to_interface_type_assertion.go +30 -0
- package/compliance/tests/interface_to_interface_type_assertion/interface_to_interface_type_assertion.gs.ts +41 -0
- package/compliance/tests/interface_type_assertion/expected.log +1 -0
- package/compliance/tests/interface_type_assertion/interface_type_assertion.go +26 -0
- package/compliance/tests/interface_type_assertion/interface_type_assertion.gs.ts +36 -0
- package/compliance/tests/map_support/expected.log +13 -0
- package/compliance/tests/map_support/map_support.go +89 -0
- package/compliance/tests/map_support/map_support.gs.ts +102 -0
- package/compliance/tests/method_call_on_pointer_receiver/expected.log +1 -0
- package/compliance/tests/method_call_on_pointer_receiver/method_call_on_pointer_receiver.go +19 -0
- package/compliance/tests/method_call_on_pointer_receiver/method_call_on_pointer_receiver.gs.ts +27 -0
- package/compliance/tests/method_call_on_pointer_via_value/expected.log +1 -0
- package/compliance/tests/method_call_on_pointer_via_value/method_call_on_pointer_via_value.go +29 -0
- package/compliance/tests/method_call_on_pointer_via_value/method_call_on_pointer_via_value.gs.ts +38 -0
- package/compliance/tests/method_call_on_value_receiver/expected.log +1 -0
- package/compliance/tests/method_call_on_value_receiver/method_call_on_value_receiver.go +16 -0
- package/compliance/tests/method_call_on_value_receiver/method_call_on_value_receiver.gs.ts +24 -0
- package/compliance/tests/method_call_on_value_via_pointer/expected.log +2 -0
- package/compliance/tests/method_call_on_value_via_pointer/method_call_on_value_via_pointer.go +30 -0
- package/compliance/tests/method_call_on_value_via_pointer/method_call_on_value_via_pointer.gs.ts +38 -0
- package/compliance/tests/multiple_return_values/expected.log +6 -0
- package/compliance/tests/multiple_return_values/multiple_return_values.go +19 -0
- package/compliance/tests/multiple_return_values/multiple_return_values.gs.ts +23 -0
- package/compliance/tests/pointer_assignment_no_copy/expected.log +2 -0
- package/compliance/tests/pointer_assignment_no_copy/pointer_assignment_no_copy.go +28 -0
- package/compliance/tests/pointer_assignment_no_copy/pointer_assignment_no_copy.gs.ts +35 -0
- package/compliance/tests/pointer_composite_literal_assignment/expected.log +3 -0
- package/compliance/tests/pointer_composite_literal_assignment/pointer_composite_literal_assignment.go +23 -0
- package/compliance/tests/pointer_composite_literal_assignment/pointer_composite_literal_assignment.gs.ts +30 -0
- package/compliance/tests/pointer_deref_multiassign/expected.log +0 -0
- package/compliance/tests/pointer_deref_multiassign/pointer_deref_multiassign.go +17 -0
- package/compliance/tests/pointer_deref_multiassign/pointer_deref_multiassign.gs.ts +27 -0
- package/compliance/tests/pointer_initialization/expected.log +1 -0
- package/compliance/tests/pointer_initialization/pointer_initialization.go +16 -0
- package/compliance/tests/pointer_initialization/pointer_initialization.gs.ts +22 -0
- package/compliance/tests/select_receive_on_closed_channel_no_default/expected.log +1 -0
- package/compliance/tests/select_receive_on_closed_channel_no_default/select_receive_on_closed_channel_no_default.go +15 -0
- package/compliance/tests/select_receive_on_closed_channel_no_default/select_receive_on_closed_channel_no_default.gs.ts +31 -0
- package/compliance/tests/select_send_on_full_buffered_channel_with_default/expected.log +1 -0
- package/compliance/tests/select_send_on_full_buffered_channel_with_default/select_send_on_full_buffered_channel_with_default.go +13 -0
- package/compliance/tests/select_send_on_full_buffered_channel_with_default/select_send_on_full_buffered_channel_with_default.gs.ts +35 -0
- package/compliance/tests/select_statement/expected.log +9 -0
- package/compliance/tests/select_statement/select_statement.go +109 -0
- package/compliance/tests/select_statement/select_statement.gs.ts +239 -0
- package/compliance/tests/simple/expected.log +1 -0
- package/compliance/tests/simple/simple.go +5 -0
- package/compliance/tests/simple/simple.gs.ts +9 -0
- package/compliance/tests/simple_deref_assignment/expected.log +2 -0
- package/compliance/tests/simple_deref_assignment/simple_deref_assignment.go +19 -0
- package/compliance/tests/simple_deref_assignment/simple_deref_assignment.gs.ts +26 -0
- package/compliance/tests/slices/expected.log +7 -0
- package/compliance/tests/slices/slices.go +22 -0
- package/compliance/tests/slices/slices.gs.ts +26 -0
- package/compliance/tests/string_rune_conversion/expected.log +3 -0
- package/compliance/tests/string_rune_conversion/string_rune_conversion.go +16 -0
- package/compliance/tests/string_rune_conversion/string_rune_conversion.gs.ts +22 -0
- package/compliance/tests/struct_field_access/expected.log +2 -0
- package/compliance/tests/struct_field_access/struct_field_access.go +13 -0
- package/compliance/tests/struct_field_access/struct_field_access.gs.ts +20 -0
- package/compliance/tests/struct_value_init_clone/expected.log +5 -0
- package/compliance/tests/struct_value_init_clone/struct_value_init_clone.go +28 -0
- package/compliance/tests/struct_value_init_clone/struct_value_init_clone.gs.ts +35 -0
- package/compliance/tests/switch_statement/expected.log +14 -0
- package/compliance/tests/switch_statement/switch_statement.go +59 -0
- package/compliance/tests/switch_statement/switch_statement.gs.ts +85 -0
- package/compliance/tests/value_type_copy_behavior/expected.log +3 -0
- package/compliance/tests/value_type_copy_behavior/value_type_copy_behavior.go +25 -0
- package/compliance/tests/value_type_copy_behavior/value_type_copy_behavior.gs.ts +34 -0
- package/design/DESIGN.md +599 -0
- package/example/simple/build.bash +10 -0
- package/example/simple/go.mod +23 -0
- package/example/simple/go.sum +39 -0
- package/example/simple/main.go +138 -0
- package/example/simple/main.gs.ts +133 -0
- package/example/simple/main.ts +3 -0
- package/example/simple/main_test.go +59 -0
- package/example/simple/main_tools.go +5 -0
- package/example/simple/package.json +7 -0
- package/example/simple/run.bash +6 -0
- package/example/simple/tsconfig.json +28 -0
- package/example/simple/yarn.lock +8 -0
- package/go.mod +22 -0
- package/go.sum +39 -0
- package/output/output.go +10 -0
- package/package.json +14 -0
- package/tsconfig.json +10 -0
- package/types/tokens.go +65 -0
- package/types/types.go +46 -0
package/.aider-prompt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
The GoScript compiler needs to correctly handle the compilation of Go function literals (`ast.FuncLit`) into TypeScript.
|
|
2
|
+
|
|
3
|
+
There are two related failing compliance tests:
|
|
4
|
+
1. `compliance/tests/channel_basic/channel_basic.go`: This test uses a function literal within a `go func() { ... }()` statement. The compiler currently fails to compile the function literal in this context, resulting in a TypeScript syntax error. The desired output for the goroutine part is `queueMicrotask(() => { ... compiled function literal body ... })`.
|
|
5
|
+
2. `compliance/tests/func_literal/func_literal.go`: This is a new test specifically for basic function literal usage (assigning a function literal to a variable and calling it). This test is also expected to fail because the compiler does not yet have full support for compiling function literals.
|
|
6
|
+
|
|
7
|
+
The issue is considered architectural because it involves the fundamental translation of Go's function literal construct to TypeScript, which impacts how goroutines and potentially other features (like closures) will be handled.
|
|
8
|
+
|
|
9
|
+
Please analyze the provided files, including `design/DESIGN.md`, and suggest the necessary changes to the compiler, primarily in `compiler/compile_expr.go` (where expressions are compiled) and potentially `compiler/compile_stmt.go` (where statements like `go` are handled), to correctly compile `ast.FuncLit` in these contexts.
|
|
10
|
+
|
|
11
|
+
The compilation of a function literal should produce a TypeScript arrow function or equivalent, ensuring that the body of the function literal is also correctly compiled.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-2024 Christian Stewart
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# GoScript
|
|
2
|
+
|
|
3
|
+
[![GoDoc Widget]][GoDoc] [![Go Report Card Widget]][Go Report Card]
|
|
4
|
+
|
|
5
|
+
[GoDoc]: https://godoc.org/github.com/paralin/goscript
|
|
6
|
+
[GoDoc Widget]: https://godoc.org/github.com/paralin/goscript?status.svg
|
|
7
|
+
[Go Report Card Widget]: https://goreportcard.com/badge/github.com/paralin/goscript
|
|
8
|
+
[Go Report Card]: https://goreportcard.com/report/github.com/paralin/goscript
|
|
9
|
+
|
|
10
|
+
## Introduction
|
|
11
|
+
|
|
12
|
+
GoScript is a Go to TypeScript compiler / translater.
|
|
13
|
+
|
|
14
|
+
It works on translating Go to TypeScript on the AST level.
|
|
15
|
+
|
|
16
|
+
For detailed information on the compiler's design, refer to the [design document](./design/DESIGN.md).
|
|
17
|
+
|
|
18
|
+
GoScript intends to compile a subset of the Go language to TypeScript in a
|
|
19
|
+
non-spec-compliant way. It is intended only for bringing over high-level logic
|
|
20
|
+
from Go to TypeScript, so not all programs will work correctly:
|
|
21
|
+
|
|
22
|
+
- Numbers (ints) use the "number" type in JavaScript is different than Go int32.
|
|
23
|
+
- Pointer arithmetic (uintptr) and unsafe are not supported
|
|
24
|
+
- Reflection is not supported
|
|
25
|
+
- Complex numbers are not supported
|
|
26
|
+
|
|
27
|
+
If you are OK with these limitations, GoScript is for you!
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Command Line
|
|
32
|
+
|
|
33
|
+
Compile a package using the CLI tool:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
goscript compile \
|
|
37
|
+
--package "my/package" \
|
|
38
|
+
--output ./output
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For example, to compile the simple example:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cd example/simple
|
|
45
|
+
go run ../../cmd/goscript compile --package . --output ./output
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### As a Library
|
|
49
|
+
|
|
50
|
+
You can also use the compiler directly within your Go code. Here's a basic example:
|
|
51
|
+
|
|
52
|
+
```go
|
|
53
|
+
package main
|
|
54
|
+
|
|
55
|
+
import (
|
|
56
|
+
"context"
|
|
57
|
+
"log"
|
|
58
|
+
|
|
59
|
+
"github.com/paralin/goscript/compiler"
|
|
60
|
+
"github.com/sirupsen/logrus"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
func main() {
|
|
64
|
+
// Initialize logger (optional)
|
|
65
|
+
logger := logrus.New()
|
|
66
|
+
logger.SetLevel(logrus.DebugLevel) // Adjust log level as needed
|
|
67
|
+
le := logrus.NewEntry(logger)
|
|
68
|
+
|
|
69
|
+
// Configure the compiler
|
|
70
|
+
conf := &compiler.Config{
|
|
71
|
+
OutputPathRoot: "./ts_output", // Directory for generated TypeScript files
|
|
72
|
+
}
|
|
73
|
+
if err := conf.Validate(); err != nil {
|
|
74
|
+
log.Fatalf("invalid compiler config: %v", err)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Create a new compiler instance
|
|
78
|
+
comp, err := compiler.NewCompiler(conf, le, nil) // Pass nil for default package loading options
|
|
79
|
+
if err != nil {
|
|
80
|
+
log.Fatalf("failed to create compiler: %v", err)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Compile the desired Go package(s)
|
|
84
|
+
// Replace "." with the specific Go import path of the package you want to compile
|
|
85
|
+
if err := comp.CompilePackages(context.Background(), "your/go/package/path"); err != nil {
|
|
86
|
+
log.Fatalf("compilation failed: %v", err)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
log.Println("Compilation successful!")
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This example initializes the compiler, creates a compiler instance, and then calls `CompilePackages` to translate the specified Go package into TypeScript files in the output directory.
|
|
95
|
+
|
|
96
|
+
## Roadmap
|
|
97
|
+
|
|
98
|
+
Check [the compliance tests](./compliance/COMPLIANCE.md) for implementation progress.
|
|
99
|
+
|
|
100
|
+
- [X] Simple programs compile & run
|
|
101
|
+
- [ ] Compliance for basic language features complete
|
|
102
|
+
- [ ] Function coloring and async logic
|
|
103
|
+
- [ ] Work our way up to more complex programs
|
|
104
|
+
- [ ] Generate init() function to recursively initialize packages
|
|
105
|
+
- [ ] Tooling to integrate with typescript compiler
|
|
106
|
+
- [ ] "go test" implementation with Go -> Ts transformation
|
|
107
|
+
- vitest
|
|
108
|
+
- [ ] performance testing
|
|
109
|
+
- [ ] examples of calling Go code from TypeScript
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## Generated Code
|
|
113
|
+
|
|
114
|
+
Below is a simple example of how code is generated:
|
|
115
|
+
|
|
116
|
+
```go
|
|
117
|
+
package main
|
|
118
|
+
|
|
119
|
+
// MyStruct demonstrates a simple struct with public and private fields.
|
|
120
|
+
// It will be converted into a TypeScript class by goscript.
|
|
121
|
+
type MyStruct struct {
|
|
122
|
+
// MyInt is a public integer field, initialized to zero.
|
|
123
|
+
MyInt int
|
|
124
|
+
// MyString is a public string field, initialized to empty string.
|
|
125
|
+
MyString string
|
|
126
|
+
// myBool is a private boolean field, initialized to false.
|
|
127
|
+
myBool bool
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// GetMyString returns the MyString field.
|
|
131
|
+
func (m *MyStruct) GetMyString() string {
|
|
132
|
+
return m.MyString
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// GetMyBool returns the myBool field.
|
|
136
|
+
func (m *MyStruct) GetMyBool() bool {
|
|
137
|
+
return m.myBool
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// NewMyStruct creates a new MyStruct instance.
|
|
141
|
+
func NewMyStruct(s string) MyStruct {
|
|
142
|
+
return MyStruct{MyString: s}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
func vals() (int, int) {
|
|
146
|
+
return 1, 2
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
func main() {
|
|
150
|
+
println("Hello from GoScript example!")
|
|
151
|
+
|
|
152
|
+
// Basic arithmetic
|
|
153
|
+
a, b := 10, 3
|
|
154
|
+
println("Addition:", a+b, "Subtraction:", a-b, "Multiplication:", a*b, "Division:", a/b, "Modulo:", a%b)
|
|
155
|
+
|
|
156
|
+
// Boolean logic and comparisons
|
|
157
|
+
println("Logic &&:", true && false, "||:", true || false, "!:!", !true)
|
|
158
|
+
println("Comparisons:", a == b, a != b, a < b, a > b, a <= b, a >= b)
|
|
159
|
+
|
|
160
|
+
// string(rune) conversion
|
|
161
|
+
var r rune = 'X'
|
|
162
|
+
s := string(r)
|
|
163
|
+
println("string('X'):", s)
|
|
164
|
+
|
|
165
|
+
var r2 rune = 121 // 'y'
|
|
166
|
+
s2 := string(r2)
|
|
167
|
+
println("string(121):", s2)
|
|
168
|
+
|
|
169
|
+
var r3 rune = 0x221A // '√'
|
|
170
|
+
s3 := string(r3)
|
|
171
|
+
println("string(0x221A):", s3)
|
|
172
|
+
|
|
173
|
+
// Arrays
|
|
174
|
+
arr := [3]int{1, 2, 3}
|
|
175
|
+
println("Array elements:", arr[0], arr[1], arr[2])
|
|
176
|
+
|
|
177
|
+
// Slices and range loop
|
|
178
|
+
slice := []int{4, 5, 6}
|
|
179
|
+
println("Slice elements:", slice[0], slice[1], slice[2])
|
|
180
|
+
sum := 0
|
|
181
|
+
for idx, val := range slice {
|
|
182
|
+
sum += val
|
|
183
|
+
println("Range idx:", idx, "val:", val)
|
|
184
|
+
}
|
|
185
|
+
println("Range sum:", sum)
|
|
186
|
+
|
|
187
|
+
// Basic for loop
|
|
188
|
+
prod := 1
|
|
189
|
+
for i := 1; i <= 3; i++ {
|
|
190
|
+
prod *= i
|
|
191
|
+
}
|
|
192
|
+
println("Product via for:", prod)
|
|
193
|
+
|
|
194
|
+
// Struct, pointers, copy independence
|
|
195
|
+
instance := NewMyStruct("go-script")
|
|
196
|
+
println("instance.MyString:", instance.GetMyString())
|
|
197
|
+
instance.MyInt = 42
|
|
198
|
+
copyInst := instance
|
|
199
|
+
copyInst.MyInt = 7
|
|
200
|
+
println("instance.MyInt:", instance.MyInt, "copyInst.MyInt:", copyInst.MyInt)
|
|
201
|
+
|
|
202
|
+
// Pointer initialization and dereference assignment
|
|
203
|
+
ptr := new(MyStruct)
|
|
204
|
+
ptr.MyInt = 9
|
|
205
|
+
println("ptr.MyInt:", ptr.MyInt)
|
|
206
|
+
deref := *ptr
|
|
207
|
+
deref.MyInt = 8
|
|
208
|
+
println("After deref assign, ptr.MyInt:", ptr.MyInt, "deref.MyInt:", deref.MyInt)
|
|
209
|
+
|
|
210
|
+
// Method calls on pointer receiver
|
|
211
|
+
ptr.myBool = true
|
|
212
|
+
println("ptr.GetMyBool():", ptr.GetMyBool())
|
|
213
|
+
|
|
214
|
+
// Composite literal assignment
|
|
215
|
+
comp := MyStruct{MyInt: 100, MyString: "composite", myBool: false}
|
|
216
|
+
println("comp fields:", comp.MyInt, comp.GetMyString(), comp.GetMyBool())
|
|
217
|
+
|
|
218
|
+
// Multiple return values and blank identifier
|
|
219
|
+
x, _ := vals()
|
|
220
|
+
_, y := vals()
|
|
221
|
+
println("vals x:", x, "y:", y)
|
|
222
|
+
|
|
223
|
+
// If/else
|
|
224
|
+
if a > b {
|
|
225
|
+
println("If branch: a>b")
|
|
226
|
+
} else {
|
|
227
|
+
println("Else branch: a<=b")
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Switch statement
|
|
231
|
+
switch a {
|
|
232
|
+
case 10:
|
|
233
|
+
println("Switch case 10")
|
|
234
|
+
default:
|
|
235
|
+
println("Switch default")
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Goroutines and Channels
|
|
239
|
+
println("\nGoroutines and Channels:")
|
|
240
|
+
ch := make(chan string)
|
|
241
|
+
go func() {
|
|
242
|
+
println("Goroutine: Sending message")
|
|
243
|
+
ch <- "Hello from goroutine!"
|
|
244
|
+
}()
|
|
245
|
+
msg := <-ch
|
|
246
|
+
println("Main goroutine: Received message:", msg)
|
|
247
|
+
|
|
248
|
+
// Function Literals
|
|
249
|
+
println("\nFunction Literals:")
|
|
250
|
+
add := func(x, y int) int {
|
|
251
|
+
return x + y
|
|
252
|
+
}
|
|
253
|
+
sum = add(5, 7)
|
|
254
|
+
println("Function literal result:", sum)
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Generated with `goscript compile .`:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import * as goscript from "@go/builtin"
|
|
262
|
+
|
|
263
|
+
class MyStruct {
|
|
264
|
+
// MyInt is a public integer field, initialized to zero.
|
|
265
|
+
public MyInt: number = 0
|
|
266
|
+
// MyString is a public string field, initialized to empty string.
|
|
267
|
+
public MyString: string = ""
|
|
268
|
+
// myBool is a private boolean field, initialized to false.
|
|
269
|
+
private myBool: boolean = false
|
|
270
|
+
|
|
271
|
+
// GetMyString returns the MyString field.
|
|
272
|
+
public GetMyString(): string {
|
|
273
|
+
const m = this
|
|
274
|
+
return m.MyString
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// GetMyBool returns the myBool field.
|
|
278
|
+
public GetMyBool(): boolean {
|
|
279
|
+
const m = this
|
|
280
|
+
return m.myBool
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
constructor(init?: Partial<MyStruct>) { if (init) Object.assign(this, init as any) }
|
|
284
|
+
public clone(): MyStruct { return Object.assign(Object.create(MyStruct.prototype) as MyStruct, this) }
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// NewMyStruct creates a new MyStruct instance.
|
|
288
|
+
export function NewMyStruct(s: string): MyStruct {
|
|
289
|
+
return new MyStruct({ MyString: s })
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function vals(): [number, number] {
|
|
293
|
+
return [1, 2]
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export async function main(): Promise<void> {
|
|
297
|
+
console.log("Hello from GoScript example!")
|
|
298
|
+
|
|
299
|
+
// Basic arithmetic
|
|
300
|
+
let a = 10
|
|
301
|
+
let b = 3
|
|
302
|
+
console.log("Addition:", a + b, "Subtraction:", a - b, "Multiplication:", a * b, "Division:", a / b, "Modulo:", a % b)
|
|
303
|
+
|
|
304
|
+
// Boolean logic and comparisons
|
|
305
|
+
console.log("Logic &&:", true && false, "||:", true || false, "!:!", !true)
|
|
306
|
+
console.log("Comparisons:", a == b, a != b, a < b, a > b, a <= b, a >= b)
|
|
307
|
+
|
|
308
|
+
// string(rune) conversion
|
|
309
|
+
let r: number = 'X'
|
|
310
|
+
let s = String.fromCharCode(r)
|
|
311
|
+
console.log("string('X'):", s)
|
|
312
|
+
|
|
313
|
+
// 'y'
|
|
314
|
+
let r2: number = 121
|
|
315
|
+
let s2 = String.fromCharCode(r2)
|
|
316
|
+
console.log("string(121):", s2)
|
|
317
|
+
|
|
318
|
+
// '√'
|
|
319
|
+
let r3: number = 0x221A
|
|
320
|
+
let s3 = String.fromCharCode(r3)
|
|
321
|
+
console.log("string(0x221A):", s3)
|
|
322
|
+
|
|
323
|
+
// Arrays
|
|
324
|
+
let arr = [1, 2, 3]
|
|
325
|
+
console.log("Array elements:", arr[0], arr[1], arr[2])
|
|
326
|
+
|
|
327
|
+
// Slices and range loop
|
|
328
|
+
let slice = [4, 5, 6]
|
|
329
|
+
console.log("Slice elements:", slice[0], slice[1], slice[2])
|
|
330
|
+
let sum = 0
|
|
331
|
+
for (let idx = 0; idx < slice.length; idx++) {
|
|
332
|
+
const val = slice[idx]
|
|
333
|
+
{
|
|
334
|
+
sum += val
|
|
335
|
+
console.log("Range idx:", idx, "val:", val)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
console.log("Range sum:", sum)
|
|
339
|
+
|
|
340
|
+
// Basic for loop
|
|
341
|
+
let prod = 1
|
|
342
|
+
for (let i = 1; i <= 3; i++) {
|
|
343
|
+
prod *= i
|
|
344
|
+
}
|
|
345
|
+
console.log("Product via for:", prod)
|
|
346
|
+
|
|
347
|
+
// Struct, pointers, copy independence
|
|
348
|
+
let instance = NewMyStruct("go-script").clone()
|
|
349
|
+
console.log("instance.MyString:", instance.GetMyString())
|
|
350
|
+
instance.MyInt = 42
|
|
351
|
+
let copyInst = instance.clone()
|
|
352
|
+
copyInst.MyInt = 7
|
|
353
|
+
console.log("instance.MyInt:", instance.MyInt, "copyInst.MyInt:", copyInst.MyInt)
|
|
354
|
+
|
|
355
|
+
// Pointer initialization and dereference assignment
|
|
356
|
+
let ptr = new MyStruct()
|
|
357
|
+
ptr.MyInt = 9
|
|
358
|
+
console.log("ptr.MyInt:", ptr.MyInt)
|
|
359
|
+
let deref = ptr.clone()
|
|
360
|
+
deref.MyInt = 8
|
|
361
|
+
console.log("After deref assign, ptr.MyInt:", ptr.MyInt, "deref.MyInt:", deref.MyInt)
|
|
362
|
+
|
|
363
|
+
// Method calls on pointer receiver
|
|
364
|
+
ptr.myBool = true
|
|
365
|
+
console.log("ptr.GetMyBool():", ptr.GetMyBool())
|
|
366
|
+
|
|
367
|
+
// Composite literal assignment
|
|
368
|
+
let comp = new MyStruct({ MyInt: 100, MyString: "composite", myBool: false }).clone()
|
|
369
|
+
console.log("comp fields:", comp.MyInt, comp.GetMyString(), comp.GetMyBool())
|
|
370
|
+
|
|
371
|
+
// Multiple return values and blank identifier
|
|
372
|
+
let [x, ] = vals()
|
|
373
|
+
let [, y] = vals()
|
|
374
|
+
console.log("vals x:", x, "y:", y)
|
|
375
|
+
|
|
376
|
+
// If/else
|
|
377
|
+
if (a > b) {
|
|
378
|
+
console.log("If branch: a>b")
|
|
379
|
+
} else {
|
|
380
|
+
console.log("Else branch: a<=b")
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Switch statement
|
|
384
|
+
switch (a) {
|
|
385
|
+
case 10:
|
|
386
|
+
console.log("Switch case 10")
|
|
387
|
+
break
|
|
388
|
+
default:
|
|
389
|
+
console.log("Switch default")
|
|
390
|
+
break
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Goroutines and Channels
|
|
394
|
+
console.log("\nGoroutines and Channels:")
|
|
395
|
+
let ch = goscript.makeChannel<string>(0)
|
|
396
|
+
queueMicrotask(async () => {
|
|
397
|
+
console.log("Goroutine: Sending message")
|
|
398
|
+
await ch.send("Hello from goroutine!")
|
|
399
|
+
})
|
|
400
|
+
let msg = await ch.receive()
|
|
401
|
+
console.log("Main goroutine: Received message:", msg)
|
|
402
|
+
|
|
403
|
+
// Function Literals
|
|
404
|
+
console.log("\nFunction Literals:")
|
|
405
|
+
let add = (x: number, y: number): number => {
|
|
406
|
+
return x + y
|
|
407
|
+
}
|
|
408
|
+
sum = add(5, 7)
|
|
409
|
+
console.log("Function literal result:", sum)
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Code is compiled with `GOARCH=js` and uses a 32-bit environment similar to wasm.
|
|
414
|
+
|
|
415
|
+
All Go import paths are prefixed with `@go/` and can be imported in TypeScript:
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
import { MyFunction, MyStruct } from '@go/github.com/myorg/mypackage';
|
|
419
|
+
|
|
420
|
+
MyFunction();
|
|
421
|
+
let myThing = new MyStruct();
|
|
422
|
+
myThing.DoSometing();
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## License
|
|
426
|
+
|
|
427
|
+
MIT
|