+### Functions
+
+A function is a named chunk of code which can be passed parameters and
+can return results. Each function has an implicit type which includes
+the set of parameters and the return value. As yet these types cannot
+be declared separate from the function itself.
+
+In fact, only one function is currently possible - `main`. `main` is
+passed an array of strings together with the size of the array, and
+doesn't return anything. The strings are command line arguments.
+
+The parameters can be specified either in parentheses as a list, such as
+
+##### Example: function 1
+
+ func main(av:[ac::number]string)
+ code block
+
+or as an indented list of one parameter per line
+
+##### Example: function 2
+
+ func main
+ argv:[argc::number]string
+ do
+ code block
+
+###### Binode types
+ Func, List,
+
+###### Grammar
+
+ $TERM func main
+
+ $*binode
+ MainFunction -> func main ( OpenScope Args ) Block Newlines ${
+ $0 = new(binode);
+ $0->op = Func;
+ $0->left = reorder_bilist($<Ar);
+ $0->right = $<Bl;
+ var_block_close(c, CloseSequential);
+ if (c->scope_stack && !c->parse_error) abort();
+ }$
+ | func main IN OpenScope OptNL Args OUT OptNL do Block Newlines ${
+ $0 = new(binode);
+ $0->op = Func;
+ $0->left = reorder_bilist($<Ar);
+ $0->right = $<Bl;
+ var_block_close(c, CloseSequential);
+ if (c->scope_stack && !c->parse_error) abort();
+ }$
+ | func main NEWLINE OpenScope OptNL do Block Newlines ${
+ $0 = new(binode);
+ $0->op = Func;
+ $0->left = NULL;
+ $0->right = $<Bl;
+ var_block_close(c, CloseSequential);
+ if (c->scope_stack && !c->parse_error) abort();
+ }$
+
+ Args -> ${ $0 = NULL; }$
+ | Varlist ${ $0 = $<1; }$
+ | Varlist ; ${ $0 = $<1; }$
+ | Varlist NEWLINE ${ $0 = $<1; }$
+
+ Varlist -> Varlist ; ArgDecl ${
+ $0 = new(binode);
+ $0->op = List;
+ $0->left = $<Vl;
+ $0->right = $<AD;
+ }$
+ | ArgDecl ${
+ $0 = new(binode);
+ $0->op = List;
+ $0->left = NULL;
+ $0->right = $<AD;
+ }$
+
+ $*var
+ ArgDecl -> IDENTIFIER : FormalType ${ {
+ struct variable *v = var_decl(c, $1.txt);
+ $0 = new(var);
+ $0->var = v;
+ v->type = $<FT;
+ } }$
+