home *** CD-ROM | disk | FTP | other *** search
- Introduction.
- Patterns.
- Subroutine Groups.
- Conditional Skeletons.
- Iterative Skeletons.
- The "Same" Skeleton <=>.
- The (REC/.../) pattern and skeleton.
- Memory buffer operations.
- Disk system and return to CP/M functions.
- Arithmetic Skeletons.
- Character "Arithmetic".
- Overlays.
- Loading of .COM binary files.
- Priority Queues (Heaps).
- Error messages.
- :Introduction.
-
- This Help file describes advanced CNVRT features as well as additions and
- changes made to the compiler after CNVPRG.HLP was prepared. Among the most
- noteworthy changes the following may be mentioned:
-
- - Full functionality for pattern definitions and the Boolean
- combinations OR and AND.
-
- - Generalization of skeletons if, nf, while and until.
-
- - Generalization of pattern <[n]>.
-
- - Inclusion of evaluation of general arithmetic expressions whose
- operands are constants (including floating point).
-
- - Acceptance of any functional skeleton as a pattern.
-
- :Patterns
-
- References to defined patterns and the Boolean OR now perform as expected, so
- that programs such as the following give results consistent with the formal
- definition of Convert:
-
- (( ((OR,[<:e:>],<(><:e:><)>,[<0>],<(><0><)>)) e
- )()(0)(
- ((^Z),);
- (<:e:><0>,(%t, yes)(%R)):
- (,(%t, no)(%R)):
- ))
- [end]
-
- This programs answers "yes" if it finds the same string inside and to the
- right of a nest of possibly alternated parentheses and brackets and types "no"
- otherwise. For example, ([[([(ab)])]])ab produces "yes", (b)c gives "no".
-
- Making this program work requires that pattern <:e:> "know" what follows it
- at the place where it is referenced; this issue has been resolved, so that if
- pattern <0> in the second rule fails, the next alternative in the OR is tried
- out.
- -
- The effect on compiled programs, of having defined patterns check the patterns
- that follow references to them (in the example, that "e" take into account <0>
- in the concatenation <:e:><0>) is an object file requiring up to about 20%
- more space, so that CONVERT.REC allows selection of the type of treatment
- desired in the compilation of defined pattern references by a flag appended
- to the source file name in the command line tail; if no flag appears or is /s
- or /S, the code produced is simpler but less general. A slash followed by
- anything other than an s or S indicates full treatment should be given. For
- example, if the above example is placed in a file TEST.CNV, when compiling it
- with the command line
-
- REC80 CONVERT TEST/L
-
- the program obtained would recognize the string [([ab])][ab], whereas the line
-
- REC80 CONVERT TEST
-
- would result in a program in which <:e:><0> would not match that string
- (although it would match some simpler strings such as [([ab])]ab).
-
- The default is the shorter compilation because most applications to date have
- only used simple pattern definitions not requiring the general treatment.
- -
- The other question now resolved is that of AND. Consider a concatenation
- (AND,p1,...,pn)p, in which it could happen that there is more than one way in
- which the concatenation of p1 and p may match the text and that it may not be
- necessarily the first alternative (the one that would have p1 matching the
- shortest possible text) that for which p2, ..., pn match the same text as p1.
- In this case, one requires that if pi fails (i>1), a different way to match p1
- and p to the text be sought. This is necessary even if p is the null pattern,
- for consider the following patterns:
-
- (AND,<0>;,<1>ab;)
-
- (and,<0>;,<1>ab;)
-
- The first one matches any text containing the substring "ab;"; the second
- matches only if no semicolon precedes the first occurrence of "ab;" because <0>
- will match the shortest substring left of a semicolon; for instance, the first
- pattern maches x;y;ab;z, whereas the second does not. Notice however that
- (and,<1>ab;,<0>;) has the same effect as the AND shown above, illustrating the
- convenience of always analyzing the possibility of expressing the desired
- pattern in terms of (and,...) and (or,...), which produce less code and are
- less time-consuming.
-
- -
- The length pattern <[n]> admits in place of n any skeleton. The pattern will
- fail to match if the skeleton doesn't evaluate to a string of ASCII decimal
- digits, or if the skeleton does evaluate to such a string but there aren't
- that many characters in the text under scrutiny. Some posibilities now
- allowed by this pattern are:
-
- <[128]> A constant skeleton: its original definition.
- <[<0>]> A variable, which should be already bound to a
- string of ASCII digits.
- <[(&!,<0>)]> The length of the value of a variable.
- <[(#f,2*<0>+1)]> Twice the value of a variable, plus one
- (the value of the variable here could be
- a string of ASCII digits or an arithmetic
- expression whose operands are integer
- constants).
-
- Assuming <0> is bound to the two-digit string "32", the second pattern will
- match a 32-byte string, the third pattern will match a 2-byte string and the
- last pattern will match a string of 65 characters. If the value of <0> is
- abc, the second and fourth patterns will fail, while the third one will match
- a 3-byte string.
-
- -
- Any functional, conditional or iterative skeleton may appear wherever a
- pattern is allowed. A skeleton such as (a,<0>:k), (%R), (if,<0>,(^Z),<1>)
- or (until,(%R),(^Z),<=>,(%R),), when appearing on the pattern side of a rule
- or within a defined pattern, will have the same effect as if a constant
- pattern equal to the value of the skeleton were present in its place.
- Variables used within such skeletons must have been previously bound.
-
- :Subroutine Groups.
- Since CNVRT inherits REC's features as regards the grouping of subroutines,
- groups of defined patterns, defined skeletons and whole programs may be built.
-
- The following example shows a defined pattern group:
-
- { ((IVL,0,9)) d (<:d:>(ITR,<:d:>)) i ((or,+,-,)<:i:>) I
- ((or,<:i:>.<:i:>,.<:i:>,<:i:>.)) r
- ((or,<:i:>E<:I:>,<:r:>(or,E<:I:>,))) R
- (<:@:>) } K
-
- Notice that the main routine of the group must consist only of <:@:>. In this
- example, d matches a decimal digit, i a decimal integer, I an optionally
- signed integer, r a decimal number with explicit point and R a general real
- constant in the fashion of FORTRAN. External references to these patterns
- are accomplished by writing <:Kd:>, <:Ki:>, <:KI:>, <:Kr:>, and <:KR:>,
- respectively. A reference to the main routine by itself (e.g., <:K:>) is
- meaningless and therefore not to be used, and references from within the group
- to definitions in the same group need not have the group name, as illustrated
- in the example. If no external access is desired to d, i, I or r, R could be
- the main program (removing the last line and placing the right brace before
- the R); in this case the only valid external reference would be <:R:>.
- -
- The next example shows a defined skeleton group:
-
- { ((%V,MEM:ll,<=>)) G
- ((%V,MEM:sy,<=>)) Y
- ((@)) } F
-
- The main routine of the group must consist only of a reference to the
- "skeleton" @. Outside references to G and Y may take any of the following
- forms: (FG,s), (FG), (FY,s) or (FY), where s is a skeleton whose value will
- be passed as an argument to the corresponding skeleton in group F. (FG) and
- (FY) deliver a null argument to G and Y, respectively. As with patterns,
- groups may be defined in which the main program is not (@), in which case
- outside access would only be allowed to the main program of the group.
-
- Finally, program groups may also be formed:
-
- { (()()()()) a (()()()()) b (()()()()) } A
-
- In this case, subroutines a and b are not directly available from outside
- the braces, but can only be called mutually and recursively, from the main
- program (A) and from any subroutine called from within this same group.
-
- :Conditional skeletons.
-
- Four conditional skeletons are provided: IF, NF, if and nf. IF and NF require
- a variable list to be given, if and nf do not. Their general forms are the
- following:
-
- (IF,(v),s0{,pj,sjt,sj}[,pF,sFt])
- (if,s0{,pj,sjt,sj}[,pF,sFt])
- (NF,(v),s0{,pj,sjt,sj}[,pF,sFt])
- (nf,s0{,pj,sjt,sj}[,pF,sFt])
-
- where v is list of variables (zero or more integers between 0 and 30 with one
- space between each pair of variables), the s's are skeletons and the p's are
- patterns; braces indicate 0 or more instances of the enclosed list and
- brackets indicate 0 or 1 instances of their contents. In IF and NF, the (v)
- list creates new instances of the listed variables after s0 has been evaluated;
- these instances persist during the execution of the IF or NF and disappear
- upon termination. Otherwise, IF and NF execute like if and nf, respectively.
-
- The next panels describe the operation of if and nf; we repeat
- the form of the corresponding skeleton for ease of reference.
-
- -
- (if,s0{,pj,sjt,sj}[,pF,sFt])
-
- Skeleton s0 is evaluated and matched to the first pattern, p1. If they match,
- s1t is evaluated and its value becomes the value of the entire skeleton; if
- the match fails s1 is evaluated and matched to p2. This continues until a
- match obtains between some sk and p(k+1), in which case the result is s(k+1)t,
- or there are no more comparisons to be made, in which case the last skeleton
- evaluated for a comparison is left as the result. In particular, if pF and
- sFt appear and pF does not match the last sk, the value of if is that of sk.
- The conditional skeleton
-
- (if,(%R),(^Z),<=>(%t,End of file encountered),(%T,<=>))
-
- reads a line from the default file; if it finds and end-of-file marker
- (control-Z), it leaves it but types the message "End of file encountered"
- (the value of %t is the null string); otherwise, it leaves the line read by
- (%R) after typing it.
-
- The use of more than one triple [,p,st,s] allows constructs of the "elseif"
- type within a single (if,...).
-
-
- -
- (nf,s0{,pj,sjt,sj}[,pF,sFt])
-
- NF and nf are the negative forms of IF and if, repectively; that is, if s0
- does NOT match p1, s1t is substituted, else if s1 does not match p2, s2t is
- substituted, etc. If each sk matches p(k+1), (k=0,...,n and pF=p(n+1)), sn
- is left as the result (This includes the case in which pF and sFt are present.)
-
- Alternatively, "nf" may be read as "unless": Unless s0 matches p1, s1t is
- evaluated and delivered as the result, else unless s1 matches p2, s2t is
- given as the result, etc.
-
- A useful example follows:
-
- (nf,(%Or),Not Found,(a,(%R)))
-
- This skeleton will call function a, with argument equal to the first line of
- the default file only if it is possible to open the default file for reading.
- Variants of this example include giving arguments to the %Or and %R
- functions. Notice that if the value of (%Or) is "Not Found", this string
- will be left as the value of the nf skeleton since no skeleton follows sFt.
-
- :Iterative skeletons.
-
- Four iterative skeletons are provided: WHILE, UNTIL, while and until. WHILE
- and UNTIL require a variable list to be given, while and until do not. Their
- general forms are the following:
-
- (WHILE,(v),sI{,pk,sk,skr}[,sf])
- (while,sI{,pk,sk,skr}[,sf])
- (UNTIL,(v),sI{,pk,sk,skr}[,sf])
- (until,sI{,pk,sk,skr}[,sf])
-
- where v is list of variables (zero or more integers between 0 and 30 with one
- space between each pair of variables), each s represents a skeleton and each p
- represents a pattern; braces denote 0 or more instances of their contents and
- brackets indicate 0 or 1 instance of the enclosed item. In WHILE and UNTIL,
- the list v generates new instances of the indicated variables after the initial
- skeleton sI is evaluated; these instances persist during the execution of the
- iterative skeleton and disappear upon termination. Otherwise, WHILE and UNTIL
- perform as while and until, respectively.
-
- The next panels describe the operation of while and until; we repeat
- the form of the skeleton for ease of reference.
- -
- (while,sI{,pk,sk,skr}[,sf])
-
- 1. The initial skeleton sI is evaluated.
-
- 2. If the first pk matches the text, sk is evaluated and put aside and
- a new text to match with pk is given by the repetition skeleton skr. This
- step is repeated until pk no longer matches the text presented to it.
-
- 3. The last text skr from step 2 (or sI if pk did not match on the very
- first try) is used as initial text to match with the next pattern (if any) and
- a similar iteration as that of step 2 occurs on the next triple pk,sk,skr.
-
- 4. Similar iterations are performed for each triple pk,sk,pkr; when the
- last pattern pn fails to match its text, its last residue pnr is left on the
- workspace, unless the optional final skeleton sf is present, in which case
- it replaces the text which last failed to match. The text produced by
- "while" will thus be a concatenation of 0 or more instances of s1, s2, ...
- sn and either of the last of snr or sf; the number of instances of each sk
- will depend on how many iterations of each triple took place.
-
- "Until" performs in a similar manner, except that iteration occurs as long as
- the pattern does NOT match. Examples follow in the next panel.
- -
- The following WHILE reads the default file, leaving on the workspace its
- contents up to but not including the end-of-file marker.
-
- (WHILE,(0),(%R),(and,<[128]>,(NOT,<-->(^Z))),<=>,(%R),<<
- >><=>,<0>(^Z),<0>,)
-
- The symbol <=> is the "same" skeleton, whose value is the text used in the
- last matching attempt (regardless of the outcome); this skeleton is described
- in the next section of this file.
-
- The first triple in the above example leaves on the workspace, one by one,
- all full disk sectors of the file which do not contain ^Z. The iteration
- ends when either no more sectors remain in the file or a sector is read which
- contains a control-Z. The last text (which is either a null string or a sector
- containing a ^Z) is given to the next triple, in which the pattern is <0>(^Z);
- if there is a ^Z, <0> will match the text in the sector up to but not including
- the ^Z. A null string is given as the repeat text (the skeleton skr in the
- second triple), which will not match <0>(^Z), so the last action of the WHILE
- will be to "append" this null text to the right of the contents of the
- workspace.
-
- An example of until follows.
- -
- (until,0,13,(,(%Ow,MEM:<=>)),(#p,<=>),)
-
- This skeleton creates 13 memory buffers, named MEM:0 through MEM:12. After
- each comparison, the value of <=> is the text used in the comparison; since
- #p increments by one its argument if it is a number, the value of <=> will
- succesively be 0, 1, 2,... up to 12; when #p increments 12 to 13 the pattern
- matches and the iteration ends.
-
- The skeleton which would close these buffers and release the memory associated
- with them would be the following:
-
- (until,12,-1,(%C,MEM:<=>),(#m,<=>),)
-
- #m decrements its argument by one; notice that closing is performed in the
- order opposite to the one followed when opening: since memory buffers
- are assigned space on the pushdown list, space must be released in order
- opposite to that of arrival.
-
- The final value of the skeletons in both examples is the null string.
-
- :The "Same" Skeleton <=>.
-
- The skeleton <=> may be used wherever a pattern match has taken place, and in
- skeletons appearing in the list of skeleton definitions. It may not appear
- in skeletons used as patterns embedded in pattern definitions. In particular,
- <=> may appear anywhere in the skeleton part of a rule and in any skeleton
- within a conditional or iterative skeleton. Its value is the entirety of the
- text used in the latest comparison, except when appearing within a skeleton
- definition, in which case its value is the text passed as argument to such a
- skeleton.
-
- For example, if the skeleton definition list contains the definition
-
- ((%W,<8>.<9>,<=>(^MJ))) W
-
- and a skeleton (W,abc) is executed at some point, its effect will be to write
- five bytes (a, b, c, CR and LF) into the file whose name and extension are
- given by variables 8 and 9.
-
- :The (REC/.../) pattern and skeleton.
-
- The (REC/.../) pattern and skeleton allows REC code to be inserted directly
- at the point where it appears. The inserted code is that delimited by "/";
- any character may be used as a delimiter as long as it is not contained in
- the code to be inserted. As a pattern, it can make certain searches faster
- than if they are left to the normal Convert mechanisms; as a skeleton it can
- help to produce more compact code.
-
- The use of this feature requires a thorough knowledge of REC and of the
- translation from Convert to REC. Examples of its use may be found in
- RECONVERT.CNV, a Convert compiler for Convert.
-
- :Memory buffer operations.
-
- Open operations on MEM:-type pseudo files may have an additional argument
- whose value should be a string of decimal digits indicating the size in bytes
- of the buffer desired. This number is effective only at the time the buffer
- is actually created; it is ignored if the buffer already exists. If omitted
- at the time of the initial opening, 1024 is assumed.
-
- Associated with a memory buffer pseudofile there are two pointers: a read
- pointer and a write pointer. When the buffer is first created, both pointers
- reflect an empty buffer. Write operations start writing into a buffer at the
- location indicated by the write pointer, update the pointer to the next
- available location when done and remove the written argument from the
- workspace, however, if the argument doesn't fit in what's left of the buffer,
- nothing is written, the argument remains in the workspace and the write
- pointer remains unaltered. Read operations will transfer to the workspace
- that portion of the text starting at the read pointer and matching the pattern
- (implicit or explicit) associated with %R. If the pattern does not match the
- text between the pointers, this whole text is returned with a ^Z appended to
- it (which is deleted if %R contains an explicit pattern) and the read pointer
- moves up to the write pointer. When there is a match, the read pointer
- advances to the byte following the portion of text which matched.
- -
- When a read is attempted on a MEM: pseudo file in which both read and write
- pointers have the same value (either because the buffer is empty or it has
- been read out entirely), a single ^Z or the null string is returned, depending
- on whether the implicit pattern or an explicit one is used, respectively. In
- any case, the final text returned by %R from a memory buffer will depend on the
- presence or absence of the optional skeletons which %R may include.
-
- Open operations may be performed on an open buffer, with the following effects:
-
- (%Or,MEM:...) moves the read pointer to the beginning of the
- buffer, thus making available all of its contents.
-
- (%Ow,MEM:...) moves both pointers to the beginning of the buffer,
- effectively leaving it empty.
-
- Both open operations on a MEM: pseudofile return the address of the buffer as
- a four-digit ASCII hexadecimal number; this is provided for use with the %B
- direct BIOS call available with CP/M-86. For most purposes, %O skeletons
- involving MEM: buffers should be nested inside the null function (,...) which
- erases its argument from the workspace.
-
- :Disk system and return to CP/M functions.
-
- (%Lr) returns a single letter (A, B, ...) corresponding to the
- identifier of the currently logged-in disk.
-
- (%Lw,x) logs in the disk specified by the first letter of skeleton
- x; if x is omitted or is null, A is assumed.
-
- (%M) returns to CP/M after closing all files.
-
- :Arithmetic Skeletons.
-
- Arithmetic skeletons have the form
-
- (#x,s)
-
- where x may be a string of one or more of the arithmetic functions and s is
- the argument to which the functions given by x are applied. In the listing
- of arithmetic functions which follows, the term "constant" means a string of
- ASCII characters representing an integer when the program is run with REC80
- or REC86, or an integer, long integer, single precision real or double
- precision real when the program is run with REC80F or REC86F. Convert inherits
- REC8xF's default of promoting smaller-sized arguments to the size and type of
- the larger argument in operations involving arguments of different sizes.
-
- f evaluates a formula. Its argument must be an arithmetic
- expression in which the operands are constants. Parentheses
- are allowed (and must be balanced if present); the operators
- recognized are ** or ^ for raising to a power, * for product
- / for division, % for remainder, + for addition or unary
- plus and - for subtraction or unary minus. If the argument is
- not an expression it is left unchanged.
- -
- The usual rules for operator precedence and association are
- followed: ** or ^ precede *, / and %, all of which precede +
- and -. Unary +'s are removed and unary -'s are replaced by
- 0-. *, /, %, + and - associate from left to right and **
- or ^ associate from right to left. Thus, (#f,2^3^2) yields
- 512, (#f,(QUO\(2^3)^2\)) yields 64, (#f,2/4*6) gives 0 and
- (#f,6*2/4) gives 3. Exponents must be of integer type; a
- floating point exponent is truncated and causes the message
- "Xpterr" to be displayed.
-
- + Takes an argument of the form a+b, where a and b are
- constants and returns their sum. The argument is unchanged
- if it doesn't have the required form.
-
- - Takes an argument of the form a-b, where a and b are
- constants and returns the indicated difference. No change
- is made in the argument if its form isn't a-b.
-
- * Returns the product if the argument has the form a*b, with
- a and b constant; otherwise the original argument remains.
-
-
- -
- / Returns the quotient given an argument a/b in which a and
- b are constants; no change is effected if the argument
- does not have the specified form.
-
- ^ Given an argument of the form a^b, where a is any constant
- and b is an integer, returns a raised to the power b. The
- argument is returned intact if it does not have the indicated
- form.
-
- % Returns the remainder of the division a/b if the argument
- has the form a%b; otherwise the argument is left unchanged.
- If either operand is a floating point number, the result
- returned will be a-(b*int(a/b)), where int(x) is the
- integer part of x. [e.g., int(3.5)=3; int(-4.8)=-4.]
-
- | If its argument has the form a|b, where a and b are integer
- constants, it returns the greatest common divisor of the
- pair. No change occurs if the argument lacks the prescribed
- form and no check is made to ensure that a and b are
- integers; results are unpredictable in the latter case.
- | may not be used as an operator in arithmetic expressions
- to be evaluated by f.
- -
- p Accepts a single constant as argument and returns that
- constant plus one, in a string of the same numeric type
- as the original argument. It will not alter its argument
- if it isn't a constant.
-
- m If its argument is a constant, it returns that constant minus
- one, in a string of the same type; otherwise it leaves its
- argument unchanged.
-
- =
- > These three skeletons take arguments in either of two
- < forms: a single number or two numbers separated by a comma.
- In the case of a single number, say a, they return the
- letter t if a=0, a>0 or a<0, respectively, and the letter f
- otherwise. In the two-argument case of the form "a,b", t
- is returned if a=b, a>b or a<b, respectively, and f if the
- relation doesn't hold. In this case, if a and b are two-byte
- integers they are compared as unsigned operands, since
- two-byte integers are more often used in address
- calculations. Arguments not having either of the allowed
- forms are left unchanged.
-
- -
- l Requires a single constant as argument; it converts it to
- a string of the following larger numeric type. For instance,
- (#l,-1) yields 065535, (#l,010000000) yields 1.E7 and
- (#l,3.14159) gives 3.14159D0. Double precision constants and
- non-numeric arguments remain unchanged, a null string as
- argument returns the digit 0.
-
- s Converts a single constant argument to next smaller numeric
- type before rendering it back to ASCII. Thus
- (#s,3.141592653589D0) returns 3.14159265, (#s,-45.98) returns
- -045, (#s,0100000) leaves 34464 (because of truncation modulo
- 2**16) and (#s,2000) leaves 208 (because of truncation modulo
- 256). Non-numeric arguments remain unchanged; a null string
- returns the digit 0.
-
- D Leaves the binary form of a numeric constant in its place;
- this will take the form of 2, 4, 5 or 8 bytes arranged in
- Intel form (least significant byte first); the lengths
- correspond to short integers, long integers, single precision
- reals and double precision reals, respectively. D is more
- often used together with h to produce the ASCII hexadecimal
- representation of a number.
- -
- No change takes place if the argument is non-numeric.
- Examples: (#Dh,1.5) produces 3FC0000000
- (#Dh,-1) produces FFFF
- (#Dh,01000000) produces 000F4240
-
- H Leaves the binary form of a string of ASCII hexadecimal
- digits (0-9, A-F). Given a string of n bytes, it produces
- a string of flr((n+1)/2) bytes, where flr(x) is the greatest
- integer not exceeding x. H is often used together with d
- to convert from ASCII hexadecimal to ASCII decimal. No
- change is effected if the argument contains characters other
- than hex digits. Examples:
- (#H,414243) gives CBA (when interpreted as ASCII)
- (#Hd,3FC0000000) gives 1.5
- (#Hd,F) gives 15
-
- d Assumes its argument is the binary representation of a number
- and converts it to an ASCII decimal string. If the argument
- length is not 0, 1, 2, 4, 5 or 8 no change takes place.
- Examples: (#d,(^MJ)) yields 2573 (10*256+13, due to Intel
- ordering of bytes in binary operands being assumed);
- (#Hd,FFFE) yields 65534.
- -
- h Assumes its argument to be binary and converts it to a string
- of ASCII hex. An n-byte argument produces a 2n-byte result.
- Examples: (#Dh,1.) produces 3F80000000; (#h,jkl) produces
- 6C6B6A (because Intel ordering of binary operands is assumed)
-
- As mentioned near the beginning of this section, in a skeleton of the form
- (#x,s), x may be a string. When x consists of more than one character, each
- of the represented functions is applied to the argument from left to right;
- thus in (#Hd,FFFF), H is applied first to FFFF and d is then applied to the
- result left by H (the two byte binary representation of 65535).
-
- As mentioned in CNVRT.HLP, a program using function #f and requiring handling
- of floating point constnats must have the pair #. in an [Include ..] comment;
- furthermore, if functions #^ and #% are not invoked explicitly but operators
- ** or ^ and % are to appear in formulas for #f, the pairs #^ and #% must be
- present in the "Include". [Include #.#^#%] would serve in a program which
- only uses #f explicitly but is intended for computation of formulas involving
- floating point numbers and exponentiation and remainder operations.
-
- :Character "Arithmetic".
-
- Character arithmetic skeletons have the form
-
- (&x,s)
-
- where x may be a string of one or more of the character arithmetic functions
- and s is the argument to which the functions given by x are applied. When
- x consists of two or more characters, the function represented by each
- character is applied in turn from left to right, the first one to the
- original argument and the rest to the result left by the preceding function
- For instance, (&D!,1.5) applies D to the string 1.5 and ! to the resulting
- string.
-
- Functions available for character arithmetic are the following:
-
- D Converts a string of one or more decimal integer ASCII
- numbers optionally preceded by minus signs and separated by
- commas or other nondecimal characters into binary, a pair
- of bytes for each integer. Examples: (&D,2573<,>-1) yields
- 4 consecutive bytes whose hex values are 0D, 0A, FF and FF;
- (&D,ab) yields 6 zero bytes: a and b delimit 3 null strings.
- -
- H Converts a string of one or more hexadecimal ASCII numbers
- into binary (modulo 2**16), a pair of bytes for each number.
- For instance, (&H,F) yields two bytes whose values are, in
- hex, 0F and 00; (&H,ABCDEf0123) produces 4 bytes whose
- values expressed in hex are DE, BC, 23 and 01, in that order.
- The inversion of high and low order bytes is due to the
- Intel convention for binary data storage. Notice also that
- lowercase f is not considered a hex digit.
-
- d Converts a string by pairs of bytes into ASCII decimal
- strings separated by commas; if the argument has an odd
- number of bytes the rightmost byte is converted assuming
- a zero high order byte. Examples:
- (#d,(^MJZ)) produces the string 2573,26
- (#Hd,FFFE) produces the string -2
-
- h Converts a string by pairs of bytes into strings of 4 ASCII
- hexadecimal digits separated by commas; the rightmost byte
- of a string of odd length gets converted to two hex digits.
- Examples:
- (#h,(^ABMJZ)) produces the string 0201,0A0D,1A
- (#Dh,32767) produces the string 7FFF
- -
- u Shifts all lowercase letters (a-z) in its argument to
- uppercase, e.g., (&u,Hello) yields HELLO.
-
- l Shifts all uppercase letters (A-Z) in its argument to
- lowercase, e.g., (&u,What IS it?) results in what is it?
-
- a Turns off the sign bit of each byte in its argument.
- For instance (&Dah,-1) results in the string 7F7F.
-
- s Turns on the sign bit of each byte in its argument.
- For instance (&sh,(^MJZ)) gives 8A8D,9A
-
- p Substitutes a period for each byte in its argument whose
- value is not a printable ASCII character (i.e., SP to ~)
- Example: (&p,abc(^MJ)de) results in abc..de
-
- n Converts each byte in its argument into two ASCII hexadecimal
- digits. For example (&n,ABCDEF) produces 414243444546.
-
- b Inverts the effect of n: converts pairs of ASCII hex digits
- into bytes of the corresponding binary value. Results are
- unpredictable for odd-numbered arguments or non-hex digits.
- -
- i Converts a string of bytes into 3-digit ASCII octal numbers
- (one for each byte) separated by commas; a null argument
- produces 000. Example:
- (&i,Zz) produces 132,172
-
- I Converts a string of ASCII octal numbers separated by commas
- to binary, a byte for each ASCII number. For example,
- (&I,116<,>117<,>77) yields the 3-byte ASCII string NO?
-
- 8 Converts a string of bytes into 8-bit ASCII binary numbers
- (one for each byte) separated by commas; an isolated null
- string produces 00000000. Example:
- (&8,Zz) produces 01011010,01111010
-
- B Converts a string of ASCII binary numbers separated by commas
- to binary, a byte to each ASCII number; a single null string
- produces a single zero byte. For example,
- (&Bh,01011010<,>01111010) yields 7A5A.
-
- = Yields the letter f if its argument is the null string or at
- least one of its bytes is non-null; leaves the letter t if
- all of the argument's bytes are binary 0.
- -
- > Yields the letter f if its argument is the null string or if
- the sign bit of its rightmost byte is on; t if this byte's
- sign bit is off.
-
- < Yields the letter f if its argument is the null string or if
- the sign bit of the rightmost byte is off; the letter t is
- returned if the rightmost byte's sign bit is on.
-
- ! Returns the length of its argument as an ASCII decimal
- number. For example, (&!,What<,> me worry?) returns 15.
-
- # Returns the hash function of its argument as an ASCII decimal
- number, always between 0 and 12. The hash function is
- defined here as the remainder modulo 13 of the exclusive or
- of all the bytes in the argument.
-
-
- :Overlays.
-
- Overlays are an extremely useful feature which allow the running of programs
- whose overall size is much larger than REC's compilation area. Overlays may
- be used when a program can be divided into three or more segments such that
- two or more of them are not needed simultaneously in memory.
-
- For instance, suppose program A calls subroutines B and C, but neither B
- calls C nor C calls B. Then program A could constitute a root program which
- loads B or C when either of them is required. Thus B and C share the same
- memory area and the memory requirements for the entire program are smaller
- by the length of the smaller of B and C than the requirements for the
- non-overlaid A-B-C combination. An overlay may load other overlays, and this
- way a very large program may be organized in a tree-like structure of
- overlays. Since each overlay is a REC program compiled when loaded, no
- relocatability issue arises so that a given overlay may be loaded at different
- levels of an overlay tree.
-
- For the purpose of discussion, in what follows the root overlay
- will be called "driver" and the rest of the overlays will be called
- "segments".
-
- -
- The driver is the only program which should contain the initializing code
- inserted by the compiler; all segments must be compiled with an [Exclude LIB]
- comment in their source files appearing before the first subroutine or program,
- preventing thus insertion of the initializing code.
-
- Automatic inclusion of library routines at runtime requires that the root
- inform the compiler which routines must be included in addition to those
- determined automatically by the compiler during compilation of the root. This
- is accomplished by an [Include ....] comment near the beginning of the root's
- source file, where "...." is replaced by the strings inserted by the compiler
- (after enclosing them in square brackets) at the end of each segment's object
- file (which will always happen if the source file contains [Exclude LIB]).
-
- For example, the quantum chemistry program HAMEL is made up of 9 programs;
- the root is HAMELD and the segments are HAMELx, where x is X, F, G1, G2, G3,
- G4, G5 and M. Due to the [Exclude LIB] in the 8 segments, the compiler
- produced the following strings, inserted at the end of each file HAMELx.REC:
- [T # #*#|#/W 64O OrOwE ], [T W 64O OrOwE ], [W t T 64O OrOw E ],
- [T W 64O OrOwE ], [T W 64O OrOwE ], [t T W 64O OrOwE ],
- [# #*#|#/T W 64O OrOwE ] and [T W 64# #*#+#-#|#/O OrOwE ]; with these strings
- a comment [Include T t W 64# #+#-#*#/#|O OrOwE ] was formed for insertion in
- the program file of the root, HAMELD.CNV.
- -
- The "Include" comment in the example was built gathering all distinct pairs of
- characters appearing in the eight final strings generated for the segments;
- notice spaces are important because the automatic inclusion mechanism examines
- the "Include" string by pairs of characters.
-
- Overlays may be read from disk files or memory buffers; the latter case
- essentially extends the compilation area into REC's pushdown list, from
- which space is procured for memory buffers. Storing overlays in memory
- buffers also has the advantage that overlay loading from them is
- substantially faster than loading from a disk file. The following skeleton
- fragment shows how an overlay in a file called FSY.REC is read from disk
- and written into a MEM: pseudofile whose size is computed from the length
- of the original file itself:
-
- (IF,(0),(until,(%R,FSY.REC),(^Z),<=>,(%R,FSY.REC),),<0>,<<
- >>(%C,FSY.REC)(,(%Ow,MEM:sy,(&!,<0>)))(%W,MEM:sy,<0>))
-
- Closing FSY.REC before opening MEM:sy saves memory by releasing table and
- buffer space associated with F77SY.REC; the length of MEM:sy is determined
- by the length of the contents of F77SY.REC; <0> is bound to these contents.
-
-
- -
- An overlay is loaded and executed by the skeleton
-
- (%V,name,arg)
-
- where 'name' is the name of the disk file (whose extension is assumed to be
- .REC if not explicitly given) or memory buffer containing the overlay and
- 'arg' is a skeleton whose value is the argument received by the overlay in
- the workspace; 'arg' is optional and when omitted, the preceding comma may
- also be omitted and the overlay will receive an empty workspace.
-
- The last overlay loaded may be reexecuted any number of times without
- recompiling it (as long as no other overlay is loaded) by calling it with the
- skeleton ( ,arg) in which a single blank space appears between the left
- parenthesis and the comma, and 'arg' is the argument to be passed to the
- overlay; the skeleton ( ) (with a single blank) may be used if no argument is
- to be passed (i.e., if the null string is to be passed).
-
- The Convert compiler may be loaded as a segment: (%V,CONVERT,arg) compiles the
- program contained in the disk file given by 'arg', generating the corresponding
- REC file. If X.CNV, Y.CNV and Z.CNV are to be compiled, the concatenation
- (%V,CONVERT,X)( ,Y)( ,Z) will load CONVERT.REC once and compile the three
- programs. The default extension for 'arg' in this case is .CNV.
-
- :Loading of .COM binary files.
-
- Three skeletons permit loading and executing machine code files:
-
- (%Xl,f)
- (%Xx,f,c)
- (%Xv,f,c)
-
- %Xl loads the file whose name is given by the skeleton f (an extension .COM
- is assumed if none is given), using a file of the same name and extension .BIM
- (containing a bit map) to relocate the loaded file, which is assumed to be
- loadable without relocation at 100H. The program contained in "f" is loaded
- starting at the next available address in REC's compilation area; this address
- is updated if the loaded program fits into the available space. If the
- program does not fit or it or its bit map file do not exist, (%Xl,f) evaluates
- to the string 'Not Found'; otherwise its value is the null string.
-
- %Xx executes a program previously loaded by %Xl; a program loaded by %Xl stays
- resident for the duration of the run, so that %Xx may be used to execute it as
- many times as desired.
-
-
- -
- The argument c in this skeleton is a skeleton whose value is interpreted as
- a command line tail from which up to two file names are parsed and placed at
- locations 5CH and 6CH; the length of the string resulting from c (or 127,
- whichever is less) is stored in location 80H and the string itself (up to the
- first 127 characters) is placed in the data area starting at 81H. If the
- program was not loaded, %Xx returns the string 'Not Found' to the calling
- program; otherwise (and assuming program "f" returns to the calling program)
- it returns the string starting at 81H and whose length is stored at 80H, as
- long as it does not exceed 127 (if it does, the null string is returned).
-
- %Xv loads and executes a file in the manner of %Xl and %Xx, but restores the
- compilation area pointer upon return from execution of the loaded program, so
- that it executes the named program as an overlay, freeing the compilation area
- space after execution. It returns the string 'Not Found' if either the file
- given by f or its .BIM bit map cannot be found or if the program will not fit
- into the available space. %Xv and %Xl must not be used on the same file f in
- a given Convert program, that is, a program to be loaded and executed by the
- %X skeletons must be either a resident program or an overlay, but not both,
- during a given run of a Convert program using it.
-
-
-
- -
- The bit map is a file containing one byte for each eight bytes of the program
- file. The correspondence starts at the most significant bit; the first byte
- of the BIM file corresponds to the first eight bytes of the COM file. When a
- 1 bit is present in the bit map, it indicates that the corresponding byte in
- the COM file is the higher byte of an address; relocation is effected by
- adjusting this address.
-
- To obtain the BIM file, the corresponding program must have been assembled or
- compiled with two origins differing by an integer multiple of 0100H (256); the
- differences between the resulting files is exploited by GENBIM (program 165.13
- in the SIG/M collection) to produce the bit map.
-
- :Priority Queues (Heaps).
-
- The following skeletons handle a MEM: pseudofile as a priority queue (or heap)
- of two-byte unsigned integers:
-
- (%Hi,m,d) (%Hs,m)
- (%Hr,m) (%Hh,m)
-
- In all four skeletons, m is a skeleton which must evaluate to a MEM:
- pseudofile name; d in skeleton %Hi must be evaluate to a four byte ASCII
- string representing a hexadecimal number (lower case a-f are not recognized).
-
- %Hi inserts the two-byte binary representation of the ASCII hex number d
- into the pseudofile m, sifting the file to maintain the heap condition. If
- the pseudofile is viewed as an array P with N entries, maintaining the heap
- condition means requiring that P(i)>P(2*i) and P(i)>P(2*i+1) for i between
- 1 and floor(N/2). After an insertion, the pseudofile read pointer is set to
- beginning of the buffer, so that a subsequent read from m will start from the
- top of the heap. %Hi returns the null string.
-
-
-
- -
- %Hr reads the next two-byte value from m, converting it to a four-byte ASCII
- string (hex). This skeleton is essentially equivalent to (&h,(%R,m,<[2]>)),
- and is included for convenience.
-
- %Hs sorts the contents of m, which are assumed to satisfy the heap condition.
- It returns the null string and does not affect the value of the pseudofile
- read and write pointers.
-
- %Hh sorts the pseudofile m by the heapsort method assuming it to contain
- two-byte unsigned values. The file need not satisfy the heap condition
- initially; a file suitable for sorting by %Hh may be produced by writing
- values with the skeleton (%W,m,(&H,h)), where h is a four-byte ASCII
- hexadecimal string, or with (%W,m,(&D,d)) where d is an ASCII decimal integer
- between 0 and 65535.
-
- :Error messages.
-
- CONVERT.REC displays the following messages upon detecting the corresponding
- errors:
-
- Unexpected EOF End of file encountered in the middle of a
- compilation, for instance, if there are
- subroutines but no main program.
-
- Unbal {
-
- Excess }
-
- WS ovf Workspace overflow.
-
- Unbal [
-
- Expected (, [, { Spurious characters in the source file.
-
- Expected )
-
- Expected "," Syntax violation in LAM, IF, WHILE, etc.
- -
- Ill patt Illegal pattern.
-
- Ill skel Illegal skeleton.
-
- Ill rule Rule lacking the comma separating pattern
- from skeleton.
-
- Ill sep Colon/semicolon missing after a rule.
-
- Ill var Variable number not between 0 and 30.
-
- Ill var list Badly formed variable list.
-
- Ill <=> Illegal use of skeleton <=>.
-
- Dir full Directory full reported by the operating
- system when attempting to write.
-
- Disk full Disk full reported by the operating system
- when attempting to write.
-
- Not Found Nonexistent source file.
- -
- No file given No source file name given to the compiler.
-
- :[CNVADV.HLP]
- [Gerardo Cisneros, 13.8.84]
- [Rev.: G. Cisneros, 28.1.86]
- [end]