18
loading...
This website collects cookies to deliver better user experience
+-><[],.
. Each of them can take an argument represented by a number directly after the command. Just like in brainfuck the commands operate on a linear memory using a single pointer. Anything that's not a command or a number is a comment and is ignored by compilers.+
/-
: add/subtract the argument from the selected cell.>
/<
: move the pointer up or down the memory according to the argument.[
/]
: jump forwards/backwards some number of commands if the selected cell is zero/nonzero.,
/.
: input/output the selected cell. Argument use depends on the BPU build, I will ignore it completely here.+-><[]
commands are called "add commands" and their argument must be at least one. It's also assumed to be one if you don't specify it, but that's a bad practice and leads to less readable code. ,.
commands are "I/O commands" ant their default is zero. There will also be a maximum argument depending on the BPU architecture. This tutorial assumes an 8-bit BPU, so max arguments are 32 for add commands and 31 for I/O commands.In memory explanations cells are divided with pipes (|)
and the current cell is marked by *asterisks*.
Starting memory: *some number*
[3 Jump over the loop if the cell is already zero
-1 Subtract one
]1 Jump back until the cell is zero
Final memory: *zero*
for (i = cell; i > 0; i--) pass;
. It's very important to think about actions in BAL in terms of "repeat something N times" and most loops will end with -1 ]X
.Starting memory: *N* | zero
[6 Jump over the loop if the cell is already zero
>1 Move over to the cell that the value is moved to
+1 Increment it
<1 Move back to the original cell
-1 Decrement it
]4 Repeat until original cell is zero
Final memory: *zero* | N
Starting memory: *M* | N | target (zero)
[11
>1 Move over to N
Add N to the target
[6 >1 +1 <1 -1 ]4
<1 Get back to M
-1 Close up the loop
]9
Final memory: *zero* | zero | N
Starting memory: *M* | N | target (zero) | helper (also zero)
[20
>1 Move over to N
Move N to the target and helper
[8
>1 +1 Increment target
>1 +1 Increment helper
<2 -1 Decrement N
]6
>2 Move to helper
Move helper back to N
[6 <2 +1 >2 -1 ]4
<3 Get back to M
-1 Close up the loop
]18
Final memory: *zero* | N | N*M
]
command which jumps back and facilitates looping: executing the same code multiple times. Now is the time to take a closer look at the [
command which jumps forward and facilitates ifs: skipping parts of the code based on a condition.-1 ]1
. It starts by subtracting one, and then repeats it until the cell is zero. The problem arises when the cell is zero before this loop starts. Since BAL is supposed to be executed on hardware solutions, subtracting one from zero will result in overflow and wrap back to the maximum value the cell can hold (255 for 8-byte solutions), and then repeat the loop the maximum possible number of times until it's back at zero. That's why it's usually worth it to spare this one additional memory cell for a [
command before most loops.if n == 0 then
do something
else if n == 1 then
do something else
else if n == 2 then
do something even more different
else
do the final thing
end
[
offers jumping if the number is equal to zero. This means the code requires some reorganisation:if n == 0 goto N0
if n == 1 goto N1
if n == 2 goto N2
do the final thing
goto END
N0:
do something
goto END
N1:
do something else
goto END
N2:
do something even more different
END:
[9 Jump if N equals zero
-1 [9 Jump if N minus one equals zero
-1 [9 Jump if N minus two equals zero
do the final thing
-1 ]1 Set N to zero for the jump
[6
do something
[4 N is already zero here so it can be used for jump
do something else
[2
do something even more different
Starting memory: *zero* | anything
+10 >1 Set cell to the bumper value and move over
Intermediate memory: bumper | *anything*
Intermediate memory: bumper | *anything* | more of anything
, Read a byte
-10 [6 Don't enter the loop if newline
+10 Restore original value
>1 , Move over and read a new byte
-10 ]4 Stop looping if newline
Memory after one cycle: bumper | byte | *anything minus ten* | more of anything
Intermediate memory after the loop terminates: bumper | many bytes | *zero*
Intermediate memory: bumper | many bytes | *zero*
<1 Move to the last byte
-10 [6 Don't enter the loop if already at the end
+10 Restore original value
. <1 Write and move to the next byte
-10 ]4 Stop looping if at the end
Memory after one cycle: bumper | many bytes | *byte* | zero
Final memory: *zero* | many bytes
+10 . Set the bumper back to newline and print it
]19 Jump back to the start
]3 ]30
then when it's executed normally either the first jump will take place or no jump will take place. On the other hand if you jump directly into the ]30
it will continue jumping back allowing for jumps bigger than whatever your maximum argument is.>22
at the start of the setup, which gives the complete and working program:>22
+10 >1 Set cell to the bumper value and move over
, Read a byte
-10 [6 Don't enter the loop if newline
+10 Restore original value
>1 , Move over and read a new byte
-10 ]4 Stop looping if newline
<1 Move to the last byte
-10 [6 Don't enter the loop if already at the end
+10 Restore original value
. <1 Write and move to the next byte
-10 ]4 Stop looping if at the end
+10 . Set the bumper back to newline and print it
]19 Jump back to the start
[
and ]
commands to create advanced loops and conditionals. With such powerful tools you can write anything! Just remember to carefully plan your memory usage and the BPU is your oyster.