$Id: README,v 1.3 2003/08/21 17:49:46 rene0 Exp $

BF2C - Optimizing BrainFuck to C compiler.

(draft readme)

*** It's usage: ***

-h : usage message.
-i file : specify input file (defaults to stdin)
-o file : specify output file (defaults to stdout)
-r number : specify cell size (defaults to 8 bits)
-s number : specify tape size (defaults to 65536 cells)

The version number reported by the main module is only an "overall" version,
individual versions of the various files are maintained by CVS.

*** The language: ***

BrainFuck is a minimalistic but Turing complete programming language devised
by Urban Mueller. It is oriented around a tape, a read/write head, an input
and an output device.

There are 8 instructions available:
Char	Name	action
+ -	Val 	increase/decrease the value of the tape cell pointed to by
		the head
> <	Ptr	move the head 1 position to the right/left
[	Do	loop while the contents of the tape cell is nonzero
]	Od	closes a loop
,	Get	read a value from the input device and write the ASCII code
		of that value to the current tape cell
.	Put	output the value from the current tape cell as an ASCII
		character to the output device

Any other character represents a comment.

The de facto default values for the environment are:
cell : 8 bits wide
tape : 10000,30000 (original value) or 65336 cells wide
The head position and cell values are mostly wrapped.

Initially, the head points to cell 0 (the leftmost one) and all cells contain
the value 0.

Example programs: both "[-]" and "[+]" set the current cell value to 0 and
"[-]." outputs a NUL character.

*** The program: ***

The program uses 'a' as name for the tape and 'p' as the value of the head's
position.

** Terminology: **
* Mulzero
  	A loop dedicated to multiplying values and clearing the current cell
	after wards (hence it's name).
	"[-]" and "[+]" are the most obvious ones, they only zero out the
	current cell.
	"[>+++<-]" thus equals "a[p+1] += 3 * a[p] ; a[p] = 0"
	Multiple multiplications are possible.
	Note that the current cell value may only be increased or decreased by
	one, since other values may cause infinite loops.
	Also, only Ptr and Val tokens are allowed within the loop.
	
* Non-i/o tail
	All statements of the program after the last loop and after the last
	Get and Put token.

* Absolute header
	Because of the initial state of the program, all C code before the
	first loop can be made absolute. This means that all Ptr tokens can be
	removed after recording the head position in the other statements and
	all Val and Put can be made absolute.
	Also, values are calculated on the fly and only the resulting value is
	written to the final parse tree. This includes values derived from
	mulzero's.
	Positions with Get statement are necessarily made relative, but are
	made absolute again after a Val token with an absolute value.

** The structure: **
For each token, a separate class has been defined:
	* Token (a generic class, ancestor of all real token classes)
	* Eof (end of file)
	* Mulzero (synthesized by the optimizer)
	* And all tokens recognized by the scanner have a separate class.

Each token class has methods for generating C code, interpreting itself,
setting and retrieving it's various values and states and testing if it's
usable in the parse tree (i.e. if it isn't redundant).

The parse tree is cleaned in the following way :
* neighbouring tokens of the same type are unified
* (resulting) redundant tokens are removed
* loops right after a loop and before a Get,Val or Ptr token are removed since
  they are never executed.
* the non-i/o tail is removed

The parse tree is optimized as follows:
* mulzero's are detected and generated
* the header is made absolute
* Val and Get statements are unified in a non-redundant way

Comments are never added to the parse tree.

Tokens are scanned in a cumulative way and a count is kept for the tokens,
except for Do and Od. This results in a much smaller initial parse tree and
reduces the work in the cleaning phases.
