TEACH POPCOURSE2 - Basic constructs

Contents

This file introduces basic POP-11 commands involving variables, assignments, repeat loops and simple procedures. Some of the exercises in this file use the LIB POPBUGS `bugworld' package. These can only be done if you are using a graphics screen (e.g., an X terminal). If you are working through the files using an ordinary terminal you should skip any section marked `POPBUGS ex'.


How to load POP-11 commands

POP-11 commands can be used to make the computer do various sorts of things, and as such are like Ved commands. However, whereas Ved commands are executed on the command line, POP-11 commands are executed from inside a file. To execute a POP-11 command we write it into a file, mark it as a (one line) range and then execute it by giving the Ved command `lmr' (which stands for `load marked range'---`load' being another word for `execute').

Unless it has good reason to think otherwise, Poplog assumes that the commands you are trying to execute with `lmr' are POP-11 commands. Thus you can insert POP-11 commands and execute them in almost any file you like---even this one. It is recommended that you always test out the examples that you see in the teach files by marking them and doing `lmr'. If something goes wrong and POP-11 is not behaving as you expect, you can always abort the processing by tapping the INTERRUPT key (usually CTRL-C).


Expressions and statements

One of the simplest POP-11 commands is the `+' command, which adds two numbers together. Here is an example of a `+' command.

2 + 2
If you mark this as a range and then do `lmr' (i.e., give the `lmr' command) POP-11 will add the two numbers together. This produces a result or a value, which is just the sum of the two numbers (namely 4). BUT NOTE that nothing is done with this value unless we explicitly tell POP-11 what we want done with it. The simplest thing is to append an extra command that asks for the value to be printed out. We do this by putting the text `==>' after the `2 + 2'. The `==>' is a command called the `print arrow'. It tells POP-11 to print out the value that has been computed by the command on the left. Thus if we execute

2 + 2 ==>
POP-11 will print out

** 4
If you have your windows set up the usual way, the `** 4' will come out in a Ved file called `output.p'. This file should be visible in its own window. Note that POP-11 always inserts two asterisks before anything it prints out.

In POP-11, commands that produce values are called `expressions'. Commands that just do things without producing a value are called `statements'. Thus

2 + 2 ==>
consists of an expression (`2 + 2') and a statement (`==>').

We can construct POP-11 expressions using any of the usual mathematical operators, e.g. + (plus), - (minus), * (multiplication), / (division). We can also construct expressions using the special exponentiation (`raising') symbol **. The value of the expression

2 ** 3
is 2 raised to the power 3 (i.e. 2 * 2 * 2).

Experiment: type in a command that will make POP-11 print out the value of the expression `4 * 5'. If you have got the command right, POP-11 should print out `** 20'. Now try making POP-11 print out the value of the expression `4 ** 5'. The printing this time should be `** 1024'.

POP-11 does not care how you lay out the command. Thus if you mark the following lines and do `lmr', you will get the same answer as before.

2

  +

           2    ==>
However, you cannot put spaces between individual symbols. So, although

2 + 23 ==>
causes

** 25
to be printed out. Doing

2 + 2 3 ==>
causes an error. POP-11 assumes that you must have missed out something between the 2 and the 3 and displays a message saying `MISSING SEPARATOR' on the command line.


Mishap messages

The message that POP-11 prints out in the example above is called a `mishap message'. Short mishap messages are displayed at the end of the command line. Longer messages get printed out just like ordinary output. Long messages can have several parts to them. For example if we do

2 * ==>
POP-11 will print out

;;; MISHAP - ste: STACK EMPTY (missing argument? missing result?)
;;; FILE     :  popcourse2  LINE NUMBER:  141
;;; DOING    :  * compile runproc compile pop_setpop_compiler
The first line begins `MISHAP - ste: STACK EMPTY'. The text here is POP-11's description of what has gone wrong. (See below.) The second line begins with `FILE' and identifies the name of the file in which you are working and the number of the line where the error occurred. The final line begins with `DOING' and lists the `procedures' that were running when the mishap occurred. For the time being you can ignore everything except the first line.

In the present case the mishap message is `STACK EMPTY'. This is POP-11's way of saying that you tried to make use of a value that did not exist. The code

2 * ==>
Tries to multiply 2 by nothing. Thus it attempts to use a value (a number) that does not exist.

(To familiarize yourself with mishap messages, try executing the following POP-11 code: `2 ++ 4'.)

But, back to expressions. Note that we can combine expressions together in the normal way. Thus

2 * 4 + 3 / 2 ==>
** 9.5
(In some Poplog environments this value will print out as `19_/2', which is the way Poplog represents the value internally.) Note that, by convention, division and multiplication operations are carried out before additions and subtractions. If there is any ambiguity over which values should be evaluated first, POP-11 simply works through the expression left-to-right. We can force it to work out a particular value in a particular way by using round brackets to separate off some particular sub-expression. Thus, given

2 * (4 + 3) / 2 ==>
POP-11 prints

** 7
By putting `4 + 3' in brackets we have forced POP-11 to multiply the 2 by 7 rather than by 4.

(Put brackets into the expression `2 * 4 + 3 / 2' so as to force the `3 / 2' part to be evaluated first. Type in the new expression and make POP-11 print out its value. The result should be `** 9.5'.)

No special approach is required to deal with real numbers, i.e., numbers like 9.5 which have a fractional part. They can be used exactly like whole numbers (integers). Thus

3.4 * 2.1 / 10.3 ==>
prints out

** 0.693204

Variables

POP-11 expressions (i.e., commands that produce values) are most useful when used in conjunction with `variables'. A variable is effectively a named box in which you can store the value of an expression. It is possible to create new variables in which to store things. This is done with the `vars' command. The command

vars mine;
sets up a variable called `mine'. Note the semi-colon at the end. All commands that do not have a `==>' at the end, should be terminated with a semi-colon.

More than one variable can be set up at the same time by typing several words separated by commas after the `vars'.

vars mine, yours;
The names of variables can contain alphabetical characters in upper or lower case. The can also contain numbers, or the underscore character `_'. However, they are not allowed to begin with a number or the underscore character. And they are not allowed to contain hyphens. Thus

vars foo_bang23;
is OK, but

vars 23foo_bang;
is not.

(Work out which of the following are legal variable names: man, big-man, BIG-MAN, big_man, word23, _word5, Another_word, 5List, list5.)

Once we have established a variable, we can put something in it using the `->' command. This is known as the `assignment arrow'. We use the assignment arrow by placing it between the value and the variable. Thus

2 -> mine
has the effect of putting the value 2 into the variable `mine'. This value stays in this variable until you assign another value to it or exit from Poplog.

By convention, a variable name is treated as an expression whose value is just the contents of the variable. Thus the result of

mine ==>
is

** 2
Now that I have stored 2 in the variable `mine', I can use the variable anyplace I might have used 2. So

mine * (4 + 3) / mine ==>
has the same effect as

2 * (4 + 3) / 2 ==>
namely

** 7
(For practice, write the POP-11 code to set up a variable called `num' and assign the value 3.6 to it.)

We can effectively save the value of complex expressions by storing them in variables. Thus

vars yours;
mine * (4 + 3) / mine -> yours;
This sets up a new variable, then assigns the value of the expression to be its new value. Note how the semi-colon is used to separate the two commands. If we left out the semi-colon, POP-11 would complain by displaying the message `ILLEGAL DECLARATION OF WORD'. It would do this because it would not know where the `vars' command ends and thus would carry on turning the successive words into variables. On reaching the star, POP-11 realises that something is amiss since the multiplication symbol (star) is not an allowed variable name. You can see this effect if you try to execute the following.

vars yours
mine * (4 + 3) / mine -> yours
Note that it is good style to include a semi-colon at the end of every command, even if there are no commands coming after.


POPBUGS ex: using assignments to control behaviour

The next exercise involves using the POPBUGS library and should be done by people using graphics displays. First load the library with the command

lib popbugs
Once the library has been loaded a window will appear on your screen containing the POPBUGS banner. (Don't ever attempt to close this window since that will terminate the entire poplog session.) You can move the window around by moving the `mouse pointer' (the little arrow whose movements mirror the movements of the mouse attached to your keyboard) up to the top of the window, pressing down the left button over the bar, and then moving the mouse to a new position. You can usually make windows bigger and smaller by applying the same technique to the corners of the window. However, if you change the size of the Poplog window you will need to refresh it by pressing the REFRESH key.

The POPBUGS library lets you use POP-11 commands to make things happen in a simulated world, populated by insect-like bugs. For example, to construct a new world with a single bug in it we assign 1 to `pb_new_world'.

1 -> pb_new_world;
To make the bug move forwards or backwards we assign numbers to the special POPBUGS variable `pb_steps'. (This makes the bug move because the POPBUGS library `knows' each time this variable has a new value assigned to it.) Positive numbers make the bug go forwards the specified number of steps. Negative numbers make the bug go backwards. Try

3 -> pb_steps;
And then

-6 -> pb_steps;
We can control the direction in which the bug is heading by assigning a heading value to the variable `pb_direction'. Try

220 -> pb_direction;
The values of the pb_direction variable work like compass headings with heading 0 corresponding to due west (i.e. left of centre). Headings increase anti-clockwise. Thus, a heading of 270 is to due north, 90 is due south, 0 is due west and 180 is due east. We can make the bug turn to the left by increasing the value of `pb_direction' and make it turn to the right by decreasing the value. This simply involves adding 1 to the relevant variables. Thus we can make the bug draw out a rectangle trail with the following sequence of commands.

1 -> pb_new_world;
5 -> pb_steps;
pb_direction - 90 -> pb_direction;
5 -> pb_steps;
pb_direction - 90 -> pb_direction;
5 -> pb_steps;
pb_direction - 90 -> pb_direction;
5 -> pb_steps;
pb_direction - 90 -> pb_direction;
Experiment: write a program that makes the bug visit all four corners of the simulated world before returning to the centre.


Repeat commands

Often when programming, we want to execute a particular sequence of commands several times over. This affect can be achieved in POP-11 using the `repeat' command. To construct a `repeat' command we type in a single copy of the sequence of commands and then put `repeat N times' at the beginning and `endrepeat' at the end---with `N' replaced with a suitable whole number. So to print out all the numbers between 1 and 10 we might do the following.

vars num;
1 -> num;
repeat 10 times
   num ==>
   num + 1 -> num;
endrepeat;
The `repeat' command is called a `looping' command since it effectively makes POP-11 repeat a loop of actions several times over.

Note that if you ever want to stop POP-11 doing whatever it is currently doing, you can interrupt the program. This is achieved by holding down the CONTROL key (sometimes marked CTRL) and pressing `c'. The key combination is often referred to as `CTRL-C' or `Control-C'. Try changing the code above so that it loops 1000 times. Then execute it but instead of waiting for it to finish, interrupt as soon as possible by pressing CTRL-C.


POPBUGS ex: using repeat loops to draw pictures

Our previous program to make the bug draw a rectangle involved repeating the subsequence of commands

pb_direction - 90 -> pb_direction;
5 -> pb_steps;
several times over. We can improve on this (i.e., make the program much shorter) by using a `repeat' command. For example

1 -> pb_new_world;
repeat 4 times
   5 -> pb_steps;
   pb_direction - 90 -> pb_direction;
endrepeat;
The fact that the `repeat' command is an ordinary POP-11 command means that we can put `repeat' commands inside other `repeat' commands. With two repeat commands---one `nested' inside the other---we can draw out quite a complex picture.

1 -> pb_new_world;
repeat 7 times
   repeat 4 times
      5 -> pb_steps;
      pb_direction - 90 -> pb_direction;
   endrepeat;
   pb_direction + 15 -> pb_direction;
endrepeat;

Using simple procedures

When we have a set of commands that achieve a certain effect, we can package them up into a named `procedure'. We can then run the whole sequence just by `calling' the procedure. This involves typing in the name of the procedure followed by a pair of round brackets.

To define a procedure we type in the relevant sequence of commands and then put `define NAME;' at the beginning and `enddefine' at the end---with NAME being replaced by a suitable name. For example, we might define a procedure to print out all the numbers between 1 and 10 as follows.

vars num;

define print_nums;
   1 -> num;
   repeat 10 times
      num ==>
      num + 1 -> num;
   endrepeat;
enddefine;
Now we can print out the numbers just by calling the procedure.

print_nums();

** 1
** 2
** 3
** 4
** 5
** 6
** 7
** 8
** 9
** 10
Wrapping up chunks of code into procedures has many advantages. For example, we can get the code tidied up automatically (i.e., indented properly) simply by placing the cursor inside the procedure and giving the Ved command `jcp'. If we want to load the procedure then instead of marking it and doing `lmr', we simply place the cursor inside the procedure and give the command `lcp'. Try using `jcp' to tidy up the following definition and then `lcp' to load it.

define untidy; repeat 20 times 2 ==> endrepeat enddefine;

Note that the command only works if the initial `define' is flush against the margin.


POPBUGS ex: defining drawing procedures

Using the `define' command we might define a procedure that makes the bug draw out a rectangle. For example

define rectangle;
   repeat 4 times
      5 -> pb_steps;
      pb_direction - 90 -> pb_direction;
   endrepeat;
enddefine;
We can now make the bug draw a rectangle just by calling the procedure. Try

rectangle();
We could also define a procedure to draw triangles;

define triangle;
   repeat 3 times
      pb_direction - 120 -> pb_direction;
      5 -> pb_steps;
   endrepeat;
enddefine;
Now we can test it. (Use the procedure `pb_refresh()' if you want a clean display.)

triangle();
Now we can write a procedure to draw a house that uses the rectangle procedure followed by the triangle procedure. The procedure can be defined like this.

define house;
   1 -> pb_new_world;
   0 -> pb_direction;
   triangle();
   pb_direction + 180 -> pb_direction;
   rectangle();
enddefine;
To test it, just load the following

house();
Experiment: work out what affect assignments to the variable `pb_size' have.


Tip of the day

Many of the most common Ved commands have `shortcuts'. For example, on most keybords, it is possible to execute the `lmr' command simply by typing CTRL-d, i.e., by pushing down the CTRL key and hitting `d'.


Exercises

To test your understanding of the material in this file you should do the following exercises. First, copy them into a file of your own. Then, edit in answers underneath each question and print out the file.

Do not make the mistake of writing your answers directly into the TEACH file. If you do this, your work will be lost when you leave Poplog.

If you are having difficulty with a particular problem, search back through the file for relevant information. If necessary, check the index (using the `g' command) for relevant section headings. Do not waste your time typing in code unless you feel SURE it will do what you want.

  1. Which of the following cause a mishap and why?

    2 + 3 = 4 ==>
    
    2 3 * 2 ==>
    
    * 4 ==>
    
  2. The following all cause POP-11 to print out a `mishap' message that says `STACK EMPTY'. Describe the source of the trouble in each case.

    2 + 3 = ==>
    
    * 4 ==>
    
    2 * * 4 ==>
    
    2 = >
    
  3. What POP-11 commands are required to do the following: (1) establish two variables called `bang' and `bong'; (2) assign 3 to `bang' and `4' to `bong'; (3) divide the value of `bang' by the value of `bong' and assign it to be the new value of `bong'; (4) print out the value of `bong'.

  4. What happens if you assign a value to a variable that you have not previously declared?

  5. Define a procedure that prints out all the `squares' of all the whole numbers between 1 and 25. (The square of a number is just the number multiplied by itself.)

  6. Does the `lcp' command have a shortcut. If so what is it?

  7. Create a new file and insert into it a POP-11 program that makes the bug draw out a picture of a double-decker bus crossing a bridge.

Revision exercises

Do not do the following exercises on your first reading of this file. Save them from revision purposes.


Quick reference

The following list contains the main commands you have been introduced to in this file. If you copied the list from TEACH POPCOURSE1 into a file of your own, you might like to add these items to it. (You can put the whole list into alphabetical order by marking it and giving the Ved command `smr'.)

*       operator that multiplies two numbers
**      operator that raises one number to a specified power
+       operator that adds two numbers together
->      the assignment arrow; used to put a value into a variable
/       operator that divides two numbers
==>     the print arrow, used for printing values out
lmr     Ved command that loads (executes) a marked range of POP-11 code
vars    command that sets up one or more new variables

Moving on

If you have completed all the exercises above you are ready to move on to TEACH POPCOURSE3.


Page created on: Fri Apr 26 09:34:49 BST 2002
Feedback to Chris Thornton
hits this year