//---------------------------------------------------------- funcs need be pushed in func _push_funcs(conn net.Conn, L *lua.State) { luar.Register(L, "", luar.Map{ "conn": conn, "Print": Print, }) luar.Register(L, "gsdb", luar.Map{ "ListAll": gsdb.ListAll, "QueryOnline": gsdb.QueryOnline, }) }
func (script *Script) seed() { luar.Register(script.L, "uuid", luar.Map{ "new": uuid.New, }) luar.Register(script.L, "web", luar.Map{ "get": http.Get, "post": http.Post, }) luar.Register(script.L, "ioutil", luar.Map{ "readall": ioutil.ReadAll, "byte2string": byteSliceToString, }) luar.Register(script.L, "crypto", luar.Map{ "hash": crypto.Hash, "fnv": crypto.Fnv, }) luar.Register(script.L, "strings", luar.Map{ "join": strings.Join, "split": strings.Split, "first": func(str string) string { if len(str) > 0 { return string(str[0]) } else { return "" } }, "rest": func(str string) string { if len(str) > 0 { return str[1:] } else { return "" } }, "format": func(format string, args ...interface{}) string { return fmt.Sprintf(format, args...) }, "scan": fmt.Sscanf, "shuck": func(victim string) string { return victim[1 : len(victim)-1] }, "hassuffix": func(s, pattern string) bool { return strings.HasSuffix(s, pattern) }, }) }
func ExampleMap() { const code = ` print(#M) print(M.one) print(M.two) print(M.three) ` L := luar.Init() defer L.Close() M := luar.Map{ "one": "ein", "two": "zwei", "three": "drei", } luar.Register(L, "", luar.Map{ "M": M, "print": fmt.Println, }) err := L.DoString(code) if err != nil { fmt.Println("error", err.Error()) } // Output: // 3 // ein // zwei // drei }
func Example_pointers() { const test = ` -- Pointers to structs and structs within pointers are automatically dereferenced. local t = newRef() Print(t.Index, t.Number, t.Title) ` type Ref struct { Index int Number *int Title *string } newRef := func() *Ref { n := new(int) *n = 10 t := new(string) *t = "foo" return &Ref{Index: 17, Number: n, Title: t} } L := luar.Init() defer L.Close() luar.Register(L, "", luar.Map{ "Print": fmt.Println, "newRef": newRef, }) L.DoString(test) // Output: // 17 10 foo }
func (PM *PluginManager) initLua() { PM.L = luar.Init() luar.RawRegister(PM.L, "", luar.Map{ "RegisterCommand": func(L *lua.State) int { name := L.ToString(1) fn := luar.NewLuaObject(L, 2) PM.Commands[name] = Plugin{name, fn} log.Printf(" %-10s command\n", name) return 0 }, "RegisterEvent": func(L *lua.State) int { name := L.ToString(1) event := L.ToString(2) fn := luar.NewLuaObject(L, 3) if _, ok := PM.Events[event]; !ok { PM.Events[event] = make(map[string]Plugin) } PM.Events[event][name] = Plugin{name, fn} log.Printf(" %-10s event\n", name) return 0 }, }) luar.Register(PM.L, "go", luar.Map{ "Split": strings.Split, "SplitN": strings.SplitN, "PrintTable": func(table interface{}) { log.Printf("%#v\n", table) }, }) }
func loadMoonScript(script *Script) (*Script, error) { contents, failed := ioutil.ReadFile("modules/" + script.Name + ".moon") if failed != nil { return script, errors.New("Could not read " + script.Name + ".moon") } luar.Register(script.L, "", luar.Map{ "moonscript_code_from_file": string(contents), }) /* moonscript = require "moonscript" xpcall = unsafe_xpcall pcall = unsafe_pcall local func, err = moonscript.loadstring(moonscript_code_from_file) if err ~= nil then tetra.log.Printf("Moonscript error, %#v", err) error(err) end func() */ err := script.L.DoString(`moonscript = require "moonscript" xpcall = unsafe_xpcall pcall = unsafe_pcall local func, err = moonscript.loadstring(moonscript_code_from_file) if err ~= nil then tetra.log.Printf("Moonscript error, %#v", err) error(err) end func()`) if err != nil { script.Log.Print(err) return nil, err } script.Kind = "moonscript" return script, nil }
func main() { L := luar.Init() defer L.Close() // arbitrary Go functions can be registered // to be callable from Lua luar.Register(L, "", luar.Map{ "GoFun": GoFun, }) res := L.DoString(code) if !res { fmt.Println("Error:", L.ToString(-1)) os.Exit(1) } res = L.DoString(setup) if !res { fmt.Println("Error:", L.ToString(-1)) os.Exit(1) } else { // there will be a table on the stack! fmt.Println("table?", L.IsTable(-1)) v := luar.CopyTableToMap(L, nil, -1) fmt.Println("returned map", v) m := v.(map[string]interface{}) for k, v := range m { fmt.Println(k, v) } } }
func main() { L := luar.Init() defer L.Close() M := luar.Map{ "one": "ein", "two": "zwei", "three": "drei", } S := []string{"alfred", "alice", "bob", "frodo"} ST := &MyStruct{"Dolly", 46} luar.Register(L, "", luar.Map{ "M": M, "S": S, "ST": ST, }) err := L.DoString(code) if err != nil { fmt.Println("error", err.Error()) } }
func init() { piepan.Register("lua", &piepan.Plugin{ Name: "Lua (C)", New: func(in *piepan.Instance) piepan.Environment { s := luar.Init() p := &Plugin{ instance: in, state: s, listeners: make(map[string][]*luar.LuaObject), } luar.Register(s, "piepan", luar.Map{ "On": p.apiOn, "Disconnect": p.apiDisconnect, }) s.GetGlobal("piepan") s.NewTable() luar.Register(s, "*", luar.Map{ "Play": p.apiAudioPlay, "IsPlaying": p.apiAudioIsPlaying, "Stop": p.apiAudioStop, "NewTarget": p.apiAudioNewTarget, "SetTarget": p.apiAudioSetTarget, "Bitrate": p.apiAudioBitrate, "SetBitrate": p.apiAudioSetBitrate, "Volume": p.apiAudioVolume, "SetVolume": p.apiAudioSetVolume, }) s.SetField(-2, "Audio") s.NewTable() luar.Register(s, "*", luar.Map{ "New": p.apiTimerNew, }) s.SetField(-2, "Timer") s.NewTable() luar.Register(s, "*", luar.Map{ "New": p.apiProcessNew, }) s.SetField(-2, "Process") s.SetTop(0) return p }, }) }
// mkstate constructs a new lua state with the appropriate functions binded // for use in scripts. // it also binds functions used for actions, which should probably go somewhere else. func mkstate() *lua.State { L := luar.Init() luar.Register(L, "", luar.Map{ "connect": lconnect, "http": lhttp, }) return L }
func (r Runtime) InitPlugin(name, source string, implements func(string)) error { context := luar.Init() luar.Register(context, "", luar.Map{ "implements": func(interfaceName string) { implements(interfaceName) }, }) context.DoString(source) r.plugins[name] = context return nil }
// TODO: move these bindings into another file func (gs *GameServer) BindLua() { luar.Register(gs.Lua, "", luar.Map{ "gs": gs, }) // add our script path here.. pkgpathscript := `package.path = package.path .. ";" .. gs.GetScriptPath() --";../?.lua"` if err := gs.Lua.DoString(pkgpathscript); err != nil { } Lua_OpenObjectLib(gs.Lua) }
func main() { whj := "wang::hai::jun" fmt.Println(strings.Split(whj, "::")) TestCall("111") L := luar.Init() defer L.Close() M := luar.Map{ "one": "ein", "two": "zwei", "three": "drei", } S := []string{"alfred", "alice", "bob", "frodo"} ST := &MyStruct{"Dolly", 46} luar.Register(L, "", luar.Map{ "Print": fmt.Println, "testcall": TestCall, "print": fmt.Println, "MSG": "hello", // can also register constants "M": M, "S": S, "ST": ST, }) //L.DoString(test) L.DoString(code) L.GetGlobal("print") print := luar.NewLuaObject(L, -1) print.Call("one two", 12) L.GetGlobal("package") pack := luar.NewLuaObject(L, -1) fmt.Println(pack.Get("path")) lcopy := luar.NewLuaObjectFromValue gsub := luar.NewLuaObjectFromName(L, "string.gsub") rmap := lcopy(L, luar.Map{ "NAME": "Dolly", "HOME": "where you belong", }) res, err := gsub.Call("hello $NAME go $HOME", "%$(%u+)", rmap) if res == nil { fmt.Println("error", err) } else { fmt.Println("\033[0;31mresult\033[0m", res) } }
func (c *Conf) registerCommands() { luar.Register(c.l, "", luar.Map{ "Directory": Directory, "File": File, "AptGet": AptGet, "HttpGet": HttpGet, "TarGz": TarGz, "UnTarGz": UnTarGz, "Cron": Cron, "Group": Group, }) }
func main() { L := luar.Init() defer L.Close() luar.Register(L, "", luar.Map{ "Print": fmt.Println, "MSG": "hello", // can also register constants }) L.DoString(test) }
func register() { // Go functions or values you want to use interactively! ST := &MyStruct{"Dolly", 46} S := MyStruct{"Joe", 32} luar.Register(L, "", luar.Map{ "regexp": regexp.Compile, "println": fmt.Println, "ST": ST, "S": S, "String": String, }) }
func main() { L := luar.Init() defer L.Close() luar.Register(L, "", luar.Map{ "newT": newT, }) res := L.DoString(setup) if res != nil { fmt.Println("Error:", res) } }
func main() { L := luar.Init() defer L.Close() // arbitrary Go functions can be registered // to be callable from Lua luar.Register(L, "", luar.Map{ "config": config, }) res := L.DoString(setup) if res != nil { fmt.Println("Error:", res) } }
func ExampleRegister_sandbox() { const code = ` Print("foo") Print(io ~= nil) Print(os == nil) ` L := luar.Init() defer L.Close() res := L.LoadString(code) if res != 0 { msg := L.ToString(-1) fmt.Println("could not compile", msg) } // Create a empty sandbox. L.NewTable() // "*" means "use table on top of the stack." luar.Register(L, "*", luar.Map{ "Print": fmt.Println, }) env := luar.NewLuaObject(L, -1) G := luar.Global(L) // We can copy any Lua object from "G" to env with 'Set', e.g.: // env.Set("print", G.Get("print")) // A more convenient and efficient way is to do a bulk copy with 'Setv': env.Setv(G, "print", "io") // Set up sandbox. L.SetfEnv(-2) // Run 'code' chunk. err := L.Call(0, 0) if err != nil { fmt.Println("could not run", err) } // Output: // foo // true // true }
func ExampleMakeChan() { L1 := luar.Init() defer L1.Close() L2 := luar.Init() defer L2.Close() luar.MakeChan(L1) L1.SetGlobal("c") L1.GetGlobal("c") c := luar.LuaToGo(L1, nil, -1) luar.Register(L2, "", luar.Map{ "c": c, "Print": fmt.Println, }) const code1 = ` c.send(17) ` const code2 = ` v = c.recv() Print(v) ` var wg sync.WaitGroup wg.Add(1) go func() { err := L1.DoString(code1) if err != nil { fmt.Println(err) } wg.Done() }() err := L2.DoString(code2) if err != nil { fmt.Println(err) } wg.Wait() // Output: // 17 }
// This example shows how Go slices and maps are marshalled to Lua tables and // vice versa. This requires the Lua state to be initialized with `luar.Init()`. // // An arbitrary Go function is callable from Lua, and list-like tables become // slices on the Go side. The Go function returns a map, which is wrapped as a // proxy object. You can however then copy this to a Lua table explicitly. There // is also `luar.unproxify` on the Lua side. func ExampleInit() { const code = ` -- Lua tables auto-convert to slices. local res = foo {10,20,30,40} -- The result is a map-proxy. print(res['1'], res['2']) -- Which we may explicitly convert to a table. res = luar.unproxify(res) for k,v in pairs(res) do print(k,v) end ` foo := func(args []int) (res map[string]int) { res = make(map[string]int) for i, val := range args { res[strconv.Itoa(i)] = val * val } return } L := luar.Init() defer L.Close() luar.Register(L, "", luar.Map{ "foo": foo, "print": fmt.Println, }) res := L.DoString(code) if res != nil { fmt.Println("Error:", res) } // Output: // 400 900 // 1 400 // 0 100 // 3 1600 // 2 900 }
func (p *Plugin) OnConnect(e *gumble.ConnectEvent) { luar.Register(p.state, "piepan", luar.Map{ "Self": e.Client.Self, "Users": e.Client.Users, "Channels": e.Client.Channels, }) event := ConnectEventWrapper{ Client: e.Client, } if e.WelcomeMessage != nil { event.WelcomeMessage = *e.WelcomeMessage } if e.MaximumBitrate != nil { event.MaximumBitrate = *e.MaximumBitrate } for _, listener := range p.listeners["connect"] { p.callValue(listener, event) } }
func main() { luaCode := ` for i = 1,10 do MyFunc(MSG,i) end ` L := luar.Init() defer L.Close() luar.Register(L, "", luar.Map{ //"MyFunc": fmt.Println, "MyFunc": MyFunc, "MSG": "Hello, Luar!", }) err := L.DoString(luaCode) if err != nil { panic(err) } }
func main() { L := luar.Init() defer L.Close() gettop := func() { fmt.Println("top", L.GetTop()) } gettop() // compile chunk res := L.LoadString(test) if res != 0 { msg := L.ToString(-1) fmt.Println("could not compile", msg) } // create environment for chunk L.NewTable() // "*" means use table on stack.... luar.Register(L, "*", luar.Map{ "Print": fmt.Println, }) env := luar.NewLuaObject(L, -1) G := luar.Global(L) //~ env.Set("print",G.Get("print")) //~ env.Set("io",G.Get("io")) // more convenient/efficient way to do a bulk copy env.Setv(G, "print", "io") L.SetfEnv(-2) // run chunk err := L.Call(0, 0) if err != nil { fmt.Println("could not run", err) } }
func main() { luaCode := ` print 'in the lua code' local res = GoFun {10, 20, 30, 40} print(res['1'], res['2']) res = luar.map2table(res) for k,v in pairs(res) do print(k,v) end ` L := luar.Init() defer L.Close() luar.Register(L, "", luar.Map{ "GoFun": GoFun, }) err := L.DoString(luaCode) if err != nil { panic(err) } }
func Example() { const test = ` for i = 1, 3 do Print(msg, i) end Print(user) Print(user.Name, user.Age) ` type person struct { Name string Age int } L := luar.Init() defer L.Close() user := &person{"Dolly", 46} luar.Register(L, "", luar.Map{ // Go functions may be registered directly. "Print": fmt.Println, // Constants can be registered. "msg": "foo", // And other values as well. "user": user, }) L.DoString(test) // Output: // foo 1 // foo 2 // foo 3 // &{Dolly 46} // Dolly 46 }
// Slices must be looped with 'ipairs'. func Example_slices() { const test = ` for i, v in ipairs(names) do Print(i, v) end ` L := luar.Init() defer L.Close() names := []string{"alfred", "alice", "bob", "frodo"} luar.Register(L, "", luar.Map{ "Print": fmt.Println, "names": names, }) L.DoString(test) // Output: // 1 alfred // 2 alice // 3 bob // 4 frodo }
func (luaipt *LuaIpt) Bind(name string, item interface{}) error { luar.Register(luaipt.state, module, luar.Map{ name: item, }) return nil }
func (script *Script) seed() { luar.Register(script.L, "", luar.Map{ "client": script.Client, "print": script.Log.Print, "script": script, "log": script.Log, "use": func(library string) bool { if funcs, ok := Libraries[library]; ok { luar.Register(script.L, library, funcs) return true } else { return false } }, }) luar.Register(script.L, "tetra", luar.Map{ "script": script, "log": script.Log, "Info": Info, "Clients": Clients, "Channels": Channels, "Bursted": Bursted, "Services": Services, "Config": ActiveConfig, "ActiveConfig": ActiveConfig, "Servers": Servers, "Log": script.Log, "Etcd": Etcd, "Atheme": Atheme, "RunHook": RunHook, "LoadScript": func(name string) (script *Script, err error) { return LoadScript(name) }, "UnloadScript": func(name string) error { return UnloadScript(name) }, "Scripts": Scripts, "GetYo": func(name string) (client *yo.Client, err error) { return GetYo(name) }, "protohook": script.AddLuaProtohook, "GC": runtime.GC, "debug": debug, "debugf": debugf, "atheme": Atheme, "Quit": Quit, }) luar.Register(script.L, "uuid", luar.Map{ "new": uuid.New, }) luar.Register(script.L, "web", luar.Map{ "get": http.Get, "post": http.Post, "encode": url.QueryEscape, "decode": url.QueryUnescape, }) luar.Register(script.L, "ioutil", luar.Map{ "readall": ioutil.ReadAll, "byte2string": byteSliceToString, }) //luar.Register(script.L, "strings", Libraries["strings"]) }
func main() { history := os.Getenv("HOME") + "/.luar_history" linenoise.LoadHistory(history) defer func() { L.Close() linenoise.SaveHistory(history) if x := recover(); x != nil { fmt.Println("runtime " + x.(error).Error()) } }() luar.Register(L, "", luar.Map{ "__DUMMY__": &Dummy{"me"}, }) // most of this program's code is Lua.... err := L.DoString(lua_code) if err != nil { fmt.Println("initial " + err.Error()) return } // particularly the completion logic complete := luar.NewLuaObjectFromName(L, "lua_candidates") // this function returns a string slice of candidates str_slice := luar.Types([]string{}) linenoise.SetCompletionHandler(func(in string) []string { val, err := complete.Callf(str_slice, in) if err != nil || len(val) == 1 && val[0] == nil { return []string{} } else { return val[0].([]string) } }) register() fmt.Println("luar 1.2 Copyright (C) 2013-2014 Steve Donovan") fmt.Println("Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio") prompt := LUA_PROMPT1 code := "" for { // ctrl-C/ctrl-D handling with latest update of go.linenoise str, err := linenoise.Line(prompt) if err != nil { return } if len(str) > 0 { if str == "exit" { return } linenoise.AddHistory(str) if str[0] == '=' || str[0] == '.' { exprs := str[1:] if str[0] == '=' { str = "pprint(" + exprs + ")" } else { str = "println(" + exprs + ")" } } continuing := false code = code + str //fmt.Println("'"+code+"'") err := L.DoString(code) if err != nil { errs := err.Error() // fmt.Println("err",errs) // strip line nonsense if error occurred on prompt idx := strings.Index(errs, ": ") if idx > -1 && strings.HasPrefix(errs, "[string ") { errs = errs[idx+2:] } // need to keep collecting line? if strings.HasSuffix(errs, "near '<eof>'") { continuing = true } else { fmt.Println(errs) } } if continuing { // prompt must reflect continuing state prompt = LUA_PROMPT2 code = code + "\n" } else { prompt = LUA_PROMPT1 code = "" } } else { fmt.Println("empty line. Use exit to get out") } } }