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).~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~