bf manual version 0.8.2a
_-_-_-_-_-_-_-_-_-_-_-_-

This is bogusforth, an obfuscated language based mainly upon forth 
(widely known) and false, another obfuscated language by Wouter van 
Oortmerssen. Many ideas were also taken from TRUE, by Dewi.
Therefore, thanks to Moore, Wouter and Dewi.

It's GPL! Enjoy!

Antonio Maschio <tbin@libero.it>

Language specs
-_-_-_-_-_-_-_-


1. Notation
-----------

The following stack values are used in commands notation:
n		a number
[f]		a function
"s"		a string
d		a number, string or a function
f		a flag (true/false)
v		a variable
x*d		a non definite number of data


2. Input strings
----------------

Input string are evaluated from left to right, just like in forth. 
Any line is 256 characters long; this is not a limitation, since commands use 
a stack or variables, so any command may reside on a single line each,
and the result would be same; besides, input is buffered, so if your
line is, say, 356 chars long, the first 256 will be evaluated as the
first command line, and the rest as the second.
BEWARE! commands are single chars, and may be divided, but numbers, strings 
comments and functions are not, so they may get split. For secure input,
limit input lines to be not longer than screen monitor (circa 80 chars).


3. Entities
-----------

The following are the bricks of the whole language. 

3.1 
numbers (0-9; H; O; B)

Numbers are only long int integers (ranging from -2^31 to 2^31-1);

- negative numbers must be input with '\' (negate) after them, as in 345\;
- hex numbers may be input with H *JUST* after them, as in 345H;
- octal numbers may be input with O *JUST* after them, as in 345O;
- binary numbers may be input with B *JUST* after them, as in 1010B;

Anyway, stack treats only decimal numbers. I'm working on HOB output.
	
3.2 
variables (a-z; A-Z)

they can host numbers, strings and functions; variables names are 
constituted by single letters, but 'a' and 'A' are distinct variables, 
so the programmer may use 26 x 2 = 52 variables. Not much, but a wise 
use of the stack may help. See 4.1.
	
3.3 
strings

they are input enclosing them into double quotes ".." - ( - "s" ).
If you omit the last ", everything from the first " up to the end of line
will be a string.

3.4 
comments

they are input enclosing them into curly brackets {..}.
If you omit the last }, everything from the first { up to the end of line
will be a string (similar to the // comment of C++). 
But beware: any { input after the first will be ignored, since the first } 
found will close the first { set.

3.5 
functions
	
they can host a complete command line, and they support if and while commands.
they are input enclosing them into square brackets [..] - ( - [f] ).
Functions may be nested.

3.6 
tests

0	zero - false value (left by tests).
1	one - true value (left by tests). Anyway, any non-zero value is true,
	like in C.

3.7 
conclusions

any other char than those compounding the language is discarded, so
you may overobfuscate your code by inserting here and there any char,
which will confound the reader (but not the compiler, I hope!).

	
4. Commands
-----------

4.1 
variable treatment

the following commands must be put *JUST* after the variable name.
treated as different commands or discarded. See relative notes.

!	exclamation mark ( d v - ) 
	store a value into a variable, as in 23f! (will store 23 into f).
	
:	colon ( v - d ) 
	fetch variable content, as in f:, and leave it on tos.


4.2 
function command

@ 	at ( [f] - x*d ) 
	execute [f], which may be left on tos by a direct command, 
	as in ["executed"i.]@ or after a variable fetching, as in d:@.

4.3 
control flow commands

? 	question mark ( f [f] | f [f1] [f2] - x*d ) 
	if-then-else; in the first form ( f[f]? ) execute [f] if f, 
	in the second ( f[f1][f2]? ) execute [f1] if f, otherwise [f2].

# 	number ( [f1] [f2] - x*d ) 
	while cycle; while [f1] execute [f2]. It's the only cycle admitted, 
	as in false and in TRUE. It would have been easy to implement a 
	form of for..next, but I don't like it much. Maybe in the future...
	
t	letter t ( - ) 
	tear away remaining input line, without parsing it.

4.4 
stack commands

% 	percent ( n - n n ) 
	dup.
	
; 	semi-colon ( n - ) 
	drop.
	
$	dollar ( n1 n2 - n2 n1 ) 
	swap.
	
_	underscore ( n3 n2 n1 - n2 n1 n3 ) 
	rot.
	
r 	letter r ( n1 - n2 ) 
	roll, with control over limits. 0r does nothing; 1r does nothing; 
	2r = $; 3r = _. If n1 is beyond stack depth, does nothing.
	
p	letter p ( n1 - n2 ) 
	pick, with control over limits. 0p does nothing; 1p = %; 2p = over 
	(like in forth, but this specific command is not part of bf).
	
:	colon ( - ) 
	show stack content, leaving it untouched.
	
)	right parenthesis ( x*d - ) 
	empty stack (but maintain variables). In my opinion, good programming 
	should always end with an empty stack, after all calculations are done 
	and results shown, and this command helps in doing this.
	
}	right curly bracket ( - ) 
	If used outside a comment, leave on tos current stack depth, 
	a value between 0 and 255. If you need more stack space, change 
	the value of STACKMAX in bf.h and recompile.
	
4.5 
math commands	

* 	asterisk ( n1 n2 - n1*n2 ) 
	multiplication.
	
+ 	plus ( n1 n2 - n1+n2 ) 
	addition.
	
- 	hyphen ( n1 n2 - n1-n2 ) 
	subtraction.
	
/ 	slash ( n1 n2 - n1/n2 ) 
	integer division.
	
m	letter m ( n1 n2 - n3 ) 
	modulus n3 of n1/n2.
	
^	circumflex accent ( n1 n2 - n3 ) 
	n2th power of n1. Controls are taken over zero base and negative exponent, 
	which would lead to a 1/0 fraction.
	
!	exclamation mark ( n1 n2 - n3 )
	if used not just after a letter, gives the integer n2th root of n1, 
	with control over zero root (which would lead to a 1/0 exponent) 
	and over negative base and odd exponent (which would lead to a complex 
	mathematics).
	
\	backslash ( n - -n ) 
	negate number on tos.
	
g	letter g ( f - ) 
	generate random number if f is True, otherwise set random seed
	
4.6 
logical commands

= 	equal ( d1 d2 - f ) 
	true if d1 = d2 (for strings and function, usual conventions apply).
	
>	greater than ( d1 d2 - f ) 
	true if d1 > d2 (for strings and functions, usual conventions apply).
	
& 	ampersand ( n1 n2 - f ) 
	logical and.
	
| 	vertical bar ( n1 n2 - f ) 
	logical or
	
~ 	tilde ( n - f ) 
	logical not.
	
l	letter l ( n1 n2 - f ) 
	logical xor.
	
4.7 
bitwise commands

a	letter a ( n1 n2 - n3 ) 
	bitwise and.
	
o	letter o ( n1 n2 - n3 ) 
	bitwise or.
	
n	letter n ( n1 - n2 ) 
	bitwise not (1 complement).
	
x	letter x ( n1 n2 - n3 ) 
	bitwise xor.
	
4.8 
input/output commands

i	letter i ( n - ) 
	print tos (number, string or function).
	
j	letter j ( n1 n2 - ) 
	print number n1 in a field of n2 chars (filled with spaces if number is 
	smaller). If number is longer than n2, n1 is printed with no field.
	
k	letter k ( n1 n2 - ) 
	print number n1 with n2 decimal digits after the dot (useful for 
	printing fixed sized decimal numbers calculated as integers).
	
< 	lesser than ( - "s" ) 
	read input string from keyboard.
	
( 	left parenthesis ( "s" - x*d ) 
	read input stream from file whose name is on tos. File lines are read 
	sequentially until EOF or an error is met. Stack may result changed, 
	after this operation, so you may ) before launching a file, if you need 
	stack checking. Use the form f( to read and execute buffer file (see f).
			
4.9 
string and char commands

`	grave ( - n ) 
	put on tos ascii code of the following char on stream; it's the only 
	command which must be put before its input. If followed by a blank space, 
	puts 32; if followed by a tab, puts 9; if last on stream, assumes next 
	command is a return, so leaves 13. This command always succeeds 
	(and never return '\0').
	
'	single quote ( n - ) 
	emit char whose ascii code is on tos. 13' is a CR, 9' is a HT 
	(horizontal tab), 7' is the bell (on some systems, 7' may not work).
	
,	comma ( "s" - n ) 
	convert string on tos to number, leaving it on tos. Input numbers 
	with <, (see <).
	
.	period ( - ) 
	emit a Carriage Return (more elegant than 13').
	
e	letter e ( "s1" n - "s2" | n ) 
	extract nth char of string "s" and leave it on tos. Values of n 
	range from 0 to strlen("s") - 1. If n is >= strlen("s"), return a 
	null string. If negative, return string length.
	
u	letter u ( "s" - n ) 
	unveil ascii code of first char of string "s" and leave it on tos.

4.10
system commands

Some of the following commands are #def driven.
In UNIX systems, commands such pwd and cat are very common and useful.
In Windows they are available only through external software
such as djgpp and mynsys. If you happen to have a working gcc and some
unix software (ls.exe, pwd.exe, cat.exe and less.exe are needed)
uncomment the #undef WIN32 line in bf.h and recompile. You will
gain the full bf capabilities. See bf.h.
	
h	letter h ( - ) 
	help on system command list.
	
v	letter v ( - ) 
	print vocabulary (with short explanations) by screens.
	
d	letter d ( - ) 
	list directory. Executes "dir" on windows/dos systems, and "ls" on unix 
	systems. You can change commands (adding options, for example) modifying 
	COMDIR in bf.h for UNIX environments and recompiling.
	
w	letter w ( - ) ONLY FOR UNIX
	print working directory. If you have similar system commands for 
	windows/dos, you may redefine COMDIR for WIN32 environments in bf.h 
	and recompile, uncommenting #undef WIN32.
	
c	letter c ( "s" - ) 
	change working directory to "s". Absolute, relative and mnemonics 
	strings (like ..) may be used.
	
b	letter b ( "s" - ) 
	reset buffer file name to "s".
	
f	letter f ( - "s" ) 
	leave on tos current buffer file name.
	
y	letter y ( "s" - ) 
	yield stack content to file "s".
	
]	right square bracket ( - ) 
	if used outside a function, toggle on/off appending current input line 
	into file ./bf.bf. Use b to change buffer file name (see). If ] is 
	contained in the input line, the char itself won't be written to file.
	
s	letter s ( "s" - ) ONLY FOR UNIX
	show contents of file identified by "s". Executes cat | less.
	
q	letter q ( n - ) 
	quit interpreter immediately with status n. Of course, commands 
	following q will never be executed, and stack content will be lost. 
	Normal program termination is 0q, abnormal is nq, where n is a 
	programmer's defined error code (the same code is returned to the 
	operating system, for the appropriate measures, if it can manage it).


5. some remarks
---------------

5.1 
apparently missing commands

5.1.1 
You may have noticed that lesser than is missing. But a wise use of 
the stack may replace any test command, with only >, ~ and $. See this:

greater than is				>
lesser than is 				$> (swap and test again)
lesser than or equal is		>~ (not greater)
greater than or equal is 	$>~ (not lesser)
equal is 					=
not equal is 				=~ (not equal)

Fancy, huh?

5.1.2 
Also, you may have noticed that at present it's impossible to assure 
writing specific string to stdout, if a program is redirected to a file. 
Try to set something like:

"Enter your name:"i.<"Hello, "ii.0q

into a file called, say, "greetings.bf", then type:

./bf -q greeting.bf > greetings.out

You will see that the program is waiting for your string, but that the message
has been written to file, not to stdout. If you digit, say

Hugo

the program will end. Look at greetings.out; you will see:

Enter your name:
Hello, Hugo

but you'd probably have liked more to see "Enter your name" on screen
(and maybe on file) and the output on file. I'm working on this.
