-
Notifications
You must be signed in to change notification settings - Fork 3
preprocessor_proposal
Symbols are essentially global variables available only in the preprocessor scope. The same rules applies for naming of symbols as for global variables. Values are either bool
, string
, double
or empty
.
-
#define
- defines a symbol -
#undef
- undefines a symbol
The base way of defining a symbol is to use #define
followed by one or more whitespaces then by a symbol name composed by a single literal followed by one or more whitespaces, optionally followed by =
, followed by one or more whitespaces and finally a value. A value has to be a single literal, either true
, false
, a double like 1
, 3.14
or a string enclosed in either single or double quotes. Opening and enclosing quote has to be of the same type. 'my string'
, "my string"
. A string like 'my string"
is invalid and results in a preprocessor error.
#define MY_SYMBOL = 5
#define MY_SYMBOL 5
When a symbol is defined and right hand of the definition is ommited, we treat for comparisons it as if the right hand was = true
but the actual value of a symbol is empty
.
#define MY_SYMBOL
Multiple definitions can be shorthanded in one line via ,
. This works with both #define
and #undef
.
#define MY_SYMBOL = false, LOG_LEVEL = "warning", MY_VERSION = '4.0.1'
#undef MY_SYMBOL, LOG_LEVEL
All #
directives can contain single line comments //
which are ignored by the preprocessor interpreter. When //
sequence is encountered the rest of line is ignored. The only time this does not apply is when a string literal is being parsed. #define MY_STRING = '//'
is a valid usage of #define
.
#define LOG_LEVEL = "warning" // this setting means something and has some known values blah blah blah... I can use #whatever here and it is ignored
#if
-
#elseif
,#else if
,#elif
(all of these have the same meaning) #else
#endif
A block *(zero or more lines of code) between #if
and #endif
will be compiled only if the #if
's expression is truthy. Same rules apply as with normal ifs. We consider a truthy value to be true
, any double greater than 0 and any string with length greater than 0.
#if "YES" // any string other than "" or '' is truthy
#endif
Comparison operators >
, >=
, <
, <=
, ==
, !=
can be used in #if
's expression, logical !
, ||
and &&
operators are also supported.
#if 2 + 2 > 5 // this is illegal, will throw. We don't support arithmetical operators such as + in the preprocessor
#endif
Parentheses are supported in expressions.
#if DEBUG == (((true))) // this is a legit rhs
Parentheses around expression in #if
, #elif
, #elseif
and #else if
can be ommited but are supported.
// these two are the same
#if (DEBUG == true)
#if DEBUG
The existence of a variable can also be checked with the defined()
operator. This will return true if the value is defined even if the value evaluates to false.
#if defined(VARIABLE)
Multiple branches can be added to the #if
directive via #elif
, #else if
, #else if
and #else
. Alias #elif
is introduced due to it's usage in C# and C. #if
directive has to end with a #endif
directive. If no such directive is found it results in a throw.
#error
To throw errors #error
is used. An optional message can be included in #error
as a single string (single or double quotes enclosed) literal.
#if LANGVER < 2.5
#error "This snippet requires WattleScript at least 2.5"
#endif
If no rhs is provided an interpreter will throw a default message with line number on which the error was raised.
#line
#line
directive is used by code generators for WattleScript to translate line numbers and enable seamless debugging. There are two ways to write a #line
directive:
LINE_NUMBER
has to be an integer greater than 0 or a special literal. Known special literals are:
- default
- line numbering mode is set to native
- anything other is an invalid special and throws
1. #line 200
2. var a = =
3. local b = =
4. #line default
5. var c = =
// Unexpected symbol at line 200 after after "var a ="
// Unexpected symbol at line 201 after "local b ="
// Unexpected symbol at line 5 after "var c ="
-
COL_OFFSET
- the column offset for the#line
directive to take place. The next character afterCOL_OFFSET
characters is treated as column 1.
1. #line 2, 5
2. var a = =
// "var" in this example starts at line 2, character 6
#region
#endregion
#region
directives are a feature to be used in LSP implementations as "folding ranges". Preprocessor ignores them apart from checking that each #region
is enclosed with #endregion
.
-
#LANGVER
- a double corresponding to the WattleScript NuGet version installed on the executing system. Example values:1.2
or5
.
We allow redefining predefined symbols. #LANGVER 10
will force the symbol to hold value 10
.