Using Alice

This chapter is geared towards those who have mastered basic program editing. In it, we will discuss some of the ways in which you may customize your Alice sessions.

Command Line Options

There are a number of options you may add to the command line that invokes Alice.

+c

This indicates that you are using a colour monitor for the PC.

-i

This asks for the alternate indentation style described later in this chapter. The option +i asks for the normal indentation style, but since this is the default, you would have little reason to specify it on the Alice command line. The only time you would use it would be to change indentation styles in the middle of the session via the OPTION command (see Chapter 4).

+u

This indicates that your PC monitor supports underlining, but is otherwise a monochrome screen.

C=filename

This tells Alice the name of a configuration file. A configuration file sets various options, and also sets up any key bindings you may wish. For more information, see the section on ``Configuration Files''.

d=N

As explained in the introduction to this manual, this option calls for an Alice demonstration session. For this to work, you must have a demo version of Alice.

f=N

This tells Alice how frequently to typecheck the declarations in your program. Possible values of N are 0, 2, 4, and 6. With f=6 , Alice typechecks your program after every input. With f=0 , Alice never typechecks your declarations unless you explicitly issue the CHECK command (described in Chapter 4). f=2 gives occasional typechecking, and f=4 gives typechecking after every change to a declaration. The default is f=4 . Alice always typechecks declarations before running a program and after loading a program, regardless of the f= setting.

h=prefix

This tells where the help file "helpfile.huf" can be found. The prefix is a string giving a device name and directory. The default is ?:\helpfile . (This notation is explained later in this chapter.)

i=string

This option will act as if you typed the given string from the keyboard after Alice's initializations are through. The format of the string is the same as the format for macro arguments on the command line (see below). This option is mainly for use in configuration files. The given string can have a maximum of 255 characters.

L=lines

Specifies the number of lines on the screen. In the old days, PCs typically had 25 line screens though some could be set with more. However, if you are running Alice in a "DOS Box" under Windows, you can enlarge that box to have more lines by clicking on the "Properties" toolbar box, selecting the "Screen" tab and adjusting the line count. Then provide this option to Alice on the command line or in the ap.ini file.

l=NNNNN

This sets the size of the ``location'' stack. The location stack keeps track of the hierarchy of program calling (what subprogram is current, what called that subprogram, and so on). The location stack should be about one fifth the size of the normal run-time stack. The default is

l=1200

s=NNNNN

This sets the size of the run-time stack for user programs. NNNNN is an integer giving the number of bytes. The default is

s=5000

cL=NN

This option tells how a particular type of information should be displayed on the screen. The letter L that follows the c indicates the type of information. The following letters are recognized.


anormal text
bplaceholders
cerrors
dkeywords
evariables
fnamed constants
gcomments
hchar constants
iinteger constants
jreal constants
kstring constants
luser subprogram names
mbuilt-in subprogram names
nrecord field names
oundefined symbols
plabels
qexpressions being edited with the Simple Text Editor

The number NN is a number indicating colour or representation mode. Possible values of this number are given in the description of the Set_Attr procedure in Chapter 6. For colour screens, the defaults are

normal text:white
placeholders:bold blue
errors:bold red
keywords:bold white
variables:white
named constants:white
comments:yellow
constants:white
user subprogram names:bold green
built-in subprogram names:cyan
record field names:white
undefined symbols:reverse video magenta
labels:white
expressions being edited:bright green

For monochrome screens, the defaults are

placeholders:underlined
errors:reverse video
undefined symbols:reverse video
keywords:bold
comments:bold
expressions being edited:underlined
everything else:normal

If your monochrome screen is not capable of underlining, placeholders and expressions being edited are shown in boldface.

Macros

Alice lets you associate a string of characters with a single character typed from the keyboard. The process of associating such a string with a single character is called setting up a macro.

Macros may be set up on the command line that invokes Alice, in the configuration file, or with the MAP command. The use of the MAP command is described in Chapter 4. The use of the configuration file is described later on. Right now, we will only describe how to set up macros on the command line.

The option to set up a macro can have one of three forms.

mNNN=string

This associates the given ``string'' with the ASCII character whose decimal equivalent is NNN . For example,

m7=beep!

means that every time you type in the ASCII character whose decimal equivalent is 7 (hexadecimal 07), Alice will convert this to beep! .

m'X'=string

This associates the string with the given character X . For example,

m'W'=while

will set up a macro so that every time you type an upper case W , Alice converts this to the keyword while.

m^X=string

This associates the string with the sequence CTRL-X (where X can be any appropriate character). For example,

m^Z=readln(

sets up a macro so that every time you type CTRL-Z, Alice converts it to the string readln( .

Alice automatically sets up macros for a number of commands. These are the ``Key Bindings'' given in Chapter 4.

Default key bindings may be changed with any of the techniques we have mentioned for setting up macros. For example, if you want [CTRL-U] to stand for something other than the UNDO command, you can re-assign its meaning in a configuration file, on the Alice command line, or with the MAP command. Similarly, if you want UNDO associated with a different key sequence, you can set up an appropriate macro.

Special control sequences can be used in all three forms of macro definition. The sequence \n stands for pressing [ENTER]. The sequence \c has the same effect as pressing the [CTRL-X] key, i.e. it indicates the beginning of a typed-in command. Therefore,

m^B=\cimmediate\n

means that every time you type CTRL-B, Alice acts as if you pressed the [CTRL-X] key, typed immediate , and then pressed [ENTER]. In other words, every time you type CTRL-B, Alice will act as if you had issued the IMMEDIATE command.

Note: when using \c , always make sure that there is a \n in the macro string to stand for [ENTER].

Other escape sequences that may be used are

\u  -- up-arrow key
\d  -- down-arrow key
\r  -- right-arrow key
\l  -- left-arrow key
\s  -- symbol completion key ([END])
\b  -- delete character under cursor
\h  -- backspace
\\  -- the backslash character

This technique can be used to bind frequently used commands to your choice of key sequence. It can also be used to change the default bindings of commands. All key bindings can be changed except the cursor movement keys, the completion key [END], and the backspace.

Note that Alice currently does not expand macros when a menu is displayed on the screen. This means that you cannot write a macro that summons a menu, then selects an item from that menu.

Alternate Indentation

By default, the end that ends a begin-end block is indented to the same degree as the statements in the block. For example, you have seen

while Condition do begin
    Statement
    end;

Alice can provide a second style of indentation for those who do not like the default indentation. In this style, the end lines up with the statement that began the begin-end block, as in

while Condition do begin
    Statement
end;

If you prefer this type of indentation, use the -i option on the command line that invokes Alice, as in

alice -i

In this style of indentation, the begin and end in a procedure or function template will line up with the statements of the subprogram, all indented from the subprogram heading.

Note that the indentation style is associated with the Alice session, not with files containing Alice Pascal programs. This means that you can create a program using the default indentation, then edit it later in a session that uses the -i indentation.

Configuration Files

Any option that can appear on the command line can be placed in a configuration file. When Alice starts up, it will read all the options from the configuration file and treat them in the same way as they are treated on the command line. This makes it easy to create a standard environment of macros and options that go into effect every time you enter Alice.

To tell Alice the name of your configuration file, use the DOS command

set APINIT=pathname

where pathname is the name of the file that contains your initialization commands. For example, you might say

set APINIT=C:\alice.ini

if the configuration file was alice.ini in the root directory on your C: drive.

Alice comes with a standard configuration file named ap.ini . This sets up all the standard key bindings described in this manual. You will have trouble if your configuration file does not contain the standard key-macro initializations or equivalents thereof. In this case, you will not be able to use any of the default key bindings.

If Alice finds that you have too few key bindings defined in your configuration file, a few key bindings will be defined automatically. [F9] will be bound to the HELP command; ESC will be bound to the EXIT command; and [CTRL-X] will be set up as the command key. This ensures that you won't become helplessly trapped in Alice if you make a mistake setting up your configuration file.

If Alice encounters too many errors in your configuration file, Alice will simply abort the session.

Note that configuration files can contain the C=file option, pointing to another configuration file. Thus you might write your own configuration file that sets a number of personal macros, then contains a C=file line giving the name of the standard Alice configuration file. In this way, you get all the default Alice bindings as well as your own bindings.

Alice and Other Versions of Pascal

As noted previously, files containing Alice Pascal programs are kept in a special format. However, you can write out your Alice program as normal text using the TEXT command.

The TEXT command is located on the Files Menu. If the name of your Alice-format save file is file.ap , the default name of the text-format save file will be file.pas . If you do not want this default name, issue the TEXT command by pressing [CTRL-X] and entering

text yourname

where yourname is the file name that you want to use.

If there is no save file associated with the program as yet (and you do not provide an argument with the SAVE command), Alice will go through the standard routine of issuing a menu to prompt for the name of a file.

When a program is saved as text, all hidden material in the file is revealed. For technical reasons, a program saved as text can have no more than 60 pieces of hidden code.

When a program is saved as text, tab characters are used to give indentation. Placeholders are represented as comments that have a + as the first character. For example, a Value placeholder would be written as

{+ Value}

in text output. Empty Comment placeholders are not written out in text output.

Comments

Alice's way of representing programs sometimes leads to nested comments. For example, you may have ``commented out'' a section of your program using the COMOUT command, and this code may itself contain comments.

If such a program is saved as text, you will probably have trouble running the program through another Pascal interpreter or compiler. In standard Pascal, a closing brace marks the end of all comments up to that point. You cannot have

{A comment with {a comment} inside}

The first } ends all comments, leaving inside dangling outside.

Alice can't avoid such situations -- you'll have to watch for them yourself.

Forward Declarations

Some programs will need Forward declarations in order to work properly when compiled by another Pascal compiler.

Alice does not need forward declarations because it knows the name of all your subprograms at the time that you run your program. Other compilers, however, compile the program by passing through it from start to finish. If the definition of subprogram A contains a call to subprogram B and B has not yet been defined in the source code, the compiler has a problem with argument type-checking because it does not know the type of B's arguments.

Such compilers need Forward declarations. Essentially, the programmer writes down the heading for subprogram B so that the compiler knows the type of the arguments, but replaces the body of subprogram B with the keyword forward. The actual definition of B is given later on in the source code.

When Alice is writing out a program in text form, it must be told when a forward declaration is necessary. To enter a forward declaration, type for in any Declaration placeholder that comes before the first use of the routine in question. Alice will lay out the template

Forward <routine>;

The routine placeholder should be filled in with the name of the routine that needs a forward declaration. When the TEXT command is used to output the program in text form, Alice will transform the above Forward declaration to the usual Pascal format. The actual definition of the routine will also be adjusted to the format required by conventional Pascal.

Because Alice uses this technique for forward declarations, you may not use the standard Pascal method (putting the word forward after a subprogram declaration heading).

The NOT Feature

As noted in Chapter 3, you may enter the keyword not in any Statement or Declaration placeholder for a special effect. Whatever you type after the not will be treated as a comment, but will not be enclosed in brace brackets. In this way, you can enter source code which is not accepted by Alice but which is accepted by some other version of Pascal. When you use the TEXT command to output your program in text format, the ``invisible'' comment will be written out as is.

This feature lets you use all the features of Alice, even when you are preparing Pascal programs for execution under a different version of Pascal.

APIN

The APIN program converts normal Pascal source code into Alice's special program format so that the source code can then be edited with Alice. APIN only works for correct, working Pascal programs -- if there is even one error in the source file, APIN will abort with an error message.

The format of the APIN command line is

apin infile outfile

where infile is a file containing ASCII Pascal source code, and outfile will be filled with the equivalent program in Alice Pascal format. (You will find it convenient for outfile to have the usual .ap suffix.) Once you have created outfile , you can load it into Alice for editing.

With APIN, you can use i= to label input files and o= to label output files if you wish. For example,

apin i=infile o=outfile

is permitted.

If the output file name is omitted, Alice will use the input file with the extension .ap . For example,

apin file.pas

writes the Alice-format output into file.ap .

If a text input program contains a comment like

{+ Value}

APIN will convert it to a Value placeholder (if it is found in an appropriate position in the source code). In this way, programs can be saved as text with the Alice TEXT command, then converted back to Alice format with APIN.

APIN currently cannot handle large programs. If a program is too large for APIN to handle, break the program into pieces (that are still correct Pascal programs), APIN each piece separately, then use Alice's MERGE command to merge the pieces.

APIN normally prints a message naming the files it will use for input and output. To suppress this message, add ``+s'' to the APIN command line.

Merge Libraries

The MERGE command (described in Chapter 4) is a simple way to support ``libraries'' of routines. You start by creating a program that contains definitions for one or more subprograms, plus any declarations they may need. This program need not have any instructions in the mainline. Next, save the program in a file with the SAVE command. This file can be thought of as the subprogram ``library''.

If you want to use one or more of the library routines in a program, just use the MERGE command to merge the saved library with your program. The various declarations and routine definitions will be added to your program.

If there are some routines you do not need, you can delete them in the normal way. You may also want to HIDE the routine definitions so that they are invisible in some sense.

The Alice package already comes with a number of useful subprogram libraries. These let you perform such useful operations as editing another Alice program, calling C functions, and manipulating display windows. Each library contains its own documentation.

The History List

Alice maintains a history list that records the last few editing actions that have been taken. This information lets the UNDO command (described in Chapter 4) undo recent actions, by ``backing up'' in the history list. One UNDO command undoes the most recent action, a second UNDO undoes the second most recent action, and so on.

The number of consecutive UNDO commands you can issue depends on the size of the commands that you are undoing. The history list has 100 elements in which source code changes can be recorded. It may take several elements to record the changes made by a single command. For example, it takes two elements to record each statement deleted by a DELETE command, even though a single DELETE command can delete many statements. You may be able to UNDO many small changes, but only one or two large-scale changes.

The main function of the RECOVER command is to throw away the current history list in order to clear room in memory. The LOAD and WS commands also throw away the current history list during their operations. This means that you can't UNDO past a RECOVER, LOAD, or WS command -- the history that preceded these commands has been lost.

Notes

In this section, we will cover miscellaneous details about Alice and how it may be used most productively.

Stopping Programs

If a program is stuck in an infinite loop, or if you simply want to stop it before it finishes execution, press [CTRL-BREAK]. Pressing [CTRL-BREAK] will stop certain other actions as well, e.g. the TEXT command.

In addition, pressing CTRL NUM-LOCK pauses a program temporarily. Pressing any other key on the board will resume execution.

GET and MOVE

The GET and MOVE commands are particularly powerful for many different editing operations. For example, in Alice there is no really good way to change an assignment statement into a procedure call. However, you can move the right hand expression of the assignment into a different workspace, CLIP the assignment to get an empty Statement placeholder, set up the procedure call, then GET the expression back from the workspace.

Macros

Set up macros for common editing operations. For example, you may want to create a macro that does a MOVE into a standard workspace and a second macro that GETs material from that workspace. This will make normal MOVE/GET operations into two single keystrokes.

Spaces

Because Alice pays attention to space characters more than text editors do, you may find that you cannot type spaces everywhere you're used to. This is just something you'll have to remember. Also, since TAB is used to move the cursor around, you may not use it to indent lines of code the way you would if you were using a text editor.

Editing Declarations

If you delete the Name in a declaration, Alice will highlight all the occurrences of that name in the program, since they are now undeclared variables.

If you edit the Name in a declaration (using the EDIT command), all the occurrences of the old name will automatically be changed to the new name.

If you change the Type in a variable declaration, you should immediately issue the CHECK command to make sure that the change in type has not created type incompatibilities in the body of the program. CHECK is invoked with the Typecheck Program option on the Run-Time Menu or by pressing [CTRL-T].

Type-ahead

Normally, Alice reads and processes one character of input at a time. Similarly, if it is appropriate to display input characters (i.e. if you are entering source code instead of commands), Alice normally displays one character at a time. However, if you are entering characters very quickly (e.g. with the automatic repeat feature of many keys on the keyboard), Alice stops working character-by-character and deals with several characters at once. You will see your input written out in short ``bursts'' rather than a continuous stream.

The same sort of thing happens when Alice is scrolling lines on the screen. If you are scrolling very quickly through a file (e.g. with the automatic repeat feature of the downarrow key), Alice will jump the screen several lines at a time rather than scrolling smoothly.

Trees

The tree structure of an Alice program can often be exploited during editing. For example, it allows you to edit part of an expression without touching the rest.

The fastest way to change a small subtree is often to delete it and retype it. Remember that the completion key [END] is particularly useful when completing identifiers.

Finding the Cursor

Alice has two ways of representing Pascal code: the internal tree representation and the text display shown on the terminal screen. One of Alice's biggest jobs is reconciling the two.

Suppose, for example, that you use one of the arrow keys to move the cursor to the blank space to the right of a line of source code. Alice has to examine cursor movements on the screen and figure out what the equivalent movement is in the tree; otherwise, the tree and the screen will be out of synch. However, the cursor is pointing to a blank area. This contains no code, so there is no corresponding entry in the program tree.

In such cases, Alice always acts as if the cursor is pointing to the closest part of the program tree to the left of the cursor. For example, if the cursor comes after the placeholder

{Comment}

Alice will consider that the cursor is pointing to the Comment placeholder, even though it is actually on the blank space to the right. If you start entering input, you will see the cursor jump left and the input will fill in the Comment placeholder.

The same thing happens when the cursor is pointing to part of a template that has no corresponding tree entry. For example, consider

while Condition do begin
    Statement
    end;

The program tree needs to record that this is a while loop, and it needs to record the Condition and the statements enclosed in the loop. The do begin and the end are shown on the screen, but they have no corresponding entry in the tree. They are just extra things that have to be shown in a Pascal program.

If you move the cursor to the do begin and start typing, you will see that your input is filled into the Condition placeholder. Again, Alice is using the first actual tree entry to the left of the cursor.

Line Length

Alice cannot handle lines that are over 255 characters long.

UNDO

You might regard UNDO as a ``program-oriented backspace''. Alice tries to read the programmer's mind in many instances, and sometimes it guesses wrong. UNDO is particularly useful in such situations.

For example, suppose you enter an undeclared name on a Statement placeholder. Alice guesses that you want an assignment statement and the name is the name of a variable. If you actually wanted a procedure call and the name is the name of a procedure, you can UNDO, put in a declaration for the procedure, then enter the procedure name again.

Declaration Error Checking

In order for Alice to check for errors in your code, it is important that the declarations of your types, variables, and constants be as complete and correct as possible.

This means that whenever you change ANY declaration, ALL the affected declarations are checked for errors. When this is done, the first error is reported on the error line and all the other errors just get highlighted.

If you want Alice to deal properly with the rest of your program, you should always make sure your declarations are in good order. The fact that Alice reports only the first error it finds can be confusing, since you might be changing one declaration while Alice is reporting an error in a declaration that occurs earlier on. Don't be alarmed by this. Remember that the [CTRL-leftarrow] key will take you back through the errors in your program, and this can help you find your error.

If you change a declaration, errors may result throughout the program. If the declared name occurs several times in a single declaration section, only the first error will be indicated. To avoid spurious errors, Alice does not give an error message if the first error happens to be associated with a placeholder. The same problem occurs if Alice is typechecking an executable statement: even if there is a type error in the statement, no message will be printed if the first error in the line is associated with a placeholder.

This whole situation is very rare in normal use, but it can lead to surprises if it ever does surface in your work. We are working on a future version of Alice can get around the problem and give a reasonable error message.

Immediate Mode

Some people may wonder why immediate mode was implemented the way it was, seeming to be a part of the program. The answer is that variables in Alice need to be referenced within the context of a particular program location (e.g. inside a particular subprogram). If you have several variables named i in your program and subprograms,

writeln(i);

cannot be executed until Alice knows which i you're using. This means that immediate mode instructions must be thought of as local to a particular program location. This point is more visible by placing those instructions right in the program's code at that location.

Immediate mode blocks can contain any valid Pascal instruction. This means that you can have such things as for loops to print out the contents of an array. You will find immediate mode very powerful once you get the hang of it.

If you press [CTRL-BREAK] to stop a statement executed in immediate mode, you have to use the POP command to pop off the suspended state that results from interrupting immediate mode.

Note that the [ENTER] key does double duty in immediate mode. It acts as the ``run'' key as well as performing its usual function of creating empty placeholders. For this reason, you may want to use INSERT ([INS]) and EXTEND ([CTRL-E]) to create empty placeholders instead of [ENTER] in immediate mode.

File Search Rules

Users may use the special format

?:filename

to specify file names, both in Alice command line options and in Alice commands (like LOAD). This format tells Alice to look for the given file on several drives.

The search works like this. First, Alice strips off the ?: from the name as typed and searches for the file on the current drive. If the file is not found, it searches the other drives on the system (without searching the current drive again). If you have only two drives, Alice will search A: first, then B: . If you have three drives, the search order is C: , A: , then B: . Alice does not search extra drives like D: unless they are the current drive.

The default configuration file is specified as ?:\ap.ini and the default help file is ?:\helpfile . This means that Alice looks for the ap.ini file on all the major disks of your system, starting with your current drive, then going on (if necessary) to your hard disk and the other floppy. This should make it easier to install Alice on your hard disk, since the APINIT variable usually won't be needed.