@@ -1937,15 +1937,9 @@ local function doLateExpansionsResources(tokensToExpand, fileBuffers, params, st
19371937 local identTok = tokNext
19381938 tokNext , iNext = getNextUsableToken (tokenStack , iNext - 1 , nil , - 1 )
19391939
1940- if isTokenAndNotNil (tokNext , " punctuation" , " (" ) then
1941- -- Apply the same 'ambiguous syntax' rule as Lua.
1942- if isTokenAndNotNil (tokenStack [iNext + 1 ], " whitespace" ) and tokenStack [iNext + 1 ].value :find " \n " then
1943- errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Ambiguous syntax near '(' - part of macro, or new statement?" )
1944- end
1945-
1946- elseif not (tokNext and (
1940+ if not (tokNext and (
19471941 tokNext .type == " string"
1948- or (tokNext .type == " punctuation" and isAny (tokNext .value , " {" ," ." ," :" ))
1942+ or (tokNext .type == " punctuation" and isAny (tokNext .value , " ( " , " {" ," ." ," :" , " [ " ))
19491943 )) then
19501944 errorAtToken (fileBuffers , identTok , identTok .position +# identTok .representation , " Macro" , " Syntax error: Expected '(' after macro name '%s'." , identTok .value )
19511945 end
@@ -2044,6 +2038,10 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
20442038 end
20452039 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, macroStartTok ))
20462040
2041+ --
2042+ -- Callee.
2043+ --
2044+
20472045 -- Add 'ident' for start of (or whole) callee.
20482046 local tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack - 1 , nil , - 1 )
20492047 if not isTokenAndNotNil (tokNext , " identifier" ) then
@@ -2054,29 +2052,67 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
20542052 tableInsert (tokens , tokNext )
20552053 local lastCalleeTok = tokNext
20562054
2057- -- Maybe add '.field:method' for end of callee.
2058- -- @Incomplete: @@name[expr]()
2055+ -- Maybe add '.field[expr]:method' for rest of callee.
20592056 tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
20602057
2061- while isTokenAndNotNil (tokNext , " punctuation" ) and (tokNext .value == " ." or tokNext .value == " :" ) do
2062- local punctTok = tokNext
2063- local isMethodCall = (punctTok .value == " :" )
2058+ while tokNext do
2059+ if isToken (tokNext , " punctuation" , " ." ) or isToken (tokNext , " punctuation" , " :" ) then
2060+ local punctTok = tokNext
2061+ popTokens (tokenStack , iNext ) -- '.' or ':'
2062+ tableInsert (tokens , tokNext )
20642063
2065- popTokens (tokenStack , iNext ) -- '.' or ':'
2066- tableInsert (tokens , tokNext )
2064+ tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
2065+ if not tokNext then
2066+ errorAfterToken (fileBuffers , punctTok , " Macro" , " Syntax error: Expected an identifier after '%s'." , punctTok .value )
2067+ end
2068+ popTokens (tokenStack , iNext ) -- the identifier
2069+ tableInsert (tokens , tokNext )
20672070
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
2071+ lastCalleeTok = tokNext
2072+ tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
20752073
2076- tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
2077- if isMethodCall then break end
2074+ if punctTok .value == " :" then break end
2075+
2076+ elseif isToken (tokNext , " punctuation" , " [" ) then
2077+ local punctTok = tokNext
2078+ popTokens (tokenStack , iNext ) -- '['
2079+ tableInsert (tokens , tokNext )
2080+
2081+ local bracketBalance = 1
2082+
2083+ while true do
2084+ tokNext = tableRemove (tokenStack ) -- anything
2085+ if not tokNext then
2086+ errorAtToken (
2087+ fileBuffers , punctTok , nil , " Macro" ,
2088+ " Syntax error: Could not find matching bracket before EOF. (Macro starts %s)" ,
2089+ getRelativeLocationText (macroStartTok , punctTok )
2090+ )
2091+ end
2092+ tableInsert (tokens , tokNext )
2093+
2094+ if isToken (tokNext , " punctuation" , " [" ) then
2095+ bracketBalance = bracketBalance + 1
2096+ elseif isToken (tokNext , " punctuation" , " ]" ) then
2097+ bracketBalance = bracketBalance - 1
2098+ if bracketBalance == 0 then break end
2099+ elseif tokNext .type :find " ^pp_" then
2100+ errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Preprocessor token inside metaprogram/macro name expression (starting %s)." , getRelativeLocationText (macroStartTok , tokNext ))
2101+ end
2102+ end
2103+
2104+ lastCalleeTok = tokNext
2105+ tokNext , iNext = getNextUsableToken (tokenStack , # tokenStack , nil , - 1 )
2106+
2107+ else
2108+ break
2109+ end
20782110 end
20792111
2112+ --
2113+ -- Arguments.
2114+ --
2115+
20802116 -- @insert identifier " ... "
20812117 if isTokenAndNotNil (tokNext , " string" ) then
20822118 local stringTok = tokNext
@@ -2172,11 +2208,9 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
21722208 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [# tokens ]))
21732209
21742210 -- @insert identifier ( argument1, ... )
2175- else
2176- if not isTokenAndNotNil (tokNext , " punctuation" , " (" ) then
2177- printErrorTraceback (" Internal error." )
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
2211+ elseif isTokenAndNotNil (tokNext , " punctuation" , " (" ) then
2212+ -- Apply the same 'ambiguous syntax' rule as Lua.
2213+ if isTokenAndNotNil (tokenStack [iNext + 1 ], " whitespace" ) and tokenStack [iNext + 1 ].value :find " \n " then
21802214 errorAtToken (fileBuffers , tokNext , nil , " Macro" , " Ambiguous syntax near '(' - part of macro, or new statement?" )
21812215 end
21822216
@@ -2313,8 +2347,15 @@ local function expandMacro(tokens, fileBuffers, tokenStack, macroStartTok, isNes
23132347
23142348 -- Add ')' for end of call.
23152349 tableInsert (tokens , tableRemove (tokenStack )) -- ')'
2350+
2351+ else
2352+ errorAfterToken (fileBuffers , lastCalleeTok , " Macro" , " Syntax error: Expected '(' after macro name." )
23162353 end
23172354
2355+ --
2356+ -- End.
2357+ --
2358+
23182359 -- Add ')' for end of preprocessor block.
23192360 tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, tokens [# tokens ]))
23202361end
0 commit comments