next up previous contents
Next: CHAPTER.2: INTRODUCTION TO Up: CHAPTER.1: INTRODUCTION --- Previous: Type-less higher order

POP-11 : A MINIMAL MODEL

Added 11 Oct 1997

Understanding Pop-11 requires understanding at least the syntax and semantics of Pop-11.

The syntax of Pop-11.

Chapter 2 of this Primer includes a lot of information about the syntax, including:

o The "lexical" syntax, i.e. how the stream of characters read into Pop-11 is broken up into "lexical items", or "text items", including: words, strings, and numbers. (See also HELP WORDS, HELP STRINGS, HELP NUMBERS).

o The "compositional" syntax, i.e. how the text items can be combined in various ways to form more complex programming constructs, e.g. variable declarations, procedure definitions, procedure invocations, list expressions, vector expressions, commands, comments, the use of infix operators like "+", "-", "<>", etc. (Experienced students can try looking at REF POPSYNTAX)

The semantics of Pop-11

Chapters 2 and 3 primer give a lot of information about the semantics of Pop-11 including:

o Some of the types of structures that can be created and manipulated by Pop-11 programs.

o Some of the types of processes that can be generated by running Pop-11 programs. (See also TEACH STACK).

o The differences between the "compile time" semantics (i.e. the processes that occur when a program is being read in and translated into machine instructions) and the "run time" semantics (i.e. the processes that occur when your program has already been compiled, and starts running).

These notes provide additional information about what happens when declarations are compiled and when procedures are running.

The Pop-11 "virtual machine"

When Pop-11 starts up space is allocated for it in the computer. Some of the space may be in the main memory of the computer (RAM), some in temporary disk files. Where the space is allocated may change while the program is running. (Some parts of the Pop-11 system include bits that your programs cannot alter, so their space can be shared with other users, saving memory in the machine.)

Pop-11 breaks up the space into different areas which have different functions. These are parts of the Pop-11 "virtual machine". When your program is compiled, and when it runs, it causes changes to occur in the virtual machine.

The actual virtual machine is quite complicated because it is designed to support a variety of types of languages (including Lisp, Prolog and ML), and also interactions with the operating system, the file system, the windowing system and remote machines. However, a subset depicted in the diagram is fairly easy to understand, consisting of six parts of the virtual machine:

o 1. The dictionary, containing words (some of which are variables, some Pop-11 syntax words, and some simply words used as symbols to be manipulated or printed out),

o 2. The set of "built-in" procedures,

o 3. The "heap" where new procedures and structures are created, including temporary ones.

o 4. The procedure-call stack (procedure-activation stack)

o 5. The user stack (sometimes just called "the stack")

o 6. Input and output channels for communicating with the terminal.

All of these can change, both while programs are being compiled and while they are running. However during the running of the program it is normally the last four which change.


Diagram of the model

The dictionary

The dictionary includes (among other things):

o Syntax words known to Pop-11, including "define", "enddefine", "if", "for", "endfor", "vars", "(", ")", "[", "]", "=>", "->", ",", ";",

o Procedure names known to Pop-11, including "readline", "mishap", "ved_teach", "pr", "sqrt", "hd", "last", "random", and infix procedure names, like "+", "-", "=", "*", "<>",

o Names of global variables defined in the Pop-11 system, or by your program.

o Other words which do not have any "meaning" for the program, but are used as symbols, e.g. in a list printed out by eliza, or a list of words typed in by the user in answer to a question. These words do not have a "value" cell associated with them, unlike variables, procedure names, and some of the syntax words. E.g. the list [the cat] contains two words which are put in the dictionary, but need not have any associated value (unless they are later used as variables).

When the Pop-11 compiler reads a declaration like the following,

    vars list1, list2;
it adds the words "list1" "list2", to the dictionary, specifies (in the dictionary) that each word is a em variable, and associates with it a default value, i.e. an "undefined" value, which prints as <undef list1>, for example. Later an assignment using the format "-> list1", may assign something to the variable and that will change the contents of the value cell for that variable. The picture shows two user variables num1 and num2 which have been assigned numbers as values.

Built-in procedures

When Pop-11 starts up it has many built-in, previously compiled, procedures, e.g. all the syntax procedures used by the Pop-11 compiler, and procedures for creating and manipulating words, strings, arrays, lists, vectors, numbers, buffers in the editor, graphical windows, etc. These are in a "permanently allocated" portion of the Pop-11 virtual machine. I.e. you can't remove them.

The heap: for structures which may change

When your program creates a list, e.g. using expressions like these:

    [the cat sat on the mat]

    [perhaps in your fantasy we .^^.list each other]
as an Eliza program might do, then the list is assembled using locations in the heap (explained in TEACH WAL).

A "pointer" to the list is put on the user stack, i.e. an internal symbol with the address of the list (the place in the heap where it starts) is put on the stack. An assignment or a procedure requiring an input value, may remove it from the stack, while it remains in the heap. Later, if your program runs out of heap space, a special procedure called the "garbage collector" is automatically invoked. It may decide that nothing in your program can access that list any more (e.g. none of your variables has the list as its value, and none of the other lists that your program can still access includes the list). In that case the space will be cleared and can be re-used for something else.

(One source of inefficiency in programs is creating unnecessary temporary structures and giving the garbage collector too much to do.)

Besides lists, Pop-11 programs can create many other types of objects, some described in the Primer, Chapter 2. E.g. each Ved buffer is a "vector" of strings, stored in the heap.

The procedure call stack

When you have started up Pop-11 and the editor, Ved, there are already several procedures "active". First there are procedures that set up Pop-11, and find out what you want to do. If you specify that you want to run the editor, the setup procedures will invoke Ved procedures, and just wait until Ved finishes before they do anything else, such as close down Ved windows and terminate the Pop-11 process.

If you have created and compiled the conversational procedures specified in TEACH RESPOND, you can then run your procedure called converse, Ved will hand the instruction to Pop-11, which will start the procedure. Converse may then invoke other procedures, e.g. a procedure to find out the user's name and print a greeting, the readline procedure to read in a sentence typed by the user. It may then invoke the respond procedure to work out how to reply.

That procedure might call (i.e. invoke) the system procedure matches to decide what sort of sentence the user typed in.

At that point several procedures are all active, as shown (approximately) in the picture of the procedure call stack, where each procedure is waiting for the one above it (which it invoked) to finish. Only the one at the top is actually doing anything, and as soon as it has finished, it is removed from the top of the call stack and the one below it continues immediately with the next instruction. That may call yet another procedure, which will then go on the call stack.

Thus the contents of the call stack are constantly increasing and decreasing. For each active procedure (either running, or waiting to continue) the call stack needs information about which procedure it is, what its next instruction is, whether it has "local" variables (lvars) and if so what their current values are.

If you get a MISHAP, the "DOING" line tells you which procedures were in the procedure call stack (apart from "system" procedures which are not printed out).

The user stack

If a procedure (e.g. readline) creates a list, the list is created in the heap, and a pointer to it (its address in the heap) is put on top of the stack. Then another procedure can get the last item constructed, by examining the top of the stack. E.g. if this command is run, then

    readline() -> sentence;
the procedure readline pauses while the user types things. Pressing RETURN wakes up readline, so that it reads the characters from the terminal input channel (possibly via the editor), breaks them up into words, assembles them into a list in the heap, and puts its address on the stack. The assignment operation moves the address to the value slot currently associated with the variable "sentence".

The value slot is in the dictionary if "sentence" is a global variable, declared with vars or in the current procedure activation record if it is a local variable declared with lvars.

"Arguments" can be passed to a procedure via the user stack. E.g. if converse includes the command,

    respond(sentence) =>
that first of all puts the value of the variable sentence on the stack, then suspends converse and runs respond. The latter takes the item off the stack and then does things with it (e.g. if it's a list, the words in it may be used to decide how to reply). When finished respond puts another item on the stack, its result. Then the print arrow => procedure takes it off, prints it through the output channel (a character at a time), and then converse continues with its next instruction.

The chapter on procedures and the stack, Chapter 3, gives a lot more information about how procedures use the stack.

Input and output channels

These are used for reading in characters typed at the terminal, and for printing out characters, e.g. in the form of words, or numbers, or spaces, newlines, etc. Pop-11 can also read things in from files stored on the disc, or send information out to files on disk: Ved uses that capability to read your files and save them afterwards. So a more complete model would show additional input and output channels, and all the program and documentation libraries.

Poplog and the operating system

For some purposes, understanding how Poplog, Pop-11, and the Editor works requires knowledge of other parts of the operating system, which is usually some version of unix or linux. The following diagram gives an approximate impression of the relationships, though many details are omitted, such as the fact that Pop-11 may have to communicate with the operating systems memory management sub-system, or its filemanagement sub-system.


Diagram showing Poplog, Pop11 and the rest of the operating system

Conclusion

This section may make it easier for you to understand some of the remaining portions of the Primer. Much of the explanation here has been simplified. However, this model will enable you to do a lot of the programming required for an introductory course. The rest of the PRIMER provides a lot more information. Further information is in REF files, HELP files and TEACH files.



next up previous contents
Next: CHAPTER.2: INTRODUCTION TO Up: CHAPTER.1: INTRODUCTION --- Previous: Type-less higher order



Aaron Sloman
Fri Jan 2 03:17:44 GMT 1998