A macro is a set of commands (statements) that can be repeated anywhere in the program. In other words, it is a set of commands
that are given a name, and whenever the compiler encounters that name it replaces it with those set of commands.
Macros are defined in the following way:
def macro_name: macro [parameters] { // macro_body }
Or in the shorter form:
macro macro_name [parameters] { // macro_body }
Where:
macro_name: a name used later to call the macro.
macro: a keyword.
parameters: macro parameters that will be used (substituted) in macro body.
macro_body: macro body where we will put the programming statements (in case there is only one statement we could omit the curly brackets).
Example 1:
We will define a macro named `LIMIT` and it will hold the value 5. So whenever the compiler reach the name of this macro it will replace
it with 5.
import "Srl/Console.alusus"; macro LIMIT 5; // a macro without parameters. Srl.Console.print("The value of LIMIT is %d\n", LIMIT[]); //The value of LIMIT is 5
Example 2:
We will use a macro to calculate the area of a rectangle.
import "Srl/Console.alusus"; macro AREA [x,y] x*y; def a: int = 4; def b: int = 9; def area: int; area = AREA[a, b]; Srl.Console.print("Area of rectangle is: %d\n", area); // Area of rectangle is: 36
In the example above we can see that each time the compiler encounters `AREA[x, y]` it replaces it with
the body of the macro after substituting the arguments x and y with the parameters provided to the macro.
Example 3:
import "Srl/Console.alusus"; import "Srl/String.alusus"; use Srl; def s: String = "Macro.."; macro printString [s] Console.print("%s", s.buf); printString[s]; // Macro...
Note that when using variables in macros we don't specify its type (and we can't do this); the compiler will simply
substitute the macro name with the macro body during preprocessing, so it doesn't need to know the types of the
arguments.
Notes:
Example:
import "Srl/Console.alusus"; macro INSTAGRAM FOLLOWERS[]; macro FOLLOWERS 100; Srl.Console.print("Alusus has %dK followers on Instagram\n", INSTAGRAM[]); // Alusus has 100K followers on Instagram
You can read about the differences between Alusus macros and C macros here
Macros are similer to functions, but there exists cases where functions fall short and macros are needed instead:
import "Srl/Console.alusus"; macro defX { def x: int = 9; } defX[] Srl.Console.print("%d", x); // 9Note how that when we called the macro we became able to use the variable `x`.
import "Srl/Console.alusus" use Srl.Console; macro square [x] { x * x } print("%d\n", square[5]); // 25 print("%0.2f\n", square[5.5]~cast[Float[64]]); // 30.25Here we can use the macro `square` with any type that accepts the operator `*`.
import "Srl/Console.alusus"; macro square[x] { x * x } function f () { def x: int = 9; Srl.Console.print("%d", square[x]); } f() // 81If we remove the parameters from the macro and assume that the function should define that variable, the macro will still work. This is not possible with functions.
import "Srl/Console.alusus"; macro square { x * x } function f () { def x: int = 9; Srl.Console.print("%d", square[]); } f(); // 81