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