44--= by Marcus 'ReFreezed' Thunström
55--=
66--= License: MIT (see the bottom of this file)
7- --= Website: https ://github. com/ReFreezed/LuaPreprocess
8- --= Documentation: https ://github. com/ReFreezed/LuaPreprocess/wiki
7+ --= Website: http ://luapreprocess.refreezed. com/
8+ --= Documentation: http ://luapreprocess.refreezed. com/docs/
99--=
1010--= Tested with Lua 5.1, 5.2, 5.3 and 5.4.
1111--=
112112 -- Though in this specific case a preprocessor line (without the parenthesis) would be nicer:
113113 !func()
114114
115- -- For the full documentation, see: https ://github. com/ReFreezed/LuaPreprocess/wiki
115+ -- For the full documentation, see: http ://luapreprocess.refreezed. com/docs/
116116
117117--============================================================]]
118118
@@ -1942,7 +1942,11 @@ local function doLateExpansionsResources(tokensToExpand, fileBuffers, params, st
19421942 if isTokenAndNotNil (tokenStack [iNext + 1 ], " whitespace" ) and tokenStack [iNext + 1 ].value :find " \n " then
19431943 errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Ambiguous syntax near '(' - part of macro, or new statement?" )
19441944 end
1945- elseif not (isTokenAndNotNil (tokNext , " string" ) or isTokenAndNotNil (tokNext , " punctuation" , " {" )) then
1945+
1946+ elseif not (tokNext and (
1947+ tokNext .type == " string"
1948+ or (tokNext .type == " punctuation" and isAny (tokNext .value , " {" ," ." ," :" ))
1949+ )) then
19461950 errorAtToken (fileBuffers , identTok , identTok .position +# identTok .representation , " Macro" , " Syntax error: Expected '(' after macro name '%s'." , identTok .value )
19471951 end
19481952
@@ -2032,16 +2036,6 @@ end
20322036
20332037local function expandMacro (tokens , fileBuffers , tokenStack , macroStartTok , isNested )
20342038 -- @Robustness: Make sure key tokens came from the same source file.
2035- local tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack - 1 , nil , - 1 )
2036-
2037- if not isTokenAndNotNil (tokNext , " identifier" ) then
2038- printErrorTraceback (" Internal error." )
2039- errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Internal error. (%s)" , (tokNext and tokNext .type or " ?" ))
2040- end
2041-
2042- local identTok = tokNext
2043- popTokens (tokenStack , iNext ) -- the identifier
2044-
20452039 -- Add '!!(' for start of preprocessor block.
20462040 if isNested then
20472041 tableInsert (tokens , newTokenAt ({type = " identifier" , value = " __ASSERTLUA" , representation = " __ASSERTLUA" }, macroStartTok ))
@@ -2050,16 +2044,45 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
20502044 end
20512045 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, macroStartTok ))
20522046
2047+ -- Add 'ident' for start of (or whole) callee.
2048+ local tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack - 1 , nil , - 1 )
2049+ if not isTokenAndNotNil (tokNext , " identifier" ) then
2050+ printErrorTraceback (" Internal error." )
2051+ errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Internal error. (%s)" , (tokNext and tokNext .type or " ?" ))
2052+ end
2053+ popTokens (tokenStack , iNext ) -- the identifier
2054+ tableInsert (tokens , tokNext )
2055+ local lastCalleeTok = tokNext
2056+
2057+ -- Maybe add '.field:method' for end of callee.
2058+ -- @Incomplete: @@name[expr]()
20532059 tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
20542060
2061+ while isTokenAndNotNil (tokNext , " punctuation" ) and (tokNext .value == " ." or tokNext .value == " :" ) do
2062+ local punctTok = tokNext
2063+ local isMethodCall = (punctTok .value == " :" )
2064+
2065+ popTokens (tokenStack , iNext ) -- '.' or ':'
2066+ tableInsert (tokens , tokNext )
2067+
2068+ tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
2069+ if not tokNext then
2070+ errorAfterToken (fileBuffers , punctTok , " Macro" , " Syntax error: Expected an identifier after '%s'." , punctTok .value )
2071+ end
2072+ popTokens (tokenStack , iNext ) -- the identifier
2073+ tableInsert (tokens , tokNext )
2074+ lastCalleeTok = tokNext
2075+
2076+ tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
2077+ if isMethodCall then break end
2078+ end
2079+
20552080 -- @insert identifier " ... "
20562081 if isTokenAndNotNil (tokNext , " string" ) then
20572082 local stringTok = tokNext
20582083 popTokens (tokenStack , iNext ) -- the string
20592084
2060- -- Add 'ident' for start of call. We don't need parenthesis for this macro variant.
2061- tableInsert (tokens , identTok )
2062-
2085+ -- Note: We don't need parenthesis for this macro variant.
20632086 stringTok .value = stringTok .representation
20642087 stringTok .representation = F (" %q" , stringTok .value ):gsub (" \n " , " n" )
20652088 tableInsert (tokens , stringTok )
@@ -2072,9 +2095,8 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
20722095 -- (Similar code as `@insert identifier()` below.)
20732096 --
20742097
2075- -- Add 'ident(' for start of call.
2076- tableInsert (tokens , identTok )
2077- tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, identTok ))
2098+ -- Add '(' for start of call.
2099+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, tokNext ))
20782100
20792101 -- Collect tokens for the table arg.
20802102 -- We're looking for the closing '}'.
@@ -2153,14 +2175,15 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
21532175 else
21542176 if not isTokenAndNotNil (tokNext , " punctuation" , " (" ) then
21552177 printErrorTraceback (" Internal error." )
2156- errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Internal error. (%s)" , (tokNext and tokNext .type or " ?" ))
2178+ errorAfterToken (fileBuffers , lastCalleeTok , " Macro" , " Syntax error: Expected '(' after macro name." )
2179+ elseif isTokenAndNotNil (tokenStack [iNext + 1 ], " whitespace" ) and tokenStack [iNext + 1 ].value :find " \n " then
2180+ errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Ambiguous syntax near '(' - part of macro, or new statement?" )
21572181 end
21582182
21592183 local parensStartTok = tokNext
21602184 popTokens (tokenStack , iNext ) -- '('
21612185
2162- -- Add 'ident(' for start of call.
2163- tableInsert (tokens , identTok )
2186+ -- Add '(' for start of call.
21642187 tableInsert (tokens , parensStartTok )
21652188
21662189 tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
@@ -2943,7 +2966,7 @@ local pp = {
29432966 -- fastStrings = boolean -- [Optional] Force fast serialization of string values. (Non-ASCII characters will look ugly.) (Default: false)
29442967 -- validate = boolean -- [Optional] Validate output. (Default: true)
29452968 --
2946- -- onInsert = function( name ) -- [Optional] Called for each @insert"name" statement . It's expected to return a Lua code string. By default 'name' is a path to a file to be inserted.
2969+ -- onInsert = function( name ) -- [Optional] Called for each @insert"name" instruction . It's expected to return a Lua code string. By default 'name' is a path to a file to be inserted.
29472970 -- onBeforeMeta = function( ) -- [Optional] Called before the metaprogram runs.
29482971 -- onAfterMeta = function( luaString ) -- [Optional] Here you can modify and return the Lua code before it's written to 'pathOut'.
29492972 -- onError = function( error ) -- [Optional] You can use this to get traceback information. 'error' is the same value as what is returned from processFile().
@@ -2969,7 +2992,7 @@ local pp = {
29692992 -- fastStrings = boolean -- [Optional] Force fast serialization of string values. (Non-ASCII characters will look ugly.) (Default: false)
29702993 -- validate = boolean -- [Optional] Validate output. (Default: true)
29712994 --
2972- -- onInsert = function( name ) -- [Optional] Called for each @insert"name" statement . It's expected to return a Lua code string. By default 'name' is a path to a file to be inserted.
2995+ -- onInsert = function( name ) -- [Optional] Called for each @insert"name" instruction . It's expected to return a Lua code string. By default 'name' is a path to a file to be inserted.
29732996 -- onBeforeMeta = function( ) -- [Optional] Called before the metaprogram runs.
29742997 -- onError = function( error ) -- [Optional] You can use this to get traceback information. 'error' is the same value as the second returned value from processString().
29752998 --
0 commit comments