|
28 | 28 | Only during processing: |
29 | 29 | - getCurrentPathIn, getCurrentPathOut |
30 | 30 | - getOutputSoFar, getOutputSoFarOnLine, getOutputSizeSoFar, getCurrentLineNumberInOutput, getCurrentIndentationInOutput |
31 | | - - loadResource |
| 31 | + - loadResource, callMacro |
32 | 32 | - outputValue, outputLua, outputLuaTemplate |
33 | 33 | - startInterceptingOutput, stopInterceptingOutput |
34 | 34 | Macros: |
@@ -209,6 +209,8 @@ local current_parsing_insertCount = 0 |
209 | 209 | local current_parsingAndMeta_onInsert = nil |
210 | 210 | local current_parsingAndMeta_fileBuffers = nil |
211 | 211 | local current_parsingAndMeta_addLineNumbers = false |
| 212 | +local current_parsingAndMeta_macroPrefix = "" |
| 213 | +local current_parsingAndMeta_macroSuffix = "" |
212 | 214 | local current_parsingAndMeta_strictMacroArguments = true |
213 | 215 | local current_meta_pathForErrorMessages = "" |
214 | 216 | local current_meta_outputStack = nil |
@@ -1997,7 +1999,6 @@ function metaFuncs.getNextUsefulToken(tokens, i1, steps) |
1997 | 1999 | end |
1998 | 2000 |
|
1999 | 2001 | local numberFormatters = { |
2000 | | - -- @Incomplete: Hexadecimal floats. |
2001 | 2002 | auto = function(n) return tostring(n) end, |
2002 | 2003 | integer = function(n) return F("%d", n) end, |
2003 | 2004 | int = function(n) return F("%d", n) end, |
@@ -2247,6 +2248,32 @@ function metaFuncs.loadResource(resourceName) |
2247 | 2248 | return (_loadResource(resourceName, false, 2)) |
2248 | 2249 | end |
2249 | 2250 |
|
| 2251 | +local function isCallable(v) |
| 2252 | + return type(v) == "function" |
| 2253 | + -- We use debug.getmetatable instead of _G.getmetatable because we don't want to |
| 2254 | + -- potentially invoke user code - we just want to know if the value is callable. |
| 2255 | + or (type(v) == "table" and debug.getmetatable(v) ~= nil and type(debug.getmetatable(v).__call) == "function") |
| 2256 | +end |
| 2257 | + |
| 2258 | +-- callMacro() |
| 2259 | +-- luaString = callMacro( macroName, argument1, ... ) |
| 2260 | +-- Call a macro function (which must be a global in metaEnvironment). |
| 2261 | +-- The arguments should be Lua code strings. |
| 2262 | +function metaFuncs.callMacro(name, ...) |
| 2263 | + errorIfNotRunningMeta(2) |
| 2264 | + |
| 2265 | + local nameResult = current_parsingAndMeta_macroPrefix .. name .. current_parsingAndMeta_macroSuffix |
| 2266 | + local f = metaEnv[nameResult] |
| 2267 | + |
| 2268 | + if not isCallable(f) then |
| 2269 | + if name == nameResult |
| 2270 | + then errorf(2, "'%s' is not a macro/global function. (Got %s)", name, type(f)) |
| 2271 | + else errorf(2, "'%s' (resolving to '%s') is not a macro/global function. (Got %s)", name, nameResult, type(f)) end |
| 2272 | + end |
| 2273 | + |
| 2274 | + return (metaEnv.__M()(f(...))) |
| 2275 | +end |
| 2276 | + |
2250 | 2277 | -- :PredefinedMacros |
2251 | 2278 |
|
2252 | 2279 | -- ASSERT() |
@@ -2379,13 +2406,7 @@ function metaEnv.__ARG(locTokNum, v) |
2379 | 2406 | end |
2380 | 2407 |
|
2381 | 2408 | function metaEnv.__EVAL(v) -- For symbols. |
2382 | | - if |
2383 | | - type(v) == "function" |
2384 | | - -- We use debug.getmetatable instead of _G.getmetatable because we |
2385 | | - -- don't want to potentially invoke user code right here - we just |
2386 | | - -- want to know if the value is callable. |
2387 | | - or (type(v) == "table" and debug.getmetatable(v) and debug.getmetatable(v).__call) |
2388 | | - then |
| 2409 | + if isCallable(v) then |
2389 | 2410 | v = v() |
2390 | 2411 | end |
2391 | 2412 | return v |
@@ -2609,12 +2630,8 @@ end |
2609 | 2630 |
|
2610 | 2631 | -- outTokens = doExpansions( params, tokensToExpand, stats ) |
2611 | 2632 | local function doExpansions(params, tokens, stats) |
2612 | | - local macroPrefix = params.macroPrefix or "" |
2613 | | - local macroSuffix = params.macroSuffix or "" |
2614 | | - |
2615 | 2633 | tokens = doEarlyExpansions(tokens, stats) |
2616 | 2634 | tokens = doLateExpansions (tokens, stats, params.backtickStrings, params.jitSyntax) -- Resources. |
2617 | | - |
2618 | 2635 | return tokens |
2619 | 2636 | end |
2620 | 2637 |
|
@@ -2908,7 +2925,7 @@ local function astParseMacro(params, tokens) |
2908 | 2925 | local initialCalleeIdentTok = tokNext |
2909 | 2926 |
|
2910 | 2927 | -- Add macro prefix and suffix. (Note: We only edit the initial identifier in the callee if there are more.) |
2911 | | - initialCalleeIdentTok.value = (params.macroPrefix or "") .. initialCalleeIdentTok.value .. (params.macroSuffix or "") |
| 2928 | + initialCalleeIdentTok.value = current_parsingAndMeta_macroPrefix .. initialCalleeIdentTok.value .. current_parsingAndMeta_macroSuffix |
2912 | 2929 | initialCalleeIdentTok.representation = initialCalleeIdentTok.value |
2913 | 2930 |
|
2914 | 2931 | -- Maybe add '.field[expr]:method' for rest of callee. |
@@ -3486,6 +3503,8 @@ local function _processFileOrString(params, isFile) |
3486 | 3503 | current_parsingAndMeta_fileBuffers = {[virtualPathIn]=luaUnprocessed} -- Doesn't have to be the contents of files if params.onInsert() is defined. |
3487 | 3504 | current_parsingAndMeta_onInsert = params.onInsert |
3488 | 3505 | current_parsingAndMeta_addLineNumbers = params.addLineNumbers |
| 3506 | + current_parsingAndMeta_macroPrefix = params.macroPrefix or "" |
| 3507 | + current_parsingAndMeta_macroSuffix = params.macroSuffix or "" |
3489 | 3508 | current_parsingAndMeta_strictMacroArguments = params.strictMacroArguments ~= false |
3490 | 3509 | current_meta_locationTokens = {} |
3491 | 3510 |
|
@@ -3654,6 +3673,8 @@ local function _processFileOrString(params, isFile) |
3654 | 3673 | current_parsingAndMeta_fileBuffers = nil |
3655 | 3674 | current_parsingAndMeta_onInsert = nil |
3656 | 3675 | current_parsingAndMeta_addLineNumbers = false |
| 3676 | + current_parsingAndMeta_macroPrefix = "" |
| 3677 | + current_parsingAndMeta_macroSuffix = "" |
3657 | 3678 | current_parsingAndMeta_strictMacroArguments = true |
3658 | 3679 |
|
3659 | 3680 | if isFile then |
@@ -3712,6 +3733,8 @@ local function processFileOrString(params, isFile) |
3712 | 3733 | current_parsingAndMeta_onInsert = nil |
3713 | 3734 | current_parsingAndMeta_fileBuffers = nil |
3714 | 3735 | current_parsingAndMeta_addLineNumbers = false |
| 3736 | + current_parsingAndMeta_macroPrefix = "" |
| 3737 | + current_parsingAndMeta_macroSuffix = "" |
3715 | 3738 | current_parsingAndMeta_strictMacroArguments = true |
3716 | 3739 | current_meta_pathForErrorMessages = "" |
3717 | 3740 | current_meta_outputStack = nil |
|
0 commit comments