BFC: Brainfuck compiler for TI-83+

This is the official documentation of BFC R1 by ThomasW. It describes the usage of the named compiler as well as it gives a short introduction into how to write programs in the Brainfuck language.

What is BFC?

BFC is an on-calc Brainfuck compiler which translates Brainfuck source code directly into TI-83+ machine code. This leads to very fast binaries which may be run on any TI-83+ (no need to ship the compiler for running the compiled Brainfuck program!). Because it's run on-calc, you can code and compile your Brainfuck programs everywhere where you have your TI-83+ available, just like in TI-BASIC! BFC is free software: For licensing and warranty, have a look at the top of the included file bfc.z80.

Installation

Just transfer the included binary bfc.8XP to your TI-83+ by TiLP or a similar program.

Usage

  1. Create a new program on your calculator through pgrm-->NEW-->Create New as you usually do.
  2. Enter the Brainfuck source code into this program and exit.
  3. On homescreen, enter "(the name of the program where your source is in):(the name of the program where your program should be compiled to)"->Str1, e.g. "SRC:TGT"->Str1 would instruct the compiler to compile the source code in pgrmSRC to pgrmTGT. If you call Str1 on homescreen, it should display SRC:TGT in the example above.
  4. Run the compiler by entering Asm(pgrmBFC) on homescreen. The Asm( token can only be obtained through the catalog (2nd-->0), while the rest can be filled in by pressing pgrm and selecting BFC.
  5. Your calculator will display BFC R1(c)ThomasW and immediately exit with an exit code (Exception: The target program already exists and no other errors occured. In that case the compiler will display an additional line saying Enter: overwrite. Pressing Enter will delete the existing program that has the same name as your new target program would have, while any other key aborts the process and keeps your current program.) There are the following exit codes:
    0 Everything went fine.
    1 Str1 is misformatted, not present at all or archived.
    2 The source program could not be found or not be opened (maybe it's archived?) or the compiler asked you to overwrite and you cancelled.
    3 The number of the loop begins [ in your source code is not the same as that of the loop ends ].
    4 You have more than 255 nested loops (i.e. more than 255 loops are open at the same time) in your source code. This is not supported by this compiler currently.
  6. In case you have to change the source code and want to compile again, you don't have to set up Str1 again each time (except that you/another program has overwritten/deleted it). That is the main reason why I chose to use a Str instead of direct input in the compiler. Also, you don't have to manually delete the old binary of your source before running BFC again because it can do it for you.
  7. Run the compiled binary by Asm(pgrmTGT). In case it loops infinitely, just hit the On key, and it will return to TI-OS safely.

A short introduction into Brainfuck and it's Implementation in BFC

Well, I won't give you big stories here, there is a lot of information available on the Internet, but rather just some words about how to use the language.

There are eight characters which build four pairs in Brainfuck, respectively:

+ - Increments or decrements current value.
> < Increments or decrements index.
[ ] These two characters define a loop. The [ is the begin, it jumps only to after the ] if the current value is zero. The ] is the end, it always jumps back to the [. In other words: The inside of the loop is executed again and again as long as the current value at the beginning is not zero.
, . Inputs or outputs a character. Input in BFC is currently limited to 0-9 and A-Z, all other keys give their keycodes instead of what would be appropriate for their captions. It is also to note that the TI-83+ has a special character set which quite differs from ASCI (see below).

+ and - should be pretty much self-explaining. Every value is initialised to zero, that means that after one + it will of course be 1. Maybe a bit more tricky, after a - it's not -1 as someone might expect, but 255 which is the highest supported number (1 byte = 8 bits = 2^8 = 256 = 0..255). The same way it wraps around to zero again if it was 255 and a + is performed.

If you don't know what's meant by index, you can think of the following: A Brainfuck program has an array of memory available. In BFC it has the size 768, which means there are 768 places, each one byte, available to hold data needed in your program. In C syntax, that would mean char mem[768];, and you could use every place between mem[0] and mem[767]. You can also think of it as a list in TI-BASIC with a dimension of 768. Or, as a spreadsheet table (okay, thats two-dimensional, so concentrate on A1 to A768). When your program starts, the index (also called pointer) will point to mem[0], L1(1) or A1. A > will make it point to mem[1], L1(2) or A2, and a < will make it point to mem[0], L1(1) or A1 again. All other operands use the currently selected cell.

Be aware that BFC does not check the boundaries, so you can very well do something like accessing mem[-1], L1(0) or A0 which you probably think should be illegal for good reasons. The same applies for going higher than allowed (mem[768], L1(769) or A769). Be careful what you do in these areas. You can actually access (and modify!) the entire calculator's ram but you should know what you're doing, otherwise you might crash the calculator and lose your data (or maybe worse, I don't know...). So it's not considered a bug but rather a feature that the boundaries aren't checked (ha, good excuse for my laziness :P). Anyway, 768 bytes should be more than enough for every small- to middle-sized program, so there's no good reason for leaving the safe area. Better don't do it. You have been warned.

Loops can be nested like this: [[]]. The maximum nest level (i.e. how many loops are allowed to be opened concurrently) is 255. Every [ must have exactly one corresponding ]. A ] always closes the most nested loop.

Here is a table of the character set used for output, taken from Learn TI-83 Plus Assembly In 28 Days (c) 2002, 2003, 2004 Sean McLaughlin released under the GFPL.

char table

So in order to print a capitalized A, we need to output value 65, which could be done the following way: ++++++++[->++++++++<]>+. The eight + at the beginning set the first cell to 8, which will be used as loop counter. Then, as long as it is not zero, one is subtracted. The next cell is selected and eight is added. Then the loop counter is selected again and this gets repeated 8 times (because the loop counter was 8 in the beginning) so in the end the second cell is 8*8 = 64. Now, we need 65 for a big A so we add one more. The dot at the end outputs the big A.

Generally speaking, the shortest source code for "loading" a value can be produced by taking the nearest root less or equal to the value wanted and set the loop counter to that value as well as add this amount to the cell where the wanted value should be stored in the loop, then add what's missing after the loop, e.g. for 23 it would be shortest to use: ++++[->++++<]+++++++ But be aware that shortest source code doesn't necessarily mean best compiled code. The compiler could "optimize" and convert ++++++++ not to 8 times a=a+1 but to once a=a+8. Then, ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ would certainly be faster and smaller in compiled form than ++++++++[->++++++++<] BFC doesn't do this yet, but it might in a future version.

You should also know that you can safely use any other char in your Brainfuck source code, the compiler will simply skip it. This way, the 64 pluses could be arranged in 8 rows to make it easier to count. You can indent and even comment your source code without using stuff like // :D

More information

There's some more information in the source code file bfc.z80. You should read at least until before .nolist. If you're interested, also have a look at the code. I think it's quite simple to understand. Finally, you can search for Brainfuck on a search engine on the Internet and will likely find a lot of resources.