package luajit /* #include */ import "C" import ( "fmt" "strconv" ) // LuaType represents Lua value types type LuaType int const ( // These constants match lua.h's LUA_T* values TypeNone LuaType = -1 TypeNil LuaType = 0 TypeBoolean LuaType = 1 TypeLightUserData LuaType = 2 TypeNumber LuaType = 3 TypeString LuaType = 4 TypeTable LuaType = 5 TypeFunction LuaType = 6 TypeUserData LuaType = 7 TypeThread LuaType = 8 ) // String returns the string representation of the Lua type func (t LuaType) String() string { switch t { case TypeNone: return "none" case TypeNil: return "nil" case TypeBoolean: return "boolean" case TypeLightUserData: return "lightuserdata" case TypeNumber: return "number" case TypeString: return "string" case TypeTable: return "table" case TypeFunction: return "function" case TypeUserData: return "userdata" case TypeThread: return "thread" default: return "unknown" } } // ConvertValue converts a value to the requested type with proper type conversion func ConvertValue[T any](value any) (T, bool) { var zero T // Handle nil case if value == nil { return zero, false } // Try direct type assertion first if result, ok := value.(T); ok { return result, true } // Type-specific conversions switch any(zero).(type) { case string: switch v := value.(type) { case float64: return any(fmt.Sprintf("%g", v)).(T), true case int: return any(strconv.Itoa(v)).(T), true case bool: if v { return any("true").(T), true } return any("false").(T), true } case int: switch v := value.(type) { case float64: return any(int(v)).(T), true case string: if i, err := strconv.Atoi(v); err == nil { return any(i).(T), true } case bool: if v { return any(1).(T), true } return any(0).(T), true } case float64: switch v := value.(type) { case int: return any(float64(v)).(T), true case string: if f, err := strconv.ParseFloat(v, 64); err == nil { return any(f).(T), true } case bool: if v { return any(1.0).(T), true } return any(0.0).(T), true } case bool: switch v := value.(type) { case string: switch v { case "true", "yes", "1": return any(true).(T), true case "false", "no", "0": return any(false).(T), true } case int: return any(v != 0).(T), true case float64: return any(v != 0).(T), true } } return zero, false } // GetTypedValue gets a value from the state with type conversion func GetTypedValue[T any](s *State, index int) (T, bool) { var zero T // Get the value as any type value, err := s.ToValue(index) if err != nil { return zero, false } // Convert it to the requested type return ConvertValue[T](value) } // GetGlobalTyped gets a global variable with type conversion func GetGlobalTyped[T any](s *State, name string) (T, bool) { s.GetGlobal(name) defer s.Pop(1) return GetTypedValue[T](s, -1) }