home *** CD-ROM | disk | FTP | other *** search
- Preface -- Statement of Policy
- Introduction
- Chapter 1. The Structure of REC
- Chapter 2. Operator Arguments and Data Structures
- Chapter 3. The Pushdown List
- Chapter 4. The Workspace
- Chapter 5. Variables, the Compiling Operator and the OS Interface
- Chapter 6. Operation of REC and User-supplied Extensions
- Appendix -- Summary of REC Operators and Predicates
- :
-
-
- PREFACE
-
- With dropping prices of microcomputers, programming is becoming
- accessible to more people, and software is assuming an increasing importance
- in the total balance of the operation of a computer. This has originated much
- controversy about an author's rights to his software, ranging from the idea
- that the world can be held to ransom for a brilliant idea to the suggestion
- that there should be no impediment to any copying whatsoever.
-
- The research reported in this document has been supported by public
- funds (Mexican, American, Swedish) in a number of institutions (Universities,
- Atomic Energy Commissions, Polytechnic Institutes) over a decade or two. Its
- result has especially been used in programming and applied mathematics
- courses in an attempt to get people to learn it and to use it. Accordingly it
- might be held to belong in the public domain.
-
-
-
-
-
- Most people read scientific literature, as well as any other
- literature, to establish a background. Should they encounter something
- particularly useful, they are expected to acknowledge its source, because the
- resulting fame more than anything is the author's compensation for his work.
- In those rare instances where a resounding commercial success has been the
- sole or a substantial consequence of the largely unaltered use of an author's
- work, it is to be expected that he, his associates, and his employer will
- expect to share in the benefits. It is curious that there does not seem to be
- a corresponding willingness to share in the consequences of a bungling or
- even bona fide misapplication of the work or the attendant catastrophe,
- should something go wrong.
-
- In short, although the authors have licensed REC and many REC
- programs (especially Convert) for free personal, non-commercial use, they
- retain copyright (duly registered at the Dirección General del Registro de
- Derechos de Autor in México) and will appreciate proper acknowledgment of
- source from users.
-
- Gainesville, Florida, U.S.A.
- Puebla, Puebla, Mexico.
- :
- Introduction
-
- REC (Regular Expression Compiler) is the end product of an effort
- begun many years ago at the University of Florida to find an aesthetic
- structure to take the place of the "program feature" in McCarthy's LISP.
- "Operator Predicates" were the solution evolved at that time. Later, when
- they were taken completely out of the context of LISP and implemented on a
- PDP-8 computer at the National Autonomous University of Mexico in 1966, the
- programming language REC arose.
-
- For more than a decade thereafter it was used in programming,
- numerical analysis and mathematical logic courses at the National Polytechnic
- Institute, also in Mexico City, acquiring a number of versions and giving
- many people considerable experience in its presentation and usage. REC
- compilers developed at the Polytechnic included versions suitable for matrix
- manipulations, text editing and numerical integration of second order
- differential equations; REC was also used there to program hand calculations
- on the Friden 132 desk calculator, one of the first machines to offer an
- operand stack. One version was used extensively in the administration and
- data processing of the Mexican Nuclear Energy Institute, in conjunction with
- the monitor system of the PDP-10.
-
- In the last five years, and with the advent of microcomputers, REC
- has matured at the Autonomous University of Puebla into a very powerful
- symbolic manipulation language with some arithmetic capabilities, which has
- proved to be very well suited to the construction of compilers and operating
- systems.
-
- REC possesses an extremely simple control structure consisting of
- four symbols: the two parentheses, the colon, and the semicolon. Besides
- these there may be any number of predicates and operators (these being a
- special case of predicates), which are responsible for all the work to be
- done. This represents an attempt to reduce computer programming to its
- barest essentials, both for pedagogical reasons, and in the expectation that
- it will be a manageable structure when it is cast in its simplest terms. The
- resulting language is very concise, not unlike APL or TECO.
-
- As the allusion to regular expressions implies, there is also the
- expectation that the language is intimately related to the theory of
- computations. In effect, REC derives its appeal from the fact that computers
- can be regarded reasonably well as Turing machines with very elaborate
- built-in shortcuts to eliminate the grotesque inefficiency of manipulating
- individual bits on a single linear tape. A Turing machine itself consists of
- a finite-state machine acting as the control of a tape memory; finite state
- machines in turn are conveniently described by regular expressions.
- The REC notation simply allows one to write regular expressions in a
- manner somewhat more amenable to programming the Turing machine which they
- control. If one does not wish to think so strictly in terms of Turing
- machines, REC expressions still provide a means of defining the flow of
- control in a program which is quite convenient for many applications.
-
- REC defines only a control structure. It takes some getting used to,
- but coincides well with contemporary ideas about "structured programming."
- Some particularly useful REC languages come into being when specific sets of
- operators and predicates are chosen. One selection gives the
- symbol-manipulation language REC/MARKOV. People who are familiar with DEC's
- PDP-10 will note a strong resemblance to TECO, although REC actually
- contemporizes with or even antedates TECO. One of the most important
- differences between these two languages is that TECO lacks REC's orderly
- control structure.
-
-
-
-
-
-
-
-
- The REC/MARKOV processor is remarkably compact, fitting into about
- 5Kbytes of memory in many machines (7.5Kbytes when floating point arithmetic
- operations are included), exclusive of working storage. In the course of these
- notes we shall analyze the operation of the microcomputer implementation of
- REC/MARKOV mentioned earlier; we shall call it simply REC throughout the
- remainder of the notes. Our principal objective will be to introduce a symbol
- manipulation programming language sufficiently powerful that it can handle
- the compilation of REC languages in a wide variety of different computers. At
- the same time one will have a language useful for text editing, assembly
- including macro assembly and cross assemblers, compiling, and even file
- maintenance and data analysis. To do all this will also entail some
- discussion of programming languages and computer architecture, but not to the
- extent that no previous familiarity with such things is needed.
-
- : Chapter 1. The Structure of REC
-
- To define formally a REC expression, let us use ten characters as
- metasymbols, that is, symbols which would not appear explicitly in an actual
- instance of the object being defined and whose significance as metasymbols is
- limited to the definition in which they are used. Let these characters be
- [, ], *, |, =, o, p, E, P and n. Establishing the convention that
- concatenation is implicit, alternatives are separated by the vertical bar,
- repetition --even zero times-- is denoted by an asterisk, square brackets are
- used for grouping and the equals sign means "is defined as", a REC expression
- E and a REC program P are defined recursively by
-
- E = ( [[o | p | P]*[: | ;]]* [o | p | P]* ) P = E | { [P n]* P }
-
- where the parentheses, colon, semicolon and braces, denote instances of them-
- selves, o denotes an operator, p denotes a predicate and n denotes a name for
- the program preceding it (any printing ASCII character other than the space,
- the atsign and the right brace). In other words, a REC expression is a string
- enclosed by balanced parentheses, which consists of a sequence of predicates
- or REC programs separated by punctuation consisting of one more colons or
- semicolons; a REC program is either a REC expression or an alternating list
- of programs and names, ending in a program and enclosed in braces.
-
- Operators and predicates carry out operations, not all of them
- necessarily primitive. They may be coded either in machine language or
- consist of subroutines themselves defined in REC. Predicates differ from
- operators by acquiring either of two truth values as a consequence of their
- operation; operators always have the value TRUE. The difference between
- operators and predicates makes itself felt in the way that predicates can
- affect the sequence of operations which is chosen to execute a program. Both
- REC expressions and programs acquire also a truth value as a result of their
- execution and thus are composite predicates.
-
- A REC expression is executed by reading it from left to right in
- sequence. Operators or predicates are performed in the order in which they
- occur, except that jumps occur after predicates if their truth value turns
- out to be FALSE. On encountering a right parenthesis, the expression
- terminates with the value FALSE, but if a semicolon is encountered,
- termination results with the value TRUE. Colons mean repetition from the
- opening left parenthesis. Finally we have to say what kinds of jumps are
- caused by predicates whose truth value is FALSE. If there is a colon or
- semicolon to the right of the predicate and on the same parenthesis level,
- the jump is to the next position beyond. If there is none, the jump is beyond
- the terminating right parenthesis, resulting in the value TRUE just as if a
- semicolon had been encountered.
-
- It should be mentioned that parentheses within parentheses are treated as a
- single expression, so that all jumps originating inside a given level of
- parentheses refer to locations only on the same level and never to locations
- within subexpressions.
-
- The rules for executing a REC program P are as follows: if P is an
- expression, it is executed as described in the preceding paragraphs. If P is
- a brace-enclosed list, the last program P (which is the main program of the
- list) is executed; this rule is applied recursively until an expression E
- (the program's main expression) is found.
-
- The following figure illustrates the flow of control in REC, assuming
- the only colons, semicolons and parentheses are those explicitly shown, and p
- is any predicate. Jumps from colons point leftwards; all other jumps point
- to the right. Jumps from predicates are taken only when they become FALSE.
-
- ┌─────────────────┬──────────────────────────┐
- │ ┌──────┐ │ ┌──────┐ │ ┌──────┐
- ( (p ) : ( p ; ) : ; )
- └──────┘ └────┘ └─────┘ └
-
-
-
- The structure which we have described allows Boolean combinations of
- predicates. Suppose that P, P1, and P2 are predicates. Then
-
- (P) is not-P, () is always FALSE,
- (P1; P2;) is (P1 or P2), (;) is always TRUE,
- (P1 P2;) is (P1 and P2).
-
- Some care has to be taken with the Boolean interpretation because the
- combinations which were described do not strictly follow the laws of Boolean
- algebra. The principal discrepancy is the failure of the commutative law,
- because the order in which the two predicates are executed might make a
- difference. One reason for the importance of the order might be that an
- irreversible operation is effected, such as initiating an input-output
- operation, or changing the value of a variable, or something similar. Another
- factor is the fact that algorithms are sometimes undefined, either because
- their arguments are inappropriate, or the attempt to follow them out would
- never terminate. By testing first for terminal conditions or for the
- suitability of data, the undefined conditions can be avoided.
-
-
-
-
-
- The structured programming constructs if-then-else, while-do and
- repeat-until are readily expressed in REC: let p be a condition (i.e., a
- predicate), and o, o1 and o2 operations (no matter how complicated). Then
-
- (p o1; o2;) is if p then o1 else o2
- (p o;) is while p do o
- (o p:;) is repeat o until p.
-
- The first expression can clearly be extended to cover the else-if construct:
-
- (p1 o1; p2 o2; p3 o3; o4;) is if p1 then o1
- else if p2 then o2
- else if p3 then o3
- else o4
-
-
-
-
-
-
-
-
-
- Subroutines are defined in REC by grouping them together with a main
- program within a pair of braces; any printing ASCII character other than the
- space, atsign (@) or right brace may be assigned as a subroutine name. In a
- subroutine group
-
- { P1 n1 P2 n2 ... Pk nk Pm }
-
- where P1, P2, ... Pk and Pm are REC programs as defined above, the characters
- denoted by n1, n2, ... nk are the names assigned to P1, P2, ... Pk, respective-
- ly, and Pm is the main program, where execution of the braced group starts.
- Since a program within braces also has a truth value (that of its main
- program), such a structure may also be given a name within an outer level of
- braces, or it may appear as a composite predicate within a REC expression.
-
- Subroutines are recursive and definitions that become active when entering a
- pair of braces replace definitions of the same name which were active in the
- previous level; on exit from a braced expression all of its definitions
- become inactive and any definitions which were replaced on entry become
- active again. Calls are effected by the predicate @x, which produces a call
- to subroutine x and whose truth value is that of the REC program named x.
-
-
-
- All of the above is illustrated in the following example, in which
- ellipses (...) are used to denote features not essential to our discussion
- and the numbers on the left are for reference only:
-
- [1] { { ( ... @A ... ) A
- [2] ( ... @C ... @D ... ) B
- [3] ( ... @A ... ) } C
- [4] ( ... ) A ( ... @A ... ) D
- [5] ( ... @A ...
- [6] {( ... ) A ( ... @A ... ) }
- [7] ... @C ... @A ... ) }
-
- Assume the only subroutine definitions are the ones shown explicitly
- in the example. The main program is defined in lines 5 through 7; its level
- of braces (which runs through the whole example) contains also definitions
- for subroutines C (lines 1-3), A (line 4) and D (line 4). @A in lines 5 and 7
- are calls to subroutine A of line 4, while @A in lines 1 and 3 refer to
- subroutine A defined in line 1. The call @A appearing in line 6 calls
- subroutine A of the same line. The subroutine A called by @A in D (line 4)
- depends on who the caller of D is: when B calls D, @A in D invokes subroutine
- A of line 1; when the main program calls D (line 8), @A in D refers to
- subroutine A of line 4.
-
- Due to the mechanism whereby upon entrance to a brace level previous
- definitions of the names defined in that level are saved and the new
- definitions become active (with reversal of the process on exit), it will be
- noticed that in our example the definition of subroutines D (line 4) and C
- (lines 1-3) remain active throughout the entire program while the definition
- of A depends on which pair of braces is currently executing. B is only
- defined within the brace pair defining C (lines 1-3) and reference to B from
- any of the programs defined in lines 4-7 would cause immediate termination of
- execution with an error message and return to the computer's operating system.
-
- Finally, both square brackets, the space and the comma have been
- reserved for readability and documentation purposes. Brackets are used to
- delimit comments; these may be nested, so that it is possible to inhibit
- compilation of a program or portion of a program containing comments by
- enclosing it with a pair of brackets. Comments may appear anywhere except
- between an expression defining a subroutine and its name and between the main
- program of a group and its closing right brace. No operations have been
- assigned to either the space or the comma, so they may be freely used to
- improve the readability of programs.
-
- : Chapter 2. Operator Arguments and Data Structures
-
- Insofar as REC is defined as a language exclusively in terms of its
- control structure, leaving the selection of operators and predicates to be
- chosen as best fits a given problem or application area, there can be
- differing versions of REC, such as one dedicated to arithmetic, or another to
- text editing, or even monitor systems whose primitive operations are fairly
- complicated file handling subroutines.
-
- However, there are still general aspects of operators, such as the
- way that they pass data to one another, or how they are formed into
- subroutines, which remain the same from one version of REC to another. No
- doubt it is desirable to establish norms and a vocabulary for these aspects
- of the language just as was done for the control structure. For example, the
- problem of data transmission can be considered.
-
- There are about three ways of passing information from one part of a
- program to another --- at least three that have found a noticeably popular
- acceptance. These are: by means of a calling sequence, by depositing the
- information in known locations, or by means of a pushdown list.
-
-
-
- Calling sequences are associated with subroutine usage; one might
- write
-
- CALL SUBROUTINE
- (data # 1)
- ( ... )
- (data # n)
- RETURN: ...
-
- Here, it is the program counter which localizes the area in which
- data is stored. From the point of view of writing a program, especially in
- assembly language, the registers following the subroutine call are a
- convenient place to locate data, the more so if the computer being used does
- not provide an automatic pushdown stack. This is particularly so if the data
- is constant from one subroutine call to another, but differs from one calling
- location to another.
-
-
-
-
-
-
-
- A second device for data transmission is to store information in a
- known location which is accessible to all the subroutines and to the main
- program. A typical example of this type of communication is through COMMON
- or labelled COMMON in FORTRAN programs. The method is particularly useful
- when the data is never changed or only infrequently modified. Even though
- this is its preferred use, it is not a real restriction because programs can
- always store data in COMMON just before a subroutine jump. Speed can be
- gained by thereby bypassing the way in which FORTRAN copies and restores the
- arguments in subroutine calling sequences. Nevertheless the use of fixed
- locations is most likely when the data is constant, or it is so widely used
- throughout the program that it would be redundant to incorporate it in a
- large number of calling sequences.
-
- The third technique of data communication is the use of a stack
- pointer which locates the head of a structure known as a pushdown list. This
- is the preferred method of handling temporary storage of the type which is
- required in such applications as the execution of algebraic formulas. It is
- nearly unavoidable whenever recursive programming is involved.
-
- The idea is to maintain a pointer to an array of temporary storage.
- As the arguments of a function or subroutine are evaluated they are deposited
- in the array and the pointer advanced to be ready for the next result.
-
- When all of the arguments are present, the calculations are made and the
- pointer moves backward, effectively erasing the arguments. Then the result of
- the calculation is left in the last position on the array, in place of the
- first argument if threre was one, and the process continues.
-
- Since each subroutine knows how many arguments it needs and how many
- values it is going to deposit, the maintenance of the pointer and the
- pushdown list is quite automatic. Errors can occur through setting up an
- incorrect number or arguments, and it is always possible, especially in a
- very deep recursion, that the pushdown list may grow beyond available space.
- Some checking should always be done to prevent the pointer from straying out
- of bounds.
-
- Primitive functions which have several arguments and which are coded
- in machine language can easily locate their arguments through a displacement
- relative to the stack pointer, but it is sometimes convenient to have a way
- of directing a component of a composite subroutine to the nth argument. A
- much more systematic way to make these arguments accessible is to give them
- names, and set aside a special storage area for them. This leads to the idea
- of a variable, even though its name may be nothing more than a serial number.
-
-
-
- Two activities concern the variables. First, its value has to be
- transferred to the pushdown list when it occurs in a program so that it will
- be available for use as an argument. Second, the value has to be transferred
- from the pushdown list to the special storage area so as to define the
- variable on entry into the subroutine.
-
- Two complications can occur, both aggravated when recursive
- subroutines are allowed. One is that the same names may be in use in various
- parts of the program, particularly when this happens both in the subroutine
- and in the main program which called it. Then it is necessary that previous
- values be set aside - not destroyed - when the subroutine is entered, and
- that they be replaced upon exit. Then all will work smoothly and the
- conflict in variable names will not be noticed.
-
- The other complication which can occur is the one of free variables,
- wherein we might not only want to refer to the kth argument of a subroutine,
- but as well to the mth argument of a higher level subroutine which called it.
- If no recursion is involved and one knows how many arguments each subroutine
- had, the position of any given argument on the pushdown list can be
- calculated; this is not possible when recursive subroutine chains are
- permitted.
-
-
- Rather, it is much more convenient to use the device of named
- variables and copies of the arguments rather than working with offsets from
- the stack pointer even though under restricted circumstances the latter is
- more economical.
-
- Some argumentation also surrounds the decision as to whether an
- operator ought to erase its own arguments, or whether the erasure ought to be
- done by a separate operator. The argument in favor of automatic erasure is
- that the pushdown list is then self-balancing, while the argument against
- stems from the possibility of the iterated use of an operator. In that case
- it would seem futile to keep loading and erasing the same argument over and
- over again.
-
- Finally we might want to get the nth argument directly off the
- pushdown list without having to fetch it up to the top. This would facilitate
- the definition of subroutines with an arbitrary number of arguments by
- allowing them to be used directly without the intermediate step of storing
- them as variables and fetching them out again later. However this direct
- access will not work if some part of the subroutine itself involved a
- recursive process, and thus direct access would not be usable in general.
-
-
-
- As a practical matter pushdown underflow and overflow have to be
- detected and acted upon --- probably resulting in a fatal error message.
-
- Even though the definition of techniques of argument communication
- does not form part of the official specification of REC, most varieties of
- REC will naturally require data handling capabilities. The current version
- of REC has
-
- - An array, together with a pointer and limit registers, which can
- be used as a pushdown list.
-
- - A space which can be used to store the values or addresses of
- variables.
-
- - A workspace into which text may be inserted and in which searches,
- deletions and substitutions may be carried out.
-
- Any other version of REC would be expected to have at least the first
- two data structures.
-
-
-
-
- In summary, the three data transference techniques and the error
- detection aspect affect current REC programming in the following way:
-
- - A double push down list is used systematically; "double" referring
- to the fact that both ends of the (finite) list are available for
- argument storage.
-
- - Constants are introduced into a program through a subroutine which
- expects to find the constant as part of its calling sequence.
- Parameters may also be introduced into a subroutine through a
- calling sequence, but otherwise calling sequences are not much
- used. More elaborate compilers may even set aside variable space
- rather than calling sequence space for constants, referring to the
- constants only through pointers.
-
- - Variables or registers which are of central importance to a program
- are set aside, and manipulated through special operators. This
- takes the form of a workspace for text manipulation and a set of
- locations in which values or pointers to values may be stored.
- Otherwise there is not much data communication through fixed
- program areas.
-
-
- - In order to conserve space, error detection and handling is kept to
- a minimum. Pushdown list, workspace and compile area overflows
- cause a message to be issued and immediate termination of
- execution. So does an attempt to read a source file or a memory
- buffer beyond its end during compilation (usually due to an excess
- of opening braces or parentheses). Other errors are noted in a
- location reserved for this purpose; the question mark '?' is the
- predicate the programmer may use to find out whether an error has
- occurred.
-
- ::REC3.HLP
- ::REC4.HLP
- ::REC5.HLP
- ::REC6.HLP
- : Appendix. List of REC Predicates and Operators
-
- This section gives an index to the REC predicates and operators, ordered by
- their ASCII codes. [O] [P] and [C] indicate the corresponding character is
- an operator, symbol or control flow character, respectively. The notation
- X/n under "Panel" means the description appears in panel n of section X in
- this help file; the notation X/Y/n:m means that the description appears in
- panels n through m (or simply n) of subsection Y of the sub-help file
- invoked by selecting section X of this help file's menu. A few items
- are described more than once.
-
- Character Short description Panel
-
- ! [O] Convert binary to ASCII hexadecimal. E/C/7
- "α" [O] Load string α on the PDL. Nests alternately with 'ß'. E/A/3:4
- # [O] Convert binary to decimal ASCII. E/B/12
- $ [O] Replace variable number by its table address. E/C/6, G/A/1
- % [O] Convert a number to the next shorter type. E/A/10, E/B/10
- & [O] Exchange the top two PDL arguments. E/B/12, E/C/2
- 'ß' [O] Load string ß on the PDL. Nests alternately with "α". E/A/3:4
- ( [C] Start a REC expression. C/1, C/3
- ) [C] End a REC expression. C/1, C/3
-
- * [O] Logical AND or arithmetic product. E/B/7:8
- + [O] Logical OR or arithmetic sum. E/B/7
- , [C] No operation, used as a separator. C/8
- - [O] Logical exclusive OR, subtraction or sign of constant. E/B/7
- . [O] Part of floating point constant to be loaded on the PDL. E/B/3:6
- / [O] Division. E/B/3
- 0 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 1 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 2 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 3 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 4 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 5 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 6 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 7 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 8 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- 9 [O] Part of numeric constant to be loaded on the PDL. E/A/3, E/B/3:6
- : [C] Repeat from start of expression. C/1, C/3
- ; [C] Take true exit from expression. C/1, C/3
- > [O] Restrict workspace. F/C/4
- = [P] Test string equality of top two PDL arguments. E/A/9
- > [O] Reopen workspace (after <). F/C/4
- ? [P] Test occurrence of an error. E/C/7
-
- @σ [P] Call subroutine σ; @@ gets name/address from PDL top. E/A/10:11
- A [P] Try moving WS pointer p1 forward one byte. F/B/4
- B [P] Try moving p1 backward one byte. F/B/4
- C [O] Compile a REC program/leave compilation area pointers. G/B/1:3
- D [O] Delete the WS substring delimited by p1 and p2. F/A/5
- E [P] Test equality of PDL top and WS substring at p1. F/B/1
- F [P] Search WS starting at p1 for string matching PDL top. F/A/4
- G [O] Load a string on the PDL given its address and length. E/C/3
- H [P] Try hexadecimal ASCII to binary conversion on PDL top. E/C/6:7
- I [O] Insert PDL top into the WS at p2. F/A/4
- J [O] Move p1 to the beginning of the current WS text. F/A/5
- K [O] Call operating system, leave return value(s) on PDL. G/C/1
- L [O] Lift (pop) the top of the PDL. E/A/5
- M [P] Test WS string for inclusion in lexicographic interval. F/B/2:3
- N [P] Test top two PDL arguments for numerical inequality. E/B/9
- O [P] Try decimal ASCII to binary conversion on PDL top. E/B/11
- P [O] Save string in buffer if it will fit, note length. E/C/5
- Q [O] Copy WS string between p1 and p2 to the PDL. F/A/4
- R [O] Read a byte from the console keyboard onto the PDL. E/A/8
- S [O] Store a string at the given address; pop both from the PDL. E/C/4
- T [O] Display PDL top on the console screen. E/A/8
- U [P] Search for PDL top from p2, delimit intervening string. F/B/1
-
- V [P] Search for PDL top from p2, delimit from original p1. F/B/2
- W [O] Print a string given its address and length on the PDL. E/D/1
- Xσ [O] Execute user-supplied operator σ. H/B/1
- Y [P] Move p1 and p2 according to PDL top. F/B/5
- Z [O] Move p2 to the end of the WS text. F/A/5
- [α] [C] A comment ignored by the compiler. Comments nest in REC. C/8
- \ [O] Convert a number to the next longer type. E/B/11
- ] [C] No operation; used only to balance left brackets. C/8
- ^ [O] Add one to PDL top. E/B/9
- _ [O] Return to operating system. G/C/1
- ` [P] Test console keyboard status. G/C/2
- a [P] Try delimiting string of given length, starting at p1. F/C/1
- b [P] Try delimiting string of given length, ending at p2. F/C/1
- c [O] Create a block of given length on PDL, leave address too. E/C/4
- d [P] Subtract one from top if nonzero; else pop and ret. false. E/B/10
- e [P] Try extending WS text from p3 by amount given on PDL top. F/C/2
- f [P] Replace WS string at p1 w/PDL top shorter than p2-p1. F/C/2
- g [O] Get a byte from the given address, both remain on the PDL. E/C/3
- h [O] Save/restore machine registers. E/C/8:9
- i [O] Input a byte from the given port. E/D/2
- j [O] Move p2 to p1 (delimit leftmost null substring). F/B/4
- k [O] Call operating system, no return values left on the PDL. G/C/1
-
- l [O] Put address of high PDL limit (current pz) on the PDL. E/C/2
- m [O] Move PDL top to high end of the PDL. E/A/5
- n [O] Retrieve last item sent by m to high PDL end. E/A/5
- o [O] Output byte to the given port. E/D/2
- p [O] Push address and length of the current top. E/C/2
- q [O] Push current WS p1 and p2-p1. F/B/4
- r [O] Replace address on the PDL by its (address-sized) contents. E/C/5
- s [O] Save string in a buffer if it will fit. E/C/5
- t [O] Display on the screen a string given address and length. E/D/1
- u [O] Address-incrementing byte fetch. E/C/3
- v [O] Address-updating string store. E/C/4
- w [O] Copy/exchange WS pointers. F/C/3
- xσ [P] Execute predicate σ (x@ defines table to be used). H/B/8:9
- y [O] Address-incrementing word fetch. E/C/3
- z [O] Move p1 to p2 (delimit rightmost null substring). F/B/4
- { [C] Start a subroutine group. C/1, C/6:7
- | [O] Concatenate top two PDL arguments. E/A/10
- } [C] Terminate a subroutine group. C/1, C/6:7
- ~ [O] Complement or negate PDL top. E/B/9
-
- :[REC.HLP]
-
-
- REC - A Regular Expression Compiler
-
-
- Gerardo Cisneros and Harold V. McIntosh
-
- Departamento de Aplicacion de Microcomputadoras
- Instituto de Ciencias
- Universidad Autonoma de Puebla
-
-
- Copyright (c) 1976, 1985, 1990
- Gerardo Cisneros
- H. V. McIntosh