Пример #1
0
Файл: lgo.go Проект: reusee/lgo
func (self *Lua) RegisterFunction(name string, fun interface{}) {
	path := strings.Split(name, ".")
	name = path[len(path)-1]
	path = path[0 : len(path)-1]
	if len(path) == 0 {
		path = append(path, "_G")
	}

	// ensure namespaces
	for i, namespace := range path {
		cNamespace := cstr(namespace)
		if i == 0 { // top namespace
			what := C.lua_getglobal(self.State, cNamespace)
			if what == C.LUA_TNIL { // not exists
				C.lua_settop(self.State, -2)
				C.lua_createtable(self.State, 0, 0)
				C.lua_setglobal(self.State, cNamespace)
				C.lua_getglobal(self.State, cNamespace)
			}
			if C.lua_type(self.State, -1) != C.LUA_TTABLE {
				self.Panic("global %s is not a table", namespace)
			}
		} else { // sub namespace
			C.lua_pushstring(self.State, cNamespace)
			C.lua_rawget(self.State, -2)
			if C.lua_type(self.State, -1) == C.LUA_TNIL {
				C.lua_settop(self.State, -2)
				C.lua_pushstring(self.State, cNamespace)
				C.lua_createtable(self.State, 0, 0)
				C.lua_rawset(self.State, -3)
				C.lua_pushstring(self.State, cNamespace)
				C.lua_rawget(self.State, -2)
			}
			if C.lua_type(self.State, -1) != C.LUA_TTABLE {
				self.Panic("namespace %s is not a table", namespace)
			}
		}
	}

	// register function
	funcType := reflect.TypeOf(fun)
	if funcType.IsVariadic() {
		self.Panic("cannot register variadic function: %v", fun)
	}
	argc := funcType.NumIn()
	cName := cstr(name)
	function := &Function{
		fun:       fun,
		lua:       self,
		name:      name,
		funcType:  funcType,
		funcValue: reflect.ValueOf(fun),
		argc:      argc,
	}
	funcId := rand.Int63()
	functionRegister.Set(funcId, function)
	C.register_function(self.State, cName, (C.int64_t)(funcId))
	self.Functions[name] = function
	C.lua_settop(self.State, -2)
}
Пример #2
0
func unpackMapToLua(state State, m *P.Map) {
	L := state.L
	n := len(m.Elems)

	C.lua_createtable(L, 0, 0)

	for i := 0; i < n; i++ {
		key := m.Elems[i].Key
		value := m.Elems[i].Value

		// key
		switch key.(type) {
		case int, int8, int32, int64, uint, uint8, uint32, uint64, float32, float64, string:
			UnpackObjectToLua(state, key)
		case []byte:
			bytes := key.([]byte)
			pushBytesToLua(L, bytes)
		default:
			continue
		}

		// value
		UnpackObjectToLua(state, value)

		C.lua_settable(L, -3)
	}
}
Пример #3
0
Файл: lgo.go Проект: reusee/lgo
func (lua *Lua) PushGoValue(value reflect.Value) {
	switch t := value.Type(); t.Kind() {
	case reflect.Bool:
		if value.Bool() {
			C.lua_pushboolean(lua.State, C.int(1))
		} else {
			C.lua_pushboolean(lua.State, C.int(0))
		}
	case reflect.String:
		C.lua_pushstring(lua.State, C.CString(value.String()))
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		C.lua_pushnumber(lua.State, C.lua_Number(C.longlong(value.Int())))
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		C.lua_pushnumber(lua.State, C.lua_Number(C.ulonglong(value.Uint())))
	case reflect.Float32, reflect.Float64:
		C.lua_pushnumber(lua.State, C.lua_Number(C.double(value.Float())))
	case reflect.Slice:
		length := value.Len()
		C.lua_createtable(lua.State, C.int(length), 0)
		for i := 0; i < length; i++ {
			C.lua_pushnumber(lua.State, C.lua_Number(i+1))
			lua.PushGoValue(value.Index(i))
			C.lua_settable(lua.State, -3)
		}
	case reflect.Interface:
		lua.PushGoValue(value.Elem())
	case reflect.Ptr, reflect.UnsafePointer:
		C.lua_pushlightuserdata(lua.State, unsafe.Pointer(value.Pointer()))
	default:
		lua.Panic("wrong return value %v %v", value, t.Kind())
	}
}
Пример #4
0
func unpackArrayToLua(state State, a *P.Array) {
	L := state.L
	n := len(a.Elems)
	C.lua_createtable(L, C.int(n), 0)
	for i := 0; i < n; i++ {
		UnpackObjectToLua(state, a.Elems[i])
		C.lua_rawseti(L, C.int(-2), C.int(i+1))
	}
}
Пример #5
0
Файл: lua.go Проект: reusee/lua
// Peval evaluates a piece of lua code. no panic when error occur.
func (l *Lua) Peval(code string, envs ...interface{}) (returns []interface{}, err error) {
	defer C.lua_settop(l.State, 0)
	C.push_errfunc(l.State)
	curTop := C.lua_gettop(l.State)
	// parse
	cCode := C.CString(code)
	defer C.free(unsafe.Pointer(cCode))
	if ret := C.luaL_loadstring(l.State, cCode); ret != 0 { // load error
		return nil, fmt.Errorf("LOAD ERROR: %s", C.GoString(C.lua_tolstring(l.State, -1, nil)))
	}
	// env
	if len(envs) > 0 {
		if len(envs)%2 != 0 {
			return nil, fmt.Errorf("number of arguments not match")
		}
		C.lua_createtable(l.State, 0, 0)
		for i := 0; i < len(envs); i += 2 {
			name, ok := envs[i].(string)
			if !ok {
				return nil, fmt.Errorf("name must be string, not %v", envs[i])
			}
			C.lua_pushstring(l.State, cstr(name))
			err := l.pushGoValue(envs[i+1], name)
			if err != nil {
				return nil, err
			}
			C.lua_rawset(l.State, -3)
		}
		// set env
		C.set_eval_env(l.State)
	}
	// call
	l.err = nil
	if ret := C.lua_pcall(l.State, 0, C.LUA_MULTRET, -2); ret != 0 {
		// error occured
		return nil, fmt.Errorf("CALL ERROR: %s", C.GoString(C.lua_tolstring(l.State, -1, nil)))
	} else if l.err != nil { // error raise by invokeGoFunc
		return nil, l.err
	} else {
		// return values
		nReturn := C.lua_gettop(l.State) - curTop
		returns = make([]interface{}, int(nReturn))
		for i := C.int(0); i < nReturn; i++ {
			value, err := l.toGoValue(-1-i, interfaceType)
			if err != nil {
				return nil, err
			}
			if value != nil {
				returns[int(nReturn-1-i)] = value.Interface()
			} else {
				returns[int(nReturn-1-i)] = nil
			}
		}
	}
	return
}
Пример #6
0
func luaGetSubTable(L *C.lua_State, table C.int, key string) (bool, error) {
	pushStringToLua(L, key)
	C.lua_gettable(L, table)
	ltype := C.lua_type(L, -1)
	if ltype == C.LUA_TNIL {
		C.lua_createtable(L, 0, 0)
		// table[key] = {}
		pushStringToLua(L, key)
		C.lua_pushvalue(L, -2)
		C.lua_settable(L, table)
	}
	ltype = C.lua_type(L, -1)
	if ltype != C.LUA_TTABLE {
		C.lua_settop(L, -2)
		return false, fmt.Errorf("field `%v` exist, and it is not a table", key)
	}
	return true, nil
}
Пример #7
0
func luaKeys(state State) int {
	L := state.L
	vmap := mustBeMap(state, 2)
	if vmap == nil {
		C.lua_pushnil(L)
		pushStringToLua(L, "Keys() only apply to `map'")
		return 2
	}

	vkeys := vmap.MapKeys()
	C.lua_createtable(L, C.int(len(vkeys)), 0)
	for i := 0; i < len(vkeys); i++ {
		if !state.goToLuaValue(vkeys[i]) {
			continue
		}
		C.lua_rawseti(L, C.int(-2), C.int(i+1))
	}

	return 1
}
Пример #8
0
func (s *State) NewTable() {
	C.lua_createtable(s.L, 0, 0)
}
Пример #9
0
Файл: lua.go Проект: szll/golua
// lua_newtable
func (L *State) NewTable() {
	C.lua_createtable(L.s, 0, 0)
}
Пример #10
0
Файл: lua.go Проект: szll/golua
// lua_createtable
func (L *State) CreateTable(narr int, nrec int) {
	C.lua_createtable(L.s, C.int(narr), C.int(nrec))
}
Пример #11
0
// Creates a new empty table and pushes it onto the stack. The new table
// has space pre-allocated for narr array elements and nrec non-array
// elements. This pre-allocation is useful when you know exactly how many
// elements the table will have. Otherwise you can use the function Newtable.
func (this *State) Createtable(narr, nrec int) {
	if !this.Checkstack(1) {
		panic("STATE: unable to grow lua_state stack")
	}
	C.lua_createtable(this.luastate, C.int(narr), C.int(nrec))
}
Пример #12
0
// Creates a new empty table and pushes it onto the stack. The new table
// has space pre-allocated for narr array elements and nrec non-array
// elements. This pre-allocation is useful when you know exactly how many
// elements the table will have. Otherwise you can use the function Newtable.
func (s *State) Createtable(narr, nrec int) {
	C.lua_createtable(s.l, C.int(narr), C.int(nrec))
}
Пример #13
0
Файл: lua.go Проект: reusee/lua
func (l *Lua) pushGoValue(v interface{}, name string) error {
	if v == nil {
		C.lua_pushnil(l.State)
		return nil
	}
	switch value := v.(type) {
	case bool:
		if value {
			C.lua_pushboolean(l.State, C.int(1))
		} else {
			C.lua_pushboolean(l.State, C.int(0))
		}
	case string:
		C.lua_pushstring(l.State, C.CString(value))
	case int:
		C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value)))
	case int8:
		C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value)))
	case int16:
		C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value)))
	case int32:
		C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value)))
	case int64:
		C.lua_pushnumber(l.State, C.lua_Number(C.longlong(value)))
	case uint:
		C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value)))
	case uint8:
		C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value)))
	case uint16:
		C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value)))
	case uint32:
		C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value)))
	case uint64:
		C.lua_pushnumber(l.State, C.lua_Number(C.ulonglong(value)))
	case float32:
		C.lua_pushnumber(l.State, C.lua_Number(C.double(value)))
	case float64:
		C.lua_pushnumber(l.State, C.lua_Number(C.double(value)))
	case unsafe.Pointer:
		C.lua_pushlightuserdata(l.State, value)
	default:
		// not basic types, use reflect
		switch valueType := reflect.TypeOf(v); valueType.Kind() {
		case reflect.Func:
			// function
			if valueType.IsVariadic() {
				return fmt.Errorf("variadic function is not supported, %s", name)
			}
			function := &_Function{
				name:      name,
				lua:       l,
				fun:       v,
				funcType:  valueType,
				funcValue: reflect.ValueOf(v),
				argc:      valueType.NumIn(),
			}
			funcsLock.Lock()
			funcs = append(funcs, function)
			id := len(funcs) - 1
			funcsLock.Unlock()
			C.push_go_func(l.State, C.int64_t(id))
		case reflect.Slice:
			value := reflect.ValueOf(v)
			length := value.Len()
			C.lua_createtable(l.State, C.int(length), 0)
			for i := 0; i < length; i++ {
				C.lua_pushnumber(l.State, C.lua_Number(i+1))
				err := l.pushGoValue(value.Index(i).Interface(), "")
				if err != nil {
					return err
				}
				C.lua_settable(l.State, -3)
			}
		case reflect.Ptr:
			C.lua_pushlightuserdata(l.State, unsafe.Pointer(reflect.ValueOf(v).Pointer()))
		default:
			// unknown type
			return fmt.Errorf("unsupported type %v", v)
		}
	}
	return nil
}
Пример #14
0
Файл: core.go Проект: vron/lua
func Createtable(s *State, narr, nrec int) {
	C.lua_createtable((*C.lua_State)(s), C.int(narr), C.int(nrec))
}
Пример #15
0
func LuaL_newlibtable(L Lua_State, l unsafe.Pointer) {
	C.lua_createtable(Lua_CStatePtr(L), 0, LuaF_RegLen(l))
}