[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22. Afl

Afl is the af extension language, a simple programming language which allows you to write files containing af commands. Afl is similar to the Lisp programming language, so Lisp programmers should find afl easy to learn. Afl should be simple enough that it is easy for other programmers to learn.

Afl is designed for programmers to use, although once a programmer has written an afl program anyone should be able to use that program.

22.1 Basic Afl Concepts  An introduction to afl.
22.2 Afl Data Types  Data types used in afl.
22.3 Afl Primitive Functions  The predefined afl functions.
22.4 Running Afl Programs  How to run an afl program.
22.5 Examples of Afl Code  Samples of afl code.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.1 Basic Afl Concepts

Afl programs are made up of one or more afl objects; pieces of data used and manipulated by afl programs. For our purposes, a type or data type is a set of possible objects.

When you run an afl program, the afl reader is called to read the textual representations of the afl objects in the program, and convert them to actual afl objects. If you try to display an object, the afl printer is called to generate a printed representation of the object.

The evaluation of expressions in afl is performed by the afl interpreter; a program that receives an afl object as input and computes its value as an expression. How it does this depends on the data type of the object. An afl object that is intended for evaluation is called an expression or a form.

The most useful type of afl object to evaluate is lists. When you evaluate an afl list, the head of the list is evaluated as a function, and then the remaining items in the list are passed as arguments to the function. Arguments are always evaluated in left-to-right order, although there are a few functions, known as special forms, which may not evaluate all of their arguments. These functions' handling of arguments will be explained in the function's description.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2 Afl Data Types

Each data type in afl has a read syntax and a printed representation. The read syntax is the way the data type should be written in an afl program. The printed representation is the way that the data type will be displayed by the afl printer. These may be the same or different.

22.2.1 Comments  How to insert comments into afl programs.
22.2.2 Special Constants  Constants you can use in afl programs.
22.2.3 Lists  Lists of objects of any data type.
22.2.4 Numbers  Numeric values.
22.2.5 Characters  The representation of characters.
22.2.6 Strings  Dealing with strings of characters.
22.2.7 Symbols  Objects which hold values.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]


A comment is text that is written in a program only for the sake of humans that read the program, and that has no effect on the meaning of the program. In afl, a semicolon (`;') starts a comment if it is not within a string or character constant. The comment continues to the end of line. The afl reader discards comments; they do not become part of the afl objects which represent the program.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2.2 Special Constants

In afl, the symbol nil is overloaded with three meanings: it is a symbol with the name `nil'; it is the logical truth value false; and it is the empty list--the list of zero elements. When used as a variable, nil always has the value nil.

As far as the afl reader is concerned, `()' and `nil' are identical: they stand for the same object, the symbol nil. The different ways of writing the symbol are intended entirely for human readers. After the afl reader has read either `()' or `nil', there is no way to determine which representation was actually written by the programmer.

In contexts where a truth value is expected, any non-nil value is considered to be true. However, t is the preferred way to represent the truth value true. When you need to choose a value which represents true, and there is no other basis for choosing, use t. The symbol t always has value t.

For convenience, the constant a is defined to be the value `ask' or `accept' in af's tristate configuration variables. This is the preferred way to set, for example, the variable copy-on-reply to `ask'.

In afl, nil, t and a, are special symbols that always evaluate to themselves. This is so that you do not need to quote them to use them as constants in a program. An attempt to change their values results in an error.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2.3 Lists

A list of objects of any data type (including lists). A list is read or printed as a set of objects enclosed in parentheses; for example `(a b c)', or `(a b (c d e) f)'.

Lists are evaluated by evaluating the symbol at their head as a function. The remaining objects are evaluated (unless the function is a special form), and passed as arguments to the function.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2.4 Numbers

Afl only supports integer numbers. A number is read or printed as an optional sign, followed by one or more digits; for example `42', or `-999'.

There is a system-defined limit to the maximum value of a number, usually 32 bits. Larger values will be truncated to fit within these bounds, which will leave them with unexpected values.

Numbers always evaluate to themselves.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2.5 Characters

In afl, characters are interchangeable with numbers, and are always printed as a number. They can be read either as a number, or as a question mark followed by the character; for example `?a'. If the character is not a normal alphanumeric one, then it is often necessary to prefix it with a backslash '\' to make sure it is treated as a character. If the character is '\' then you need a second '\' to quote it; for example. `?\\'.

You can write the characters Control-g, backspace, tab, newline, vertical tab, formfeed, return, and escape as `?\a', `?\b', `?\t', `?\n', `?\v', `?\f', `?\r', and `?\e', respectively.

Rather than quoting a control character with `\', another read syntax may be used. If a character is a backslash followed by a caret and another non-control character, then it represents the control character. For example, `?\^I' is read syntax for the character C-i. You may also use `C-' rather than `^', so `\C-i' is also read syntax for C-i.

A meta character is one that has the top bit set, and can be typed with a meta key on some keyboards. Read syntax for meta characters is `?\M-' followed by the character. This may be combined with control character read sequence, hence `?\C-\M-i' is read syntax for C-M-i.

Finally, the most general read syntax for characters is a question mark followed by a backslash and the numeric value of the character in octal (up to three digits are allowed). So `?\001' is read syntax for the character C-a.

An invalid control or meta character sequence (such as `?\C-\^a' or `?\C-1') will be flagged as an error by the afl reader.

As with numbers, there is a system-defined limit to the maximum value of a character, usually 8 bits. Larger values will be truncated to fit within these bounds, which will leave them with unexpected values.

Characters always evaluate to themselves.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2.6 Strings

The read syntax and printed representation of afl strings is the string enclosed in double quotes; for example `"A string"'. All the special ways of writing characters can be used within strings. In addition, a backslash followed by a newline is ignored within a string, so strings can be broken to fit on the screen better; for example:

"This string is broken here \
by a \\\\n sequence"

would be read as `This string is broken here by a \\n sequence'.

Strings always evaluate to themselves.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2.7 Symbols

A symbol name can contain any characters you require. Any use of the characters `'"();?.,\ \t\n' should be quoted with a `\' character. If the symbol name looks like a number, then it can be prefixed with a `\' to force it to be treated as a symbol. Note that unlike its use in strings, the `\' simply quotes the next character in the symbol name.

Evaluating a symbol works differently according to the context in which the symbol is being evaluated. An afl symbol can store a variable or a function, or both. The afl evaluator will usually look up the value of the symbol as a variable, but will use the value as a function if the symbol is at the head of a list.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.3 Afl Primitive Functions

Afl has several primitive functions, which are predefined in af, and can be called from your afl programs. In addition, an afl program can call any af command as a function; af commands are simply functions that have made provision for interactive use.

The appearance of the keyword &optional in the parameter list of a function indicates that the arguments for subsequent parameters may be omitted (omitted parameters default to nil). Do not write &optional when you call the function.

The keyword &rest (which will always be followed by a single parameter) indicates that any number of arguments can follow. The value of the single following parameter will be a list of all these arguments. Do not write &rest when you call the function.

22.3.1 Quoting Forms  Protecting forms from evaluation.
22.3.2 Controlling Program Flow  Functions that alter program flow.
22.3.3 Configuring Af From Afl  Functions to configure af.
22.3.4 Interacting With the Environment  Functions for dealing with externals.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.3.1 Quoting Forms

(quote form)
Quote form, protecting it from evaluation.

Sometimes, you may not want a form to be evaluated, for example the name of a symbol to assign a value to with set. You can prevent a form from being evaluated by using the special form quote. So (quote list-functions) expands to the symbol list-functions.

Because quote is used so often, there is a special notation for it. Writing 'form is equivalent to writing (quote form). So 'list-functions is equivalent to the example above.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.3.2 Controlling Program Flow

cindex comparing afl objects

(if condition then &optional else)
Execute then if condition evaluates to non-nil, else otherwise.
(progn &rest forms)
Evaluates forms from left to right, returning the value of the last form evaluated.
(equal object1 object2)
Returns t if object1 and object2 have the same afl type and contents, nil otherwise.
(and &rest conditions)
Evaluates conditions until one returns nil. Returns the value of the last condition evaluated.
(or &rest conditions)
Evaluates conditions until one returns non-nil. Returns the value of the last condition evaluated.
(not condition)
Returns t if condition evaluates to nil, nil otherwise.

To evaluate code only if a condition is true, use (if condition true false). This evaluates condition, and then evaluates true if condition returned non-nil, or false (if specified) otherwise.

You can use progn to group a set of forms, for example to use in an if. progn evaluates its arguments from left-to-right, and returns the value returned by the last argument.

You can compare the value of two afl objects with equal. This will return t if the two objects have the same afl type and contents, or nil otherwise.

To combine one or more logical expressions, you can use and, or, and not. The special form and evaluates its arguments from left to right until one of them returns nil, and then returns nil; the remaining arguments are never evaluated. If no argument returns nil, then the value returned by the last argument evaluated is returned.

The special form or is more-or-less the opposite of and; it evaluates its arguments from left to right until one of them returns non-nil, and then returns the value the argument returned; the remaining forms are never evaluated. If no argument evaluates to non-nil, then or returns nil.

To reverse a test use not. This returns t if the argument evaluates to nil, or nil otherwise.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.3.3 Configuring Af From Afl

(set symbol value)
Set symbol to contain value.
(setq symbol value)
Equivalent to (set 'symbol value).
(define-key keymap "key" value)
Bind key key in keymap keymap to value.
(define-kbd-macro macro "keys")
Define a keyboard macro macro to execute keys.

To set an af configuration variable, use the function set. This sets the variable to the value supplied. The value will be checked to make sure that it is a valid value for the variable.

Since set is a function you will need to quote the symbol to be set. For convenience, the special form setq is equivalent to set, but does not evaluate the object which is to be set. So (setq ask-cc t) is equivalent to (set 'ask-cc t).

To bind a key in a keymap use (define-key keymap "key" object). This binds key in keymap keymap to object, which must be a command, a keymap, a keyboard macro, or nil. To find the name of the keymap you want to bind the key in use the list-keymaps command. Since define-key is a function you will need to quote keymap and object.

To define a new keyboard macro, or redefine an existing one, use the function (define-kbd-macro macro "keys"). This defines macro to execute keys. Since define-kbd-macro is a function you will need to quote macro.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.3.4 Interacting With the Environment

(message &rest forms)
Display the print format of forms in the echo area.
(error &rest forms)
Beep and display forms in the echo area.
(getenv "name")
Return the value of the environment variable name, or nil if name is not set in the environment.

The functions message and error display messages or error messages in the echo area. While message returns the forms that it printed, error returns an error condition, which will halt the] execution of the afl program.

You can extract values from the environment by using (getenv "variable"), which looks up and returns the definition of variable in the environment. This can be very useful for terminal-dependent customisation of af.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.4 Running Afl Programs

M-x load-file RET file RET
Load file as an afl program.
M-x load-library RET lib RET
Search for and load a file `lib' or `lib.afl'.

Once you have created a file containing af commands (known as an afl program or afl library, you can load it. When you load an afl program, the file is opened, and its contents are passed to the afl reader. Once all the file has been read and evaluated, then the file is closed. If any form in the file is invalid, or produces an error, then the afl reader will abort, and the file will be closed.

The simplest way to load an afl program is to use the the command load-file, which loads a named file. You must specify the full name of the file.

The load-library command will search for an afl program in a set of directories defined by the load-path variable. It checks for the file name with `.afl' appended, as well as the filename alone.

If you want to modify where af looks for library files, there are two ways to do so. You can set the environment variable AFLOADPATH to a colon-separated list of directories to search; or you can set the configuration variable load-path to the same value. For example:

(setq load-path '("/usr/lib/af" "/usr/local/lib/af"))

would make af look for afl libraries in the directories `/usr/lib/af' and `/usr/local/lib/af'.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.5 Examples of Afl Code

Here are a few examples of afl code, with brief explanations.

Load the library `ansi.afl' if you are using an ANSI terminal (under one of several common names):

(if (or (equal (getenv "TERM") "ansi")
	(equal (getenv "TERM") "xterm")
	(equal (getenv "TERM") "vt100"))
    (load-library "ansi"))

Set the viewable-charsets variable to allow displaying the iso-8859-1 character set if running on an xterm:

(if (equal (getenv "TERM") "xterm")
    (setq viewable-charsets '("iso-8859-1" "us-ascii")))

Complain if the user isn't running on an xterm:

(if (not (equal (getenv "TERM") "xterm"))
    (error "Must be running on an xterm"))

Define a keyboard macro to move to the next message from typeout:

(define-kbd-macro 'typeout-next-message "\C-g\C-n\r")

Bind the above macro to the key M-n in the typeout maps:

(define-key 'typeout-prefix-command "n" 'typeout-next-message)

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Malc Arnold on August, 22 2002 using texi2html