Expressions never have any side-effects when they are evaluated.

Literal expressions

Int literal expressions

A non-empty seqence of decimal digits, optionally preceded by a - sign. The value must be in the range for a signed 32-bit integer, and has type int.

Float literal expressions

A non-empty sequence of decimal digits, followed by a decimal point ‘.’, followed by a non-empty sequence of decimal digits. The value has type float.

String literal expressions

A sequence of characters delimited by either ' or ". Characters may be escaped by a backslash \, and the escape sequences \n and \t mean newline and tab characters respectively. The value has type str.

Dict literal expressions

A sequence of key = value pairs delimited by braces { and }, separated by commas, with an optional trailing comma before the closing brace. The keys must be simple names, and cannot be keywords. The value has a dict type.

Pattern literal expressions

A non-empty sequence of pattern characters or character-sets, delimited by [ and ], with rows separated by /. The character ‘.’ means a wildcard which matches any alphabet symbol when it occurs in an input pattern, and writes nothing to the grid when it occurs in an output pattern. Character-sets are also delimited by [ and ], and may not contain wildcards.

Name expressions

Simple name expressions

A simple name is an identifier, and refers to a variable of that name. A compilation error occurs if no such variable exists in the lexical context.

Keyword name expressions

A keyword name is one of the following:

Attribute expressions

An attribute expression is of the form object.attribute, where attribute is an identifier, and object must be either a simple name, a keyword name or itself an attribute expression. The type of object must be either:

Grid expressions

A grid expression is of the form grid [Alphabet] or grid {Arguments} [Alphabet]. Its result is a reference to a new grid; however, the expression will always refer to the same new grid however many times it is evaluated. (This is so that grids never need to be dynamically allocated.) The alphabet must be a literal pattern containing no repeated characters, wildcards, row separators or character-sets.

The allowed arguments are listed below, and may be present in any combination; they must be compile-time constants.

A grid expression may also occur as a bare ‘use’ statement, in which case the new grid is also set as the context’s current grid.

Operator expressions

Operators in the table below are binary unless shown otherwise via their syntax; see also operator precedence. The “numeric” types are int, float and fraction.

Operator Operand types Meaning
+ Numeric or str Addition for numeric types; concatenation for str
- Numeric Subtraction
* Numeric Multiplication
/ Numeric True division; if both operands are int, result is fraction
// int Floor division; rounds towards negative infinity, not zero
% int or float Modulo; result has same sign as second operand, not the first
==, != Numeric or str Comparison; result is bool
<, <=, >, >= Numeric Comparison; result is bool
and, or bool or pattern.in Logical operations
+X Numeric Has no effect; it is included for symmetry with unary -, and by tradition
-X Numeric Negation
not X bool Logical negation
count X pattern.in Count operator
load X str Load operator
randint X int Randint operator
sum X 1x1 pattern.in Sum operator
if condition else B condition: bool Conditional expression; A and B must have a common type (after coercion).

The binary operators +, -, *, // and the unary operator - may overflow on values of type int, such that the result is within the signed 32-bit integer range.

A runtime error occurs if the second operand of a binary /, // or % expression is zero.

Count operator

The count operator returns the number of matches of a given pattern, as an int. The count includes matches of symmetries of the given pattern, according to the context’s current symmetry group. The operand must be a compile-time constant pattern for the current alphabet.

A compilation error occurs if the count operator is used in a context without a current grid.

Load operator

The load operator loads a pattern from an image file, using the current legend to translate pixel colours into pattern characters or character-sets.

The image file’s path must be a compile-time constant of type str. A compilation error occurs if no legend is declared in the expression’s lexical context.

Randint operator

The randint operator generates a pseudorandom int value between zero (inclusive) and the operand’s value (exclusive). The operand must be of type int.

A runtime error occurs if the operand’s value is less than or equal to zero; a compilation error occurs if the operand is a compile-time constant with value less or equal to zero.

Sum operator

The sum operator may only be used within a convolution statement. The result of the expression is the number of neighbours of the “current position” (as defined in a rule context) which match the given 1x1 pattern, as an int. The kernel argument of the convolution statement determines which cells are “neighbours”.

The operand must be a compile-time constant 1x1 pattern for the current alphabet. A compilation error occurs if the sum operator is used outside of a rule context, or outside of a convolution statement.

Declaration expressions

A declaration expression is of the form (D in E), where E is a sub-expression and D is a declaration which takes effect in E’s lexical context.

A declaration expression must be written in parentheses, unless it is the immediate sub-expression of another declaration expression; see also operator precedence.