Flow Control - mdoug/FIAL GitHub Wiki
Flow control in FIAL is actually a tad peculiar -- it features "named blocks", which allow flow control manipulation using "leave" and "redo". "If" is also a provided.
While it is the goal of this tutorial to describe what FIAL is as opposed to what it isn't, in this instance I think it is worthwhile that named blocks, and leave, construct a flow control mechanism that is similar to what can be done with exceptions in other langauges, with the block being a try .. catch statement, and the leave being a throw.
The differences are:
- that this is not intended to be "exceptional" in FIAL, rather it is the primary form of flow control.
- Values are not thrown. There is a simple way to have a value accessible at both points, however, due to dynamic scoping in FIAL.
- Instead of leaving a block, it can be repeated by using "redo" instead of "leave". In this way, the need for other looping mechanisms is allevaited.
FIAL has blocks. blocks have two purposes:
() to delineate the scope of variables () Combined with if, break, and continue, they provide flow control.
A block is defined by an opening brace, then optionally by a name followed by a colon, then statements followed by a closing curly brace --
{ my_block :
var v1, v2
v1 = 10
v2 = 20
}
Nothing outside of my_block will be able to access v1 or v2, which are destroyed when the block reaches its end. The name on a block is optional.
{
var var_in_an_unnamed_block
}
FIAL supports if statements:
if expr block
This will execute "block" if expr evaluates to true (currently, non zero integers are considered true, and maybe some other stuff, I forget. Just use equalities and stuff! I will figure this out better later. )
Note: There is no "else". It is not necessary in this flow control framework.
Both leave and redo follow similar rules, though they do different things. Since both prevent the flow control of the program from ever getting past them, both leave and redo statements must be followed by a closing curly brace.
You can leave out of any named block by using leave followed by the name of the block. Optionally, a ':' can be placed between the "leave" keyword and the block name. Leaves must have names. To escape the immediate block, use a closing curly brace.
Redo works similarly, except instead of exiting the block and moving forward, it causes the block to repeat itself. It can also be used without a label to repeat the current block.
Thus, using just these four things, we have sufficient flow control mechanisms. Consider the folowing, using a block named else to effect variables based on whether or not an equality holds :
{ else :
if(var1 == var2) {
var1 = 0
leave else
}
var2 = var1 - 10
}
this can be extended to "switch" or "case" statements, consider the following code, which includes procedure calls as placeholder statements. Though they have not yet been covered, they are not important here.
var something, something_else, yet_again_something_else
{ switch :
if(something) {
do_something
leave switch
}
if (something_else) {
do_something_else
leave switch
}
if (yet_again_something_else) {
do_yet_another_thing
leave : switch /* this colon can be used optionally for now, I think I
will take this out at some point, however */
}
}
Loops are also simple, this example is using a block named "loop" to add numbers 1 through 10.
var counter, stop_at, accumulater;
counter = 1;
stop_at = 10;
accumulater = 0;
{ loop :
if ( counter > stop_at) {
leave loop
}
accumulater = accumulater + (counter + 1)
counter = counter +1
redo
}