Example commands:-
IMP MYPROG
IMP PARSER-LIST
IMP PROG2-NOCHECK-NODIAG
Unless -NOEDIT is specified, the compiler works in tandem with the editor. On detection of a fault, control is passed to the editor with the file pointer at the fault position. Corrective action may be taken, or not as wished, then %c (or keypad ',') to resume.
Error reports are directed to the terminal (as well as the listing file). Line-numbering continues through any included files.
Unless otherwise directed, the Compiler generates an object file with the same name as the source file and extension MOB (for Motorola object). The object file is eligible for execution by citing the name as a command verb.
For example, the system command IMP MYFIRST calls for the source file "MYFIRST" (no extension) to be compiled as an IMP program, creating the file "MYFIRST.MOB". On successful completion of the compilation, the command "MYFIRST ...." becomes available as a command, and causes the object program to be loaded and entered.
The main options are given below. Those not yet implemented are marked with an asterisk, and those only partially implemented with a query. In the case of the yes/no options, the option is suppressed by selecting the keyword prefixed with "NO".
Source listing control:
-LFILE=<filename> send listing to specified file
(extension LIS added)
-LFILE=LP: send listing to network printer
-LIST produce source file listing
-- if no LFILE specified, then to
a file with same name as source
and extension LIS added
Default: -NOLIST
-LOG output statistics indicating number of statements,
atoms per statement, identifiers per statement,
time taken, etc.
Default: -NOLOG
Object program control:
-OFILE=<filename> produce object file with specified name
(extension MOB added)
-OFILE=:N do not produce object file
Default: produce object file with same name as source and extension MOB
-FORCE produce object file even if program faulty
Default: -NOFORCE
Run-time checks:
? -ASS include unassigned check on full integers
? -STRASS include unassigned check on strings
? -SASS include unassigned check on shorts
? -BASS include unassigned check on bytes
-ARR include array bound checking
* -LOOP include %for loop check
* -OVER include overflow check
* -CAP include capacity checking
Default: -ASS-STRASS-NOSASS-NOBASS-ARR-LOOP-OVER-CAP
-NOCHECK has the effect of suppressing all checks
Run-time diagnostics:
-DIAG include line-number updating for diagnostics
-TRACE generate code which allows the program to
be executed one line at a time under the
control of the Software Front Panel
Default: -DIAG-NOTRACE
Features of IMP77 which are not valid in IMP80 (EMAS IMP) and conversely, or which are peculiar to this implementation, are reported as 'non-standard' (warning only). However, this warning is not produced for the following widely used IMP77 facilities, even though they are not available in IMP80:
%shortintegers, %predicates, %else %if,
the operator mod-sign,
initialisation of dynamic variables to literal values
(but initialisation to non-literal values is flagged).
. full diagnostics and %monitor
. procedures as parameters
. NEW and DISPOSE
. %string(*)%array%name variables
. %array %name parameters must have bounds specified in the declaration
in one of the following ways:
all literal bounds eg %byteintegerarrayname A(0:31)
one or more indefinite bounds eg %integerarrayname B,C(1:*)
[Note that in the second example, all actual parameters for B,C
must have the same upper bound. Cf B(1:*),C(1:*)]
The Vax IMP form in which the keyword %array is followed by the
number of dimensions in parentheses is also accepted:
eg %integerarray(1)%name A == %integerarrayname A(*:*)
%shortarray(2)%name B == %shortarrayname B(*:*,*:*)
However, if this form is used, the number must be included even
for the one-dimensional case (cf Vax IMP which allows omission
in this case).
. the low-level pointer-relative facility (see Section 9) differs from
the version of this implemented in the current Vax compiler
. %on %event * as a way of trapping all events is not supported
. line-breaks following %and and %or are not ignored
. there is no built-in function TYPEOF
. untyped %name parameters are usable only to supply an address,
not type or length information; the built-in function SIZEOF
is not applicable to such parameters
. the Compiler is stricter about the ordering of statements
than the Vax IMP Compiler. The normal ordering in any block
should be declarations, then event trap if any, then instructions.
It is acceptable for static declarations, of procedures and %own
variables, to be interspersed among instructions, but the Compiler
queries any dynamic variable declarations which appear after
instructions, and hard-faults any which appear in a loop or after a
sequence change.
See also the restrictions noted in the section on externals
. non-decimal constants expressed in IBM style (X'...')
. Atlas Autocode style of %for loop (without %for)
Error reports are kept short to economise on screen space. For reports which relate to a particular component of a statement, the culprit is identified by a marker at the start of the component.
REPORT MEANING
Faulty form statement part indicated is syntactically faulty
Unknown atom lexical atom indicated is mis-spelt or unknown
Non-starter atom at the start of the statement is not a
possible statement introducer
Unknown name identifier indicated has not been declared
Duplicate identifier indicated has already been declared
Mismatch parameters in body of procedure do not match spec
Not variable operand in assignment context is not a variable
Not reference operand in pointer context is not a reference
Wrong type expression is of wrong type for context
Wrong class category of identifier is wrong for context
Not literal expression in literal context is not literal
Inside out upper bound is less than lower
Endless loop literal %for loop cannot terminate
Out of range operand value is out of range
Too few args too few arguments are given for procedure call
Too many args too many arguments are given for procedure call
Not in loop %exit %or %continue is not within a loop construct
Not in routine %return is not within a routine
Not in fn/map %result is not within a function or map
Not in pred %true/%false is not within a predicate
%CYCLE missing %repeat encountered with no matching %cycle
%REPEAT missing %end reached with unmatched %cycle
%START missing %finish or %else encountered with no matching %start
%FINISH missing %end reached with unmatched %start
Extra %ELSE %else encountered matching earlier unconditional %else
%BEGIN missing %end encountered with no matching %begin or
procedure header
%END missing %end %of %program or %file reached with unmatched
%begin or procedure header
%RESULT missing there is apparently a path to the end of a function
or map which does not specify a result
Not accessible instruction apparently cannot be executed (warning only)
Out of order statement appears in incorrect order in block
(warning if benign)
Nonstandard non-standard language feature (warning only)
<ident> void identifier is used before a value is assigned to it
(warning only)
<ident> missing forward label or specced identifier does not appear
in block
<ident>(?) missing switch label to which there is an explicit jump
has not been specified
<n> extra values for <ident>
too many values for %const or %own array
Faulty operand incorrect operand type for machine instruction
Wrong size operand is of incorrect size for machine instruction
Too complex! compiler limitation exceeded
Not in yet! language feature not supported in current compiler
Out of reach! %const or literal string, record or array is not
within the range of the machine addressing capability
<ident> Out of reach!
call to procedure specified is not within the
range of the machine addressing capability
Internal error <n>! compiler fault
Disastrous errors
These reports relate to compiler limits being exceeded. They all cause
compilation to be abandoned.
Program too big total size of the compiled code and constants
exceeds the maximum allowed for
Program space exhausted size of the code for currently open blocks
exceeds the maximum allowed for
Identifier space exhausted total length of all identifiers currently
in scope exceeds the maximum permitted
Too many identifiers number of identifiers currently in scope
exceeds the maximum permitted
Too many levels depth of textual nesting of blocks exceeds
the maximum permitted
Too many owns space required for %own variable
initialisation exceeds the maximum permitted
Too many literals internal storage space for literals is exhausted
Input ended there is no %endofprogram statement
. The maximum depth of textual nesting is 7.
. The total size of the static data area (for owns/externals) is
limited to 32k bytes.
. The size of the code area (for program and constants) is limited
to 64k bytes. In addition, there is no escape from the machine
imposed reach of +-32k bytes for accesses to constants.
The compiler does attempt to cater automatically for procedure calls
which would otherwise run into this limitation, but is not
guaranteed to succeed.
The compiler report 'Out of reach!' indicates that one of these
limits has been breached. If a name is given, it is that of a
procedure; if no name is given, the problem is access to a constant.
. In the absence of floating-point hardware, all floating-point
operations are performed by software.
. Integer multiply and divide are also performed by software, although
multiplication by a literal power of 2 or sum of two powers of 2
is optimised. This optimisation is also performed for array
accesses where the element size meets the condition stated (with
array bound checks off).
. Accesses to arrays (including accesses via array names) are more
efficient if at least the lower bound is a literal (and for
multi-dimensional arrays if all the inner bounds are literal)
A program module containing external procedures or variables, and terminated by
endoffile, is compiled in the ordinary way, eg IMP MYLIB. Before the externals
it contains can be accessed, the compiled module must be installed by the
INSTALL command. The INSTALL command takes as parameter the name of a program
file (extension MOB assumed) -- or list of names separated by commas. For
example INSTALL MYLIB. The effect of installing a program file is to add all
the external names it contains to the external symbol table; the code of the
module is not loaded at this stage. Thereafter (until logoff) these names are
available for external linking, which is done automatically when a program
referencing any of the names is loaded. It is only necessary to re-install a
program file if a change is made to the external names it contains.
An external name is the identifier declared as external (standardised to space-free lower-case form) unless this is over-ridden by an alias, in which case the alias name is used instead (exactly as presented). Note that an alias over-rides the declared identifier, rather than providing an alternative to it.
The system command HELP LIB gives information about generally available libraries.
1. Names are truncated to 11 characters for purposes of matching as externals
(temporary restriction).
2. The type checking is nominal (temporary amnesty).
3. External %name variables are not supported (temporary restriction).
4. External specs must all be at the top program level, that is, they may not
appear within procedures or inner blocks.
5. An external spec for a procedure may be satisfied by a procedure occurring
later in the same module, but the same is not true for variables.
6. Externals may not be combined with a main program (%begin ...
%endofprogram).
CAUTION: The form of external linkage in V2.0 onwards will differ from this interim form, necessitating re-compilation.
%integermap INTEGER(%integer a)
%realmap REAL(%integer a)
%string(*)%map STRING(%integer a)
%record(*)%map RECORD(%integer a)
%bytemap BYTEINTEGER(%integer a)
%shortmap SHORTINTEGER(%integer a)
%bytemap LENGTH(%string(*)%name s)
%bytemap CHARNO(%string(*)%name s, %integer n)
%integerfn ADDR(%name n)
%string(1)%fn TOSTRING(%integer k)
%string(255)%fn SUBSTRING(%string(255) s, %integer from,to)
%integerfn REM(%integer a,b)
%integerfn INTPT(%real x)
%integerfn INT(%real x)
%realfn FRACPT(%real x)
%realfn SQRT(%real x)
%string(8)%fn DATE
%string(5)%fn TIME
%integerfn CPUTIME
!in milliseconds (actually elapsed time at present)
%record(*) NIL
%recordformat EVENTFM(%integer event,sub,extra,pc,
%string(255) message,%integerarray r(0:15))
!PC and R are APM-specific extensions
%record(eventfm) EVENT
%constinteger NL
%integerfn NEXTSYMBOL
%routine READSYMBOL(%name n)
%routine PRINTSYMBOL(%integer k)
%routine SKIPSYMBOL
%routine PRINTSTRING(%string(255) s)
%routine READ(%name n)
%routine WRITE(%integer m, n)
%routine PRINT(%real x, %integer n,m)
%routine PRINTFL(%real x, %integer n)
%routine NEWLINE
%routine NEWLINES(%integer i)
%routine SPACE
%routine SPACES(%integer i)
%routine SELECTINPUT(%integer n)
%routine SELECTOUTPUT(%integer n)
%routine RESET INPUT
%routine RESET OUTPUT
%routine CLOSE INPUT
%routine CLOSE OUTPUT
%integerfn INSTREAM
%integerfn OUTSTREAM
%routine OPEN INPUT(%integer n, %string(31) S)
!*selects N at present*
%routine OPEN OUTPUT(%integer n, %string(31) S)
!*selects N at present*
%routine PROMPT(%string(31) S)
%integerfn TESTSYMBOL
!*APM specific*
!value is -1 if no symbol available from terminal
!otherwise value is the symbol, which is skipped
%constinteger NOECHO,NOTERMECHO,SINGLE,NOPAGE
%routine SET TERMINAL MODE(%integer m)
!*APM specific*
!set terminal mode as specified by M (sum of flags)
As a system implementation language IMP provides a number of facilities which permit access to parts of the system other languages do not reach. The store-mapping functions (INTEGER, BYTEINTEGER, etc) allow for direct addressing using machine addresses; the name-relative indexing facility (as in CUR
[1] or POS[-2]) extends the capability of %name variables; the fixed-address declaration facility (as in @16_200 %integer TIMER, KBIN, KBOUT) allows efficient source-level access to specific areas of store.
The use of these facilities involves some loss of the protection normally conferred by a high-level language and a potential (particularly on a processor without hardware protection) for uncontrolled malfunction. They should, therefore, be used with restraint and care.
Sequences of assembly language instructions may be incorporated in an IMP program at any point. At present no enabling directive is required. Apart from the usual hazards of machine level programming, there is the danger of corrupting the environment pre-supposed by the high-level facilities. For this reason, it is sensible to keep the use of these instructions to a minimum and to take particular care in programming these sections.
Assembly language instructions are distinguished from IMP statements by being prefaced by an asterisk (eg *MOVE D0,D1). They appear within IMP blocks and procedures and are executed according to the normal flow of control, subject to any control transfers invoked by the instructions themselves. IMP conventions for statement termination, labelling and commenting apply, but otherwise the form of instruction follows closely that defined under the heading of Assembler Syntax for each individual instruction in the Motorola M68000 manual. Machine-level operands are specified using the mnemonics D0-D7 and A0-A7 (or SP), and the standard syntax for <ea> modes. Immediate and Address register variants of op-codes are selected automatically. By comparison with full Assembler, most of the directives do not apply; assembly-time expression evaluation is restricted; size specification in cases where the size is implicit in the op-code is not in general allowed; the indexed PC-relative mode is not supported, nor is the 'current location counter'.
The error report 'Faulty operand' indicates use of an invalid operand for the context, but the compiler does not fully check the validity of <ea> modes for the particular instruction.
NB the default 'size' applied is Long (32-bits) rather than Word (16-bits) which is the manufacturer's default. It is sensible to make a practice of including the size suffix explicitly for all relevant instructions.
The special mnemonics USP (User Stack Pointer), SR (Status Register) and CCR (Condition Code Register) are NOT supported but the relevant effects can be achieved by use of the additional op-codes:
MTCCR <ea> for MOVE <ea>,CCR MTSR <ea> for MOVE <ea>,SR MFSR <ea> for MOVE SR,<ea> MTUSP An for MOVE An,USP MFUSP An for MOVE USP,An ATCCR #<data> for AND #<data>,CCR ATSR #<data> for AND #<data>,SR ETCCR #<data> for EOR #<data>,CCR ETSR #<data> for EOR #<data>,SR OTCCR #<data> for OR #<data>,CCR OTSR #<data> for OR #<data>,SR
IMP identifiers may also be used as operands for assembly language instructions. The detailed implications of this over the whole range of data types are fairly complex and subject to change. The following cases are reasonably straightforward and stable. Scalar variables may be used as <ea> operands provided that they are:
declared as own or
declared at the outermost level or
declared at the current level or
declared by means of a fixed-address declaration
Variables declared at intermediate levels should not be accessed. In the case of a name variable the reference is to the pointer value (32-bit address) rather than the referenced object. At present it is not possible to access record fields in assembly language instructions.
Labels and procedure names may be referenced in the Branch group of instructions, including BSR. The only alternative form of operand for these instructions is immediate (eg *BLT #-4), the value specified being the machine-level displacement. Short and long branches are handled automatically (though the Compiler's CODE listing does not show this). To access a forward label in an assembly language instruction, it is neccesary for the label to have been declared by means of the IMP declaration %LABEL <lab>.
The registers D0-D3 and A0-A3 may be freely used within assembly sections, but no assumptions can be made about their contents after execution of most IMP statements. Other registers may be used only on the basis that their values are restored before reverting to IMP. In particular this applies to SP. In addition, NOTE WELL that the accessing of local variables depends on SP; if SP is changed, access to such variables in machine instructions becomes a nonsense (though no error report can be made). Similarly, any modification of A4-A6 rules out access to non-local variables.
Note that any declaration of IMP identifiers which co-incide with the register mnemonics takes precedence.
%on %event <eventno>, <eventno>, ..... %start
...
finish
"%event" is optional in the statement above. Once the event has been trapped, further information may be obtained by interrogating the built-in record EVENT..
%recordformat eventfm(%byte event,sub,%short line,%integer extra,
%string(255)message,%integerarray r(0:15))
IMP and PASCAL share a common set of Event numbers. HELP EVENTS gives a table of these.
. Statements like "%if COND %then %result = EXP1 %else %result = EXP2"
"%if COND %then %return %else ...
"%if COND %then %true/%false %else ...
"%if COND %then ->LAB %else ...
are liable to be mis-compiled. Fix: change "%else" to ";".
. run-time checks are not imposed on capacity, overflow for addition
and subtraction, invalid %for loops or stack over-run
. The %include construction cannot currently be nested i.e. %included files
should not contain %includes. This restriction has been lifted in versions
of IMP for the new operating system.
This software is frozen. It may be possible to fix bugs in the run-time libraries but any faults found in the compiler will have to be programmed around.
view:impv1 printed on 01/03/89 at 16.15