Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Operators

Crush’s operators are deliberately few. Everything in this chapter is verified against the current compiler.

Arithmetic

OperatorMeaningExample
+add / string concatenation5 + 3, "a" + "b"
-subtract / unary negate10 - 4, -x
*multiply6 * 7
/divide (Int / Int truncates toward zero)20 / 4, -7 / 2
%remainder17 % 5
print(5 + 3)
print(10 - 4)
print(6 * 7)
print(20 / 4)
print(17 % 5)
print(-7 / 2)
print(-(3 + 2))
8
6
42
5
2
-3
-5

Mixing Int and Float promotes to Float (1 + 2.5 is 3.5). + between a string and a number concatenates ("n=" + 5 is "n=5"); * on a string does not repeat it.

There is no exponent operator (**), floor-division (//), or compound assignment (+=, -=, …) — use math.pow(a, b) (with --stdlib) and x = x + 1. See Variables.

Comparison

==, !=, <, >, <=, >= return Bool. Operands must be of compatible types; comparing a string with an int is a compile error. Strings compare lexicographically; arrays compare element-wise with ==.

let a = 10
let b = 20
print(a == b)
print(a != b)
print(a < b)
print(a >= b)
print("apple" < "banana")
print([1, 2] == [1, 2])
print(1 == 1.0)
false
true
true
false
true
true
true

Logical

Logic uses symbols: &&, ||, !. The words and, or and not are not operators. && and || short-circuit (crush-ast CRUSH-125):

fn noisy() {
    print("evaluated")
    return true
}

print(false && noisy())
print(true || noisy())
print(!(1 > 2))
false
true
true
print(true and false)

Conditions in if/while must be Bool — see Types.

Range

a..b is a half-open range (a inclusive, b exclusive). It is used by for, and also evaluates to an array of the integers in the range:

for i in 2..5 {
    print(i)
}
let r = 1..5
print(r)
2
3
4
[1, 2, 3, 4]

An empty or reversed range (5..2) produces no iterations. Both bounds may be expressions: for i in 0..len(items). There is no range() function.

Pipeline

x |> f calls f(x); x |> f(y) calls f(x, y). Chains read left to right. The right side must be a user-defined function (or a call to one):

fn inc(x) {
    return x + 1
}
fn dbl(x) {
    return x * 2
}
fn add(a, b) {
    return a + b
}

print(3 |> inc |> dbl)
print(3 |> add(4))
8
7

Piping into a capability such as str.trim or conv.to_str is rejected (Pipeline right side must be function); wrap it in a function first:

print("  hi  " |> str.trim)

Not available

Bitwise operators (&, |, ^, ~, <<, >>) are not part of the Crush language today — the lexer rejects them — even though CASM has bit_* opcodes (CASM reference). There is no ternary a ? b : c, no null-coalescing ??, and no **.

Precedence (high → low)

LevelOperators
1(), ., [] — call, field access, indexing
2unary -, !
3* / %
4+ -
5< > <= >=
6== !=
7&&
8||
9|>
print(2 + 3 * 4)
print((2 + 3) * 4)
print(1 + 1 == 2 && 2 * 2 == 4)
14
20
true

Next Steps