123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- .\" $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
|