ISPP uses C/C++-like expression syntax. It supports simple and compound assignment operators, the conditional operator, and the sequential evaluation operator. Although ISPP is an interpreter, it does support short-circuit boolean evaluation. It never evaluates an expression (or calls any user defined function within it) when the operator's rules say it should not be evaluated. For example, the conditional operator always evaluates only 2 of its 3 operands.
ISPPBuiltins.iss contains many example expressions.
There are three types in ISPP: void, integer, and string. A variable of void type is declared by specifying its name after the define directive without any value. Such variables should be used with the ifdef directive or the Defined function.
If the "allow undeclared identifiers" parser option is off (the default state, see pragma), an error is raised when an 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 the addition operator with void and integer operands. In this case, the void operand will be treated as zero. In conjunction with a string, the void operand is treated as an empty string.
String comparison operators are case-insensitive.
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. For example:
#emit Var1 + Var2 ; this is a comment
Note that the 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, you can use named parameters when calling a 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 the 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.
Even when a function doesn't have named parameters, assignment expressions still need parentheses when calling it.
By the standard rule, a comma is used to separate actual parameters. If you need to use the 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, and the second one is treated as the parameter delimiter.