// 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() }
// 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 }
// 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() }
// 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 }
// luaL_getmetatable func (L *State) LGetMetaTable(tname string) { Ctname := C.CString(tname) defer C.free(unsafe.Pointer(Ctname)) C.lua_getfield(L.s, LUA_REGISTRYINDEX, Ctname) }
// lua_getfield func (L *State) GetField(index int, k string) { Ck := C.CString(k) defer C.free(unsafe.Pointer(Ck)) C.lua_getfield(L.s, C.int(index), Ck) }
// Pushes onto the stack the value t[k], where t is the value at the // given valid index. func (this *State) Getfield(index int, k string) { cs := C.CString(k) defer C.free(unsafe.Pointer(cs)) C.lua_getfield(this.luastate, C.int(index), cs) }
func (L *State) GetField(index int, k string) { C.lua_getfield(L.s, C.int(index), C.CString(k)) }
func (l *Lua) getStackTraceback() string { C.lua_getfield(l.State, C.LUA_GLOBALSINDEX, cstr("debug")) C.lua_getfield(l.State, -1, cstr("traceback")) C.lua_call(l.State, 0, 1) return C.GoString(C.lua_tolstring(l.State, -1, nil)) }
//TODO: rename better... clashes with lua_getmetatable func LGetMetaTable(L *State, tname string) { //C.luaL_getmetatable(L.s,C.CString(tname)); C.lua_getfield(L.s, LUA_REGISTRYINDEX, C.CString(tname)) }