M routines have a name and consist of lines of code followed by a formfeed. M separates the name of a routine from the body of the routine with an end-of-line which is a line-feed. This form is mostly used for interchange with other M implementations and can be read and written by the %RI and %RO utility routines.
GT.M stores routine sources in UNIX text files.
In M, a routine has no particular impact on variable management and may include code that is invoked at different times and has no logical intersection.
A line of M code consists of the following elements in the following order:
An optional label.
A line-start delimiter. The standard defines the line-start delimiter as a space (<SP>) character. In order to enhance routine readability, GT.M extends M by accepting one or more tab (<HT>) characters as line-start delimiters.
Zero or more level indicators, which are periods (.). The level indicators show the level of nesting for argumentless DO commands: the more periods, the deeper the nesting. M ignores lines that contain level indicators unless they directly follow an argumentless DO command with a matching level of nesting.
For more information on the DO command, see Chapter 6: “Commands”.
Zero or more commands and their arguments. M accepts multiple commands on a line. The argument(s) of one command are separated from the next command by a command-start delimiter, consisting of one or more spaces (<SP>).
A terminating end-of-line, which is a line feed.
In addition to labels that follow the rules for M names, M accepts labels consisting only of digits. In a label consisting only of digits, leading zeros are considered significant. For example, labels 1 and 01 are different. Formalists may immediately follow a label. A Formalists consists of one or more names enclosed in parentheses (). Formalists identify local variables that "receive" passed values in M parameter passing. For more information, see “Parameter Passing”.
In GT.M, a colon (:) delimiter may be appended to the label, which causes the label to be treated as "local." Within the routine in which they appear, they perform exactly as they would without the trailing colon but they are inaccessible to other routines. Using local labels reduces object size and linking overhead, for both ZLINK and host linking.
In addition to commands, a line may also contain a comment that starts with a leading semi-colon (;) delimiter. The scope of a comment is the remainder of the line. In other words, M ignores anything to the right of the comment delimiter. The standard defines the comment delimiter (;) as it would a command, and therefore requires that it always appear after a linestart. GT.M extends the standard to permit comments to start at the first character of a line or in an argument position.
M entryrefs provide a generalized target for referring to a line within a routine. An entryref may contain some combination of a label, an offset, and a routine name (in that order). The offset is delimited by a plus sign (+) and the routinename is delimited by a caret symbol(^). When an entryref does not contain a label, M assumes the offset is from the beginning of the routine. When an entryref does not contain an offset, M uses an offset of zero (0). When an entryref does not contain a routine name, M assumes the routine that is currently executing.
M permits every element in an entryref to have the form of an indirection operator, followed by an element that evaluates to a legitimate occurrence of that portion of the entryref.
While most commands and functions that use entryrefs permit argument indirection, M does not accept indirection that resolves to a combination of label and offset or offset and routine name.
Offsets provide an extremely useful tool for debugging. However, avoid their use in production code because they generally produce maintenance problems.