Entering a Program

At every point during the editing process, the Alice cursor points to a node within the internal tree. At every node, there are only a limited number of actions that you may take: issue a command, move the cursor, or type in something that makes sense in the context of the current node.

The various Alice commands are described in Chapter 4. In this chapter, we will discuss code entry itself.

Principles of Code Entry

The most fundamental design principle of the Alice editor is that you should be able to enter a program more or less the way you would enter a program with a conventional editor. However, if you prefer Alice also offers a wide variety of short-cuts and simplifications to make program entry more dependable and efficient.

Some of the things you can enter will move the cursor. We have already discussed some fundamental cursor movement keys like TAB and [CTRL-rightarrow]. There are also some less obvious ways to move the cursor. For example, if you type the keyword var anywhere in your program, Alice will move the cursor to the var declaration section of the enclosing subprogram or the program mainline. The declaration section will be created if it doesn't already exist.

If an input doesn't move the cursor, Alice assumes that it is source code to be filled into a placeholder. If the cursor is not on a placeholder or the type of the input does not match the type of the placeholder (e.g. you put a number where a variable was required), Alice will usually give an error message.

There is one exception to this rule: if your input doesn't make sense in the current cursor context but does make sense in an enclosing context, Alice will take appropriate action according to the enclosing context. For example, if you type the keyword else while the cursor is on a Value placeholder, the keyword doesn't make sense. However, suppose the Value placeholder occurs within an enclosing if statement. else does make sense in the context of an if statement -- it tells Alice to add an else clause to the if. Alice will therefore take the appropriate action in the context of the while if statement (an else clause will be added to the if).

Having given the general principles of input, the rest of this chapter will describe special cases. In order to avoid a tedious discussion of every possible action, we will spend most of our time looking at places where the course of action that Alice takes might not be obvious to some users.

Keywords

We will look at three types of keywords: those related to declarations, those related to statements, and those related to expressions.

Declaration Keywords

With the cursor anywhere in the program, you may enter the keyword that starts a declaration section (i.e. label, const, type, or var). If the cursor is in a position where it is appropriate to enter such a declaration, Alice will create a declaration placeholder. Otherwise, Alice will move the cursor to the appropriate declaration section and create the placeholder. If the cursor is currently inside a subprogram, Alice will move to the declaration section inside that subprogram; otherwise, Alice goes to the mainline's declaration section. If the appropriate declaration section does not exist yet, it will be created.

Similarly, if you enter either of the keywords procedure or function, Alice will create an appropriate subprogram definition template in the program or current subprogram.

When you enter a keyword that moves to a declaration, Alice will put the cursor on a placeholder in that declaration. For subprogram definitions, the cursor will be placed on the first placeholder in the definition template: the name of the function or procedure.

Several of the above keywords have special meaning in connection with the parameters in the heading of a subprogram declaration. If you enter procedure or function in a Parameter placeholder, Alice will lay out the template of a formal procedure or function. This indicates that the argument being passed to the subprogram will be the name of a procedure or function.

If you enter the keyword var in a Parameter placeholder, Alice will lay out the template of a var parameter. If you type var on top of an existing value parameter, the parameter will be changed into a var parameter.

A number of other declaration keywords are related to data types, e.g. record, array, file, etc. These may only be entered in appropriate Type placeholders in declaration templates. When such a keyword is entered in a Type placeholder, Alice will lay out an appropriate template. For example, if you have

var
    iarr : Type; {Comment}

and enter array in the Type placeholder, Alice will lay out

var
    iarr : array of Type; {Comment}

Statement Keywords

The statement keywords are all those that may be filled into a Statement placeholder:

begin
case
downto
for
goto
if
repeat
while
with

If you enter any of these on a Statement placeholder, Alice will lay out the template for the corresponding statement. These keywords may not be entered except on a Statement placeholder. (The downto keyword will give you a reverse for loop.)

The keyword else may be entered anywhere inside an if statement. Unlike most input, it does NOT have to be entered on a placeholder. Typing in else will add an else clause on the end of the enclosing if. If you type in the else on a Statement placeholder, the placeholder will disappear at the same time that the else clause is added.

The keyword downto may be entered anywhere inside a for loop. Like else, it does NOT have to be entered on a placeholder. Entering downto changes the form of

for Variable := Start to Finish ...

into

for Variable := Start downto Finish ...

Similarly, entering to inside a ``downto'' for loop changes the downto back to to.

Expression Keywords

Expression keywords are words like div, mod, not, etc. that serve as operators in expressions.

These keywords may only be filled into placeholders that represent expressions. The most common such placeholder is Value , although other placeholders are used in special circumstances (e.g. the placeholder Start is used for the expression that gives the starting value for a variable in a for loop). For convenience, we will assume that the keywords are being entered on a Value placeholder.

When an expression keyword is entered on a Value placeholder, Alice expands the placeholder into the template of an expression using that keyword. For example, if you enter div, Alice will expand things to

Value div Value

Notice that this now gives you two ways to enter an expression. If you start filling in a Value placeholder with a symbol or a constant, Alice will assume that you are entering the expression in a ``textual'' way and will call up the Simple Text Editor to gather the expression in its entirety. If, however, you type in an expression keyword (or operator) first, Alice will expand the expression in a manner appropriate to the operator.

Expression Operators

By expression operators, we mean symbols like + , * , > , and all the other arithmetic and logical operators of Pascal.

These may only be entered in expression placeholders, e.g. Value or Condition . Entering an expression operator in an expression placeholder has the same sort of effect as entering an expression keyword. For example, if you enter * in a Value placeholder, Alice will expand the expression to

Value * Value

The one exception to this principle is the minus sign - . If you enter a - in a Value placeholder, it could be taken in several ways. It might be a unary minus; it might be a subtraction operator; or it might be the beginning of a negative constant that is being entered in a textual way via the Simple Text Editor. Since we believe that most people will prefer to enter expressions as text rather than entering operators first then filling in arguments, Alice will begin gathering an expression with the Simple Text Editor if you enter a ``-'' on an expression placeholder.

If you decide to enter an expression ``operators first'', you should be aware that Alice builds the expression as a tree as you input operators. For example, suppose you start with a Value placeholder and enter a * . Alice will expand things to

Value * Value

If we were to represent this as a tree, it would be

If you now go to the second Value placeholder and enter a + , you will see

Value * (Value + Value)

To understand what has happened, think of what has happened to the tree.


By entering a + on the second placeholder, you indicate that this part of the multiplication expression is an addition. This addition should be performed before the multiplication. Since the usual order of operation is to perform multiplications instead of additions, Alice automatically adds parentheses in the output.

If you experiment with this ``operator first'' method of entering expressions, you will find that Alice only adds parentheses when they are needed to reflect the tree structure of the expression. For example, if you entered a + on a Value placeholder to get

Value + Value

and then entered a * on the second placeholder, you would get

Value + Value * Value

Parentheses are not needed because the usual order of operations will ensure that the multiplication is performed before the addition.

Variable Name Operators

The operators [ , . , and ^ are special in that they may be entered in Variable placeholders. If you enter a [ operator, Alice will give you

Variable[ Subscript ]

If you enter a . , Alice will give you

Variable.Field

If you enter a ^ , Alice will give you

Variable^

In addition, typing [ , . , ^ on a variable name adds the appropriate type of construct to the variable. For example, suppose ptr is a pointer variable name and you have

ptr := Value;

Typing ^ on top of the ptr creates

ptr^ := Value;

Names

After keywords and operators, names are the most common things to enter when creating a Pascal program. A name can refer to a variable, a procedure, a function, a named type, or a named constant.

Names can be user-defined (in which case they must be declared) or built-in. Built-in names include named constants (e.g. maxint ), named types (e.g. integer ), named procedures (e.g. writeln ), and named functions (e.g. sin ).

Names may only be entered in empty placeholders. The action that Alice will then take is based on the type of the placeholder. In most cases, the name will simply be filled into the placeholder. However, there are a few special cases that should be mentioned.

Statement Placeholders

If a simple variable name is filled into a Statement placeholder, Alice will expand things to the assignment

NAME := Value;

where NAME is the name you have entered.

If you are assigning a value to an array element, enter

NAME[

without typing a space after the NAME of the array. Alice will expand this to

NAME[Subscript] := Value;

Similarly, enter NAME. to assign a value to a record field, and NAME^ to assign a value to a pointer variable.

If a user-defined procedure name is filled into a Statement placeholder, Alice will expand things to the procedure call

NAME(p1:type,p2:type,...);

Inside the parentheses of the call are placeholders that correspond to the parameters given in the declaration of the procedure. Each of these placeholders gives the name of the parameter and the type. For example, if you defined a procedure proc with

procedure proc(a:integer; b:real);

Alice would use the template

proc(a:integer,b:real);

for a call to proc . var parameters are marked as such, as in

proc2(var c:char);

Alice takes a similar approach when you enter the name of a built-in procedure on a Statement placeholder. In most cases, Alice will immediately draw up a call to the procedure, using placeholders that look like parameter declarations. However, a few built-in functions like readln and writeln can take different numbers and types of variables. In this case, parameter-like placeholders are not appropriate and Alice must take a different approach.

Alice pays attention to what you type immediately after the name of such procedures. If you enter an opening parenthesis, Alice will give you a call to the procedure with a single placeholder as argument. For example, if you type writeln( , Alice will give you

writeln(Value);

If you want to write more than one value with this writeln instruction, type a comma after you have filled in the Value placeholder, and Alice will give you another such placeholder (see the description of ``Delimiters'' below for further details).

If you type a space or move the cursor somehow (e.g. with TAB) after entering the name of the built-in procedure, Alice will give you the symbol without an argument list. For example, if you enter writeln followed by a space, you will get

writeln ;

Notice that there is a space between the writeln and the semicolon. Alice always puts in this space when a function or procedure takes no arguments.


If you accidentally get the no-argument form of a built-in procedure call, you can add arguments to it by moving the cursor to the procedure name and typing an opening parenthesis ``(''. For example, if you type a ``('' on top of the no-argument writeln above, you will get

writeln(Value);

If you enter an undeclared name on a Statement placeholder, Alice doesn't know if the name represents a variable or a procedure. This means that Alice doesn't know whether to lay out an assignment template or a procedure call. For this reason, Alice gives you an error message, highlights the name that you have entered to show that it is undeclared, and arbitrarily chooses to lay out an assignment template. You may change this template to a procedure call by typing ( on top of the name.

Constants

There is nothing very surprising about the way one enters constants in Alice. If you are entering a string constant, you will be under the control of the Simple Text Editor. Thus, in addition to the usual closing quote, you must type a cursor-movement key (e.g. TAB) to indicate that you have finished typing a string. Apart from this, everything is just as you'd expect.

Delimiters

We use the word delimiter as a catch-all term for all characters and strings used to separate placeholders and user input on the screen. For example, the following are all delimiters:

  1. The ``:'' in a variable declaration.
  2. The commas in a list of arguments to a subprogram call.
  3. The semicolons that end most Pascal statements.
  4. Keywords like then in the template of an if statement.

The sections that follow tell what happens when you enter such delimiters.

Delimiters Present in a Template

If you enter a delimiter that is already shown in the template you are filling in, the usual action is to move to the placeholder that follows the delimiter. For example, suppose you have just filled in the first placeholder of a for statement, as in

for i := Start to Finish do begin
    Statement
    end;

The cursor is just after the variable i . If you enter := , the cursor will move to the Start placeholder. If you enter to , the cursor will move to the Finish placeholder. If you enter do or begin , the cursor will move to the Statement placeholder. If you enter end , the cursor will move to whatever follows the end of the loop.

Commas

In Pascal source code, commas are used to separate the elements of various kinds of lists: lists of names in declarations, lists of arguments in subprogram calls, etc. For this reason, typing a comma on a blank placeholder in Alice will create a second placeholder, provided that a comma-separated list is valid at that point in the code. As an example, suppose you have the usual variable declaration template

var
    Name : Type; {Comment}

If you type a comma on the Name placeholder, Alice will give you

var
    Name, Name : Type; {Comment}

If you were to type a comma on the Type placeholder, however, you would be given an error message -- a variable declaration cannot have a list of types.

You may also type a comma at the end of other input. For example, if you are on the Value placeholder of

writeln(Value);

and type i, you will see

writeln(i,Value);

The comma is recognized as a delimiter marking the end of the first output value. It also indicates that there will be another output value, so an appropriate placeholder is created.

Semicolons

Entering a semicolon in a Parameter placeholder creates a new Parameter placeholder (giving a list of parameters). Typing a semicolon anywhere else will move the cursor to whatever follows the next semicolon (usually the next line).

Entering Comments

Comments can be placed in the code by going to a placeholder that occupies a line on its own (e.g. Statement or a Declaration placeholder) and typing an opening brace ``{''. Alice will lay out the template

{Comment}

and you may then fill in the comment. To indicate the end of the comment, type a closing brace ``}'' or move the cursor off the comment with a cursor movement key (e.g. TAB, [CTRL-rightarrow], or an arrow key).

All such comments will be placed on a line of their own -- due to internal restrictions, Alice cannot place comments in the middle of a line except where the comment is already built-in (e.g. on declarations).

Miscellaneous Notes

We have already mentioned a few special input keys, e.g. the name completion key [END]. In this section, we cover some other keys with special input functions.

{key

Pressing [ENTER] indicates the end of a token. It also indicates the end of an expression, string constant, or comment that is being collected via the Simple Text Editor.

Pressing [ENTER] also moves the cursor in a number of cases. The usual effect is to move the cursor down one line. If this line consists of a single placeholder (e.g. the line is a Statement or Declaration placeholder of some kind), the cursor is just positioned on the placeholder. If the line is not a single placeholder in this way, Alice creates a single placeholder of an appropriate kind.

For example, if the cursor is on a variable declaration and you press [ENTER], Alice will create a new Variable-Declaration placeholder. If the cursor is on a statement in a for loop, Alice will create a new Statement placeholder. If the cursor is on the end that marks the end of one Case Instance block (in a case statement), Alice will create a new Case-Instance placeholder.

If you press [ENTER] and the cursor is already on a line consisting of a single placeholder, the cursor will not move. Thus if you are already on a Statement placeholder, pressing [ENTER] will not move off the placeholder.

When you are in an immediate block, pressing [ENTER] after entering an instruction executes that instruction. Immediate mode was discussed in Chapter 2.

The Question Mark

Typing a question mark ``?'' on a Statement placeholder gives you

writeln(Value);

This was primarily introduced to make immediate mode easy to use. However, the trick works both inside and outside immediate blocks.

The End of an Expression

When you use the Simple Text Editor to enter an expression, comment, or string constant, you need some way to show when you've finished the expression.

Moving the cursor off the expression using one of the cursor movement keys (arrow keys, TAB, [ENTER], etc.) will always work. This is what you must do if you are editing an existing expression via the EDIT command (explained in Chapter 4).

However, if you are filling in a placeholder for the first time, there are other ways to indicate the end of the expression. For example, you can type the keyword or delimiter that follows the expression in the template that you are filling in. For example, if you are filling in the Start placeholder of

for i := Start to Finish do begin
    Statement
    end;

you can type the keyword to to indicate the end of the Start expression.

Special Use of Not

If you enter the keyword not in a placeholder that takes up a whole line (e.g. a Statement placeholder), Alice will let you enter a comment without braces around it. This lets you enter source code that Alice would normally not accept, e.g. statements supported by other versions of Pascal but not Alice. In this case, you could then use the TEXT command (described next chapter) to save your program in a text file, then submit the text file to another Pascal compiler or interpreter.

When Alice executes a program that contains this kind of construct, such lines are ignored.