func ExampleLuaObject_Callf() { L := luar.Init() defer L.Close() returns := luar.Types([]string{}) // []reflect.Type const code = ` function return_strings() return {'one', luar.null, 'three'} end` err := L.DoString(code) if err != nil { log.Fatal(err) } fun := luar.NewLuaObjectFromName(L, "return_strings") // Using `Call` we would get a generic `[]interface{}`, which is awkward to // work with. But the return type can be specified: results, err := fun.Callf(returns) if err != nil { log.Fatal(err) } strs := results[0].([]string) fmt.Println(strs[0]) // We get an empty string corresponding to a luar.null in a table, // since that's the empty 'zero' value for a string. fmt.Println(strs[1]) fmt.Println(strs[2]) // Output: // one // // three }
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") } } }