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 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 main() { lua := ` fn = function(obj) slice = obj.GetSlice() print(type(slice), #slice) obj = slice[1] -- slice[2] will raise a 'index out of range' error -- obj.Naam = 'howzit' -- will raise a 'no field' error name = obj.GetName() return name end ` L := luar.Init() defer L.Close() L.DoString(lua) luafn := luar.NewLuaObjectFromName(L, "fn") gobj := NewStructWithSlice("string") res, err := luafn.Call(gobj) if err != nil { fmt.Println("error!", err) } else { fmt.Println("result", res) } }
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 main() { L := luar.Init() defer L.Close() 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")) /* L.GetGlobal("string") strtab := luar.NewLuaObject(L,-1) iter := strtab.Iter() for iter.Next() { fmt.Println(iter.Key,iter.Value) } */ gsub := luar.NewLuaObjectFromName(L, "string.gsub") res, err := gsub.Call("hello $NAME go $HOME", "%$(%u+)", luar.Map{ "NAME": "Dolly", "HOME": "where you belong", }) if res == nil { fmt.Println("error", err) } else { fmt.Println("result", res) } }
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) }, }) }
// Read configuration in Lua format. // // WARNING: Deprecated. func ExampleCopyTableToMap() { L := luar.Init() defer L.Close() err := L.DoString(config) if err != nil { log.Fatal(err) } // There should be a table on the Lua stack. if !L.IsTable(-1) { log.Fatal("no table on stack") } v := luar.CopyTableToMap(L, nil, -1) // Extract table from the returned interface. m := v.(map[string]interface{}) marked := m["marked"].([]interface{}) options := m["options"].(map[string]interface{}) fmt.Printf("%#v\n", m["baggins"]) fmt.Printf("%#v\n", m["name"]) fmt.Printf("%#v\n", len(marked)) fmt.Printf("%.1f\n", marked[0]) fmt.Printf("%.1f\n", marked[1]) fmt.Printf("%#v\n", options["leave"]) // Output: // true // "dumbo" // 2 // 1.0 // 2.0 // true }
func ExampleLuaTableIter_Next() { const code = ` return { foo = 17, bar = 18, } ` L := luar.Init() defer L.Close() err := L.DoString(code) if err != nil { log.Fatal(err) } lo := luar.NewLuaObject(L, -1) iter := lo.Iter() keys := []string{} values := map[string]float64{} for iter.Next() { k := iter.Key.(string) keys = append(keys, k) values[k] = iter.Value.(float64) } sort.Strings(keys) for _, v := range keys { fmt.Println(v, values[v]) } // Output: // bar 18 // foo 17 }
func main() { L := luar.Init() defer L.Close() 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("result", res) } }
// TODO: better error handling func LuaInit() *lua.State { L := luar.Init() //L.AtPanic(LuaAtPanic) L.OpenLibs() L.DoString("math.randomseed( os.time() )") return L }
func NewConf() *Conf { c := Conf{ l: luar.Init(), } c.registerCommands() return &c }
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 }
// 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 }
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 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 (luaipt *LuaIpt) Init(path string) error { luaipt.state = luar.Init() luaipt.Bind("Debugf", log.Debugf) luaipt.Bind("Debug", log.Debug) luaipt.Bind("Messagef", log.Messagef) luaipt.Bind("Message", log.Message) luaipt.Bind("Warningf", log.Warningf) luaipt.Bind("Warning", log.Warning) luaipt.Bind("Errorf", log.Errorf) luaipt.Bind("Error", log.Error) luaipt.path = path return nil }
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 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 }, }) }
// WARNING: Deprecated. func ExampleCopyTableToStruct() { L := luar.Init() defer L.Close() err := L.DoString(config) if err != nil { log.Fatal(err) } // There should be a table on the Lua stack. if !L.IsTable(-1) { log.Fatal("no table on stack") } type conf struct { Baggins bool `lua:"baggins"` Age int `lua:"age"` Name string `lua:"name"` Marked []int `lua:"marked"` Options struct { Leave bool `lua:"leave"` cancel string // Ingored since it is unexported. Tags map[string]bool `lua:"tags"` } `lua:"options"` } var s conf v := luar.CopyTableToStruct(L, reflect.TypeOf(s), -1) s = v.(conf) fmt.Println(s.Baggins) fmt.Println(s.Age) fmt.Println(s.Name) fmt.Println(s.Marked) fmt.Println(s.Options.Leave) fmt.Println(s.Options.Tags["foolish"], s.Options.Tags["strong"]) // Output: // true // 24 // dumbo // [1 2] // true // true true }
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 }
// 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 ExampleNewLuaObjectFromValue() { L := luar.Init() defer L.Close() gsub := luar.NewLuaObjectFromName(L, "string.gsub") // We do have to explicitly copy the map to a Lua table, because `gsub` // will not handle userdata types. gmap := luar.NewLuaObjectFromValue(L, luar.Map{ "NAME": "Dolly", "HOME": "where you belong", }) res, err := gsub.Call("hello $NAME go $HOME", "%$(%u+)", gmap) if err != nil { log.Fatal(err) } fmt.Println(res) // Output: // hello Dolly go where you belong }
// LoadScript finds and loads the appropriate script by a given short name (tetra/die). func LoadScript(name string) (script *Script, err error) { kind := strings.Split(name, "/")[0] client, ok := Services[kind] if !ok { return nil, errors.New("Cannot find target service " + kind) } if _, present := Scripts[name]; present { return nil, errors.New("Double script load!") } script = &Script{ Name: name, L: luar.Init(), Log: log.New(os.Stdout, name+" ", log.LstdFlags), Handlers: make(map[string]*Handler), Commands: make(map[string]*Command), Service: kind, Client: client, Uuid: uuid.New(), Trigger: make(chan []interface{}, 5), } script.seed() script, err = loadLuaScript(script) if err != nil { return nil, errors.New("No such script " + name) } Scripts[name] = script Etcd.CreateDir("/tetra/scripts/"+name, 0) RunHook("SCRIPTLOAD", script) go script.trigger() return }
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) } }
// LoadScript finds and loads the appropriate script by a given short name (tetra/die). func NewScript(name string) (script *Script, err error) { kind := strings.Split(name, "/")[0] script = &Script{ Name: name, L: luar.Init(), Log: log.New(os.Stdout, name+" ", log.LstdFlags), Service: kind, Uuid: uuid.New(), } script.seed() script, err = loadLuaScript(script) if err != nil { script, err = loadMoonScript(script) if err != nil { return nil, errors.New("No such script " + name) } } return }
// 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 }