Skip to content

Commit 65669d4

Browse files
committed
Added processedFileInfo.hasMetaprogram .
processedFileInfo.hasPreprocessorCode now means anything that isn't pure Lua. Better error messages when encoutering preprocessor code when it's disallowed.
1 parent 04ba8ca commit 65669d4

File tree

3 files changed

+55
-27
lines changed

3 files changed

+55
-27
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ end
7070
-- Preprocessor inline block. (Expression that returns a value.)
7171
local text = !("Precalculated hash: "..getHash())
7272

73-
-- Preprocessor inline block variant. (Expression that returns a Lua string.)
73+
-- Preprocessor inline block variant. (Expression that returns a Lua code string.)
7474
!!("myRandomGlobal"..math.random(9)) = "foo"
7575
```
7676

@@ -101,7 +101,7 @@ function newEntity() return {__name="Entity",x=0,y=0} end
101101
-- Preprocessor inline block. (Expression that returns a value.)
102102
local text = "Precalculated hash: 6CD3556DEB0DA54BCA060B4C39479839"
103103

104-
-- Preprocessor inline block variant. (Expression that returns a Lua string.)
104+
-- Preprocessor inline block variant. (Expression that returns a Lua code string.)
105105
myRandomGlobal4 = "foo"
106106
```
107107

preprocess-cl.lua

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ exec lua "$0" "$@"
106106
outputPaths: If the --outputpaths option is present this is an array of output paths for the respective path in inputPaths, otherwise it's nil.
107107
108108
"insert"
109-
Sent for each @insert statement. The handler is expected to return a Lua string.
109+
Sent for each @insert"name" statement. The handler is expected to return a Lua code string.
110110
Arguments:
111111
path: The file being processed.
112112
name: The name of the resource to be inserted (could be a file path or anything).
@@ -460,12 +460,12 @@ for i, pathIn in ipairs(pathsIn) do
460460
onInsert = (hasMessageHandler("insert") or nil) and function(name)
461461
local lua = sendMessage("insert", pathIn, name)
462462

463-
-- onInsert() is expected to return a Lua string and so is the message handler.
464-
-- However, if the handler is a single catch-all function we allow the message
465-
-- to not be handled and we fall back to the default behavior of treating 'name'
466-
-- as a path to a file to be inserted. If we didn't allow this then it would be
467-
-- required for the "insert" message to be handled. I think it's better if the
468-
-- user can choose whether to handle a message or not!
463+
-- onInsert() is expected to return a Lua code string and so is the message
464+
-- handler. However, if the handler is a single catch-all function we allow
465+
-- the message to not be handled and we fall back to the default behavior of
466+
-- treating 'name' as a path to a file to be inserted. If we didn't allow this
467+
-- then it would be required for the "insert" message to be handled. I think
468+
-- it's better if the user can choose whether to handle a message or not!
469469
--
470470
if lua == nil and type(messageHandler) == "function" then
471471
return assert(pp.getFileContents(name))

preprocess.lua

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
-- Preprocessor inline block. (Expression that returns a value.)
9797
local text = !("The dog said: "..getDogText())
9898
99-
-- Preprocessor inline block variant. (Expression that returns a Lua string.)
99+
-- Preprocessor inline block variant. (Expression that returns a Lua code string.)
100100
_G.!!("myRandomGlobal"..math.random(5)) = 99
101101
102102
-- Dual code (both preprocessor line and final output).
@@ -420,7 +420,9 @@ local NUM_DEC_FRAC = ("^( %d* %.%d+
420420
local NUM_DEC_EXP = ("^( %d+ %.? [Ee][-+]?%d+ )"):gsub(" +", "")
421421
local NUM_DEC = ("^( %d+ %.? )"):gsub(" +", "")
422422

423-
function _tokenize(s, path, allowMetaTokens, allowBacktickStrings, allowJitSyntax)
423+
-- tokens = _tokenize( luaString, path, allowPreprocessorTokens, allowBacktickStrings, allowJitSyntax )
424+
-- Returns nil and a message on error.
425+
function _tokenize(s, path, allowPpTokens, allowBacktickStrings, allowJitSyntax)
424426
local tokens = {}
425427
local ptr = 1
426428
local ln = 1
@@ -636,14 +638,16 @@ function _tokenize(s, path, allowMetaTokens, allowBacktickStrings, allowJitSynta
636638
tok.value = v
637639

638640
-- Backtick string.
639-
elseif allowBacktickStrings and s:find("^`", ptr) then
640-
local i1, i2, v = s:find("^`([^`]*)`", ptr)
641+
elseif s:find("^`", ptr) then
642+
if not allowBacktickStrings then
643+
return nil, errorInFile(s, path, ptr, "Tokenizer", "Encountered backtick string. (Feature not enabled.)")
644+
end
645+
646+
local i1, i2, repr, v = s:find("^(`([^`]*)`)", ptr)
641647
if not i2 then
642648
return nil, errorInFile(s, path, ptr, "Tokenizer", "Unfinished backtick string.")
643649
end
644650

645-
local repr = F("%q", v)
646-
647651
ptr = i2+1
648652
tok = {type="string", representation=repr, value=v, long=false}
649653

@@ -661,15 +665,24 @@ function _tokenize(s, path, allowMetaTokens, allowBacktickStrings, allowJitSynta
661665
tok = {type="punctuation", representation=repr, value=repr}
662666
ptr = ptr+#repr
663667

664-
-- Preprocessor: Entry.
665-
elseif allowMetaTokens and s:find("^!", ptr) then
668+
-- Preprocessor entry.
669+
elseif s:find("^!", ptr) then
670+
if not allowPpTokens then
671+
return nil, errorInFile(s, path, ptr, "Tokenizer", "Encountered preprocessor entry. (Feature not enabled.)")
672+
end
673+
666674
local double = s:find("^!", ptr+1) ~= nil
667675
local repr = s:sub(ptr, ptr+(double and 1 or 0))
676+
668677
tok = {type="pp_entry", representation=repr, value=repr, double=double}
669678
ptr = ptr+#repr
670679

671-
-- Preprocessor: Keyword.
672-
elseif allowMetaTokens and s:find("^@", ptr) then
680+
-- Preprocessor keyword.
681+
elseif s:find("^@", ptr) then
682+
if not allowPpTokens then
683+
return nil, errorInFile(s, path, ptr, "Tokenizer", "Encountered preprocessor keyword. (Feature not enabled.)")
684+
end
685+
673686
if s:find("^@@", ptr) then
674687
ptr = ptr+2
675688
tok = {type="pp_keyword", representation="@@", value="insert"}
@@ -1282,15 +1295,15 @@ end
12821295

12831296
-- tokenize()
12841297
-- Convert Lua code to tokens. Returns nil and a message on error. (See newToken() for token types.)
1285-
-- tokens, error = tokenize( luaString [, allowPreprocessorTokens=false ] )
1298+
-- tokens, error = tokenize( luaString [, allowPreprocessorCode=false ] )
12861299
-- token = {
12871300
-- type=tokenType, representation=representation, value=value,
12881301
-- line=lineNumber, lineEnd=lineNumber, position=bytePosition, file=filePath,
12891302
-- ...
12901303
-- }
1291-
function metaFuncs.tokenize(lua, allowMetaTokens)
1304+
function metaFuncs.tokenize(lua, allowPpCode)
12921305
pushErrorHandler(NOOP)
1293-
local tokens, err = _tokenize(lua, "<string>", allowMetaTokens, allowMetaTokens, true) -- @Incomplete: Make allowJitSyntax a parameter to tokenize()?
1306+
local tokens, err = _tokenize(lua, "<string>", allowPpCode, allowPpCode, true) -- @Incomplete: Make allowJitSyntax a parameter to tokenize()?
12941307
popErrorHandler()
12951308
return tokens, err
12961309
end
@@ -1591,7 +1604,7 @@ local function newTokenAt(tok, locationTok)
15911604
return tok
15921605
end
15931606

1594-
local function processKeywords(tokensRaw, fileBuffers, params, stats)
1607+
local function doExpansions(tokensRaw, fileBuffers, params, stats)
15951608
if not stats.hasPreprocessorCode then
15961609
return tokensRaw
15971610
end
@@ -1607,6 +1620,7 @@ local function processKeywords(tokensRaw, fileBuffers, params, stats)
16071620
while tokenStack[1] do
16081621
local tok = tokenStack[#tokenStack]
16091622

1623+
-- Keyword.
16101624
if isToken(tok, "pp_keyword") then
16111625
local ppKeywordTok = tok
16121626

@@ -1922,6 +1936,14 @@ local function processKeywords(tokensRaw, fileBuffers, params, stats)
19221936
errorAtToken(fileBuffers, ppKeywordTok, ppKeywordTok.position+1, "Parser", "Unknown preprocessor keyword '%s'.", ppKeywordTok.value)
19231937
end
19241938

1939+
-- Backtick string.
1940+
elseif isToken(tok, "string") and tok.representation:find"^`" then
1941+
tok.representation = F("%q", tok.value)
1942+
1943+
table.insert(tokens, tok)
1944+
table.remove(tokenStack)
1945+
1946+
-- Anything else.
19251947
else
19261948
table.insert(tokens, tok)
19271949
table.remove(tokenStack)
@@ -1981,17 +2003,22 @@ local function _processFileOrString(params, isFile)
19812003
lineCountCode = getLineCountWithCode(tokensRaw),
19822004
tokenCount = 0, -- Set later.
19832005
hasPreprocessorCode = false,
2006+
hasMetaprogram = false,
19842007
insertedNames = {},
19852008
}
19862009

19872010
for _, tok in ipairs(tokensRaw) do
1988-
if isToken(tok, "pp_entry") or isToken(tok, "pp_keyword") then
2011+
if isToken(tok, "pp_entry") or isToken(tok, "pp_keyword", "insert") then
19892012
stats.hasPreprocessorCode = true
2013+
stats.hasMetaprogram = true
19902014
break
2015+
elseif isToken(tok, "pp_keyword") or (isToken(tok, "string") and tok.representation:find"^`") then
2016+
stats.hasPreprocessorCode = true
2017+
-- Keep going as there may be metaprogram.
19912018
end
19922019
end
19932020

1994-
local tokens = processKeywords(tokensRaw, fileBuffers, params, stats) -- Tokens for constructing the metaprogram.
2021+
local tokens = doExpansions(tokensRaw, fileBuffers, params, stats) -- Tokens for constructing the metaprogram.
19952022
stats.tokenCount = #tokens
19962023

19972024
-- Generate metaprogram.
@@ -2413,6 +2440,7 @@ local function _processFileOrString(params, isFile)
24132440
linesOfCode = stats.lineCountCode,
24142441
tokenCount = stats.tokenCount,
24152442
hasPreprocessorCode = stats.hasPreprocessorCode,
2443+
hasMetaprogram = stats.hasMetaprogram,
24162444
insertedFiles = stats.insertedNames,
24172445
}
24182446

@@ -2531,7 +2559,7 @@ local pp = {
25312559
-- jitSyntax = boolean -- [Optional] Allow LuaJIT-specific syntax. (Default: false)
25322560
-- validate = boolean -- [Optional] Validate output. (Default: true)
25332561
--
2534-
-- onInsert = function( name ) -- [Optional] Called for each @insert"name" statement. It's expected to return a Lua string. By default 'name' is a path to a file to be inserted.
2562+
-- 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.
25352563
-- onBeforeMeta = function( ) -- [Optional] Called before the metaprogram runs.
25362564
-- onAfterMeta = function( luaString ) -- [Optional] Here you can modify and return the Lua code before it's written to 'pathOut'.
25372565
-- onError = function( error ) -- [Optional] You can use this to get traceback information. 'error' is the same value as what is returned from processFile().
@@ -2556,7 +2584,7 @@ local pp = {
25562584
-- jitSyntax = boolean -- [Optional] Allow LuaJIT-specific syntax. (Default: false)
25572585
-- validate = boolean -- [Optional] Validate output. (Default: true)
25582586
--
2559-
-- onInsert = function( name ) -- [Optional] Called for each @insert"name" statement. It's expected to return a Lua string. By default 'name' is a path to a file to be inserted.
2587+
-- 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.
25602588
-- onBeforeMeta = function( ) -- [Optional] Called before the metaprogram runs.
25612589
-- onError = function( error ) -- [Optional] You can use this to get traceback information. 'error' is the same value as the second returned value from processString().
25622590
--

0 commit comments

Comments
 (0)