@@ -318,10 +318,10 @@ function errorf(sOrLevel, ...)
318
318
end
319
319
end
320
320
321
- function errorLine (err )
322
- if type (err ) ~= " string" then error (err ) end
323
- error (" \0 " .. err , 0 ) -- The 0 tells our own error handler not to print the traceback.
324
- end
321
+ -- function errorLine(err) -- Unused.
322
+ -- if type(err) ~= "string" then error(err) end
323
+ -- error("\0"..err, 0) -- The 0 tells our own error handler not to print the traceback.
324
+ -- end
325
325
function errorfLine (s , ...)
326
326
errorf (0 , " \0 " .. s , ... ) -- The 0 tells our own error handler not to print the traceback.
327
327
end
366
366
local linePre2End = findEndOfLine (contents , linePre2Start - 1 )
367
367
-- printfError("pos %d | lines %d..%d, %d..%d, %d..%d", pos, linePre2Start,linePre2End+1, linePre1Start,linePre1End+1, lineStart,lineEnd+1) -- DEBUG
368
368
369
- errorfLine ( " \0 %s:%d: [%s] %s\n >\n %s%s%s>-%s^" ,
370
- path , ln , agent , s ,
369
+ errorOnLine ( path , ln , agent , " %s\n >\n %s%s%s>-%s^" ,
370
+ s ,
371
371
(linePre2Start < linePre1Start and linePre2Start <= linePre2End ) and F (" > %s\n " , (contents :sub (linePre2Start , linePre2End ):gsub (" \t " , " " ))) or " " ,
372
372
(linePre1Start < lineStart and linePre1Start <= linePre1End ) and F (" > %s\n " , (contents :sub (linePre1Start , linePre1End ):gsub (" \t " , " " ))) or " " ,
373
373
( lineStart <= lineEnd ) and F (" > %s\n " , (contents :sub (lineStart , lineEnd ):gsub (" \t " , " " ))) or " >\n " ,
374
- (" -" ):rep (pos - lineStart + 3 * countSubString (contents , lineStart , lineEnd , " \t " , true )),
375
- nil
374
+ (" -" ):rep (pos - lineStart + 3 * countSubString (contents , lineStart , lineEnd , " \t " , true ))
376
375
)
377
376
end
378
377
end
@@ -569,9 +568,9 @@ function _tokenize(s, path, allowPpTokens, allowBacktickStrings, allowJitSyntax)
569
568
570
569
if tok .long then
571
570
-- Check for nesting of [[...]], which is depricated in Lua.
572
- local mainChunk , err = loadLuaString (" --" .. tok .representation , " @" )
571
+ local chunk , err = loadLuaString (" --" .. tok .representation , " @" )
573
572
574
- if not mainChunk then
573
+ if not chunk then
575
574
local lnInString , luaErr = err :match ' ^:(%d+): (.*)'
576
575
if luaErr then
577
576
errorOnLine (path , getLineNumber (s , reprStart )+ tonumber (lnInString )- 1 , " Tokenizer" , " Malformed long comment. (%s)" , luaErr )
@@ -1149,12 +1148,12 @@ if IS_LUA_52_OR_LATER then
1149
1148
end
1150
1149
else
1151
1150
function loadLuaString (lua , chunkName , env )
1152
- local mainChunk , err = loadstring (lua , chunkName )
1153
- if not mainChunk then return nil , err end
1151
+ local chunk , err = loadstring (lua , chunkName )
1152
+ if not chunk then return nil , err end
1154
1153
1155
- if env then setfenv (mainChunk , env ) end
1154
+ if env then setfenv (chunk , env ) end
1156
1155
1157
- return mainChunk
1156
+ return chunk
1158
1157
end
1159
1158
end
1160
1159
@@ -1164,12 +1163,12 @@ if IS_LUA_52_OR_LATER then
1164
1163
end
1165
1164
else
1166
1165
function loadLuaFile (path , env )
1167
- local mainChunk , err = loadfile (path )
1168
- if not mainChunk then return nil , err end
1166
+ local chunk , err = loadfile (path )
1167
+ if not chunk then return nil , err end
1169
1168
1170
- if env then setfenv (mainChunk , env ) end
1169
+ if env then setfenv (chunk , env ) end
1171
1170
1172
- return mainChunk
1171
+ return chunk
1173
1172
end
1174
1173
end
1175
1174
@@ -1214,15 +1213,21 @@ end
1214
1213
1215
1214
1216
1215
1217
- -- getRelativeLocationText( tokenOfInterest, otherToken )
1218
- -- getRelativeLocationText( tokenOfInterest, otherFilename, otherLineNumber )
1216
+ -- text = getRelativeLocationText( tokenOfInterest, otherToken )
1217
+ -- text = getRelativeLocationText( tokenOfInterest, otherFilename, otherLineNumber )
1219
1218
function getRelativeLocationText (tokOfInterest , otherFilename , otherLn )
1220
1219
if type (otherFilename ) == " table" then
1221
1220
return getRelativeLocationText (tokOfInterest , otherFilename .file , otherFilename .line )
1222
1221
end
1223
1222
1224
- if tokOfInterest .file ~= otherFilename then return F (" at %s:%d" , tokOfInterest .file , tokOfInterest .line ) end
1225
- if tokOfInterest .line ~= otherLn then return F (" on line %d" , tokOfInterest .line ) end
1223
+ if not (tokOfInterest .file and tokOfInterest .line ) then
1224
+ return " at <UnknownLocation>"
1225
+ end
1226
+
1227
+ if tokOfInterest .file ~= otherFilename then return F (" at %s:%d" , tokOfInterest .file , tokOfInterest .line ) end
1228
+ if tokOfInterest .line + 1 == otherLn then return F (" on the previous line" ) end
1229
+ if tokOfInterest .line - 1 == otherLn then return F (" on the next line" ) end
1230
+ if tokOfInterest .line ~= otherLn then return F (" on line %d" , tokOfInterest .line ) end
1226
1231
return " on the same line"
1227
1232
end
1228
1233
@@ -1357,11 +1362,11 @@ metaFuncs.pack = pack
1357
1362
function metaFuncs .run (path , ...)
1358
1363
assertarg (1 , path , " string" )
1359
1364
1360
- local mainChunk , err = loadLuaFile (path , metaEnv )
1361
- if not mainChunk then errorLine (err ) end
1365
+ local main_chunk , err = loadLuaFile (path , metaEnv )
1366
+ if not main_chunk then error (err , 0 ) end
1362
1367
1363
1368
-- We want multiple return values while avoiding a tail call to preserve stack info.
1364
- local returnValues = pack (mainChunk (... ))
1369
+ local returnValues = pack (main_chunk (... ))
1365
1370
return unpack (returnValues , 1 , returnValues .n )
1366
1371
end
1367
1372
@@ -1964,7 +1969,7 @@ local function doLateExpansions(tokensToExpand, fileBuffers, params, stats)
1964
1969
errorAtToken (fileBuffers , tableStartTok , nil , " Macro" , " Syntax error: Could not find end of table constructor before EOF." )
1965
1970
1966
1971
elseif tok .type :find " ^pp_" then
1967
- errorAtToken (fileBuffers , tok , nil , " Macro" , " Preprocessor code not supported in macros. (Macro starting %s)" , getRelativeLocationText (ppKeywordTok , tok ))
1972
+ errorAtToken (fileBuffers , tok , nil , " Macro" , " Preprocessor code not supported in macros. (Macro starts %s)" , getRelativeLocationText (ppKeywordTok , tok ))
1968
1973
1969
1974
elseif bracketDepth == 1 and isToken (tok , " punctuation" , " }" ) then
1970
1975
tableInsert (argTokens , table.remove (tokenStack ))
@@ -2042,7 +2047,7 @@ local function doLateExpansions(tokensToExpand, fileBuffers, params, stats)
2042
2047
errorAtToken (fileBuffers , parensStartTok , nil , " Macro" , " Syntax error: Could not find end of argument list before EOF." )
2043
2048
2044
2049
elseif tok .type :find " ^pp_" then
2045
- errorAtToken (fileBuffers , tok , nil , " Macro" , " Preprocessor code not supported in macros. (Macro starting %s)" , getRelativeLocationText (ppKeywordTok , tok ))
2050
+ errorAtToken (fileBuffers , tok , nil , " Macro" , " Preprocessor code not supported in macros. (Macro starts %s)" , getRelativeLocationText (ppKeywordTok , tok ))
2046
2051
2047
2052
elseif not depthStack [1 ] and (isToken (tok , " punctuation" , " ," ) or isToken (tok , " punctuation" , " )" )) then
2048
2053
break
@@ -2166,7 +2171,7 @@ local function _processFileOrString(params, isFile)
2166
2171
luaUnprocessed , err = getFileContents (pathIn , true )
2167
2172
2168
2173
if not luaUnprocessed then
2169
- errorfLine (" Could not read file '%s'. (%s)" , pathIn , err )
2174
+ errorf (" Could not read file '%s'. (%s)" , pathIn , err )
2170
2175
end
2171
2176
2172
2177
currentPathIn = params .pathIn
@@ -2364,14 +2369,19 @@ local function _processFileOrString(params, isFile)
2364
2369
-- Note: Can be multiple actual lines if extended.
2365
2370
local function processMetaLine (isDual , metaStartTok )
2366
2371
local metaLineIndexStart = tokenIndex
2367
- local bracketBalance = 0
2372
+ local depthStack = {}
2368
2373
2369
2374
while true do
2370
2375
local tok = tokens [tokenIndex ]
2371
2376
2372
2377
if not tok then
2373
- if bracketBalance ~= 0 then
2374
- errorAtToken (fileBuffers , metaStartTok , nil , " Parser" , " Preprocessor line has unbalanced brackets. (Reached EOF.)" )
2378
+ if depthStack [1 ] then
2379
+ tok = depthStack [# depthStack ].startToken
2380
+ errorAtToken (
2381
+ fileBuffers , tok , nil , " Parser" ,
2382
+ " Syntax error: Could not find matching bracket before EOF. (Preprocessor line starts %s)" ,
2383
+ getRelativeLocationText (metaStartTok , tok )
2384
+ )
2375
2385
end
2376
2386
if isDual then
2377
2387
outputFinalDualValueStatement (metaLineIndexStart , tokenIndex - 1 )
@@ -2381,7 +2391,7 @@ local function _processFileOrString(params, isFile)
2381
2391
2382
2392
local tokType = tok .type
2383
2393
if
2384
- bracketBalance == 0 and (
2394
+ not depthStack [ 1 ] and (
2385
2395
(tokType == " whitespace" and tok .value :find (" \n " , 1 , true )) or
2386
2396
(tokType == " comment" and not tok .long )
2387
2397
)
@@ -2409,7 +2419,7 @@ local function _processFileOrString(params, isFile)
2409
2419
tableInsert (tokensToProcess , tokExtra )
2410
2420
2411
2421
elseif tokType == " comment" and not tok .long then
2412
- local tokExtra = {type = " whitespace" , representation = " \n " , value = " \n " , line = tok . line , position = tok . position }
2422
+ local tokExtra = newTokenAt ( {type = " whitespace" , representation = " \n " , value = " \n " }, tok )
2413
2423
tableInsert (tokensToProcess , tokExtra )
2414
2424
end
2415
2425
@@ -2421,17 +2431,29 @@ local function _processFileOrString(params, isFile)
2421
2431
else
2422
2432
tableInsert (metaParts , tok .representation )
2423
2433
2424
- if tokType == " punctuation" and isAny (tok .value , " (" ," {" ," [" ) then
2425
- bracketBalance = bracketBalance + 1
2426
- elseif tokType == " punctuation" and isAny (tok .value , " )" ," }" ," ]" ) then
2427
- bracketBalance = bracketBalance - 1
2428
- if bracketBalance < 0 then
2434
+ if isToken (tok , " punctuation" , " (" ) then
2435
+ tableInsert (depthStack , {startToken = tok , [1 ]= " punctuation" , [2 ]= " )" })
2436
+ elseif isToken (tok , " punctuation" , " [" ) then
2437
+ tableInsert (depthStack , {startToken = tok , [1 ]= " punctuation" , [2 ]= " ]" })
2438
+ elseif isToken (tok , " punctuation" , " {" ) then
2439
+ tableInsert (depthStack , {startToken = tok , [1 ]= " punctuation" , [2 ]= " }" })
2440
+
2441
+ elseif
2442
+ isToken (tok , " punctuation" , " )" ) or
2443
+ isToken (tok , " punctuation" , " ]" ) or
2444
+ isToken (tok , " punctuation" , " }" )
2445
+ then
2446
+ if not depthStack [1 ] then
2447
+ errorAtToken (fileBuffers , tok , nil , " Parser" , " Unexpected '%s'." , tok .value )
2448
+ elseif not isToken (tok , unpack (depthStack [# depthStack ])) then
2449
+ local startTok = depthStack [# depthStack ].startToken
2429
2450
errorAtToken (
2430
2451
fileBuffers , tok , nil , " Parser" ,
2431
- " Unexpected '%s'. Preprocessor line (starting %s) has unbalanced brackets. " ,
2432
- tok .value , getRelativeLocationText (metaStartTok , tok )
2452
+ " Expected '%s' (to close '%s' %s) but got '%s'. (Preprocessor line starts %s) " ,
2453
+ depthStack [ # depthStack ][ 2 ], startTok . value , getRelativeLocationText ( startTok , tok ), tok .value , getRelativeLocationText (metaStartTok , tok )
2433
2454
)
2434
2455
end
2456
+ table.remove (depthStack )
2435
2457
end
2436
2458
end
2437
2459
@@ -2445,40 +2467,39 @@ local function _processFileOrString(params, isFile)
2445
2467
2446
2468
local tokType = tok .type
2447
2469
2448
- -- Meta block or start of meta line .
2470
+ -- Metaprogram .
2449
2471
---- ----------------------------
2450
2472
2451
- -- Meta block. Examples:
2473
+ -- Preprocessor block. Examples:
2452
2474
-- !( function sum(a, b) return a+b; end )
2453
2475
-- local text = !("Hello, mr. "..getName())
2454
2476
-- _G.!!("myRandomGlobal"..math.random(5)) = 99
2455
2477
if tokType == " pp_entry" and isTokenAndNotNil (tokens [tokenIndex + 1 ], " punctuation" , " (" ) then
2456
- local startToken = tok
2457
- local doOutputLua = startToken .double
2458
- tokenIndex = tokenIndex + 2 -- Jump past "!(" or "!!(".
2478
+ local startTok = tok
2479
+ local startIndex = tokenIndex
2480
+ local doOutputLua = startTok .double
2481
+ tokenIndex = tokenIndex + 2 -- Eat "!(" or "!!("
2459
2482
2460
2483
flushTokensToProcess ()
2461
2484
2462
2485
local tokensInBlock = {}
2463
- local depth = 1
2486
+ local parensDepth = 1 -- @Incomplete: Use depthStack like in other places.
2464
2487
2465
2488
while true do
2466
2489
tok = tokens [tokenIndex ]
2467
- if not tok then
2468
- errorAtToken (fileBuffers , startToken , nil , " Parser" , " Missing end of preprocessor block." )
2469
- end
2470
2490
2471
- tokType = tok .type
2491
+ if not tok then
2492
+ errorAtToken (fileBuffers , startTok , nil , " Parser" , " Missing end of preprocessor block." )
2472
2493
2473
- if tokType == " punctuation" and tok . value == " (" then
2474
- depth = depth + 1
2494
+ elseif isToken ( tok , " punctuation" , " (" ) then
2495
+ parensDepth = parensDepth + 1
2475
2496
2476
- elseif tokType == " punctuation" and tok . value == " )" then
2477
- depth = depth - 1
2478
- if depth == 0 then break end
2497
+ elseif isToken ( tok , " punctuation" , " )" ) then
2498
+ parensDepth = parensDepth - 1
2499
+ if parensDepth == 0 then break end
2479
2500
2480
- elseif tokType == " pp_entry " then
2481
- errorAtToken (fileBuffers , tok , nil , " Parser" , " Preprocessor token inside metaprogram (starting %s)." , getRelativeLocationText (startToken , tok ))
2501
+ elseif tok . type : find " ^pp_ " then
2502
+ errorAtToken (fileBuffers , tok , nil , " Parser" , " Preprocessor token inside metaprogram (starting %s)." , getRelativeLocationText (startTok , tok ))
2482
2503
end
2483
2504
2484
2505
tableInsert (tokensInBlock , tok )
@@ -2494,25 +2515,22 @@ local function _processFileOrString(params, isFile)
2494
2515
2495
2516
elseif doOutputLua then
2496
2517
-- We could do something other than error here. Room for more functionality.
2497
- errorAtToken (
2498
- fileBuffers , startToken , startToken .position + 3 , " Parser" ,
2499
- " Preprocessor block variant does not contain a valid expression that results in a value."
2500
- )
2518
+ errorAfterToken (fileBuffers , tokens [startIndex + 1 ], " Parser" , " Preprocessor block does not contain a valid value expression." )
2501
2519
2502
2520
else
2503
2521
tableInsert (metaParts , metaBlock )
2504
2522
tableInsert (metaParts , " \n " )
2505
2523
end
2506
2524
2507
- -- Meta line. Example:
2525
+ -- Preprocessor line. Example:
2508
2526
-- !for i = 1, 3 do
2509
- -- print("Marco? Polo!")
2527
+ -- print("Marco? Polo!")
2510
2528
-- !end
2511
2529
--
2512
- -- Extended meta line. Example:
2530
+ -- Preprocessor line, extended . Example:
2513
2531
-- !newClass{
2514
- -- name = "Entity",
2515
- -- props = {x=0, y=0},
2532
+ -- name = "Entity",
2533
+ -- props = {x=0, y=0},
2516
2534
-- }
2517
2535
--
2518
2536
-- Dual code. Example:
@@ -2525,7 +2543,7 @@ local function _processFileOrString(params, isFile)
2525
2543
tokenIndex = tokenIndex + 1
2526
2544
processMetaLine (tok .double , tok )
2527
2545
2528
- -- Non-meta .
2546
+ -- Normal code .
2529
2547
---- ----------------------------
2530
2548
else
2531
2549
tableInsert (tokensToProcess , tok )
@@ -2558,16 +2576,16 @@ local function _processFileOrString(params, isFile)
2558
2576
file :close ()
2559
2577
end
2560
2578
2561
- local mainChunk , err = loadLuaString (luaMeta , ( params . pathMeta and " @" or " " ) .. metaPathForErrorMessages , metaEnv )
2562
- if not mainChunk then
2579
+ local main_chunk , err = loadLuaString (luaMeta , " @" .. metaPathForErrorMessages , metaEnv )
2580
+ if not main_chunk then
2563
2581
local ln , _err = err :match ' ^.-:(%d+): (.*)'
2564
2582
errorOnLine (metaPathForErrorMessages , (tonumber (ln ) or 0 ), nil , " %s" , (_err or err ))
2565
2583
end
2566
2584
2567
2585
if params .onBeforeMeta then params .onBeforeMeta () end
2568
2586
2569
2587
isRunningMeta = true
2570
- mainChunk () -- Note: The caller should clean up metaPathForErrorMessages etc. on error.
2588
+ main_chunk () -- Note: Our caller should clean up metaPathForErrorMessages etc. on error.
2571
2589
isRunningMeta = false
2572
2590
2573
2591
if not isDebug and params .pathMeta then
@@ -2591,7 +2609,7 @@ local function _processFileOrString(params, isFile)
2591
2609
if type (luaModified ) == " string" then
2592
2610
lua = luaModified
2593
2611
elseif luaModified ~= nil then
2594
- errorfLine (" onAfterMeta() did not return a string. (Got %s)" , type (luaModified ))
2612
+ errorf (" onAfterMeta() did not return a string. (Got %s)" , type (luaModified ))
2595
2613
end
2596
2614
end
2597
2615
@@ -2609,10 +2627,10 @@ local function _processFileOrString(params, isFile)
2609
2627
2610
2628
-- Check if the output is valid Lua.
2611
2629
if params .validate ~= false then
2612
- local luaToCheck = lua :gsub (" ^#![^\n ]*" , " " )
2613
- local mainChunk , err = loadLuaString (luaToCheck , ( isFile and params . pathMeta and " @" or " " ) .. pathOut )
2630
+ local luaToCheck = lua :gsub (" ^#![^\n ]*" , " " )
2631
+ local chunk , err = loadLuaString (luaToCheck , " @" .. pathOut )
2614
2632
2615
- if not mainChunk then
2633
+ if not chunk then
2616
2634
local ln , _err = err :match ' ^.-:(%d+): (.*)'
2617
2635
errorOnLine (pathOut , (tonumber (ln ) or 0 ), nil , " %s" , (_err or err ))
2618
2636
end
0 commit comments