Expression Evaluation in Scripts
A script in the C4 Engine can contain methods of the type Evaluate Expression, sometimes called an expression method for short. An expression method holds a text string representing a mathematical expression that gets evaluated when script execution reaches the method.
For an expression method, a text box is displayed on the left side of the Method Info window where a textual expression may be entered. (The Method Info window is opened by selecting a method and then typing CtrlI.) A field for designating an output variable also appears in the lowerleft corner of the Method Info window.
If there is a syntax error in an expression, then the method is colored yellow in the script viewport.
Operators
Expressions can use any of the operators from the following list. They are listed in order of evaluation precedence, which matches the precedence rules for C++. Parentheses can be used to group subexpressions.
Operator 
Description 
Variable types accepted 
Notes 

Member Access 
color, vector, point 
Returns a scalar component of type float. For colors, one of For vectors and points, one of 

Bitwise NOT 
boolean, integer 
This is a unary operator. 

Multiply 
boolean, integer, float, color, vector, point 
Colors can only be multiplied by other colors or by floatingpoint, integer, or boolean scalar values. Vectors and points can only be multiplied by other vectors and points or by floatingpoint, integer, or boolean scalar values. Multiplication is componentwise for colors, vectors, and points. 

Divide 
boolean, integer, float, color, vector, point 
A color, vector, or point type can only appear as the left operand, and they can be divided by floatingpoint, integer, or boolean scalar values. Integer division by zero is defined to be zero. 

Modulo 
boolean, integer 
If the right operand is zero, then the result is defined to be zero. 

Plus 
boolean, integer, float, string, color, vector, point 
Colors can only be added to other colors. Vectors and points can only be added to other vectors and points. A unary plus is accepted and performs no operation. 

Minus or Negate 
boolean, integer, float, color, vector, point 
Colors can only be subtracted from other colors. Vectors and points can only be subtracted from other vectors and points. 

Shift Left 
boolean, integer 


Shift Right 
boolean, integer 
The shift is always signed. 

Less Than 
boolean, integer, float 
Always returns a boolean result. 

Greater Than 
boolean, integer, float 
Always returns a boolean result. 

Less Than or Equal 
boolean, integer, float 
Always returns a boolean result. 

Greater Than or Equal 
boolean, integer, float 
Always returns a boolean result. 

Equal 
boolean, integer, float, string 
Always returns a boolean result. 

Not Equal 
boolean, integer, float, string 
Always returns a boolean result. 

Bitwise AND 
boolean, integer 


Bitwise XOR 
boolean, integer 


Bitwise OR 
boolean, integer 

Note that the logical operators &&
and 
are not present in the table. These were intentionally left out of the scripting language because they are not necessary. The same results can be attained by using the &
and 
operators instead. If the evaluation semantics of &&
and 
are needed, then you can use conditional execution to evaluate the expression in pieces.
Operands
Each operand in an expression can be any of the following:
 The boolean value
true
orfalse
.  An integer literal value using any features from the OpenDDL syntax. This includes underscores separating digits, support for binary, octal, and hexadecimal literals (using the prefixes
0b
,0o
, and0x
, respectively), and character literals enclosed in single quotes. Integers are always stored as signed 32bit quantities.  A floatingpoint literal value matching the OpenDDL syntax, with the exception that it must be decimal and contain one of the characters '
.
', 'e
', or 'E
' (decimal point or exponent indicator). Floats are always stored as 32bit quantities.  A literal string matching the OpenDDL syntax. Escape characters and Unicode are supported.
 The name of any variable defined for the script, possibly followed by the dot operator to access an individual component of a color, vector, or point.
In any binary operation appearing in an expression, a mismatch between the types of the two operands causes one of the operands to be promoted to the type of the other. The possible promotions are those in the following list:
 Boolean can be promoted to integer, float, or string.
 Integer can be promoted to float or string.
 Float can be promoted to string.
Result
An expression always produces an output value, and the boolean result for the expression method reflects the value of the expression. If the output value is not stored in a variable, then the boolean result is still valid. If the value of the expression is not boolean, then one of the following conversions is made to arrive at a boolean result:
 For an integer, the value 0 becomes false, and any other value becomes true.
 For a float, the value 0.0 becomes false, and any other value becomes true.
 For a string, the empty string becomes false, and any other string becomes true.
Expression Grammar
The following grammar provides a formal description of exactly how expressions are parsed.
identifier ::= [AZaz_] [09AZaz_]* hexdigit ::= [09AFaf] escapechar ::= '\"'  "\'"  "\?"  "\\"  "\a"  "\b"  "\f"  "\n"  "\r"  "\t"  "\v"  "\x" hexdigit hexdigit boolliteral ::= "false"  "true" decimalliteral ::= [09] ("_"? [09])* hexliteral ::= ("0x"  "0X") hexdigit ("_"? hexdigit)* octalliteral ::= ("0o"  "0O") [07] ("_"? [07])* binaryliteral ::= ("0b"  "0B") ("0"  "1") ("_"? ("0"  "1"))* charliteral ::= "'" ([#x20#x26#x28#x5B#x5D#x7E]  escapechar)+ "'" integerliteral ::= decimalliteral  hexliteral  octalliteral  binaryliteral  charliteral floatliteral ::= (([09] ("_"? [09])* "." ([09] ("_"? [09])*)?  ([09] ("_"? [09])*)? "." [09] ("_"? [09])*) (("e"  "E") ("+"  "")? [09] ("_"? [09])*)?  [09] ("_"? [09])* ("e"  "E") ("+"  "")? [09] ("_"? [09])*) stringliteral ::= ('"' ([#x20#x21#x23#x5B#x5D#x7E#xA0#xD7FF#xE000#xFFFD#x010000#x10FFFF]  escapechar  "\u" hexdigit hexdigit hexdigit hexdigit  "\U" hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit)* '"')+ primaryexpression ::= ("+"  ""  "~")? (identifier ("." identifier)?  integerliteral  floatliteral  stringliteral  "(" orexpression ")") multiplicativeexpression ::= (multiplicativeexpression "*"  multiplicativeexpression "/"  multiplicativeexpression "%")? primaryexpression additiveexpression ::= (additiveexpression "+"  additiveexpression "")? multiplicativeexpression shiftexpression ::= (shiftexpression "<<"  shiftexpression ">>")? additiveexpression relationalexpression ::= (relationalexpression "<"  relationalexpression ">"  relationalexpression "<<"  relationalexpression ">>")? shiftexpression equalityexpression ::= (equalityexpression "=="  equalityexpression "!=")? relationalexpression andexpression ::= (andexpression "&")? equalityexpression xorexpression ::= (xorexpression "^")? andexpression orexpression ::= (orexpression "")? xorexpression