Show pageBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. {{htmlmetatags>metatag-description:(GIN Reference Manual - Chapter 3 The Source Program)}} ====== 3 THE SOURCE PROGRAM ====== ===== 3.0 Source formats ===== This section of the manual describes in greater detail the source which GIN will accept.\\ The compiler is regulated by [[gin:chapter3#3.2 The format of directives|directives]] and thereby obtains the definitions of a number of [[gin:chapter3#3.3 Identifiers|identifiers]] and [[gin:chapter5|macros]]. The identifiers can be combined with other numerical terms to form [[gin:chapter3#3.4 Expressions|expressions]] having a numerical value, and these expressions may be referred to by [[gin:chapter3#3.2 The format of directives|directives]] and in [[gin:chapter3#3.5 Instruction Formats|instructions]] and [[gin:chapter3#3.6 Data Constants|dataconstants]]. The ways in which source is selected for compilation are discussed in [[gin:chapter3#3.7 Selective Compilation|3.7]].\\ GIN source consists of a series of records or lines. In general each record will contain one [[gin:chapter3#3.2 The format of directives|directive]], one instruction or one macro call, but it is possible to have several data constants in one record. A record in this sense normally corresponds to one card, paper-tape block or magnetic-tape record or to one line of a macro expansion; however, where continuation lines are used as described in [[gin:chapter2#2.1 Input|Section 2.1]] one logical record can consist of more than one physical record.\\ The format of GIN source is fairly free, Certain fields of source records must start in column 1, and certain other fields must start in a later column. However, where fields are separated by spaces the number of spaces is not significant.\\ The end of a source record, as far as GIN is concerned, is reached at - the character [,or - the end of a record on magnetic tape, or - a TC<sub>4</sub> or newline character on paper tape, or - if none of the above has been encountered, the 500th character (counting spaces) of the record. Anything following [ is treated as comment and printed (if necessary) but otherwise ignored. The 50l<sup>st</sup> and subsequent characters of a record will be flagged as an error and otherwise ignored. Any number of blank records may intervene at any point with no effect on the program, except that if a blank record immediately follows #SKIP or a similar directive it will be the only record skipped. Blank records are not stored in macro definitions.\\ It is possible to align fields in the source line as if it were written in PLAN. This produces a neat result which is easy to read, and has therefore become standard practice. However, GIN does not insist on this layout being used. ===== 3.1 Overlays and Segments ===== * Source lines in GIN are divided into three classes: * Lines which give rise to stored words: these must be in the formats described in Sections [[gin:chapter3#3.5 Instruction Formats|3.5]] and [[gin:chapter3#3.6 Data Constants|3.6]] * Lines which only affect the operation of the compiler; these consist of directives ([[gin:chapter3#3.2 The format of directives|Section 3.2]]) and labels (see [[gin:chapter3#3.3 Identifiers|Section 3.3]]) and lines in macro definitions. * Lines which give rise to other source lines: these are macro call lines ([[gin:chapter5|Section 5]]). Every source line which gives rise to a stored word must be within an overlay (except for interludes: see [[gin:chapter6|Section 6]]). Every GIN program consists of one or more overlays. An overlay is a block of consecutive words in a program which are stored together and which will be brought into core as a unit distinct from any other overlays.\\ Almost any program which is not very large will consist of a single overlay. For example, the GIN compiler (which is written in GIN) consists of one overlay, and any such program is colloquially referred to as non-overlaid since no changing of overlays takes place.\\ However, GIN allows programs to be set up as a collection of overlays; one of these (the first to be compiled) will be resident in core initially, and the rest will be stored on some kind of backing-store and brought in by the program as required.\\ For its own convenience, GIN also insists that a program be subdivided into segments. A segment is a section of code containing up to 1024 stored words. Each segment has its own name, and is included as a unit according to the user's instructions (see [[gin:chapter3#3.7 Selective Compilation|Section 3.7]]). Labels and other identifiers within the segment can be local to the segment and unavailable outside it.\\ GIN insists that each segment should be contained within, or else form the whole of, an overlay.\\ There are two classes of overlays, long overlays and chapters. ==== Long Overlays ==== A long overlay commences with a #BASE directive and ends with a #OVERLAY directive. It will contain one or more segments, and will have a name (which should be unique, although GIN does not depend on this). The #BASE directive specifies the name of the overlay and the base address, which is the core address where its first word is expected to go when the overlay is in core. The #OVERLAY directive can specify the first instruction in the overlay to be obeyed, and whether the program is to halt before entering the overlay.\\ The first overlay of a program must be in the form of a long overlay. ==== Chapters ==== A chapter consists of a segment which does not lie between #BASE and OVERLAY. It has a base address of zero, and it is assumed to have no specific entry point (that is, the user arranges for entry to it).\\ The intended use of chapters is as relocatable code which may be obeyed irrespective of its position in the machine. Most of GEORGE is written as chapters. To use chapters successfully, all branches within a chapter should be relative, and references to data words in the chapter should be modified by a pointer to the first word of the chapter. (GEORGE holds such a pointer in FX1). ==== SEGMENTS ==== A segment is simply all the code between #SEGMENT and #END. It has a name and an address on backing-store.\\ It is possible to correct a segment already compiled by means of the #MEND directive; this directive specifies the segment to be altered, and all that is to be done is to state which words in the segment need correction and what their contents should be. The end of a series of corrections is a #END directive. ===== 3.2 The format of directives ===== A directive is a sequence of characters which starts with # in column 1. At present, all directives consist entirely of letters after the #, and the first four characters including the # are sufficient for a directive to be recognised. Any number of nonspace characters may follow the first four, and they will be ignored. (This does not apply to #GO, where a space must follow the O, and any following characters will be taken as forming the parameter to the directive).\\ A # in column 1 followed immediately by a space in column 2 introduces comment, which will be printed if necessary, stored if it is in a macro definition, and otherwise ignored.\\ Each directive will have a number of parameters (or none) as described in its individual specification. The first parameter is separated from the directive by a space, but the separators between subsequent parameters may be commas, spaces or other symbols as described in the specifications: |Space between A and %B |#BAS, #POS| |Space between A and %B, later parameters separated by commas | #BIP, #DUM, #OFR, #OFW, #REN| |Spaces between %A and %B and between %B and %C |#FID| |= between %A and %B |#DEF, #OPT| | No separator: %B recognised by starting with first non-alphabetic character |#INC, #SEG| |Commas |All other directives| Note: These directives allow either the format described above or the use of commas between the appropriate pairs of parameters. Eventually, GIN will standardise on the latter format for all directives except those which (a) take a segment name and number as a parameter or (b) set an identifier to a value. The old formats of the directives mentioned should be removed when it is convenient to do so.\\ Generally, if the separator between two parameters is not a space there should be no spaces between the preceding parameter and the separator,nor between the separator and the following parameter. A null parameter is indicated by two separators with no spaces between them. There may be any number of spaces after the last parameter, or after the last separator if the last parameter is null.\\ For example, the following are incorrect, and may be treated as errors; #DEF A NAME=B #ITE 6, ,10 but the following are correct in format: #DEF A=B #ITE 6,,10 In the latter, 6 is the first parameter, 10 is the third, and the second parameter and the fourth and subsequent parameters are null.\\ The following lines are permissible only in GIN513 and later versions: #DEF A =B #DEF A= B At present directives vary as to whether spaces on either side of commas are permissible. ===== 3.3 Identifiers ===== An identifier is a string of up to 11 alphanumeric characters of which the first is alphabetic. Identifiers are divided into two classes, local identifiers and universal identifiers, according to their initial letters: A to L Universal M to Z Local Each identifier has a value, which is an integer n in the range -2<sup>23</sup>≤n≤2<sup>23</sup>-1. At a given point in a compilation the value of a given identifier may be known or unknown. Whenever an identifier whose value is known is referred to in a program, the value will be substituted for it. If an identifier whose value is not yet known is referred to, GIN will if possible remember to insert the value when it becomes available; but sometimes it is necessary to know the value at once, and then the source line will be error-flagged. Any use of an identifier whose value is unknown is called a forward reference.\\ A universal identifier may be defined at any point in the program after #CORE, and must be unique; and it may be referred to anywhere after #CORE. A local identifier is available only in the segment in which it is defined and subsequent code before the next segment. The same name can be used for locals in different segments, and no connection is assumed between them if this is done.\\ The number of universals which can be defined is limited by the size of the workfile, and the number of locals in any one segment by the size of the local working storage.\\ Both these sizes may be adjusted by the user, and the current default sizes allow roughly 35000 universals and 400 locals (ignoring space which may be used for other purposes). ==== DEFINING IDENTIFIERS ==== A value may be assigned to an identifier in any one of the following ways: - By using the directives #DEFINE or #OPTIONAL - By placing it in the label field of a source line during the compilation of a segment - Implicitly by the compiler if the initial letter is D or L. A value once assigned to an identifier cannot be changed except by the use of an interlude, such as that in the RESET macro (Section 10.6.1). ==== #DEFINE and #OPTIONAL ==== These two directives each take two parameters separated by "=" and their purpose is to assign the value of the expression right of "=" to the identifier named left of "=". The distinction between them is that if this identifier has already been assigned a value #DEFINE is treated as an error but #OPTIONAL is merely ignored.\\ The expression whose value is assigned to the identifier may contain references to undefined identifiers. This is permissible unless the identifier being defined is a local and at least one of the unset identifiers referred to is a universal.\\ GIN will not detect the error if an attempt is made to define an identifier directly or indirectly in terms of itself, for example by #DEF FRED=FRED+2 or #DEF FRED=BILL+1 #DEF BILL=FRED-1 In such cases it will generally be impossible to redefine the identifiers correctly.\\ Another use of the #DEFINE directive is to change the values of compiler variables; see [[gin:chapter6#6.1 Compiler Variables|Section 6.1]]. ==== LABELS ==== If a valid identifier name is written in a source line with its first character in column 1, it is taken to be a label in the program. The value assigned to it is the core address (when the part of the program being compiled is loaded) of the next word in the program; this word may be set up by the same source line or a later one. The first word of a chapter (a single-segment overlay) is taken as address O, and the address of the first word of any other segment is the base address of the overlay plus the sum of the lengths of the preceding segments. In an interlude, the value of the identifier is the address within the compiler where the interlude is being assembled.\\ It should be clear that labels can only appear within segments (including mends) and interludes. Apart from the method of definition there is no distinction between labels and other identifiers.\\ If a number is placed in the label field, GIN takes it as the equivalent of a #TRANSFER directive whose first parameter is the number. ==== IMPLICIT DEFINITION: D AND L ==== Universals whose names begin with D and L may not be defined by the above methods. The compiler will itself assign values to such identifiers as follows:\\ Whenever #SEGMENT is compiled, an identifier D//segment// is defined whose value is the program file address of the segment, that is, the address of the backing store area where it will be stored.\\ Whenever #END is compiled at the end of a new segment, an identifier L//segment// is defined whose value is the length in words of the segment.\\ D and L identifiers may be referred to in the same way as any other universals. They can in particular be used by an overlay-changing system in the user's program which keeps each segment at the same backing-store address as the one used by GIN. If an overlay consists of one segment A its backing-store address is DA and its length is LA; if it consists of several segments A,B,C,...,Z its backing-store address is still DA and its length is LA+LB+LC+...+LZ.\\ The D identifier is always set up as a drum address; the corresponding address on direct-access devices is obtained by dividing it by 128 and adding 1 to the quotient, leaving any remainder as a word address.\\ The use of other identifiers beginning with D and L is reserved. ==== FREEING IDENTIFIERS ==== Universals once referred to are available throughout the compilation, and cannot be freed.\\ Locals are freed - en bloc by #SEGMENT, #MEND and #FRL - individually by #FREE and by the end of a macro expansion being reached. Whenever a new segment is started, the locals from the previous segment are all forgotton and the space used to store them is made available for re-use. The user may cause this to happen within a segment or interlude by #FRL.\\ It is possible to free individual locals by #FREE; in versions of GIN up to and including GIN 510 the storage space used will not be re-used until all the locals are next freed.\\ Whenever the end of a macro is reached, the source is scanned again, and if a recognisable local label is found it is freed. However, the following are not freed: universals - locals not defined within the macro - locals defined by #DEFINE or #OPTIONAL - local labels whose names contain "%" indicating parameter substitution. Thus labels (other than universals) used inside macros are local to the macro in the sense that they are unavailable after the end of the macro. If the label has been used outside a macro earlier in the segment a clash will occur. To avoid this, it is recommended that all locals defined within macros should begin with M followed by the name of the macro.\\ The fact that locals defined by #DEFINE or #OPTIONAL are not automatically freed has been made use of very ingeniously in some macros (see Section 10.3, Example 4).\\ Recursive macros in versions up to GIN 510 may use up an excessive amount of space by alternately defining and freeing identifiers. Any user in this position should consider using #FRL and possibly the compiler variables. ==== CHOOSING IDENTIFIER NAMES ==== As mentioned above, up to eleven characters can be used in identifier names, of which the first must be a letter. While it saves space in core and on backing store to use short identifiers up to four characters), the purpose of allowing 11 characters is to permit the user to use names which suggest what the identifier is used for. This is true even for labels; there can be few things more confusing than to read a stretch of code where the labels are Z1,Z2,... and so on in no particular order. BNG 0 NOMACROS is more meaningful and memorable than BNG 0 Z20. Un-numbered labels also lend themselves to being moved more easily than numbered labels.\\ Another point which can help users to write code which others can easily understand is to avoid using identifier names which coincide with those of macros, instructions or segments. GIN itself stores all of these separately and will not be confused, but it does lead to confusion in the mind of the human reader and can cause him to look for nonexistent conections. Worse still is to have identifiers which look identical to the casual reader, and differ only in internal characters.\\ Lastly, it is useful to create and use conventions such as the one that M is only used in a macro. This avoids clashes between different people working on macros which may appear throughout the source program. ===== 3.4 Expressions ===== An expression consists of a series of one or more terms as described below, each optionally followed by ], and separated by operators. The first term may be preceded by an operator, and it must be preceded by an operator if the expression is a data constant (see 3.6) and the first term of the expression is an identifier. (No spaces may occur within an expression.)<sup>upto GIN512</sup>\\ Whether spaces may appear in an expression or not depends on the context in which the expression is found; spaces are not allowed in the first and second parameters to #FIDDLE, and in numeric labels, but they are permitted in other expressions. Where they are allowed they may appear on either side of any operator, except in front of "!" or "?".<sup>GIN513 onwards</sup>\\ An expression may be evaluated to yield a value in the range -2<sup>23</sup> to +2<sup>23</sup>-1. It is evaluated from left to right, and there is no provision for precedence of operators or for bracketing sub-expressions. (However, it is generally possible to use compiler variables to obtain equivalent results.)<sup>upto GIN512</sup> (It is evaluated from left to right except where the order is changed by enclosing sub-expressions in parentheses, and at present there is no provision for precedence of operators.)<sup>GIN513 onwards</sup> No sub-expression obtained in the course of evaluation may fall outside the permitted range of values.\\ The terms in the expression may be - Identifiers - Decimal numbers - Octal numbers - Compiler variables - The expression £ - In GIN 511 onwards, mend status values - In GIN513 onwards, valid expressions enclosed in parentheses. Within an expression these terms may be added, subtracted, multiplied, divided, compared (as 24-bit quantities) (, shifted logically or circularly)<sup>GIN513 onwards</sup> and combined by logical operations. Any resulting value may be treated as an address relative to GIN's datum and its contents extracted. ==== TERMS ==== === Identifiers === The format of identifiers has been described above ([[gin:chapter3#3.3 Identifiers|Section 3.3]]). Identifiers which have already been defined may be used in any expression. The use of forward references is governed by the following rules: - In certain circumstances expressions containing forward references are absolutely prohibited, and so every identifier used must be fully set. - In other expressions, identifiers which are not fully set may be used, provided that the operator (if any) immediately preceding the first such identifier is "+" or "-" and each operator after it is one of "+" "-" and "." - Where an identifier which is not fully set occurs within parentheses, it is permissible only if each bracketed sub-expression containing it could permissibly be replaced by a forward reference.<sup>GIN513 onwards</sup> Wherever forward reference is impermissible because it is preceded or followed by the wrong operator, it may be remembered incorrectly by GIN. The value of the resulting expression is indeterminate and may change in the course of compilation. === Decimal numbers === A decimal number is a string of up to seven decimal digits not exceeding 8388607 in value. === Octal numbers === An octal number consists of "#" followed by up to eight octal digits, e.g. #243607. === Compiler variables === A compiler variable is an octal or decimal number not exceeding 74 (GIN 511: 76) followed by "?", e.g. 32? The value of a compiler variable may change from time to time through the compilation, and the value used in evaluating the expression is that at the moment the term is reached. Full details of compiler variables and their use can be found in [[gin:chapter6#6.1 Compiler Variables|Section 6.1]], and the meanings of the variables are listed in Section 10.2. === The special expression £ === The symbol "£" may be used to represent the address of the next stored word; thus it may be used in a branch instruction to cause the compiled program to branch to the following instruction. It must be the only term in its expression. === Mend status values === A term of the form n! where n is a positive decimal integer is interpreted as the status of the mend whose number is n; e.g. 74316! is the status of mend 74316. If no status has been recorded for the given mend number, the term is replaced by zero and evaluation continues, but the line is error-flagged C. See [[gin:chapter4#4.4 Mending the Compilation|Section 4.4]] for information about mend statuses. === Bracketed expressions === Any valid expression may be enclosed in parentheses "()" and parentheses may be nested to a considerable depth. Any such expression is evaluated as a whole before being treated as a term in the expression which contains it. If the end of a bracketed expression is reached without a matching ")" being found, an error is flagged. An unmatched ")" is treated as the end of the expression.\\ The operand of an extended-mode branch instruction may be enclosed in parentheses to indicate that the branch is a replaced branch; these parentheses do not form part of the operand expression, but this expression may itself contain matched parentheses. === UNARY OPERATORS === There are a number of unary operators available in GIN. "?" and "!" qualify the preceding term, which must be numeric; "]" qualifies the whole expression preceding it; "#" qualifies the following octal number; (and "+" and "-" qualify the following term, which may be a bracketed expression)<sup>GIN513 onwards</sup> "?", "!" and "#" are described above.\\ "]" qualifies the whole of the expression preceding it; when it is recognised, the preceding expression is treated as an address relative to GIN's datum, and the value of the expression including "]" is the contents of this address. For example, 187+2]+2] might be evaluated as follows, the numerical values depending on the version of GIN: ^ Partial expression ^ Value so far ^ | 18 | 18 | |18? | The contents of the 18th word of the compiler variable table, i.e. (657+18]=[675]=746 | | 18?+2 | 748 | | 18?+2] | The contents of word 748 in GIN | | 18?+2]+2 | 828 | | 187+2]+2] | The contents of word 828, e.g. 3969 | Clearly "]" can only properly be used when the expression to the left of it contains or was defined in terms of compiler variables. The meanings of a number of expressions of the form m?+n] or m?+n]+p] are tabulated in Section 10.2.\\ At present a restriction exists by which "]" may only follow a digit. Thus we write "19?+O]" rather than "19?], or "FRED+20]" rather than "FRED]".\\ If the expression preceding "]" is outside GIN's addressing range the line will be error-flagged.\\ "+" and "-" may precede any term, including a bracketed expression, and may follow each other or themselves to an indefinite extent. The result of "+" is null; each "-" causes the term which follows to be negated once before the operation which followed the previous term is applied. Thus we can write (equivalently) +- FRED or FRED*-1. If a forward reference is preceded by unary "-" signs its value is still filled in correctly. === BINARY OPERATORS === The binary operators known to GIN are as follows: | + | Add | | - | Subtract | | * | Multiply: the expression left of "*" is multiplied as an integer by the term right of "*", testing for overflow. | | / | Divide: the result is the quotient rounded downwards (away from zero if it is negative). Division by 0 is treated as division by 1. | | & | Logical AND of the term right of "&" with the expression left of it. | | ↑ | Logical OR | | $ | Exclusive OR | | < | The result of expression<term is min (expression, term) | | > | max (expression, term) N.B. that the TXL instruction is used, so that if the expression and the term have different signs the negative number is taken as the greater. | | : | The expression is shifted left logically 15 bits into the count field of the word, and the term following ":" is added into the word. The terms following, if any, operate on the whole word, not the least significant 15 bits. | | . | The two least significant bits of the term following "." are added into the two most significant bits (the character index position) of the preceding expression. Any following terms act on the whole word, not the most significant two bits. This operator is not allowed in instruction words. | | @ | Strictly, "@" itself is not an operator, but it may be combined with the following character to produce an operator. The following combinations are defined, the use of any others causing an error; | | @C | The expression is shifted circularly the number of bits (not exceeding 23) specified by the term. If the term is positive the shift is left, if negative it is right. | | @L | As for "@C" except that the shift is logical. | **NOTES**\\ **1.**\\ The binary operators given above may not be placed side by side, although they may occur next to ?, ], ! or #. For example, you may not write FRED+BILL*-1, although FRED+BILL*#77777777 is permissible.\\ The following are legal: 0?+1 18?+2]+4]*3 100/#76 (whose value is equal to 1). The following are wrong 2:+ABLE should be 2:ABLE 2:ABLE.+TOM should be 2:ABLE.TOM The only cases where operators may occur side by side are where at least one is a unary operator; there must be one and only one binary operator between any two terms, and none anywhere else. In this context, "+" or "-" immediately after a term or "]" is a binary operator, and anywhere else "+" or "-" is a unary operator. The sign "]" may occur repeatedly after a term; the signs "+" and "-" may occur repeatedly in any combination before a term.\\ **2.**\\ Where an expression is used as a data constant (see [[gin:chapter3#3.6 Data Constants|Section 3.6]]) and its first term is an identifier, it must be preceded by a sign to distinguish it from a macro call. CONST1 ABLE+TOM (is treated as a macro call and flagged error G) CONST2 +ABLE+TOM (OK) CONST3 2+ABLE (no sign needed before digit). **3.**\\ Where a word includes a count and a character modifier they will both be added in: #301:11.2 gives #701 00013 #301:11.1 gives #401 00013 and error E for overflow. **4.**\\ In PLAN it is permissible to write *+n or *-n as the operand of a branch instruction. This facility is not provided in GIN - because it is possible to use labels within macros easily (see "Freeing identifiers", [[gin:chapter3#3.3 Identifiers|Section 3.3]]) - because in other contexts it is easy to overlook the necessity of changing such operands if intervening code changes in length. GIN only provides the expression "£" which is equivalent to "*+1".\\ **5.**\\ GIN uses ":" where PLAN uses "/" to separate the count field and the modifier field of a word. **EXAMPLES**\\ **1.**\\ +BUZ+3)5/2*4 means the greater of +BUZ+3 and 5, divided by 2, and the rounded result multiplied by 4. The method of evaluation is shown for three values of BUZ: +BUZ -1 +5 -10 +BUZ+3 +2 +8 -7 +BUZ+3>5 +5 +8 -7 (note -7>+5) +BUZ+3>5/2 +2 +4 -4 +BUZ+3>5/2*4 +8 +16 -16 **2.**\\ Forward references in definitions: #DEF FRED=SPUD*4 [SPUD must be set #DEF FRED=SPUD+SPUD+SPUD+SPUD [SPUD may be unset #DEF SPUD=FRED [FRED must be set **3.**\\ In instructions, all operations except "." are permitted: LDN 3 BSBS/128+1 [ BSBS must be set BUX 1 £ BCT 6 FRED-3 [ not recommended **4.**\\ The rules about forward references are illustrated by: +BUZ-4+BILL-#77/JACK+3-TOM where only TOM may be a forward reference. GIN is only capable of remembering whether a forward reference is to be added or subtracted (and, if the forward reference was set up by an instruction, #FIDDLE, or #HALVES, the part of the word concerned.)\\ **5.**\\ #SKI ASKIP<1$1 is the standard way of skipping if ASKIP is non zero: similarly #SKI G3MARK>6$6 (ignore if G3MARK is 6 or less) #SKI G3MARK<7$7 (ignore if G3MARK is 7 or more) (See [[gin:chapter3#3.7 Selective Compilation|Section 3.7]] for more information about #SKIP.)\\ **6.**\\ The standard way of setting up non-preset data areas is: #DEF ABLE=45 #DEF BAKER=ABLE+1 #DEF CHARLIE=BAKER+4 [BAKER is a 4 - word area #DEF ABASE=CHARLIE+2050 #BAS PROGRAM ABASE [base of main overlay. **7.**\\ In macro source before GIN513. LDN 4 ABLE+%B will cause an error if the parameter %B is specified as "+ABLE", "-2" etcetera, because "++", "+-" and so on are not permitted. **8.**\\ The expression 10.2+1 is equivalent to 11.2, not to 10.3. **9.**\\ The following expressions are trivially valid: <code>-3 0 +379 +FRED #26 37?</code> **10.**\\ 60027!+3 is the number 3 greater than the status of mend 60027. **11.**\\ 5@C2=20 5@L2=20 5@C-2=#20000001 5@L-2=1 **12.**\\ (A+B)*C=A+B*C A+(B*C)=B*C+A A*(B+C)=B+C*A but it would be impossible to write without brackets (A+B)*(C+D) **13.**\\ From GIN 513 we can write 18?]] for 18?+0]+0], or 19?+M] for 19?+M+0]. ===== 3.5 Instruction Formats ===== In GIN the instruction set and the formats of instructions are almost identical to those in PLAN. The comparatively few differences are documented below, but all other information about the format and meaning of any instruction should be obtained from the PLAN Reference Manual bearing in mind these differences.\\ This manual does not attempt to explain how hardware and Executive implement any instruction. This information should be obtained from: * The Executive Specification Manual for extracodes issued by GEORGE to Executive. * The USM or the GEORGE 3 and 4 external Manuals for extracodes issued by programs running under GEORGE. * The PLAN Reference Manual and the 1900 Series Progrmmers' Reference Manual for other instructions. Instructions may only be compiled within a segment or mend or an interlude. Since segments are used in GIN as the equivalent of PLAN's lower and upper preset areas and program area, this simply means that they may only occur where they will actually form part of the object program (or be obeyed by the compiler).\\ Every instruction consists of a mnemonic, possibly followed by one or both of an accumulator and an operand. ==== MNEMONICS ==== The mnemonics recognised by GIN are those known to PLAN (except for those listed below) and the special GEORGE mnemonics ISBY (153) and GEO (177).\\ The PLAN mnemonics which GIN does not recognise are those which lead to the compilation of two or more words, that is the pseudo-instructions or macro-instructions. These fall into the following groups:\\ 1. LDPL If the label addresses a word whose address is below 4096, use LDN. Otherwise set up a word containing the label, e.g. ALABPTR +ALABEL and write LDX 0 ALABPTR 2. LDX, ADX, etc., BUX, BDX, BCHX when taking two accumulators.\\ Either write out in full: LDXC 2 FRED+1 BCHX 1 £ LDX 1 FRED BCT 4 REPEAT or else define new macros in which the two accumulators appear as separate parameters: #MACRO LDX2 [LDX2 1,2,FRED LDXC %B %C+1 LDX %A %C #NORMAL #MACRO BCHE [BCHE 1,4 REPEAT BCHX %A £ BCT %B #NORMAL In BCHE, %B represents both the accumulator field and the operand field of BCT.\\ 3. BXU, BXE, BXL, BXGE, LDSA, LDLA, ON, OFF, TEST, OVER\\ If you wish, you can define macros with the same names and effects.\\ 4. Magnetic tape macros\\ These must be written out in full.\\ The format of the mnemonics ISBY and GEO is the same as for LDX. ==== ACCUMULATOR FIELD ==== An accumulator field is required in an instruction if it is required in the corresponding PLAN instruction. Except in the shift instructions and NORM, an instruction statement needing an accumulator must contain exactly one digit between 0 and 7, separated from the mnemonic by one or more spaces. No other expression may be used to specify the accumulator field.\\ In the shift instructions and NORM, the accumulator field must be present and may contain either: * One accumulator as described above, when a single-length instruction is compiled, or * Two accumulators, which must be either consecutive digits between 0 and 7 or else 7 and 0 in that order, written adjacent to one another with no intervening spaces; in this case a double-length instruction is compiled. In SUSIN and SUSAR, the accumulator field may be present or absent. If it is present it will be inserted, and if it is absent 2 or 1 respectively will be inserted.\\ The #ACCUMULATOR directive will test whether a character string is a valid accumulator field for an instruction. ==== OPERAND FIELD ==== An operand field is required in an instruction if it is required in the corresponding PLAN instruction. It must consist of a valid GIN expression, but may contain any number of forward references. The value of the expression will be truncated to the appropriate number of bits before it is inserted in the instruction, and no indication is given if this causes bits to be lost. Thus the following are correct and equivalent to each other: LDN 0 4095 LDN 0 -1 LDN 0 8191 If the expression contains forward references, when the references are filled in their values will be truncated in the same way before insertion. GIN does not follow the PLAN practice of inventing a value for identifiers referred to before they are defined, but leaves it to the user to provide the value at his leisure. There is no literal facility in GIN at present. ==== MODIFIER FIELD ==== If an instruction may be modified, the modifier if present must follow the operand expression with no intervening spaces in the form (n) where n is 1, 2 or 3. If the modifier is present, the operand must also be present even if zero - LDX 0 (1) is the same as LDX 0 1 since (1) is treated as a bracketed expression. GIN distinguishes a modifier from a bracketed term in an expression by the fact that "(" follows a term and not an operator.\\ The #MODIFIER directive will check whether a character string is a valid modifier.\\ ==== FORMAT OF INDIVIDUAL INSTRUCTIONS ==== * As a general rule, the format of any instruction is the same as it is in PLAN. The following exceptions exist: * GIN does not recognise literals. * In the instructions ALLOT, CONT, DIS, REL, SUSBY ad SUSDP the form of operarand which consists of two letters and a digit is not available, e.g. <code>PLAN: ALLOT LP3 GIN: ALLOT 3 2</code> * In the AUTO instruction, O is not an acceptable accumulator. (This will be changed in a future version). * In the DISP, DEL and SUSWT instructions, the "2H" form of operand is not available, e.g. <code>PLAN: DEL 2HOK GIN: DEL #5753</code> * In the RRQ instruction, the use of an accumulator other than 0 or 1 is not error-flagged. * The accumulator in SUSAR and SUSIN may be omitted (see ACCUMULATOR FIELD above). * The formats for replaced branch instructions are different (see below). ==== BRANCH INSTRUCTIONS ==== GIN can compile branches in either of two modes. #EXTENDED mode is set when GIN is first loaded, and assumes that the object program will be run in extended branch mode. #ORDINARY mode assumes that the code will be run in direct branch mode. The compilation mode may be changed anywhere in the compilation: e.g. #ENTRY 0 LDN 0 5 GIVE 0 9 STO 0 AMODE ANDN 0 4 #ORD BZE 0 ERROR #EXT 3? contains a code indicating the compilation mode.\\ In #ORDINARY mode, the effect of writing an expression as the operand of a branch is to insert the value of that expression in the bottom 15 bits of the compiled instruction.\\ In #EXTENDED mode, the effect of writing an expression as the operand of a branch is to compile a relative branch; that is, the current transfer address is subtracted from the expression, and the result is inserted in the bottom 14 bits of the compiled instruction. (This result may be positive or negative; bit 10 indicates whether the branch is forwards (B10 unset) or backwards (B10 set).) Alternatively, the expression may be enclosed in parentheses; if this is done, a replaced branch is compiled, that is, bit 9 of the instruction is set and the value of the expression is inserted in the bottom 14 bits of the compiled instruction.\\ Thus in extended branch mode branch instructions can take either of two formats: BRN ALABEL [RELATIVE BRANCH BRN (ALABPTR) [REPLACED BRANCH where ALABPTR is a word whose address is below 16384 containing the address to be branched to: e.g. ALABPTR +ALABEL Source lines in replaced-branch format may not be present when the compilation mode is #ORDINARY. GIN distinguishes the operand of a replaced branch from any other bracketed expression by searching for "(" before entering the evaluation routine, and exiting from it on encountering the last ")".\\ The PLAN4 equivalent of "BRN (ALABPTR)" is "BRN :ALABEL".\\ OBEYing relative branches\\ A particular point arises in connection with relative branch instructions which are the subject of OBEY (023) instructions. If a relative branch is OBEYed, the hardware treats the branch as if it were in the location of the OBEY instruction; for example, if the OBEYed instruction contains 03600002, a branch will occur to two words after the OBEY, and not to two words after the branch instruction. On the other hand, GIN has no way of distinguishing instructions which are the subject of OBEYs, and so compiles the instruction relative to its actual position. It is thus necessary to ensure that the instruction OBEYed will have the desired effect, and the following method will do this: TABLE [LABELS START OF OBEYED TABLE BRN ALAB0+TABLE-OBEY BRN ALAB1+TABLE1-OBEY BRN ALAB2+TABLE2-OBEY . . . OBEY OBEY TABLE(1) or else the following: #ORD TABLE BRN ALAB0-OBEY BRN ALAB1-OBEY BRN ALAB2-OBEY #EXT . . . OBEY OBEY TABLE(1) Provided that TABLE is less than 4096 and that none of the labels is more than 8191 words from OBEY either of these will work successfully.\\ If the table will be obeyed from two or more OBEY instructions something similar must be done by the user's program.\\ Use of £\\ It is not permissible to use the PLAN form *+n or *-n as the operand of a branch; *+1 may be replaced by £, but the others must be replaced by use of an appropriate label. It should be remembered that labels may be used within GIN macros. ==== LITERAL INSTRUCTIONS ==== Where it is desired to use an instruction which GIN does not recognise, the octal instruction code may be inserted, preceded by an apostrophe. GIN will assume that the instruction has the format of an LDX instruction, that is, it expects an accumulator and a 12-bit modifiable operand. For example, '157 0 FRED is the same as PERI 0 FRED '123 7 0 is the same as #75140000 '074 0 BILL is the same as BILLṡ+#03600000 even in extended branch mode.\\ It is also possible to write an instruction mnemonic followed by a literal instruction, If this is done, GIN compiles the literal instruction according to the rules which apply to the mnemonic which preceded it.\\ For example, BRN '174 FRED ) BZE '066 2 FRED ) are all treated as branches CALL '170 0 (J) ) OBEY '033 BUZ is equivalent to STOZ BUZ It is not possible to use this facility with NULL and LFPZ, which have no operands. ==== THE USE OF IDENTIFIERS ==== In PLAN certain restrictive rules apply to the symbolic names which may be used in instructions - that is, branch instructions must refer to labels, others to lower data locations. GIN makes no such distinctions among identifiers, so that it is possible to compile a branch instruction whose operand did not label an instruction, or a non-branch instruction whose operand was (or will be) defined by use as a label. ===== 3.6 Data Constants ===== A data constant is any stored word other than an instruction. There are three main forms of data constant: - Expressions - Character texts - The #HALVES directive Any data constant may be labelled.\\ ==== Expressions ==== Any valid expression may be used as a data constant, and it may contain forward references. If the first term is an identifier, it must be preceded by + or - so that GIN will not treat the expression as a macro.\\ Any number of expressions separated by commas may appear on a source line, as long as the line length does not exceed 72 characters. The expressions will be stored one to a word in consecutive words.\\ GIN does not provide any facilities for the use of sterling constants or of mixed, fractional or floating-point numbers. All these should be set up as the corresponding decimal or octal numbers.\\ Some examples follow: 2:0,0,121,+ALPBUF.3 #73160001 +R2-R1*2 ==== Character texts ==== A character text consists of a decimal integer, followed immediately by the letter H, followed by the characters to be stored. The decimal integer should be such that the character string does not extend past column 72 of the line. The character string may include any character except [ (which is taken to introduce comment), although ← cannot be generated from paper tape input. If the number of characters is not a multiple of 4, the remaining characters are spacefilled. Spaces within the string or at the end of it are stored.\\ It is possible to have several character texts on one source line separated by commas, or to intersperse expression and character texts. Extreme care must be taken to ensure that commas intended to separate strings are not included in them, or vice versa. Particular attention should be given to this when character texts are included in macro source or macro parameters, where the rules as to space suppression can lead to disastrous effects if they are not carefully considered. It is not possible to include a comma in a parameter to a macro. ==== THE #HALVES DIRECTIVE ==== The #HALVES directive takes two parameters, each of which is an expression which may contain forward references. The first expression will be rounded to 12 bits and placed in the top 12 bits of the word, and the second will be rounded to 12 bits and placed in the bottom 12 bits. The directive must be the only thing on its source line, and like other directives must start in column 1. ==== THE #FIDDLE DIRECTIVE ==== The #FIDDLE directive will cause quantities to be added into defined fields of the previous stored word, which may be an instruction or a data constant. Several #FIDDLE directives may follow in succession, and will all affect the same word.\\ There are three parameters, separated by spaces. The first two specify the bits to be affected as the first and last bit to be affected. The third specifies the quantity to be added in to that field. This quantity is added in to the specified bit positions, and any resulting carry to more significant bit positions is lost. (This is not the same as an OR, as carry occurs within the field). This quantity may include forward references.\\ To illustrate the rules about carry, the result of the code: FRED #00002300 #FID 12,17,#67 will be to set the contents of FRED equal to #00001200.\\ For example, the word in GIN containing the version number in the headline to each output page is compiled as follows: 4H 500 [ V500 #FID 12,17,AMAJREVIS [7510 #FID 18,23,AMINREVIS [V513 #SKI EXNOTWANTED [ EXEC VERSION ONLY #FID 0,5,#50 [ X513 where AMAJREVIS=1 and AMINREVIS=3 Note: The format of #FIDDLE, shown above, in which the parameters are separated by commas, is available in GIN513 onwards and will eventually become mandatory. Formerly the parameters were separated by spaces. ==== THE #ENTRY DIRECTIVE ==== The #ENTRY directive is used to set up an entry point in one of the words 20 to 29 of the object program. The parameter is a single decimal digit n, and word 20+n of the program will be set up as a branch to the next word in the segment being compiled. This branch is either direct or relative depending on the current compilation mode.\\ If the base of the main overlay of the program is below word 30 the entry points set up by #ENTRY may be overwritten. ===== 3.7 Selective Compilation ===== One of the facilities of GIN which is most useful in the development of large-scale programs is its ability to select one of a number of alternative parts of the source stream for compilation according to the user's requirements, which he makes known to the compiler by the use of various directives. It is possible either to include or exclude complete segments, or to cause a series of one or more source lines to be ignored. There are two corresponding groups of directives, the #INCLUDE group and the #SKIP group. A further directive, #EXIT, is available in GIN 511 onwards.\\ ==== THE #INCLUDE GROUP ==== As has already been mentioned, all source lines which lead to stored words being inserted in the object program must be within a segment, that is, they must be enclosed between the directives #SEGMENT and #END. __GIN will only compile a segment if it has previously been instructed to do so and given the name of that segment.__\\ A segment is identified by its name (a string of up to 8 letters). There may be several segments of the same name in a source stream, and these are distinguished from one another by a version number (a string of up to 4 digits). GIN is instructed to compile a given segment by the use of the #INCLUDE directive. The user may either specify a version number as well as a segment name or else give the name only.\\ If only the segment name is given, GIN will compile the first segment of that name which is reached, whether or not it has a version number. Later versions of the segment will be ignored.\\ If a version number is given, GIN will compile the first segment of the given name and number that it reaches, and will ignore all other versions of the segment.\\ It is possible to have several #INCLUDEs all specifying the same segment name. In this case, the following rules apply: * If the present #INCLUDE is the first for a given segment name, it will be accepted. * If the present #INCLUDE is the first for a given segment name which specifies a version number, it will be accepted (and the version number will be recorded). * If a #INCLUDE specifying a different version number has been accepted, the present INCLUDE will be rejected and error-flagged. * If a segment of the given name has already been compiled, the present #INCLUDE will be rejected and error-flagged. * In any other case the #INCLUDE will be rejected but not error-flagged. The #EXCLUDE directive instructs GIN to reject and error-flag all #INCLUDEs for a named segment. The #UNXCLUDE directive causes all #EXCLUDE directives to be forgotten, so that #INCLUDE directives can then be compiled for the segments previously #EXCLUDEd.\\ GIN users normally hold the bulk of the source of a GIN program on magnetic tape, and this source will contain #INCLUDE directives for the most reliable or most up-to-date version of each segment required. For development purposes, these default #INCLUDEs may be over-ridden by others which are either provided before the #USE directive which causes the magnetic tape to be used for input or compiled under skips (see below). In some cases it will be required to compile the bulk of a program, but to keep open the option of combining with this compilation any one of a number of versions of a given segment. The user will then insert a #EXCLUDE directive for that segment. At a later stage he will insert a #UNXCLUDE directive; this does not revive the #INCLUDEs which have already been ignored, but he can cause other #INCLUDEs to be compiled. He could also #EXCLUDE some segments again with a view to repeating the process, if there is any prospect of reading unwanted #INCLUDEs.\\ If a segment to be ignored is met, no action is taken on any source line before the next #END. While #END is being searched for, no macros are expanded. In GIN 511 onwards, if input is on magnetic tape no action will be taken on any source line in the same simple subfile after the #SEGMENT, and so it is important that: - No subfile should contain more than one segment. - No segment should cover two or more subfiles. - No code in a subfile after #END should be required if the segment is not compiled (remembering in particular #OVERLAY directives). ==== THE #SKIP GROUP ==== While #INCLUDE controls the selection of complete segments to be compiled, #SKIP and its relatives control the selection of individual records in the input.\\ The directives in the #SKIP group are #SKIP, #STRING, #ACCUMULATOR and #MODIFIER. In each case, depending on the parameter of the directive, following source lines will be ignored or compiled. If the first source line after the directive does not consist of "(" in column 1, that line only will be ignored if the directive takes effect. If the directive is immediately followed by a source line containing "(" in column 1, then if the directive takes effect all lines up to and including a matching ")" will be ignored For the purpose of finding the matching ")", a count of left-hand parentheses is kept, and the ignoring of source is terminated when this equals a count of right-hand parentheses. Thus, skips can be nested. While this process is continuing macros are not expanded, so that the presence of macros containing unpaired parentheses can lead to errors unless great care is taken. In GIN 511 onwards, the end of a magnetic tape subfile will be taken as terminating any current skips; this is so that the accidental omission of a parenthesis cannot cause the whole program to be ignored.\\ It should be noted that any lines which are entirely blank or which have "[" as their first non-space character may be entirely ignored by GIN. If such a line follows immediately after a #SKIP or similar directive which takes effect, either that line or the first non-trivial line may be the one to be ignored. In general, GIN512 and earlier versions ignore the line immediately after #SKIP even if it is blank, but GIN 513 and later versions ignore (or test for "(") the next line containing meaningful text.\\ #SKIP can be used anywhere in the input stream. It takes one parameter, which is an expression containing no forward references. #SKIP will take effect if the value of the expression is zero.\\ #STRING, #ACCUMULATOR and #MODIFIER can only be used non-trivially in macro definitions, since their action depends entirely on the character strings forming their parameters.\\ #STRING will take effect if the two character strings which are its parameters match, in the sense that the characters forming the first string are the same and in the same order as the initial characters of the second string. The number of characters compared is the number of characters in the first string.\\ #ACCUMULATOR will take effect if its parameter is one of the single characters O, 1, 2, 3, 4, 5, 6 or 7.\\ #MODIFIER will take effect if its parameter is one of the single characters 1, 2 or 3.\\ Some of the main uses of the #SKIP facility will be: * To allow different sections of code to be compiled according to identifier settings. For example: #OPT EXTIMP=O #SKI EXTIMP STMOV MOVE 1 BX5>BX6 #SKI EXTIMP<1$1 ( STMOV LDN 0 1 GIVE 0 9 MOVE 1 BX5>BX5 ) where the set of three source lines will be compiled if the identifier EXTIMP is zero or was previously undefined, but if EXTIMP was defined and non-zero the single source line is compiled. Since only one of the alternative sections of code can be compiled, the duplication of the label STMOV causes no difficulty. For any expression, expression<1$1 is zero if and only if expression is non-zero.\\ Another example shows the combination of #SKIP and #OPTIONAL: #SKI KEW ( #DEF AQ=K4+1 #DEF J105=AQ+1 ) #OPT J105=K4+1 where J105 will be set differently according to the value of KEW. * To allow different code to be compiled according to the compiler' s environment: #SKI 11?-9*11? [DISC CODE #SKI 11?-9*11? #SKI [DRUM CODE (where "DRUM CODE" will be compiled if the program file is on device type 0 or 9, and "DISC CODE" otherwise.) #SKI 45?򽸱>#50077$#50077 [IGNORE IF BEFORE GIN510 (where the code depends on the GIN version in use). * To allow a macro to produce different expansions according to what its parameters are: #STRING %A [IGNORED IF %A IS ABSENT #STRING %A,FRED [IGNORED IF THE FIRST 4 CHARACTERS OF %A ARE FRED An example of a rather artificial macro which uses all these directives is given below: #MAC STOREMOD #STR L,%A [THESE PREVENT "S" ERROR IN #OPT ( [IF %A BEGINS WITH L OR D #STR D,%A #OPT %A=0 [SET %A IF NOT ALREADY SET ) #SKIP %A [IGNORE IF %A ZERO ( #ACC %B ( #SKI %B [IGNORE IF %B IS 0 LDX 0 %B [IF %B NOT ACCUMULATOR #MOD %C ( SMO %C [IF %C NOT MODIFIER STO 0 %A ) #MOD %C #SKI STO 0 %A(%C) [ IF %C MODIFIER ) #ACC %B [IF %B IS ACCUMULATOR #SKI ( #MOD %C ( SMO %C STO %B %A ) #MOD %C #SKI STO %B %A(%C) ) ) * It is of course possible to skip #INCLUDEs. Thus a single skip early in the source can be used to leave out large areas later on.\\ ==== #EXIT ==== This directive causes the expansion of a macro to be terminated. See [[gin:chapter5#5.2 Macro Expansion|Section 5.2]] for further details. Last modified: 17/01/2024 11:55by 127.0.0.1 Log In