Pre-processor Directives
To define pre-processor meta-macros, the directive $define is used. Its format is:-
$define identifier replacement
When the pre-processor encounters this directive, it replaces any occurrence of identifier in the rest of the code by replacement. This replacement can be an expression, a statement, a block, or simply anything. The pre-processor does not understand BASIC, it simply replaces any occurrence of identifier by replacement.
$define TableSize 100
Dim Table1[TableSize] as Byte
Dim Table2[TableSize] as Byte
After the pre-processor has replaced TableSize, the code becomes equivalent to:-
Dim Table1[100] as Byte
Dim Table2[100] as Byte
The use of $define as a constant definer is only one aspect of the pre-processor, and $define can also work with parameters to define pseudo function macros. The syntax then is:-
$define identifier (parameter list) replacement
A simple example of a function-like macro is:-
$define RadToDeg(pValue) ((pValue) * 57.29578)
This defines a radians to degrees conversion which can be used as:-
Var1 = RadToDeg(34)
This is expanded in-place, so the caller does not need to clutter copies of the multiplication constant throughout the code.
Precedence
Note that the example macro RadToDeg(x) given above uses normally unnecessary parentheses both around the argument and around the entire expression. Omitting either of these can lead to unexpected results. For example:-
Macro defined as:
$define RadToDeg(pValue) (pValue * 57.29578)
will expand
RadToDeg(a + b)
to
(a + b * 57.29578)
Macro defined as:
$define RadToDeg(pValue) (pValue) * 57.29578
will expand
1 / RadToDeg(a)
to
1 / (a) * 57.29578
Neither of which give the intended result.
Not all replacement tokens can be passed back to an assignment using the equals operator. If this is the case, the code needs to be similar to BASIC Stamp syntax, where the assignment variable is the last parameter:-
$define GetMax(x, y, z) If x > y Then z = x : Else : z = y
This would replace any occurrence of GetMax followed by three parameter (argument) by the replacement expression, but also replacing each parameter by its identifier, exactly as would be expected of a function.
Dim bVar1 as Byte
Dim bVar2 as Byte
Dim bVar3 as Byte
bVar1 = 100
bVar2 = 99
GetMax(bVar1, bVar2, bVar3)
The previous would be placed within the BASIC program as:-
Dim bVar1 as Byte
Dim bVar2 as Byte
Dim bVar3 as Byte
bVar1 = 100
bVar2 = 99
If bVar1 > bVar2 Then bVar3 = bVar1 : Else : bVar3 = bVar2
Notice that the third parameter “Var3” is loaded with the result.
A macro lasts until it is undefined with the $undef pre-processor directive:-
$define TableSize 100
Dim Table1[TableSize] as Byte
$undef TableSize
$define TableSize 200
Dim Table2[TableSize] as Byte
This would generate the same code as:-
Dim Table1[100] as Byte
Dim Table2[200] as Byte
Because pre-processor replacements happen before any BASIC syntax check, macro definitions can be a tricky feature, so be careful. Code that relies heavily on complicated macros may be difficult to understand, since the syntax they expect is, on many occasions, different from the regular expressions programmers expect in Positron8 BASIC.
Pre-processor directives only extend across a single line of code. As soon as a newline character is found (end of line), the pre-processor directive is considered to end. The only way a preprocessor directive can extend through more than one line is by preceding the newline character at the end of the line by a comment character (‘) followed by a new line. No comment text can follow the comment character. For example:-
$define GetMax(x,y,z) If x > y Then '
z = x
'
Else
'
z = y
'
EndIf
GetMax(Var1, Var2, Var3)
The compiler will see:-
If Var1 > Var2 Then
Var3 = Var1
Else
Var3 = Var2
EndIf
Note that parenthesis is always required around the $define declaration and its use within the program. If the replacement argument is not included within the $define directive, the identifier argument will output nothing. However, it can be used as an identifier for conditional code:-
$define DoThis
$ifdef DoThis
{Rest of Code here}
$endif
$undef identifier This removes any existing definition of the user macro identifier.
$eval expression In normal operation, the $define directive simply replaces text, however, using the $eval directive allows constant value expressions to be evaluated before replacement within the BASIC code. For example:-
$define Expression(pPrm1) $eval Prm1 << 1
The above will evaluate the constant parameter pPrm1, shifting it left one position.
Var1 = Expression(1)
Will be added to the BASIC code as:-
Var1 = 2
Because 1 shifted left one position is 2.
Several operators are available for use with an expression. These are +, -, *, -, ~, <<, >>, =, >, <, >=, <=, <>, And, Or, Xor.