Пример #1
0
// 执行lua脚本字符串
func (L *State) Dostring(str string) (ok bool) {
	cs := C.CString(str)
	defer C.free(unsafe.Pointer(cs))

	if C.luaL_loadstring(L.s, cs) == 0 {
		return C.lua_pcall(L.s, 0, C.LUA_MULTRET, 0) == 0
	}
	return false
}
Пример #2
0
// 执行lua脚本
func (L *State) Dofile(fname string) (ok bool) {
	fn := C.CString(fname)
	defer C.free(unsafe.Pointer(fn))

	if C.luaL_loadfile(L.s, fn) == 0 {
		return C.lua_pcall(L.s, 0, C.LUA_MULTRET, 0) == 0
	}
	return false
}
Пример #3
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
}
Пример #4
0
// Calls a function in protected mode.
//
// Both nargs and nresults have the same meaning as in Call. If there are
// no errors during the call, Pcall behaves exactly like Call. However,
// if there is any error, Pcall catches it, pushes a single value on the
// stack (the error message), and returns an error code. Like Call, Pcall
// always removes the function and its arguments from the stack.
//
// If errfunc is 0, then the error message returned on the stack is exactly
// the original error message. Otherwise, errfunc is the stack index of
// an error handler function. (In the current implementation, this index
// cannot be a pseudo-index.) In case of runtime errors, this function
// will be called with the error message and its return value will be the
// message returned on the stack by Pcall.
//
// Typically, the error handler function is used to add more debug
// information to the error message, such as a stack traceback. Such
// information cannot be gathered after the return of Pcall, since by then
// the stack has unwound.
func (this *State) Pcall(nargs, nresults, errfunc int) error {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r.(string))
		}
	}()

	r := int(C.lua_pcall(this.luastate, C.int(nargs), C.int(nresults), C.int(errfunc)))
	return this.geterror(r)
}
Пример #5
0
// Executes an aggregation over the iterator.
func (e *ExecutionEngine) Aggregate() (interface{}, error) {
	functionName := C.CString("sky_aggregate")
	defer C.free(unsafe.Pointer(functionName))

	C.lua_getfield(e.state, -10002, functionName)
	C.lua_pushlightuserdata(e.state, unsafe.Pointer(e.cursor))
	rc := C.lua_pcall(e.state, 1, 1, 0)
	if rc != 0 {
		luaErrString := C.GoString(C.lua_tolstring(e.state, -1, nil))
		fmt.Println(e.FullAnnotatedSource())
		return nil, fmt.Errorf("skyd.ExecutionEngine: Unable to aggregate: %s", luaErrString)
	}

	return e.decodeResult()
}
Пример #6
0
// Initializes the Lua context and compiles the source code.
func (e *ExecutionEngine) init() error {
	if e.state != nil {
		return nil
	}

	// Initialize the state and open the libraries.
	e.state = C.luaL_newstate()
	if e.state == nil {
		return errors.New("Unable to initialize Lua context.")
	}
	C.luaL_openlibs(e.state)

	// Generate the header file.
	err := e.generateHeader()
	if err != nil {
		e.Destroy()
		return err
	}

	// Compile the script.
	e.fullSource = fmt.Sprintf("%v\n%v", e.header, e.source)
	source := C.CString(e.fullSource)
	defer C.free(unsafe.Pointer(source))
	ret := C.luaL_loadstring(e.state, source)
	if ret != 0 {
		defer e.Destroy()
		errstring := C.GoString(C.lua_tolstring(e.state, -1, nil))
		return fmt.Errorf("skyd.ExecutionEngine: Syntax Error: %v", errstring)
	}

	// Run script once to initialize.
	ret = C.lua_pcall(e.state, 0, 0, 0)
	if ret != 0 {
		defer e.Destroy()
		errstring := C.GoString(C.lua_tolstring(e.state, -1, nil))
		return fmt.Errorf("skyd.ExecutionEngine: Init Error: %v", errstring)
	}

	// Setup cursor.
	err = e.initCursor()
	if err != nil {
		e.Destroy()
		return err
	}

	return nil
}
Пример #7
0
Файл: lua.go Проект: reusee/lua
// Pcall calls a lua function. no panic
func (l *Lua) Pcall(fullname string, args ...interface{}) (returns []interface{}, err error) {
	C.push_errfunc(l.State)
	curTop := C.lua_gettop(l.State)
	// get function
	path := strings.Split(fullname, ".")
	for i, name := range path {
		if i == 0 {
			C.lua_getfield(l.State, C.LUA_GLOBALSINDEX, cstr(name))
		} else {
			if C.lua_type(l.State, -1) != C.LUA_TTABLE {
				return nil, fmt.Errorf("%s is not a function", fullname)
			}
			C.lua_pushstring(l.State, cstr(name))
			C.lua_gettable(l.State, -2)
			C.lua_remove(l.State, -2) // remove table
		}
	}
	if C.lua_type(l.State, -1) != C.LUA_TFUNCTION {
		return nil, fmt.Errorf("%s is not a function", fullname)
	}
	// args
	for _, arg := range args {
		l.pushGoValue(arg, "")
	}
	// call
	l.err = nil
	if ret := C.lua_pcall(l.State, C.int(len(args)), C.LUA_MULTRET, C.int(-(len(args))-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
			}
			returns[int(nReturn-1-i)] = value.Interface()
		}
	}
	return
}
Пример #8
0
func callLuaFuncUtil(state State, inv []reflect.Value, nout int) ([]interface{}, error) {
	L := state.L
	bottom := int(C.lua_gettop(L))

	var result []interface{}
	var nluaout C.int
	var nin C.int
	if nout >= 0 {
		nluaout = C.int(nout)
		result = make([]interface{}, 0, nout)
	} else {
		nluaout = C.LUA_MULTRET
		result = make([]interface{}, 0, 1)
	}
	if inv != nil {
		for _, iarg := range inv {
			state.goToLuaValue(iarg)
		}
		nin = C.int(len(inv))
	} else {
		nin = 0
	}
	ret := int(C.lua_pcall(L, nin, nluaout, 0))
	if ret != 0 {
		err := stringFromLua(L, -1)
		C.lua_settop(L, -2)
		return result, errors.New(err)
	}
	top := int(C.lua_gettop(L))
	for i := bottom; i <= top; i++ {
		value, _ := state.luaToGoValue(i, nil)
		if value.IsValid() {
			result = append(result, value.Interface())
		} else {
			result = append(result, nil)
		}
	}
	rnout := C.int(top + 1 - bottom)
	C.lua_settop(L, -rnout-1)
	return result, nil
}
Пример #9
0
// Executes an merge over the iterator.
func (e *ExecutionEngine) Merge(results interface{}, data interface{}) (interface{}, error) {
	functionName := C.CString("sky_merge")
	defer C.free(unsafe.Pointer(functionName))

	C.lua_getfield(e.state, -10002, functionName)
	err := e.encodeArgument(results)
	if err != nil {
		return results, err
	}
	err = e.encodeArgument(data)
	if err != nil {
		return results, err
	}
	rc := C.lua_pcall(e.state, 2, 1, 0)
	if rc != 0 {
		luaErrString := C.GoString(C.lua_tolstring(e.state, -1, nil))
		fmt.Println(e.FullAnnotatedSource())
		return results, fmt.Errorf("skyd.ExecutionEngine: Unable to merge: %s", luaErrString)
	}

	return e.decodeResult()
}
Пример #10
0
// Initializes the cursor used by the script.
func (e *ExecutionEngine) initCursor() error {
	// Create the cursor.
	minPropertyId, maxPropertyId := e.propertyFile.NextIdentifiers()
	e.cursor = C.sky_cursor_new((C.int32_t)(minPropertyId), (C.int32_t)(maxPropertyId))
	e.cursor.context = unsafe.Pointer(e)
	C.executionEngine_setNextObjectFunc(unsafe.Pointer(e.cursor))

	// Initialize the cursor from within Lua.
	functionName := C.CString("sky_init_cursor")
	defer C.free(unsafe.Pointer(functionName))

	C.lua_getfield(e.state, -10002, functionName)
	C.lua_pushlightuserdata(e.state, unsafe.Pointer(e.cursor))
	//fmt.Printf("%s\n\n", e.FullAnnotatedSource())
	rc := C.lua_pcall(e.state, 1, 0, 0)
	if rc != 0 {
		luaErrString := C.GoString(C.lua_tolstring(e.state, -1, nil))
		return fmt.Errorf("Unable to init cursor: %s", luaErrString)
	}

	return nil
}
Пример #11
0
Файл: lua.go Проект: szll/golua
func (L *State) pcall(nargs, nresults, errfunc int) int {
	return int(C.lua_pcall(L.s, C.int(nargs), C.int(nresults), C.int(errfunc)))
}
Пример #12
0
// Calls a function in protected mode.
//
// Both nargs and nresults have the same meaning as in Call. If there are
// no errors during the call, Pcall behaves exactly like Call. However,
// if there is any error, Pcall catches it, pushes a single value on the
// stack (the error message), and returns an error code. Like Call, Pcall
// always removes the function and its arguments from the stack.
//
// If errfunc is 0, then the error message returned on the stack is exactly
// the original error message. Otherwise, errfunc is the stack index of
// an error handler function. (In the current implementation, this index
// cannot be a pseudo-index.) In case of runtime errors, this function
// will be called with the error message and its return value will be the
// message returned on the stack by Pcall.
//
// Typically, the error handler function is used to add more debug
// information to the error message, such as a stack traceback. Such
// information cannot be gathered after the return of Pcall, since by then
// the stack has unwound.
func (s *State) Pcall(nargs, nresults, errfunc int) error {
	r := int(C.lua_pcall(s.l, C.int(nargs), C.int(nresults), C.int(errfunc)))
	return numtoerror(r)
}
Пример #13
0
Файл: core.go Проект: vron/lua
func Pcall(s *State, nargs, nres, errf int) int {
	return int(C.lua_pcall((*C.lua_State)(s),
		C.int(nargs), C.int(nres), C.int(errf)))
}