@@ -318,10 +318,10 @@ function errorf(sOrLevel, ...)
318318 end
319319end
320320
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
325325function errorfLine (s , ...)
326326 errorf (0 , " \0 " .. s , ... ) -- The 0 tells our own error handler not to print the traceback.
327327end
366366 local linePre2End = findEndOfLine (contents , linePre2Start - 1 )
367367 -- printfError("pos %d | lines %d..%d, %d..%d, %d..%d", pos, linePre2Start,linePre2End+1, linePre1Start,linePre1End+1, lineStart,lineEnd+1) -- DEBUG
368368
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 ,
371371 (linePre2Start < linePre1Start and linePre2Start <= linePre2End ) and F (" > %s\n " , (contents :sub (linePre2Start , linePre2End ):gsub (" \t " , " " ))) or " " ,
372372 (linePre1Start < lineStart and linePre1Start <= linePre1End ) and F (" > %s\n " , (contents :sub (linePre1Start , linePre1End ):gsub (" \t " , " " ))) or " " ,
373373 ( 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 ))
376375 )
377376 end
378377end
@@ -569,9 +568,9 @@ function _tokenize(s, path, allowPpTokens, allowBacktickStrings, allowJitSyntax)
569568
570569 if tok .long then
571570 -- Check for nesting of [[...]], which is depricated in Lua.
572- local mainChunk , err = loadLuaString (" --" .. tok .representation , " @" )
571+ local chunk , err = loadLuaString (" --" .. tok .representation , " @" )
573572
574- if not mainChunk then
573+ if not chunk then
575574 local lnInString , luaErr = err :match ' ^:(%d+): (.*)'
576575 if luaErr then
577576 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
11491148 end
11501149else
11511150 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
11541153
1155- if env then setfenv (mainChunk , env ) end
1154+ if env then setfenv (chunk , env ) end
11561155
1157- return mainChunk
1156+ return chunk
11581157 end
11591158end
11601159
@@ -1164,12 +1163,12 @@ if IS_LUA_52_OR_LATER then
11641163 end
11651164else
11661165 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
11691168
1170- if env then setfenv (mainChunk , env ) end
1169+ if env then setfenv (chunk , env ) end
11711170
1172- return mainChunk
1171+ return chunk
11731172 end
11741173end
11751174
@@ -1214,15 +1213,21 @@ end
12141213
12151214
12161215
1217- -- getRelativeLocationText( tokenOfInterest, otherToken )
1218- -- getRelativeLocationText( tokenOfInterest, otherFilename, otherLineNumber )
1216+ -- text = getRelativeLocationText( tokenOfInterest, otherToken )
1217+ -- text = getRelativeLocationText( tokenOfInterest, otherFilename, otherLineNumber )
12191218function getRelativeLocationText (tokOfInterest , otherFilename , otherLn )
12201219 if type (otherFilename ) == " table" then
12211220 return getRelativeLocationText (tokOfInterest , otherFilename .file , otherFilename .line )
12221221 end
12231222
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
12261231 return " on the same line"
12271232end
12281233
@@ -1357,11 +1362,11 @@ metaFuncs.pack = pack
13571362function metaFuncs .run (path , ...)
13581363 assertarg (1 , path , " string" )
13591364
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
13621367
13631368 -- 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 (... ))
13651370 return unpack (returnValues , 1 , returnValues .n )
13661371end
13671372
@@ -1964,7 +1969,7 @@ local function doLateExpansions(tokensToExpand, fileBuffers, params, stats)
19641969 errorAtToken (fileBuffers , tableStartTok , nil , " Macro" , " Syntax error: Could not find end of table constructor before EOF." )
19651970
19661971 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 ))
19681973
19691974 elseif bracketDepth == 1 and isToken (tok , " punctuation" , " }" ) then
19701975 tableInsert (argTokens , table.remove (tokenStack ))
@@ -2042,7 +2047,7 @@ local function doLateExpansions(tokensToExpand, fileBuffers, params, stats)
20422047 errorAtToken (fileBuffers , parensStartTok , nil , " Macro" , " Syntax error: Could not find end of argument list before EOF." )
20432048
20442049 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 ))
20462051
20472052 elseif not depthStack [1 ] and (isToken (tok , " punctuation" , " ," ) or isToken (tok , " punctuation" , " )" )) then
20482053 break
@@ -2166,7 +2171,7 @@ local function _processFileOrString(params, isFile)
21662171 luaUnprocessed , err = getFileContents (pathIn , true )
21672172
21682173 if not luaUnprocessed then
2169- errorfLine (" Could not read file '%s'. (%s)" , pathIn , err )
2174+ errorf (" Could not read file '%s'. (%s)" , pathIn , err )
21702175 end
21712176
21722177 currentPathIn = params .pathIn
@@ -2364,14 +2369,19 @@ local function _processFileOrString(params, isFile)
23642369 -- Note: Can be multiple actual lines if extended.
23652370 local function processMetaLine (isDual , metaStartTok )
23662371 local metaLineIndexStart = tokenIndex
2367- local bracketBalance = 0
2372+ local depthStack = {}
23682373
23692374 while true do
23702375 local tok = tokens [tokenIndex ]
23712376
23722377 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+ )
23752385 end
23762386 if isDual then
23772387 outputFinalDualValueStatement (metaLineIndexStart , tokenIndex - 1 )
@@ -2381,7 +2391,7 @@ local function _processFileOrString(params, isFile)
23812391
23822392 local tokType = tok .type
23832393 if
2384- bracketBalance == 0 and (
2394+ not depthStack [ 1 ] and (
23852395 (tokType == " whitespace" and tok .value :find (" \n " , 1 , true )) or
23862396 (tokType == " comment" and not tok .long )
23872397 )
@@ -2409,7 +2419,7 @@ local function _processFileOrString(params, isFile)
24092419 tableInsert (tokensToProcess , tokExtra )
24102420
24112421 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 )
24132423 tableInsert (tokensToProcess , tokExtra )
24142424 end
24152425
@@ -2421,17 +2431,29 @@ local function _processFileOrString(params, isFile)
24212431 else
24222432 tableInsert (metaParts , tok .representation )
24232433
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
24292450 errorAtToken (
24302451 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 )
24332454 )
24342455 end
2456+ table.remove (depthStack )
24352457 end
24362458 end
24372459
@@ -2445,40 +2467,39 @@ local function _processFileOrString(params, isFile)
24452467
24462468 local tokType = tok .type
24472469
2448- -- Meta block or start of meta line .
2470+ -- Metaprogram .
24492471 ---- ----------------------------
24502472
2451- -- Meta block. Examples:
2473+ -- Preprocessor block. Examples:
24522474 -- !( function sum(a, b) return a+b; end )
24532475 -- local text = !("Hello, mr. "..getName())
24542476 -- _G.!!("myRandomGlobal"..math.random(5)) = 99
24552477 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 "!!("
24592482
24602483 flushTokensToProcess ()
24612484
24622485 local tokensInBlock = {}
2463- local depth = 1
2486+ local parensDepth = 1 -- @Incomplete: Use depthStack like in other places.
24642487
24652488 while true do
24662489 tok = tokens [tokenIndex ]
2467- if not tok then
2468- errorAtToken (fileBuffers , startToken , nil , " Parser" , " Missing end of preprocessor block." )
2469- end
24702490
2471- tokType = tok .type
2491+ if not tok then
2492+ errorAtToken (fileBuffers , startTok , nil , " Parser" , " Missing end of preprocessor block." )
24722493
2473- if tokType == " punctuation" and tok . value == " (" then
2474- depth = depth + 1
2494+ elseif isToken ( tok , " punctuation" , " (" ) then
2495+ parensDepth = parensDepth + 1
24752496
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
24792500
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 ))
24822503 end
24832504
24842505 tableInsert (tokensInBlock , tok )
@@ -2494,25 +2515,22 @@ local function _processFileOrString(params, isFile)
24942515
24952516 elseif doOutputLua then
24962517 -- 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." )
25012519
25022520 else
25032521 tableInsert (metaParts , metaBlock )
25042522 tableInsert (metaParts , " \n " )
25052523 end
25062524
2507- -- Meta line. Example:
2525+ -- Preprocessor line. Example:
25082526 -- !for i = 1, 3 do
2509- -- print("Marco? Polo!")
2527+ -- print("Marco? Polo!")
25102528 -- !end
25112529 --
2512- -- Extended meta line. Example:
2530+ -- Preprocessor line, extended . Example:
25132531 -- !newClass{
2514- -- name = "Entity",
2515- -- props = {x=0, y=0},
2532+ -- name = "Entity",
2533+ -- props = {x=0, y=0},
25162534 -- }
25172535 --
25182536 -- Dual code. Example:
@@ -2525,7 +2543,7 @@ local function _processFileOrString(params, isFile)
25252543 tokenIndex = tokenIndex + 1
25262544 processMetaLine (tok .double , tok )
25272545
2528- -- Non-meta .
2546+ -- Normal code .
25292547 ---- ----------------------------
25302548 else
25312549 tableInsert (tokensToProcess , tok )
@@ -2558,16 +2576,16 @@ local function _processFileOrString(params, isFile)
25582576 file :close ()
25592577 end
25602578
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
25632581 local ln , _err = err :match ' ^.-:(%d+): (.*)'
25642582 errorOnLine (metaPathForErrorMessages , (tonumber (ln ) or 0 ), nil , " %s" , (_err or err ))
25652583 end
25662584
25672585 if params .onBeforeMeta then params .onBeforeMeta () end
25682586
25692587 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.
25712589 isRunningMeta = false
25722590
25732591 if not isDebug and params .pathMeta then
@@ -2591,7 +2609,7 @@ local function _processFileOrString(params, isFile)
25912609 if type (luaModified ) == " string" then
25922610 lua = luaModified
25932611 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 ))
25952613 end
25962614 end
25972615
@@ -2609,10 +2627,10 @@ local function _processFileOrString(params, isFile)
26092627
26102628 -- Check if the output is valid Lua.
26112629 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 )
26142632
2615- if not mainChunk then
2633+ if not chunk then
26162634 local ln , _err = err :match ' ^.-:(%d+): (.*)'
26172635 errorOnLine (pathOut , (tonumber (ln ) or 0 ), nil , " %s" , (_err or err ))
26182636 end
0 commit comments