Example #1
0
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
}
Example #2
0
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")
		}
	}
}