google / starlark-go

Starlark in Go: the Starlark configuration language, implemented in Go
BSD 3-Clause "New" or "Revised" License
2.34k stars 212 forks source link

Question: How to use globals/predeclared functions in load()'ed modules? #180

Closed dragonquest closed 5 years ago

dragonquest commented 5 years ago

Whenever I want to call a predeclared function in a load()'ed module I get "myFunctionName() not found". Example is:

prog1.txt

print("hello", "world") 
load("./include.txt", "printtest")
sayHello()
printtest()`

**include.txt**
`def printtest(dirName):
    sayHello("from include")

(NOTE: I fail to format it properly but include.txt is in a separate file)

output

hello world
Traceback (most recent call last):
  prog1.txt:2: in <toplevel>
Error: cannot load ./include.txt: ./include.txt:2:5: undefined: sayHello
exit status 1

main.go

func main() {
    thread := &starlark.Thread{Load: repl.MakeLoad()}
    globals := make(starlark.StringDict)
    globals["sayHello"] = starlark.NewBuiltin("sayHello", sayHello)

    filename := "prog1.txt"

    thread.Name = "exec " + filename
    globals, err := starlark.ExecFile(thread, filename, nil, globals)
    if err != nil {
        repl.PrintError(err)
        os.Exit(1)
    }
}

func sayHello(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
    if err := starlark.UnpackArgs("glob", args, kwargs); err != nil {
        return nil, err
    }

    fmt.Println("'Hello' from sayHello()")

    return starlark.Bool(true), nil
}

What am I doing wrong? Thank you very much.

alandonovan commented 5 years ago

I assume you've figured out the answer, but for the record, the implementation of load provided by repl.MakeLoad executes each loaded file in a "clean" environment that doesn't define sayHello. You can fork and modify MakeLoad to use whatever environment you like---perhaps the same environment that you use to execute the main script, prog1.txt.

I am intrigued by the string "glob" in your example. Are you by any chance building a tool to read Bazel BUILD files?

dragonquest commented 5 years ago

Hey @alandonovan Sort of, as a hobby project I want to see how much work it takes to implement the most simple functionatlities to have something which can build .NET projects from .csproj files. Generally I like bazel and it's syntax but I don't like java. Since bazel is mature and my tool won't be, I'm not sure if I will ever take it further. But starlark is awesome ;) Also, csproj contains all the needed .cs files so I find it kind of annoying to specify them again...