@@ -168,58 +168,90 @@ pub fn int_token_value(token: &LuaSyntaxToken) -> Result<NumberResult, LuaParseE
168168 match signed_value {
169169 Ok ( value) => Ok ( NumberResult :: Int ( value) ) ,
170170 Err ( e) => {
171- let range = token. text_range ( ) ;
172-
173- // 如果是溢出错误,尝试解析为无符号整数
174- if * e. kind ( ) == std:: num:: IntErrorKind :: PosOverflow && is_luajit_unsigned {
175- let unsigned_value = match repr {
176- IntegerRepr :: Hex => {
177- let text = & text[ 2 ..] ;
178- u64:: from_str_radix ( text, 16 )
179- }
180- IntegerRepr :: Bin => {
181- let text = & text[ 2 ..] ;
182- u64:: from_str_radix ( text, 2 )
183- }
184- IntegerRepr :: Normal => text. parse :: < u64 > ( ) ,
185- } ;
186-
187- match unsigned_value {
188- Ok ( value) => Ok ( NumberResult :: Uint ( value) ) ,
189- Err ( _) => Err ( LuaParseError :: new (
190- LuaParseErrorKind :: SyntaxError ,
191- & t ! (
192- "The integer literal '%{text}' is too large to be represented" ,
193- text = token. text( )
194- ) ,
195- range,
196- ) ) ,
197- }
198- } else if matches ! (
171+ // 按照Lua的行为:如果整数溢出,尝试解析为浮点数
172+ if matches ! (
199173 * e. kind( ) ,
200174 std:: num:: IntErrorKind :: NegOverflow | std:: num:: IntErrorKind :: PosOverflow
201175 ) {
202- if let Ok ( f) = text. parse :: < f64 > ( ) {
203- return Ok ( NumberResult :: Float ( f) ) ;
176+ // 如果是luajit无符号整数,尝试解析为u64
177+ if is_luajit_unsigned {
178+ let unsigned_value = match repr {
179+ IntegerRepr :: Hex => {
180+ let text = & text[ 2 ..] ;
181+ u64:: from_str_radix ( text, 16 )
182+ }
183+ IntegerRepr :: Bin => {
184+ let text = & text[ 2 ..] ;
185+ u64:: from_str_radix ( text, 2 )
186+ }
187+ IntegerRepr :: Normal => text. parse :: < u64 > ( ) ,
188+ } ;
189+
190+ if let Ok ( value) = unsigned_value {
191+ return Ok ( NumberResult :: Uint ( value) ) ;
192+ }
193+ } else {
194+ // Lua 5.4行为:对于十六进制/二进制整数溢出,解析为u64然后reinterpret为i64
195+ // 例如:0xFFFFFFFFFFFFFFFF = -1
196+ if matches ! ( repr, IntegerRepr :: Hex | IntegerRepr :: Bin ) {
197+ let unsigned_value = match repr {
198+ IntegerRepr :: Hex => {
199+ let text = & text[ 2 ..] ;
200+ u64:: from_str_radix ( text, 16 )
201+ }
202+ IntegerRepr :: Bin => {
203+ let text = & text[ 2 ..] ;
204+ u64:: from_str_radix ( text, 2 )
205+ }
206+ _ => unreachable ! ( ) ,
207+ } ;
208+
209+ if let Ok ( value) = unsigned_value {
210+ // Reinterpret u64 as i64 (补码转换)
211+ return Ok ( NumberResult :: Int ( value as i64 ) ) ;
212+ } else {
213+ // 超过64位,转换为浮点数
214+ // 例如:0x13121110090807060504030201
215+ let hex_str = match repr {
216+ IntegerRepr :: Hex => & text[ 2 ..] ,
217+ IntegerRepr :: Bin => & text[ 2 ..] ,
218+ _ => unreachable ! ( ) ,
219+ } ;
220+
221+ // 手动将十六进制转为浮点数
222+ let base = if matches ! ( repr, IntegerRepr :: Hex ) {
223+ 16.0
224+ } else {
225+ 2.0
226+ } ;
227+ let mut result = 0.0f64 ;
228+ for c in hex_str. chars ( ) {
229+ if let Some ( digit) = c. to_digit ( base as u32 ) {
230+ result = result * base + ( digit as f64 ) ;
231+ }
232+ }
233+ return Ok ( NumberResult :: Float ( result) ) ;
234+ }
235+ } else if let Ok ( f) = text. parse :: < f64 > ( ) {
236+ // 十进制整数溢出,解析为浮点数
237+ return Ok ( NumberResult :: Float ( f) ) ;
238+ }
204239 }
205240
206241 Err ( LuaParseError :: new (
207242 LuaParseErrorKind :: SyntaxError ,
208- & t ! (
209- "The integer literal '%{text}' is too large to be represented in type 'float'" ,
210- text = token. text( )
211- ) ,
212- range,
243+ & t ! ( "malformed number" ) ,
244+ token. text_range ( ) ,
213245 ) )
214246 } else {
215247 Err ( LuaParseError :: new (
216248 LuaParseErrorKind :: SyntaxError ,
217249 & t ! (
218- "The integer literal ' %{text}' is invalid, %{err}" ,
250+ "Failed to parse integer literal %{text}: %{err}" ,
219251 text = token. text( ) ,
220252 err = e
221253 ) ,
222- range ,
254+ token . text_range ( ) ,
223255 ) )
224256 }
225257 }
0 commit comments