6.1 General
An expression specifies a computation that produces a value.
Expressions are formed from literals, variables, constants, function invocations, operators, and other expressions. Every expression has a compile-time type that determines the operations that may be performed upon the resulting value.
Unless otherwise specified, evaluation of an expression does not modify program state.
6.2 Expression Categories
Expressions include, but are not limited to:
- literal expressions
- variable references
- constant references
- member access expressions
- function invocations
- unary expressions
- binary expressions
- assignment expressions
- indexing expressions
- constructor expressions
Each expression category is defined in the sections that follow.
6.3 Literal Expressions
A literal expression denotes a constant value written directly within the source code.
Examples include:
- integer literals
- floating-point literals
- string literals
- Boolean literals
- collection literals
The type of a literal is determined by its lexical form and the surrounding context.
6.4 Variable References
A variable reference evaluates to the current value stored in the referenced variable.
The variable shall be visible at the point of reference and shall satisfy the definite assignment rules defined in Chapter 5.
6.5 Constant References
A constant reference evaluates to the value associated with the constant declaration.
The value of a constant cannot change during program execution.
6.6 Function Invocation
Invoking a function evaluates each argument, transfers control to the function body, and produces the value returned by the function.
Every execution path through a function shall produce a value compatible with the declared return type.
A function invocation is itself an expression and may therefore appear wherever an expression is permitted.
Example:
total = CalculateTotal(price, quantity)
6.7 Sub Invocation
A Sub performs an action but does not produce a value.
Because a Sub has no result, a Sub invocation is a statement rather than an expression.
The following is valid:
WriteReport(customer)
The following is invalid:
total = WriteReport(customer)
Attempting to use a Sub where a value is required is a compile-time error.
6.8 Parenthesized Expressions
Parentheses may be used to control evaluation order or improve readability.
A parenthesized expression has the same type and value as the enclosed expression.
6.9 Unary Operators
A unary operator acts upon a single operand.
Examples include:
- arithmetic negation
- logical negation
- bitwise complement
The operand type shall support the selected operator.
6.10 Binary Operators
A binary operator combines two operands to produce a result.
Categories of binary operators include:
- arithmetic operators
- comparison operators
- logical operators
- bitwise operators
- concatenation operators
Each operator specifies:
- the permitted operand types
- the resulting type
- its precedence
- its associativity
6.11 Assignment
An assignment expression replaces the value stored by a variable.
The right-hand expression is evaluated before the assignment occurs.
The resulting value shall be compatible with the destination type.
6.12 Member Access
Member access selects a member of a composite value.
Members may include:
- fields
- properties
- methods
- functions
- subs
- nested types
- constants
The referenced member shall be visible and accessible.
6.13 Indexing
Indexing selects an element of an indexed value.
The index expression shall evaluate to a valid index type.
The semantics of indexing are determined by the indexed type.
6.14 Evaluation Order
Unless otherwise specified, operands are evaluated from left to right.
The language guarantees that each operand is evaluated exactly once.
Programs shall not depend upon any alternative evaluation order.
6.15 Compile-Time Evaluation
The compiler may evaluate expressions during compilation when every operand is known at compile time.
Compile-time evaluation shall not alter the observable behaviour of a valid program.
6.16 Summary
Expressions compute values.
Every expression has a well-defined compile-time type, and every operator defines the relationship between its operands and its result.
