This file details the syntax of the POP-11 language, in terms of a stream of items as produced by the itemiser. (It does not describe the lexical syntax for a character stream input to compilation, for which see REF ITEMISE, which describes the textual representation of numbers, words, strings, character constants, etc.) REF POPCOMPILE describes the POP11 compiler.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |compilation stream|
----------------------
--------------| statement sequence |------ <termin> ---------
----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|statement sequence|
-------------
------------------| statement |--------------------
| ------------- |
| |
|---<--- ; ---<---|
| |
|---<--- => ---<----
| |
----<-- ==> ---<----
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|statement|
-----------------------
--------------| expression sequence |---------------
-----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|expression sequence|
----------------->------------------
| |
| -------------- |
------------------| expression |--------------------
| -------------- |
| |
----<---- , ----<-----
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<< Expressions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<The word categories referred to by the |expression| diagram are:
|operator| : A word whose identprops are N (/= 0), where N is the
operator precedence.
|identifier| : Any word that is not syntax, syntax operator or
operator, i.e. whose identprops are not "syntax",
"syntax N" or N.
A |literal| is any POPLOG object except a word or <termin>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|expression|
------------------
|----------------------|empty expression|-------------------------|
| ------------------ |
---| |--
| ---------------------- |
|---------------------|non-empty expression|----------------------|
----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|empty expression|
-------------------------------->----------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |non-empty expression|
-----------
--|------------------------| literal |---------------------------|--
| ----------- |
| |
| -------------- |
|-----------------------| identifier |-------------------------|
| -------------- |
| |
| -------------- ------------- -------------- |
|------| expression |----| operator |----| expression |-------|
| -------------- ------------- -------------- |
| |
| ------------------------ |
|-------------------| syntax operator form |-------------------|
| ------------------------ |
| |
| --------------- |
|-----------------------| syntax form |------------------------|
---------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<< Syntax Operator Forms >>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
The generic form is:
|syntax operator form|
-------------- -------------------- ------------
------| expression |----| syntax operator |----| body |--------
-------------- -------------------- ------------
where |syntax operator| is a word whose identprops are "syntax N", N
being the operator precedence. |body| is dependent on the particular
syntax operator. Standard syntax operator forms follow.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ( [syntax -1] (Procedure Apply/Partial Apply or Parenthesised Statement Sequence)
This takes two forms, depending on whether the preceding
|expression| is empty or not. If empty, this is a parenthesised
|statement sequence| Otherwise, it is procedure application or
partial application:
|parenthesized statement sequence|
------------------ ----------------------
---|empty expression|-- ( ----------| statement sequence |----- ) ---
------------------ ----------------------
|procedure application or partial application|
-----------------------
-------| expression sequence |-------
---------------------- | ----------------------- |
--|non-empty expression|-- ( --| |- ) --
---------------------- | ----------------------- |
-- % --| expression sequence |-- % --
-----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
. [syntax 1]
(Postfix Procedure Call)
-------------- --------------
------| expression |---- . ----| expression |--------
-------------- --------------
The result of the second |expression| is applied after
evaluating the first |expression|.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-> [syntax 11]
->> [syntax 11]
(Assignment Arrows)
----- -> ----
-------------- | | --------------
----| expression |----| |----| expression |------
-------------- | | --------------
----- ->> ----
After evaluating the first |expression| (and duplicating its
result for "->>"), the second |expression| is compiled in update
mode.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
and [syntax 9]
or [syntax 10]
(Boolean Expressions)
----- and -----
-------------- | | --------------
----| expression |----| |----| expression |------
-------------- | | --------------
------ or -----
The second |expression| is not evaluated if the first is false
for "and" or true for "or".
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: [syntax -1]
:* [syntax -1]
(Labelled Expression)
The second form is available for use with non-local jumps.
-- : ---
-------------- | | --------------
------| identifier |----| |----| expression |--------
-------------- | | --------------
-- :* --
If the preceding |expression| is not an |identifier|, a mishap
results. No code is produced for the |identifier|, instead it
becomes a label for the second |expression|.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$- [syntax -1]
(Section pathname)
--------->----------
| |
| -------------- | --------------
------| identifier |--------- $- ----| identifier |--------
-------------- | -------------- |
| |
---------------<--------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=> [syntax 12]
==> [syntax 12]
(Print Arrows)
----- => ----
-------------- | |
----| expression |----| |----
-------------- | |
----- ==> ----
These are special syntax operators in the sense that after
producing the appropriate printing code they replace themselves
on -proglist- with ";", thus terminating the current |expression
sequence|.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<< Syntax Forms >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
The generic form is:
|syntax form|
------------------ ------------
------| syntax opener |----| body |--------
------------------ ------------
where |syntax opener| is a word whose identprops are "syntax", AND whose
value is a procedure. |body| is dependent on the particular syntax
opener. Standard syntax forms follow.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if [syntax] unless [syntax] (Conditionals)
---- if -----
| -------------- ------------------
|---| expression |--- then ---| statement seq. |----
| -------------- ------------------ |
-- unless --- |
|
--------------------------------<-------------------------------
|
| ---- elseif -----
| | | -------------- ------------------
|->-| |---| expression |--- then ---| statement seq. |--
| | | -------------- ------------------ |
| -- elseunless --- |
| |
|-------------------------------<-------------------------------------
|
| ------------------
|->- else ---| statement seq. |---
| ------------------ |
| |
|----------------<----------------
|
| ----- endif -----
| |
|---|
|
--- endunless ---
(The closing syntax word must match the opener.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
while [syntax]
until [syntax]
(Iteration)
- while --- - endwhile -
| -------------- ------------------ |
|---| expression |--- do ---| statement seq. |---|
| -------------- ------------------ |
- until --- - enduntil -
(The closing syntax word must match the opener.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
repeat [syntax]
-------------->--------------
| |
| -------------- | ------------------
- repeat ----| expression |-- times -----| statement seq. |- endrepeat-
-------------- ------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for [syntax]
-------- -------- --------
-------| expr |-- step --| expr |-- till --| expr |------------
| -------- -------- -------- |
| |
for -| |
| |
| -------------- |
---| identifier |---- |
-------------- | |
| |
---------<-------- |----
| | |
| -------- | |
| -- in -----| expr |------------------------------------| |
| | -------- | |
| | | |
| | -------- | |
| |- on -----| expr |------------------------------------| |
| | -------- | |
----| | |
| -------- -------- -------- | |
|- from ---| expr |--- by --| expr |--- to --| expr |--- |
| -------- | -------- | -------- |
| --------->-------| |
| | |
------------------>------------------- |
|
|
----------------------------<-----------------------------------
|
| ----------------------
--- do ---| statement sequence |---- endfor ----
----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
goto [syntax]
(Jump to Label)
--------------
---- goto ----| identifier |-----
--------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
go_on [syntax]
(Multi-way jump)
------------>------------
-------- -------------- | ------------- |
- go_on --| expr |--- to ----| identifier |------ else --| identifer |---
-------- | -------------- | -------------
----------<---------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
quitloop [syntax]
nextloop [syntax]
quitif [syntax]
quitunless [syntax]
nextif [syntax]
nextunless [syntax]
(Loop exits)
--- quitloop --- -----------
|--------------------------------- ( --| integer |-- )---
--- nextloop --- | | ----------- |
| | |
| ------------->----------
---- quitif ---- |
| |
-- quitunless -| ------------- |
|-- ( --| expression|-- ) --
---- nextif ---| -------------
|
-- nextunless --
If omitted, |integer| defaults to 1.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return [syntax]
(Return from procedure)
-----------------------
--- return -------- ( --| expression sequence |-- ) ------
| ----------------------- |
| |
-------------------->------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
returnif [syntax]
returnunless [syntax]
(Conditional return from procedure)
------- returnif ---- --------------
|--- ( --| expression |-- ) ------------
--- returnunless ---- ------------- |
|
|
-------------------------<------------------------------
|
|
| -----------------------
------- ( --| expression sequence | -- ) -------------------
-----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
" [syntax]
(Quoted Word)
--------
---- " -------------| word |------------- " ----
| -------- |
| |
| ----------------- |
|------| quoted string |-----|
| ----------------- |
| |
| -------------- |
--- ident ---| identifier |---
--------------
In the last case, |identifier| is any word/pathname for a permanent
identifier, and produces the word-identifier for that identifier.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ident [syntax]
(Push Identifier)
--------------
---- ident ---| identifier |----
--------------
where |identifier| is any word declared as an identifier, including
syntax and operators.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nonactive [syntax]
(Nonactive Value of Active Identifier)
--------------
---- nonactive ----| identifier |----
--------------
where |identifier| is any word declared as an active identifier.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nonop [syntax]
nonsyntax [syntax]
(Operator or Syntax Word as an ordinary Identifier)
----------------------------
---- nonop --------| operator/syntax operator |----
----------------------------
-------------------------------
---- nonsyntax ----| syntax word/syntax operator |----
-------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#| [syntax]
(Counted Statement Sequence)
----------------------
----- #| -----| statement sequence |----- |# -----
----------------------
The difference between the userstack length after and before
|statement seq| (i.e. after-before) is pushed onto the stack after
|statement seq|.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ [syntax]
{ [syntax]
cons_with [syntax]
(List and vector constructors)
-----------
----------| literal |-----------
| ----------- |
| ---------- |
--- [ --- |--- ^ ---| insert |-----------| --- ] ---
| | ---------- | |
--------| |----------
| | | ---------- | | |
--- { --- | |--- ^^ --| insert |-----------| | --- } ---
| | ---------- | |
| | | |
| | ------------ | |
| |--- % ---| expr seq |--- % ---| |
| | ------------ | |
| | | |
| | --------------- | |
| ---------| constructor |-------- |
| --------------- |
| |
---------------------<--------------------
In the above, |literal| is any POP object except the words "[", "{",
"^", "^^" or "%", and |constructor| is the whole diagram
recursively. |insert| is either a word, or an expression in
parentheses. The opening bracket must match the closing bracket.
For "cons_with", |vector constructor| is the {...} form of
|constructor|, and |expression| must yield a vector constructor
procedure:
-------------- ----------------------
--- cons_with ---| expression |---| vector constructor |---
-------------- ----------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lblock [syntax]
(Lexical Block)
------------------
--- lblock ---| statement seq. |--- endlblock ---
------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lvars [syntax]
dlvars [syntax]
lconstant [syntax]
vars [syntax]
constant [syntax]
iconstant [syntax]
(Identifier Declaration)
global [syntax]
nonglobal [syntax]
(Global/Nonglobal Permanent Identifier Declaration)
The above constructs and -dlocal- (below) have a similar format, and
both use the following diagrams:
|declaration list|
---------------<----------- , ---------------<----------
| |
| --------->--------- -------- |
| | | -----------| spec |----------- |
| | ------------- | | -------- | |
---------| attribute |------| |----- ; ---
------------- | -------- |
--- ( -----| spec |----- ) ---
| -------- |
| |
--<--- , --<--
|spec|
------------->--------------
| |
--------- | -------------- |
---| thing |----- = ---| expression |------
--------- --------------
Here |attribute| may only be omitted if a single |spec| follows; if
present, it applies either to the single |spec| following, or to all
the |spec|s following in parentheses. Each |spec| is a |thing|
optionally followed by an initialisation expression.
Using the above, identifier declarations are then simply
---- lvars ----
|
--- dlvars ---|
|
-- lconstant -|
| --------------------
---- vars ----|----| declaration list |---
| --------------------
-- constant --|
|
-- iconstant -|
|
|
-- global -- ---- vars ----|
--| |--| |
- nonglobal- --- constant --
where |thing| is an |identifier|, and |attribute| is an |identprops|
value.
Permissible values for the |identprops| are: a number N in the
range -12.7 <= N <= 12.7, one of the words "procedure", "macro" or
"syntax", or "syntax" followed by a number N (except that only 0 or
"procedure" are allowed for "lvars" and "dlvars" inside a
procedure). |identprops| defaults to 0 if omitted.
To declare an active |identifier|, |attribute| is
------------->------------ --------->--------
| | | |
| ---------------- | | ------------ |
--- active --- : --| multiplicity |--------|identprops|------
---------------- ------------
where |multiplicity| is an integer in the range 0 - 255, or defaults
to 1 if absent. A multiplicity other than 1 is allowed only if
|identprops| is 0 or omitted.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dlocal [syntax]
(Dynamic Localisation of Variables/Expressions)
Using the |declaration list| diagrams given in Identifier
Declarations above, this is just
--------------------
--- dlocal ----| declaration list |---
--------------------
but with the following |thing| and |attribute| values:
For a dynamic local variable, |thing| is an |identifier| (obviously
one for a variable, not a constant). In this case, |attribute| if
present has only only one permissible value, the word "nonactive"
(meaning that the non-active value of the |identifier| is to be
local).
For a dynamic local expression, |thing| has the form
-------------->------------
| |
-------------- | -------------- |
--- % ---| expression |----- , ---| expression |------ % ---
-------------- --------------
where the first |expression| is the access part, and the (optional)
second |expression| is the update part; if the second is omitted,
then the update part defaults to being the first |expression|
compiled in update mode.
|attribute| if present specifies the multiplicity of the
expression (i.e. how many values it produces), and must be an
integer in the range 0 - 255. If omitted, it defaults to 1.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
section [syntax]
----------------------------->-----------------------------
| |
| -------->-------- ----------->------------- |
| | | | | |
| -------- | ---------- | | ---------- | |
section---| name |-----| import |-------- => ----| export |---------;---
-------- | ---------- | | ---------- | |
-------<------- -------<------- |
|
|
---------------------------------<-----------------------------
|
| ----------------------
------| statement sequence |---- endsection --
----------------------
|import| and |export| are words. |name| is either a word or a
section pathname. If |name| is omitted (i.e. ";" follows immediately
after "section") then the top-level section -popsection- is used.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure [syntax]
define [syntax]
(Procedure Definition)
---------
-- define --| specs |---
--------- |
| ---------- ----------- --------
|---| inputs |---| outputs |---| with |--- ; ---
| ---------- ----------- -------- |
--- procedure ---------- |
|
|
------------------------------<-------------------------------
|
| ----- enddefine -----
| ---------------------- |
-----| statement sequence |----|
---------------------- |
----- endprocedure ---
|inputs| have two possible forms; conventionally, the second form
without parentheses or commas is used only for macro definitions:
----------------->--------------
| -------------- |
--- ( ------------| identifier |------------ ) ---
| -------------- |
----<---- , ----<-----
---------------->---------------
| -------------- |
---------------| identifier |-------------
| -------------- |
------------<-----------
|outputs| are always:
----------------->---------------------
| -------------- |
----------- -> ---| identifier |-----------
| -------------- |
----------------<--------------
and |with| is:
----------------->----------------------
| ---------- ----------- |
-----------| with_x |---| literal |-----------
| ---------- ----------- |
----------------<---------------
where |with_x| may be either "with_nargs" or "with_props", each
occurring at most once. For "with_nargs", |literal| must be an
integer; for "with_props" it may be any item, the word "false" being
interpreted specially as <false>.
In the "define" syntax form, |specs| are:
------->--------
| | --------------- --------------
----- updaterof --------| declaration |-----| identifier |---
--------------- --------------
where |declaration| declares the procedure name |identifier|, and
can be either
----------->---------
| |
----- dlocal -------- nonactive ----------
or
------->----- ----------->--------- ---------->---------
| | | --------------- | | -------------- |
----- global --------| declarator |--------| identprops |------
--------------- --------------
In the second form, |declarator| follows the same rules as for
Identifier Declarations, i.e. "lvars", "dlvars", "lconstant",
"vars", "constant", or "iconstant", but "vars" or "constant" only
when "global" is present. If |declarator| is omitted, the default
declaration made is controlled by the variable -popdefineconstant-.
|identprops| has the same values as for Identifier Declarations.
If omitted, it defaults to "procedure" if -popdefineprocedure- is
true, or 0 otherwise.
A special case for the "define" statement is when |identprops|
declares an ordinary operator. In this case, |identifier| is
amalgamated with the |inputs| which would normally follow it, and
together take the form
------->---------- --------->-------- -------->---------
| -------------- | | -------------- | | -------------- |
-----| identifier |-----| identifier |-----| identifier |-----
-------------- -------------- --------------
i.e. 1, 2 or 3 occurrences of |identifier|. The name being defined
is then the first |identifier| if 1 or 2 are present (nonary and
unary prefix forms), and the second if 3 are present (binary infix
form).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~