1
0

Updated BefunGen to >> BefunUtils

This commit is contained in:
2014-12-29 13:41:57 +01:00
parent 9ee572fa9f
commit 7500ee5b5a
25 changed files with 15 additions and 11 deletions

View File

@@ -0,0 +1,478 @@
TextFunge is the c-like language used for BefunGen.
Most constructs are very similar to C and Pascal, so you won't have trouble writing anything in it.
> *Note:*
> TexFunge programs are case-insensitive. *(but please be consistent with your naming)*
###Program structure
A TextFunge program starts with the keyword `program` and the program name and ends with `end`
```textfunge
program example_01 : display[0, 0]
begin
// code
end
void method()
begin
// code
end
end
```
between program` and `end` you can put your methods. The first method has no header and is called the main method.
This method is called upon the beginning and when this method has finished the program terminates.
You can specify a display by writing `: display[width, height]`, if the display is not specified its has a width and height of zero.
###Types
TextFunge knows 9 different variable types:
- Integer: A single integer value
- Digit: A single Base-10 digit (integer in the range from `0` to `9` )
- Character: A single character
- Boolean: A boolean value (`TRUE` or `FALSE`)
- Void: Nothing, used for methods that return nothing
- Integer Array: An fixed-length array of multiple integer
- String: An fixed-length array of multiple character
- Digit Array: An fixed-length array of multiple digits
- Boolean Array: An fixed-length array of multiple booleans
```textfunge
int a1;
integer a2;
int[4] a3;
char b1;
character b2;
character[4] b3;
bool c1;
boolean c2;
bool[4] c3;
digit d1;
digit[4] d2;
```
You can freely cast all value types into each other and all array-types with the same length (see *Casts* for more information)
###Variables
Between each method header and the `begin` keyword you can specify local variables under the `var` keyword:
```textfunge
void method()
var
int var_1, var_2;
int var_3 := 77;
int[4] var_4 := {0, 1, 1, 0};
char[4] var_5 := "FFFF";
begin
```
These variables have a local scope and can't be accessed from anywhere else.
You can also at the beginning of the program specify variables with a global scope
```textfunge
program example_02
global
int gvar_1, gvar_2;
int gvar3;
```
> *Note:*
> Global variables (unlike local variables) can **not** have an initializer, they will initially have the value which you specified while compiling.
To access a variable as whole just write its name, to access an specific array index write the index in square brackets:
```textfunge
var_1[0] = var_2[4 + 1];
```
###Constants
At the same position as global variables can (global) constants be defined:
```textfunge
program example_02
const
int VERSION := 14;
int COL_BLUE := 0x0000FF;
char UNDERSCORE := '_';
```
Be aware that constants are always in the compiled program inlined.
So constants are only *syntactical sugar* and result in the same as writing the literal everywhere, where you use the constant.
> *Note:*
> You can only define constants for value types, array constants are not *yet* supported.
###Literals
You can specify (Base-10) integer literals by simply writing the number:
```textfunge
0
9283
-9283
```
And also Base-16 (Hexadecimal) integer literals with `0x`
```textfunge
0x00
0xF0F
0x123
```
Digit literals have a `#` prefix:
```textfunge
#0
#6
#9
```
Char literals are surrounded by single ticks:
```textfunge
' '
'A'
'a'
```
Boolean literals consist of the two boolean keywords:
```textfunge
true
false
TRUE
```
String literals are surrounded by quotation marks: (Be aware that a string literal is only a shortcut notation of an char array)
```textfunge
""
"hello"
"hello \r\n second line"
```
And Array literals are the values inside of a set of curly braces:
```textfunge
{0, 1}
{'h', 'e', 'l', 'l', 'o'}
{true, false, true}
```
###Methods
Methods consist of 2 parts, the header and the body:
```textfunge
int[9] method(int a, int b, int[9] c)
var
int var_1 := 0;
int var_2;
begin
// Code
// Code
// Code
return c;
end
```
In the header you define the return type (value type, array type or `void`),
the method name (the normal C naming restriction are valid) and the parameter list (multiple value or array types).
Then you can (optionally) define local variables.
And finally between `begin` and `end` you can write your code.
> *Note:*
> Every path of an method must result in an `return` statement.
> If the return type is void the compiler can automatically add an return to the end.
###Control Structures
#### If / Elsif
```textfunge
if (a) then
// Code [a == true]
elsif (b) then
// Code [b == true]
elsif (c) then
// Code [c == true]
else
// Code [else]
end
```
You can write a branch statement with the keyword `if`.
Unlike C you have to write additional `else if`-branches with the keyword `elsif` and you have to end the whole block with `end`
#### While do
The `while` loop repeats a statement block until a condition is false
```textfunge
while (running) do
// Code
end
```
Every loop the condition is evaluated and checked.
#### Repeat until
The `repeat until` loop repeats a statement block until a condition is true
```textfunge
while (running) do
// Code
end
```
The difference to a `while` loop is that the condition is executed at least once.
#### For
The `for` loop is a more comfortable loop, because it has an initializer field, a condition field, and a statement field
```textfunge
// (init ; cond ; stmt)
for (i = 0; i < 10; i++ ) do
// Code
end
```
Each field can also be empty, allowing for this simple, infinite loop:
```textfunge
for (;;) do
// Code
end
// <-- unreachable (without goto)
```
#### Switch case
If you want to distinct multiple values you can use a switch statement:
```textfunge
switch(c)
begin
case ' ':
// Code
end
case '0':
// Code
end
default:
// Else-Code
end
end
```
> *Note:*
> This is **not** C, there is no fall-through with empty case blocks.
> *Note:*
> Having a lot of cases in a single switch can increase the horizontal size of your program drastically.
> Think about using other possibilities in this case
#### Goto
```textfunge
goto MLBL;
out "Nobody sees me";
MLBL:
out "end";
```
You can define labels by writing the identifier and a colon (instead of a semicolon).
And you can write goto statements with the keyword `goto`
> *Note:*
> This is **not** C, you have to end an goto statement with an semicolon, like every other statement too.
> *Note:*
> Use goto's sparely, they are pretty slow and I'm not sure if they are bug-free.
###Expressions
####Mathematical operators
You can use the normal mathematical operators `+`, `-`, `*`, `/`, `%` (modulo), `(` and `)`.
Normal precedence rules apply
```textfunge
a = ((5 + 5)*4 - 10)/-1 % 4;
```
####Boolean operators
You can use the boolean operators `&&` (AND), `||` (OR), `^` (XOR), `!` (NOT).
```textfunge
a = (10 == x) ^ true;
b = !(10 == x);
```
####Comparison
You can use the normal c-like comparison operators `==`, `!=`, `<`, `>`, `<=` and `>=`
```textfunge
while (a < 100 && a > -100) do
a *= 2;
end
```
###Special Statements
####Random
You can either generate a random boolean value by using `rand`, or a random integer value by using `rand[?]`.
`rand[n]` generates a random number from [0, 4^n), where 0 is included and 4^n is excluded. So you are only able to set the upper border to results of the formula 4^n.
```textfunge
if (rand) do
a = rand[6] % 10;
end
```
> *Note:*
> Be aware that in the example above not all values are equally distributed (4^6 % 10 != 0), but approximately it is good, and it becomes better with bigger values for n.
####Quit
The statement `quit`, `stop` or `close` instantly terminates the program. The main method will always implicitly have an `quit` at the end.
```textfunge
if (error != 0) then
out "FATAL ERROR";
quit;
end
```
####Code block
You can start everywhere a new code block, it probably wont change the resulting program but has its use in structuring the source code.
```textfunge
// Code
begin
// Code
// Code
end
// Code
```
####De-/Increment
With `++` and `--` you can increment/decrement a variable in a shorter way than a assignment.
```textfunge
a++;
a = a + 1; // equally
```
####Assignments
With a single `=` you can assign a value to a variable.
```textfunge
a = 3;
b[3] = 0;
```
###Method calls
Method calls are pretty much like in every other language.
```textfunge
method_1(0, 6, "hello");
method_2(getA(), getB(0));
```
###Comments
You can write either full line comments with `//` or block comments with `/*` and `*/`
```textfunge
/* Comment
* Comment
*/
// Comment
method_99( /* comment */ );
```
###Casts
TextFunge supports explicit and implicit casting.
The cases in which implicit casts happen are:
- `digit` -> `int`
- `digit[]` -> `int[]` (with same length)
You can cast all other value types into each other and array types if they have the same length.
```textfunge
var
bool b;
int i;
char c;
begin
c = (char)i;
b = (bool)c;
```
> *Note:*
> When casting no information is lost, so hard casting to an digit can yield to an illegal value.
> Also casting something from an boolean does not always result in `0` or `1` (it results in `0` / `not 0`). If you want this you can enable "explicit boolean casting" in the compiler options.
###Input/Output
####Out
With the statement `out` you can output either a value or a string:
```textfunge
out 99;
out 'a';
out "Hello World";
out var_1;
```
####OutF
`Outf` is a shortcut to writing multiple `out` statement. You can give it a comma-separated list of expressions to output
```textfunge
out 99, 'a', "Hello World", var_1;
```
####In
With the `In` Statement you can ask the user for a value, the input routine differs when you give it a integer variable or a character variable.
```
var
int var_1;
char var_2;
begin
in var_1; // Asks for number
in var_2; // Asks for character
```

View File

@@ -0,0 +1,37 @@
In TextFunge you can optionally define a read- and writable display area.
```textfunge
program example_01 : display[16, 16]
```
The display has a width and a height and every field has initially the value you set in the options (the standard is space).
You can access the display with the `display[x, y]` command.
```textfunge
display[0, 0] = 'X'; // Write 'X' to position (0,0)
c = display[0, 1]; // Set c to the value of (0,1)
```
There are also a few automatically defined constants for teh work with displays:
```textfunge
DISPLAY_WIDTH // The width of the display
DISPLAY_HEIGHT // The height of the display
DISPLAY_SIZE // The size (width*height) of the display
```
You can use the display to
- display information to the user without using input commands
- gather a big amount of data from the user before execution (he has to fill the display manually)
- use it as a big 2-dimensional array for calculations
> **Note:**
> Beware that there is normally no mechanism to control access overflow.
> So you can enter to high/low x/y values and access/modify program pieces that are not part of the display.
> This is a way of bricking your program by writing in the area of program code
>
>**Tip:**
> You can prevent this by enabling the compiler option *Prevent display overflow*.
> But beware that tis will result in longer display access times.

View File

@@ -0,0 +1,37 @@
There are a few things you should consider when creating programs with Befunge:
###Number ranges
The size of the internal numbers is dependent on the interpreter, while you can safely assume that the number is at least 16bit, everything higher is not sure.
So for bigger programs you have to either work with smaller numbers or use interpreters which use bigger sizes.
> **Tip:**
> [BefunExec](/programs/view/BefunGen) uses 64bit integer (= long values).
###Negative numbers
A real problem are negative numbers. In created programs variables are saved in the grid.
If the interpreter does not support negative grid values you will not be able to use negative numbers.
But don't worry too much - most interpreters I know support negative numbers in the grid.
###Performance
BefunGen is definitely not a tool to create fast Befunge programs, it's a tool to create big ones.
And while it optimize your program quite a bit, a manual written program will always be faster and smaller.
So for bigger programs you will also need an fast interpreter - otherwise the execution could take a long time
> **Tip:**
> [BefunExec](/programs/view/BefunGen) is a pretty fast multi-threaded interpreter.
###Program size
While the generated programs are strictly bound to the Befunge-93, they can become pretty big (bigger than 80x25).
So you have to either use a Befunge-93 interpreter which ignores the size limit (many interpreters do that)
or use a Befunge-98 interpreter.
> **Tip:**
> [BefunExec](/programs/view/BefunGen), as you probably can assume, has no "real" size limit to it.

View File

@@ -0,0 +1,29 @@
Here a few tricks for programming with BefunGen:
###Horizontal size
Normally a program only grows in height, the more instructions your program has the greater is the height of the generated code.
So it is kinda bad when you have one really long line, because the width of the program is determined by the longest line.
So its good to try to avoid long lines for the sake of smaller - more compressed programs.
Here are a few common cases which compile to long single lines:
- Deep Nesting (e.g. multiple nested `for` loops)
- A lot of consecutive `elsif` statements
- `Switch` statements with a lot of cases
- Function calls with a lot of parameters
- Very long arrays
- Complex "one-line" statements (e.g. multiple nested method calls)
Neither of these things has any real consequence - except your program having a lot of empty space.
###Display as array
If you are in need of a really big array, or of a 2 dimensional array you can use the display for that.
The display is an easy way of having an **global** 2dimensional array, that is easily visible to the user.
###Constants
You can without hesitation use constants in your program, they are inlined on compilation and have no performance cost at all.