January 1977, October 2018
Stephen Fickas
R.D. Eager
Copyright © 1977, 2018 Stephen Fickas, R.D. Eager
Permission is granted to copy and/or modify this document for private use only. Machine readable versions must not be placed on public web sites or FTP sites, or otherwise made generally accessible in an electronic form. Instead, please provide a link to the original document on the official ML/I web site.
[ < ] | [ > ] | [Contents] | [Index] | [ ? ] |
Copyright © 1977, 2018 Stephen Fickas, R.D. Eager
Permission is granted to copy and/or modify this document for private use only. Machine readable versions must not be placed on public web sites or FTP sites, or otherwise made generally accessible in an electronic form. Instead, please provide a link to the original document on the official ML/I web site.
This document was originally written by Stephen Fickas. It has been rewritten in Texinfo, so that it can be published in both printed and machine readable form; this has necessitated some re-wording and re-ordering of the text. Some minor corrections and clarifications have also been made. The rewrite was carried out by Bob Eager.
The changes have been fairly minor, mainly to fit the document within the Texinfo conventions. Appendix C was added, documenting the subroutines and code sections in the L source. A contents list and index were also added. Reference is also made to ML/I character variables, which are not present in the L version, but are available in the C implementation.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These notes are a by-product of my efforts in providing in-line documentation to the L version of ML/I. The following sections are arranged in the most conducive way for understanding the documented L code. The notes are general in nature, and for specifics the in-line documentation should be consulted.
1.1 Reference material | ||
1.2 Strategy |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Some of the following material can be found on the ML/I website, at http://www.ml1.org.uk.
Three manuals/notes/listings should be obtained before attempting hand simulations of the documented L code:
If only the LOWL or undocumented L version of ML/I are available, then also obtain How ML/I Works, P. J. Brown, 1973. For readers that are more interested in an L mapping, the following material will be useful:
The above material is available to anyone who agrees that it will not be used in any type of commercial venture.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There is no belying the fact that the L code presents a complex system to be fully understood only after a number of simulated cases are tried. I have found the following procedure (not algorithm, for it does not necessarily halt) to be a good one in understanding the L code (• signifies newline):
<
as a primary name and >
as a secondary and closing delimiter.
SIMULATE(X<ABC>Y)
SIMULATE(X<A<BC>>Y)
M
, D
and T
options, repeat steps 1, 2
and 3 until the skip is fully understood.
MCDEF X AS Y
SIMULATE(A X B)
MCGO
in
MACNAMES
in the L data section.
SIMULATE(MCGO L1
•)
MCDEF
in
MACNAMES
in the L data section.
SIMULATE(MCDEF X Y AS %A1.
•)
MCINS
in
MACNAMES
in the L data section.
SIMULATE(X Q Y Z)
The subroutine SIMULATE is defined as:
SUBROUTINE SIMULATE (INSOURCE) Starting at MBEGIN, hand-simulate the L code, obtaining source input from the passed parameter INSOURCE. END SIMULATE
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
2.1 The stacks | ||
2.2 The hash table | ||
2.3 Variables |
The easiest way to understand the L implementation of ML/I is first to understand the underlying data structures. There are three basic data areas in ML/I:
The size of each area is at the individual implementer’s discretion. Each will be described below in more detail.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ML/I makes use of two stacks called FSTACK
(forwards stack)
and BSTACK
(backwards stack).
Given a contiguous section of
memory between M
and N
(M<N
), FSTACK
will grow towards N
and have its bottom at M
.
Likewise, BSTACK
will grow towards M
and have its bottom at N
. Currently, if they meet in the middle,
ML/I is aborted.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
See [2], section 6.2.3.
The hash table is made up of a number of pointers (LHV
being the number), four additional pointers and, finally, a
switch variable. There is also an additional
bottom neighbour pointer.
LHV
pointers.MDFIND
, which takes the current atom being scanned and
produces a number K
where 0 < K < LHV
,
the value of LHV
also being
up to the implementer. It is hoped that MDFIND
will
efficiently scatter K
within this range. As various
macros, inserts, etc. are defined, they will be added
to the appropriate chain headed by one of these pointers.
CKVALY
,
to turn off any local definitions when a MCNODEF
is called,
any local skips when a MCNOSKIP
is called, etc.
(see [1], section 5.2.5).
The initial value for all four is any number greater
than a possible pointer value.
MCWARNG
. Initially 7,
denoting no warning active, changed to 6 when MCWARNG
is
called.
NULLPT
for the earliest version), and in this way
the stacked hash tables are chained together.
Note
Although it was initially stated that only one
hash table exists, there now seems to be a proliferation of
hash tables. Actually, storage need be
allocated for only one hash table; in processing,
ML/I will stack and unstack various copies of this
original on BSTACK
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
See [2], section 3.1.
Each variable type can use an implementer defined number
of bits, words or bytes, depending on the mapping of the OF
function.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
3.1 Pointers | ||
3.2 Arrays of numbers | ||
3.3 Arrays of characters | ||
3.4 LID s | ||
3.5 The ERBLOC |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are two types of pointers used in ML/I; relative and
absolute. Relative pointers (actually, numbers) are used only
within the stacks and are defined relative to their location.
For example, if a block of 10 pointers are stacked on FSTACK
,
and we wish the last pointer to point relatively to the first,
we would set it to -9.
Absolute pointers correspond with the usual notion of a pointer, their value being the address of some memory location.
+-----+ | R | flags a relative pointer +-----+ | A | flags an absolute pointer +-----+
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Most blocks of numbers (i.e. permanent variables, system variables, etc.) have the following format:
+-----+ | . | +-----+ | . | | . | values | . | +-----+ | . | +-----+ pointer to block -----> | N | number of above values +-----+
where the values are stored in reverse order.
For example, P0
would be the cell above N
and PN-1
would be the top cell.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If character variables are implemented, they are stored as a fixed number
of character cells preceded by the actual number of cells used.
The fixed number is determined by the second argument to the first
call of MCCVAR
, and is stored in CVSIZE
.
The variables are stored in the following format:
+-----+ | . | etc. +-----+ | . | value2 +-----+ | . | value1 +-----+ pointer to block -----> | N | number of values +-----+
where the values are stored in reverse order. Each value looks like this:
+-----+ | . | | . | | . |M
cells, determined byMCCVAR
| . | | . | +-----+ | M | actual length of value +-----+
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
LID
sA LID
is a number N
followed by N
characters. One or
more LID
s can occur in sequence. If there is more than one,
they are separated by either a WITHMK
or a WTHSMK
.
As an example, XX WITH ;
would be represented as
+-------+ | 2 | +-------+ | X | +-------+ | X | +-------+ |WITHMK | +-------+ | 1 | +-------+ | ; | +-------+
Following are the definitions for various keywords:
SPACE
+-------+ | 1 | +-------+ | | character for space +-------+
SPACES
+-------+ | 1 | +-------+ | | character for space +-------+ |SPCSMK | +-------+
SPACES WITH
, SPACES WITHS
, SPACE WITHS
+-------+ | 1 | +-------+ | | character for space +-------+ |WTHSMK | +-------+
WITH SPACES
, WITHS SPACE
+-------+ |WTHSMK | +-------+ |SPCSMK | +-------+
WITHS SPACES
+-------+ |WTHSMK | +-------+ | 1 | +-------+ | | character for space +-------+ |SPCSMK | +-------+
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ERBLOC
There is a contiguous block of storage required for the
error block (ERBLOC
), which is used by the error routines.
This can be reserved on the top of FSTACK
, or else in variable storage.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
4.1 Primary construction | ||
4.2 Information blocks | ||
4.3 Secondary delimiters |
Perhaps the quintessential structure of ML/I is the construction.
Each time a MCDEF
(G
), MCWARN
(G
),
MCINS
(G
) or MCSKIP
(G
)
is processed by ML/I, a new construction is built. Constructions
exist also for each ML/I operation macro (e.g. MCDEF
), but not
necessarily on the stack. All local and global constructions
reside entirely on one of the two stacks. A construction or
structure representation is as shown in the following sections.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
+-----+
| . |
| . | Replacement text (see type 1 below)
| . |
+-----+
| A | Hash chain to next construction
+-----+
| R | OR-LINK to alternative name of same construction
+-----+
| . | One or more LIDs representing the name of the
| . | primary construction (more than one in the
| . | case of WITH
)
+-----+
| R | NEXT-LINK to next delimiter
+-----+
| | Construction type (0 through 4)
+-----+
| . |
| . | Information block (depends on type)
| . |
+-----+
The items above are, in more detail:
K
and thus belongs to an equivalence class defined
by MDFIND
.
OR-LINK
ENDCHN
, else used to link together alternative
names (i.e. primary constructions) for this construction.
Before studying the following example, it will probably
be necessary to review [1], section 5.1.3.
An example macro definition, and its corresponding representation, is:
MCDEF N1 OPT A N1 OR B ALL C AS D
+-----+ | D | +-----+ +---> | | --> Hash chainA
| +-----+ +-----+ | | | ---------------> | | --> Hash chainB
| +-----+ +-----+ | | 1 | | 00 | OR-LINK | +-----+ +-----+ | | A | | 1 | | +-----+ +-----+ +---- | -4 | NEXT-LINK | B | +-----+ +-----+ | 1 | | | --> Secondary delimiter forC
+-----+ +-----+ | -6 | <-- Info block | 1 | +-----+ +-----+ | -8 | | | +-----+ | | <-- Info block | 3 | | | +-----+ +-----+
ML/I will then recognise as a macro call:
B ..... C A B ..... C A A B ..... C
etc.
NEXT-LINK
This is normally a secondary delimiter, but in some cases may be another primary construction (see (b) above).
0 for STOP-MARKER 1 for MACRO 2 for WARNING-MARKER 3 for INSERT 4 for SKIP
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A substitution macro information block looks like this:
+-----+
| 2 | optional STRMK
+-----+
| R | --> negative offset to end + 1
+-----+
| R | --> negative offset to start
+-----+
| | number of temporary variables
+-----+
If the optional STRMK
is present, then this is a straight scan
macro (see [1], section 2.9).
The two negative offsets refer to the replacement text in the primary construction.
As an example, after ML/I had fully processed
MCDEF X AS Y
the following construction would appear on the hash
chain associated with X
:
+-----+
| Y | replacement text
+-----+
| | --> hash chain X
+-----+
| 00 | OR-LINK
+-----+
| 1 |
+-----+
| X |
+-----+
| 00 | NEXT-LINK
+-----+
| 1 |
+-----+
| -6 | Info block
+-----+
| -8 |
+-----+
| 3 |
+-----+
An operation macro information block looks like this:
+-----+ | . |LOCMK
(1) for local macros, elseOPMK
(2) +-----+ | . | Operation type (0-15) +-----+
+-----+ | . |PINSMK
(2) orUINSMK
(3) +-----+
PINSMK
for protected insert, UINSMK
for
unprotected insert (see [1], section 2.6.8).
+-----+ | . | flags (only least significant three bits used) +-----+
Bit 0 = 1 if matched skip (M
option) (least significant bit)
Bit 1 = 1 if text copy (T
option)
Bit 2 = 1 if delimiter copy (D
option)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
+-----+
| R | OR-LINK
+-----+
| . |
| . | LID
(s)
| . |
+-----+
| R | NEXT-LINK
+-----+
As can be seen, secondary delimiters have a similar but abbreviated format to the primary construction. They are used to hold delimiters which follow the primary name. As an example,
MCDEF MAIN1 SECDl SECD2 AS ...
would result in
+-----+ (MAIN1) +-----------> | 00 | +-----+ | +-----+ | . | | | 5 | | . | | +-----+ | . | | | S | +-----+ | +-----+ | |---+ NEXT-LINK | E | +-----+ +-----+ | . | | C | | . | +-----+ | . | | D | +-----+ +-----+ | 1 | +-----+ +-----+ | | ----> | 00 | +-----+ +-----+ | 5 | +-----+ | S | +-----+ | E | +-----+ | C | +-----+ | D | +-----+ | 2 | +-----+ | 00 | +-----+
The OR-LINK is used to chain together delimiters found in an option block. As an example:
MCDEF X OPT A OR B ALL C AS ...
would result in:
primary construction +-----+ forX
| 00 | | +-----+ V | 1 | +-----+ +-----+ | . | | B | +-----+ +-----+ | 1 | +- | . | +-----+ | +-----+ | A | | +-----+ V | . | --> secondary delimiter forC
+-----+
The NEXT-LINK can be:
ENDCHN
, signifying this is the last delimiter, or
EXCLMK
, signifying this is the last delimiter, and in
addition that this is an exclusive delimiter (see [1], section 3.5).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
FSTACK
The top pointer of FSTACK
is FFPT
, which points at the
first available cell (contrast with LFPT
). After finishing
the initialisation code at MBEGIN
, FSTACK
will be as follows:
+-----+ | . | | . | <-- predefined global macros (possibly empty) | . | +-----+ | . | <-- permanent variables | . | | . | <--P1
+-----+ | | <-- number of permanent variables +-----+ | . | | . | <--FSTACK
free space | . | +-----+
All global constructions are retained on the bottom of FSTACK
.
Since the ML/I macros defined in the MACNAMES
section are
global, they may be placed here. When the user calls upon
ML/I macros such as MCDEFG
or MCSKIPG
, they are
defining additional global constructs which must be included
on FSTACK
.
This is accomplished by inserting the new global construction
in between the current global constructions and the top of
the permanent variables (see MKROOM
routine), moving
everything down to make room.
If character variables are implemented, a single value of zero
is stacked on FSTACK
immediately after the number of permanent
variables; this signifies the number of character variables (initially none),
and CVARPT
is set to point to this.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
BSTACK
The top pointer of BSTACK
is LFPT
, which points at the
last used cell. After finishing the initialisation code at
MBEGIN
, BSTACK
looks as follows:
+-----+ | . | | . | <--BSTACK
free space | . | +-----+LFPT
--> | . | | . | <-- copy of hash table | . | +-----+ENDPT
--> | 00 | <-- hash table link +-----+
All local constructions are eventually placed on BSTACK
. Note
that this means a hash chain pointer to a global definition
will always be less than LFPT
. This fact is used in
differentiating between the two.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
7.1 Recognising the primary name | ||
7.2 Delimiter recognition | ||
7.3 Nested constructions |
Once the basic data structures of ML/I are understood, it is left to study the various ways ML/I manipulates these structures to produce the desired results. There are two basic actions which ML/I performs:
Since the second is a prerequisite to the first, it may be desirable to understand this section before moving on to the next, which deals with the evaluation of a recognised construction. Ignoring the STOP-MARKER, there are four types of construction:
All are evaluated in similar fashion, but the MACRO construction has been chosen to follow as an example, mainly because it is the most difficult of the four. Let us assume that the user has typed in:
MCDEF A B C AS D
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The section of code at BSNAME
is responsible for searching
the primary constructions, looking for a match on the current atom.
In our example, the current atom is MCDEF
, and a match will be
found with the primary construction set up in the MACNAMES
section.
Following is a diagram of the MCDEF
construction set up in the
MACNAMES
and DELS
sections. The $
sign is used
to represent a newline.
Readers may wish to review these two sections for their own verification.
+-----+
| | --> Hash chain for MCDEF
+-----+
| 00 | No alternative names
+-----+
| 5 |
+-----+
| M |
+-----+
| C |
+-----+
| D |
+-----+
| E |
+-----+
| F |
+-----+ +-----+ +-----+
| | ------> | | ---+--> | | ------> DSSAS ...
+-----+ +-----+ | +-----+
| 1 | | 4 | | | 2 |
+-----+ +-----+ | +-----+
| 1 | | V | | | A |
+-----+ +-----+ | +-----+
| 4 | | A | | | S |
+-----+ +-----+ | +-----+ +-----+
| R | | | | ------> | 00 |
+-----+ | +-----+ +-----+
| S | | | 1 |
+-----+ | +-----+
| | -->+ | $ |
+-----+ +-----+
| 00 |
+-----+
The TEBEST
routine will decipher this as a MACRO type construction,
and set the variable BESTPL
so as to jump at BSSWIT
accordingly
(i.e. to CALLO
).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
After the primary name has been matched, ML/I attempts to find
each of the secondary delimiters defined by the NEXT-LINK chain.
In our example, ML/I will continue reading in characters (i.e.
the first argument A B C
) until either a VARS
,
AS
, or SSAS
is matched.
When the AS
of our example is read, CMPARE
will match it and TEBEST
, after determining that it is a secondary
delimiter, will set BESTPL
so as to jump to DELLO
at BSSWIT
.
ML/I will determine that AS
is not the last or closing
delimiter, and so continue reading characters (i.e. the second
argument D
) until the next delimiter (newline) is matched,
again shifting control to DELLO
. ML/I notes that this is
the last delimiter, so searching is halted. One by-product
of the above actions is an argument vector, which is
constructed on BSTACK
.
Below is the status of the two stacks at this point; once again,
the $
sign is used to represent a newline.
+-----+
| | other FSTACK
info
+-----+
1 ---> | M |
+-----+
| C |
+-----+
| D |
+-----+ +-----+
| E | LFPT ---> | | ---> FFPT
+-----+ +-----+
| F | | A | ---> 5
+-----+ +-----+
2 ---> | | | A | ---> 4
+-----+ +-----+
| A | | A | ---> 3
+-----+ +-----+
| | | A | ---> 2
+-----+ +-----+
| B | | A | ---> 1
+-----+ +-----+
| | DBUGPT ---> | . |
+-----+ | . | Stacked SDB
| C | | . |
+-----+ +-----+
| | | . |
+-----+ | . | other BSTACK info
3 ---> | A | | . |
+-----+ +-----+
| S |
+-----+
4 ---> | |
+-----+
| D |
+-----+
5 ---> | $ |
+-----+
FFPT --> | |
+-----+
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If, while searching for the delimiters by the procedure described above, a nested construction call is found, then note the following actions:
MCDEF A C AS Z
had been previously typed.
While searching for the AS
in
our current example, ML/I would have discovered the
nested call on A
.
The action of ML/I in this case
would then be:
AS
,
A
in the same fashion
described earlier in this section, i.e. find all delimiters, and
AS
.
Note that at this stage
A B C
is not replaced by Z
, but is merely scanned
over so that the search for AS
can be resumed.
It should be clear from the above description why it is not allowed to use macros in place of delimiters in the hope that they will be evaluated and reduced to the desired delimiter. As an example, suppose we are given the following definitions:
MCDEF Q AS B MCDEF A B AS . . .
then we might expect the call
A ... Q
to be correctly matched. We know that it will not, for even
though Q
will be recognised as a macro, it will not be
evaluated (i.e. replaced by B
), and so ML/I will vainly
search for the closing delimiter B
.
The next section will describe the actions of ML/I after construction evaluation.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
8.1 Evaluating arguments – the STKARG routine | ||
8.2 Building a construction | ||
8.3 Link-up |
This section deals with the actions taken by ML/I once a
construction has been recognised. When an example is called
for, we will carry on with the example started in Recognition,
i.e. MCDEF A B C AS D
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
STKARG
routineIn Recognition, ML/I skipped over any nested constructions
found while searching for delimiters. Before evaluation can
proceed on MCDEF
, each argument must be evaluated
to catch any nested calls.
The STKARG
routine is used by ML/I for this
purpose, evaluating a specific argument.
When STKARG
is called,
ARGN0
contains the argument number to be evaluated.
STKARG
then finds where the argument starts and ends in
FSTACK
, and jumps back to the construction recognition loop
to scan the argument.
Basically, we are back to Recognition, trying to recognise a primary
construction. We can see then that STKARG
is a recursive routine, for if any constructions are recognised
in an argument, they in turn will eventually lead to another call on
STKARG
, potentially ad infinitum.
The following diagram shows the call MCDEF A B C AS D
before
link-up.
+-----+ | . | | . | original source text | . | +-----+ | D | evaluated form of argument 2 +-----+ | A | | | | B | evaluated form of argument 1 | | (no longer needed) | C | +-----+ | 00 | Hash chain forA
+-----+ | 00 | OR-LINK +-----+ | 1 | +-----+ +--- | A | | +-----+ | | 5 | NEXT-LINK | +-----+ | | 1 | | +-----+ | | -6 | <-- Info block | +-----+ | | -8 | | +-----+ | | 3 | | +-----+ +--> | 00 | OR-LINK for secondary delimiterB
+-----+ | 1 | +-----+ | B | +-----+ +--- | 1 | NEXT-LINK | +-----+ +--> | 00 | OR-LINK for secondary delimiterC
+-----+ | 1 | +-----+ | C | +-----+ | 00 | +-----+ | . | | . |FSTACK
free space | . | +-----+
When control does return from STKARG
(LINK-BACK
) for the final time, we are guaranteed that all
nested calls have been evaluated, and FSTACK
will be as follows:
+-----+
| . |
| . | globals, permanent variables,
| . | etc.
| . |
+-----+
| . |
| . | original source text
| . | (e.g. MCDEF A B C AS D
)
| . |
+-----+
| . |
| . | possible other information
SPT --> | . |
+-----+
| . | evaluated argument N
| . |
| . |
+-----+
STOPPT --> | . |
| . | free space
| . |
+-----+
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Depending on the construction type (i.e. MCSET
,
MCDEF
, user macro, etc.), prescribed actions are carried
out on the evaluated arguments.
To show what these actions are in the
MCDEF
case, we will carry on with the example started in
Recognition.
After finding the closing delimiter, ML/I
will transfer control to DEF
, the MCDEF
handler.
There are two arguments to worry about: the replacement text D
and the structure representation A B C
.
The strategy ML/I will use is:
FSTACK
FSTACK
FSTACK
using results from a. and b.
The result can be seen in Evaluating arguments – STKARG
.
If arguments 1 or
2 had contained any nested calls, their evaluated forms would
have reflected the results of these calls. In our example,
since no nested calls were involved, the call to STKARG
was almost nothing more than a straight copy from the original
source text to the evaluated form, (almost, because leading
and trailing spaces are deleted).
In arriving at the diagram in
Evaluating arguments – STKARG
,
we have glossed over a large
amount of ML/I processing in the EVTREE
section,
and in the GETDEL
routine.
These sections of code deal with the sticky details
of parsing a structure, and will need to be worked through by
hand to appreciate their function.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The final step of ML/I is to link the newly built construction
into the appropriate hash chain, in our case
MDFIND(A)
.
Preliminary to this link-up, ML/I will move the
construction up adjacent to the replacement text, overwriting
evaluated argument 1 which is no longer needed. Since our
construction is a local one (MCDEF
instead of MCDEFG
),
it will be moved to the top of BSTACK
.
Next, the correct hash chain will be found and ML/I will insert the
new construction at the head of the chain.
BSTACK
will be as follows:
+-----+ | D | +-----+ +--> | | ---> previous head of chain | +-----+ | | . | | | . | rest of construction | | . | | +-----+ | | . | | | . | otherBSTACK
info | | . | | +-----+ | | . | | | . | most current hash table | | . | | +-----+ +--- | | entry forMDFIND(A)
+-----+ | . | | . | | . | +-----+ | . | | . | rest ofBSTACK
| . | +-----+
This concludes ML/I processing of MCDEF A B C AS D
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following summarises the uses of important variables in the MI-logic of ML/I. Note that line numbers may vary slightly, depending on the exact version of the L code available.
Variable | Declared | Meaning |
in line | ||
ALLPT | 61 | head of chain of nextlinks to be attached to delimiter following ALL |
ARGCT | 13 | in SDB |
ARGLEN | 49 | length of value of current argument |
ARGNO | 24 | in SDB |
ARGPT | 19 | in SDB |
BESLIN | 123 | best-so-far value of LINECT |
BESPT | 96 | best-so-far value of SPT |
BESTPL | 120 | switch value used in basic scan routine |
BFNDPT | 87 | best-so-far value of FNDPT |
BINDIC | 111 | best-so-far value of INDIC |
BINFPT | 89 | best-so-far value of INFOPT |
CALTYP | 124 | first number in information block |
CHANPT | 94 | used in CHAIN FROM operation |
CHLINK | 116 | used in CHAIN FROM operation |
CINFPT | 103 | points at information block in primary construction |
CLLFPT | 101 | points to top entry after scanning information is stacked |
CONSW | 150 | for syntax checking (see EVTREE and GETDEL ) |
COPDSW | 131 | for skips. Reflects setting of delimiter option. |
COPTSW | 130 | for skips. Reflects setting of text option. |
CVARPT | 72 | points at character variables |
CVNUM | 74 | number of character variables |
DBUGPT | 20 | in SDB |
DBUGSW | 25 | in SDB |
DELCT | 145 | count of delimiters |
DELPT | 104 | head of chain of delimiters being searched for |
ENDPT | 71 | points at end of BSTACK |
ERIAPT | 95 | points at value of operation macro argument |
ETEMPT | 84 | points at error block (temporary storage for EDB ) |
EXIDPT | 140 | temporary storage for IDPT |
EXITSW | 151 | for syntax checking (see EVTREE ) |
FFPT | 90 | points to first free location on FSTACK |
FLAGPT | 158 | points at flag |
FNDPT | 86 | points at LID when a name is found |
GHSHPT | 845 | points at global hash table |
GLBWSW | 705 | value 6 if there is a global warning; value 7 otherwise |
HASHPT | 30 | in SDB |
HTABPT | 97 | points at current hash table |
IDLEN | 119 | length of current identifier |
IDPT | 98 | points at current identifier |
INDIC | 115 | contents of nextlink |
INFFPT | 34 | in SDB |
INFOPT | 88 | points beyond currently matched LID |
INSW | 132 | to set DBUGSW , and as implied parameter to SETPTS |
INVOCT | 113 | count of macro calls |
KEYSW | 149 | for syntax checking (see EVTREE and GETDEL ) |
KNPT | 83 | temporary storage |
LABPT | 33 | in SDB |
LEVEL | 112 | level of macros and inserts |
LFPT | 73 | points at top of BSTACK (last used location) |
LINECT | 23 | in SDB |
LINKPT | 48 | link for STKARG |
LNODPT | 139 | points at topmost node entry on BSTACK |
MASKSW | 129 | mask used to indicate which types of construction are recognised |
MCHLIN | 22 | in SDB |
MEVAL | 122 | miscellaneous. Used for numerical values calculated at macro time |
MHSHPT | 46 | value of HASHPT when macro was called |
MTCHPT | 31 | in SDB |
MTYPE | 175 | type of items to be printed |
NARGPT | 102 | points at argument vector + 1 |
NDEFPT | 143 | destination of newly defined construction |
NEGVAL | 162 | indicates if result is to be negative |
NESTLV | 109 | nesting level of calls and skips during scanning |
NNODPT | 138 | points at current node entry on BSTACK |
NODEPT | 137 | head of chain of links to be attached to next delimiter |
NODESW | 148 | for syntax checking (EVTREE and GETDEL ) |
NTYPSW | 53 | type of construction being defined |
OFFSET | 121 | offset in hash table |
OHSW | 37 | in SDB |
OLDSPT | 142 | previous value of SPT |
OLIDPT | 157 | temporary storage for IDPT |
OLLFPT | 141 | previous value of LFPT |
OP1 | 160 | LHS operand |
OPLEV | 110 | level of operation macros and inserts |
OPSW | 164 | “operation expected” switch (see GETEXP ) |
OPTHPT | 663 | head of orlink chain |
OPTLEV | 146 | level of OPT-ALL brackets |
OPTPT | 62 | last entry on orlink chain |
OPTYP | 50 | type, e.g. global, local, insert. Also other uses |
PARNM | 117 | formal parameter of type number |
PARPT | 91 | formal parameter of type pointer |
PARSW | 128 | formal parameter of type switch |
PRSTPT | 172 | start of current hash table (see PRCTXT ) |
PRTAPT | 173 | counts down hash table (see PRCTXT ) |
PRTBPT | 174 | follows down hash chains (see PRCTXT ) |
PVARPT | 72 | points at permanent variables |
PVNUM | 74 | number of permanent variables |
SKIPLV | 108 | level of skip nesting |
SKLIN | 36 | in SDB |
SKVAL | 35 | in SDB |
SPT | 21 | in SDB |
SQNUM | 51 | safe variable, miscellaneous uses |
SQPT | 47 | safe variable, miscellaneous uses |
SQSW | 52 | safe variable, miscellaneous uses |
STAKPT | 18 | in SDB |
STFFPT | 100 | points at start of global macros |
STOPPT | 32 | in SDB |
SUM | 161 | running total |
TEMAPT | 93 | temporary pointer |
TEMP | 114 | temporary number |
TEMPSW | 127 | temporary switch |
TEMAPT | 92 | temporary pointer |
TEMPT | 92 | temporary pointer |
TIDPT | 99 | temporary storage for IDPT |
TLINCT | 125 | temporary storage for LINECT |
TOPSPT | 45 | points at latest OPDB on BSTACK |
TSPT | 100 | temporary storage for SPT |
TVARPT | 29 | in SDB |
TYPE | 118 | type of construction name |
VARPT | 156 | points at vector of variables |
VARSW | 165 | “variable expected” switch (see GETEXP ) |
WNIDPT | 106 | temporary storage for IDPT |
WNSPT | 105 | temporary storage for SPT |
WSW | 166 | written argument or delimiter |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SDB
This Appendix describes the uses of the variables declared in the
Scanning Description Block (SDB
), and their values in each
of the main scanning states.
If this table looks messy in HTML, try making the window smaller.
Name of variable | 1. Scanning source text | 2. Scanning replacement text | 3. Scanning argument or delimiter | 4. Evaluating operation macro or first insert |
---|
ARGCT | counts number of arguments when nested construction is scanned | not used |
STAKPT | NULLPT | points at latest SDB on stack .............................. |
ARGPT | NULLPT | points at argument vector | containing text value | calling value |
DBUGPT | not used | points at orlink preceding macro name | points at argument vector in which argument or delimiter is included | points at argument vector |
MCHLIN | set to current value of LINECT when a nested construction is encountered | not used |
LINECT | line count of current text ........................................ | not used |
ARGNO | not used | not used | number of argument or delimiter | number of argument currently being processed |
DBUGSW | 0 | 1 | 2 for operation macro argument 4 for substitution macro argument 6 for delimiter | 5 |
HASHPT | points at local hash table | U insert: calling valueP insert: containing text value | calling value |
TVARPT | NULLPT | points at temporary variables | containing text value | calling value |
MTCHPT | when a nested construction is encountered, this is set to point at the orlink of this construction | used as workspace |
SPT | points at last scanned character .............................. | used in scanning values of arguments |
STOPPT | NULLPT | points one beyond last character of current text | points one beyond end of latest argument |
LABPT | NULLPT | head of chain of labels .......... | not used |
INFFPT | points at start of source text on FSTACK | not used | for operation macro argument: 4; otherwise undefined | value of FFPT when operation macro was called |
SKVAL | if not scanning call or insert, then number of designated label
for forward MCGO , zero if none in progress.
If scanning call or insert, then (-1 - (above value)) | not used |
OHSW | true if a new hash table has been stacked for this level; false otherwise | not used |
SKLIN | if in forward MCGO , then line number in which MCGO
occurred | not used |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following lists all of the sections, subroutines and other important areas of code in the L source.
Name | Section | Type | Declared |
in line | |||
ADVNCE | MAINSUBS | Subroutine | 383 |
BUMPFF | MAINSUBS | Subroutine | 395 |
CHATOM | MAINSUBS | Subroutine | 406 |
CHEKID | MAINSUBS | Subroutine | 418 |
CKVALY | MAINSUBS | Subroutine | 430 |
CMPARE | MAINSUBS | Subroutine | 442 |
CORECT | MAINSUBS | Subroutine | 460 |
DECALV | MAINSUBS | Subroutine | 471 |
DECLF | MAINSUBS | Subroutine | 484 |
DEFSUBS | Section | 1448 | |
ENCALL | MAINSUBS | Subroutine | 495 |
ENVPR | Section | 2116 | |
ER1TST | MAINSUBS | Subroutine | 511 |
ERMTST | ERR | Subroutine | 1773 |
ERR | Section | 1712 | |
ERSIC | ERR | Subroutine | 1743 |
ERSNW | ERR | Subroutine | 1759 |
ERTEST | DEFSUBS | Subroutine | 1450 |
GARGCH | MAINSUBS | Subroutine | 523 |
GETDEL | DEFSUBS | Subroutine | 1460 |
GETEXP | MAINSUBS | Subroutine | 535 |
GMEADD | MAINSUBS | Subroutine | 584 |
GSATOM | MAINSUBS | Subroutine | 610 |
GSRATM | DEFSUBS | Subroutine | 1610 |
GTATOM | MAINSUBS | Subroutine | 626 |
INVALS | Section | 8 | |
JOINCH | DEFSUBS | Subroutine | 1622 |
KEYSRC | DEFSUBS | Subroutine | 1639 |
LUDEL | MAINSUBS | Subroutine | 652 |
LULAYK | MAINSUBS | Subroutine | 665 |
MAIN | Section | 26 | |
MAINSUBS | Section | 380 | |
MCALTERMAC | OPMACS | Code for | 1024 |
MCDEFMAC | OPMACS | Code for | 1238 |
MCGOMAC | OPMACS | Code for | 1056 |
MCINSMAC | OPMACS | Code for | 1260 |
MCLENGMAC | OPMACS | Code for | 1135 |
MCNO--- | OPMACS | Code for | 1216 |
MCNOTEMAC | OPMACS | Code for | 1148 |
MCPVARMAC | OPMACS | Code for | 1161 |
MCSETMAC | OPMACS | Code for | 1175 |
MCSKIPMAC | OPMACS | Code for | 1277 |
MCSUBMAC | OPMACS | Code for | 1191 |
MCWARNMAC | OPMACS | Code for | 1230 |
MKROOM | MAINSUBS | Subroutine | 688 |
OPEXIT | MAINSUBS | Subroutine | 726 |
OPMACS | Section | 1022 | |
PLNODE | DEFSUBS | Subroutine | 1652 |
PRARG | MAINSUBS | Subroutine | 737 |
PRCTXT | ERR | Subroutine | 1834 |
PRENV | ENVPR | Subroutine | 2118 |
PRERR | ERR | Subroutine | 1913 |
PRID | ERR | Subroutine | 1923 |
PRLID | ERR | Subroutine | 1965 |
PRLINO | ERR | Subroutine | 1982 |
PRMISS | ERR | Subroutine | 1993 |
PRNAME | ERR | Subroutine | 2027 |
PRNFND | ERR | Subroutine | 2041 |
PRNUM | ERR | Subroutine | 2053 |
PRSCAN | MAINSUBS | Subroutine | 761 |
PRTABL | ENVPR | Subroutine | 2137 |
PRTYPE | ERR | Subroutine | 2065 |
PRVIZ | ERR | Subroutine | 2086 |
RESSP | MAINSUBS | Subroutine | 774 |
SBSTPL | MAINSUBS | Subroutine | 796 |
SETPTS | MAINSUBS | Subroutine | 808 |
SETYPE | ERR | Subroutine | 2100 |
SKLAB | MAINSUBS | Subroutine | 821 |
SMSKSW | MAINSUBS | Subroutine | 837 |
SNODCH | DEFSUBS | Subroutine | 1682 |
SUBCHK | MAINSUBS | Subroutine | 847 |
TEBEST | MAINSUBS | Subroutine | 884 |
TESDEL | MAINSUBS | Subroutine | 867 |
TESPAC | DEFSUBS | Subroutine | 1697 |
TEWITH | MAINSUBS | Subroutine | 948 |
UNOPDB | MAINSUBS | Subroutine | 959 |
UNSDB | MAINSUBS | Subroutine | 974 |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jump to: | A B C D E F G H I L M N O P R S T U W |
---|
Jump to: | A B C D E F G H I L M N O P R S T U W |
---|
[Top] | [Contents] | [Index] | [ ? ] |
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on October 1, 2018 using texi2html 5.0.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ Up ] | Up | Up section | 1.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on October 1, 2018 using texi2html 5.0.