Macros - jpbubble/NIL-isn-t-Lua GitHub Wiki

As Lua doesn't support constants (why?), but I did want something I could use as a good alternative without having to rely on variables (since they can be modified, hence the name "variable", they are not safe for this purpose), I decided to get into macros.

They are similar to C macros, but not as sophisticated as their C variant.

#define mymacro "Hello World"
// This has a NIL variant.

#define forrange(a,from,till) for (a=from;a<till;a++)
// This doesn't have a NIL variant, and I'm not planning that either

Please note, that one trapdoor C offers here, also arises in NIL. Macros are in code just replaced by their content, and they are processed before the code is parsed or pre-processed in any other way. Yes, even keywords can be replaced, and thus handling them carelessly will result into trouble.

Also NIL parses line by line, so the position of your macro definition is important.

print("HW")
#macro HW "Hello World
print("HW")
-- output
HW
Hello World

Also note, unlike C, macros cannot be redefined nor be undefined, so be careful around them. However just like C, it doesn't matter were Macros live, in string or in the code, it's all the same.

#macro HW "Hello World"
print(HW)
-- output
Hello World

Also note that the macro directive does NOT take note of any scopes, so they always count as 'global'.

There is also "#localmacro". The only difference between '#localmacro' and '#macro' is that '#macro' counts for the entire Lua state, and '#localmacro' only for the chunk in which they are defined. They do NOT take note of scopes, only of chunks.

// chunk demo
#macro HW "Hello World"
var H = NIL.Load([[#localmacro HW "Hallo Welt"
print(HW)
]])
print(HW)
// output
Hallo Welt
Hello World
// Scopes are ignored
for a=1,5 do
    #localmacro HW "Hello World"
    print(" In scope:"..HW)
end
print("Out scope:"..HW)
// output
 In scope:Hello World
 In scope:Hello World
 In scope:Hello World
 In scope:Hello World
 In scope:Hello World
Out scope:Hello World

Macro conflicts

In case of 'conflicts' between macros, please take the following in mind

  • The macro processor first replaces all local macros, and after that the global ones.
  • Macros are within their group ASCII sorted, which mostly leads to an alphabetic order (however 'B' comes before 'a', since upper case letters have a lower ASCII value than upper case letters.
  • Like everything else in Lua macros are case-sensitive so MyMacro and mymacro and MYMACRO are three different macros.
  • Please note Macros are replaced by actual code, and when you are not careful this can lead to strange effects like below
#macro Hello Hello World
#macro World Earth
#macro Hi Yo Ape
#macro Ape Monkey
print("Hello") // output: Hello Earth
print("Hi") // output: Yo Ape
// Can you figure out why the outcome is not what you may expect?