@@ -126,6 +126,8 @@ local PUNCTUATION = {
126126 " ==" , " ~=" , " <=" , " >=" , " <" , " >" , " =" ,
127127 " (" , " )" , " {" , " }" , " [" , " ]" ,
128128 " ;" , " :" , " ," , " ." , " .." , " ..." ,
129+ -- Lua 5.2
130+ " ::" ,
129131 -- Lua 5.3
130132 " //" , " &" , " |" , " ~" , " >>" , " <<" ,
131133} for i , v in ipairs (PUNCTUATION ) do PUNCTUATION [v ], PUNCTUATION [i ] = true , nil end
@@ -231,7 +233,7 @@ function errorOnLine(path, ln, agent, s, ...)
231233 path , ln , s :format (... )
232234 )
233235 end
234- onError (err , 2 )
236+ onError (s , 2 )
235237end
236238function errorInFile (contents , path , ptr , agent , s , ...)
237239 s = s :format (... )
@@ -258,7 +260,7 @@ function errorInFile(contents, path, ptr, agent, s, ...)
258260 path , ln , s , lastLine , (" -" ):rep (col - 1 )
259261 )
260262 end
261- onError (err , 2 )
263+ onError (s , 2 )
262264
263265 return s
264266end
@@ -310,6 +312,15 @@ function parseStringlike(s, ptr)
310312 return tok , ptr
311313end
312314
315+ local NUM_HEX_FRAC_EXP = (" ^( 0x ([%dA-Fa-f]*) %.([%dA-Fa-f]+) [Pp]([-+]?[%dA-Fa-f]+) )" ):gsub (" +" , " " )
316+ local NUM_HEX_FRAC = (" ^( 0x ([%dA-Fa-f]*) %.([%dA-Fa-f]+) )" ):gsub (" +" , " " )
317+ local NUM_HEX_EXP = (" ^( 0x ([%dA-Fa-f]+) [Pp]([-+]?[%dA-Fa-f]+) )" ):gsub (" +" , " " )
318+ local NUM_HEX = (" ^( 0x [%dA-Fa-f]+ )" ):gsub (" +" , " " )
319+ local NUM_DEC_FRAC_EXP = (" ^( %d* %.%d+ [Ee][-+]?%d+ )" ):gsub (" +" , " " )
320+ local NUM_DEC_FRAC = (" ^( %d* %.%d+ )" ):gsub (" +" , " " )
321+ local NUM_DEC_EXP = (" ^( %d+ [Ee][-+]?%d+ )" ):gsub (" +" , " " )
322+ local NUM_DEC = (" ^( %d+ )" ):gsub (" +" , " " )
323+
313324-- tokens = tokenize( lua, filePath, allowBacktickStrings [, allowPreprocessorTokens=false ] )
314325function tokenize (s , path , allowBacktickStrings , allowMetaTokens )
315326 local tokens = {}
@@ -333,17 +344,43 @@ function tokenize(s, path, allowBacktickStrings, allowMetaTokens)
333344
334345 -- Number.
335346 elseif s :find (" ^%.?%d" , ptr ) then
336- local i1 , i2 , numStr = s :find (" ^(%d*%.%d+[Ee]%-?%d+)" , ptr )
337- if not i1 then i1 , i2 , numStr = s :find (" ^(%d+[Ee]%-?%d+)" , ptr ) end
338- if not i1 then i1 , i2 , numStr = s :find (" ^(0x[%dA-Fa-f]+)" , ptr ) end
339- if not i1 then i1 , i2 , numStr = s :find (" ^(%d*%.%d+)" , ptr ) end
340- if not i1 then i1 , i2 , numStr = s :find (" ^(%d+)" , ptr ) end
341-
342- if not i1 then
347+ local lua52Hex , i1 , i2 , numStr = true , s :find (NUM_HEX_FRAC_EXP , ptr )
348+ if not i1 then lua52Hex , i1 , i2 , numStr = true , s :find (NUM_HEX_FRAC , ptr ) end
349+ if not i1 then lua52Hex , i1 , i2 , numStr = true , s :find (NUM_HEX_EXP , ptr ) end
350+ if not i1 then lua52Hex , i1 , i2 , numStr = false , s :find (NUM_HEX , ptr ) end
351+ if not i1 then lua52Hex , i1 , i2 , numStr = false , s :find (NUM_DEC_FRAC_EXP , ptr ) end
352+ if not i1 then lua52Hex , i1 , i2 , numStr = false , s :find (NUM_DEC_FRAC , ptr ) end
353+ if not i1 then lua52Hex , i1 , i2 , numStr = false , s :find (NUM_DEC_EXP , ptr ) end
354+ if not i1 then lua52Hex , i1 , i2 , numStr = false , s :find (NUM_DEC , ptr ) end
355+
356+ if not numStr then
343357 return nil , errorInFile (s , path , ptr , " Tokenizer" , " Malformed number." )
344358 end
359+ if s :find (" ^[%w_]" , i2 + 1 ) then
360+ -- This is actually only an error in Lua 5.1. Maybe we should issue a warning instead of an error here?
361+ return nil , errorInFile (s , path , i2 + 1 , " Tokenizer" , " Malformed number." )
362+ end
345363
346364 local n = tonumber (numStr )
365+
366+ -- Support hexadecimal floats in Lua 5.1.
367+ if not n and lua52Hex then
368+ local _ , intStr , fracStr , expStr = numStr :match (NUM_HEX_FRAC_EXP )
369+ if not intStr then _ , intStr , fracStr = numStr :match (NUM_HEX_FRAC ) ; expStr = " 0" end
370+ if not intStr then _ , intStr , expStr = numStr :match (NUM_HEX_EXP ) ; fracStr = " " end
371+ assert (intStr , numStr )
372+
373+ n = tonumber (intStr , 16 ) or 0 -- intStr may be "".
374+
375+ local fracValue = 1
376+ for i = 1 , # fracStr do
377+ fracValue = fracValue / 16
378+ n = n + tonumber (fracStr :sub (i , i ), 16 )* fracValue
379+ end
380+
381+ n = n * 2 ^ expStr :gsub (" ^+" , " " )
382+ end
383+
347384 if not n then
348385 return nil , errorInFile (s , path , ptr , " Tokenizer" , " Invalid number." )
349386 end
@@ -492,7 +529,7 @@ function tokenize(s, path, allowBacktickStrings, allowMetaTokens)
492529 local repr = s :sub (ptr , ptr + 2 )
493530 tok = {type = " punctuation" , representation = repr , value = repr }
494531 ptr = ptr +# repr
495- elseif s :find (" ^%.%." , ptr ) or s :find (" ^[=~<>]=" , ptr ) or s :find (" ^//" , ptr ) or s :find (" ^<<" , ptr ) or s :find (" ^>>" , ptr ) then
532+ elseif s :find (" ^%.%." , ptr ) or s :find (" ^[=~<>]=" , ptr ) or s :find (" ^:: " , ptr ) or s : find ( " ^ //" , ptr ) or s :find (" ^<<" , ptr ) or s :find (" ^>>" , ptr ) then
496533 local repr = s :sub (ptr , ptr + 1 )
497534 tok = {type = " punctuation" , representation = repr , value = repr }
498535 ptr = ptr +# repr
@@ -1100,17 +1137,18 @@ function metaFuncs.newToken(tokType, ...)
11001137 numberFormat = numberFormat or " auto"
11011138
11021139 -- Some of these are technically multiple other tokens. We could trigger an error but ehhh...
1140+ -- @Incomplete: Hexadecimal floats.
11031141 local numStr
11041142 = n ~= n and " 0/0"
11051143 or n == math.huge and " math.huge"
1106- or n == - math.huge and " -math.huge"
1144+ or n == - math.huge and " -math.huge" -- The space prevents an accidental comment if a "-" is right before.
11071145 or numberFormat == " auto" and tostring (n )
11081146 or numberFormat == " integer" and F (" %d" , n )
11091147 or numberFormat == " float" and F (" %f" , n ):gsub (" (%d)0+$" , " %1" )
11101148 or numberFormat == " scientific" and F (" %e" , n ):gsub (" (%d)0+e" , " %1e" ):gsub (" 0+(%d+)$" , " %1" )
11111149 or numberFormat == " SCIENTIFIC" and F (" %E" , n ):gsub (" (%d)0+E" , " %1E" ):gsub (" 0+(%d+)$" , " %1" )
1112- or numberFormat == " hexadecimal" and F (" 0x%x" , n )
1113- or numberFormat == " HEXADECIMAL" and F (" 0x%X" , n )
1150+ or numberFormat == " hexadecimal" and ( n == math.floor ( n ) and F (" 0x%x" , n ) or error ( " Hexadecimal floats not supported yet. " ) )
1151+ or numberFormat == " HEXADECIMAL" and ( n == math.floor ( n ) and F (" 0x%X" , n ) or error ( " Hexadecimal floats not supported yet. " ) )
11141152 or error (F (" Invalid number format '%s'." , numberFormat ))
11151153
11161154 return {type = " number" , representation = numStr , value = n }
0 commit comments