445 lines
16 KiB
Plaintext
445 lines
16 KiB
Plaintext
.\" $Id$
|
|
.nr PD 1v
|
|
.tr ~
|
|
.TL
|
|
Ack Description File
|
|
.br
|
|
Reference Manual
|
|
.AU
|
|
Ed Keizer
|
|
.AI
|
|
Vakgroep Informatica
|
|
Vrije Universiteit
|
|
Amsterdam
|
|
.NH
|
|
Introduction
|
|
.PP
|
|
The program \fIack\fP(I) internally maintains a table of
|
|
possible transformations and a table of string variables.
|
|
The transformation table contains one entry for each possible
|
|
transformation of a file.
|
|
Which transformations are used depends on the suffix of the
|
|
source file.
|
|
Each transformation table entry tells which input suffixes are
|
|
allowed and what suffix/name the output file has.
|
|
When the output file does not already satisfy the request of the
|
|
user (indicated with the flag \fB\-c.suffix\fP), the table is scanned
|
|
starting with the next transformation in the table for another
|
|
transformation that has as input suffix the output suffix of
|
|
the previous transformation.
|
|
A few special transformations are recognized, among them is the
|
|
combiner, which is
|
|
a program combining several files into one.
|
|
When no stop suffix was specified (flag \fB\-c.suffix\fP) \fIack\fP
|
|
stops after executing the combiner with as arguments the \-
|
|
possibly transformed \- input files and libraries.
|
|
\fIAck\fP will only perform the transformations in the order in
|
|
which they are presented in the table.
|
|
.LP
|
|
The string variables are used while creating the argument list
|
|
and program call name for
|
|
a particular transformation.
|
|
.NH
|
|
Which descriptions are used
|
|
.PP
|
|
\fIAck\fP always uses two description files: one to define the
|
|
front-end transformations and one for the machine dependent
|
|
back-end transformations.
|
|
Each description has a name.
|
|
First the way of determining
|
|
the name of the descriptions needed is described.
|
|
.PP
|
|
When the shell environment variable ACKFE is set \fIack\fP uses
|
|
that to determine the front-end table name, otherwise it uses
|
|
\fBfe\fP.
|
|
.PP
|
|
The way the backend table name is determined is more
|
|
convoluted.
|
|
.br
|
|
First, when the last filename in the program call name is not
|
|
one of \fIack\fP or the front-end call-names,
|
|
this filename is used as the backend description name.
|
|
Second, when the \fB\-m\fP is present the \fB\-m\fP is chopped of this
|
|
flag and the rest is used as the backend description name.
|
|
Third, when both failed the shell environment variable ACKM is
|
|
used.
|
|
Last, when also ACKM was not present the default backend is
|
|
used, determined by the definition of ACKM in h/local.h.
|
|
The presence and value of the definition of ACKM is
|
|
determined at compile time of \fIack\fP.
|
|
.PP
|
|
Now, we have the names, but that is only the first step.
|
|
\fIAck\fP stores a few descriptions at compile time.
|
|
This descriptions are simply files read in at compile time.
|
|
At the moment of writing this document, the descriptions
|
|
included are: pdp, fe, i86, m68k2, vax2 and int.
|
|
The name of a description is first searched for internally,
|
|
then in lib/descr/\fIname\fP, then in
|
|
lib/\fIname\fP/descr, and finally in the current
|
|
directory of the user.
|
|
.NH
|
|
Using the description file
|
|
.PP
|
|
Before starting on a narrative of the description file,
|
|
the introduction of a few terms is necessary.
|
|
All these terms are used to describe the scanning of zero
|
|
terminated strings, thereby producing another string or
|
|
sequence of strings.
|
|
.IP Backslashing 5
|
|
.br
|
|
All characters preceded by \e are modified to prevent
|
|
recognition at further scanning.
|
|
This modification is undone before a string is passed to the
|
|
outside world as argument or message.
|
|
When reading the description files the
|
|
sequences \e\e, \e# and \e<newline> have a special meaning.
|
|
\e\e translates to a single \e, \e# translates to a single #
|
|
that is not
|
|
recognized as the start of comment, but can be used in
|
|
recognition and finally, \e<newline> translates to nothing at
|
|
all, thereby allowing continuation lines.
|
|
.nr PD 0
|
|
.IP "Variable replacement"
|
|
.br
|
|
The scan recognizes the sequences {{, {NAME} and {NAME?text}
|
|
Where NAME can be any combination if characters excluding ? and
|
|
} and text may be anything excluding }.
|
|
(~\e} is allowed of course~)
|
|
The first sequence produces an unescaped single {.
|
|
The second produces the contents of the NAME, definitions are
|
|
done by \fIack\fP and in description files.
|
|
When the NAME is not defined an error message is produced on
|
|
the diagnostic output.
|
|
The last sequence produces the contents of NAME if it is
|
|
defined and text otherwise.
|
|
.PP
|
|
.IP "Expression replacement"
|
|
.br
|
|
Syntax: (\fIsuffix sequence\fP:\fIsuffix sequence\fP=\fItext\fP)
|
|
.br
|
|
Example: (.c.p.e:.e=tail_em)
|
|
.br
|
|
If the two suffix sequences have a common member \-~\&.e in this
|
|
case~\- the text is produced.
|
|
When no common member is present the empty string is produced.
|
|
Thus the example given is a constant expression.
|
|
Normally, one of the suffix sequences is produced by variable
|
|
replacement.
|
|
\fIAck\fP sets three variables while performing the diverse
|
|
transformations: HEAD, TAIL and RTS.
|
|
All three variables depend on the properties \fIrts\fP and
|
|
\fIneed\fP from the transformations used.
|
|
Whenever a transformation is used for the first time,
|
|
the text following the \fIneed\fP is appended to both the HEAD and
|
|
TAIL variable.
|
|
The value of the variable RTS is determined by the first
|
|
transformation used with a \fIrts\fP property.
|
|
.IP
|
|
Two runtime flags have effect on the value of one or more of
|
|
these variables.
|
|
The flag \fB\-.suffix\fP has the same effect on these three variables
|
|
as if a file with that \fBsuffix\fP was included in the argument list
|
|
and had to be translated.
|
|
The flag \fB\-r.suffix\fP only has that effect on the TAIL
|
|
variable.
|
|
The program call names \fIacc\fP and \fIcc\fP have the effect
|
|
of an automatic \fB\-.c\fP flag.
|
|
\fIApc\fP and \fIpc\fP have the effect of an automatic \fB\-.p\fP flag.
|
|
.IP "Line splitting"
|
|
.br
|
|
The string is transformed into a sequence of strings by replacing
|
|
the blank space by string separators (nulls).
|
|
.IP "IO replacement"
|
|
.br
|
|
The > in the string is replaced by the output file name.
|
|
The < in the string is replaced by the input file name.
|
|
When multiple input files are present the string is duplicated
|
|
for each input file name.
|
|
.nr PD 1v
|
|
.LP
|
|
Each description is a sequence of variable definitions followed
|
|
by a sequence of transformation definitions.
|
|
Variable definitions use a line each, transformations
|
|
definitions consist of a sequence of lines.
|
|
Empty lines are discarded, as are lines with nothing but
|
|
comment.
|
|
Comment is started by a # character, and continues to the end
|
|
of the line.
|
|
Three special two-characters sequences exist: \e#, \e\e and
|
|
\e<newline>.
|
|
Their effect is described under 'backslashing' above.
|
|
Each \- nonempty \- line starts with a keyword, possibly
|
|
preceded by blank space.
|
|
The keyword can be followed by a further specification.
|
|
The two are separated by blank space.
|
|
.PP
|
|
Variable definitions use the keyword \fIvar\fP and look like this:
|
|
.DS X
|
|
var NAME=text
|
|
.DE
|
|
The name can be any identifier, the text may contain any
|
|
character.
|
|
Blank space before the equal sign is not part of the NAME.
|
|
Blank space after the equal is considered as part of the text.
|
|
The text is scanned for variable replacement before it is
|
|
associated with the variable name.
|
|
.br
|
|
.sp 2
|
|
The start of a transformation definition is indicated by the
|
|
keyword \fIname\fP.
|
|
The last line of such a definition contains the keyword
|
|
\fIend\fP.
|
|
The lines in between associate properties to a transformation
|
|
and may be presented in any order.
|
|
The identifier after the \fIname\fP keyword determines the name
|
|
of the transformation.
|
|
This name is used for debugging and by the \fB\-R\fP flag.
|
|
The keywords are used to specify which input suffices are
|
|
recognized by that transformation,
|
|
the program to run, the arguments to be handed to that program
|
|
and the name or suffix of the resulting output file.
|
|
Two keywords are used to indicate which run-time startoffs and
|
|
libraries are needed.
|
|
The possible keywords are:
|
|
.IP \fIfrom\fP
|
|
.br
|
|
followed by a sequence of suffices.
|
|
Each file with one of these suffices is allowed as input file.
|
|
Preprocessor transformations do not need the \fIfrom\fP
|
|
keyword. All other transformations do.
|
|
.nr PD 0
|
|
.IP \fIto\fP
|
|
.br
|
|
followed by the suffix of the output file name or in the case of a
|
|
linker
|
|
the output file name.
|
|
.IP \fIprogram\fP
|
|
.br
|
|
followed by name of the load file of the program, a pathname most likely
|
|
starts with either a / or {EM}.
|
|
This keyword must be
|
|
present, the remainder of the line
|
|
is subject to backslashing and variable replacement.
|
|
.IP \fImapflag\fP
|
|
.br
|
|
The mapflags are used to grab flags given to \fIack\fP and
|
|
pass them on to a specific transformation.
|
|
This feature uses a few simple pattern matching and replacement
|
|
facilities.
|
|
Multiple occurrences of this keyword are allowed.
|
|
This text following the keyword is
|
|
subjected to backslashing.
|
|
The keyword is followed by a match expression and a variable
|
|
assignment separated by blank space.
|
|
As soon as both description files are read, \fIack\fP looks
|
|
at all transformations in these files to find a match for the
|
|
flags given to \fIack\fP.
|
|
The flags \fB\-m\fP, \fB\-o\fP,
|
|
\fB\-O\fP, \fB\-r\fP, \fB\-v\fP, \fB\-g\fP, \-\fB\-c\fP, \fB\-t\fP,
|
|
\fB\-k\fP, \fB\-R\fP and \-\fB\-.\fP are specific to \fIack\fP and
|
|
not handed down to any transformation.
|
|
The matching is performed in the order in which the entries
|
|
appear in the definition.
|
|
The scanning stops after first match is found.
|
|
When a match is found, the variable assignment is executed.
|
|
A * in the match expression matches any sequence of characters,
|
|
a * in the right hand part of the assignment is
|
|
replaced by the characters matched by
|
|
the * in the expression.
|
|
The right hand part is also subject to variable replacement.
|
|
The variable will probably be used in the program arguments.
|
|
The \fB\-l\fP flags are special,
|
|
the order in which they are presented to \fIack\fP must be
|
|
preserved.
|
|
The identifier LNAME is used in conjunction with the scanning of
|
|
\fB\-l\fP flags.
|
|
The value assigned to LNAME is used to replace the flag.
|
|
The example further on shows the use of all this.
|
|
.IP \fIargs\fP
|
|
.br
|
|
The keyword is followed by the program call arguments.
|
|
It is subject to backslashing, variable replacement, expression
|
|
replacement, line splitting and IO replacement.
|
|
The variables assigned to by \fImapflags\fP will probably be
|
|
used here.
|
|
The flags not recognized by \fIack\fP or any of the transformations
|
|
are passed to the linker and inserted before all other arguments.
|
|
.IP \fIstdin\fP
|
|
.br
|
|
This keyword indicates that the transformation reads from standard input.
|
|
.IP \fIstdout\fP
|
|
.br
|
|
This keyword indicates that the transformation writes on standard output.
|
|
.IP \fIoptimizer\fP
|
|
.br
|
|
The presence of this keyword indicates that this transformation is an optimizer.
|
|
It can be followed by a number, indicating the "level" of the
|
|
optimizer (see description of the -O option in the ack(1ACK) manual page).
|
|
.IP \fIpriority\fP
|
|
.br
|
|
This \-~optional~\- keyword is followed by a number. Positive priority means
|
|
that the transformation is likely to be used, negative priority means that
|
|
the transformation is unlikely to be used.
|
|
Priorities can also be set with a ack(1ACK) command line option.
|
|
Priorities come in handy when there are several implementations of a
|
|
certain transformation. They can then be used to select a default one.
|
|
.IP \fIlinker\fP
|
|
.br
|
|
This keyword indicates that this transformation is the linker.
|
|
.IP \fIcombiner\fP
|
|
.br
|
|
This keyword indicates that this transformation is a combiner. A combiner
|
|
is a program combining several files into one, but is not a linker.
|
|
An example of a combiner is the global optimizer.
|
|
.IP \fIprep\fP
|
|
.br
|
|
This \-~optional~\- keyword is followed an option indicating its relation
|
|
to the preprocessor.
|
|
The possible options are:
|
|
.DS X
|
|
always the input files must be preprocessed
|
|
cond the input files must be preprocessed when starting with #
|
|
is this transformation is the preprocessor
|
|
.DE
|
|
.IP \fIrts\fP
|
|
.br
|
|
This \-~optional~\- keyword indicates that the rest of the line must be
|
|
used to set the variable RTS, if it was not already set.
|
|
Thus the variable RTS is set by the first transformation
|
|
executed which such a property or as a result from \fIack\fP's program
|
|
call name (acc, cc, apc or pc) or by the \fB\-.suffix\fP flag.
|
|
.IP \fIneed\fP
|
|
.br
|
|
This \-~optional~\- keyword indicates that the rest of the line must be
|
|
concatenated to the HEAD and TAIL variables.
|
|
This is done once for every transformation used or indicated
|
|
by one of the program call names mentioned above or indicated
|
|
by the \fB\-.suffix\fP flag.
|
|
.br
|
|
.nr PD 1v
|
|
.NH
|
|
Conventions used in description files
|
|
.PP
|
|
\fIAck\fP reads two description files.
|
|
A few of the variables defined in the machine specific file
|
|
are used by the descriptions of the front-ends.
|
|
Other variables, set by \fIack\fP, are of use to all
|
|
transformations.
|
|
.PP
|
|
\fIAck\fP sets the variable EM to the home directory of the
|
|
Amsterdam Compiler Kit.
|
|
The variable SOURCE is set to the name of the argument that is currently
|
|
being massaged, this is useful for debugging.
|
|
The variable SUFFIX is set to the suffix of the argument that is
|
|
currently being massaged.
|
|
.br
|
|
The variable M indicates the
|
|
directory in lib/{M}/tail_..... and NAME is the string to
|
|
be defined by the preprocessor with \-D{NAME}.
|
|
The definitions of {w}, {s}, {l}, {d}, {f} and {p} indicate
|
|
EM_WSIZE, EM_SSIZE, EM_LSIZE, EM_DSIZE, EM_FSIZE and EM_PSIZE
|
|
respectively.
|
|
.br
|
|
The variable INCLUDES is used as the last argument to \fIcpp\fP.
|
|
It is used to add directories to
|
|
the list of directories containing #include files.
|
|
.PP
|
|
The variables HEAD, TAIL and RTS are set by \fIack\fP and used
|
|
to compose the arguments for the linker.
|
|
.NH
|
|
Example
|
|
.PP
|
|
Description for front-end
|
|
.DS X
|
|
.ta 4n 40n
|
|
name cpp # the C-preprocessor
|
|
# no from, it's governed by the P property
|
|
to .i # result files have suffix i
|
|
program {EM}/lib/cpp # pathname of loadfile
|
|
mapflag \-I* CPP_F={CPP_F?} \-I* # grab \-I.. \-U.. and
|
|
mapflag \-U* CPP_F={CPP_F?} \-U* # \-D.. to use as arguments
|
|
mapflag \-D* CPP_F={CPP_F?} \-D* # in the variable CPP_F
|
|
args {CPP_F?} {INCLUDES?} \-D{NAME} \-DEM_WSIZE={w} \-DEM_PSIZE={p} \e
|
|
\-DEM_SSIZE={s} \-DEM_LSIZE={l} \-DEM_FSIZE={f} \-DEM_DSIZE={d} <
|
|
# The arguments are: first the \-[IUD]...
|
|
# then the include dir's for this machine
|
|
# then the NAME and size values finally
|
|
# followed by the input file name
|
|
stdout # Output on stdout
|
|
prep is # Is preprocessor
|
|
end
|
|
name cem # the C-compiler proper
|
|
from .c # used for files with suffix .c
|
|
to .k # produces compact code files
|
|
program {EM}/lib/em_cem # pathname of loadfile
|
|
mapflag \-p CEM_F={CEM_F?} \-Xp # pass \-p as \-Xp to cem
|
|
mapflag \-L CEM_F={CEM_F?} \-l # pass \-L as \-l to cem
|
|
args \-Vw{w}i{w}p{p}f{f}s{s}l{l}d{d} {CEM_F?}
|
|
# the arguments are the object sizes in
|
|
# the \-V... flag and possibly \-l and \-Xp
|
|
stdin # input from stdin
|
|
stdout # output on stdout
|
|
prep always # use cpp
|
|
rts .c # use the C run-time system
|
|
need .c # use the C libraries
|
|
end
|
|
name decode # make human readable files from compact code
|
|
from .k.m # accept files with suffix .k or .m
|
|
to .e # produce .e files
|
|
program {EM}/lib/em_decode # pathname of loadfile
|
|
args < # the input file name is the only argument
|
|
stdout # the output comes on stdout
|
|
end
|
|
.DE
|
|
|
|
.DS X
|
|
.ta 4n 40n
|
|
Example of a backend, in this case the EM assembler/loader.
|
|
|
|
var w=2 # wordsize 2
|
|
var p=2 # pointersize 2
|
|
var s=2 # short size 2
|
|
var l=4 # long size 4
|
|
var f=4 # float size 4
|
|
var d=8 # double size 8
|
|
var M=em22
|
|
var NAME=em22 # for cpp (NAME=em22 results in #define em22 1)
|
|
var LIB=lib/{M}/tail_ # part of file name for libraries
|
|
var RT=lib/{M}/head_ # part of file name for run-time startoff
|
|
var SIZE_FLAG=\-sm # default internal table size flag
|
|
var INCLUDES=\-I{EM}/include # use {EM}/include for #include files
|
|
name asld # Assembler/loader
|
|
from .k.m.a # accepts compact code and archives
|
|
to e.out # output file name
|
|
program {EM}/lib/em_ass # load file pathname
|
|
mapflag \-l* LNAME={EM}/{LIB}* # e.g. \-ly becomes
|
|
# {EM}/mach/int/lib/tail_y
|
|
mapflag \-+* ASS_F={ASS_F?} \-+* # recognize \-+ and \-\-
|
|
mapflag \-\-* ASS_F={ASS_F?} \-\-*
|
|
mapflag \-s* SIZE_FLAG=\-s* # overwrite old value of SIZE_FLAG
|
|
args {SIZE_FLAG} \e
|
|
({RTS}:.c={EM}/{RT}cc) ({RTS}:.p={EM}/{RT}pc) \-o > < \e
|
|
(.p:{TAIL}={EM}/{LIB}pc) \e
|
|
(.c:{TAIL}={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g) \e
|
|
(.c.p:{TAIL}={EM}/{LIB}mon)
|
|
# \-s[sml] must be first argument
|
|
# the next line contains the choice for head_cc or head_pc
|
|
# and the specification of in- and output.
|
|
# the last three args lines choose libraries
|
|
linker
|
|
end
|
|
.DE
|
|
|
|
The command \fIack \-mem22 \-v \-v \-I../h \-L \-ly prog.c\fP
|
|
would result in the following
|
|
calls (with exec(II)):
|
|
.DS X
|
|
.ta 4n
|
|
1) /lib/cpp \-I../h \-I/usr/em/include \-Dem22 \-DEM_WSIZE=2 \-DEM_PSIZE=2 \e
|
|
\-DEM_SSIZE=2 \-DEM_LSIZE=4 \-DEM_FSIZE=4 \-DEM_DSIZE=8 prog.c
|
|
2) /usr/em/lib/em_cem \-Vw2i2p2f4s2l4d8 \-l
|
|
3) /usr/em/lib/em_ass \-sm /usr/em/lib/em22/head_cc \-o e.out prog.k
|
|
/usr/em/lib/em22/tail_y /usr/em/lib/em22/tail_cc.1s
|
|
/usr/em/lib/em22/tail_cc.2g /usr/em/lib/em22/tail_mon
|
|
.DE
|