diff --git a/processor/processor.go b/processor/processor.go index 1a1c5c6..e9f5636 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -2,6 +2,7 @@ package processor import ( "fmt" + "reflect" "strings" lua "github.com/yuin/gopher-lua" @@ -32,6 +33,86 @@ type ModificationRecord struct { Context string } +func NewLuaState() (*lua.LState, error) { + L := lua.NewState() + // defer L.Close() + + // Load math library + L.Push(L.GetGlobal("require")) + L.Push(lua.LString("math")) + if err := L.PCall(1, 1, nil); err != nil { + return nil, fmt.Errorf("error loading Lua math library: %v", err) + } + + // Initialize helper functions + if err := InitLuaHelpers(L); err != nil { + return nil, err + } + + return L, nil +} + +// ToLuaTable converts a struct or map to a Lua table recursively +func ToLuaTable(L *lua.LState, data interface{}) (*lua.LTable, error) { + luaTable := L.NewTable() + + switch v := data.(type) { + case map[string]interface{}: + for key, value := range v { + luaValue, err := ToLuaTable(L, value) + if err != nil { + return nil, err + } + luaTable.RawSetString(key, luaValue) + } + case struct{}: + val := reflect.ValueOf(v) + for i := 0; i < val.NumField(); i++ { + field := val.Type().Field(i) + luaValue, err := ToLuaTable(L, val.Field(i).Interface()) + if err != nil { + return nil, err + } + luaTable.RawSetString(field.Name, luaValue) + } + case string: + luaTable.RawSetString("v", lua.LString(v)) + case bool: + luaTable.RawSetString("v", lua.LBool(v)) + case float64: + luaTable.RawSetString("v", lua.LNumber(v)) + default: + return nil, fmt.Errorf("unsupported data type: %T", data) + } + return luaTable, nil +} + +// FromLuaTable converts a Lua table to a struct or map recursively +func FromLuaTable(L *lua.LState, luaTable *lua.LTable) (map[string]interface{}, error) { + result := make(map[string]interface{}) + + luaTable.ForEach(func(key lua.LValue, value lua.LValue) { + switch v := value.(type) { + case *lua.LTable: + nestedMap, err := FromLuaTable(L, v) + if err != nil { + return + } + result[key.String()] = nestedMap + case lua.LString: + result[key.String()] = string(v) + case lua.LBool: + result[key.String()] = bool(v) + case lua.LNumber: + result[key.String()] = float64(v) + default: + result[key.String()] = nil + } + }) + + return result, nil +} + // InitLuaHelpers initializes common Lua helper functions func InitLuaHelpers(L *lua.LState) error { helperScript := `