Created
August 25, 2022 07:33
-
-
Save kemingy/7c3f6f5ab67af961552622576c6d3ac1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"sync" | |
"go.starlark.net/starlark" | |
"go.starlark.net/starlarkstruct" | |
) | |
var fakeFilesystem = map[string]string { | |
"x.star": `y = use("y"); y.foo()`, | |
"y.star": ` | |
name = "starlark" | |
# print(name) | |
def foo(): | |
print(name) | |
`, | |
} | |
type entry struct { | |
globals starlark.StringDict | |
err error | |
} | |
type Interpreter struct { | |
predeclared starlark.StringDict | |
context string | |
cache map[string]*entry | |
} | |
var interpreter *Interpreter | |
var once sync.Once | |
var import_keyword = "use" | |
func GetInterpreter() *Interpreter { | |
once.Do(func() { | |
interpreter = &Interpreter{ | |
predeclared: starlark.StringDict{}, | |
cache: make(map[string]*entry), | |
context: "test", | |
} | |
}) | |
return interpreter | |
} | |
func (it *Interpreter) load(thread *starlark.Thread, module string) (starlark.StringDict, error) { | |
return it.execModule(thread, module) | |
} | |
func (it *Interpreter) execModule(thread *starlark.Thread, module string) (starlark.StringDict, error) { | |
e, ok := it.cache[module] | |
if e != nil { | |
return e.globals, e.err | |
} | |
if ok { | |
return nil, fmt.Errorf("[x] cycle") | |
} | |
it.cache[module] = nil | |
data := fakeFilesystem[module] | |
fmt.Printf("@ before exec %s: %s\n", module, it.predeclared) | |
globals, err := starlark.ExecFile(thread, module, data, it.predeclared) | |
fmt.Printf("> after exec %s: %s\n%s\n", module, globals, it.predeclared) | |
e = &entry{globals, err} | |
return globals, err | |
} | |
func (it *Interpreter) newThread(name string) *starlark.Thread { | |
thread := &starlark.Thread{ | |
Name: name, | |
Load: it.load, | |
} | |
return thread | |
} | |
func (it *Interpreter) Exec(filename string) (starlark.StringDict, error) { | |
thread := it.newThread(filename) | |
return it.execModule(thread, filename) | |
} | |
func main() { | |
it := GetInterpreter() | |
starlark.Universe[import_keyword] = starlark.NewBuiltin(import_keyword, func(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { | |
var file string | |
if err := starlark.UnpackArgs(import_keyword, args, kwargs, "file?", &file); err != nil { | |
return nil, err | |
} | |
filename := file + ".star" | |
globals, err := thread.Load(thread, filename) | |
if err != nil { | |
return nil, err | |
} | |
module := &starlarkstruct.Module { | |
Name: file, | |
Members: globals, | |
} | |
return module, err | |
}) | |
globals, err := it.Exec("x.star") | |
if err != nil { | |
fmt.Printf("exec error: %v\n", err) | |
return | |
} | |
fmt.Printf(">> %s\n", globals.String()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment