123123
124124
125125
126- local PP_VERSION = " 1.15.0"
126+ local PP_VERSION = " 1.15.0-dev "
127127
128128local MAX_DUPLICATE_FILE_INSERTS = 1000 -- @Incomplete: Make this a parameter for processFile()/processString().
129129
@@ -733,6 +733,21 @@ function _tokenize(s, path, allowPpTokens, allowBacktickStrings, allowJitSyntax)
733733 tok = {type = " pp_keyword" , representation = repr , value = word }
734734 end
735735
736+ -- Preprocessor symbol.
737+ elseif s :find (" ^%$" , ptr ) then
738+ if not allowPpTokens then
739+ errorInFile (s , path , ptr , " Tokenizer" , " Encountered preprocessor symbol. (Feature not enabled.)" )
740+ end
741+
742+ local i1 , i2 , repr , word = s :find (" ^(%$([%a_][%w_]*))" , ptr )
743+ if not i1 then
744+ errorInFile (s , path , ptr + 1 , " Tokenizer" , " Expected an identifier." )
745+ elseif KEYWORDS [word ] then
746+ errorInFile (s , path , ptr + 1 , " Tokenizer" , " Invalid preprocessor symbol '%s'. (Must not be a Lua keyword.)" , word )
747+ end
748+ ptr = i2 + 1
749+ tok = {type = " pp_symbol" , representation = repr , value = word }
750+
736751 else
737752 errorInFile (s , path , ptr , " Tokenizer" , " Unknown character." )
738753 end
@@ -1629,6 +1644,7 @@ local numberFormatters = {
16291644-- whitespaceToken = newToken( "whitespace", contents )
16301645-- ppEntryToken = newToken( "pp_entry", isDouble )
16311646-- ppKeywordToken = newToken( "pp_keyword", ppKeyword ) -- ppKeyword can be "@".
1647+ -- ppKeywordToken = newToken( "pp_symbol", identifier )
16321648--
16331649-- commentToken = { type="comment", representation=string, value=string, long=isLongForm }
16341650-- identifierToken = { type="identifier", representation=string, value=string }
@@ -1639,6 +1655,7 @@ local numberFormatters = {
16391655-- whitespaceToken = { type="whitespace", representation=string, value=string }
16401656-- ppEntryToken = { type="pp_entry", representation=string, value=string, double=isDouble }
16411657-- ppKeywordToken = { type="pp_keyword", representation=string, value=string }
1658+ -- ppSymbolToken = { type="pp_symbol", representation=string, value=string }
16421659--
16431660-- Number formats:
16441661-- "integer" E.g. 42
@@ -1684,6 +1701,8 @@ function metaFuncs.newToken(tokType, ...)
16841701 error (" Identifier length is 0." , 2 )
16851702 elseif not ident :find " ^[%a_][%w_]*$" then
16861703 errorf (2 , " Bad identifier format: '%s'" , ident )
1704+ elseif KEYWORDS [ident ] then
1705+ errorf (2 , " Identifier must not be a keyword: '%s'" , ident )
16871706 end
16881707
16891708 return {type = " identifier" , representation = ident , value = ident }
@@ -1780,6 +1799,20 @@ function metaFuncs.newToken(tokType, ...)
17801799 return {type = " pp_keyword" , representation = " @" .. keyword , value = keyword }
17811800 end
17821801
1802+ elseif tokType == " pp_symbol" then
1803+ local ident = ...
1804+ assertarg (2 , ident , " string" )
1805+
1806+ if ident == " " then
1807+ error (" Identifier length is 0." , 2 )
1808+ elseif not ident :find " ^[%a_][%w_]*$" then
1809+ errorf (2 , " Bad identifier format: '%s'" , ident )
1810+ elseif KEYWORDS [ident ] then
1811+ errorf (2 , " Identifier must not be a keyword: '%s'" , ident )
1812+ else
1813+ return {type = " pp_symbol" , representation = " $" .. ident , value = ident }
1814+ end
1815+
17831816 else
17841817 errorf (2 , " Invalid token type '%s'." , tostring (tokType ))
17851818 end
@@ -1812,6 +1845,13 @@ function metaEnv.__ASSERTLUA(lua)
18121845 return lua
18131846end
18141847
1848+ function metaEnv .__EVALSYMBOL (v )
1849+ if type (v ) == " function" then
1850+ v = v ()
1851+ end
1852+ return v
1853+ end
1854+
18151855
18161856
18171857local function getLineCountWithCode (tokens )
@@ -1861,6 +1901,7 @@ local function doEarlyExpansions(tokensToExpand, fileBuffers, params, stats)
18611901 -- @file
18621902 -- @line
18631903 -- ` ... `
1904+ -- $symbol
18641905 --
18651906 if not stats .hasPreprocessorCode then
18661907 return tokensToExpand
@@ -1903,6 +1944,20 @@ local function doEarlyExpansions(tokensToExpand, fileBuffers, params, stats)
19031944 tableInsert (tokens , stringTok )
19041945 tableRemove (tokenStack ) -- the string
19051946
1947+ -- Symbol. (Should this expand later? Does it matter?)
1948+ elseif isToken (tok , " pp_symbol" ) then
1949+ local ppSymbolTok = tok
1950+
1951+ -- $symbol
1952+ tableRemove (tokenStack ) -- '$symbol'
1953+ tableInsert (tokens , newTokenAt ({type = " pp_entry" , value = " !!" , representation = " !!" , double = true }, ppSymbolTok ))
1954+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, ppSymbolTok ))
1955+ tableInsert (tokens , newTokenAt ({type = " identifier" , value = " __EVALSYMBOL" , representation = " __EVALSYMBOL" }, ppSymbolTok ))
1956+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " (" , representation = " (" }, ppSymbolTok ))
1957+ tableInsert (tokens , newTokenAt ({type = " identifier" , value = ppSymbolTok .value , representation = ppSymbolTok .value }, ppSymbolTok ))
1958+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, ppSymbolTok ))
1959+ tableInsert (tokens , newTokenAt ({type = " punctuation" , value = " )" , representation = " )" }, ppSymbolTok ))
1960+
19061961 -- Anything else.
19071962 else
19081963 tableInsert (tokens , tok )
@@ -2549,7 +2604,7 @@ local function _processFileOrString(params, isFile)
25492604 }
25502605
25512606 for _ , tok in ipairs (tokens ) do
2552- if isToken (tok , " pp_entry" ) or isToken (tok , " pp_keyword" , " insert" ) then
2607+ if isToken (tok , " pp_entry" ) or isToken (tok , " pp_keyword" , " insert" ) or isToken ( tok , " pp_symbol " ) then
25532608 stats .hasPreprocessorCode = true
25542609 stats .hasMetaprogram = true
25552610 break
@@ -2857,6 +2912,9 @@ local function _processFileOrString(params, isFile)
28572912 tableInsert (metaParts , metaBlock )
28582913 tableInsert (metaParts , " ))\n " )
28592914
2915+ elseif metaBlock :find (" ," , 1 , true ) and loadLuaString (" return''," .. metaBlock ) then
2916+ errorAfterToken (fileBuffers , tokens [startIndex + 1 ], " Parser" , " Ambiguous preprocessor block contents. (Comma-separated lists are not supported here.)" )
2917+
28602918 elseif doOutputLua then
28612919 -- We could do something other than error here. Room for more functionality.
28622920 errorAfterToken (fileBuffers , tokens [startIndex + 1 ], " Parser" , " Preprocessor block does not contain a valid value expression." )
0 commit comments