ISPP uses C/C++-like expression syntax. It supports simple and compound assignment operators, conditional operator, and sequential evaluation operator. Although ISPP is an interpreter, it does support short circuit boolean evaluation and never evaluates expressions (nor calls any user defined functions mentioned in those expressions) that should not be evaluated due to specific rules (for example, when conditional operator is used, always only 2 out of 3 operands are evaluated).
ISPPBuiltins.iss contains many example expressions.
There are three types in ISPP: void, integer, and string. Variable of void type is declared by just specifying its name after define directive without any value. Such variables should be used with ifdef directive or Defined function.
If "allow undeclared identifiers" parser option is off (the default state, see pragma), an error is raised when undefined variable is mentioned. Otherwise, it will be treated as a value of type void.
Void is compatible with integer and string in expressions. For example, you can use addition operator with void and integer operands, in this case void operand will be treated as zero. In conjunction with string, void operand is treated as an empty string.
Comments may be embedded in an expression by using a slash and an asterisk. For example:
#emit Var1 /* this is a comment */ + Var2 /* this is also a comment */
Comments may also be placed at the end of an expression by using a semicolon or two slashes. For example:
#emit Var1 + Var2 ; this is a comment
#emit Var1 + Var2 // this is also comment
Please note that line spanning feature is triggered before any further processing, so this is also a valid comment:
#emit Var1 + Var2 ; this is \
still a comment
Comments may also be placed anywhere by starting a line with two slashes. For example:
// This is a comment
All of the comments listed above are not included in the preprocessor output, unlike (non ISPP) comments using a semicolon at the start of a line. For example:
#emit Var1 + Var2 ; this comment is not included
// This comment is not included
; This comment IS included
In ISPP, it is possible to use named parameters when calling user defined function. Given the declaration:
#define MyFunction(int A = 2, int B = 2) A + B
This function can be called specifying parameter names:
#emit MyFunction(A = 5, B = 10)
#emit MyFunction(B = 3)
#emit MyFunction(B = 10, A = 5)
Because of this extension, an assignment expression must be enclosed in parentheses, if not using extended call syntax, to avoid ambiguity:
#emit MyFunction((MyVar = 5), 10)
In the above example, the equality sign is treated as a direct assignment operator.
Although functions do not have named parameters, it is still required to enclose assignment expressions in parentheses when calling those functions.
By standard rule, comma is used to separate actual parameters. If you need to use sequential evaluation operator, you must include the expression in parentheses:
#emit MyFunction((SaveToFile("script.txt"), 5), 10)
In the above example, the first comma is treated as the sequential evaluation operator, whereas the second one as the parameter delimiter.