.he 'SYNTAX''Page %'
.fo 'Steven Hardy'- % -'30th May, 1977'
.de fl
.bb
.so \\$1
..
.de he
..
.de fo
..
.ce 2
Syntax words in POP11
=====================
.sp2
.in +8
.ll -8
In this, and all other 'demos', POP11 code is shown in upper case.
This is to help the reader tell the difference between code and text
(also the majority of our users will be using upper case only terminals).
If you are using a terminal capable of generating lower case letters
then type POP11 in lower case. POP11 keywords will not be recognized
if typed in upper case on a terminal capable of generating lower case.
.in -8
.ll +8
.sp 2
Round brackets, ( and )
.br
-----------------------
.br
Parentheses have two purposes:-

i)   To denote function application, for example F(X,Y) means 'apply the function
held in the variable F to the value of the two expressions X and Y.  The arguments
of a function call (in this case X and Y) can be any POP11 expression, for
example:
.br
 	: EQUAL(HD(X), HD(TL([A B C D])))
.br
There may be any number of arguments, from 0 upwards.  For example G() means apply
the function
held in the variable G with no arguments.
Notice that arguments of a function call are separated by commas.
Expressions like
.br
 	: F(G)(H)
.br
are permissible.
This one means 'apply F to G and apply the result of that to H`.
For example:
.br
 	: VALOF(HD(LIST))(ARG)
.br
can be used if LIST is a variable whose value is a list of words
whose values are functions.

ii)   To force the computer to regard a sequence of code as a single unit.
For example,  because of precedence rules 1+2*3 is
interpreted as 'add one to the result of multiplying two by three', whilst
(1+2)*3 means 'multiply the result of adding one and
two by three'.
.bb
Decorated round brackets, (% and %)
.br
-----------------------------------
.br
Decorated parentheses are used to create 'function closures`, for example:
.nf
 	: FUNCTION HYPOT(HEIGHT, BASE);
 	:	SQRT(HEIGHT * HEIGHT + BASE * BASE)
 	: END;
.fi
This function could be used to find the length of the longest side
of a right angled triangle, given the the lengths of the other two
sides.
If we execute:
.br
 	: HYPOT(%5%) -> F;
.br
then F will be a function of one argument such that a call of
.br
 	: F(X)
.br
is equivalent to a call of:
.br
 	: HYPOT(X, 5)
.br
the second argument of hypot has been 'frozen' into F to give us a function
of one argument to compute the longest side of right angled triangles
whose base is 5 units long.
.sp
A second example, using the library function MEMBER, is:
.nf
 	: VARS ISCOLOUR;
 	: MEMBER(%[RED ORANGE YELLOW GREEN BLUE INDIGO VIOLET]%)
 	:	-> ISCOLOUR;
.fi
.sp
F(%...%) is 'syntactic sugar` for PARTAPPLY(F,[%...%]) - see SYSVARS.
.bb
Square brackets, [ and ]
.br
------------------------
.br
List brackets signify to the compiler that it must create a list.  For example
.br
 	: [CATS EAT MICE] -> X;
.br
assigns a list of three
words to the variable X.  The three elements of this list are the words CATS,
EAT and MICE.  The elements of a list
created in this way can be words (as here), numbers, strings or other lists.
for example
.br
 	: [TIMES [PLUS 1 2] 3]
.br
is a list of three
elements, the word TIMES, the list [PLUS\ 1\ 2] and the integer 3.  The empty
list is held in the variable NIL, so that
.br
 	: NIL -> X;
.br
is equivalent to:
.br
 	: [] -> X;
.br
.sp
The items in a list are not evaluated, so that:
.nf
 	: VARS X; 3 -> X;
 	: VARS Y; 4 -> Y;
 	: [THE SUM OF X AND Y IS X+Y] =>
 	** [THE SUM OF X AND Y IS X + Y]
.fi
We can tell the POP11 system we want part of a list evaluated by putting the
appropriate part of the list between percents, thus:
.nf
 	: [THE SUM OF %X% AND %Y% IS %X+Y%] =>
 	** [THE SUM OF 3 AND 4 IS 7]
.fi
You can have several expressions between percents, but you should separate them
with commas, thus:
.nf
 	: [THE SUM AND PRODUCT OF %X% AND %Y% ARE %X+Y, X*Y%] =>
 	** [THE SUM AND PRODUCT OF 3 AND 4 ARE 7 12]
.fi
A further example of the use of percents in lists is:
.br
 	: [%F(X,Y)%] =>
.br
This makes a list of the results of applying F to X and Y - even if F
has several results.
.sp
There is a further 'frill` in list expressions which is only useful
in advanced programming. Consider the following:
.nf
 	: VARS NUMS; [1 2 3 4] -> NUMS;
 	: [%NUMS% 5] =>
 	** [[1 2 3 4] 5]
.fi
The list expression here evaluates to a two element list whose first
element is the four element list [1 2 3 4].
Had we wanted
.br
 	** [1 2 3 4 5]
.br
we would have to write:
.br
 	: NUMS <> [5] =>
.br
or	: [%DL(NUMS)% 5] =>
.bb
Twiddly brackets, { and }
.br
-------------------------
.br
These brackets are like [ and ] except that they create 'strips' instead of lists.
See INIT in the SYSVARS demo.
.bb
Dot, .
.br
------
.br
Dots are an alternative denotation for function application, .F is equivalent
to F(), X.F is equivalent to F(X).  This
notation is especially convenient for long chains of function applications,
for example HD(TL(TL(X))) can be replaced by
X.TL.TL.HD
Dot is defined thus:
.nf
 	: VARS OPERATION 1 .;
 	: APPLY -> NONOP .;
.fi
.bb
Comma ,
.br
-------
.br
Commas are used to separate the arguments of a function call and as a separater
between the expressions in a decorated list
expression - for example.  
.br
 	: F(X,Y), [%X, Y%]
.br
Commas can be used to separate
statements - for example 
.br
 	: 3, 4, 5=> 
.br
instead of
.br
 	: 3; 4; 5=>
.br
or
 	: X, Y -> X -> Y;
.br
instead of
.br
 	: X; Y; ->X; -> Y;.
.bb
Semicolon, ;
.br
------------
.br
Semi-colons separate statements and terminate the list of formal and output
locals in a function definition or LAMBDA
expression.  For example
.nf
 	: VARS X, Y; 3-> X; 5 * X -> Y;
 	: FUNCTION AREA(BASE,HEIGHT) => RESULT;
 	:	(HEIGHT * BASE) / 2 -> RESULT
 	: END;
.fi
Unless terminating a declaration, semi-colons can be omitted if they would
be immediately followed by END, CLOSE, ELSE, ELSEIF,
EXIT or "->".
Superfluous semi-colons are usually ignored by the POP11 compiler,
for example, the following is legal:
.br
 	: VARS X, Y;; 3 -> X;; 5 * X -> Y;;
.br

Semicolons can also be used to introduce comments,
for example:
.br
 	: VARS PAINT; "*" -> PAINT;     ;;; SET PAINT TO BE AN ASTERISK
.br
The three semicolons tell the compiler to ignore the rest of the line.
.bb
Word quotes, "
.br
--------------
.br
Normally a word is used to denote a variable, for example X+1->X means add
one to the value  of X and store
the result of the addition in the variable X, or again X=> means print the
value of the variable
X, or yet again F(X) means apply the function held in the variable F to the
value of the variable X.
Word quotes indicate that it is the word itself we are interested in
and not its value, thus
"X"=> means print the word X,
"X"+1 would produce an error (since one cannot add a word to a number) and
F("X") means apply the function F to the word X.
Some more examples:
.br
 	: 3 -> X; "X" -> Y;
.br
assigns 3 to the variable X and the word X to the variable Y, so that:
.nf
 	: X, Y=>
 	** 3 X
.fi
.bb
Character quote, `
.br
------------------
.br
The character quote is used to find the numerical code
associated with any given character, for example:
.nf
 	: `A =>
 	** 97
.fi
97 is the code for the character 'A'.
.nf
 	: `B =>
 	** 98
.fi
Notice that
.br
 	: CUCHAROUT(`A);
.br
is equivalent to
.br
 	: PR("A");
.br
but a lot faster.
.br
The following are the codes for a space, a tab, a newline
and a backslash respectively:
.nf
 	: `\\S, `\\T, `\\N, `\\\\ =>
 	** 32 9 10 92
.fi
If you have an upper case only terminal you must type
the sequence \\' to get `. Remember, also, to type
the sequence \\\\N to get \\N.
(See the TERMINALS demo).
.bb
String quote, '
.br
---------------
.br
String quotes turn the enclosed characters into a 'string'.  (The POP11 name
for a data struicture holding a sequence of
characters).  
For example:
.bl
'HI THERE' - a string of eight characters
'+) FOO'      - a string of six characters
.el
(notice that spaces are significant inside strings).
Any characters, except string quotes and new lines, can be put between string quotes.
Strings don't have to be legal POP11 (see the second example above).
.br
If you want to put a string quote or a new line inside a string use the
'escape character` "\\".
If this character is followed by an 'n' it puts a new line in the string and
and if followed by any other character then it allows that character into the string.
.tp 10
For example:
.nf
 	: PRSTRING('HOW TO PUT STRING QUOTES - \\' - INTO STRINGS');
 	 HOW TO PUT STRING QUOTES - ' - INTO STRINGS
 	: PRSTRING('BRING ME JOHN\\'S BOOK');
 	BRING ME JOHN'S BOOK
 	: PRSTRING('THIS IS THE FIRST LINE,\\NTHIS IS THE SECOND\\
 	: AND THIS IS THE THIRD');
 	THIS IS THE FIRST LINE,
 	THIS IS THE SECOND
 	AND THIS IS THE THIRD
.fi
NB - If you are using an upper case only terminal you will need to type
\\\\N (just one backslash would you you a capital N and \\\\' (just one backslash would get you a ') - see the TERMINALS demo.
.bb
Colon, :
.br
--------
.br
Colons are used after a POP11 word
to label an instruction inside a function.  See "GOTO" for a more detailed
description of this usage.
.bb
Assignment arrow, ->
.br
--------------------
.br
The assignment arrow can be used in two ways:-
.br
i)   If followed by the name of a variable, e.g. ->X it removes the top element
from the stack and stores it in that variable.
For example the sequence:
.br
 	: 3 -> X; 4 -> Y;
.br
puts 3 on the stack, removes it and stores it in X, then puts 4 on the stack
and then removes it, storing it in Y.
.br
 	: 3, 4 -> X -> Y;
.br
puts 3 on the stack, then 4, then removes the top element (i.e. 4) storing
it in X and then removes the top element (now 3)
storing it in Y.
.br
 	: X, Y -> X -> Y;
.br
swaps the values of X and Y.

An assignment arrow need not be preceded by
an expression, for example:
.br
 	: VARS X Y; -> Y -> X;
.br
declares two variables (X and Y) and then initialises them with whatever the top two items
on the stack are.

ii)
If followed by a 'function call`, for example:
.br
 	: "A" -> HD(L);
.br
the compiler ensures that the UPDATER (see SYSVARS) of the function is called.
So this example
replaces the first element of the list held in the variable L by the word
"A".
Since arrays are functions with updaters,
you use this notation for updating an array.  For example if PIC is a
2-dimensional array then "APPLE" -> PIC(3,4); assigns the word
APPLE  to position 3,4 of the array PIC.  The notation:
.br
 	: E1 -> F(E2)
.br
(Whatever E1, F and E2 are) is equivalent to:
.br
 	: UPDATER(F)(E1,E2)
.bb
.nf
The non-destructive assignment arrow, ->>
-----------------------------------------
 	X + Y  ->> Z
is equivalent to:
 	(X + Y  -> Z; Z)
i.e. the thing assigned is left on the stack.
Examples of its use:
        : 0 ->> X ->> Y -> Z;
This sets X, Y, and Z all to zero.  Or again:
        : IF SEARCH() ->> RESULT THEN ... ELSE ... CLOSE
Beware of the following:
        : IF E1 ->> R OR E2 ->> R THEN ... ELSE ... CLOSE
This means:
        : IF (E1 ->> R OR E2) ->> R THEN ... ELSE ... CLOSE
and not:
        : IF (E1 ->> R) OR (E2 ->> R) THEN ... ELSE ... CLOSE
In  this  particular case the code still works, but the following
might not be what you intend:
        : IF E1 ->> R1 OR E2 ->> R2 THEN ... ELSE ... CLOSE
.fi
.fl /srce/usr/source/L/pop/demos/=>
.fl /srce/usr/source/L/pop/demos/and
.fl /srce/usr/source/L/pop/demos/cancel
.fl /srce/usr/source/L/pop/demos/close
.fl /srce/usr/source/L/pop/demos/else
.fl /srce/usr/source/L/pop/demos/elseif
.fl /srce/usr/source/L/pop/demos/end
.fl /srce/usr/source/L/pop/demos/exit
.fl /srce/usr/source/L/pop/demos/function
.fl /srce/usr/source/L/pop/demos/goto
.fl /srce/usr/source/L/pop/demos/if
.fl /srce/usr/source/L/pop/demos/lambda
.fl /srce/usr/source/L/pop/demos/while
.fl /srce/usr/source/L/pop/demos/macro
.fl /srce/usr/source/L/pop/demos/nonop
.fl /srce/usr/source/L/pop/demos/operation
.fl /srce/usr/source/L/pop/demos/or
.fl /srce/usr/source/L/pop/demos/return
.fl /srce/usr/source/L/pop/demos/then
.fl /srce/usr/source/L/pop/demos/unless
.fl /srce/usr/source/L/pop/demos/until
.fl /srce/usr/source/L/pop/demos/vars
