[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |
(quote form)
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] | [ ? ] |
(if condition then &optional else)
(progn &rest forms)
(equal object1 object2)
t
if object1 and object2 have the same afl
type and contents, nil
otherwise.
(and &rest conditions)
nil
.
Returns the value of the last condition evaluated.
(or &rest conditions)
(not condition)
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] | [ ? ] |
(set symbol value)
(setq symbol value)
(set 'symbol value)
.
(define-key keymap "key" value)
(define-kbd-macro macro "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] | [ ? ] |
(message &rest forms)
(error &rest forms)
(getenv "name")
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] | [ ? ] |
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] | [ ? ] |
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] | [ ? ] |