-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstarlark.go
94 lines (80 loc) · 1.95 KB
/
starlark.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
/*
#include <stdlib.h>
*/
import "C"
import (
"encoding/json"
"fmt"
"math/rand"
"unsafe"
"go.starlark.net/starlark"
)
var THREADS = map[uint64]*starlark.Thread{}
var GLOBALS = map[uint64]starlark.StringDict{}
//export NewThread
func NewThread() C.ulong {
threadId := rand.Uint64()
thread := &starlark.Thread{}
THREADS[threadId] = thread
GLOBALS[threadId] = starlark.StringDict{}
return C.ulong(threadId)
}
//export DestroyThread
func DestroyThread(threadId C.ulong) {
goThreadId := uint64(threadId)
delete(THREADS, goThreadId)
delete(GLOBALS, goThreadId)
}
//export Eval
func Eval(threadId C.ulong, stmt *C.char) *C.char {
// Cast *char to string
goStmt := C.GoString(stmt)
goThreadId := uint64(threadId)
thread := THREADS[goThreadId]
globals := GLOBALS[goThreadId]
result, err := starlark.Eval(thread, "<expr>", goStmt, globals)
if err != nil {
fmt.Printf("%v\n", err)
panic(err)
}
// Convert starlark.Value struct into a JSON blob
rawResponse := make(map[string]string)
rawResponse["value"] = result.String()
rawResponse["type"] = result.Type()
response, _ := json.Marshal(rawResponse)
// Convert JSON blob to string and then CString
return C.CString(string(response))
}
//export ExecFile
func ExecFile(threadId C.ulong, data *C.char) {
// Cast *char to string
goData := C.GoString(data)
goThreadId := uint64(threadId)
thread := THREADS[goThreadId]
globals, err := starlark.ExecFile(thread, "main.star", goData, starlark.StringDict{})
if err != nil {
fmt.Printf("%v\n", err)
panic(err)
}
GLOBALS[goThreadId] = globals
return
}
//export FreeCString
func FreeCString(s *C.char) {
C.free(unsafe.Pointer(s))
}
func main() {
const data = `
def fibonacci(n=10):
res = list(range(n))
for i in res[2:]:
res[i] = res[i-2] + res[i-1]
return res
`
threadId := NewThread()
ExecFile(threadId, C.CString(data))
r := Eval(threadId, C.CString("fibonacci(25)"))
fmt.Printf("%v\n", C.GoString(r))
DestroyThread(threadId)
}