2626 - getCurrentPathIn, getCurrentPathOut
2727 - getOutputSoFar, getOutputSizeSoFar, getCurrentLineNumberInOutput
2828 - outputValue, outputLua, outputLuaTemplate
29+ - startInterceptingOutput, stopInterceptingOutput
2930 Search this file for 'EnvironmentTable' for more info.
3031
3132 Exported stuff from the library:
@@ -188,7 +189,8 @@ local isRunningMeta = false
188189local currentPathIn = " "
189190local currentPathOut = " "
190191local metaPathForErrorMessages = " "
191- local outputFromMeta = nil
192+ local outputFromMetaStack = nil
193+ local outputFromMeta = nil -- Top item in outputFromMetaStack.
192194local canOutputNil = true
193195local fastStrings = false
194196
@@ -1321,6 +1323,8 @@ end
13211323
13221324
13231325-- :EnvironmentTable
1326+ ---- ------------------------------------------------------------
1327+
13241328metaEnv = copyTable (_G , true ) -- Include all standard Lua stuff.
13251329metaEnv ._G = metaEnv
13261330
@@ -1485,7 +1489,7 @@ end
14851489-- Raises an error if no file or string is being processed.
14861490function metaFuncs .getOutputSoFar (asTable )
14871491 errorIfNotRunningMeta (2 )
1488- return asTable and copyArray (outputFromMeta ) or table.concat (outputFromMeta )
1492+ return asTable and copyArray (outputFromMetaStack [ 1 ] ) or table.concat (outputFromMetaStack [ 1 ]) -- Should there be a way to get the contents of outputFromMeta etc.? :GetMoreOutputFromStack
14891493end
14901494
14911495-- getOutputSizeSoFar()
@@ -1497,7 +1501,7 @@ function metaFuncs.getOutputSizeSoFar()
14971501
14981502 local size = 0
14991503
1500- for _ , lua in ipairs (outputFromMeta ) do
1504+ for _ , lua in ipairs (outputFromMetaStack [ 1 ] ) do -- :GetMoreOutputFromStack
15011505 size = size + # lua
15021506 end
15031507
@@ -1512,7 +1516,7 @@ function metaFuncs.getCurrentLineNumberInOutput()
15121516
15131517 local ln = 1
15141518
1515- for _ , lua in ipairs (outputFromMeta ) do
1519+ for _ , lua in ipairs (outputFromMetaStack [ 1 ] ) do -- :GetMoreOutputFromStack
15161520 ln = ln + countString (lua , " \n " , true )
15171521 end
15181522
@@ -1825,9 +1829,34 @@ function metaFuncs.concatTokens(tokens)
18251829 return _concatTokens (tokens , nil , false , nil , nil )
18261830end
18271831
1832+ -- startInterceptingOutput()
1833+ -- startInterceptingOutput( )
1834+ -- Start intercepting output until stopInterceptingOutput() is called.
1835+ -- The function can be called multiple times to intercept interceptions.
1836+ function metaFuncs .startInterceptingOutput ()
1837+ errorIfNotRunningMeta (2 )
1838+
1839+ outputFromMeta = {}
1840+ tableInsert (outputFromMetaStack , outputFromMeta )
1841+ end
1842+
1843+ -- stopInterceptingOutput()
1844+ -- luaString = stopInterceptingOutput( )
1845+ -- Stop intercepting output.
1846+ function metaFuncs .stopInterceptingOutput ()
1847+ errorIfNotRunningMeta (2 )
1848+
1849+ local interceptedLua = tableRemove (outputFromMetaStack )
1850+ outputFromMeta = outputFromMetaStack [# outputFromMetaStack ] or error (" Called stopInterceptingOutput() before calling startInterceptingOutput()" , 2 )
1851+
1852+ return table.concat (interceptedLua )
1853+ end
1854+
18281855-- Extra stuff used by the command line program:
18291856metaFuncs .tryToFormatError = tryToFormatError
18301857
1858+ ---- ------------------------------------------------------------
1859+
18311860
18321861
18331862for k , v in pairs (metaFuncs ) do metaEnv [k ] = v end
@@ -1845,6 +1874,23 @@ function metaEnv.__ASSERTLUA(lua)
18451874 return lua
18461875end
18471876
1877+ local function finalizeMacro (lua )
1878+ if lua == nil then
1879+ return (metaFuncs .stopInterceptingOutput ())
1880+ elseif type (lua ) ~= " string" then
1881+ error (" [Macro] Value is not Lua code." , 2 )
1882+ elseif outputFromMeta [1 ] then
1883+ error (" [Macro] Got Lua code from both value expression and outputLua(). Only one method may be used." , 2 ) -- It's also possible interception calls are unbalanced.
1884+ else
1885+ metaFuncs .stopInterceptingOutput () -- Returns "" because nothing was outputted.
1886+ return lua
1887+ end
1888+ end
1889+ function metaEnv .__MACRO ()
1890+ metaFuncs .startInterceptingOutput ()
1891+ return finalizeMacro
1892+ end
1893+
18481894function metaEnv .__EVALSYMBOL (v )
18491895 if type (v ) == " function" then
18501896 v = v ()
@@ -2152,13 +2198,18 @@ end
21522198
21532199local function expandMacro (tokens , fileBuffers , tokenStack , macroStartTok , isNested )
21542200 -- @Robustness: Make sure key tokens came from the same source file.
2201+
21552202 -- Add '!!(' for start of preprocessor block.
2156- if isNested then
2157- tableInsert (tokens , newTokenAt ({type = " identifier" , value = " __ASSERTLUA" , representation = " __ASSERTLUA" }, macroStartTok ))
2158- else
2159- tableInsert (tokens , newTokenAt ({type = " pp_entry" , value = " !!" , representation = " !!" , double = true }, macroStartTok ))
2203+ if not isNested then
2204+ tableInsert (tokens , newTokenAt ({type = " pp_entry" , value = " !!" , representation = " !!" , double = true }, macroStartTok ))
2205+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, macroStartTok ))
21602206 end
2161- tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, macroStartTok ))
2207+
2208+ -- Start macro wrapper.
2209+ tableInsert (tokens , newTokenAt ({type = " identifier" , value = " __MACRO" , representation = " __MACRO" }, macroStartTok ))
2210+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, macroStartTok ))
2211+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, macroStartTok ))
2212+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, macroStartTok ))
21622213
21632214 --
21642215 -- Callee.
@@ -2496,8 +2547,13 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
24962547 -- End.
24972548 --
24982549
2499- -- Add ')' for end of preprocessor block .
2550+ -- End macro wrapper .
25002551 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [# tokens ]))
2552+
2553+ -- Add ')' for end of preprocessor block.
2554+ if not isNested then
2555+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [# tokens ]))
2556+ end
25012557end
25022558
25032559local function doLateExpansionsMacros (tokensToExpand , fileBuffers , params , stats )
@@ -2969,6 +3025,7 @@ local function _processFileOrString(params, isFile)
29693025
29703026 metaPathForErrorMessages = params .pathMeta or " <meta>"
29713027 outputFromMeta = {}
3028+ outputFromMetaStack = {outputFromMeta }
29723029 canOutputNil = params .canOutputNil ~= false
29733030 fastStrings = params .fastStrings
29743031
@@ -2994,6 +3051,10 @@ local function _processFileOrString(params, isFile)
29943051 os.remove (params .pathMeta )
29953052 end
29963053
3054+ if outputFromMetaStack [2 ] then
3055+ error (" Called startInterceptingOutput() more times than stopInterceptingOutput()." )
3056+ end
3057+
29973058 local lua = table.concat (outputFromMeta )
29983059 --[[ :PrintCode
29993060 print("=OUTPUT=============================")
@@ -3002,6 +3063,7 @@ local function _processFileOrString(params, isFile)
30023063 --]]
30033064
30043065 metaPathForErrorMessages = " "
3066+ outputFromMetaStack = nil
30053067 outputFromMeta = nil
30063068 canOutputNil = true
30073069
@@ -3103,6 +3165,7 @@ local function processFileOrString(params, isFile)
31033165 currentPathIn = " "
31043166 currentPathOut = " "
31053167 metaPathForErrorMessages = " "
3168+ outputFromMetaStack = nil
31063169 outputFromMeta = nil
31073170 canOutputNil = true
31083171 fastStrings = false
0 commit comments