PLN 5

Example of the use of PL1900 to Define Basic List Processing Procedures

D.M. Foster

22.7.68

This example shows how the basic list processing procedures can easily be defined using PL1900. The procedures could, with minor modifications, be used as machine functions in IL1900.

The scheme assumed here, which is not necessarily the best, is the classical one. It assumes a list consists of a string of two word pairs. The first word in each pair is an item which could either be an atom or a pointer to another list. The second word in each pair points to the next pair in the list. The last pair in the list has its second word zero. Thus a list of three items of which the first is the atom A, the second a list of two atoms B and C, and the third the atom D, is represented as follows:

A D 0 B C 0

We will assume for the sake of this exercise that as in the EMA system there is an area of store available whose address is kept in FREESTORE. This is used for building up lists. The address of the next available store is kept in NEXTFREESTORE. At the top of the freestore is a stack built up downwards. As the freestore is built upwards and stack downwards a check must be made as to whether they are encroaching on each other. If they do a jump is made to FSERROR.

The address of the top of the stack is kept in X2 (the top of the stack is the end with the lowest numbered address). All procedures take their arguments from, and leave their results on, the top of the stack.

Pointers are distinguished by having their first bit set to 1.

The following block is a block of procedures that use X0 as their link and assume that X3, X6 and X7 are free for use.

BEGIN 
LOWER INTEGER LINK, RUBATOM = #37777777; 
      GLOBAL LAYOUT: INTEGER FREESTORE, NEXT FREESTORE GLOBEND LOWEND; 

PROCEDURE STOREITEM (X0) ; 
     [STORES A TWO WORD PAIR FROM X67 ON FREESTORE IF NOT ALREADY PRESENT 
     AND LEAVES POINTER TO IT IN X3] 
BEGIN 
      X3←FREESTORE; 
  L1: IF X3 = NEXT FREESTORE THEN 
      BEGIN (X3)←X6; (X3+1)←X7; X7←X3+2; 
             IF X7>X2 THEN GOTO FSERROR; 
             NEXT FREESTORE←X7; GO TO OUT; END 
      IF X6 = (X3) AND X7 = (X3+1) THEN GO TO OUT; 
      X3←X3+2; GO TO L1; 
 OUT: X3←X3 OR 256 CNT; 
END 

PROCEDURE LIST1 (X0) 
     [CREATES A LIST OF ONE ITEM FROM TOP ITEM OF STACK] 
BEGIN 
  LINK←X0; X6←(X2); X7←0; 
  CALL STOREITEM; (X2)←X3; X0←LINK; 

PROCEDURE LIST 2 (X0) 
     [CREATES A LIST OF TWO ITEMS FROM TOP TWO ITEMS OF STACK] 
BEGIN 
  LINK←X0; 
  X6←(X2); X7←0; CALL STOREITEM; 
  X6←(X2+1); X7←X3; CALL STOREITEM; 
  X2←X2+1; (X2)←X3; X0←LINK; 
END 

PROCEDURE LIST 3 (X0)
     [CREATES A LIST OF THREE ITEMS FROM TOP THREE ITEMS OF STACK ] 
BEGIN 
  LINK←X0; 
  X6←(X2); X7←0; CALL STOREITEM; 
  X6←(X2+1); X7←X3; CALL STOREITEM; 
  X6←(X2+2); X7←X3; CALL STOREITEM; 
  X2←X2+2; (X2)←X3; X0←LINK; 
END 

PROCEDURE FIRST (X0) 
     [EXTRACTS THE FIRST ITEM FROM A LIST. A SPECIAL RUBBISH ATOM IS 
      GIVEN AS RESULT IF TOP ITEM OF STACK IS NOT A LIST] 
BEGIN 
  X3←(X2); 
GLABEL FIRSTL: IF X3>=0 THEN X3←RUBATOM ELSE X3←(X3); 
  (X2)←X3; 
END 

PROCEDURE SECOND (X0) 
     [EXTRACTS THE SECOND ITEM FROM A LIST. THE RUBBISH ATOM IS GIVEN 
     AS RESULT IF LIST HAS NOT AT LEAST TWO ITEMS] 
BEGIN 
  X3←(X2); 
GLABEL SECONDL : IF X3>=0 THEN X3←RUBATOM ELSE X3←(X3+1) 
  GOTO FIRSTL; 
END 

PROCEDURE THIRD (X0) 
     [EXTRACTS THE THIRD ITEM FROM A LIST. THE RUBBISH ATOM IS GIVEN 
      AS RESULT IF LIST HAS NOT AT LEAST THREE ITEMS]
BEGIN 
  X3←(X2); 
  IF X3 >=0 THEN X3←RUBATOM ELSE X3←(X3+1); 
  GO TO SECONDL; 
END 

PROCEDURE TAIL (X0) 
     [REMOVES THE FIRST ITEM FROM A LIST. THE RUBBISH ATOM IS GIVEN 
      AS RESULT IF TOP ITEM ON STACK IS NOT A LISTJ 
BEGIN 
  X3←(X2); 
  IF X3 >=0 THEN X3←RUBATOM ELSE X3←(X3+1);
  (X2)←X3; 
END 

PROCEDURE CONS (X0) 
     [ADDS THE ITEM ON THE TOP OF THE STACK TO THE FRONT OF THE LIST 
      ON THE SECOND WORD OF THE STACKJ 
BEGIN 
  LINK←X0; X6←(X2); X7←(X2+1); CALL STOREITEM; 
  X2←X2+1; (X2)←X3; X0←LINK; 
END 
END 

Notes

  1. It is not necessary to use the rubbish atom, but it does allow more freedom when analysing lists.
  2. Note that if two identical lists are built up they are represented by the same list, not two separate lists. Hence if lists are used to represent arithmetic expressions, common subexpressions are represented by the same list.
  3. A less elegant although perhaps more efficient way of representing lists is used in 1900 EMA. A list of n items is represented by n consecutive words and the pointer to it contains n in its top bits. The forming of lists thus becomes more complicated (CONS is horrible if we want to check for identical lists) but analysing of lists is more efficient.
  4. I am not sure whether jumping to global labels within procedures is permissable, but I think that it should be.