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

& · * · + · - · -> · … · / · < · << · <= · <> · = · > · >= · >> · @* · @+ · @- · AND · MOD · NOT · OR · TO · [](#-23) · ^ · | · ~


&

Keeps only the bits that are set on both sides — the usual way to test or clear a flag. Like all my bit operators it takes whole numbers only, and it sits with * in the order of operations. It isn’t AND: AND asks a true-or-false question, & works bit by bit.

Example

IF flags & 0b0100 THEN PRINT "third bit is set"

*

Multiplies two numbers. A coordinate times a number scales every part. A string times a number repeats the string — and a count of zero or less gives you "".

Example

PRINT 6 * 7, (10, 20) * 2, "ab" * 3

+

Adds two numbers, or two coordinates part by part. With a string on either side I join the two as text, turning the other side into text first.

With an array on the left, + gives you a longer array — a new one, so assign it to keep it. A whole number is how many empty items to add on the end. Another array is joined on. Anything else is added as one item. So to add the number 5 itself, wrap it: scores + [5].

Examples

PRINT 1 + 2, (1, 2) + (3, 4), "score: " + 5
names = names + "bob"
scores = scores + [5]
grid = grid + 1

-

Subtracts two numbers, or two coordinates part by part. In front of a number or a coordinate, it makes it negative.

With an array on the left and a whole number on the right, - gives you a new array with that many items taken off the end. I’ll stop you if you ask for more than it has.

Examples

PRINT 10 - 3, (5, 5) - (1, 2), -speed
last = stack(LEN(stack) - 1)
stack = stack - 1

->

Makes a vector from one coordinate to another. Read or change its ends with .start and .stop.

Example

path = (0, 0) -> (10, 5)
PRINT path.stop.x

…

Makes a range: every whole number from the first to the last, both included. A range counts towards its end, so 3 ... 1 gives 3, 2, 1. TO means exactly the same thing.

Watch out — that means a range is never empty! 0 ... count - 1 still runs twice when count is 0. To step through an array, hand me the array itself.

Example

FOR i = 1 ... 3
    PRINT i
END FOR

/

Divides, and always gives a float: 7 / 2 is 3.5. A coordinate divided by a number divides every part. Dividing by a coordinate uses its length. Dividing by zero is a number no-no even for me, so I stop there.

Example

PRINT 7 / 2, (4, 6) / 2

<

Asks whether the left side is smaller. Strings compare in alphabetical order, capitals first. A coordinate is compared by its length. I can only compare two things at a time, so write a < b AND b < c.

Example

IF hp < 10 THEN PRINT "careful"

<<

Moves the bits of a whole number to the left, filling with zeros: 1 << 4 is 16. Bits pushed off the end are gone, so moving 64 places or more leaves 0. A negative count moves them right instead.

Example

bit = 1 << n

<=

Asks whether the left side is smaller or equal. See <.

Example

IF n <= 0 THEN RETURN

<>

Asks whether two values are different. The opposite of =.

Example

IF name <> "" THEN PRINT name

=

In an expression, asks me whether two values are equal, and I answer 1 or 0. Numbers compare by value, so 1 = 1.0. Strings compare by their text. A string and a number are equal if the string reads as that number. Coordinates compare part by part. Arrays, maps and objects are equal only to themselves.

At the start of a statement, name = value is an assignment — that always wins. To pass a comparison to a keyword, put it in parentheses.

Examples

IF answer = 42 THEN PRINT "yes"
score = 0

>

Asks whether the left side is larger. Everything I said about < goes for this one too.

Example

IF score > best THEN best = score

>=

Asks whether the left side is larger or equal. See <.

Example

IF level >= 5 THEN PRINT "unlocked"

>>

Moves the bits of a whole number to the right: 256 >> 4 is 16. I keep the sign, so a negative number stays negative. A negative count moves them left instead.

Example

high = value >> 8

@*

Multiplies a matrix: an array of rows of numbers, all the same length. Times another matrix, each row on the left meets each column on the right, so the left has to be as many across as the right is down. Times a number, every part is scaled. Times a coordinate or a vector, the point is put through the matrix — turned, scaled, and moved too if the matrix is one bigger than the point each way. A plain array of numbers works like a one-row matrix.

Example

turn = [[0, -1], [1, 0]]
PRINT turn @* (3, 4), turn @* turn, turn @* 2

@+

Adds two matrices of the same shape, part to part, and gives a new one. Two plain arrays of numbers of the same length add the same way. (A plain + on arrays joins them instead.)

Example

PRINT [[1, 2], [3, 4]] @+ [[10, 20], [30, 40]], [1, 2] @+ [3, 4]

@-

Subtracts one matrix from another of the same shape, part from part, and gives a new one. Two plain arrays of numbers of the same length subtract the same way.

Example

PRINT [[10, 20], [30, 40]] @- [[1, 2], [3, 4]], [5, 5] @- [1, 2]

AND

True when both sides are true; gives 1 or 0. I only look at the right side if the left side is true.

Example

IF hp > 0 AND ammo > 0 THEN fire()

MOD

The remainder after dividing: 7 MOD 4 is 3. Two whole numbers give a whole number. It’s still a division, so zero on the right stops me.

Example

IF n MOD 2 = 0 THEN PRINT "even"

NOT

Gives 1 if the value is false and 0 if it’s true. I apply it to a whole comparison: NOT a = b is NOT (a = b).

Example

IF NOT ready THEN RETURN

OR

True when either side is true; gives 1 or 0. I only look at the right side if the left side is false.

Example

IF hp <= 0 OR time <= 0 THEN PRINT "game over"

TO

Another way to write ..., for when words read better than dots.

Example

FOR i = 10 TO 1
    PRINT i
END FOR

\

Divides and drops the fraction, giving a whole number: 7 \ 2 is 3. No dividing by zero here either!

Example

PRINT 7 \ 2

^

Raises a number to a power. I work it out before a leading minus, so -2 ^ 2 is -4, and it groups to the right: 2 ^ 3 ^ 2 is 2 ^ 9. A whole number raised to a whole number that isn’t negative stays a whole number.

Example

PRINT 2 ^ 10

|

Keeps every bit that is set on either side — the usual way to switch a flag on. Whole numbers only, and it sits with + in the order of operations.

Example

flags = flags | 0b0100

~

Between two whole numbers, keeps the bits that are set on one side but not both, which flips flags on and off. In front of a single whole number, it flips every bit, so ~0 is -1. (^ was already taken — that’s my power operator!)

Examples

flags = flags ~ 0b0001
flags = flags & ~mask