// script package util import ( "encoding/json" "fmt" ljson "github.com/yuin/gopher-json" "github.com/yuin/gopher-lua" ) type LuaScript struct { Code, Name, Script string Doc map[string]interface{} L *lua.LState } func (s *LuaScript) RunScript() map[string]interface{} { data := map[string]interface{}{} s.L = lua.NewState() s.L.PreloadModule("json", ljson.Loader) defer s.L.Close() if err := s.L.DoString(s.Script); err != nil { data["err"] = err.Error() } else { tab := MapToLuaTable(s.L, s.Doc) if err := s.L.CallByParam(lua.P{ Fn: s.L.GetGlobal("main"), NRet: 1, Protect: true, }, tab); err != nil { data["err"] = err.Error() } ret := s.L.Get(-1) s.L.Pop(1) if tmp, ok := ret.(*lua.LTable); ok { data = LuaTableToMap(tmp) } else { data["rep"] = ret } } return data } func Logic(str string, doc map[string]interface{}) bool { L := lua.NewState() L.PreloadModule("json", ljson.Loader) defer L.Close() b := false if err := L.DoString(str); err != nil { panic(err) } else { tab := MapToLuaTable(L, doc) if err := L.CallByParam(lua.P{ Fn: L.GetGlobal("logic"), NRet: 1, Protect: true, }, tab); err != nil { panic(err) } ret := L.Get(-1) L.Pop(1) if ret.String() == "true" { b = true } } return b } func MapToLuaTable(l *lua.LState, obj map[string]interface{}) *lua.LTable { tab := l.NewTable() for k, v := range obj { if val, ok := v.(string); ok { tab.RawSet(lua.LString(k), lua.LString(val)) } else if val, ok := v.(int64); ok { tab.RawSet(lua.LString(k), lua.LNumber(val)) } else if val, ok := v.(int32); ok { tab.RawSet(lua.LString(k), lua.LNumber(val)) } else if val, ok := v.(float64); ok { tab.RawSet(lua.LString(k), lua.LNumber(val)) } else if val, ok := v.(float32); ok { tab.RawSet(lua.LString(k), lua.LNumber(val)) } else if val, ok := v.(bool); ok { tab.RawSet(lua.LString(k), lua.LBool(val)) } else if val, ok := v.(map[string]interface{}); ok { tab.RawSet(lua.LString(k), MapToLuaTable(l, val)) } else if val, ok := v.([]interface{}); ok { bs, _ := json.Marshal(val) tab.RawSet(lua.LString(k), lua.LString(string(bs))) } } return tab } func LuaTableToMap(param *lua.LTable) map[string]interface{} { tmp := map[string]interface{}{} param.ForEach(func(key, val lua.LValue) { k := fmt.Sprint(key) if v, ok := val.(lua.LString); ok { tmp[k] = string(v) } else if v, ok := val.(*lua.LTable); ok { tmp[k] = LuaTableToMap(v) } else if v, ok := val.(*lua.LBool); ok { if v.String() == "true" { tmp[k] = true } else { tmp[k] = false } } else { tmp[k] = v } }) return tmp }