Chapter 1: Script entry and context

1.1. What is fawk?

Fawk ("Function AWK") is a dialect of the AWK programming language, built on libfawk, a custom Virtual Machine (VM). Libfawk comes with different scripting language frontends, including fawk, fbas ("Function BASIC") and fpas("Function Pascal"). This tutorial demonstrates every feature of the libfawk VM using the fbas language for examples.

A libfawk script is always running embedded in a host application, which is a bigger program, typically written in a C-like language. Since libfawk has almost no I/O, there are two interfaces to the outside world:

Normally the job is split up between the host application and libfawk in a way that the host application implements the functions that can execute the low level tasks (the "how do we do it" part) while the script is responsible for the high level logics ("why do we do it").

1.2. Fawk code

A libfawk script consists code (in form of functions) and data memory (in form of variables, called cells). The BASIC program has instructions outside of functions. These are all part of the main section. This is the entry point, the first code the host application should call. Depending on the application:

Beside main, the API (function names and parameters) between the host application and the script are always specific to the given host application. This is true in both direction: for script implemented functions the host application will call and for the application provided functions the script can call. The API should be documented in the host application's documentation.

For this tutorial, we will use fawk(1), shipped with libfawk. This is a tiny host application, indented for diagnostics. It implements the bare minimum: it calls the main of the script and does not provide any application funtion for the script. However, that is enough for this tutorial, since the focus is the scripting language and the VM, not any specific host application.

1.3. Functions, main

A libfawk function has a name unique in the script context, has zero or more parameters and has a return value. The type of the parameters and the return value are all flexible and decided run-time. More on this in chapter 2.

The syntax for defining a function is: function funcname(argname1, argname2, argnameN) statments end function

In this tutorial text written in italic in the examples are parts that the user needs to fill in; the rest, written with normal font are keywords.

If there are no parameters, an empty () needs to follow the function name. Libfawk is not white-space sensitive: there can be spaces between function and funcname and (), the opening brace can be in the same line, with or without space. The part between the "function" and "end function" lines is called the body of the function. The function line and the end funtion line must be in separate lines from the function body.

1.4. Hello world

The classic hello world program in fbas:
example program ch1_ex1
fawk_print("hello, world")

Function fawk_print() is a libfawk builtin, implemented in C, which prints all arguments supplied then a newline, to the standard output. In our case this one argument is an immediate string literal, which is written using doublequotes in fbas. Alternatively fawk_print_cell() can be used which prints verbose information about the arguments passed, including type and length and reference counters.

Running the script with fawk from a shell, assuming the script is saved as hello.bas:

fawk -Wb hello.bas

Alternatively rename or symlink the fawk to fbas; -Wb can be omitted when using the executbale with name fbas.

Unlike classic BASIC, fbas does not have PRINT or INPUT instructions. The fawk_print() call, which usually can be used to print to the standard output is a real function call, so it requires parenthesis around its arguments and the arguments have to be separated by comma.

The dialect fbas implements is closer to a third generation "OOP" BASIC (e.g. VisualBasic) than to first generation "unstructured" (e.g. GW-BASIC) or second generation "structured" (e.g. QuickBasic) dialects.

1.5. Separators

The fawk_print line is a function call. A function call is an expression (because it has a return value). We did not use the return value in this example. Whether the return value is used or not, the whole line becomes a statement: an atomic part of a code sequence (e.g. function body) that needs to be executed ordered the same way the source code is.

A function can have any amount of statements. For example this script will print the two words in two lines:
example program ch1_ex2
fawk_print("hello,")
fawk_print("world")

1.6. multiple functions

A BASIC source file is a sequence of statements and functions. Statements outside of any function are all considered part of the main code that will be run in order of appearance at the beginning of the script execution. Functions are called by name from the host app or from the script. The following example demonstrates how to declare multiple functions:
example program ch1_ex3
function hello()
	fawk_print("hello,")
end function

function world()
	fawk_print("world")
end function

hello()
world()

In this example main first calls hello() with no parameter and then calls world() with no parameter. The order of functions is arbitrary, the following script is equivalent to the previous one:
example program ch1_ex4
hello()
world()

function world()
	fawk_print("world")
end function

function hello()
	fawk_print("hello,")
end function

1.7. comments

The rem statement ("remark") and words written in the same line are ignored. Remarks are called comments in scripting, libfawk uses this terminology too.

rem This is a comment
fawk_print("rem this is not a comment and will be printed")

Comments are filtered out while loading a script. . A function body is always a block. But wherever a single statement can be written, a block can be written too. This will be useful with flow controls in chapter 3:
example program ch1_ex5