@@ -1987,6 +1987,50 @@ local function insertTokensAsStringLiteral(tokens, tokensToConcat, locationTok)
19871987 return lua
19881988end
19891989
1990+ local function processPreprocessorBlockInMacro (tokens , fileBuffers , tokenStack , argNonPpTokens , locationTok , isFirstPart )
1991+ local ppEntryTok = tableRemove (tokenStack ) -- '!' or '!!'
1992+ assert (isToken (ppEntryTok , " pp_entry" ))
1993+
1994+ if not isFirstPart then
1995+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " .." , representation = " .." }, locationTok ))
1996+ end
1997+ if argNonPpTokens [1 ] then
1998+ insertTokensAsStringLiteral (tokens , argNonPpTokens , locationTok )
1999+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " .." , representation = " .." }, ppEntryTok ))
2000+ end
2001+
2002+ local ident = (ppEntryTok .value == " !" ) and " __TOLUA" or " __ASSERTLUA"
2003+ tableInsert (tokens , newTokenAt ({type = " identifier" , value = ident , representation = ident }, ppEntryTok ))
2004+ tableInsert (tokens , tableRemove (tokenStack )) -- '('
2005+ local exprStartTokIndex = # tokens
2006+
2007+ local parensDepth = 1
2008+
2009+ while true do
2010+ local tok = tableRemove (tokenStack ) -- anything
2011+ if not tok then
2012+ errorAtToken (fileBuffers , ppEntryTok , nil , " Parser" , " Missing end of preprocessor block." )
2013+ end
2014+ tableInsert (tokens , tok )
2015+
2016+ if isToken (tok , " punctuation" , " (" ) then
2017+ parensDepth = parensDepth + 1
2018+ elseif isToken (tok , " punctuation" , " )" ) then
2019+ parensDepth = parensDepth - 1
2020+ if parensDepth == 0 then break end
2021+ elseif tok .type :find " ^pp_" then
2022+ errorAtToken (fileBuffers , tok , nil , " Parser" , " Preprocessor token inside metaprogram (starting %s)." , getRelativeLocationText (ppEntryTok , tok ))
2023+ end
2024+ end
2025+
2026+ local chunk , err = loadLuaString (" return " .. _concatTokens (tokens , nil , false , exprStartTokIndex , nil ), " @" )
2027+ if not chunk then
2028+ errorAtToken (fileBuffers , tokens [exprStartTokIndex + 1 ], nil , " Macro" , " Syntax error: Invalid expression in preprocessor block." )
2029+ -- err = err:gsub("^:%d+: ", "")
2030+ -- errorAtToken(fileBuffers, tokens[exprStartTokIndex+1], nil, "Macro", "Syntax error: Invalid expression in preprocessor block. (%s)", err)
2031+ end
2032+ end
2033+
19902034local function doLateExpansionsMacros (tokensToExpand , fileBuffers , params , stats )
19912035 --
19922036 -- Expand expressions:
@@ -2053,59 +2097,75 @@ local function doLateExpansionsMacros(tokensToExpand, fileBuffers, params, stats
20532097 -- (Similar code as `@insert identifier()` below.)
20542098 --
20552099
2056- -- Add '!!(ident'.
2100+ -- Add '!!(ident( '.
20572101 tableInsert (tokens , newTokenAt ({type = " pp_entry" , value = " !!" , representation = " !!" , double = true }, ppKeywordTok ))
20582102 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, ppKeywordTok ))
20592103 tableInsert (tokens , identTok )
2104+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, identTok ))
20602105
20612106 -- Collect tokens for the table arg.
20622107 -- We're looking for the closing '}'.
2063- local tableStartTok = tokNext
2064- local argTokens = {tableStartTok }
2065- local bracketDepth = 1
2108+ local argNonPpStartTok = tokNext -- Used for location info.
2109+ local argNonPpTokens = {argNonPpStartTok }
2110+ local bracketDepth = 1
2111+ local isFirstPart = true
20662112
20672113 while true do
2068- tok = tokenStack [# tokenStack ]
2114+ local len = # tokenStack
2115+ tok = tokenStack [len ]
20692116
20702117 if not tok then
2071- errorAtToken (fileBuffers , tableStartTok , nil , " Macro" , " Syntax error: Could not find end of table constructor before EOF." )
2118+ errorAtToken (fileBuffers , argNonPpStartTok , nil , " Macro" , " Syntax error: Could not find end of table constructor before EOF." )
2119+
2120+ -- Preprocessor block in macro.
2121+ elseif tok .type == " pp_entry" and isTokenAndNotNil (tokenStack [len - 1 ], " punctuation" , " (" ) then
2122+ processPreprocessorBlockInMacro (tokens , fileBuffers , tokenStack , argNonPpTokens , argNonPpStartTok , isFirstPart )
20722123
2124+ argNonPpStartTok = tokenStack [# tokenStack ] -- Could be nil, but that should be fine I think.
2125+ argNonPpTokens = argNonPpTokens [1 ] and {} or argNonPpTokens
2126+ isFirstPart = false
2127+
2128+ -- Other preprocessor code in macro.
20732129 elseif tok .type :find " ^pp_" then
20742130 errorAtToken (fileBuffers , tok , nil , " Macro" , " Unsupported preprocessor code in macro. (Macro starts %s)" , getRelativeLocationText (ppKeywordTok , tok ))
20752131
2132+ -- End of table and argument.
20762133 elseif bracketDepth == 1 and isToken (tok , " punctuation" , " }" ) then
2077- tableInsert (argTokens , tableRemove (tokenStack )) -- '}'
2134+ tableInsert (argNonPpTokens , tableRemove (tokenStack )) -- '}'
20782135 break
20792136
2137+ -- Normal token.
20802138 else
20812139 if isToken (tok , " punctuation" , " {" ) then
20822140 bracketDepth = bracketDepth + 1
20832141 elseif isToken (tok , " punctuation" , " }" ) then
20842142 bracketDepth = bracketDepth - 1
20852143 end
2086- tableInsert (argTokens , tableRemove (tokenStack )) -- anything
2144+ tableInsert (argNonPpTokens , tableRemove (tokenStack )) -- anything
20872145 end
20882146 end
20892147
2090- local argStr = _concatTokens (argTokens , nil , false , nil , nil )
2148+ -- Add last part of argument value.
2149+ if argNonPpTokens [1 ] then
2150+ if not isFirstPart then
2151+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " .." , representation = " .." }, argNonPpStartTok ))
2152+ end
2153+ local argStr = insertTokensAsStringLiteral (tokens , argNonPpTokens , argNonPpStartTok )
2154+
2155+ if isFirstPart then
2156+ local chunk , err = loadLuaString (" return (" .. argStr .. " )" , " @" )
20912157
2092- local chunk , err = loadLuaString (" return " .. argStr , " @" )
2093- if not chunk then
2094- errorAtToken (fileBuffers , argTokens [1 ], nil , " Macro" , " Syntax error: Invalid table constructor expression." )
2095- -- err = err:gsub("^:%d+: ", "")
2096- -- errorAtToken(fileBuffers, argTokens[1], nil, "Macro", "Syntax error: Invalid table constructor expression. (%s)", err)
2158+ if not chunk then
2159+ errorAtToken (fileBuffers , argNonPpStartTok , nil , " Macro" , " Syntax error: Invalid table constructor expression." )
2160+ -- err = err:gsub("^:%d+: ", "")
2161+ -- errorAtToken(fileBuffers, argNonPpStartTok, nil, "Macro", "Syntax error: Invalid table constructor expression. (%s)", err)
2162+ end
2163+ end
20972164 end
20982165
2099- -- Add argument value.
2100- tableInsert (tokens , newTokenAt ({
2101- type = " string" ,
2102- value = argStr ,
2103- representation = F (" %q" , argStr ):gsub (" \n " , " n" ),
2104- long = false ,
2105- }, tableStartTok ))
2106-
2107- -- Add ')'.
2108- tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, ppKeywordTok ))
2166+ -- Add '))'.
2167+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [# tokens ]))
2168+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [# tokens ]))
21092169
21102170 -- @insert identifier ( argument1, ... )
21112171 else
@@ -2138,10 +2198,10 @@ local function doLateExpansionsMacros(tokensToExpand, fileBuffers, params, stats
21382198
21392199 -- Collect tokens for this arg.
21402200 -- We're looking for the next comma at depth 0 or closing ')'.
2141- local argNonPpStartTok = tokenStack [# tokenStack ]
2201+ local argNonPpStartTok = tokenStack [# tokenStack ] -- Used for location info.
21422202 local argNonPpTokens = {}
21432203 local depthStack = {}
2144- local insertedPpEntry = false
2204+ local isFirstPart = true
21452205 popUseless (tokenStack ) -- Trim leading useless tokens.
21462206
21472207 while true do
@@ -2153,51 +2213,11 @@ local function doLateExpansionsMacros(tokensToExpand, fileBuffers, params, stats
21532213
21542214 -- Preprocessor block in macro.
21552215 elseif tok .type == " pp_entry" and isTokenAndNotNil (tokenStack [len - 1 ], " punctuation" , " (" ) then
2156- local ppEntryTok = tok
2157- tableRemove (tokenStack ) -- '!' or '!!'
2158-
2159- if insertedPpEntry then
2160- tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " .." , representation = " .." }, argNonPpStartTok ))
2161- end
2162- if argNonPpTokens [1 ] then
2163- insertTokensAsStringLiteral (tokens , argNonPpTokens , argNonPpStartTok )
2164- argNonPpTokens = {}
2165- tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " .." , representation = " .." }, ppEntryTok ))
2166- end
2167-
2168- local ident = (ppEntryTok .value == " !" ) and " __TOLUA" or " __ASSERTLUA"
2169- tableInsert (tokens , newTokenAt ({type = " identifier" , value = ident , representation = ident }, ppEntryTok ))
2170- tableInsert (tokens , tableRemove (tokenStack )) -- '('
2171- local exprStartTokIndex = # tokens
2216+ processPreprocessorBlockInMacro (tokens , fileBuffers , tokenStack , argNonPpTokens , argNonPpStartTok , isFirstPart )
21722217
2173- local parensDepth = 1
2174-
2175- while true do
2176- tok = tableRemove (tokenStack ) -- anything
2177- if not tok then
2178- errorAtToken (fileBuffers , ppEntryTok , nil , " Parser" , " Missing end of preprocessor block." )
2179- end
2180- tableInsert (tokens , tok )
2181-
2182- if isToken (tok , " punctuation" , " (" ) then
2183- parensDepth = parensDepth + 1
2184- elseif isToken (tok , " punctuation" , " )" ) then
2185- parensDepth = parensDepth - 1
2186- if parensDepth == 0 then break end
2187- elseif tok .type :find " ^pp_" then
2188- errorAtToken (fileBuffers , tok , nil , " Parser" , " Preprocessor token inside metaprogram (starting %s)." , getRelativeLocationText (ppEntryTok , tok ))
2189- end
2190- end
2191-
2192- local chunk , err = loadLuaString (" return " .. _concatTokens (tokens , nil , false , exprStartTokIndex , nil ), " @" )
2193- if not chunk then
2194- errorAtToken (fileBuffers , tokens [exprStartTokIndex + 1 ], nil , " Macro" , " Syntax error: Invalid expression in preprocessor block." )
2195- -- err = err:gsub("^:%d+: ", "")
2196- -- errorAtToken(fileBuffers, tokens[exprStartTokIndex+1], nil, "Macro", "Syntax error: Invalid expression in preprocessor block. (%s)", err)
2197- end
2198-
2199- insertedPpEntry = true
22002218 argNonPpStartTok = tokenStack [# tokenStack ] -- Could be nil, but that should be fine I think.
2219+ argNonPpTokens = argNonPpTokens [1 ] and {} or argNonPpTokens
2220+ isFirstPart = false
22012221
22022222 -- Other preprocessor code in macro.
22032223 elseif tok .type :find " ^pp_" then
@@ -2248,12 +2268,12 @@ local function doLateExpansionsMacros(tokensToExpand, fileBuffers, params, stats
22482268 popUseless (argNonPpTokens ) -- Trim trailing useless tokens.
22492269
22502270 if argNonPpTokens [1 ] then
2251- if insertedPpEntry then
2271+ if not isFirstPart then
22522272 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " .." , representation = " .." }, argNonPpStartTok ))
22532273 end
22542274 local argStr = insertTokensAsStringLiteral (tokens , argNonPpTokens , argNonPpStartTok )
22552275
2256- if not insertedPpEntry then
2276+ if isFirstPart then
22572277 local chunk , err = loadLuaString (" return (" .. argStr .. " )" , " @" )
22582278
22592279 if not chunk then
@@ -2263,7 +2283,8 @@ local function doLateExpansionsMacros(tokensToExpand, fileBuffers, params, stats
22632283 end
22642284 end
22652285
2266- elseif not insertedPpEntry then
2286+ elseif isFirstPart then
2287+ -- There were no useful tokens for the argument!
22672288 errorAtToken (fileBuffers , argNonPpStartTok , nil , " Macro" , " Syntax error: Expected argument #%d." , argNum )
22682289 end
22692290
@@ -2279,7 +2300,7 @@ local function doLateExpansionsMacros(tokensToExpand, fileBuffers, params, stats
22792300
22802301 -- Add '))'.
22812302 tableInsert (tokens , tableRemove (tokenStack )) -- ')'
2282- tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, ppKeywordTok ))
2303+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [ # tokens ] ))
22832304 end
22842305
22852306 else
0 commit comments