fixup commit for tag 'release-6-0-pre-4'

This commit is contained in:
cvs2hg 2010-08-04 18:04:08 +00:00
parent 9d2d5606ea
commit 7273130b4c
674 changed files with 0 additions and 45828 deletions

View file

@ -1,3 +0,0 @@
p=/proj/em/Work
sh TakeAction 'make distr' $p/distr/Action
sh TakeAction 'make distr' $p/distr/Action1

View file

@ -1,35 +0,0 @@
cmp: # compile everything and compare
(cd etc ; make cmp )
(cd util ; make cmp )
(cd lang ; make cmp )
(cd mach ; make cmp )
install: # compile everything to machine code
(cd etc ; make install )
(cd util ; make install )
(cd lang/cem ; make install )
(cd mach ; make install )
(cd lang/pc ; make install )
clean: # remove all non-sources, except boot-files
(cd doc ; make clean )
(cd man ; make clean )
(cd h ; make clean )
(cd etc ; make clean )
(cd util ; make clean )
(cd lang ; make clean )
(cd mach ; make clean )
opr: # print all sources
make pr | opr
pr: # print all sources
@( pr Makefile ; \
(cd doc ; make pr ) ; \
(cd man ; make pr ) ; \
(cd h ; make pr ) ; \
(cd etc ; make pr ) ; \
(cd lang ; make pr ) ; \
(cd util ; make pr ) ; \
(cd mach ; make pr ) \
)

View file

@ -1 +0,0 @@
exec /usr/em/doc/em/int/em /usr/em/doc/em/int/tables ${1-e.out} core

View file

@ -1,3 +0,0 @@
name "EM tables"
dir etc
end

View file

@ -1,16 +0,0 @@
name "m68k2/cg bootstrap files"
dir mach/m68k2/cg
action "make EMHOME=/proj/em/Work distr"
end
name "vax4/cg bootstrap files"
dir mach/vax4/cg
action "make EMHOME=/proj/em/Work distr"
end
name "m68020/ncg bootstrap files"
dir mach/m68020/ncg
action "make EMHOME=/proj/em/Work distr"
end
name "m68k4/cg bootstrap files"
dir mach/m68k4/cg
action "make EMHOME=/proj/em/Work distr"
end

View file

@ -1,26 +0,0 @@
-- ./doc/install.pr no RCS file
-- ./h/em_mnem.h no RCS file
-- ./h/em_pseu.h no RCS file
-- ./h/em_spec.h no RCS file
-- ./lang/basic/src/y.tab.c no RCS file
-- ./lang/basic/src/y.tab.h no RCS file
-- ./lang/pc/pem/pem22.m no RCS file
-- ./lang/pc/pem/pem24.m no RCS file
-- ./lang/pc/pem/pem44.m no RCS file
-- ./lib/LLgen/incl no RCS file
-- ./lib/LLgen/rec no RCS file
-- ./mach/m68k2/cg/tables1.c no RCS file
-- ./mach/m68k2/cg/tables1.h no RCS file
-- ./mach/m68020/ncg/tables1.c no RCS file
-- ./mach/m68020/ncg/tables1.h no RCS file
-- ./mach/vax4/cg/tables1.c no RCS file
-- ./mach/vax4/cg/tables1.h no RCS file
-- ./util/LLgen/src/parser no RCS file
-- ./util/LLgen/src/LLgen.c no RCS file
-- ./util/LLgen/src/Lpars.c no RCS file
-- ./util/LLgen/src/Lpars.h no RCS file
-- ./util/LLgen/src/tokens.c no RCS file
-- ./util/data/em_flag.c no RCS file
-- ./util/data/em_mnem.c no RCS file
-- ./util/data/em_pseu.c no RCS file
-- ./util/ego/share/pop_push.h no RCS file

View file

@ -1 +0,0 @@
cp .distr $DESTDIR/$1

View file

@ -1,6 +0,0 @@
PIC=pic
TBL=tbl
REFER=refer
../ceg.doc: ceg.tr ceg.ref
$(PIC) ceg.tr | $(REFER) -e -p ceg.ref | $(TBL) > $@

View file

@ -1,284 +0,0 @@
.TL
Code Expander
.br
(proposal)
.SH
Introduction
.LP
The \fBcode expander\fR, \fBce\fR, is a program that translates EM-code to
objectcode. The main goal is to translate very fast. \fBce\fR is an instance
of the EM_CODE(3L)-interface. During execution of \fBce\fR, \fBce\fR will build
in core a machine independent objectfile ( NEW A.OUT(5L)). With \fBcv\fR or
with routines supplied by the user the machine independent objectcode will
be converted to a machine dependent object code. \fBce\fR needs
information about the targetmachine (e.g. the opcode's). We divide the
information into two parts:
.IP
- The description in assembly instructions of EM-code instructions.
.IP
- The description in objectcode of assembly instructions.
.LP
With these two tables we can make a \fBcode expander generator\fR which
generates a \fBce\fR. It is possible to put the information in one table
but that will probably introduce (propable) more bugs in the table. So we
divide and conquer. With this approach it is also possible to generate
assembly code ( rather yhan objectcode), wich is useful for debugging.
There is of course a link between the two tables, the link
consist of a restriction on the assembly format. Every assembly
instruction must have the following format:
.sp
INSTR ::= LABEL : MNEMONIC [ OPERAND ( "," OPERAND)* ]
.sp
.LP
\fBCeg\fR uses the following algorithm:
.IP \0\0a)
The assembly table will be converted to a (C-)routine assemble().
assemble() gets as argument a string, the assembler instruction,
and can use the MNEMONIC to execute the corresponding action in the
assembly table.
.IP \0\0b)
The routine assemble() can now be used to convert the EM-code table to
a set of C-routines, wich together form an instance of the
EM_CODE(3L).
.SH
The EM-instruction table
.LP
We use the following grammar:
.sp
.TS
center box ;
l.
TABLE ::= (ROW)*
ROW ::= C_instr ( SPECIAL | SIMPLE)
SPECIAL ::= ( CONDITION SIMPLE)+ 'default' SIMPLE
SIMPLE ::= '==>' ACTIONLIST | '::=' ACTIONLIST
ACTIONLIST ::= [ ACTION ( ';' ACTION)* ] '.'
ACTION ::= function-call | assembly-instruction
.TE
.LP
An example for the 8086:
.LP
.DS
C_lxl
$arg1 == 0 ==> "push bp".
$arg1 == 1 ==> "push EM_BSIZE(bp)".
default ==> "mov cx, $arg1";
"mov si, bp";
"1: mov si, EM_BSIZE(si);
"loop 1b"
"push si".
.DE
.sp
Some remarks:
.sp
* The C_instr is a function indentifier in the EM_CODE(3L)-interface.
.LP
* CONDITION is a "boolean" C-expression.
.LP
* The arguments of an EM-instruction can be used in CONDITION and in assembly
instructions. They are referred by $arg\fIi\fR. \fBceg\fR modifies the
arguments as follows:
.IP \0\0-
For local variables at positive offsets it increases this offset by EM_BSIZE
.IP \0\0-
It makes names en labels unique. The user must supply the formats (see mach.h).
.LP
* function-call is allowed to implement e.g. push/pop optimization.
For example:
.LP
.DS
C_adi
$arg1 == 2 ==> combine( "pop ax");
combine( "pop bx");
"add ax, bx";
save( "push ax").
default ==> arg_error( "C_adi", $arg1).
.DE
.LP
* The C-functions called in the EM-instructions table have to use the routine
assemble()/gen?(). "assembler-instr" is in fact assemble( "assembler-instr").
.LP
* \fBceg\fR takes care not only about the conversions of arguments but also
about
changes between segments. There are situation when one doesn't want
conversion of arguments. This can be done by using ::= in stead of ==>.
This is usefull when two C_instr are equivalent. For example:
.IP
C_slu ::= C_sli( $arg1)
.LP
* There are EM-CODE instructions wich are machine independent (e.g. C_open()).
For these EM_CODE instructions \fBceg\fR will generate \fIdefault\fR-
instructions. There is one exception: in the case of C_pro() the tablewriter
has to supply a function prolog().
.LP
* Also the EM-pseudoinstructions C_bss_\fIcstp\fR(), C_hol_\fIcstp\fR(),
C_con_\fIcstp\fR() and C_rom_\fIcstp\fR can be translated automaticly.
\fBceg\fR only has to know how to interpretate string-constants:
.DS
\&..icon $arg2 == 1 ==> gen1( (char) atoi( $arg1))
$arg2 == 2 ==> gen2( atoi( $arg1))
$arg2 == 4 ==> gen4( atol( $arg1))
\&..ucon $arg2 == 1 ==> gen1( (char) atoi( $arg1))
$arg2 == 2 ==> gen2( atoi( $arg1))
$arg2 == 4 ==> gen4( atol( $arg1))
\&..fcon ::= not_implemented( "..fcon")
.DE
.LP
* Still, life can be made easier for the tablewriter; For the routines wich
he/she didn't implement \fBceg\fR will generate a default instruction wich
generates an error-message. \fBceg\fR seems to generate :
.IP
C_xxx ::= not_implemented( "C_xxx")
.SH
The assembly table
.LP
How to map assembly on objectcode.
.LP
Each row in the table consists of two fields, one field for the assembly
instruction, the other field for the corresponding objectcode. The tablewriter
can use the following primitives to generate code for the machine
instructions :
.IP "\0\0gen1( b)\0\0:" 17
generates one byte in de machine independent objectfile.
.IP "\0\0gen2( w)\0\0:" 17
generates one word ( = two bytes), the table writer can change the byte
order by setting the flag BYTES_REVERSED.
.IP "\0\0gen4( l)\0\0:" 17
generates two words ( = four bytes), the table writer can change the word
order by setting the flag WORDS_REVERSED.
.IP "\0\0reloc( n, o, r)\0\0:" 17
generates relocation information for a label ( = name + offset +
relocationtype).
.LP
Besides these primitives the table writer may use his self written
C-functions. This allows the table writer e.g. to write functions to set
bitfields within a byte.
.LP
There are more or less two methods to encode the assembly instructions:
.IP \0\0a)
MNEMONIC and OPERAND('s) are encoded independently of each other. This can be
done when the target machine has an orthogonal instruction set (e.g. pdp-11).
.IP \0\0b)
MNEMONIC and OPERAND('s) together determine the opcode. In this case the
assembler often uses overloading: one MNEMONIC is used for several
different machine-instructions. For example : (8086)
.br
mov ax, bx
.br
mov ax, variable
.br
These instructions have different opcodes.
.LP
As the transformation MNEMONIC-OPCODE is not one to
one the table writer must be allowed to put restrictions on the operands.
This can be done with type declarations. For example:
.LP
.DS
mov dst:REG, src:MEM ==>
gen1( 0x8b);
modRM( op2.reg, op1);
.DE
.DS
mov dst:REG, src:REG ==>
gen1( 0x89);
modRM( op2.reg, op1);
.DE
.LP
modRM() is a function written by the tablewriter and is used to encode
the operands. This frees the table writer of endless typing.
.LP
The table writer has to do the "typechecking" by himself. But typechecking
is almost the same as operand decoding. So it's more efficient to do this
in one function. We now have all the tools to describe the function
assemble().
.IP
assemble() first calls the function
decode_operand() ( by the table writer written), with two arguments: a
string ( the operand) and a
pointer to a struct. The struct is declared by the table writer and must
consist of at least a field called type. ( the other fields in the struct can
be used to remember information about the decoded operand.) Now assemble()
fires a row wich is selected by mapping the MNEMONIC and the type of the
operands.
.br
In the second field of a row there may be references to other
fields in the struct (e.g. op2.reg in the example above).
.LP
We ignored one problem. It's possible when the operands are encoded, that
not everything is known. For example $arg\fIi\fR arguments in the
EM-instruction table get their value at runtime. This problem is solved by
introducing a function eval(). eval() has a string as argument and returns
an arith. The string consists of constants and/or $arg\fIi\fR's and the value
returned by eval() is the value of the string. To encode the $arg\fIi\fR's
in as few bytes as possible the table writer can use the statements %if,
%else and %endif. They can be used in the same manner as #if, #else and
#endif in C and result in a runtime test. An example :
.LP
.DS
-- Some rows of the assembly table
mov dst:REG, src:DATA ==>
%if sfit( eval( src), 8) /* does the immediate-data fit in 1 byte? */
R53( 0x16 , op1.reg);
gen1( eval( src));
%else
R53( 0x17 , op1.reg);
gen2( eval( src));
%endif
.LD
mov dst:REG, src:REG ==>
gen1( 0x8b);
modRM( op1.reg, op2);
.DE
.DS
-- The corresponding part in the function assemble() :
case MNEM_mov :
decode_operand( arg1, &op1);
decode_operand( arg2, &op2);
if ( REG( op1.type) && DATA( op2.type)) {
printf( "if ( sfit( %s, 8)) {\\\\n", eval( src));
R53( 0x16 , op1.reg);
printf( "gen1( %s)\\\\n", eval( arg2));
printf( "}\\\\nelse {\\\\n");
R53( 0x17 , op1.reg);
printf( "gen2( %s)\\\\n", eval( arg2));
printf( "}\\\\n");
}
else if ( REG( op1.type) && REG( op2.type)) {
gen1( 0x8b);
modRM( op1.reg, op2);
}
.DE
.DS
-- Some rows of the right part of the EM-instruction table are translated
-- in the following C-functions.
"mov ax, $arg1" ==>
if ( sfit( w, 8)) { /* w is the actual argument of C_xxx( w) */
gen1( 176); /* R53() */
gen1( w);
}
else {
gen1( 184);
gen2( w);
}
.LD
"mov ax, bx" ==>
gen1( 138);
gen1( 99); /* modRM() */
.DE
.SH
Restrictions
.LP
.IP \0\01)
The EM-instructions C_exc() is not implemented.
.IP \0\03)
All messages are ignored.

View file

@ -1,276 +0,0 @@
.TL
A prototype Code expander
.NH
Introduction
.PP
A program to be compiled with ACK is first fed into the preprocessor.
The output of the preprocessor goes into the appropiate front end,
whose job it is to produce EM. The EM code generated is
fed into the peephole optimizer, wich scans it with a window of few
instructions, replacing certain inefficient code sequences by better
ones. Following the peephole optimizer follows a backend wich produces
good assembly code. The assembly code goes into the assembler and the objectcode
then goes into the loader/linker, the final component in the pipeline.
.PP
For various applications this scheme is too slow. For example for testing
programs; In this case the program has to be translated fast and the
runtime of the objectcode may be slower. A solution is to build a code
expander ( \fBce\fR) wich translates EM code to objectcode. Of course this
has to
be done automaticly by a code expander generator, but to get some feeling
for the problem we started out to build prototypes.
We built two types of ce's. One wich tranlated EM to assembly, one
wich translated EM to objectcode.
.NH
EM to assembly
.PP
We made one for the 8086 and one for the vax4. These ce's are instances of the
EM_CODE(3L)-interface and produce for a single EM instruction a set
of assembly instruction wich are semantic equivalent.
We implemented in the 8086-ce push/pop-optimalization.
.NH
EM to objectcode
.PP
Instead of producing assembly code we tried to produce vax4-objectcode.
During execution of ce, ce builds in core a machine independent
objectfile ( NEW A.OUT(5L)) and just before dumping the tables this
objectfile is converted to a Berkly 4.2BSD a.out-file. We build two versions;
One with static memory allocation and one with dynamic memory allocation.
If the first one runs out of memory it will give an error message and stop,
the second one will allocate more memory and proceed with producing
objectcode.
.PP
The C-frontend calls the EM_CODE-interface. So after linking the frontend
and the ce we have a pipeline in a program saving a lot of i/o.
It is interesting to compare this C-compiler ( called fcemcom) with "cc -c".
fcemcom1 (the dynamic variant of fcemcom) is tuned in such a way, that
alloc() won't be called.
.NH 2
Compile time
.PP
fac.c is a small program that produces n! ( see below). foo.c is small program
that loops a lot.
.TS
center, box, tab(:);
c | c | c | c | c | c
c | c | n | n | n | n.
compiler : program : real : user : sys : object size
=
fcemcom : sort.c : 31.0 : 17.5 : 1.8 : 23824
fcemcom1 : : 59.0 : 21.2 : 3.3 :
cc -c : : 50.0 : 38.0 : 3.5 : 6788
_
fcemcom : ed.c : 37.0 : 23.6 : 2.3 : 41744
fcemcom1 : : 1.16.0 : 28.3 : 4.6 :
cc -c : : 1.19.0 : 54.8 : 4.3 : 11108
_
fcemcom : cp.c : 4.0 : 2.4 : 0.8 : 4652
fcemcom1 : : 9.0 : 3.0 : 1.0 :
cc -c : : 8.0 : 5.2 : 1.6 : 1048
_
fcemcom : uniq.c : 5.0 : 2.5 : 0.8 : 5568
fcemcom1 : : 9.0 : 2.9 : 0.8 :
cc -c : : 13.0 : 5.4 : 2.0 : 3008
_
fcemcom : btlgrep.c : 24.0 : 7.2 : 1.4 : 12968
fcemcom1 : : 23.0 : 8.1 : 1.2 :
cc -c : : 1.20.0 : 15.3 : 3.8 : 2392
_
fcemcom : fac.c : 1.0 : 0.1 : 0.5 : 216
fecmcom1 : : 2.0 : 0.2 : 0.5 :
cc -c : : 3.0 : 0.7 : 1.3 : 92
_
fcemcom : foo.c : 4.0 : 0.2 : 0.5 : 272
fcemcom1 : : 11.0 : 0.3 : 0.5 :
cc -c : : 7.0 : 0.8 : 1.6 : 108
.TE
.NH 2
Run time
.LP
Is the runtime very bad?
.TS
tab(:), box, center;
c | c | c | c | c
c | c | n | n | n.
compiler : program : real : user : system
=
fcem : sort.c : 22.0 : 17.5 : 1.5
cc : : 5.0 : 2.4 : 1.1
_
fcem : btlgrep.c : 1.58.0 : 27.2 : 4.2
cc : : 12.0 : 3.6 : 1.1
_
fcem : foo.c : 1.0 : 0.7 : 0.1
cc : : 1.0 : 0.4 : 0.1
_
fcem : uniq.c : 2.0 : 0.5 : 0.3
cc : : 1.0 : 0.1 : 0.2
.TE
.NH 2
quality object code
.LP
The runtime is very bad so its interesting to have look at the code which is
produced by fcemcom and by cc -c. I took a program which computes recursively
n!.
.DS
long fac();
main()
{
int n;
scanf( "%D", &n);
printf( "fac is %D\\\\n", fac( n));
}
long fac( n)
int n;
{
if ( n == 0)
return( 1);
else
return( n * fac( n-1));
}
.DE
.br
.br
.br
.br
.LP
"cc -c fac.c" produces :
.DS
fac: tstl 4(ap)
bnequ 7f
movl $1, r0
ret
7f: subl3 $1, 4(ap), r0
pushl r0
call $1, fac
movl r0, -4(fp)
mull3 -4(fp), 4(ap), r0
ret
.DE
.br
.br
.LP
"fcem fac.c fac.o" produces :
.DS
_fac: 0
42: jmp be
48: pushl 4(ap)
4e: pushl $0
54: subl2 (sp)+,(sp)
57: tstl (sp)+
59: bnequ 61
5b: jmp 67
61: jmp 79
67: pushl $1
6d: jmp ba
73: jmp b9
79: pushl 4(ap)
7f: pushl $1
85: subl2 (sp)+,(sp)
88: calls $0,_fac
8f: addl2 $4,sp
96: pushl r0
98: pushl 4(ap)
9e: pushl $4
a4: pushl $4
aa: jsb .cii
b0: mull2 (sp)+,(sp)
b3: jmp ba
b9: ret
ba: movl (sp)+,r0
bd: ret
be: jmp 48
.DE
.NH 1
Conclusions
.PP
comparing "cc -c" with "fcemcom"
.LP
.TS
center, box, tab(:);
c | c s | c | c s
^ | c s | ^ | c s
^ | c | c | ^ | c | c
l | n | n | n | n | n.
program : compile time : object size : runtime
:_::_
: user : sys :: user : sys
=
sort.c : 0.47 : 0.5 : 3.5 : 7.3 : 1.4
_
ed.c : 0.46 : 0.5 : 3.8 : : :
_
cp.c : 0.46 : 0.5 : 4.4 : : :
_
uniq.c : 0.46 : 0.4 : 1.8 : : :
_
btlgrep.c : 0.47 : 0.3 : 5.4 : 7.5 : 3.8
_
fac.c : 0.14 : 0.4 : 2.3 : 1.8 : 1.0
_
foo.c : 0.25 : 0.3 : 2.5 : 5.0 : 1.5
.TE
.PP
The results for fcemcom1 are almost identical; The only thing that changes
is that fcemcom1 is 1.2 slower than fcemcom. ( compile time) This is due to
to an another datastructure . In the static version we use huge array's for
the text- and
data-segment, the relocation information, the symboltable and stringarea.
In the dynamic version we use linked lists, wich makes it expensive to get
and to put a byte on a abritrary memory location. So it is probably better
to use realloc(), because in the most cases there will be enough memory.
.PP
The quality of the objectcode is very bad. The reason is that the frontend
generates bad code and expects the peephole-optimizer to improve the code.
This is also one of the main reasons that the runtime is very bad.
(e.g. the expensive "cii" with arguments 4 and 4 could be deleted.)
So its seems a good
idea to put a new peephole-optimizer between the frontend and the ce.
.PP
Using the peephole optimizer the ce would produce :
.DS
_fac: 0
pushl 4(ap)
tstl (sp)+
beqlu 1f
jmp 3f
1 : pushl $1
jmp 2f
3 : pushl 4(ap)
decl (sp)
calls $0,_fac
addl2 $4,sp
pushl r0
pushl 4(ap)
mull2 (sp)+,(sp)
movl (sp)+,r0
2 : ret
.DE
.PP
Bruce McKenzy already implemented it and made some improvements in the
source code of the ce. The compile-time is two to two and a half times better
and the
size of the objectcode is two to three times bigger.(comparing with "cc -c")
Still we could do better.
.PP
Using peephole- and push/pop-optimization ce could produce :
.DS
_fac: 0
tstl 4(ap)
beqlu 1f
jmp 2f
1 : pushl $1
jmp 3f
2 : decl 4(ap)
calls $0,_fac
addl2 $4,sp
mull3 4(ap), r0, -(sp)
movl (sp)+, r0
3 : ret
.DE
.PP
prof doesn't cooperate, so no profile information.
.PP

View file

@ -1,323 +0,0 @@
.\" $Header$
.nr ID 4
.de hd
'sp 2
'tl ''-%-''
'sp 3
..
.de fo
'bp
..
.tr ~
. TITLE
.de TL
.sp 15
.ce
\\fB\\$1\\fR
..
. AUTHOR
.de AU
.sp 15
.ce
by
.sp 2
.ce
\\$1
..
. DATE
.de DA
.sp 3
.ce
( Dated \\$1 )
..
. INSTITUTE
.de VU
.sp 3
.ce 4
Wiskundig Seminarium
Vrije Universteit
De Boelelaan 1081
Amsterdam
..
. PARAGRAPH
.de PP
.sp
.ti +\n(ID
..
.nr CH 0 1
. CHAPTER
.de CH
.nr SH 0 1
.bp
.in 0
\\fB\\n+(CH.~\\$1\\fR
.PP
..
. SUBCHAPTER
.de SH
.sp 3
.in 0
\\fB\\n(CH.\\n+(SH.~\\$1\\fR
.PP
..
. INDENT START
.de IS
.sp
.in +\n(ID
..
. INDENT END
.de IE
.in -\n(ID
.sp
..
.de PT
.ti -\n(ID
.ta \n(ID
.fc " @
"\\$1@"\c
.fc
..
. DOUBLE INDENT START
.de DS
.sp
.in +\n(ID
.ll -\n(ID
..
. DOUBLE INDENT END
.de DE
.ll +\n(ID
.in -\n(ID
.sp
..
. EQUATION START
.de EQ
.sp
.nf
..
. EQUATION END
.de EN
.fi
.sp
..
. ITEM
.de IT
.sp
.in 0
\\fB~\\$1\\fR
.ti +5
..
.de CS
.br
~-~\\
..
.br
.fi
.TL "Ack-C reference manual"
.AU "Ed Keizer"
.DA "September 12, 1983"
.VU
.wh 0 hd
.wh 60 fo
.CH "Introduction"
The C frontend included in the Amsterdam Compiler Kit
translates UNIX-V7 C into compact EM code [1].
The language accepted is described in [2] and [3].
This document describes which implementation dependent choices were
made in the Ack-C frontend and
some restrictions and additions.
.CH "The language"
.PP
Under the same heading as used in [2] we describe the
properties of the Ack-C frontend.
.IT "2.2 Identifiers"
External identifiers are unique up to 7 characters and allow
both upper and lower case.
.IT "2.3 Keywords"
The word \fBvoid\fP is also reserved as a keyword.
.IT "2.4.3 Character constants"
The ASCII-mapping is used when a character is converted to an
integer.
.IT "2.4.4 Floating constants"
To prevent loss of precision the compiler does not perform
floating point constant folding.
.IT "2.6 Hardware characteristics"
The size of objects of the several arithmetic types and
pointers depend on the EM-implementation used.
The ranges of the arithmetic types depend on the size used,
the C-frontend assumes two's complement representation for the
integral types.
All sizes are multiples of bytes.
The calling program \fIack\fP[4] passes information about the
size of the types to the compiler proper.
.br
However, a few general remarks must be made:
.sp 1
.IS
.PT (a)
The size of pointers is a multiple of
(or equal to) the size of an \fIint\fP.
.PT (b)
The following relations exist for the sizes of the types
mentioned:
.br
.ti +5
\fIchar<=short<=int<=long\fP
.PT (c)
Objects of type \fIchar\fP use one 8-bit byte of storage,
although several bytes are allocated sometimes.
.PT (d)
All sizes are in multiples of bytes.
.PT (e)
Most EM implementations use 4 bytes for floats and 8 bytes
for doubles, but exceptions to this rule occur.
.IE
.IT "4 What's in a name"
The type \fIvoid\fP is added.
Objects of type void do not exist.
Functions declared as returning void, do not return a value at all.
.IT "6.1 Characters and integers"
Objects of type \fIchar\fP are unsigned and do not cause
sign-extension when converted to \fIint\fP.
The range of characters values is from 0 to 255.
.IT "6.3 Floating and integral"
Floating point numbers are truncated towards zero when
converted to the integral types.
.IT "6.4 Pointers and integers"
When a \fIlong\fP is added to or subtracted from a pointer and
longs are larger then pointers the \fIlong\fP is converted to an
\fIint\fP before the operation is performed.
.IT "7.2 Unary operators"
It is allowed to cast any expression to the type \fIvoid\fP.
.IT "8.2 Type specifiers"
One type is added to the type-specifiers:
.br
.IS
void
.IE
.IT "8.5 Structure and union declarations"
The only type allowed for fields is \fIint\fP.
Fields with exactly the size of \fIint\fP are signed,
all other fields are unsigned.
.br
The size of any single structure must be less then 4096 bytes.
.IT "8.6 Initialization"
Initialization of structures containing bit fields is not
allowed.
There is one restriction when using an 'address expression' to initialize
an integral variable.
The integral variable must have the same size as a pointer.
Conversions altering the size of the address expression are not allowed.
.IT "9.10 Return statement"
Return statements of the form:
.IS
return ;
.IE
are the only form of return statement allowed in a function of type
function returning void.
.IT "10.1 External function definitions"
The total amount for storage used for parameters
in any function must be less then 4096 bytes.
The same holds for the total amount of storage occupied by the
automatic variables declared inside any function.
.sp
Using formal parameters whose size is smaller the the size of an int
is less efficient on several machines.
At procedure entry these parameters are converted from integer to the
declared type, because the compiler doesn't know where the least
significant bytes are stored in the int.
.IT "11.2 Scope of externals"
Most C compilers are rather lax in enforcing the restriction
that only one external definition without the keyword
\fIextern\fP is allowed in a program.
The Ack-C frontend is very strict in this.
The only exception is that declarations of arrays with a
missing first array bounds expression are regarded to have an
explicit keyword \fIextern\fP.
.IT "14.4 Explicit pointer conversions"
Pointers may be larger the ints, thus assigning a pointer to an
int and back will not always result in the same pointer.
The process mentioned above works with integrals
of the same size or larger as pointers in all EM implementations
having such integrals.
When converting pointers to an integral type or vice-versa,
the pointers is seen as an unsigned int.
.br
EM guarantees that any object can be placed at a word boundary,
this allows the C-programs to use \fIint\fP pointers
as pointers to objects of any type not smaller than an \fIint\fP.
.CH "Frontend options"
The C-frontend has a few options, these are controlled
by flags:
.IS
.PT -V
This flag is followed by a sequence of letters each followed by
positive integers. Each letter indicates a
certain type, the integer following it specifies the size of
objects of that type. One letter indicates the wordsize used.
.IS
.sp 1
.TS
center tab(:);
l l16 l l.
letter:type:letter:type
w:wordsize:i:int
s:short:l:long
f:float:d:double
p:pointer::
.TE
.sp 1
All existing implementations use an integer size equal to the
wordsize.
.IE
The calling program \fIack\fP[4] provides the frontend with
this flag, with values depending on the machine used.
.sp 1
.PT -l
The frontend normally generates code to keep track of the line
number and source file name at runtime for debugging purposes.
Currently a pointer to a
string containing the filename is stored at a fixed place in
memory at each function
entry and the line number at the start of every expression.
At the return from a function these memory locations are not reset to
the values they had before the call.
Most library routines do not use this feature and thus do not
ruin the current line number and filename when called.
However, you are really unlucky when your program crashes due
to a bug in such a library function, because the line number
and filename do not indicate that something went wrong inside
the library function.
.br
Providing the flag -l to the frontend tells it not to generate
the code updating line number and file name.
This is, for example, used when translating the stdio library.
.br
When the \fIack\fP[4] is called with the -L flag it provides
the frontend with this flag.
.sp 1
.PT -Xp
When this flag is present the frontend generates a call to
the function \fBprocentry\fP at each function entry and a
call to \fBprocexit\fP at each function exit.
Both functions are provided with one parameter,
a pointer to a string containing the function name.
.br
When \fIack\fP is called with the -p flag it provides the
frontend with this flag.
.IE
.CH References
.IS
.PT [1]
A.S. Tanenbaum, Hans van Staveren, Ed Keizer and Johan
Stevenson \fIDescription of a machine architecture for use with
block structured languages\fP Informatica report IR-81.
.sp 1
.PT [2]
B.W. Kernighan and D.M. Ritchie, \fIThe C Programming
language\fP, Prentice-Hall, 1978
.PT [3]
D.M. Ritchie, \fIC Reference Manual\fP
.sp
.PT [4]
UNIX manual ack(I).

View file

@ -1,55 +0,0 @@
REFS=-p refs.opt -p refs.stat -p refs.gen
INTRO=intro/intro?
OV=ov/ov?
IC=ic/ic?
CF=cf/cf?
IL=il/il?
SR=sr/sr?
CS=cs/cs?
SP=sp/sp?
UD=ud/ud?
LV=lv/lv?
CJ=cj/cj?
BO=bo/bo?
RA=ra/ra?
CA=ca/ca?
EGO=$(INTRO) $(OV) $(IC) $(CF) $(IL) $(SR) $(CS) $(SP) $(CJ) $(BO) \
$(UD) $(LV) $(RA) $(CA)
REFER=refer
TROFF=troff
TBL=tbl
TARGET=-Tlp
../ego.doc: refs.opt refs.stat refs.gen intro/head intro/tail $(EGO)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | $(TBL) > ../ego.doc
ego.f: refs.opt refs.stat refs.gen intro/head intro/tail $(EGO)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ego.f
intro.f: refs.opt refs.stat refs.gen intro/head intro/tail $(INTRO)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(INTRO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > intro.f
ov.f: refs.opt refs.stat refs.gen intro/head intro/tail $(OV)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(OV) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ov.f
ic.f: refs.opt refs.stat refs.gen intro/head intro/tail $(IC)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(IC) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ic.f
cf.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CF)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CF) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cf.f
il.f: refs.opt refs.stat refs.gen intro/head intro/tail $(IL)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(IL) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > il.f
sr.f: refs.opt refs.stat refs.gen intro/head intro/tail $(SR)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(SR) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > sr.f
cs.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CS)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CS) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cs.f
sp.f: refs.opt refs.stat refs.gen intro/head intro/tail $(SP)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(SP) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > sp.f
cj.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CJ)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CJ) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cj.f
bo.f: refs.opt refs.stat refs.gen intro/head intro/tail $(BO)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(BO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > bo.f
ud.f: refs.opt refs.stat refs.gen intro/head intro/tail $(UD)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(UD) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ud.f
lv.f: refs.opt refs.stat refs.gen intro/head intro/tail $(LV)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(LV) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > lv.f
ra.f: refs.opt refs.stat refs.gen intro/head intro/tail $(RA)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(RA) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ra.f
ca.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CA)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CA) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ca.f

View file

@ -1,37 +0,0 @@
HOME=../..
TBL=tbl
NROFF=nroff
SUF=pr
TARGET=-Tlp
head: ../em.$(SUF)
FILES = macr.nr title.nr intro.nr mem.nr ispace.nr dspace.nr mapping.nr \
types.nr descr.nr env.nr traps.nr mach.nr assem.nr \
app.int.nr app.codes.nr app.exam.nr cont.nr
IOP=$(HOME)/etc/ip_spec.t# # to construct itables from
../em.$(SUF): $(FILES) itables dispatdummy em.i Makefile
$(TBL) $(FILES) | $(NROFF) -mkun $(TARGET) > ../em.$(SUF)
app.codes.pr: app.codes.nr itables dispatdummy
itables: $(IOP) ip.awk
awk -f ip.awk $(IOP) | sed 's/-/\\-/g' | $(TBL) >itables
dispatdummy: $(IOP) mkdispatch
mkdispatch < $(IOP) > dispatdummy
sed -f dispat1.sed < dispatdummy | $(TBL) > dispat1
sed -f dispat2.sed < dispatdummy | $(TBL) > dispat2
sed -f dispat3.sed < dispatdummy | $(TBL) > dispat3
mkdispatch: mkdispatch.c
$(CC) -I$(HOME)/h -o mkdispatch mkdispatch.c $(HOME)/lib.bin/em_data.a
.SUFFIXES : .pr .nr
.nr.pr: ; $(TBL) macr.nr $*.nr | $(NROFF) -mkun >$@
clean:
rm -f *.pr itables *.out dispatdummy dispat? *.o mkdispatch

File diff suppressed because it is too large Load diff

View file

@ -1,11 +0,0 @@
.BP
.AP "EM INTERPRETER"
.nf
.ft CW
.lg 0
.nr x \w' '
.ta \nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu
.so em.i
.ft P
.lg 1
.fi

View file

@ -1,488 +0,0 @@
.BP
.AP "EM INTERPRETER"
.nf
.ta 8 16 24 32 40 48 56 64 72 80
.so em.i
.fi
.BP
.AP "EM CODE TABLES"
The following table is used by the assembler for EM machine
language.
It specifies the opcodes used for each instruction and
how arguments are mapped to machine language arguments.
The table is presented in three columns,
each line in each column contains three or four fields.
Each line describes a range of interpreter opcodes by
specifying for which instruction the range is used, the type of the
opcodes (mini, shortie, etc..) and range for the instruction
argument.
.A
The first field on each line gives the EM instruction mnemonic,
the second field gives some flags.
If the opcodes are minis or shorties the third field specifies
how many minis/shorties are used.
The last field gives the number of the (first) interpreter
opcode.
.N 1
Flags :
.IS 3
.N 1
Opcode type, only one of the following may be specified.
.PS - 5 " "
.PT -
opcode without argument
.PT m
mini
.PT s
shortie
.PT 2
opcode with 2-byte signed argument
.PT 4
opcode with 4-byte signed argument
.PT 8
opcode with 8-byte signed argument
.PE
Secondary (escaped) opcodes.
.PS - 5 " "
.PT e
The opcode thus marked is in the secondary opcode group instead
of the primary
.PE
restrictions on arguments
.PS - 5 " "
.PT N
Negative arguments only
.PT P
Positive and zero arguments only
.PE
mapping of arguments
.PS - 5 " "
.PT w
argument must be divisible by the wordsize and is divided by the
wordsize before use as opcode argument.
.PT o
argument ( possibly after division ) must be >= 1 and is
decremented before use as opcode argument
.PE
.IE
If the opcode type is 2,4 or 8 the resulting argument is used as
opcode argument (least significant byte first).
.N
If the opcode type is mini, the argument is added
to the first opcode - if in range - .
If the argument is negative, the absolute value minus one is
used in the algorithm above.
.N
For shorties with positive arguments the first opcode is used
for arguments in the range 0..255, the second for the range
256..511, etc..
For shorties with negative arguments the first opcode is used
for arguments in the range -1..-256, the second for the range
-257..-512, etc..
The byte following the opcode contains the least significant
byte of the argument.
First some examples of these specifications.
.PS - 5
.PT "aar mwPo 1 34"
Indicates that opcode 34 is used as a mini for Positive
instruction arguments only.
The w and o indicate division and decrementing of the
instruction argument.
Because the resulting argument must be zero ( only opcode 34 may be used
), this mini can only be used for instruction argument 2.
Conclusion: opcode 34 is for "AAR 2".
.PT "adp sP 1 41"
Opcode 41 is used as shortie for ADP with arguments in the range
0..255.
.PT "bra sN 2 60"
Opcode 60 is used as shortie for BRA with arguments -1..-256,
61 is used for arguments -257..-512.
.PT "zer e- 145"
Escaped opcode 145 is used for ZER.
.PE
The interpreter opcode table:
.N 1
.IS 3
.DS B
.so itables
.DE 0
.IE
.P
The table above results in the following dispatch tables.
Dispatch tables are used by interpreters to jump to the
routines implementing the EM instructions, indexed by the next opcode.
Each line of the dispatch tables gives the routine names
of eight consecutive opcodes, preceded by the first opcode number
on that line.
Routine names consist of an EM mnemonic followed by a suffix.
The suffices show the encoding used for each opcode.
.N
The following suffices exist:
.N 1
.VS 1 0
.IS 4
.PS - 11
.PT .z
no arguments
.PT .l
16-bit argument
.PT .lw
16-bit argument divided by the wordsize
.PT .p
positive 16-bit argument
.PT .pw
positive 16-bit argument divided by the wordsize
.PT .n
negative 16-bit argument
.PT .nw
negative 16-bit argument divided by the wordsize
.PT .s<num>
shortie with <num> as high order argument byte
.PT .sw<num>
shortie with argument divided by the wordsize
.PT .<num>
mini with <num> as argument
.PT .<num>W
mini with <num>*wordsize as argument
.PE 3
<num> is a possibly negative integer.
.VS 1 1
.IE
The dispatch table for the 256 primary opcodes:
.DS B
0 loc.0 loc.1 loc.2 loc.3 loc.4 loc.5 loc.6 loc.7
8 loc.8 loc.9 loc.10 loc.11 loc.12 loc.13 loc.14 loc.15
16 loc.16 loc.17 loc.18 loc.19 loc.20 loc.21 loc.22 loc.23
24 loc.24 loc.25 loc.26 loc.27 loc.28 loc.29 loc.30 loc.31
32 loc.32 loc.33 aar.1W adf.s0 adi.1W adi.2W adp.l adp.1
40 adp.2 adp.s0 adp.s-1 ads.1W and.1W asp.1W asp.2W asp.3W
48 asp.4W asp.5W asp.w0 beq.l beq.s0 bge.s0 bgt.s0 ble.s0
56 blm.s0 blt.s0 bne.s0 bra.l bra.s-1 bra.s-2 bra.s0 bra.s1
64 cal.1 cal.2 cal.3 cal.4 cal.5 cal.6 cal.7 cal.8
72 cal.9 cal.10 cal.11 cal.12 cal.13 cal.14 cal.15 cal.16
80 cal.17 cal.18 cal.19 cal.20 cal.21 cal.22 cal.23 cal.24
88 cal.25 cal.26 cal.27 cal.28 cal.s0 cff.z cif.z cii.z
96 cmf.s0 cmi.1W cmi.2W cmp.z cms.s0 csa.1W csb.1W dec.z
104 dee.w0 del.w-1 dup.1W dvf.s0 dvi.1W fil.l inc.z ine.lw
112 ine.w0 inl.-1W inl.-2W inl.-3W inl.w-1 inn.s0 ior.1W ior.s0
120 lae.l lae.w0 lae.w1 lae.w2 lae.w3 lae.w4 lae.w5 lae.w6
128 lal.p lal.n lal.0 lal.-1 lal.w0 lal.w-1 lal.w-2 lar.W
136 ldc.0 lde.lw lde.w0 ldl.0 ldl.w-1 lfr.1W lfr.2W lfr.s0
144 lil.w-1 lil.w0 lil.0 lil.1W lin.l lin.s0 lni.z loc.l
152 loc.-1 loc.s0 loc.s-1 loe.lw loe.w0 loe.w1 loe.w2 loe.w3
160 loe.w4 lof.l lof.1W lof.2W lof.3W lof.4W lof.s0 loi.l
168 loi.1 loi.1W loi.2W loi.3W loi.4W loi.s0 lol.pw lol.nw
176 lol.0 lol.1W lol.2W lol.3W lol.-1W lol.-2W lol.-3W lol.-4W
184 lol.-5W lol.-6W lol.-7W lol.-8W lol.w0 lol.w-1 lxa.1 lxl.1
192 lxl.2 mlf.s0 mli.1W mli.2W rck.1W ret.0 ret.1W ret.s0
200 rmi.1W sar.1W sbf.s0 sbi.1W sbi.2W sdl.w-1 set.s0 sil.w-1
208 sil.w0 sli.1W ste.lw ste.w0 ste.w1 ste.w2 stf.l stf.W
216 stf.2W stf.s0 sti.1 sti.1W sti.2W sti.3W sti.4W sti.s0
224 stl.pw stl.nw stl.0 stl.1W stl.-1W stl.-2W stl.-3W stl.-4W
232 stl.-5W stl.w-1 teq.z tgt.z tlt.z tne.z zeq.l zeq.s0
240 zeq.s1 zer.s0 zge.s0 zgt.s0 zle.s0 zlt.s0 zne.s0 zne.s-1
248 zre.lw zre.w0 zrl.-1W zrl.-2W zrl.w-1 zrl.nw escape1 escape2
.DE 2
The list of secondary opcodes (escape1):
.N 1
.DS B
0 aar.l aar.z adf.l adf.z adi.l adi.z ads.l ads.z
8 adu.l adu.z and.l and.z asp.lw ass.l ass.z bge.l
16 bgt.l ble.l blm.l bls.l bls.z blt.l bne.l cai.z
24 cal.l cfi.z cfu.z ciu.z cmf.l cmf.z cmi.l cmi.z
32 cms.l cms.z cmu.l cmu.z com.l com.z csa.l csa.z
40 csb.l csb.z cuf.z cui.z cuu.z dee.lw del.pw del.nw
48 dup.l dus.l dus.z dvf.l dvf.z dvi.l dvi.z dvu.l
56 dvu.z fef.l fef.z fif.l fif.z inl.pw inl.nw inn.l
64 inn.z ior.l ior.z lar.l lar.z ldc.l ldf.l ldl.pw
72 ldl.nw lfr.l lil.pw lil.nw lim.z los.l los.z lor.s0
80 lpi.l lxa.l lxl.l mlf.l mlf.z mli.l mli.z mlu.l
88 mlu.z mon.z ngf.l ngf.z ngi.l ngi.z nop.z rck.l
96 rck.z ret.l rmi.l rmi.z rmu.l rmu.z rol.l rol.z
104 ror.l ror.z rtt.z sar.l sar.z sbf.l sbf.z sbi.l
112 sbi.z sbs.l sbs.z sbu.l sbu.z sde.l sdf.l sdl.pw
120 sdl.nw set.l set.z sig.z sil.pw sil.nw sim.z sli.l
128 sli.z slu.l slu.z sri.l sri.z sru.l sru.z sti.l
136 sts.l sts.z str.s0 tge.z tle.z trp.z xor.l xor.z
144 zer.l zer.z zge.l zgt.l zle.l zlt.l zne.l zrf.l
152 zrf.z zrl.pw dch.z exg.s0 exg.l exg.z lpb.z gto.l
.DE 2
Finally, the list of opcodes with four byte arguments (escape2).
.DS
0 loc
.DE 0
.BP
.AP "AN EXAMPLE PROGRAM"
.DS B
1 program example(output);
2 {This program just demonstrates typical EM code.}
3 type rec = record r1: integer; r2:real; r3: boolean end;
4 var mi: integer; mx:real; r:rec;
5
6 function sum(a,b:integer):integer;
7 begin
8 sum := a + b
9 end;
10
11 procedure test(var r: rec);
12 label 1;
13 var i,j: integer;
14 x,y: real;
15 b: boolean;
16 c: char;
17 a: array[1..100] of integer;
18
19 begin
20 j := 1;
21 i := 3 * j + 6;
22 x := 4.8;
23 y := x/0.5;
24 b := true;
25 c := 'z';
26 for i:= 1 to 100 do a[i] := i * i;
27 r.r1 := j+27;
28 r.r3 := b;
29 r.r2 := x+y;
30 i := sum(r.r1, a[j]);
31 while i > 0 do begin j := j + r.r1; i := i - 1 end;
32 with r do begin r3 := b; r2 := x+y; r1 := 0 end;
33 goto 1;
34 1: writeln(j, i:6, x:9:3, b)
35 end; {test}
36 begin {main program}
37 mx := 15.96;
38 mi := 99;
39 test(r)
40 end.
.DE 0
.BP
The EM code as produced by the Pascal-VU compiler is given below. Comments
have been added manually. Note that this code has already been optimized.
.DS B
mes 2,2,2 ; wordsize 2, pointersize 2
.1
rom 't.p\e000' ; the name of the source file
hol 552,-32768,0 ; externals and buf occupy 552 bytes
exp $sum ; sum can be called from other modules
pro $sum,2 ; procedure sum; 2 bytes local storage
lin 8 ; code from source line 8
ldl 0 ; load two locals ( a and b )
adi 2 ; add them
ret 2 ; return the result
end 2 ; end of procedure ( still two bytes local storage )
.2
rom 1,99,2 ; descriptor of array a[]
exp $test ; the compiler exports all level 0 procedures
pro $test,226 ; procedure test, 226 bytes local storage
.3
rom 4.8F8 ; assemble Floating point 4.8 (8 bytes) in
.4 ; global storage
rom 0.5F8 ; same for 0.5
mes 3,-226,2,2 ; compiler temporary not referenced by address
mes 3,-24,2,0 ; the same is true for i, j, b and c in test
mes 3,-22,2,0
mes 3,-4,2,0
mes 3,-2,2,0
mes 3,-20,8,0 ; and for x and y
mes 3,-12,8,0
lin 20 ; maintain source line number
loc 1
stl -4 ; j := 1
lni ; lin 21 prior to optimization
lol -4
loc 3
mli 2
loc 6
adi 2
stl -2 ; i := 3 * j + 6
lni ; lin 22 prior to optimization
lae .3
loi 8
lal -12
sti 8 ; x := 4.8
lni ; lin 23 prior to optimization
lal -12
loi 8
lae .4
loi 8
dvf 8
lal -20
sti 8 ; y := x / 0.5
lni ; lin 24 prior to optimization
loc 1
stl -22 ; b := true
lni ; lin 25 prior to optimization
loc 122
stl -24 ; c := 'z'
lni ; lin 26 prior to optimization
loc 1
stl -2 ; for i:= 1
2
lol -2
dup 2
mli 2 ; i*i
lal -224
lol -2
lae .2
sar 2 ; a[i] :=
lol -2
loc 100
beq *3 ; to 100 do
inl -2 ; increment i and loop
bra *2
3
lin 27
lol -4
loc 27
adi 2 ; j + 27
sil 0 ; r.r1 :=
lni ; lin 28 prior to optimization
lol -22 ; b
lol 0
stf 10 ; r.r3 :=
lni ; lin 29 prior to optimization
lal -20
loi 16
adf 8 ; x + y
lol 0
adp 2
sti 8 ; r.r2 :=
lni ; lin 23 prior to optimization
lal -224
lol -4
lae .2
lar 2 ; a[j]
lil 0 ; r.r1
cal $sum ; call now
asp 4 ; remove parameters from stack
lfr 2 ; get function result
stl -2 ; i :=
4
lin 31
lol -2
zle *5 ; while i > 0 do
lol -4
lil 0
adi 2
stl -4 ; j := j + r.r1
del -2 ; i := i - 1
bra *4 ; loop
5
lin 32
lol 0
stl -226 ; make copy of address of r
lol -22
lol -226
stf 10 ; r3 := b
lal -20
loi 16
adf 8
lol -226
adp 2
sti 8 ; r2 := x + y
loc 0
sil -226 ; r1 := 0
lin 34 ; note the abscence of the unnecesary jump
lae 22 ; address of output structure
lol -4
cal $_wri ; write integer with default width
asp 4 ; pop parameters
lae 22
lol -2
loc 6
cal $_wsi ; write integer width 6
asp 6
lae 22
lal -12
loi 8
loc 9
loc 3
cal $_wrf ; write fixed format real, width 9, precision 3
asp 14
lae 22
lol -22
cal $_wrb ; write boolean, default width
asp 4
lae 22
cal $_wln ; writeln
asp 2
ret 0 ; return, no result
end 226
exp $_main
pro $_main,0 ; main program
.6
con 2,-1,22 ; description of external files
.5
rom 15.96F8
fil .1 ; maintain source file name
lae .6 ; description of external files
lae 0 ; base of hol area to relocate buffer addresses
cal $_ini ; initialize files, etc...
asp 4
lin 37
lae .5
loi 8
lae 2
sti 8 ; mx := 15.96
lni ; lin 38 prior to optimization
loc 99
ste 0 ; mi := 99
lni ; lin 39 prior to optimization
lae 10 ; address of r
cal $test
asp 2
loc 0 ; normal exit
cal $_hlt ; cleanup and finish
asp 2
end 0
mes 5 ; reals were used
.DE 0
The compact code corresponding to the above program is listed below.
Read it horizontally, line by line, not column by column.
Each number represents a byte of compact code, printed in decimal.
The first two bytes form the magic word.
.N 1
.IS 3
.DS B
173 0 159 122 122 122 255 242 1 161 250 124 116 46 112 0
255 156 245 40 2 245 0 128 120 155 249 123 115 117 109 160
249 123 115 117 109 122 67 128 63 120 3 122 88 122 152 122
242 2 161 121 219 122 255 155 249 124 116 101 115 116 160 249
124 116 101 115 116 245 226 0 242 3 161 253 128 123 52 46
56 255 242 4 161 253 128 123 48 46 53 255 159 123 245 30
255 122 122 255 159 123 96 122 120 255 159 123 98 122 120 255
159 123 116 122 120 255 159 123 118 122 120 255 159 123 100 128
120 255 159 123 108 128 120 255 67 140 69 121 113 116 68 73
116 69 123 81 122 69 126 3 122 113 118 68 57 242 3 72
128 58 108 112 128 68 58 108 72 128 57 242 4 72 128 44
128 58 100 112 128 68 69 121 113 98 68 69 245 122 0 113
96 68 69 121 113 118 182 73 118 42 122 81 122 58 245 32
255 73 118 57 242 2 94 122 73 118 69 220 10 123 54 118
18 122 183 67 147 73 116 69 147 3 122 104 120 68 73 98
73 120 111 130 68 58 100 72 136 2 128 73 120 4 122 112
128 68 58 245 32 255 73 116 57 242 2 59 122 65 120 20
249 123 115 117 109 8 124 64 122 113 118 184 67 151 73 118
128 125 73 116 65 120 3 122 113 116 41 118 18 124 185 67
152 73 120 113 245 30 255 73 98 73 245 30 255 111 130 58
100 72 136 2 128 73 245 30 255 4 122 112 128 69 120 104
245 30 255 67 154 57 142 73 116 20 249 124 95 119 114 105
8 124 57 142 73 118 69 126 20 249 124 95 119 115 105 8
126 57 142 58 108 72 128 69 129 69 123 20 249 124 95 119
114 102 8 134 57 142 73 98 20 249 124 95 119 114 98 8
124 57 142 20 249 124 95 119 108 110 8 122 88 120 152 245
226 0 155 249 125 95 109 97 105 110 160 249 125 95 109 97
105 110 120 242 6 151 122 119 142 255 242 5 161 253 128 125
49 53 46 57 54 255 50 242 1 57 242 6 57 120 20 249
124 95 105 110 105 8 124 67 157 57 242 5 72 128 57 122
112 128 68 69 219 110 120 68 57 130 20 249 124 116 101 115
116 8 122 69 120 20 249 124 95 104 108 116 8 122 152 120
159 124 160 255 159 125 255
.DE 0
.IE
.MS T A 0
.ME
.BP
.MS B A 0
.ME
.CT

View file

@ -1,32 +0,0 @@
CFLAGS=-O
HOME=../../..
install \
all: em emdmp tables
tables: mktables $(HOME)/etc/ip_spec.t
mktables $(HOME)/etc/ip_spec.t tables
mktables: mktables.c $(HOME)/h/em_spec.h $(HOME)/h/em_flag.h \
$(HOME)/lib.bin/em_data.a $(HOME)/h/ip_spec.h
$(CC) -I$(HOME)/h -O -o mktables mktables.c $(HOME)/lib.bin/em_data.a
em.out: em.p
apc -mint -O em.p >emerrs ; mv e.out em.out
em: em.p
apc -O -i em.p >emerrs ; mv a.out em
nem.p: em.p
sed -e '/maxadr = t16/s//maxadr =t15/' -e '/maxdata = 8191; /s//maxdata = 14335;/' -e '/ adr=.*long/s// adr= 0..maxadr/' <em.p >nem.p
nem: nem.p
apc -O -i nem.p >emerrs ; mv a.out nem
emdmp: emdmp.c
$(CC) -I$(HOME)/h -I$(HOME)/config -o emdmp -O emdmp.c
cmp:
pr:
@pr em.p mktables.c emdmp.c

View file

@ -1,376 +0,0 @@
.SN 8
.VS 1 0
.BP
.S1 "ENVIRONMENT INTERACTIONS"
EM programs can interact with their environment in three ways.
Two, starting/stopping and monitor calls, are dealt with in this chapter.
The remaining way to interact, interrupts, will be treated
together with traps in chapter 9.
.S2 "Program starting and stopping"
EM user programs start with a call to a procedure called
m_a_i_n.
The assembler and backends look for the definition of a procedure
with this name in their input.
The call passes three parameters to the procedure.
The parameters are similar to the parameters supplied by the
UNIX
.FS
UNIX is a Trademark of Bell Laboratories.
.FE
operating system to C programs.
These parameters are often called
.BW argc ,
.B argv
and
.BW envp .
Argc is the parameter nearest to LB and is a wordsized integer.
The other two are pointers to the first element of an array of
string pointers.
.N
The
.B argv
array contains
.B argc
strings, the first of which contains the program call name.
The other strings in the
.B argv
array are the program parameters.
.P
The
.B envp
array contains strings in the form "name=string", where 'name'
is the name of an environment variable and string its value.
The
.B envp
is terminated by a zero pointer.
.P
An EM user program stops if the program returns from the first
invocation of m_a_i_n.
The contents of the function return area are used to procure a
wordsized program return code.
EM programs also stop when traps and interrupts occur that are
not caught and when the exit monitor call is executed.
.S2 "Input/Output and other monitor calls"
EM differs from most conventional machines in that it has high level i/o
instructions.
Typical instructions are OPEN FILE and READ FROM FILE instead
of low level instructions such as setting and clearing
bits in device registers.
By providing such high level i/o primitives, the task of implementing
EM on various non EM machines is made considerably easier.
.P
I/O is initiated by the MON instruction, which expects an iocode on top
of the stack.
Often there are also parameters which are pushed on the
stack in reverse order, that is: last
parameter first.
Some i/o functions also provide results, which are returned on the stack.
In the list of monitor calls we use several types of parameters and results,
these types consist of integers and unsigneds of varying sizes, but never
smaller than the wordsize, and the two pointer types.
.N 1
The names of the types used are:
.IS 4
.PS - 10
.PT int
an integer of wordsize
.PT int2
an integer whose size is the maximum of the wordsize and 2
bytes
.PT int4
an integer whose size is the maximum of the wordsize and 4
bytes
.PT intp
an integer with the size of a pointer
.PT uns2
an unsigned integer whose size is the maximum of the wordsize and 2
.PT unsp
an unsigned integer with the size of a pointer
.PT ptr
a pointer into data space
.PE 1
.IE 0
The table below lists the i/o codes with their results and
parameters.
This list is similar to the system calls of the UNIX Version 7
operating system.
.BP
.A
To execute a monitor call, proceed as follows:
.IS 2
.N 1
.PS a 4 "" )
.PT
Stack the parameters, in reverse order, last parameter first.
.PT
Push the monitor call number (iocode) onto the stack.
.PT
Execute the MON instruction.
.PE 1
.IE
An error code is present on the top of the stack after
execution of most monitor calls.
If this error code is zero, the call performed the action
requested and the results are available on top of the stack.
Non-zero error codes indicate a failure, in this case no
results are available and the error code has been pushed twice.
This construction enables programs to test for failure with a
single instruction (~TEQ or TNE~) and still find out the cause of
the failure.
The result name 'e' is reserved for the error code.
.N 1
List of monitor calls.
.DS B
number name parameters results function
1 Exit status:int Terminate this process
2 Fork e,flag,pid:int Spawn new process
3 Read fildes:int;buf:ptr;nbytes:unsp
e:int;rbytes:unsp Read from file
4 Write fildes:int;buf:ptr;nbytes:unsp
e:int;wbytes:unsp Write on a file
5 Open string:ptr;flag:int
e,fildes:int Open file for read and/or write
6 Close fildes:int e:int Close a file
7 Wait e:int;status,pid:int2
Wait for child
8 Creat string:ptr;mode:int
e,fildes:int Create a new file
9 Link string1,string2:ptr
e:int Link to a file
10 Unlink string:ptr e:int Remove directory entry
12 Chdir string:ptr e:int Change default directory
14 Mknod string:ptr;mode,addr:int2
e:int Make a special file
15 Chmod string:ptr;mode:int2
e:int Change mode of file
16 Chown string:ptr;owner,group:int2
e:int Change owner/group of a file
18 Stat string,statbuf:ptr
e:int Get file status
19 Lseek fildes:int;off:int4;whence:int
e:int;oldoff:int4 Move read/write pointer
20 Getpid pid:int2 Get process identification
21 Mount special,string:ptr;rwflag:int
e:int Mount file system
22 Umount special:ptr e:int Unmount file system
23 Setuid userid:int2 e:int Set user ID
24 Getuid e_uid,r_uid:int2 Get user ID
25 Stime time:int4 e:int Set time and date
26 Ptrace request:int;pid:int2;addr:ptr;data:int
e,value:int Process trace
27 Alarm seconds:uns2 previous:uns2 Schedule signal
28 Fstat fildes:int;statbuf:ptr
e:int Get file status
29 Pause Stop until signal
30 Utime string,timep:ptr
e:int Set file times
33 Access string,mode:int e:int Determine file accessibility
34 Nice incr:int Set program priority
35 Ftime bufp:ptr e:int Get date and time
36 Sync Update filesystem
37 Kill pid:int2;sig:int
e:int Send signal to a process
41 Dup fildes,newfildes:int
e,fildes:int Duplicate a file descriptor
42 Pipe e,w_des,r_des:int Create a pipe
43 Times buffer:ptr Get process times
44 Profil buff:ptr;bufsiz,offset,scale:intp Execution time profile
46 Setgid gid:int2 e:int Set group ID
47 Getgid e_gid,r_gid:int Get group ID
48 Sigtrp trapno,signo:int
e,prevtrap:int See below
51 Acct file:ptr e:int Turn accounting on or off
53 Lock flag:int e:int Lock a process
54 Ioctl fildes,request:int;argp:ptr
e:int Control device
56 Mpxcall cmd:int;vec:ptr e:int Multiplexed file handling
59 Exece name,argv,envp:ptr
e:int Execute a file
60 Umask complmode:int2 oldmask:int2 Set file creation mode mask
61 Chroot string:ptr e:int Change root directory
.DE 1
Codes 0, 11, 13, 17, 31, 32, 38, 39, 40, 45, 49, 50, 52,
55, 57, 58, 62, and 63 are
not used.
.P
All monitor calls, except fork and sigtrp
are the same as the UNIX version 7 system calls.
.P
The sigtrp entry maps UNIX signals onto EM interrupts.
Normally, trapno is in the range 0 to 252.
In that case it requests that signal signo
will cause trap trapno to occur.
When given trap number -2, default signal handling is reset, and when given
trap number -3, the signal is ignored.
.P
The flag returned by fork is 1 in the child process and 0 in
the parent.
The pid returned is the process-id of the other process.
.BP
.S1 "TRAPS AND INTERRUPTS"
EM provides a means for the user program to catch all traps
generated by the program itself, the hardware, or external conditions.
This mechanism uses five instructions: LIM, SIM, SIG, TRP and RTT.
This section of the manual may be omitted on the first reading since it
presupposes knowledge of the EM instruction set.
.P
The action taken when a trap occures is determined by the value
of an internal EM trap register.
This register contains a pointer to a procedure.
Initially the pointer used is zero and all traps halt the
program with, hopefully, a useful message to the outside world.
The SIG instruction can be used to alter the trap register,
it pops a procedure pointer from the
stack into the trap register.
When a trap occurs after storing a nonzero value in the trap
register, the procedure pointed to by the trap register
is called with the trap number
as the only parameter (see below).
SIG returns the previous value of the trap register on the
stack.
Two consecutive SIGs are a no-op.
When a trap occurs, the trap register is reset to its initial
condition, to prevent recursive traps from hanging the machine up,
e.g. stack overflow in the stack overflow handling procedure.
.P
The runtime systems for some languages need to ignore some EM
traps.
EM offers a feature called the ignore mask.
It contains one bit for each of the lowest 16 trap numbers.
The bits are numbered 0 to 15, with the least significant bit
having number 0.
If a certain bit is 1 the corresponding trap never
occurs and processing simply continues.
The actions performed by the offending instruction are
described by the Pascal program in appendix A.
.N
If the bit is 0, traps are not ignored.
The instructions LIM and SIM allow copying and replacement of
the ignore mask.~
.P
The TRP instruction generates a trap, the trap number being found on the
stack.
This is, among other things,
useful for library procedures and runtime systems.
It can also be used by a low level trap procedure to pass the trap to a
higher level one (see example below).
.P
The RTT instruction returns from the trap procedure and continues after the
trap.
In the list below all traps marked with an asterisk ('*') are
considered to be fatal and it is explicitly undefined what happens if
you try to restart after the trap.
.P
The way a trap procedure is called is completely compatible
with normal calling conventions. The only way a trap procedure
differs from normal procedures is the return. It has to use RTT instead
of RET. This is necessary because the complete runtime status is saved on the
stack before calling the procedure and all this status has to be reloaded.
Error numbers are in the range 0 to 252.
The trap numbers are divided into three categories:
.IS 4
.N 1
.PS - 10
.PT ~~0-~63
EM machine errors, e.g. illegal instruction.
.PS - 8
.PT ~0-15
maskable
.PT 16-63
not maskable
.PE
.PT ~64-127
Reserved for use by compilers, run time systems, etc.
.PT 128-252
Available for user programs.
.PE 1
.IE
EM machine errors are numbered as follows:
.DS I 5
.TS
tab(@);
n l l.
0@EARRAY@Array bound error
1@ERANGE@Range bound error
2@ESET@Set bound error
3@EIOVFL@Integer overflow
4@EFOVFL@Floating overflow
5@EFUNFL@Floating underflow
6@EIDIVZ@Divide by 0
7@EFDIVZ@Divide by 0.0
8@EIUND@Undefined integer
9@EFUND@Undefined float
10@ECONV@Conversion error
16*@ESTACK@Stack overflow
17*@EHEAP@Heap overflow
18*@EILLINS@Illegal instruction
19*@EODDZ@Illegal size argument
20*@ECASE@Case error
21*@EMEMFLT@Addressing non existent memory
22*@EBADPTR@Bad pointer used
23*@EBADPC@Program counter out of range
24@EBADLAE@Bad argument of LAE
25@EBADMON@Bad monitor call
26@EBADLIN@Argument of LIN too high
27@EBADGTO@GTO descriptor error
.TE
.DE 0
.P
As an example,
suppose a subprocedure has to be written to do a numeric
calculation.
When an overflow occurs the computation has to be stopped and
the higher level procedure must be resumed.
This can be programmed as follows using the mechanism described above:
.DS B
mes 2,2,2 ; set sizes
ersave
bss 2,0,0 ; Room to save previous value of trap procedure
msave
bss 2,0,0 ; Room to save previous value of trap mask
pro calcule,0 ; entry point
lxl 0 ; fill in non-local goto descriptor with LB
ste jmpbuf+4
lor 1 ; and SP
ste jmpbuf+2
lim ; get current ignore mask
ste msave ; save it
lim
loc 16 ; bit for EFOVFL
ior 2 ; set in mask
sim ; ignore EFOVFL from now on
lpi $catch ; load procedure identifier
sig ; catch wil get all traps now
ste ersave ; save previous trap procedure identifier
; perform calculation now, possibly generating overflow
1 ; label jumped to by catch procedure
loe ersave ; get old trap procedure
sig ; refer all following trap to old procedure
asp 2 ; remove result of sig
loe msave ; restore previous mask
sim ; done now
; load result of calculation
ret 2 ; return result
jmpbuf
con *1,0,0
end
.DE 0
.VS 1 1
.DS
Example of catch procedure
pro catch,0 ; Local procedure that must catch the overflow trap
lol 2 ; Load trap number
loc 4 ; check for overflow
bne *1 ; if other trap, call higher trap procedure
gto jmpbuf ; return to procedure calcule
1 ; other trap has occurred
loe ersave ; previous trap procedure
sig ; other procedure will get the traps now
asp 2 ; remove the result of sig
lol 2 ; stack trap number
trp ; call other trap procedure
rtt ; if other procedure returns, do the same
end
.DE

File diff suppressed because it is too large Load diff

View file

@ -1,5 +0,0 @@
case $# in
1) make "$1".t ; ntlp "$1".t^lpr ;;
*) echo $0 heeft een argument nodig ;;
esac

View file

@ -1,4 +0,0 @@
case $# in
1) make $1.t ; ntout $1.t ;;
*) echo $0 heeft een argument nodig ;;
esac

View file

@ -1,9 +0,0 @@
# $Header$
FP = frontpage
DOC = abstract contents chap1 chap2 chap3 chap4 chap5 chap6 chap7\
chap8 chap9 appendix_A appendix_B
../lint.doc: $(FP) $(DOC)
cat $(FP) $(DOC) > ../lint.doc

View file

@ -1,18 +0,0 @@
EMHOME=../..
FILES= p0 p1 p2 p3 p4 p5 p6 p7 p8 p9
PIC=pic
EQN=eqn
TBL=tbl
TARGET=-Tlp
../occam.doc: p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 channel.h.t channel.c.t
soelim $(FILES) | $(PIC) $(TARGET) | $(TBL) | $(EQN) $(TARGET) > $@
channel.h.t: $(EMHOME)/h/ocm_chan.h
ctot <$(EMHOME)/h/ocm_chan.h >channel.h.t
channel.c.t: channel.c
ctot <channel.c >channel.c.t
channel.c: $(EMHOME)/lang/occam/lib/tail_ocm.a
arch x $(EMHOME)/lang/occam/lib/tail_ocm.a channel.c

View file

@ -1,10 +0,0 @@
# $Header$
REFER=refer
TBL=tbl
TARGET=-Tlp
PIC=pic
GRAP=grap
../sparc.doc: refs title intro 1 2 3 4 5 A B init
$(REFER) -sA+T '-l\", ' -p refs title intro 1 2 3 4 5 A B | $(GRAP) | $(PIC) | $(TBL) | soelim > $@

View file

@ -1,8 +0,0 @@
# $Header$
REFER=refer
TBL=tbl
TARGET=-Tlp
../top.doc: top.n refs.top
$(REFER) -sA+T -l4,2 -p refs.top top.n | $(TBL) > $@

View file

@ -1 +0,0 @@
0

View file

@ -1,28 +0,0 @@
#define WS EM_WSIZE
#define PS EM_PSIZE
#include "test.h"
mes 2,WS,PS
mes 1
mes 4,300
.000
con "tst000"
exp $m_a_i_n
pro $m_a_i_n,0
loc 123
loc -98
; TEST 000: empty
fil .000
loc -98
bne *1
loc 123
bne *1
lin 0
nop
loc 0
ret WS
1
lin 1
nop
loc 1
ret WS
end

View file

@ -1,289 +0,0 @@
non-standard feature used
identifier '%s' declared twice
end of file encountered
bad line directive
unsigned real: digit of fraction expected
unsigned real: digit of exponent expected
unsigned real: too many digits (>72)
unsigned integer: too many digits (>72)
unsigned integer: overflow (>32767)
string constant: must not exceed one line
string constant: at least one character expected
string constant: double quotes not allowed (see c option)
string constant: too long (>72 chars)
bad character
identifier '%s' not declared
location counter overflow: arrays too big
location counter overflow: arrays too big
arraysize too big
variable '%s' never used
variable '%s' never assigned
the files contained in '%s' are not closed automatically
constant expected
constant: only integers and reals may be signed
constant: out of bounds
simple type expected
enumerated type: element identifier expected
enumerated type: ',' or ')' expected
enumerated type: ',' expected
enumerated type: ')' expected
subrange type: type must be scalar, but not real
subrange type: '..' expected
subrange type: type of lower and upper bound incompatible
subrange type: lower bound exceeds upper bound
array type: '[' expected
conformant array: low bound identifier expected
conformant array: '..' expected
conformant array: high bound identifier expected
conformant array: ':' expected
conformant array: index type identifier expected
array type: index type not bounded
array type: index separator or ']' expected
array type: index separator expected
array type: ']' expected
array type: 'of' expected
record variant part: tag type identifier expected
record variant part: tag type identifier expected
record variant part: type must be bounded
record variant part: 'of' expected
record variant: type of case label and tag incompatible
record variant: multiple defined case label
record variant: ',' or ':' expected
record variant: ',' expected
record variant: ':' expected
record variant: '(' expected
record variant: ')' expected
record variant part: ';' or end of variant list expected
record variant part: ';' expected
record variant part: end of variant list expected
record variant part: there must be a variant for each tag value
field list: record section expected
record section: field identifier expected
record section: ',' or ':' expected
record section: ',' expected
record section: ':' expected
field list: ';' or end of record section list expected
field list: ';' expected
field list: end of record section list expected
type expected
type: simple and pointer type may not be packed
pointer type: type identifier expected
pointer type: type identifier expected
record type: 'end' expected
set type: 'of' expected
set type: too many elements in set
set type: bad subrange of integer
set of integer: the i option dictates the number of bits (default 16)
set type: base type not bounded
file type: 'of' expected
file type: files within files not allowed
var parameter: type identifier or conformant array expected
var parameter: type identifier expected
label declaration: unsigned integer expected
label declaration: label '%i' multiple declared
label declaration: ',' or ';' expected
label declaration: ',' expected
label declaration: ';' expected
const declaration: constant identifier expected
const declaration: '=' expected
const declaration: ';' expected
const declaration: constant identifier or 'type', 'var', 'procedure', 'function' or 'begin' expected
type declaration: type identifier expected
type declaration: '=' expected
type declaration: ';' expected
type declaration: type identifier or 'var', 'procedure', 'function' or 'begin' expected
var declaration: var identifier expected
var declaration: ',' or ':' expected
var declaration: ',' expected
var declaration: ':' expected
var declaration: ';' expected
var declaration: var identifier or 'procedure', 'function' or 'begin' expected
parameter list: 'var','procedure','function' or identifier expected
parameter list: parameter identifier expected
parameter list: ',' or ':' expected
parameter list: ',' expected
parameter list: ':' expected
parameter list: type identifier expected
parameter list: ';' or ')' expected
parameter list: ';' expected
proc/func declaration: proc/func identifier expected
proc/func declaration: previous declaration of '%s' was not forward
proc/func declaration: parameter list expected
parameterlist: ')' expected
func declaration: ':' expected
func declaration: result type identifier expected
func declaration: result type must be scalar, subrange or pointer
proc/func declaration: ';' expected
proc/func declaration: block or directive expected
proc/func declaration: '%s' unknown directive
proc/func declaration: '%s' again forward declared
proc/func declaration: ';' expected
indexed variable: '[' only allowed following array variables
indexed variable: index type not compatible with declaration
indexed variable: ',' or ']' expected
indexed variable: ',' expected
assignment: standard function not allowed as destination
assignment: cannot store the function result
assignment: formal parameter function not allowed as destination
assignment: function identifier may not be de-referenced
variable: '[', '.', '^' or end of variable expected
indexed variable: ']' expected
field designator: field identifier expected
field designator: '.' only allowed following record variables
field designator: no field '%s' in this record
referenced variable: '^' not allowed following zero-terminated strings
referenced variable: '^' only allowed following pointer or file variables
variable: var or field identifier expected
call: too many actual parameters supplied
call: proc/func identifier expected
call: standard proc/func may not be used as parameter
call: parameter lists of actual and formal proc/func incompatible
call: type of actual and formal value parameter not compatible
call: array parameter not conformable
call: type of actual and formal variable parameter not similar
call: packed elements not allowed as variable parameter
call: ',' or ')' expected
call: too few actual parameters supplied
read(ln): type must be integer, char or real
write(ln): type must be integer, char, real, string or boolean
write(ln): ':', ',' or ')' expected
write(ln): field width must be integer
write(ln): ':', ',' or ')' expected
write(ln): precision must be integer
write(ln): precision may only be specified for reals
read/write: too few actual parameters supplied
read/write: standard input/output not mentioned in program heading
read/write: ',' or ')' expected
read/write: type of parameter not the same as that of the file elements
read/write: parameter list expected
readln/writeln: standard input/output not mentioned in program heading
readln/writeln: only allowed on text files
new/dispose: C-type strings not allowed here
new/dispose: ',' or ')' expected
new/dispose: too many actual parameters supplied
new/dispose: type of tagfield value is incompatible with declaration
call: '(' or end of call expected
standard proc/func: parameter list expected
standard input/output not mentioned in program heading
file variable expected
pointer variable expected
pack: ',' expected
pack: ',' expected
unpack: ',' expected
unpack: ',' expected
standard proc/func: parameter type incompatible with specification
eoln/page: text file variable expected
pack/unpack: array types are incompatible
pack/unpack: only for arrays
abs: integer or real expected
sqr: integer or real expected
ord: type must be scalar or subrange, but not real
pred/succ: type must be scalar or subrange, but not real
trunc/round: real argument required
call: ')' expected
expression: left and right operand are incompatible
set: incompatible elements
set: base type must be bounded or of type integer
set: base type upper bound exceeds maximum set element number
set: element out of range
set: ']' or element list expected
set: '..', ',' or ']' expected
set: ',' or ']' expected
set: ',' expected
factor expected
factor: ')' expected
factor: type of factor must be boolean
set: ']' expected
term: multiplying operator or end of term expected
term: '*' only defined for integers, reals and sets
term: '/' only defined for integers and reals
term: 'div' only defined for integers
term: 'mod' only defined for integers
term: 'and' only defined for booleans
simple expression: only integers and reals may be signed
simple expression: adding operator or end of simple expression expected
simple expression: '+' only defined for integers, reals and sets
simple expression: '-' only defined for integers, reals and sets
simple expression: 'or' only defined for booleans
expression: relational operator or end of expression expected
expression: set expected
expression: left operand of 'in' not compatible with base type of right operand
expression: only '=' and '<>' allowed on pointers
expression: '<' and '>' not allowed on sets
expression: comparison of arrays only allowed for strings
expression: comparison of records not allowed
expression: comparison of files not allowed
assignment: ':=' expected
assignment: left and right hand side incompatible
goto statement: unsigned integer expected
goto statement: label '%i' not declared
if statement: type of expression must be boolean
if statement: 'then' expected
if statement: 'else' or end of if statement expected
case statement: type must be scalar or subrange, but not real
case statement: 'of' expected
case statement: incompatible case label
case statement: multiple defined case label
case statement: ',' or ':' expected
case statement: ',' expected
case statement: ':' expected
case statement: ';' or 'end' expected
case statement: ';' expected
case statement: 'end' expected
repeat statement: ';' or 'until' expected
repeat statement: ';' expected
repeat statement: 'until' expected
repeat statement: type of expression must be boolean
while statement: type of expression must be boolean
while statement: 'do' expected
for statement: type of bound and control variable incompatible
for statement: control variable expected
for statement: control variable must be local
for statement: type must be scalar or subrange, but not real
for statement: ':=' expected
for statement: 'to' or 'downto' expected
for statement: upper bound not assignment compatible
for statement: 'do' expected
with statement: record variable expected
with statement: ',' or 'do' expected
with statement: ',' expected
with statement: 'do' expected
assertion: type of expression must be boolean
statement expected
label '%i' not declared
label '%i' multiple defined
statement: ':' expected
unlabeled statement expected
compound statement: ';' or 'end' expected
compound statement: ';' expected
compound statement: 'end' expected
case statement: 'end' expected
body: ';' or 'end' expected
body: ';' expected
body: label '%i' declared, but never defined
program parameter '%s' not declared
function '%s' never assigned
block: declaration or body expected
block: 'const', 'type', 'var', 'procedure', 'function' or 'begin' expected
block: 'type', 'var', 'procedure', 'function' or 'begin' expected
block: 'var', 'procedure', 'function' or 'begin' expected
block: 'procedure', 'function' or 'begin' expected
block: unsatisfied forward proc/func declaration(s)
block: 'begin' expected
block: 'end' expected
program heading: 'program' expected
program heading: program identifier expected
program heading: file identifier list expected
program heading: file identifier expected
program heading: ',' or ')' expected
program heading: ',' expected
program heading: maximum number of file arguments exceeded (12)
program heading: ')' expected
program heading: ';' expected
program: '.' expected
'program' expected
module: 'const', 'type', 'var', 'procedure' or 'function' expected
module: 'type', 'var', 'procedure' or 'function' expected
module: 'var', 'procedure' or 'function' expected
module: 'procedure' or 'function' expected
garbage at end of program

View file

@ -1,107 +0,0 @@
array bound error
range bound error
set bound error
integer overflow
real overflow
real underflow
divide by 0
divide by 0.0
undefined integer
real undefined
conversion error
error 11
error 12
error 13
error 14
error 15
stack overflow
heap error
illegal instruction
odd or zero byte count
case error
memory fault
bad pointer
bad program counter
bad external address
bad monitor call
bad line number
error 27
error 28
error 29
error 30
error 31
error 32
error 33
error 34
error 35
error 36
error 37
error 38
error 39
error 40
error 41
error 42
error 43
error 44
error 45
error 46
error 47
error 48
error 49
error 50
error 51
error 52
error 53
error 54
error 55
error 56
error 57
error 58
error 59
error 60
error 61
error 62
error 63
more args expected
error in exp
error in ln
error in sqrt
assertion failed
array bound error in pack
array bound error in unpack
only positive j in 'i mod j'
file not yet open
dispose error
error 74
error 75
error 76
error 77
error 78
error 79
error 80
error 81
error 82
error 83
error 84
error 85
error 86
error 87
error 88
error 89
error 90
error 91
error 92
error 93
error 94
error 95
not writable
not readable
end of file
truncated
reset error
rewrite error
close error
read error
write error
digit expected
non-ASCII char read

View file

@ -1,70 +0,0 @@
trap "rm -f x$$.c" 0 1 2 3 15
EMHOME=/usr/em
CFLAG=0
TARGET=a.out
while :
do
case $# in
0) break;;
esac
case $1 in
-I*|-D*|-U*)
PREP=$PREP" "$1
;;
-c) CFLAG=1
;;
-o) shift
TARGET=$1
;;
-F) shift
LFLAG="-F $1"
;;
-*) FLAGS=$FLAGS" "$1
;;
*) ARG=$ARG" "$1
;;
esac
shift
done
for i in $ARG
do
case $i in
*.c)
nm=`basename $i .c`
if [ -x $EMHOME/lib/cpp ]
then
cpp=$EMHOME/lib/cpp
cppf=-P
else
cpp=/bin/cc
cppf=-E
fi
if $cpp $cppf $PREP $i > x$$.c && /bin/cc $FLAGS -c x$$.c
then
mv x$$.o $nm.o
LDARG=$LDARG" "$nm.o
else
rm -f x$$.c
exit 1
fi
rm -f x$$.c
;;
*.s)
if /bin/cc $FLAGS -c $i
then
LDARG=$LDARG" "`basename $i .s`.o
else exit 1
fi
;;
*) LDARG=$LDARG" "$i
;;
esac
done
case $CFLAG in
1) ;;
*) if /bin/cc $FLAGS $LFLAG $LDARG -o $TARGET
then :
else exit 1
fi
;;
esac

View file

@ -1,67 +0,0 @@
rm -f ../bin/x_tpath x_tpath
echo 'Checking out your $PATH; . and $ACK/bin should be in front ...'
echo "echo $$" >../bin/x_tpath
rm -f x_tpath
chmod +x ../bin/x_tpath
case x`(x_tpath) 2>/dev/null`
in
x$$)
STAT=0 ;;
x)
(cd ../bin ; echo Sorry, `pwd` is not in your shell PATH" ($PATH)")
STAT=1 ;;
*)
echo "Sorry, there is something wrong with your PATH ($PATH)" ;;
esac
echo "echo t_$$" > X_Y_Z_
chmod +x X_Y_Z_
case x`X_Y_Z_`
in
xt_$$)
;;
x)
(cd ../bin ; echo Sorry, . is not in your shell PATH" ($PATH)")
STAT=2 ;;
*)
echo "Sorry, there is something wrong with your PATH ($PATH)" ;;
esac
rm -f X_Y_Z_
case $STAT
in
2)
;;
*)
hash -r ;;
esac
echo "echo l_$$" >x_tpath
chmod +x x_tpath
case x`(x_tpath) 2>/dev/null`
in
xl_$$)
;;
x)
(cd ../bin ; echo Sorry, . is not in your shell PATH" ($PATH)")
STAT=2 ;;
x$$)
echo Sorry, . is not in your PATH" ($PATH)" or after the ACK bin directory
STAT=3 ;;
*)
echo "Sorry, there is something wrong with your PATH ($PATH)"
STAT=4 ;;
esac
rm -f ../bin/x_tpath x_tpath
echo "echo 93" > ../bin/cat
chmod +x ../bin/cat
hash -r
case x`cat < /dev/null 2>/dev/null`
in
x93)
rm -f ../bin/cat
;;
*)
rm -f ../bin/cat
(cd ../bin ; echo Sorry, `pwd` comes too late in your PATH" ($PATH)" )
STAT=13
;;
esac
exit $STAT

View file

@ -1,7 +0,0 @@
if (ack_sys ) >/dev/null 2>&1
then
exit 0
else
echo "You need to run 'first' first"
exit 1
fi

View file

@ -1,75 +0,0 @@
FL=succes
TRIES=
case X$# in
X0)
if (.Xlex) > /dev/null 2>&1
then
TRY=`.Xlex`
else TRY=-lln
fi
echo "trying to find your lex library ..."
cat > x.l <<'EOF'
%%
[A-Z] putchar(yytext[0]+'a'-'A');
EOF
if lex x.l > /dev/null 2>&1 && cc -c lex.yy.c > /dev/null 2>&1
then :
else echo "Sorry, your lex does not seem to work"
exit 2
fi
cat > trylib <<'EOF'
if cc lex.yy.o $1 > /dev/null 2>&1
then
rm -f lex.yy.* a.out
exit 0
else
exit 1
fi
EOF
if sh trylib $TRY
then
LEX=$TRY
else
exec $0 -ll $TRY
fi
;;
*) if sh trylib $1
then
LEX=$1
else
TRIES="$2 and $1"
FL=fail
fi
;;
esac
case X$FL in
Xfail) echo 'What option do I have to give to cc to get the LEX library?'
echo "I tried " $TRIES "but these don't seem to work."
echo -n 'LEX library option: '
if read ANSWER
then :
else echo "Sorry, got EOF while reading your answer"
exit 9
fi
exec $0 $ANSWER "$TRIES"
;;
Xsucces)
for i in ../util/opt ../util/cgg ../util/ncgg ../lang/occam/comp ../modules/src/em_opt ../util/ceg/as_parser
do
( cd $i
cp Makefile makefile
ed - makefile << EOF
/^LEXLIB/c
LEXLIB = $LEX
.
w
q
EOF
)
done
;;
esac
rm -f x.l trylib lex.yy.*
echo echo "$LEX" > .Xlex
chmod +x .Xlex
echo "apparently, \"cc ... $LEX\" works"

View file

View file

@ -1,21 +0,0 @@
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[];
{
int nflag = 0;
if(argc > 1 && ! strncmp(argv[1], "-n", 2)) {
nflag++;
argc--;
argv++;
}
while (--argc > 0) {
fputs(argv[1], stdout);
argv++;
if (argc > 1) putchar(' ');
}
if (!nflag) putchar('\n');
exit(0);
}

View file

@ -1,26 +0,0 @@
/* $Header$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/*fundamental */
#define sz_byte 1
#define sz_bool 1
#define sz_char 1
/* target machine characteristics */
/* variable (see pc.c) */
#define sz_addr sizes[0]
#define sz_real sizes[1]
#define sz_head sizes[2]
#define sz_buff sizes[3]
#define sz_mset sizes[4]
#define sz_iset sizes[5]
#define sz_word sizes[6]
#define sz_int sizes[7]
#define sz_long sizes[8]
#define sz_last 8
#define sz_proc 2*sz_addr

View file

@ -1,28 +0,0 @@
#ifdef __CHANNEL__
#define NCC 8
#define VMIN 4
#define VTIME 5
#define ICRNL 0000400
#define ONLCR 0000004
#define ICANON 0000002
#define ECHO 0000010
struct termio {
unsigned short c_iflag;
unsigned short c_oflag;
unsigned short c_cflag;
unsigned short c_lflag;
char c_line;
unsigned char c_cc[NCC];
};
#define TIOC ('T'<<8)
#define TCGETA (TIOC|1)
#define TCSETA (TIOC|2)
#else
#include "/usr/include/termio.h"
#endif

View file

@ -1,64 +0,0 @@
# $Header$
EMHOME=../../..
h=$(EMHOME)/h
m=$(EMHOME)/modules/h
LIBDIR= $(EMHOME)/modules/lib
LIBDIR2= $(EMHOME)/lib
CFLAGS = -I$h -I$m -O
FILES= bem.o symbols.o initialize.o compile.o \
parsepar.o gencode.o util.o graph.o \
eval.o func.o basic.o Lpars.o
CSRCFILES= bem.c symbols.c initialize.c compile.c \
parsepar.c gencode.c util.c graph.c \
eval.c func.c
CGENFILES= basic.c Lpars.c
CFILES=$(CSRCFILES) $(CGENFILES)
LIBFILES= $(LIBDIR)/libem_mes.a $(LIBDIR)/libemk.a \
$(LIBDIR2)/em_data.a $(LIBDIR)/libprint.a \
$(LIBDIR)/liballoc.a \
$(LIBDIR)/libsystem.a $(LIBDIR)/libstring.a
LINTLIBFILES= $(LIBDIR)/llib-lem_mes.ln $(LIBDIR)/llib-lemk.ln \
$(LIBDIR)/llib-lprint.ln \
$(LIBDIR)/llib-lalloc.ln \
$(LIBDIR)/llib-lsystem.ln $(LIBDIR)/llib-lstring.ln
all: dummy bem
dummy: basic.g
LLgen basic.g
touch dummy
install: all
cp bem $(EMHOME)/lib/em_bem
cmp: all
cmp bem $(EMHOME)/lib/em_bem
pr:
@pr Makefile maketokentab bem.h symbols.h graph.h basic.g basic.lex $(CSRCFILES)
opr:
make pr | opr
bem: $(FILES) $(LIBFILES)
$(CC) -o bem $(FILES) $(LIBFILES)
basic.o : basic.c basic.lex Lpars.h llmess.c tokentab.h
$(CC) $(CFLAGS) -c basic.c
$(FILES): bem.h symbols.h graph.h
tokentab.h: Lpars.h
maketokentab
lint: dummy $(CFILES) tokentab.h
lint -b $(CFLAGS) $(CFILES) $(LINTLIBFILES)
clean:
rm -f *.o
rm -f basic.c Lpars.h Lpars.c dummy tokentab.h bem

View file

@ -1,143 +0,0 @@
!File: lint.h
#define LINT 1 /* if defined, 'lint' is produced */
#define ANSI 1 /* tell l_* files it's ANSI */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */
#define ERR_SHADOW 0 /* a syntax error overshadows error messages
until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h
#define NPARAMS 32 /* maximum number of parameters */
#define STDC_NPARAMS 31 /* ANSI limit on number of parameters */
!File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h
#define DENSITY 2 /* see switch.[ch] for an explanation */
!File: macbuf.h
#define LAPBUF 128 /* initial size of macro replacement buffer */
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
!File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */
#define RSTRSIZE 16 /* step size in enlarging the memory for
the storage of a string */
!File: trgt_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */
#define SZ_CHAR 1
#define SZ_SHORT 2
#define SZ_WORD 4
#define SZ_INT 4
#define SZ_LONG 4
#define SZ_FLOAT 4
#define SZ_DOUBLE 8
#define SZ_POINTER 4
#define SZ_LNGDBL 8 /* for now */
/* target machine alignment requirements */
#define AL_CHAR 1
#define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#define AL_LNGDBL SZ_WORD
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
!File: botch_free.h
#undef BOTCH_FREE 1 /* when defined, botch freed memory, as a check */
!File: dataflow.h
#undef DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h
#undef DEBUG 1 /* perform various self-tests */
!File: use_tmp.h
#undef PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
and if USE_TMP is defined let them
precede the rest of the generated
compact code */
#undef USE_TMP 1 /* use C_insertpart, C_endpart mechanism
to generate EM-code in the order needed
for the code-generators. If not defined,
the old-style peephole optimizer is
needed. */
!File: parbufsize.h
#define PARBUFSIZE 1024
!File: textsize.h
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
!File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */
!File: nopp.h
#undef NOPP 1 /* if NOT defined, use built-int preprocessor */
!File: nobitfield.h
#undef NOBITFIELD 1 /* if NOT defined, implement bitfields */
!File: spec_arith.h
/* describes internal compiler arithmetics */
#undef SPECIAL_ARITHMETICS /* something different from native long */
#undef UNSIGNED_ARITH unsigned arith
!File: static.h
#define GSTATIC /* for large global "static" arrays */
!File: nocross.h
#undef NOCROSS 1 /* if NOT defined, cross compiler */
!File: regcount.h
#undef REGCOUNT 1 /* count occurrences for register messages */
!File: dbsymtab.h
#undef DBSYMTAB 1 /* ability to produce symbol table for debugger */

View file

@ -1,718 +0,0 @@
# $Header$
# M A K E F I L E F O R A C K C - C O M P I L E R
# Machine and environ dependent definitions
EMHOME = /usr/em# # ACK tree on this machine
DESTINATION = /user1/$$USER/bin# # where to put the stuff
MKDEP = $(EMHOME)/bin/mkdep# # dependency generator
MAP =
#MAP = -DInsertFile=ins_file -DInsertText=ins_text# bug in m68k2 back end
SIM = /user1/dick/bin/sim# # Dicks sim program
LINT = /usr/new/lint
# Libraries and EM interface definitions
SYSLIB = $(EMHOME)/modules/lib/libsystem.a
EMKLIB = $(EMHOME)/modules/lib/libemk.a
EMELIB = $(EMHOME)/modules/lib/libeme.a $(EMHOME)/lib/em_data.a
STRLIB = $(EMHOME)/modules/lib/libstring.a
PRTLIB = $(EMHOME)/modules/lib/libprint.a
EMMESLIB = $(EMHOME)/modules/lib/libem_mes.a
INPLIB = $(EMHOME)/modules/lib/libinput.a
ALLOCLIB = $(EMHOME)/modules/lib/liballoc.a
MALLOC = $(EMHOME)/modules/lib/malloc.o
#CH3LIB = $(EMHOME)/modules/lib/libch3.a
CH3LIB =
LIBS = $(INPLIB) $(CH3LIB) $(EMMESLIB) $(EMKLIB) \
$(PRTLIB) $(STRLIB) $(ALLOCLIB) $(MALLOC) $(SYSLIB)
ELIBS = $(INPLIB) $(CH3LIB) $(EMMESLIB) $(EMELIB) \
$(PRTLIB) $(STRLIB) $(ALLOCLIB) $(MALLOC) $(SYSLIB)
LIB_INCLUDES = -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg
EM_INCLUDES = -I$(EMHOME)/h
SYSLLIB = $(EMHOME)/modules/lib/llib-lsys.ln
EMKLLIB = $(EMHOME)/modules/lib/llib-lemk.ln
EMELLIB = $(EMHOME)/modules/lib/llib-leme.ln
STRLLIB = $(EMHOME)/modules/lib/llib-lstr.ln
PRTLLIB = $(EMHOME)/modules/lib/llib-lprint.ln
EMMESLLIB = $(EMHOME)/modules/lib/llib-lmes.ln
INPLLIB = $(EMHOME)/modules/lib/llib-linput.ln
CH3LLIB = $(EMHOME)/modules/lib/llib-lch3.ln
ALLOCLLIB = $(EMHOME)/modules/lib/llib-alloc.ln
LINTLIBS =
#LINTLIBS = $(CH3LLIB) $(INPLLIB) $(EMMESLLIB) $(EMKLLIB) \
# $(PRTLLIB) $(STRLLIB) $(SYSLLIB) $(ALLOCLLIB)
# Where to install the compiler and its driver
CEMCOM = $(DESTINATION)/cemcom
DRIVER = $(DESTINATION)/cem
# What C compiler to use and how
# CC = $(ACK) -.c
# CC = CC
# CC = /bin/cc
COPTIONS =
# What parser generator to use and how
GEN = $(EMHOME)/bin/LLgen
GENOPTIONS = -vv
# Special #defines during compilation
CDEFS = $(MAP) $(EM_INCLUDES) $(LIB_INCLUDES)
CFLAGS = $(CDEFS) $(COPTIONS) -O# we cannot pass the COPTIONS to lint!
# Grammar files and their objects
LSRC = tokenfile.g declar.g statement.g expression.g program.g ival.g
GLCSRC = tokenfile.c declar.c statement.c expression.c program.c Lpars.c ival.c
LOBJ = tokenfile.o declar.o statement.o expression.o program.o Lpars.o ival.o
CSRC = main.c idf.c declarator.c decspecs.c struct.c \
expr.c ch7.c ch7bin.c cstoper.c arith.c \
asm.c code.c dumpidf.c error.c field.c\
tokenname.c LLlex.c LLmessage.c \
input.c domacro.c replace.c init.c options.c \
scan.c skip.c stack.c type.c ch7mon.c label.c eval.c \
switch.c conversion.c util.c \
blocks.c dataflow.c Version.c
# Objects of hand-written C files
COBJ = main.o idf.o declarator.o decspecs.o struct.o \
expr.o ch7.o ch7bin.o cstoper.o arith.o \
asm.o code.o dumpidf.o error.o field.o\
tokenname.o LLlex.o LLmessage.o \
input.o domacro.o replace.o init.o options.o \
scan.o skip.o stack.o type.o ch7mon.o label.o eval.o \
switch.o conversion.o util.o \
blocks.o dataflow.o Version.o
# Objects of other generated C files
GCSRC = char.c symbol2str.c next.c
GOBJ = char.o symbol2str.o next.o
# generated source files
GSRC = char.c symbol2str.c next.c \
code.h declar.h decspecs.h def.h expr.h field.h estack.h \
idf.h macro.h stack.h stmt.h struct.h switch.h type.h util.h
# .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE!
GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
idfsize.h ifdepth.h inputtype.h inumlength.h lapbuf.h \
nobitfield.h nofloat.h nopp.h noRoption.h nocross.h \
nparams.h numsize.h parbufsize.h pathlength.h \
strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h \
reg_count.h
# Other generated files, for 'make clean' only
GENERATED = tokenfile.g Lpars.h LLfiles LL.output lint.out \
print Xref lxref hfiles cfiles $(GLCSRC)
# include files containing ALLOCDEF specifications
NEXTFILES = code.str declar.str decspecs.str def.str expr.str field.str \
estack.str util.str \
idf.str macro.str stack.str stmt.str struct.str switch.str type.str
.SUFFIXES: .str .h
.str.h:
./make.allocd <$*.str >$*.h
all: cc
cc:
make "EMHOME="$(EMHOME) "CC=$(CC)" hfiles
make "EMHOME="$(EMHOME) "CC=$(CC)" LLfiles
make "EMHOME="$(EMHOME) "CC=$(CC)" main
cem: cem.c
$(CC) -O cem.c $(SYSLIB) -o cem
lint.cem: cem.c
$(LINT) -bx cem.c
hfiles: ./make.hfiles Parameters
./make.hfiles Parameters
@touch hfiles
LLfiles: $(LSRC)
$(GEN) $(GENOPTIONS) $(LSRC)
@touch LLfiles
tokenfile.g: tokenname.c make.tokfile
<tokenname.c ./make.tokfile >tokenfile.g
symbol2str.c: tokenname.c make.tokcase
<tokenname.c ./make.tokcase >symbol2str.c
char.c: char.tab
$(EMHOME)/bin/tabgen -fchar.tab >char.c
next.c: make.next $(NEXTFILES)
./make.next $(NEXTFILES) >next.c
code.h: make.allocd
declar.h: make.allocd
decspecs.h: make.allocd
def.h: make.allocd
estack.h: make.allocd
expr.h: make.allocd
field.h: make.allocd
idf.h: make.allocd
macro.h: make.allocd
stack.h: make.allocd
stmt.h: make.allocd
struct.h: make.allocd
switch.h: make.allocd
type.h: make.allocd
util.h: make.allocd
# Objects needed for 'main'
OBJ = $(COBJ) $(LOBJ) $(GOBJ)
SRC = $(CSRC) $(LCSRC) $(GCSRC)
main: $(OBJ) Makefile.erik
$(CC) $(COPTIONS) $(LFLAGS) $(OBJ) $(LIBS) -o main
size main
emain: $(OBJ) Makefile.erik
$(CC) $(COPTIONS) $(LFLAGS) $(OBJ) $(ELIBS) -o emain
size emain
cfiles: hfiles LLfiles $(GSRC)
@touch cfiles
install: main cem
cp main $(CEMCOM)
cp cem $(DRIVER)
print: files
pr `cat files` > print
tags: cfiles
ctags $(SRC)
shar: files
shar `cat files`
listcfiles:
@echo $(SRC)
listobjects:
@echo $(OBJ)
depend: cfiles
sed '/^#AUTOAUTO/,$$d' Makefile.erik >Makefile.erik.new
echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >>Makefile.erik.new
$(MKDEP) $(SRC) | sed 's/\.c:/.o:/' >>Makefile.erik.new
mv Makefile.erik Makefile.erik.old
mv Makefile.erik.new Makefile.erik
xref:
ctags -x `grep "\.[ch]" files`|sed "s/).*/)/">Xref
lxref:
lxref $(OBJ) -lc >lxref
lint: lint.main lint.cem
lint.main: cfiles
$(LINT) -bx $(CDEFS) $(SRC) $(LINTLIBS) >lint.out
cchk:
cchk $(SRC)
clean:
rm -f $(LCSRC) $(OBJ) $(GENERATED) $(GSRC) $(GHSRC)
sim: cfiles
$(SIM) $(SIMFLAGS) $(CSRC) $(GSRC) $(LSRC)
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
main.o: LLlex.h
main.o: Lpars.h
main.o: align.h
main.o: arith.h
main.o: debug.h
main.o: declar.h
main.o: file_info.h
main.o: idf.h
main.o: input.h
main.o: inputtype.h
main.o: level.h
main.o: noRoption.h
main.o: nobitfield.h
main.o: nocross.h
main.o: nofloat.h
main.o: nopp.h
main.o: sizes.h
main.o: spec_arith.h
main.o: specials.h
main.o: target_sizes.h
main.o: tokenname.h
main.o: type.h
main.o: use_tmp.h
idf.o: LLlex.h
idf.o: Lpars.h
idf.o: align.h
idf.o: arith.h
idf.o: assert.h
idf.o: botch_free.h
idf.o: debug.h
idf.o: declar.h
idf.o: decspecs.h
idf.o: def.h
idf.o: file_info.h
idf.o: idf.h
idf.o: idfsize.h
idf.o: label.h
idf.o: level.h
idf.o: noRoption.h
idf.o: nobitfield.h
idf.o: nocross.h
idf.o: nofloat.h
idf.o: nopp.h
idf.o: sizes.h
idf.o: spec_arith.h
idf.o: specials.h
idf.o: stack.h
idf.o: struct.h
idf.o: target_sizes.h
idf.o: type.h
declarator.o: Lpars.h
declarator.o: arith.h
declarator.o: botch_free.h
declarator.o: declar.h
declarator.o: expr.h
declarator.o: idf.h
declarator.o: label.h
declarator.o: nobitfield.h
declarator.o: nocross.h
declarator.o: nofloat.h
declarator.o: nopp.h
declarator.o: sizes.h
declarator.o: spec_arith.h
declarator.o: target_sizes.h
declarator.o: type.h
decspecs.o: Lpars.h
decspecs.o: arith.h
decspecs.o: decspecs.h
decspecs.o: def.h
decspecs.o: level.h
decspecs.o: noRoption.h
decspecs.o: nobitfield.h
decspecs.o: nofloat.h
decspecs.o: spec_arith.h
decspecs.o: type.h
struct.o: LLlex.h
struct.o: Lpars.h
struct.o: align.h
struct.o: arith.h
struct.o: assert.h
struct.o: botch_free.h
struct.o: debug.h
struct.o: def.h
struct.o: field.h
struct.o: file_info.h
struct.o: idf.h
struct.o: level.h
struct.o: noRoption.h
struct.o: nobitfield.h
struct.o: nocross.h
struct.o: nofloat.h
struct.o: nopp.h
struct.o: sizes.h
struct.o: spec_arith.h
struct.o: stack.h
struct.o: struct.h
struct.o: target_sizes.h
struct.o: type.h
expr.o: LLlex.h
expr.o: Lpars.h
expr.o: arith.h
expr.o: botch_free.h
expr.o: declar.h
expr.o: decspecs.h
expr.o: def.h
expr.o: expr.h
expr.o: file_info.h
expr.o: idf.h
expr.o: label.h
expr.o: level.h
expr.o: noRoption.h
expr.o: nobitfield.h
expr.o: nocross.h
expr.o: nofloat.h
expr.o: nopp.h
expr.o: sizes.h
expr.o: spec_arith.h
expr.o: target_sizes.h
expr.o: type.h
ch7.o: Lpars.h
ch7.o: arith.h
ch7.o: assert.h
ch7.o: debug.h
ch7.o: def.h
ch7.o: expr.h
ch7.o: idf.h
ch7.o: label.h
ch7.o: nobitfield.h
ch7.o: nofloat.h
ch7.o: nopp.h
ch7.o: spec_arith.h
ch7.o: struct.h
ch7.o: type.h
ch7bin.o: Lpars.h
ch7bin.o: arith.h
ch7bin.o: botch_free.h
ch7bin.o: expr.h
ch7bin.o: idf.h
ch7bin.o: label.h
ch7bin.o: noRoption.h
ch7bin.o: nobitfield.h
ch7bin.o: nofloat.h
ch7bin.o: nopp.h
ch7bin.o: spec_arith.h
ch7bin.o: struct.h
ch7bin.o: type.h
cstoper.o: Lpars.h
cstoper.o: arith.h
cstoper.o: assert.h
cstoper.o: debug.h
cstoper.o: expr.h
cstoper.o: idf.h
cstoper.o: label.h
cstoper.o: nobitfield.h
cstoper.o: nocross.h
cstoper.o: nofloat.h
cstoper.o: nopp.h
cstoper.o: sizes.h
cstoper.o: spec_arith.h
cstoper.o: target_sizes.h
cstoper.o: type.h
arith.o: Lpars.h
arith.o: arith.h
arith.o: botch_free.h
arith.o: expr.h
arith.o: field.h
arith.o: idf.h
arith.o: label.h
arith.o: mes.h
arith.o: noRoption.h
arith.o: nobitfield.h
arith.o: nofloat.h
arith.o: nopp.h
arith.o: spec_arith.h
arith.o: type.h
code.o: Lpars.h
code.o: arith.h
code.o: assert.h
code.o: atw.h
code.o: botch_free.h
code.o: code.h
code.o: dataflow.h
code.o: debug.h
code.o: declar.h
code.o: decspecs.h
code.o: def.h
code.o: expr.h
code.o: file_info.h
code.o: idf.h
code.o: label.h
code.o: level.h
code.o: noRoption.h
code.o: nobitfield.h
code.o: nocross.h
code.o: nofloat.h
code.o: nopp.h
code.o: sizes.h
code.o: spec_arith.h
code.o: specials.h
code.o: stack.h
code.o: stmt.h
code.o: target_sizes.h
code.o: type.h
code.o: use_tmp.h
dumpidf.o: Lpars.h
dumpidf.o: arith.h
dumpidf.o: debug.h
dumpidf.o: def.h
dumpidf.o: expr.h
dumpidf.o: field.h
dumpidf.o: idf.h
dumpidf.o: label.h
dumpidf.o: nobitfield.h
dumpidf.o: nofloat.h
dumpidf.o: nopp.h
dumpidf.o: spec_arith.h
dumpidf.o: stack.h
dumpidf.o: static.h
dumpidf.o: struct.h
dumpidf.o: type.h
error.o: LLlex.h
error.o: arith.h
error.o: debug.h
error.o: errout.h
error.o: expr.h
error.o: file_info.h
error.o: label.h
error.o: nofloat.h
error.o: nopp.h
error.o: spec_arith.h
error.o: tokenname.h
field.o: Lpars.h
field.o: align.h
field.o: arith.h
field.o: assert.h
field.o: code.h
field.o: debug.h
field.o: expr.h
field.o: field.h
field.o: idf.h
field.o: label.h
field.o: nobitfield.h
field.o: nocross.h
field.o: nofloat.h
field.o: nopp.h
field.o: sizes.h
field.o: spec_arith.h
field.o: target_sizes.h
field.o: type.h
tokenname.o: LLlex.h
tokenname.o: Lpars.h
tokenname.o: arith.h
tokenname.o: file_info.h
tokenname.o: idf.h
tokenname.o: nofloat.h
tokenname.o: nopp.h
tokenname.o: spec_arith.h
tokenname.o: tokenname.h
LLlex.o: LLlex.h
LLlex.o: Lpars.h
LLlex.o: arith.h
LLlex.o: assert.h
LLlex.o: class.h
LLlex.o: debug.h
LLlex.o: def.h
LLlex.o: file_info.h
LLlex.o: idf.h
LLlex.o: idfsize.h
LLlex.o: input.h
LLlex.o: nocross.h
LLlex.o: nofloat.h
LLlex.o: nopp.h
LLlex.o: numsize.h
LLlex.o: sizes.h
LLlex.o: spec_arith.h
LLlex.o: strsize.h
LLlex.o: target_sizes.h
LLmessage.o: LLlex.h
LLmessage.o: Lpars.h
LLmessage.o: arith.h
LLmessage.o: file_info.h
LLmessage.o: idf.h
LLmessage.o: nofloat.h
LLmessage.o: nopp.h
LLmessage.o: spec_arith.h
input.o: file_info.h
input.o: input.h
input.o: inputtype.h
input.o: nopp.h
domacro.o: LLlex.h
domacro.o: Lpars.h
domacro.o: arith.h
domacro.o: assert.h
domacro.o: botch_free.h
domacro.o: class.h
domacro.o: debug.h
domacro.o: file_info.h
domacro.o: idf.h
domacro.o: idfsize.h
domacro.o: ifdepth.h
domacro.o: input.h
domacro.o: interface.h
domacro.o: macro.h
domacro.o: nofloat.h
domacro.o: nopp.h
domacro.o: nparams.h
domacro.o: parbufsize.h
domacro.o: spec_arith.h
domacro.o: textsize.h
replace.o: LLlex.h
replace.o: arith.h
replace.o: assert.h
replace.o: class.h
replace.o: debug.h
replace.o: file_info.h
replace.o: idf.h
replace.o: input.h
replace.o: interface.h
replace.o: macro.h
replace.o: nofloat.h
replace.o: nopp.h
replace.o: pathlength.h
replace.o: spec_arith.h
replace.o: static.h
replace.o: strsize.h
init.o: class.h
init.o: idf.h
init.o: interface.h
init.o: macro.h
init.o: nopp.h
options.o: align.h
options.o: arith.h
options.o: botch_free.h
options.o: class.h
options.o: dataflow.h
options.o: idf.h
options.o: idfsize.h
options.o: macro.h
options.o: noRoption.h
options.o: nobitfield.h
options.o: nocross.h
options.o: nofloat.h
options.o: nopp.h
options.o: sizes.h
options.o: spec_arith.h
options.o: target_sizes.h
options.o: use_tmp.h
scan.o: class.h
scan.o: idf.h
scan.o: input.h
scan.o: interface.h
scan.o: lapbuf.h
scan.o: macro.h
scan.o: nopp.h
scan.o: nparams.h
skip.o: LLlex.h
skip.o: arith.h
skip.o: class.h
skip.o: file_info.h
skip.o: input.h
skip.o: interface.h
skip.o: nofloat.h
skip.o: nopp.h
skip.o: spec_arith.h
stack.o: Lpars.h
stack.o: arith.h
stack.o: botch_free.h
stack.o: debug.h
stack.o: def.h
stack.o: idf.h
stack.o: level.h
stack.o: mes.h
stack.o: noRoption.h
stack.o: nobitfield.h
stack.o: nofloat.h
stack.o: nopp.h
stack.o: spec_arith.h
stack.o: stack.h
stack.o: struct.h
stack.o: type.h
type.o: Lpars.h
type.o: align.h
type.o: arith.h
type.o: botch_free.h
type.o: def.h
type.o: idf.h
type.o: nobitfield.h
type.o: nocross.h
type.o: nofloat.h
type.o: nopp.h
type.o: sizes.h
type.o: spec_arith.h
type.o: target_sizes.h
type.o: type.h
ch7mon.o: Lpars.h
ch7mon.o: arith.h
ch7mon.o: botch_free.h
ch7mon.o: def.h
ch7mon.o: expr.h
ch7mon.o: idf.h
ch7mon.o: label.h
ch7mon.o: nobitfield.h
ch7mon.o: nofloat.h
ch7mon.o: nopp.h
ch7mon.o: spec_arith.h
ch7mon.o: type.h
label.o: Lpars.h
label.o: arith.h
label.o: def.h
label.o: idf.h
label.o: label.h
label.o: level.h
label.o: noRoption.h
label.o: nobitfield.h
label.o: nofloat.h
label.o: nopp.h
label.o: spec_arith.h
label.o: type.h
eval.o: Lpars.h
eval.o: align.h
eval.o: arith.h
eval.o: assert.h
eval.o: atw.h
eval.o: code.h
eval.o: dataflow.h
eval.o: debug.h
eval.o: def.h
eval.o: expr.h
eval.o: idf.h
eval.o: label.h
eval.o: level.h
eval.o: mes.h
eval.o: nobitfield.h
eval.o: nocross.h
eval.o: nofloat.h
eval.o: nopp.h
eval.o: sizes.h
eval.o: spec_arith.h
eval.o: specials.h
eval.o: stack.h
eval.o: target_sizes.h
eval.o: type.h
switch.o: Lpars.h
switch.o: arith.h
switch.o: assert.h
switch.o: botch_free.h
switch.o: code.h
switch.o: debug.h
switch.o: density.h
switch.o: expr.h
switch.o: idf.h
switch.o: label.h
switch.o: noRoption.h
switch.o: nobitfield.h
switch.o: nofloat.h
switch.o: nopp.h
switch.o: spec_arith.h
switch.o: switch.h
switch.o: type.h
conversion.o: Lpars.h
conversion.o: arith.h
conversion.o: nobitfield.h
conversion.o: nocross.h
conversion.o: nofloat.h
conversion.o: sizes.h
conversion.o: spec_arith.h
conversion.o: target_sizes.h
conversion.o: type.h
util.o: Lpars.h
util.o: align.h
util.o: def.h
util.o: nocross.h
util.o: nofloat.h
util.o: regcount.h
util.o: sizes.h
util.o: stack.h
util.o: target_sizes.h
util.o: use_tmp.h
util.o: util.h
blocks.o: Lpars.h
blocks.o: align.h
blocks.o: arith.h
blocks.o: atw.h
blocks.o: label.h
blocks.o: nocross.h
blocks.o: nofloat.h
blocks.o: sizes.h
blocks.o: spec_arith.h
blocks.o: stack.h
blocks.o: target_sizes.h
dataflow.o: dataflow.h
char.o: class.h
symbol2str.o: Lpars.h

View file

@ -1,67 +0,0 @@
: create a directory Xsrc with name clashes resolved
: and run make in that directory
: '$Header$'
case $# in
1)
;;
*) echo "$0: one argument expected" 1>&2
exit 1
;;
esac
PW=`pwd`
options=
case $1 in
main|emain|lnt)
target=$PW/$1
;;
omain)
target=$PW/$1
options=-DPEEPHOLE
;;
cemain)
target=$PW/$1
options=-DCODE_EXPANDER
;;
Xlint)
target=$1
;;
*) echo "$0: $1: Illegal argument" 1>&2
exit 1
;;
esac
if test -d ../Xsrc
then
:
else mkdir ../Xsrc
fi
make EMHOME=$EMHOME longnames
: remove code generating routines from the clashes list as they are defines.
: code generating routine names start with C_
sed '/^C_/d' < longnames > tmp$$
cclash -c -l7 tmp$$ > ../Xsrc/Xclashes
rm -f tmp$$
cd ../Xsrc
if cmp -s Xclashes clashes
then
:
else
mv Xclashes clashes
fi
rm -f Makefile
for i in `cat $PW/Cfiles`
do
cat >> Makefile <<EOF
$i: clashes $PW/$i
cid -Fclashes < $PW/$i > $i
EOF
done
make EMHOME=$EMHOME `cat $PW/Cfiles`
rm -f Makefile
ed - $PW/Makefile <<'EOF'
/^#EXCLEXCL/,/^#INCLINCL/d
w Makefile
q
EOF
make EMHOME=$EMHOME COPTIONS=$options MACH=$mach CURRDIR=$PW/ $target

View file

@ -1,8 +0,0 @@
/* $Header$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef lint
static char Version[] = "ACK CEM compiler Version 3.1";
#endif lint

View file

@ -1,16 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* A S M */
/*ARGSUSED*/
code_asm(s, l)
char *s;
int l;
{
/* 'asm' '(' string ')' ';'
*/
error("\"asm\" instruction not implemented");
}

View file

@ -1,230 +0,0 @@
.TH CEM 1L 86/11/12
.SH NAME
cem \- ACK C compiler
.SH SYNOPSIS
.B cem
[ option ] ... file ...
.SH DESCRIPTION
.I Cem
is a
.I cc (1)-like
C compiler that uses the C front-end compiler
.I cemcom (1)
of the Amsterdam Compiler Kit.
.I Cem
interprets its arguments not starting with a '\-' as
source files, to be compiled by the various parts of the compilation process,
which are listed below.
File arguments whose names end with \fB.\fP\fIcharacter\fP are interpreted as
follows:
.IP .[ao]
object file.
.IP .[ci]
C source code
.IP .e
EM assembler source file.
.IP .k
compact EM file, not yet optimized by the EM peephole optimizer.
.IP .m
compact EM file, already optimized by the peephole optimizer.
.IP .s
assembler file.
.LP
The actions to be taken by
.I cem
are directed by the type of file argument and the various options that are
presented to it.
.PP
The following set of options, which is a mixture of options interpreted by
.I cc (1)
and
.I ack (?)
are interpreted by
.I cem .
(The options not specified here are passed to the loader.)
.IP \fB\-B\fP\fIname\fP
Use
.I name
as front-end compiler instead of the default
.I cemcom (1).
.br
Same as "\fB\-Rcem=\fP\fIname\fP".
.IP \fB\-C\fP
Run C preprocessor
.I /lib/cpp
only and prevent it from eliding comments.
.IP \fB\-D\fP\fIname\fP\fB=\fP\fIdef\fP
Define the
.I name
to the preprocessor, as if by "#define".
.IP \fB\-D\fP\fIname\fP
.br
Same as "\fB\-D\fP\fIname\fP\fB=1\fP".
.IP \fB\-E\fP
Run only the macro preprocessor on the named files and send the
result to standard output.
.IP \fB\-I\fP\fIdir\fP
\&"#include" files whose names do not begin with '/' are always
sought first in the directory of the \fIfile\fP argument, then in directories
in \fB\-I\fP options, then in directories on a standard list (which in fact
consists of "/usr/include").
.IP \fB\-L\fP\fIdir\fP
Use \fIdir\fP as library-containing directory instead of the default.
.IP \fB\-N\fP\fIc\fP
Only effective if ACK pipeline is used.
This option causes some default actions and options to be suppressed, according
to
.I c :
.RS
.IP \fBc\fP
do not convert from EM a.out to local a.out format (i.e., skip the
.B cv
pass.)
.IP \fBl\fP
do not pass the default loader flags to the
.B ld
pass.
.RE
.IP \fB\-P\fP
Same as \fB\-E\fP, but sending the result of input file \fIfile\fP\fB.[ceis]\fP
to \fIfile\fP\fB.i\fP.
.IP \fB\-R\fP
Passed to \fIcemcom\fP(1) in order to parse the named C programs according
to the C language as described in [K&R] (also called \fIRestricted\fP C).
.IP \fB\-R\fP\fIprog\fP\fB=\fP\fIname\fP
.br
Use \fIname\fP as program for phase \fIprog\fP of the compilation instead of
the default.
\&\fIProg\fP is one of the following names:
.RS
.IP \fBcpp\fP
macro preprocessor
.IP \fBcem\fP
front\-end compiler
.IP \fBopt\fP
EM peephole optimizer
.IP \fBdecode\fP
EM compact to EM assembler translator
.IP \fBencode\fP
EM assembler to EM compact translator
.IP \fBbe\fP
EM compact code to target\-machine assembly code compiler
.IP \fBcg\fP
same as \fBbe\fP
.IP \fBas\fP
assembler
.IP \fBld\fP
linker/loader
.IP \fBcv\fP
a.out format converting program (only if ACK pipeline is used)
.RE
.IP \fB\-R\fP\fIprog\fP\fB\-\fP\fIoption\fP
.br
Pass \fB\-\fP\fIoption\fP to the compilation phase indicated by \fIprog\fP.
.IP \fB\-S\fP
Same as \fB\-c.s\fP.
.IP \fB\-U\fP\fIname\fP
.br
Remove any initial definition of \fIname\fP.
.IP \fB\-V\fP\fIcm\fP.\fIn\fP,\ \fB\-V\fIcm\fP.\fIncm\fP.\fIn\fP\ ...
.br
Set the size and alignment requirements of the C constructs of the named
C input files.
The letter \fIc\fP indicates the simple type, which is one of
\fBs\fP(short), \fBi\fP(int), \fBl\fP(long), \fBf\fP(float), \fBd\fP(double) or
\fBp\fP(pointer).
The \fIm\fP parameter can be used to specify the length of the type (in bytes)
and the \fIn\fP parameter for the alignment of that type.
Absence of \fIm\fP or \fIn\fP causes the default value to be retained.
To specify that the bitfields should be right adjusted instead of the
default left adjustment, specify \fBr\fP as \fIc\fP parameter
without parameters.
.br
This option is passed directly to \fIcemcom\fP(1).
.IP \fB\-c\fP
Same as \fB\-c.o\fP.
.IP \fB\-c.e\fP
Produce human-readable EM assembly code on \fIfile\fP\fB.e\fP for the
named files \fIfile\fP\fB.[cikm]\fP
.IP \fB\-c.k\fP
Compile C source \fIfile\fP\fB.[ci]\fP or
encode human-readable EM assembly code from \fIfile\fP\fB.e\fP
into non-optimized compact EM code and write the result on \fIfile\fP\fB.k\fP
.IP \fB\-c.m\fP
Compile C source \fIfile\fP\fB.[ci]\fP,
translate non-optimized EM code from \fIfile\fP\fB.k\fP or
encode EM assembly code from \fIfile\fP\fB.e\fP
into optimized compact EM code and write the result on \fIfile\fP\fB.m\fP
.IP \fB\-c.o\fP
Suppress the loading phase of the compilation, and force an object file to
be produced even if only one program is compiled
.IP \fB\-c.s\fP
Compile the named \fIfile\fP\fB.[ceikm]\fP input files, and leave the
assembly language output on corresponding files suffixed ".s".
.IP \fB\-k\fP
Same as \fB\-c.k\fP.
.IP \fB\-l\fP\fIname\fP
.br
Append the library \fBlib\fP\fIname\fP\fB.a\fP to the list of files that
should be loaded and linked into the final output file.
The library is searched for in the library directory.
.IP \fB\-m\fP
Same as \fB\-c.m\fP.
.IP \fB\-o\fP\ \fIoutput\fP
.br
Name the final output file \fIoutput\fP.
If this option is used, the default "a.out" will be left undisturbed.
.IP \fB\-p\fP
Produce EM profiling code (\fBfil\fP and \fBlin\fP instructions to
enable an interpreter to keep track of the current location in the
source code)
.IP \fB\-t\fP
Keep the intermediate files, produced during the various phases of the
compilation.
The produced files are named \fIfile\fP\fB.\fP\fIcharacter\fP where
\&\fIcharacter\fP indicates the type of the file as listed before.
.IP \fB\-v\fP
Verbose.
Print the commands before they are executed.
.IP \fB\-vn\fP
Do not really execute (for debugging purposes only).
.IP \fB\-vd\fP
Print some additional information (for debugging purposes only).
.IP \fB\-\-\fP\fIanything\fP
.br
Equivalent to \fB\-Rcem\-\-\fP\fIanything\fP.
The options
.B \-\-C ,
.B \-\-E
and
.B \-\-P
all have the same effect as respectively
.B \-C ,
.B \-E
and
.B \-P
except for the fact that the macro preprocessor is taken to be the
built\-in preprocessor of the \fBcem\fP phase.
Most "\-\-" options are used by
.I cemcom (1)
to set some internal debug switches.
.LP
.SH SEE ALSO
cemcom(1), cc(1), ack(?), as(1), ld(1)
.br
.IP [K&R]
B.W. Kernighan and D.M. Ritchie, \fIThe C Programming Language\fP,
Prentice-Hall, 1978.
.SH DIAGNOSTICS
.I Cem
reports any failure of its components.
.SH BUGS
.IP \(bu
All intermediate files are placed in the current working directory which
causes files with the same name as the intermediate files to be overwritten.
.IP \(bu
.B Cem
only accepts a limited number of arguments to be passed to the components.
(e.g., 256).
.IP \(bu
Please report suggestions and other bugs to erikb@vu44.uucp

View file

@ -1,764 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
Driver for the CEMCOM compiler: works like /bin/cc and accepts
most of the options accepted by /bin/cc and /usr/em/bin/ack.
Date written: dec 4, 1985
Adapted for 68000 (Aug 19, 1986)
Merged the vax and mantra versions (Nov 10, 1986)
Author: Erik Baalbergen
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>
#define MAXARGC 256 /* maximum number of arguments allowed in a list */
#define USTR_SIZE 1024 /* maximum length of string variable */
struct arglist {
int al_argc;
char *al_argv[MAXARGC];
};
/* some system-dependent variables */
char *PP = "/lib/cpp";
char *CEM = "/usr/em/lib/em_cemcom";
char *ENCODE = "/usr/em/lib/em_encode";
char *DECODE = "/usr/em/lib/em_decode";
char *OPT = "/usr/em/lib/em_opt";
char *SHELL = "/bin/sh";
#ifndef MANTRA
char *CG = "/usr/em/lib/vax4/cg";
char *AS = "/bin/as";
char *AS_FIX = "/user1/erikb/bin/mcomm";
char *LD = "/bin/ld";
char *LIBDIR = "/user1/cem/lib";
char *V_FLAG = "-Vs2.2w4.4i4.4l4.4f4.4d8.4p4.4";
#else MANTRA
char *CG = "/usr/em/lib/m68k2/cg";
char *AS = "/usr/em/lib/m68k2/as";
char *LD = "/usr/em/lib/em_led";
char *CV = "/usr/em/lib/m68k2/cv";
char *LIBDIR = "/usr/em/lib/m68k2";
char *V_FLAG = "-Vs2.2w2.2i2.2l4.2f4.2d8.2p4.2";
#endif MANTRA
struct arglist LD_HEAD = {
2,
{
#ifndef MANTRA
"/usr/em/lib/vax4/head_em",
"/usr/em/lib/vax4/head_cc"
#else MANTRA
"/usr/em/lib/m68k2/head_em",
"/usr/em/lib/m68k2/head_cc"
#endif MANTRA
}
};
struct arglist LD_TAIL = {
#ifndef MANTRA
4,
{
"/user1/cem/lib/libc.a",
"/user1/cem/lib/stb.o",
"/usr/em/lib/vax4/tail_mon",
"/usr/em/lib/vax4/tail_em"
}
#else MANTRA
7,
{
"/usr/em/lib/m68k2/tail_cc.1s",
"/usr/em/lib/m68k2/tail_cc.2g",
"/usr/em/lib/m68k2/tail_cem",
"/usr/em/lib/m68k2/tail_fp.a",
"/usr/em/lib/m68k2/tail_em.rt",
"/usr/em/lib/m68k2/tail_mon",
"/usr/em/lib/m68k2/end_em"
}
#endif MANTRA
};
char *o_FILE = "a.out";
#ifdef MANTRA
char *cv_FILE = "cv.out";
#endif MANTRA
#define remove(str) (((FLAG(t) == 0) && unlink(str)), (str)[0] = '\0')
#define cleanup(str) (str && remove(str))
#define mkname(dst, s1, s2) mkstr(dst, (s1), (s2), 0)
#define init(al) (al)->al_argc = 1
#define library(nm) \
mkstr(alloc((unsigned int)strlen(nm) + strlen(LIBDIR) + 7), \
LIBDIR, "/lib", nm, ".a", 0)
struct arglist SRCFILES, LDFILES, GEN_LDFILES, PP_FLAGS, CEM_FLAGS,
OPT_FLAGS, DECODE_FLAGS, ENCODE_FLAGS, CG_FLAGS, AS_FLAGS,
O_FLAGS, DEBUG_FLAGS, CALL_VEC;
#ifndef MANTRA
struct arglist LD_FLAGS;
#else MANTRA
struct arglist LD_FLAGS = {
5,
{
"-b0:0x80000",
"-a0:2",
"-a1:2",
"-a2:2",
"-a3:2"
}
};
struct arglist CV_FLAGS;
int Nc_flag = 0;
#endif MANTRA
/* option naming */
#define NAME(chr) chr
#define FLAG(chr) NAME(chr)_flag
int E_flag, P_flag, S_flag, c_flag, e_flag, k_flag,
m_flag, o_flag, t_flag, v_flag;
/* various passes */
struct prog {
char *p_name;
char **p_task;
struct arglist *p_flags;
} ProgParts[] = {
{ "cpp", &PP, &PP_FLAGS },
{ "cem", &CEM, &CEM_FLAGS },
{ "opt", &OPT, &OPT_FLAGS },
{ "decode", &DECODE, &DECODE_FLAGS },
{ "encode", &ENCODE, &ENCODE_FLAGS },
{ "be", &CG, &CG_FLAGS },
{ "cg", &CG, &CG_FLAGS },
{ "as", &AS, &AS_FLAGS },
{ "ld", &LD, &LD_FLAGS },
#ifdef MANTRA
{ "cv", &CV, &CV_FLAGS },
#endif MANTRA
{ 0, 0, 0 }
};
/* various forward declarations */
int trap();
char *mkstr();
char *alloc();
long sizeof_file();
/* various globals */
char *ProgCall = 0;
int debug = 0;
int exec = 1;
int RET_CODE = 0;
main(argc, argv)
char *argv[];
{
char *str, **argvec, *file, *ldfile = 0;
int count, ext;
char Nfile[USTR_SIZE], kfile[USTR_SIZE], sfile[USTR_SIZE],
mfile[USTR_SIZE], ofile[USTR_SIZE], BASE[USTR_SIZE];
register struct arglist *call = &CALL_VEC;
set_traps(trap);
ProgCall = *argv++;
append(&CEM_FLAGS, "-L");
while (--argc > 0) {
if (*(str = *argv++) != '-') {
append(&SRCFILES, str);
continue;
}
switch (str[1]) {
case '-':
switch (str[2]) {
case 'C':
case 'E':
case 'P':
FLAG(E) = 1;
append(&PP_FLAGS, str);
PP = CEM;
FLAG(P) = (str[2] == 'P');
break;
default:
append(&DEBUG_FLAGS, str);
break;
}
break;
case 'B':
PP = CEM = &str[2];
break;
case 'C':
case 'E':
case 'P':
FLAG(E) = 1;
append(&PP_FLAGS, str);
FLAG(P) = (str[1] == 'P');
break;
case 'c':
if (str[2] == '.') {
switch (str[3]) {
case 's':
FLAG(S) = 1;
break;
case 'k':
FLAG(k) = 1;
break;
case 'o':
FLAG(c) = 1;
break;
case 'm':
FLAG(m) = 1;
break;
case 'e':
FLAG(e) = 1;
break;
default:
bad_option(str);
}
}
else
if (str[2] == '\0')
FLAG(c) = 1;
else
bad_option(str);
break;
case 'D':
case 'I':
case 'U':
append(&PP_FLAGS, str);
break;
case 'k':
FLAG(k) = 1;
break;
case 'l':
if (str[2] == '\0') /* no standard libraries */
LD_HEAD.al_argc = LD_TAIL.al_argc = 0;
else /* use library from library directory */
append(&SRCFILES, library(&str[2]));
break;
case 'L': /* change default library directory */
LIBDIR = &str[2];
break;
case 'm':
FLAG(m) = 1;
break;
#ifdef MANTRA
case 'N':
switch (str[2]) {
case 'c': /* no a.out conversion */
Nc_flag = 1;
break;
case 'l': /* no default options to led */
LD_FLAGS.al_argc = 0;
break;
default:
bad_option(str);
}
break;
#endif MANTRA
case 'o':
FLAG(o) = 1;
if (argc-- < 0)
bad_option(str);
else
o_FILE = *argv++;
break;
case 'O':
append(&O_FLAGS, "-O");
break;
case 'R':
if (str[2] == '\0')
append(&CEM_FLAGS, str);
else
Roption(str);
break;
case 'S':
FLAG(S) = 1;
break;
case 't':
FLAG(t) = 1;
break;
case 'v': /* set debug switches */
FLAG(v) = 1;
switch (str[2]) {
case 'd':
debug = 1;
break;
case 'n': /* no execute */
exec = 0;
break;
case '\0':
break;
default:
bad_option(str);
}
break;
case 'V':
V_FLAG = str;
break;
default:
append(&LD_FLAGS, str);
}
}
if (debug) report("Note: debug output");
if (exec == 0)
report("Note: no execution");
count = SRCFILES.al_argc;
argvec = &(SRCFILES.al_argv[0]);
Nfile[0] = '\0';
while (count-- > 0) {
basename(file = *argvec++, BASE);
if (FLAG(E)) {
char ifile[USTR_SIZE];
init(call);
append(call, PP);
concat(call, &DEBUG_FLAGS);
concat(call, &PP_FLAGS);
append(call, file);
runvec(call, FLAG(P) ? mkname(ifile, BASE, ".i") : 0);
continue;
}
ext = extension(file);
/* .c to .k and .N */
if (ext == 'c' || ext == 'i') {
init(call);
append(call, CEM);
concat(call, &DEBUG_FLAGS);
append(call, V_FLAG);
concat(call, &CEM_FLAGS);
concat(call, &PP_FLAGS);
append(call, file);
append(call, mkname(kfile, BASE, ".k"));
append(call, mkname(Nfile, BASE, ".N"));
if (runvec(call, (char *)0)) {
file = kfile;
ext = 'k';
if (sizeof_file(Nfile) <= 0L)
remove(Nfile);
}
else {
remove(kfile);
remove(Nfile);
continue;
}
}
/* .e to .k */
if (ext == 'e') {
init(call);
append(call, ENCODE);
concat(call, &ENCODE_FLAGS);
append(call, file);
append(call, mkname(kfile, BASE, ".k"));
if (runvec(call, (char *)0) == 0)
continue;
file = kfile;
ext = 'k';
}
if (FLAG(k))
continue;
/* decode .k or .m */
if (FLAG(e) && (ext == 'k' || ext == 'm')) {
char efile[USTR_SIZE];
init(call);
append(call, DECODE);
concat(call, &DECODE_FLAGS);
append(call, file);
append(call, mkname(efile, BASE, ".e"));
runvec(call, (char *)0);
cleanup(kfile);
continue;
}
/* .k to .m */
if (ext == 'k') {
init(call);
append(call, OPT);
concat(call, &OPT_FLAGS);
append(call, file);
if (runvec(call, mkname(mfile, BASE, ".m")) == 0)
continue;
file = mfile;
ext = 'm';
cleanup(kfile);
}
if (FLAG(m))
continue;
/* .m to .s */
if (ext == 'm') {
init(call);
append(call, CG);
concat(call, &CG_FLAGS);
append(call, file);
append(call, mkname(sfile, BASE, ".s"));
if (runvec(call, (char *)0) == 0)
continue;
if (Nfile[0] != '\0') {
#ifndef MANTRA
init(call);
append(call, AS_FIX);
append(call, Nfile);
append(call, sfile);
runvec(call, (char *)0);
#endif MANTRA
remove(Nfile);
}
cleanup(mfile);
file = sfile;
ext = 's';
}
if (FLAG(S))
continue;
/* .s to .o */
if (ext == 's') {
ldfile = FLAG(c) ?
ofile :
alloc((unsigned)strlen(BASE) + 3);
init(call);
append(call, AS);
concat(call, &AS_FLAGS);
#ifdef MANTRA
append(call, "-");
#endif MANTRA
append(call, "-o");
append(call, mkname(ldfile, BASE, ".o"));
append(call, file);
if (runvec(call, (char *)0) == 0)
continue;
file = ldfile;
ext = 'o';
cleanup(sfile);
}
if (FLAG(c))
continue;
append(&LDFILES, file);
if (ldfile) {
append(&GEN_LDFILES, ldfile);
ldfile = 0;
}
}
/* *.o to a.out */
if (RET_CODE == 0 && LDFILES.al_argc > 0) {
init(call);
append(call, LD);
concat(call, &LD_FLAGS);
append(call, "-o");
#ifndef MANTRA
append(call, o_FILE);
#else MANTRA
append(call, Nc_flag ? o_FILE : cv_FILE);
#endif MANTRA
concat(call, &LD_HEAD);
concat(call, &LDFILES);
concat(call, &LD_TAIL);
if (runvec(call, (char *)0)) {
register i = GEN_LDFILES.al_argc;
while (i-- > 0)
remove(GEN_LDFILES.al_argv[i]);
#ifdef MANTRA
/* convert to local a.out format */
if (Nc_flag == 0) {
init(call);
append(call, CV);
concat(call, &CV_FLAGS);
append(call, cv_FILE);
append(call, o_FILE);
if (runvec(call, (char *)0))
remove(cv_FILE);
}
#endif MANTRA
}
}
exit(RET_CODE);
}
#define BUFSIZE (USTR_SIZE * MAXARGC)
char alloc_buf[BUFSIZE];
char *
alloc(u)
unsigned u;
{
static char *bufptr = &alloc_buf[0];
register char *p = bufptr;
if ((bufptr += u) >= &alloc_buf[BUFSIZE])
panic("no space");
return p;
}
append(al, arg)
register struct arglist *al;
char *arg;
{
if (al->al_argc >= MAXARGC)
panic("argument list overflow");
al->al_argv[(al->al_argc)++] = arg;
}
concat(al1, al2)
struct arglist *al1, *al2;
{
register int i = al2->al_argc;
register char **p = &(al1->al_argv[al1->al_argc]);
register char **q = &(al2->al_argv[0]);
if ((al1->al_argc += i) >= MAXARGC)
panic("argument list overflow");
while (i-- > 0)
*p++ = *q++;
}
/* The next function is a dirty old one, taking a variable number of
arguments.
Take care that the last argument is a null-valued pointer!
*/
/*VARARGS1*/
char *
mkstr(dst, arg)
char *dst, *arg;
{
char **vec = (char **) &arg;
register char *p;
register char *q = dst;
while (p = *vec++) {
while (*q++ = *p++);
q--;
}
return dst;
}
Roption(str)
char *str; /* of the form "prog=/-arg" */
{
char *eq;
char *prog, *arg;
char bc;
char *cindex();
prog = &str[2];
if (eq = cindex(prog, '='))
bc = '=';
else
if (eq = cindex(prog, '-'))
bc = '-';
else {
bad_option(str);
return;
}
*eq++ = '\0';
if (arg = eq) {
char *opt = 0;
struct prog *pp = &ProgParts[0];
if (bc == '-')
opt = mkstr(alloc((unsigned)strlen(arg) + 2),
"-", arg, 0);
while (pp->p_name) {
if (strcmp(prog, pp->p_name) == 0) {
if (opt)
append(pp->p_flags, opt);
else
*(pp->p_task) = arg;
return;
}
pp++;
}
}
bad_option(str);
}
basename(str, dst)
char *str;
register char *dst;
{
register char *p1 = str;
register char *p2 = p1;
while (*p1)
if (*p1++ == '/')
p2 = p1;
p1--;
if (*--p1 == '.') {
*p1 = '\0';
while (*dst++ = *p2++) {}
*p1 = '.';
}
else
while (*dst++ = *p2++) {}
}
int
extension(fn)
register char *fn;
{
char c;
while (*fn++) {}
fn--;
c = *--fn;
return (*--fn == '.') ? c : 0;
}
long
sizeof_file(nm)
char *nm;
{
struct stat stbuf;
if (stat(nm, &stbuf) == 0)
return stbuf.st_size;
return -1;
}
char * sysmsg[] = {
0,
"Hangup",
"Interrupt",
"Quit",
"Illegal instruction",
"Trace/BPT trap",
"IOT trap",
"EMT trap",
"Floating exception",
"Killed",
"Bus error",
"Memory fault",
"Bad system call",
"Broken pipe",
"Alarm call",
"Terminated",
"Signal 16"
};
runvec(vec, outp)
struct arglist *vec;
char *outp;
{
int status, fd;
char *task = vec->al_argv[1];
vec->al_argv[vec->al_argc] = 0;
if (FLAG(v))
print_vec(vec);
if (exec == 0)
return 1;
if (fork() == 0) { /* start up the process */
extern int errno;
if (outp) { /* redirect standard output */
close(1);
if ((fd = creat(outp, 0666)) < 0)
panic("cannot create %s", outp);
if (fd != 1)
panic("illegal redirection");
}
if (debug) report("exec %s", task);
execv(task, &(vec->al_argv[1]));
/* not an a.out file, let's try it with the SHELL */
if (debug) report("try it with %s", SHELL);
if (errno == ENOEXEC) {
vec->al_argv[0] = SHELL;
execv(SHELL, &(vec->al_argv[0]));
}
/* failed, so ... */
panic("cannot execute %s", task);
exit(1);
}
else {
int loworder, highorder, sig;
wait(&status);
loworder = status & 0377;
highorder = (status >> 8) & 0377;
if (loworder == 0) {
if (highorder)
report("%s: exit status %d", task, highorder);
return highorder ? ((RET_CODE = 1), 0) : 1;
}
else {
sig = loworder & 0177;
if (sig == 0177)
report("%s: stopped by ptrace", task);
else
if (sysmsg[sig])
report("%s: %s%s", task, sysmsg[sig],
(loworder & 0200)
? " - core dumped"
: "");
RET_CODE = 1;
return 0;
}
}
/*NOTREACHED*/
}
bad_option(str)
char *str;
{
report("bad option %s", str);
}
/*VARARGS1*/
report(fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
char *fmt;
{
fprintf(stderr, "%s: ", ProgCall);
fprintf(stderr, fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
fprintf(stderr, "\n");
}
/*VARARGS1*/
panic(fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
char *fmt;
{
fprintf(stderr, "%s: ", ProgCall);
fprintf(stderr, fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
fprintf(stderr, "\n");
exit(1);
}
set_traps(f)
int (*f)();
{
signal(SIGHUP, f);
signal(SIGINT, f);
signal(SIGQUIT, f);
signal(SIGALRM, f);
signal(SIGTERM, f);
}
/*ARGSUSED*/
trap(sig)
{
set_traps(SIG_IGN);
panic("Trapped");
}
print_vec(vec)
struct arglist *vec;
{
register i;
for (i = 1; i < vec->al_argc; i++)
printf("%s ", vec->al_argv[i]);
printf("\n");
}
char *
cindex(s, c)
char *s, c;
{
while (*s)
if (*s++ == c)
return s - 1;
return (char *) 0;
}

View file

@ -1,104 +0,0 @@
.TH EM_CEMCOM 6ACK
.ad
.SH NAME
em_cemcom \- C to EM compiler
.SH SYNOPSIS
\fB~/em/lib/em_cemcom\fP [\fIoptions\fP] \fIsource \fP[\fIdestination \fP[\fInamelist\fP]]
.SH DESCRIPTION
\fICemcom\fP is a compiler that translates C programs
into EM compact code.
The input is taken from \fIsource\fP, while the
EM code is written on \fIdestination\fP.
If either of these two names is "\fB-\fP", standard input or output respectively
is taken.
The file \fInamelist\fP, if supplied, will contain a list of the names
of external, so-called \fBcommon\fP, variables.
When the preprocessor is invoked to run stand-alone, \fIdestination\fP
needs not be specified.
.br
\fIOptions\fP is a, possibly empty, sequence of the following combinations:
.IP \fB\-D\fIname\fR=\fItext\fR
.br
define \fIname\fR as a macro with \fItext\fR as its replacement text.
.IP \fB\-D\fIname\fR
.br
the same as \fB\-D\fIname\fR=1.
.IP \fB\-I\fIdirname\fR
.br
insert \fIdirname\fR in the list of include directories.
.IP \fB\-M\fP\fIn\fP
set maximum identifier length to \fIn\fP.
.IP \fB\-g\fP
produce a DBX-style symbol table.
.IP \fB\-n\fR
do not generate EM register messages.
The user-declared variables are not stored into registers on the target
machine.
.IP \fB\-L\fR
don't generate the EM \fBfil\fR and \fBlin\fR instructions
that usually are generated to enable
an interpreter to keep track of the current location in the source code.
.IP \fB\-p\fR
generate code at each procedure entry to call the routine
.BR procentry ,
and at each return to call the routine
.BE procexit .
These routines are supplied with one parameter, a pointer to a
string containing the name of the procedure.
.IP \fB\-A\fR[\fIfile\fR]
.br
if \fIfile\fR is not given, generate a list
of makefile dependencies and write them to the standard output.
If \fIfile\fP is given,
generate the list of makefile dependencies on file \fIfile\fP.
.IP \fB-i\fR
when generating makefile dependencies, do not include files from
/usr/include.
.IP \fB-m\fR
when generating makefile dependencies, generate them in the following format:
.RS
.IP "file.o: file1.h"
.RE
.IP ""
where "file.o" is derived from the source file name. Normally, only a list
of files included is generated.
.IP \fB\-R\fR
interpret the input as restricted C (according to the language as
described in \fIThe C programming language\fR by Kernighan and Ritchie.)
.IP \fB\-U\fIname\fR
.br
get rid of the compiler-predefined macro \fIname\fR.
.IP \fB\-V\fIcm\fR.\fIn\fR,\ \fB\-V\fIcm\fR.\fIncm\fR.\fIn\fR\ ...
.br
set the size and alignment requirements.
The letter \fIc\fR indicates the simple type, which is one of
\fBs\fR(short), \fBi\fR(int), \fBl\fR(long), \fBf\fR(float), \fBd\fR(double) or
\fBp\fR(pointer).
The \fIm\fR parameter can be used to specify the length of the type (in bytes)
and the \fIn\fR parameter for the alignment of that type.
Absence of \fIm\fR or \fIn\fR causes the default value to be retained.
To specify that the bitfields should be right adjusted instead of the
default left adjustment, specify \fBr\fR as \fIc\fR parameter.
.IP \fB\-w\fR
suppress warning messages.
.IP \fB\-s\fR
suppress stricts.
.IP \fB\-a\fR
suppress warnings and stricts.
.IP \fB\-o\fR
suppress warnings and stricts about old-style.
.IP \fB\-\-\fItext\fR
.br
where \fItext\fR can be either of the above or
a debug flag of the compiler (which is not useful for the common user.)
This feature can be used in various shell scripts and surrounding programs
to force a certain option to be handed over to \fBcemcom\fR.
.LP
.SH FILES
.IR ~em/lib/em_cemcom :
the compiler
.SH DIAGNOSTICS
All warning and error messages are written on standard error output.
.SH REFERENCE
Baalbergen, E.H., D. Grune, M. Waage ;"\fIThe CEM compiler\fR",
Informatica Manual IM-4

View file

@ -1,641 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* S E M A N T I C A N A L Y S I S -- C H A P T E R 3.3 */
#include "lint.h"
#include "debug.h"
#include "nobitfield.h"
#include "idf.h"
#include <flt_arith.h>
#include "arith.h"
#include "proto.h"
#include "type.h"
#include "struct.h"
#include "label.h"
#include "expr.h"
#include "def.h"
#include "Lpars.h"
#include "assert.h"
#include "file_info.h"
extern char options[];
extern char *symbol2str();
extern struct type *qualifier_type();
/* Most expression-handling routines have a pointer to a
(struct type *) as first parameter. The object under the pointer
gets updated in the process.
*/
ch7sel(expp, oper, idf)
struct expr **expp;
struct idf *idf;
{
/* The selector idf is applied to *expp; oper may be '.' or
ARROW.
*/
register struct expr *exp;
register struct type *tp;
register struct sdef *sd;
any2opnd(expp, oper);
exp = *expp;
tp = exp->ex_type;
if (oper == ARROW) {
if (tp->tp_fund == POINTER &&
( tp->tp_up->tp_fund == STRUCT ||
tp->tp_up->tp_fund == UNION)) /* normal case */
tp = tp->tp_up;
else { /* constructions like "12->selector" and
"char c; c->selector"
*/
switch (tp->tp_fund) {
case POINTER:
break;
case INT:
case LONG:
/* An error is given in idf2sdef() */
ch7cast(expp, CAST, pa_type);
sd = idf2sdef(idf, tp);
tp = sd->sd_stype;
break;
default:
expr_error(exp, "-> applied to %s",
symbol2str(tp->tp_fund));
case ERRONEOUS:
exp->ex_type = error_type;
return;
}
}
} else { /* oper == '.' */
/* nothing */
}
exp = *expp;
switch (tp->tp_fund) {
case POINTER: /* for int *p; p->next = ... */
case STRUCT:
case UNION:
break;
case INT:
case LONG:
/* warning will be given by idf2sdef() */
break;
default:
if (!is_anon_idf(idf))
expr_error(exp, "selector %s applied to %s",
idf->id_text, symbol2str(tp->tp_fund));
case ERRONEOUS:
exp->ex_type = error_type;
return;
}
sd = idf2sdef(idf, tp);
if (oper == '.') {
/* there are 3 cases in which the selection can be
performed compile-time:
I: n.sel (n either an identifier or a constant)
II: (e.s1).s2 (transformed into (e.(s1+s2)))
III: (e->s1).s2 (transformed into (e->(s1+s2)))
The code performing these conversions is
extremely obscure.
*/
if (exp->ex_class == Value) {
/* It is an object we know the address of; so
we can calculate the address of the
selected member
*/
exp->VL_VALUE += sd->sd_offset;
exp->ex_type = sd->sd_type;
exp->ex_lvalue = exp->ex_type->tp_fund != ARRAY;
if (exp->ex_type == error_type) {
exp->ex_flags |= EX_ERROR;
}
}
else
if (exp->ex_class == Oper) {
struct oper *op = &(exp->ex_object.ex_oper);
if (op->op_oper == '.' || op->op_oper == ARROW) {
ASSERT(is_cp_cst(op->op_right));
op->op_right->VL_VALUE += sd->sd_offset;
exp->ex_type = sd->sd_type;
exp->ex_lvalue = exp->ex_type->tp_fund != ARRAY;
if (exp->ex_type == error_type) {
exp->ex_flags |= EX_ERROR;
}
}
else {
exp = new_oper(sd->sd_type, exp, '.',
intexpr(sd->sd_offset, INT));
exp->ex_lvalue = sd->sd_type->tp_fund != ARRAY;
if (!exp->OP_LEFT->ex_lvalue)
exp->ex_flags |= EX_ILVALUE;
}
}
}
else { /* oper == ARROW */
exp = new_oper(sd->sd_type,
exp, oper, intexpr(sd->sd_offset, INT));
exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
exp->ex_flags &= ~EX_ILVALUE;
}
if (sd->sd_type->tp_typequal & TQ_CONST)
exp->ex_flags |= EX_READONLY;
if (sd->sd_type->tp_typequal & TQ_VOLATILE)
exp->ex_flags |= EX_VOLATILE;
if (oper == '.' && exp->ex_flags & EX_READONLY) {
exp->ex_type = qualifier_type(exp->ex_type, TQ_CONST);
}
*expp = exp;
}
ch7incr(expp, oper)
struct expr **expp;
{
/* The monadic prefix/postfix incr/decr operator oper is
applied to *expp.
*/
ch7asgn(expp, oper, intexpr((arith)1, INT));
}
ch7cast(expp, oper, tp)
register struct expr **expp;
register struct type *tp;
{
/* The expression *expp is cast to type tp; the cast is
caused by the operator oper. If the cast has
to be passed on to run time, its left operand will be an
expression of class Type.
*/
register struct type *oldtp;
if ((*expp)->ex_type->tp_fund == FUNCTION)
function2pointer(*expp);
if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp);
if ((*expp)->ex_class == String)
string2pointer(*expp);
oldtp = (*expp)->ex_type;
#ifndef NOBITFIELD
if (oldtp->tp_fund == FIELD) {
field2arith(expp);
ch7cast(expp, oper, tp);
}
else
if (tp->tp_fund == FIELD) {
ch7cast(expp, oper, tp->tp_up);
}
else
#endif NOBITFIELD
if (equal_type(tp, oldtp)) {
/* life is easy */
}
else
if (tp->tp_fund == VOID) {
/* easy again */
(*expp)->ex_type = void_type;
}
else
if (is_arith_type(oldtp) && is_arith_type(tp)) {
int oldi = is_integral_type(oldtp);
int i = is_integral_type(tp);
if (oldi && i) {
#ifdef LINT
if (oper == CAST)
(*expp)->ex_type = tp;
else
int2int(expp, tp);
#else LINT
int2int(expp, tp);
#endif LINT
}
else
if (oldi && !i) {
#ifdef LINT
if (oper == CAST)
(*expp)->ex_type = tp;
else
int2float(expp, tp);
#else LINT
int2float(expp, tp);
#endif LINT
}
else
if (!oldi && i) {
#ifdef LINT
if (oper == CAST)
(*expp)->ex_type = tp;
else
float2int(expp, tp);
#else LINT
float2int(expp, tp);
#endif LINT
}
else {
/* !oldi && !i */
#ifdef LINT
if (oper == CAST)
(*expp)->ex_type = tp;
else
float2float(expp, tp);
#else LINT
float2float(expp, tp);
#endif LINT
}
}
else
if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER) {
if (oper == CASTAB)
expr_warning(*expp, "incompatible pointers");
else
if (oper != CAST)
expr_warning(*expp, "incompatible pointers in %s",
symbol2str(oper));
#ifdef LINT
if (oper != CAST)
lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund);
#endif LINT
(*expp)->ex_type = tp; /* free conversion */
}
else
if (oldtp->tp_fund == POINTER && is_integral_type(tp)) {
/* from pointer to integral */
if (oper != CAST)
expr_warning(*expp,
"illegal conversion of pointer to %s",
symbol2str(tp->tp_fund));
if (oldtp->tp_size > tp->tp_size)
expr_warning(*expp,
"conversion of pointer to %s loses accuracy",
symbol2str(tp->tp_fund));
if (oldtp->tp_size != tp->tp_size)
int2int(expp, tp);
else
(*expp)->ex_type = tp;
}
else
if (tp->tp_fund == POINTER && is_integral_type(oldtp)) {
/* from integral to pointer */
switch (oper) {
case CAST:
break;
case CASTAB:
case EQUAL:
case NOTEQUAL:
case '=':
case RETURN:
if (is_cp_cst(*expp) && (*expp)->VL_VALUE == (arith)0)
break;
default:
expr_warning(*expp,
"illegal conversion of %s to pointer",
symbol2str(oldtp->tp_fund));
break;
}
if (oldtp->tp_size > tp->tp_size)
expr_warning(*expp,
"conversion of %s to pointer loses accuracy",
symbol2str(oldtp->tp_fund));
if (oldtp->tp_size != tp->tp_size)
int2int(expp, tp);
else
(*expp)->ex_type = tp;
}
else
if (oldtp->tp_fund == ERRONEOUS) {
/* we just won't look */
(*expp)->ex_type = tp; /* brute force */
}
else
if (oldtp->tp_size == tp->tp_size && oper == CAST) {
expr_warning(*expp, "dubious conversion based on equal size");
(*expp)->ex_type = tp; /* brute force */
}
else {
if (oldtp->tp_fund != ERRONEOUS && tp->tp_fund != ERRONEOUS)
expr_error(*expp, "cannot convert %s to %s",
symbol2str(oldtp->tp_fund),
symbol2str(tp->tp_fund)
);
(*expp)->ex_type = tp; /* brute force */
}
if (oper == CAST) {
(*expp)->ex_flags |= EX_ILVALUE;
}
}
/* Determine whether two types are equal.
*/
equal_type(tp, otp)
register struct type *tp, *otp;
{
if (tp == otp)
return 1;
if (!tp || !otp)
return 0;
if (tp->tp_fund != otp->tp_fund)
return 0;
if (tp->tp_unsigned != otp->tp_unsigned)
return 0;
if (tp->tp_align != otp->tp_align)
return 0;
if (tp->tp_fund != ARRAY /* && tp->tp_fund != STRUCT */ ) { /* UNION ??? */
if (tp->tp_size != otp->tp_size)
return 0;
}
switch (tp->tp_fund) {
case FUNCTION:
/* If both types have parameter type lists, the type of
each parameter in the composite parameter type list
is the composite type of the corresponding paramaters.
*/
if (tp->tp_proto && otp->tp_proto) {
if (!equal_proto(tp->tp_proto, otp->tp_proto))
return 0;
} else if (tp->tp_proto || otp->tp_proto) {
if (!legal_mixture(tp, otp))
return 0;
}
return equal_type(tp->tp_up, otp->tp_up);
case ARRAY:
/* If one type is an array of known size, the composite
type is an array of that size
*/
if (tp->tp_size != otp->tp_size &&
(tp->tp_size != -1 && otp->tp_size != -1))
return 0;
return equal_type(tp->tp_up, otp->tp_up);
case POINTER:
if (equal_type(tp->tp_up, otp->tp_up)) {
if (otp->tp_up->tp_typequal & TQ_CONST) {
if (!(tp->tp_up->tp_typequal & TQ_CONST)) {
strict("illegal use of pointer to const object");
}
}
return 1;
}
else return 0;
case FIELD:
return equal_type(tp->tp_up, otp->tp_up);
case STRUCT:
case UNION:
case ENUM:
return tp->tp_idf == otp->tp_idf && tp->tp_sdef == otp->tp_sdef;
default:
return 1;
}
}
check_pseudoproto(pl, opl)
register struct proto *pl, *opl;
{
int retval = 1;
if (pl->pl_flag & PL_ELLIPSIS) {
error("illegal ellipsis terminator");
return 2;
}
while (pl && opl) {
if (!equal_type(pl->pl_type, opl->pl_type)) {
if (!(pl->pl_flag & PL_ERRGIVEN)
&& !(opl->pl_flag & PL_ERRGIVEN))
error("incorrect type for parameter %s of definition",
opl->pl_idf->id_text);
pl->pl_flag |= PL_ERRGIVEN;
opl->pl_flag |= PL_ERRGIVEN;
retval = 2;
}
pl = pl->next;
opl = opl->next;
}
if (pl || opl) {
error("incorrect number of parameters");
retval = 2;
}
return retval;
}
legal_mixture(tp, otp)
struct type *tp, *otp;
{
register struct proto *pl = tp->tp_proto, *opl = otp->tp_proto;
int retval = 1;
struct proto *prot;
int fund;
ASSERT( (pl != 0) ^ (opl != 0));
if (pl) {
prot = pl;
} else {
prot = opl;
}
if (!opl && otp->tp_pseudoproto) {
return check_pseudoproto(tp->tp_proto, otp->tp_pseudoproto);
}
if (prot->pl_flag & PL_ELLIPSIS) {
if (!(prot->pl_flag & PL_ERRGIVEN)) {
if (pl)
error("illegal ellipsis terminator");
else error("ellipsis terminator in previous (prototype) declaration");
}
prot->pl_flag |= PL_ERRGIVEN;
prot = prot->next;
return 2;
}
while (prot) {
/* if (!(prot->pl_flag & PL_ELLIPSIS)) {} */
fund = prot->pl_type->tp_fund;
if (fund == CHAR || fund == SHORT || fund == FLOAT) {
if (!(prot->pl_flag & PL_ERRGIVEN))
error("illegal %s parameter in %sdeclaration",
symbol2str(fund), (opl ? "previous (prototype) " : "" ));
prot->pl_flag |= PL_ERRGIVEN;
retval = 2;
}
prot = prot->next;
}
return retval;
}
equal_proto(pl, opl)
register struct proto *pl, *opl;
{
if (pl == opl)
return 1;
/* If only one type is a function type with a parameter type list
(a function prototype), the composite type is a function
prototype with parameter type list.
*/
while ( pl && opl) {
if ((pl->pl_flag & ~PL_ERRGIVEN) != (opl->pl_flag & ~PL_ERRGIVEN))
return 0;
if (!equal_type(pl->pl_type, opl->pl_type))
return 0;
pl = pl->next;
opl = opl->next;
}
return !(pl || opl);
}
recurconst(tp)
struct type *tp;
{
register struct sdef *sdf;
ASSERT(tp);
if (!tp) return 0;
if (tp->tp_typequal & TQ_CONST) return 1;
sdf = tp->tp_sdef;
while (sdf) {
if (recurconst(sdf->sd_type))
return 1;
sdf = sdf->sd_sdef;
}
return 0;
}
ch7asgn(expp, oper, expr)
struct expr **expp;
struct expr *expr;
{
/* The assignment operators.
"f op= e" should be interpreted as
"f = (typeof f)((typeof (f op e))f op (typeof (f op e))e)"
and not as "f = f op (typeof f)e".
Consider, for example, (i == 10) i *= 0.9; (i == 9), where
typeof i == int.
The resulting expression tree becomes:
op=
/ \
/ \
f (typeof (f op e))e
EVAL should however take care of evaluating (typeof (f op e))f
*/
register struct expr *exp = *expp;
int fund = exp->ex_type->tp_fund;
int vol = 0;
struct type *tp;
/* We expect an lvalue */
if (!exp->ex_lvalue) {
expr_error(exp, "no lvalue in operand of %s", symbol2str(oper));
} else if (exp->ex_flags & EX_ILVALUE) {
strict("incorrect lvalue in operand of %s", symbol2str(oper));
} else if (exp->ex_flags & EX_READONLY) {
expr_error(exp, "operand of %s is read-only", symbol2str(oper));
} else if (fund == STRUCT || fund == UNION) {
if (recurconst(exp->ex_type))
expr_error(expr,"operand of %s contains a const-qualified member",
symbol2str(oper));
}
/* Preserve volatile markers across the tree.
This is questionable, depending on the way the optimizer
wants this information.
vol = (exp->ex_flags & EX_VOLATILE) || (expr->ex_flags & EX_VOLATILE);
*/
if (oper == '=') {
ch7cast(&expr, oper, exp->ex_type);
tp = expr->ex_type;
}
else { /* turn e into e' where typeof(e') = typeof (f op e) */
struct expr *extmp = intexpr((arith)0, INT);
/* this is really $#@&*%$# ! */
/* if you correct this, please correct lint_new_oper() too */
extmp->ex_lvalue = 1;
extmp->ex_type = exp->ex_type;
ch7bin(&extmp, oper, expr);
/* Note that ch7bin creates a tree of the expression
((typeof (f op e))f op (typeof (f op e))e),
where f ~ extmp and e ~ expr.
We want to use (typeof (f op e))e.
Ch7bin does not create a tree if both operands
were illegal or constants!
*/
tp = extmp->ex_type; /* perform the arithmetic in type tp */
if (extmp->ex_class == Oper) {
expr = extmp->OP_RIGHT;
extmp->OP_RIGHT = NILEXPR;
free_expression(extmp);
}
else
expr = extmp;
}
#ifndef NOBITFIELD
if (fund == FIELD)
exp = new_oper(exp->ex_type->tp_up, exp, oper, expr);
else
exp = new_oper(exp->ex_type, exp, oper, expr);
#else NOBITFIELD
exp = new_oper(exp->ex_type, exp, oper, expr);
#endif NOBITFIELD
exp->OP_TYPE = tp; /* for EVAL() */
exp->ex_flags |= vol ? (EX_SIDEEFFECTS|EX_VOLATILE) : EX_SIDEEFFECTS;
*expp = exp;
}
/* Some interesting (?) questions answered.
*/
int
is_integral_type(tp)
register struct type *tp;
{
switch (tp->tp_fund) {
case GENERIC:
case CHAR:
case SHORT:
case INT:
case LONG:
case ENUM:
return 1;
#ifndef NOBITFIELD
case FIELD:
return is_integral_type(tp->tp_up);
#endif NOBITFIELD
default:
return 0;
}
}
int
is_arith_type(tp)
register struct type *tp;
{
switch (tp->tp_fund) {
case GENERIC:
case CHAR:
case SHORT:
case INT:
case LONG:
case ENUM:
case FLOAT:
case DOUBLE:
case LNGDBL:
return 1;
#ifndef NOBITFIELD
case FIELD:
return is_arith_type(tp->tp_up);
#endif NOBITFIELD
default:
return 0;
}
}

View file

@ -1,352 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* SEMANTIC ANALYSIS (CHAPTER 3.3) -- BINARY OPERATORS */
#include "botch_free.h"
#include <alloc.h>
#include "lint.h"
#include "idf.h"
#include <flt_arith.h>
#include "arith.h"
#include "type.h"
#include "struct.h"
#include "label.h"
#include "expr.h"
#include "Lpars.h"
extern char options[];
extern char *symbol2str();
/* This chapter asks for the repeated application of code to handle
an operation that may be executed at compile time or at run time,
depending on the constancy of the operands.
*/
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
#define non_commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 0)
ch7bin(expp, oper, expr)
register struct expr **expp;
struct expr *expr;
{
/* apply binary operator oper between *expp and expr.
NB: don't swap operands if op is one of the op= operators!!!
*/
any2opnd(expp, oper);
any2opnd(&expr, oper);
switch (oper) {
case '[': /* 3.3.2.1 */
/* indexing follows the commutative laws */
switch ((*expp)->ex_type->tp_fund) {
case POINTER:
case ARRAY:
break;
case ERRONEOUS:
return;
default: /* unindexable */
switch (expr->ex_type->tp_fund) {
case POINTER:
case ARRAY:
break;
case ERRONEOUS:
return;
default:
expr_error(*expp,
"indexing an object of type %s",
symbol2str((*expp)->ex_type->tp_fund));
return;
}
break;
}
ch7bin(expp, '+', expr);
ch7mon('*', expp);
break;
case '(': /* 3.3.2.2 */
if ( (*expp)->ex_type->tp_fund == POINTER &&
(*expp)->ex_type->tp_up->tp_fund == FUNCTION
) {
ch7mon('*', expp);
}
if ((*expp)->ex_type->tp_fund != FUNCTION) {
expr_error(*expp, "call of non-function (%s)",
symbol2str((*expp)->ex_type->tp_fund));
/* leave the expression; it may still serve */
free_expression(expr); /* there go the parameters */
*expp = new_oper(error_type,
*expp, '(', (struct expr *)0);
}
else
*expp = new_oper((*expp)->ex_type->tp_up,
*expp, '(', expr);
(*expp)->ex_flags |= EX_SIDEEFFECTS;
break;
case PARCOMMA: /* 3.3.2.2 */
if ((*expp)->ex_type->tp_fund == FUNCTION)
function2pointer(*expp);
*expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
break;
case '%':
case MODAB:
case ANDAB:
case XORAB:
case ORAB:
opnd2integral(expp, oper);
opnd2integral(&expr, oper);
/* fallthrough */
case '/':
case DIVAB:
case TIMESAB:
arithbalance(expp, oper, &expr);
non_commutative_binop(expp, oper, expr);
break;
case '&':
case '^':
case '|':
opnd2integral(expp, oper);
opnd2integral(&expr, oper);
/* fallthrough */
case '*':
arithbalance(expp, oper, &expr);
commutative_binop(expp, oper, expr);
break;
case '+':
if (expr->ex_type->tp_fund == POINTER) { /* swap operands */
struct expr *etmp = expr;
expr = *expp;
*expp = etmp;
}
/* fallthrough */
case PLUSAB:
case POSTINCR:
case PLUSPLUS:
if ((*expp)->ex_type->tp_fund == POINTER) {
pointer_arithmetic(expp, oper, &expr);
if (expr->ex_type->tp_size != (*expp)->ex_type->tp_size)
ch7cast(&expr, CAST, (*expp)->ex_type);
pointer_binary(expp, oper, expr);
}
else {
arithbalance(expp, oper, &expr);
if (oper == '+')
commutative_binop(expp, oper, expr);
else
non_commutative_binop(expp, oper, expr);
}
break;
case '-':
case MINAB:
case POSTDECR:
case MINMIN:
if ((*expp)->ex_type->tp_fund == POINTER) {
if (expr->ex_type->tp_fund == POINTER)
pntminuspnt(expp, oper, expr);
else {
pointer_arithmetic(expp, oper, &expr);
pointer_binary(expp, oper, expr);
}
}
else {
arithbalance(expp, oper, &expr);
non_commutative_binop(expp, oper, expr);
}
break;
case LEFT:
case RIGHT:
case LEFTAB:
case RIGHTAB:
opnd2integral(expp, oper);
opnd2integral(&expr, oper);
arithbalance(expp, oper, &expr); /* ch. 7.5 */
ch7cast(&expr, oper, int_type); /* cvt. rightop to int */
non_commutative_binop(expp, oper, expr);
break;
case '<':
case '>':
case LESSEQ:
case GREATEREQ:
case EQUAL:
case NOTEQUAL:
relbalance(expp, oper, &expr);
non_commutative_binop(expp, oper, expr);
(*expp)->ex_type = int_type;
break;
case AND:
case OR:
opnd2test(expp, oper);
opnd2test(&expr, oper);
if (is_cp_cst(*expp)) {
register struct expr *ex = *expp;
/* the following condition is a short-hand for
((oper == AND) && o1) || ((oper == OR) && !o1)
where o1 == (*expp)->VL_VALUE;
and ((oper == AND) || (oper == OR))
*/
if ((oper == AND) == (ex->VL_VALUE != (arith)0))
*expp = expr;
else {
ex->ex_flags |= expr->ex_flags;
free_expression(expr);
*expp = intexpr((arith)((oper == AND) ? 0 : 1),
INT);
}
(*expp)->ex_flags |= ex->ex_flags;
free_expression(ex);
}
else
if (is_cp_cst(expr)) {
/* Note!!!: the following condition is a short-hand for
((oper == AND) && o2) || ((oper == OR) && !o2)
where o2 == expr->VL_VALUE
and ((oper == AND) || (oper == OR))
*/
if ((oper == AND) == (expr->VL_VALUE != (arith)0)) {
(*expp)->ex_flags |= expr->ex_flags;
free_expression(expr);
}
else {
if (oper == OR)
expr->VL_VALUE = (arith)1;
ch7bin(expp, ',', expr);
}
}
else {
*expp = new_oper(int_type, *expp, oper, expr);
}
(*expp)->ex_flags |= EX_LOGICAL;
break;
case ':':
if ( is_struct_or_union((*expp)->ex_type->tp_fund)
|| is_struct_or_union(expr->ex_type->tp_fund)
) {
if (!equal_type((*expp)->ex_type, expr->ex_type))
expr_error(*expp, "illegal balance");
}
else
relbalance(expp, oper, &expr);
#ifdef LINT
if ( (is_cp_cst(*expp) && is_cp_cst(expr))
&& (*expp)->VL_VALUE == expr->VL_VALUE
) {
hwarning("operands of : are constant and equal");
}
#endif LINT
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
break;
case '?':
opnd2logical(expp, oper);
if (is_cp_cst(*expp)) {
#ifdef LINT
hwarning("condition in ?: expression is constant");
#endif LINT
*expp = (*expp)->VL_VALUE ?
expr->OP_LEFT : expr->OP_RIGHT;
}
else {
*expp = new_oper(expr->ex_type, *expp, oper, expr);
}
break;
case ',':
if (is_cp_cst(*expp))
*expp = expr;
else
*expp = new_oper(expr->ex_type, *expp, oper, expr);
(*expp)->ex_flags |= EX_COMMA;
break;
}
}
pntminuspnt(expp, oper, expr)
register struct expr **expp, *expr;
{
/* Subtracting two pointers is so complicated it merits a
routine of its own.
*/
struct type *up_type = (*expp)->ex_type->tp_up;
if (!equal_type(up_type, expr->ex_type->tp_up)) {
expr_error(*expp, "subtracting incompatible pointers");
free_expression(expr);
erroneous2int(expp);
return;
}
/* we hope the optimizer will eliminate the load-time
pointer subtraction
*/
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
ch7cast(expp, CAST, pa_type); /* ptr-ptr: result has pa_type */
ch7bin(expp, '/',
intexpr(size_of_type(up_type, "object"), pa_type->tp_fund));
ch7cast(expp, CAST, int_type); /* result will be an integer expr */
}
mk_binop(expp, oper, expr, commutative)
struct expr **expp;
register struct expr *expr;
{
/* Constructs in *expp the operation indicated by the operands.
"commutative" indicates whether "oper" is a commutative
operator.
*/
register struct expr *ex = *expp;
if (is_cp_cst(expr) && is_cp_cst(ex))
cstbin(expp, oper, expr);
else if (is_fp_cst(expr) && is_fp_cst(ex))
fltcstbin(expp, oper, expr);
else {
*expp = (commutative && expr->ex_depth >= ex->ex_depth) ?
new_oper(ex->ex_type, expr, oper, ex) :
new_oper(ex->ex_type, ex, oper, expr);
}
}
pointer_arithmetic(expp1, oper, expp2)
register struct expr **expp1, **expp2;
{
int typ;
/* prepares the integral expression expp2 in order to
apply it to the pointer expression expp1
*/
if ((typ = any2arith(expp2, oper)) == FLOAT
|| typ == DOUBLE
|| typ == LNGDBL) {
expr_error(*expp2,
"illegal combination of %s and pointer",
symbol2str(typ));
erroneous2int(expp2);
}
ch7bin( expp2, '*',
intexpr(size_of_type((*expp1)->ex_type->tp_up, "object"),
pa_type->tp_fund)
);
}
pointer_binary(expp, oper, expr)
register struct expr **expp, *expr;
{
/* constructs the pointer arithmetic expression out of
a pointer expression, a binary operator and an integral
expression.
*/
if (is_ld_cst(expr) && is_ld_cst(*expp))
cstbin(expp, oper, expr);
else
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
}

View file

@ -1,168 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
#include "botch_free.h"
#include <alloc.h>
#include "nobitfield.h"
#include "Lpars.h"
#include <flt_arith.h>
#include "arith.h"
#include "type.h"
#include "label.h"
#include "expr.h"
#include "idf.h"
#include "def.h"
extern char options[];
extern arith full_mask[/*MAXSIZE*/]; /* cstoper.c */
char *symbol2str();
ch7mon(oper, expp)
register struct expr **expp;
{
/* The monadic prefix operator oper is applied to *expp.
*/
register struct expr *expr;
switch (oper) {
case '*': /* 3.3.3.2 */
/* no FIELD type allowed */
if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp);
if ((*expp)->ex_type->tp_fund != POINTER) {
if ((*expp)->ex_type->tp_fund != FUNCTION) {
expr_error(*expp,
"* applied to non-pointer (%s)",
symbol2str((*expp)->ex_type->tp_fund));
} else {
warning("superfluous use of * on function");
/* ignore indirection (yegh) */
}
} else {
expr = *expp;
if (expr->ex_lvalue == 0 && expr->ex_class != String)
/* dereference in administration only */
expr->ex_type = expr->ex_type->tp_up;
else /* runtime code */
*expp = new_oper(expr->ex_type->tp_up, NILEXPR,
'*', expr);
(*expp)->ex_lvalue = (
(*expp)->ex_type->tp_fund != ARRAY &&
(*expp)->ex_type->tp_fund != FUNCTION
);
if ((*expp)->ex_type->tp_typequal & TQ_CONST)
(*expp)->ex_flags |= EX_READONLY;
if ((*expp)->ex_type->tp_typequal & TQ_VOLATILE)
(*expp)->ex_flags |= EX_VOLATILE;
(*expp)->ex_flags &= ~EX_ILVALUE;
}
break;
case '&':
if ((*expp)->ex_type->tp_fund == ARRAY) {
expr_warning(*expp, "& before array ignored");
array2pointer(*expp);
}
else
if ((*expp)->ex_type->tp_fund == FUNCTION) {
expr_warning(*expp, "& before function ignored");
function2pointer(*expp);
}
else
#ifndef NOBITFIELD
if ((*expp)->ex_type->tp_fund == FIELD)
expr_error(*expp, "& applied to field variable");
else
#endif NOBITFIELD
if (!(*expp)->ex_lvalue)
expr_error(*expp, "& applied to non-lvalue");
else if ((*expp)->ex_flags & EX_ILVALUE)
expr_error(*expp, "& applied to illegal lvalue");
else {
/* assume that enums are already filtered out */
if (ISNAME(*expp)) {
register struct def *def =
(*expp)->VL_IDF->id_def;
/* &<var> indicates that <var>
cannot be used as register
anymore
*/
if (def->df_sc == REGISTER) {
expr_error(*expp,
"& on register variable not allowed");
break; /* break case '&' */
}
}
(*expp)->ex_type = pointer_to((*expp)->ex_type,
(*expp)->ex_type->tp_typequal);
(*expp)->ex_lvalue = 0;
(*expp)->ex_flags &= ~EX_READONLY;
}
break;
case '~':
{
int fund = (*expp)->ex_type->tp_fund;
if (fund == FLOAT || fund == DOUBLE || fund == LNGDBL) {
expr_error( *expp,
"~ not allowed on %s operands",
symbol2str(fund));
erroneous2int(expp);
break;
}
/* FALLTHROUGH */
}
case '-':
any2arith(expp, oper);
if (is_cp_cst(*expp)) {
arith o1 = (*expp)->VL_VALUE;
(*expp)->VL_VALUE = (oper == '-') ? -o1 :
((*expp)->ex_type->tp_unsigned ?
(~o1) & full_mask[(*expp)->ex_type->tp_size] :
~o1
);
}
else
if (is_fp_cst(*expp))
switch_sign_fp(*expp);
else
*expp = new_oper((*expp)->ex_type,
NILEXPR, oper, *expp);
break;
case '!':
if ((*expp)->ex_type->tp_fund == FUNCTION)
function2pointer(*expp);
if ((*expp)->ex_type->tp_fund != POINTER)
any2arith(expp, oper);
opnd2test(expp, '!');
if (is_cp_cst(*expp)) {
(*expp)->VL_VALUE = !((*expp)->VL_VALUE);
(*expp)->ex_type = int_type; /* a cast ???(EB) */
}
else
*expp = new_oper(int_type, NILEXPR, oper, *expp);
(*expp)->ex_flags |= EX_LOGICAL;
break;
case PLUSPLUS:
case MINMIN:
ch7incr(expp, oper);
break;
case SIZEOF:
if (ISNAME(*expp) && (*expp)->VL_IDF->id_def->df_formal_array)
expr_warning(*expp, "sizeof formal array %s is sizeof pointer!",
(*expp)->VL_IDF->id_text);
expr = intexpr((*expp)->ex_class == String ?
(arith)((*expp)->SG_LEN) :
size_of_type((*expp)->ex_type, "object"),
INT);
expr->ex_flags |= EX_SIZEOF;
free_expression(*expp);
*expp = expr;
break;
}
}

View file

@ -1,21 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* DECLARATION SPECIFIER DEFINITION */
struct decspecs {
struct decspecs *next;
struct type *ds_type; /* single type */
int ds_notypegiven; /* set if type not given explicitly */
int ds_typedef; /* 1 if type was a user typedef */
int ds_sc_given; /* 1 if the st. class is explicitly given */
int ds_sc; /* storage class, given or implied */
int ds_size; /* LONG, SHORT or 0 */
int ds_unsigned; /* SIGNED, UNSIGNED or 0 */
int ds_typequal; /* type qualifiers - see type.str */
};
extern struct type *qualifier_type();
extern struct decspecs null_decspecs;

View file

@ -1,74 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
*The following functions are hacked to null-functions (i.e. they
* do nothing). This needs another solution in the future.
*/
#include "lint.h"
#ifdef LINT
#include "arith.h"
#include "label.h"
C_close(){}
int C_busy(){return 0;}
/* More routines */
/* ARGSUSED */
CC_bhcst(ps_xxx,n,w,i) arith n,w; {}
/* ARGSUSED */
CC_crcst(ps_xxx,v) arith v; {}
/* ARGSUSED */
CC_crdlb(ps_xxx,v,s) label v; arith s; {}
/* ARGSUSED */
CC_crdnam(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crfcon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_cricon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crilb(ps_xxx,v) label v; {}
/* ARGSUSED */
CC_crpnam(ps_xxx,v) char *v; {}
/* ARGSUSED */
CC_crscon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crucon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_cst(l) {}
/* ARGSUSED */
CC_dfdlb(l) label l; {}
/* ARGSUSED */
CC_dfdnam(s) char *s; {}
/* ARGSUSED */
CC_dfilb(l) label l; {}
/* ARGSUSED */
CC_end(l) arith l; {}
CC_msend() {}
/* ARGSUSED */
CC_msstart(ms) {}
/* ARGSUSED */
CC_opcst(op_xxx,c) arith c; {}
/* ARGSUSED */
CC_opdlb(op_xxx,g,o) label g; arith o; {}
/* ARGSUSED */
CC_opilb(op_xxx,b) label b; {}
/* ARGSUSED */
CC_oppnam(op_xxx,p) char *p; {}
/* ARGSUSED */
CC_pronarg(s) char *s; {}
/* ARGSUSED */
CC_psdlb(ps_xxx,l) label l; {}
/* ARGSUSED */
CC_psdnam(ps_xxx,s) char *s; {}
/* ARGSUSED */
CC_pspnam(ps_xxx,s) char *s; {}
/* ARGSUSED */
CC_scon(v,s) char *s; {}
#endif LINT

View file

@ -1,246 +0,0 @@
/* $Header$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* mcomm.c -- change ".lcomm name" into ".comm name" where "name"
is specified in a list.
*/
#include <stdio.h>
#define IDFSIZE 4096
char *readfile();
struct node {
char *name;
struct node *left, *right;
};
char *
Malloc(n)
unsigned n;
{
char *space;
char *malloc();
if ((space = malloc(n)) == 0) {
fprintf(stderr, "out of memory\n");
exit(1);
}
return space;
}
struct node *make_tree();
#define new_node() ((struct node *) Malloc(sizeof (struct node)))
main(argc, argv)
char *argv[];
{
char *nl_file, *as_file;
char *nl_text, *as_text;
struct node *nl_tree = 0;
int nl_siz, as_siz;
if (argc != 3) {
fprintf(stderr, "use: %s namelist assembler_file\n", argv[0]);
exit(1);
}
nl_file = argv[1];
as_file = argv[2];
if ((nl_text = readfile(nl_file, &nl_siz)) == 0) {
fprintf(stderr, "%s: cannot read namelist %s\n",
argv[0], nl_file);
exit(1);
}
if ((as_text = readfile(as_file, &as_siz)) == 0) {
fprintf(stderr, "%s: cannot read assembler file %s\n",
argv[0], as_file);
exit(1);
}
nl_tree = make_tree(nl_text);
edit(as_text, nl_tree);
if (writefile(as_file, as_text, as_siz) == 0) {
fprintf(stderr, "%s: cannot write to %s\n", argv[0], as_file);
exit(1);
}
return 0;
}
#include <sys/types.h>
#include <stat.h>
char *
readfile(filename, psiz)
char *filename;
int *psiz;
{
struct stat stbuf; /* for `stat' to get filesize */
register int fd; /* filedescriptor for `filename' */
register char *cbuf; /* pointer to buffer to be returned */
if (((fd = open(filename, 0)) < 0) || (fstat(fd, &stbuf) != 0))
return 0;
cbuf = Malloc(stbuf.st_size + 1);
if (read(fd, cbuf, stbuf.st_size) != stbuf.st_size)
return 0;
cbuf[stbuf.st_size] = '\0';
close(fd); /* filedes no longer needed */
*psiz = stbuf.st_size;
return cbuf;
}
int
writefile(filename, text, size)
char *filename, *text;
{
register fd;
if ((fd = open(filename, 1)) < 0)
return 0;
if (write(fd, text, size) != size)
return 0;
close(fd);
return 1;
}
struct node *
make_tree(nl)
char *nl;
{
char *id = nl;
struct node *tree = 0;
while (*nl) {
if (*nl == '\n') {
*nl = '\0';
insert(&tree, id);
id = ++nl;
}
else {
++nl;
}
}
return tree;
}
insert(ptree, id)
struct node **ptree;
char *id;
{
register cmp;
if (*ptree == 0) {
register struct node *nnode = new_node();
nnode->name = id;
nnode->left = nnode->right = 0;
*ptree = nnode;
}
else
if ((cmp = strcmp((*ptree)->name, id)) < 0)
insert(&((*ptree)->right), id);
else
if (cmp > 0)
insert(&((*ptree)->left), id);
}
struct node *
find(tree, id)
struct node *tree;
char *id;
{
register cmp;
if (tree == 0)
return 0;
if ((cmp = strcmp(tree->name, id)) < 0)
return find(tree->right, id);
if (cmp > 0)
return find(tree->left, id);
return tree;
}
edit(text, tree)
char *text;
struct node *tree;
{
register char *ptr = text;
char idbuf[IDFSIZE];
register char *id;
register char *save_ptr;
while (*ptr) {
if (
*ptr == '.' &&
*++ptr == 'l' &&
*++ptr == 'c' &&
*++ptr == 'o' &&
*++ptr == 'm' &&
*++ptr == 'm' &&
(*++ptr == ' ' || *ptr == '\t')
)
{
save_ptr = ptr - 6;
while (*++ptr == ' ' || *ptr == '\t')
;
if (*ptr == '_')
++ptr;
if (InId(*ptr)) {
id = &idbuf[0];
*id++ = *ptr++;
while (InId(*ptr))
*id++ = *ptr++;
*id = '\0';
if (find(tree, idbuf) != 0) {
*save_ptr++ = ' ';
*save_ptr++ = '.';
}
}
}
while (*ptr && *ptr++ != '\n')
;
}
}
InId(c)
{
switch (c) {
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '_':
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return 1;
default:
return 0;
}
}
puttree(nd)
struct node *nd;
{
if (nd) {
puttree(nd->left);
printf("%s\n", nd->name);
puttree(nd->right);
}
}

View file

@ -1,9 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* Accepted if many characters of long names are significant */
/* $Header$ */
abcdefghijklmnopr() { }
abcdefghijklmnopq() { }
main() { }

View file

@ -1,237 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* PREPROCESSOR: SCANNER FOR THE ACTUAL PARAMETERS OF MACROS */
#include "nopp.h"
#ifndef NOPP
/* This file contains the function getactuals() which scans an actual
parameter list and splits it up into a list of strings, each one
representing an actual parameter.
*/
#include "lapbuf.h" /* UF */
#include "nparams.h" /* UF */
#include "input.h"
#include "class.h"
#include "idf.h"
#include "macro.h"
#include "interface.h"
#include "file_info.h"
#define EOS '\0'
#define overflow() (fatal("actual parameter buffer overflow"))
PRIVATE char apbuf[LAPBUF]; /* temporary storage for actual parameters */
PRIVATE char *actparams[NPARAMS]; /* pointers to the text of the actuals */
PRIVATE char *aptr; /* pointer to last inserted character in apbuf */
#define copy(ch) ((aptr < &apbuf[LAPBUF]) ? (*aptr++ = ch) : overflow())
PRIVATE int nr_of_params; /* number of actuals read until now */
PRIVATE char **
getactuals(idef)
register struct idf *idef;
{
/* getactuals() collects the actual parameters and turns them
into a list of strings, a pointer to which is returned.
*/
register acnt = idef->id_macro->mc_nps;
nr_of_params = 0;
actparams[0] = aptr = &apbuf[0];
copyact('(', ')', 0); /* read the actual parameters */
copy(EOS); /* mark the end of it all */
if (!nr_of_params++) { /* 0 or 1 parameter */
/* there could be a ( <spaces, comment, ...> )
*/
register char *p = actparams[0];
while ((class(*p) == STSKIP) || (*p == '\n')) {
++p;
}
if (!*p) { /* the case () : 0 parameters */
nr_of_params--;
}
}
if (nr_of_params != acnt) {
/* argument mismatch: too many or too few
actual parameters.
*/
lexwarning("argument mismatch, %s", idef->id_text);
while (nr_of_params < acnt) {
/* too few paraeters: remaining actuals are ""
*/
actparams[nr_of_params] = "";
nr_of_params++;
}
}
return actparams;
}
PRIVATE
copyact(ch1, ch2, lvl)
char ch1, ch2;
int lvl;
{
/* copyact() is taken from Ceriel Jacobs' LLgen, with
permission. Its task is to build a list of actuals
parameters, which list is surrounded by '(' and ')' and in
which the parameters are separated by ',' if there are
more than 1. The balancing of '(',')' and '[',']' and
'{','}' is taken care of by calling this function
recursively. At each level lvl, copyact() reads the input,
upto the corresponding closing bracket.
Opening bracket is ch1, closing bracket is ch2. If
lvl != 0, copy opening and closing parameters too.
*/
register int ch; /* Current char */
register int match; /* used to read strings */
if (lvl) {
copy(ch1);
}
for (;;) {
LoadChar(ch);
if (ch == ch2) {
if (lvl) {
copy(ch);
}
return;
}
switch(ch) {
#ifdef __MATCHING_PAR__
case ')':
case '}':
case ']':
lexerror("unbalanced parenthesis");
break;
#endif __MATCHING_PAR__
case '(':
copyact('(', ')', lvl+1);
break;
#ifdef __MATCHING_PAR__
case '{':
/* example:
#define declare(v, t) t v
declare(v, union{int i, j; float r;});
*/
copyact('{', '}', lvl+1);
break;
case '[':
copyact('[', ']', lvl+1);
break;
#endif __MATCHING_PAR__
case '\n':
LineNumber++;
while (LoadChar(ch), ch == '#') {
/* This piece of code needs some
explanation: consider the call of
the macro defined as:
#define sum(b,c) (b + c)
in the following form:
sum(
#include my_phone_number
,2)
in which case the include must be
interpreted as such.
*/
domacro(); /* has read nl, vt or ff */
/* Loop, for another control line */
}
PushBack();
copy(' ');
break;
case '/':
LoadChar(ch);
if (ch == '*' && !InputLevel) { /* skip comment */
skipcomment();
continue;
}
PushBack();
copy('/');
break;
case ',':
if (!lvl) {
/* next parameter encountered */
copy(EOS);
if (++nr_of_params >= NPARAMS) {
fatal("too many actual parameters");
}
actparams[nr_of_params] = aptr;
}
else {
copy(ch);
}
break;
case '\'':
case '"' :
/* watch out for brackets in strings, they do
not count !
*/
match = ch;
copy(ch);
while (LoadChar(ch), ch != EOI) {
if (ch == match) {
break;
}
if (ch == '\\') {
copy(ch);
LoadChar(ch);
}
else
if (ch == '\n') {
lexerror("newline in string");
LineNumber++;
copy(match);
break;
}
copy(ch);
}
if (ch == match) {
copy(ch);
break;
}
/* Fall through */
case EOI :
lexerror("unterminated macro call");
return;
default:
copy(ch);
break;
}
}
}
#endif NOPP

View file

@ -1,88 +0,0 @@
Files
cem.1
cem.c
cemcom.1
Parameters
Makefile
LLlex.c
LLlex.h
LLmessage.c
align.h
alloc.c
alloc.h
arith.c
arith.h
asm.c
assert.h
atw.h
blocks.c
char.tab
ch7.c
ch7bin.c
ch7mon.c
class.h
code.c
code.str
conversion.c
cstoper.c
dataflow.c
declar.g
declarator.c
declar.str
decspecs.c
decspecs.str
def.str
domacro.c
dumpidf.c
error.c
eval.c
expr.c
expr.str
expression.g
faulty.h
field.c
field.str
file_info.h
idf.c
idf.str
init.c
input.c
input.h
interface.h
ival.c
label.c
label.h
level.h
macro.str
main.c
make.allocd
make.hfiles
make.next
make.tokcase
make.tokfile
mcomm.c
mes.h
options
options.c
program.g
replace.c
scan.c
sizes.h
skip.c
specials.h
stack.c
stack.str
statement.g
stb.c
storage.c
storage.h
stmt.str
struct.c
struct.str
switch.c
switch.str
tab.c
tokenname.c
tokenname.h
type.c
type.str

View file

@ -1,146 +0,0 @@
!File: lint.h
#define LINT 1 /* if defined, 'lint' is produced */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */
#define ERR_SHADOW 0 /* a syntax error overshadows error messages
until ERR_SHADOW symbols have been
accepted without syntax error */
!File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h
#define NPARAMS 32 /* maximum number of parameters of macros */
!File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h
#define DENSITY 2 /* see switch.[ch] for an explanation */
!File: lapbuf.h
#define LAPBUF 4096 /* size of macro actual parameter buffer */
!File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */
#define RSTRSIZE 8 /* step size in enlarging the memory for
the storage of a string */
!File: target_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */
#define SZ_CHAR (arith)1
#define SZ_SHORT (arith)2
#define SZ_WORD (arith)4
#define SZ_INT (arith)4
#define SZ_LONG (arith)4
#ifndef NOFLOAT
#define SZ_FLOAT (arith)4
#define SZ_DOUBLE (arith)8
#endif NOFLOAT
#define SZ_POINTER (arith)4
/* target machine alignment requirements */
#define AL_CHAR 1
#define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#ifndef NOFLOAT
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#endif NOFLOAT
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
!File: botch_free.h
#undef BOTCH_FREE 1 /* when defined, botch freed memory, as a check */
!File: dataflow.h
#undef DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h
#undef DEBUG 1 /* perform various self-tests */
!File: use_tmp.h
#undef PREPEND_SCOPES 1 /* collect exa, exp, ina and inp commands
and if USE_TMP is defined let them
precede the rest of the generated
compact code */
#undef USE_TMP 1 /* use C_insertpart, C_endpart mechanism
to generate EM-code in the order needed
for the code-generators. If not defined,
the old-style peephole optimizer is
needed. */
!File: parbufsize.h
#define PARBUFSIZE 1024
!File: textsize.h
#define ITEXTSIZE 8 /* 1st piece of memory for repl. text */
#define RTEXTSIZE 8 /* stepsize for enlarging repl.text */
!File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */
!File: nopp.h
#undef NOPP 1 /* if NOT defined, use built-int preprocessor */
!File: nobitfield.h
#undef NOBITFIELD 1 /* if NOT defined, implement bitfields */
!File: spec_arith.h
/* describes internal compiler arithmetics */
#undef SPECIAL_ARITHMETICS /* something different from native long */
!File: static.h
#define GSTATIC /* for large global "static" arrays */
!File: nofloat.h
#undef NOFLOAT 1 /* if NOT defined, floats are implemented */
!File: noRoption.h
#undef NOROPTION 1 /* if NOT defined, R option is implemented */
!File: nocross.h
#undef NOCROSS 1 /* if NOT defined, cross compiler */
!File: regcount.h
#undef REGCOUNT 1 /* count occurrences for register messages */

View file

@ -1,139 +0,0 @@
!File: lint.h
#undef LINT 1 /* if defined, 'lint' is produced */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */
#define MAXERR_LINE 5 /* maximum number of error messages given
on the same input line. */
!File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h
#define NPARAMS 32 /* maximum number of parameters of macros */
!File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h
#define DENSITY 2 /* see switch.[ch] for an explanation */
!File: lapbuf.h
#define LAPBUF 4096 /* size of macro actual parameter buffer */
!File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */
#define RSTRSIZE 8 /* step size in enlarging the memory for
the storage of a string */
!File: target_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */
#define SZ_CHAR (arith)1
#define SZ_SHORT (arith)2
#define SZ_WORD (arith)4
#define SZ_INT (arith)4
#define SZ_LONG (arith)4
#ifndef NOFLOAT
#define SZ_FLOAT (arith)4
#define SZ_DOUBLE (arith)8
#endif NOFLOAT
#define SZ_POINTER (arith)4
/* target machine alignment requirements */
#define AL_CHAR 1
#define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#ifndef NOFLOAT
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#endif NOFLOAT
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
!File: botch_free.h
#undef BOTCH_FREE 1 /* when defined, botch freed memory, as a check */
!File: dataflow.h
#define DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h
#undef DEBUG 1 /* perform various self-tests */
!File: use_tmp.h
#define USE_TMP 1 /* collect exa, exp, ina and inp commands
and let them precede the rest of
the generated compact code */
!File: parbufsize.h
#define PARBUFSIZE 1024
!File: textsize.h
#define ITEXTSIZE 8 /* 1st piece of memory for repl. text */
#define RTEXTSIZE 8 /* stepsize for enlarging repl.text */
!File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */
!File: nopp.h
#undef NOPP 1 /* if NOT defined, use built-int preprocessor */
!File: nobitfield.h
#undef NOBITFIELD 1 /* if NOT defined, implement bitfields */
!File: spec_arith.h
/* describes internal compiler arithmetics */
#undef SPECIAL_ARITHMETICS /* something different from native long */
!File: static.h
#define GSTATIC /* for large global "static" arrays */
!File: nofloat.h
#undef NOFLOAT 1 /* if NOT defined, floats are implemented */
!File: noRoption.h
#undef NOROPTION 1 /* if NOT defined, R option is implemented */
!File: nocross.h
#undef NOCROSS 1 /* if NOT defined, cross compiler */
!File: regcount.h
#undef REGCOUNT 1 /* count occurrences for register messages */

View file

@ -1,67 +0,0 @@
: create a directory Xsrc with name clashes resolved
: and run make in that directory
: '$Header$'
case $# in
1)
;;
*) echo "$0: one argument expected" 1>&2
exit 1
;;
esac
PW=`pwd`
options=
case $1 in
main|emain|lnt)
target=$PW/$1
;;
omain)
target=$PW/$1
options=-DPEEPHOLE
;;
cemain)
target=$PW/$1
options=-DCODE_EXPANDER
;;
Xlint)
target=$1
;;
*) echo "$0: $1: Illegal argument" 1>&2
exit 1
;;
esac
if test -d ../Xsrc
then
:
else mkdir ../Xsrc
fi
make EMHOME=$EMHOME longnames
: remove code generating routines from the clashes list as they are defines.
: code generating routine names start with C_
sed '/^C_/d' < longnames > tmp$$
cclash -c -l7 tmp$$ > ../Xsrc/Xclashes
rm -f tmp$$
cd ../Xsrc
if cmp -s Xclashes clashes
then
:
else
mv Xclashes clashes
fi
rm -f Makefile
for i in `cat $PW/Cfiles`
do
cat >> Makefile <<EOF
$i: clashes $PW/$i
cid -Fclashes < $PW/$i > $i
EOF
done
make EMHOME=$EMHOME `cat $PW/Cfiles`
rm -f Makefile
ed - $PW/Makefile <<'EOF'
/^#EXCLEXCL/,/^#INCLINCL/d
w Makefile
q
EOF
make EMHOME=$EMHOME COPTIONS=$options MACH=$mach CURRDIR=$PW/ $target

View file

@ -1,8 +0,0 @@
/* $Header$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef lint
static char Version[] = "ACK CEM compiler Version 3.2";
#endif lint

View file

@ -1,159 +0,0 @@
/* $Header$ */
/* M E M O R Y A L L O C A T I O N R O U T I N E S */
/* The allocation of memory in this program, which plays an important
role in reading files, replacing macros and building expression
trees, is not performed by malloc etc. The reason for having own
memory allocation routines (malloc(), realloc() and free()) is
plain: the garbage collection performed by the library functions
malloc(), realloc() and free() costs a lot of time, while in most
cases (on a VAX) the freeing and reallocation of memory is not
necessary. The only reallocation done in this program is at
building strings in memory. This means that the last
(re-)allocated piece of memory can be extended.
The (basic) memory allocating routines offered by this memory
handling package are:
char *malloc(n) : allocate n bytes
char *realloc(ptr, n) : reallocate buffer to n bytes
(works only if ptr was last allocated)
free(ptr) : if ptr points to last allocated
memory, this memory is re-allocatable
Salloc(str, sz) : save string in malloc storage
*/
#include <system.h>
#include "myalloc.h" /* UF */
#include "debug.h" /* UF */
#include "alloc.h"
#include "assert.h"
#ifdef OWNALLOC
char *sys_break();
/* the following variables are used for book-keeping */
static int nfreebytes = 0; /* # free bytes in sys_break space */
static char *freeb; /* pointer to first free byte */
static char *lastalloc; /* pointer to last malloced sp */
static int lastnbytes; /* nr of bytes in last allocated */
/* space */
static char *firstfreeb = 0;
#endif OWNALLOC
char *
Salloc(str, sz)
register char str[];
register int sz;
{
/* Salloc() is not a primitive function: it just allocates a
piece of storage and copies a given string into it.
*/
char *res = Malloc(sz);
register char *m = res;
while (sz--)
*m++ = *str++;
return res;
}
#ifdef OWNALLOC
#define ALIGN(m) (ALIGNSIZE * (((m) - 1) / ALIGNSIZE + 1))
char *
malloc(n)
unsigned n;
{
/* malloc() is a very simple malloc().
*/
n = ALIGN(n);
if (nfreebytes < n) {
register nbts = (n <= ALLOCSIZ) ? ALLOCSIZ : n;
if (!nfreebytes) {
if ((freeb = sys_break(nbts)) == ILL_BREAK)
fatal("out of memory");
}
else {
if (sys_break(nbts) == ILL_BREAK)
fatal("out of memory");
}
nfreebytes += nbts;
}
lastalloc = freeb;
freeb = lastalloc + n;
lastnbytes = n;
nfreebytes -= n;
return lastalloc;
}
/*ARGSUSED*/
char *
realloc(ptr, n)
char *ptr;
unsigned n;
{
/* realloc() is designed to append more bytes to the latest
allocated piece of memory. However reallocation should be
performed, even if the mentioned memory is not the latest
allocated one, this situation will not occur. To do so,
realloc should know how many bytes are allocated the last
time for that piece of memory. ????
*/
register int nbytes = n;
ASSERT(ptr == lastalloc); /* security */
nbytes -= lastnbytes; /* # bytes required */
if (nbytes == 0) /* no extra bytes */
return lastalloc;
/* if nbytes < 0: free last allocated bytes;
if nbytes > 0: allocate more bytes
*/
if (nbytes > 0)
nbytes = ALIGN(nbytes);
if (nfreebytes < nbytes) {
register int nbts = (nbytes < ALLOCSIZ) ? ALLOCSIZ : nbytes;
if (sys_break(nbts) == ILL_BREAK)
fatal("out of memory");
nfreebytes += nbts;
}
freeb += nbytes; /* less bytes */
lastnbytes += nbytes; /* change nr of last all. bytes */
nfreebytes -= nbytes; /* less or more free bytes */
return lastalloc;
}
/* to ensure that the alloc library package will not be loaded: */
/*ARGSUSED*/
free(p)
char *p;
{}
init_mem()
{
firstfreeb = sys_break(0);
/* align the first memory unit to ALIGNSIZE ??? */
if ((long) firstfreeb % ALIGNSIZE != 0) {
register char *fb = firstfreeb;
fb = (char *)ALIGN((long)fb);
firstfreeb = sys_break(fb - firstfreeb);
firstfreeb = fb;
ASSERT((long)firstfreeb % ALIGNSIZE == 0);
}
}
#ifdef DEBUG
mem_stat()
{
extern char options[];
if (options['m'])
print("Total nr of bytes allocated: %d\n",
sys_break(0) - firstfreeb);
}
#endif DEBUG
#endif OWNALLOC

View file

@ -1,16 +0,0 @@
/* $Header$ */
/* PROGRAM'S INTERFACE TO MEMORY ALLOCATION ROUTINES */
/* This file serves as the interface between the program and the
memory allocating routines.
There are 3 memory allocation routines:
char *Malloc(n) to allocate n bytes
char *Salloc(str, n) to allocate n bytes
and fill them with string str
char *Realloc(str, n) reallocate the string at str to n bytes
*/
extern char *Salloc(), *malloc(), *realloc();
#define Malloc(n) malloc((unsigned)(n))
#define Srealloc(ptr,n) realloc(ptr, (unsigned)(n))

View file

@ -1,23 +0,0 @@
/* $Header$ */
/* C O D E - G E N E R A T O R D E F I N I T I O N S */
struct stat_block {
struct stat_block *next;
label st_break;
label st_continue;
};
/* allocation definitions of struct stat_block */
/* ALLOCDEF "stat_block" */
extern char *st_alloc();
extern struct stat_block *h_stat_block;
#define new_stat_block() ((struct stat_block *) \
st_alloc((char **)&h_stat_block, sizeof(struct stat_block)))
#define free_stat_block(p) st_free(p, h_stat_block, sizeof(struct stat_block))
#define LVAL 0
#define RVAL 1
#define FALSE 0
#define TRUE 1

View file

@ -1,45 +0,0 @@
/* $Header$ */
/* DEFINITION OF DECLARATOR DESCRIPTORS */
/* A 'declarator' consists of an idf and a linked list of
language-defined unary operations: *, [] and (), called
decl_unary's.
*/
struct declarator {
struct declarator *next;
struct idf *dc_idf;
struct decl_unary *dc_decl_unary;
struct idstack_item *dc_fparams; /* params for function */
};
/* allocation definitions of struct declarator */
/* ALLOCDEF "declarator" */
extern char *st_alloc();
extern struct declarator *h_declarator;
#define new_declarator() ((struct declarator *) \
st_alloc((char **)&h_declarator, sizeof(struct declarator)))
#define free_declarator(p) st_free(p, h_declarator, sizeof(struct declarator))
#define NO_PARAMS ((struct idstack_item *) 0)
struct decl_unary {
struct decl_unary *next;
int du_fund; /* POINTER, ARRAY or FUNCTION */
arith du_count; /* for ARRAYs only */
};
/* allocation definitions of struct decl_unary */
/* ALLOCDEF "decl_unary" */
extern char *st_alloc();
extern struct decl_unary *h_decl_unary;
#define new_decl_unary() ((struct decl_unary *) \
st_alloc((char **)&h_decl_unary, sizeof(struct decl_unary)))
#define free_decl_unary(p) st_free(p, h_decl_unary, sizeof(struct decl_unary))
extern struct type *declare_type();
extern struct declarator null_declarator;

View file

@ -1,23 +0,0 @@
/* $Header$ */
/* DECLARATION SPECIFIER DEFINITION */
struct decspecs {
struct decspecs *next;
struct type *ds_type; /* single type */
int ds_sc_given; /* 1 if the st. class is explicitly given */
int ds_sc; /* storage class, given or implied */
int ds_size; /* LONG, SHORT or 0 */
int ds_unsigned; /* 0 or 1 */
};
/* allocation definitions of struct decspecs */
/* ALLOCDEF "decspecs" */
extern char *st_alloc();
extern struct decspecs *h_decspecs;
#define new_decspecs() ((struct decspecs *) \
st_alloc((char **)&h_decspecs, sizeof(struct decspecs)))
#define free_decspecs(p) st_free(p, h_decspecs, sizeof(struct decspecs))
extern struct decspecs null_decspecs;

View file

@ -1,37 +0,0 @@
/* $Header$ */
/* IDENTIFIER DEFINITION DESCRIPTOR */
struct def { /* for ordinary tags */
struct def *next;
int df_level;
struct type *df_type;
int df_sc; /* may be:
GLOBAL, STATIC, EXTERN, IMPLICIT,
TYPEDEF,
FORMAL, AUTO,
ENUM, LABEL
*/
int df_register; /* REG_NONE, REG_DEFAULT or REG_BONUS */
char df_initialized; /* an initialization has been generated */
char df_alloc; /* 0, ALLOC_SEEN or ALLOC_DONE */
char df_used; /* set if idf is used */
char df_formal_array; /* to warn if sizeof is taken */
arith df_address;
};
#define ALLOC_SEEN 1 /* an allocating declaration has been seen */
#define ALLOC_DONE 2 /* the allocating declaration has been done */
#define REG_NONE 0 /* no register candidate */
#define REG_DEFAULT 1 /* register candidate, not declared as such */
#define REG_BONUS 10 /* register candidate, declared as such */
/* allocation definitions of struct def */
/* ALLOCDEF "def" */
extern char *st_alloc();
extern struct def *h_def;
#define new_def() ((struct def *) \
st_alloc((char **)&h_def, sizeof(struct def)))
#define free_def(p) st_free(p, h_def, sizeof(struct def))

View file

@ -1,144 +0,0 @@
/* $Header$ */
/* STRING MANIPULATION AND PRINT ROUTINES */
#include <system.h>
#include "ssize.h"
char *long2str();
static
integral(c)
{
switch (c) {
case 'b':
return -2;
case 'd':
return 10;
case 'o':
return -8;
case 'u':
return -10;
case 'x':
return -16;
}
return 0;
}
static int
format(buf, fmt, argp)
char *buf, *fmt;
char *argp;
{
register char *pf = fmt, *pa = argp;
register char *pb = buf;
while (*pf) {
if (*pf == '%') {
register width, base, pad, npad;
char *arg;
char cbuf[2];
char *badformat = "<bad format>";
/* get padder */
if (*++pf == '0') {
pad = '0';
++pf;
}
else
pad = ' ';
/* get width */
width = 0;
while (*pf >= '0' && *pf <= '9')
width = 10 * width + *pf++ - '0';
/* get text and move pa */
if (*pf == 's') {
arg = *(char **)pa;
pa += sizeof(char *);
}
else
if (*pf == 'c') {
cbuf[0] = * (char *) pa;
cbuf[1] = '\0';
pa += sizeof(int);
arg = &cbuf[0];
}
else
if (*pf == 'l') {
/* alignment ??? */
if (base = integral(*++pf)) {
arg = long2str(*(long *)pa, base);
pa += sizeof(long);
}
else {
pf--;
arg = badformat;
}
}
else
if (base = integral(*pf)) {
arg = long2str((long)*(int *)pa, base);
pa += sizeof(int);
}
else
if (*pf == '%')
arg = "%";
else
arg = badformat;
npad = width - strlen(arg);
while (npad-- > 0)
*pb++ = pad;
while (*pb++ = *arg++);
pb--;
pf++;
}
else
*pb++ = *pf++;
}
return pb - buf;
}
doprnt(fp, fmt, argp)
File *fp;
char *fmt;
int argp[];
{
char buf[SSIZE];
sys_write(fp, buf, format(buf, fmt, (char *)argp));
}
/*VARARGS1*/
printf(fmt, args)
char *fmt;
char args;
{
char buf[SSIZE];
sys_write(STDOUT, buf, format(buf, fmt, &args));
}
/*VARARGS1*/
fprintf(fp, fmt, args)
File *fp;
char *fmt;
char args;
{
char buf[SSIZE];
sys_write(fp, buf, format(buf, fmt, &args));
}
/*VARARGS1*/
char *
sprintf(buf, fmt, args)
char *buf, *fmt;
char args;
{
buf[format(buf, fmt, &args)] = '\0';
return buf;
}

View file

@ -1,201 +0,0 @@
/* $Header$ */
/* EM CODE OUTPUT ROUTINES */
#define CMODE 0644
#define MAX_ARG_CNT 32
#include "em.h"
#include <system.h>
#include "arith.h"
#include "label.h"
/*
putbyte(), C_open() and C_close() are the basic routines for
respectively write on, open and close the output file.
The put_*() functions serve as formatting functions of the
various EM language constructs.
See "Description of a Machine Architecture for use with
Block Structured Languages" par. 11.2 for the meaning of these
names.
*/
/* supply a kind of buffered output */
#define flush(x) sys_write(ofp, &obuf[0], x)
static char obuf[BUFSIZ];
static char *opp = &obuf[0];
File *ofp = 0;
putbyte(b) /* shouldn't putbyte() be a macro ??? (EB) */
int b;
{
if (opp >= &obuf[BUFSIZ]) { /* flush if buffer overflows */
if (flush(BUFSIZ) == 0)
sys_stop(S_ABORT);
opp = &obuf[0];
}
*opp++ = (char) b;
}
C_init(wsize, psize)
arith wsize, psize;
{}
C_open(nm) /* open file for compact code output */
char *nm;
{
if (nm == 0)
ofp = STDOUT; /* standard output */
else
if (sys_open(nm, OP_WRITE, &ofp) == 0)
return 0;
return 1;
}
C_close()
{
if (flush(opp - &obuf[0]) == 0)
sys_stop(S_ABORT);
opp = obuf; /* reset opp */
if (ofp != STDOUT)
sys_close(ofp);
ofp = 0;
}
C_busy()
{
return ofp != 0; /* true if code is being generated */
}
/*** the compact code generating routines ***/
#define fit16i(x) ((x) >= (long)0xFFFF8000 && (x) <= (long)0x00007FFF)
#define fit8u(x) ((x) <= 0xFF) /* x is already unsigned */
put_ilb(l)
label l;
{
if (fit8u(l)) {
put8(sp_ilb1);
put8((int)l);
}
else {
put8(sp_ilb2);
put16(l);
}
}
put_dlb(l)
label l;
{
if (fit8u(l)) {
put8(sp_dlb1);
put8((int)l);
}
else {
put8(sp_dlb2);
put16(l);
}
}
put_cst(l)
arith l;
{
if (l >= (arith) -sp_zcst0 && l < (arith) (sp_ncst0 - sp_zcst0)) {
/* we can convert 'l' to an int because its value
can be stored in a byte.
*/
put8((int) l + (sp_zcst0 + sp_fcst0));
}
else
if (fit16i(l)) { /* the cast from long to int causes no trouble here */
put8(sp_cst2);
put16((int) l);
}
else {
put8(sp_cst4);
put32(l);
}
}
put_doff(l, v)
label l;
arith v;
{
if (v == 0)
put_dlb(l);
else {
put8(sp_doff);
put_dlb(l);
put_cst(v);
}
}
put_noff(s, v)
char *s;
arith v;
{
if (v == 0)
put_dnam(s);
else {
put8(sp_doff);
put_dnam(s);
put_cst(v);
}
}
put_dnam(s)
char *s;
{
put8(sp_dnam);
put_str(s);
}
put_pnam(s)
char *s;
{
put8(sp_pnam);
put_str(s);
}
#ifdef ____
put_fcon(s, sz)
char *s;
arith sz;
{
put8(sp_fcon);
put_cst(sz);
put_str(s);
}
#endif ____
put_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */
int sp;
char *v;
arith sz;
{
/* how 'bout signextension int --> long ??? */
put8(sp);
put_cst(sz);
put_str(v);
}
put_str(s)
char *s;
{
register int len;
put_cst((arith) (len = strlen(s)));
while (--len >= 0)
put8(*s++);
}
put_cstr(s)
char *s;
{
register int len = prepare_string(s);
put8(sp_scon);
put_cst((arith) len);
while (--len >= 0)
put8(*s++);
}

View file

@ -1,42 +0,0 @@
/* $Header$ */
/* DESCRIPTION OF INTERFACE TO EM CODE GENERATING ROUTINES */
#include "proc_intf.h" /* use macros or functions */
/* include the EM description files */
#include <em_spec.h>
#include <em_pseu.h>
#include <em_mes.h>
#include <em_mnem.h>
#include <em_reg.h>
/* macros used in the definitions of the interface functions C_* */
#define OP(x) put_op(x)
#define CST(x) put_cst(x)
#define DCST(x) put_cst(x)
#define CSTR(x) put_cstr(x)
#define PS(x) put_ps(x)
#define DLB(x) put_dlb(x)
#define ILB(x) put_ilb(x)
#define NOFF(x,y) put_noff((x), (y))
#define DOFF(x,y) put_doff((x), (y))
#define PNAM(x) put_pnam(x)
#define DNAM(x) put_dnam(x)
#define CEND() put_cend()
#define WCON(x,y,z) put_wcon((x), (y), (z))
#define FCON(x,y) put_fcon((x), (y))
/* variants of primitive "putbyte" */
#define put8(x) putbyte(x) /* defined in "em.c" */
#define put16(x) (put8((int) x), put8((int) (x >> 8)))
#define put32(x) (put16((int) x), put16((int) (x >> 16)))
#define put_cend() put8(sp_cend)
#define put_op(x) put8(x)
#define put_ps(x) put8(x)
/* user interface */
#define C_magic() put16(sp_magic) /* EM magic word */
#ifndef PROC_INTF
#include "writeem.h"
#endif PROC_INTF

View file

@ -1,71 +0,0 @@
/*
* (c) copyright 1990 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* This file can be considered the em_code.h file of lint.
* Those code generating functions that are used by cem and that have not
* been defined away by #ifdef LINT, are defined away here. Note that this a
* fairly random collection. E.g. it does not include C_open(), since the
* standard C-open() C_close() sequence is protected by #ifdef LINT, but it
* does include C_close() since the latter is also called in other places,
* to terminate the compilation process.
*/
#define C_asp(c)
#define C_bra(b)
#define C_cal(p)
#define C_csa(w)
#define C_csb(w)
#define C_fil_dlb(g,o)
#define C_lae_dlb(g,o)
#define C_lal(c)
#define C_lin(c)
#define C_loi(c)
#define C_lol(c)
#define C_sdl(c)
#define C_sti(c)
#define C_stl(c)
#define C_busy() 0
#define C_close()
#define C_df_dlb(l)
#define C_df_dnam(s)
#define C_df_ilb(l)
#define C_pro_narg(s)
#define C_end(l)
#define C_exa_dnam(s)
#define C_ina_dnam(s)
#define C_ina_dlb(l)
#define C_exp(s)
#define C_inp(s)
#define C_bss_cst(n,w,i)
#define C_con_cst(v)
#define C_con_icon(v,s)
#define C_con_ucon(v,s)
#define C_con_fcon(v,s)
#define C_con_scon(v,s)
#define C_con_dnam(v,s)
#define C_con_dlb(v,s)
#define C_con_pnam(v)
#define C_rom_cst(v)
#define C_rom_scon(v,s)
#define C_rom_ilb(v)
#define C_ldl(l)
#define C_mes_begin(ms)
#define C_mes_end()
#define C_ms_gto()
#define C_ms_par(b)
#define C_ms_reg(o,s,t,c)

View file

@ -1,136 +0,0 @@
% emcode definitions for the CEM compiler -- intermediate code
C_adf(p) | arith p; | OP(op_adf), CST(p)
C_adi(p) | arith p; | OP(op_adi), CST(p)
C_adp(p) | arith p; | OP(op_adp), CST(p)
C_ads(p) | arith p; | OP(op_ads), CST(p)
C_adu(p) | arith p; | OP(op_adu), CST(p)
C_and(p) | arith p; | OP(op_and), CST(p)
C_asp(p) | arith p; | OP(op_asp), CST(p)
C_bra(l) | label l; | OP(op_bra), CST((arith)l)
C_cai() | | OP(op_cai)
C_cal(p) | char *p; | OP(op_cal), PNAM(p)
C_cff() | | OP(op_cff)
C_cfi() | | OP(op_cfi)
C_cfu() | | OP(op_cfu)
C_cif() | | OP(op_cif)
C_cii() | | OP(op_cii)
C_ciu() | | OP(op_ciu)
C_cmf(p) | arith p; | OP(op_cmf), CST(p)
C_cmi(p) | arith p; | OP(op_cmi), CST(p)
C_cmp() | | OP(op_cmp)
C_cmu(p) | arith p; | OP(op_cmu), CST(p)
C_com(p) | arith p; | OP(op_com), CST(p)
C_csa(p) | arith p; | OP(op_csa), CST(p)
C_csb(p) | arith p; | OP(op_csb), CST(p)
C_cuf() | | OP(op_cuf)
C_cui() | | OP(op_cui)
C_cuu() | | OP(op_cuu)
C_dup(p) | arith p; | OP(op_dup), CST(p)
C_dvf(p) | arith p; | OP(op_dvf), CST(p)
C_dvi(p) | arith p; | OP(op_dvi), CST(p)
C_dvu(p) | arith p; | OP(op_dvu), CST(p)
C_fil_dlb(l, o) | label l; arith o; | OP(op_fil), DOFF(l, o)
C_ior(p) | arith p; | OP(op_ior), CST(p)
C_lae_dnam(p, o) | char *p; arith o; | OP(op_lae), NOFF(p, o)
C_lae_dlb(l, o) | label l; arith o; | OP(op_lae), DOFF(l, o)
C_lal(p) | arith p; | OP(op_lal), CST(p)
C_ldc(p) | arith p; | OP(op_ldc), DCST(p)
C_lde_dnam(p, o) | char *p; arith o; | OP(op_lde), NOFF(p, o)
C_lde_dlb(l, o) | label l; arith o; | OP(op_lde), DOFF(l, o)
C_ldl(p) | arith p; | OP(op_ldl), CST(p)
C_lfr(p) | arith p; | OP(op_lfr), CST(p)
C_lin(p) | arith p; | OP(op_lin), CST(p)
C_loc(p) | arith p; | OP(op_loc), CST(p)
C_loe_dnam(p, o) | char *p; arith o; | OP(op_loe), NOFF(p, o)
C_loe_dlb(l, o) | label l; arith o; | OP(op_loe), DOFF(l, o)
C_loi(p) | arith p; | OP(op_loi), CST(p)
C_lol(p) | arith p; | OP(op_lol), CST(p)
C_lor(p) | arith p; | OP(op_lor), CST(p)
C_lpi(p) | char *p; | OP(op_lpi), PNAM(p)
C_mlf(p) | arith p; | OP(op_mlf), CST(p)
C_mli(p) | arith p; | OP(op_mli), CST(p)
C_mlu(p) | arith p; | OP(op_mlu), CST(p)
C_ngf(p) | arith p; | OP(op_ngf), CST(p)
C_ngi(p) | arith p; | OP(op_ngi), CST(p)
C_ret(p) | arith p; | OP(op_ret), CST(p)
C_rmi(p) | arith p; | OP(op_rmi), CST(p)
C_rmu(p) | arith p; | OP(op_rmu), CST(p)
C_sbf(p) | arith p; | OP(op_sbf), CST(p)
C_sbi(p) | arith p; | OP(op_sbi), CST(p)
C_sbs(p) | arith p; | OP(op_sbs), CST(p)
C_sbu(p) | arith p; | OP(op_sbu), CST(p)
C_sde_dnam(p, o) | char *p; arith o; | OP(op_sde), NOFF(p, o)
C_sde_dlb(l, o) | label l; arith o; | OP(op_sde), DOFF(l, o)
C_sdl(p) | arith p; | OP(op_sdl), CST(p)
C_sli(p) | arith p; | OP(op_sli), CST(p)
C_slu(p) | arith p; | OP(op_slu), CST(p)
C_sri(p) | arith p; | OP(op_sri), CST(p)
C_sru(p) | arith p; | OP(op_sru), CST(p)
C_ste_dnam(p, o) | char *p; arith o; | OP(op_ste), NOFF(p, o)
C_ste_dlb(l, o) | label l; arith o; | OP(op_ste), DOFF(l, o)
C_sti(p) | arith p; | OP(op_sti), CST(p)
C_stl(p) | arith p; | OP(op_stl), CST(p)
C_xor(p) | arith p; | OP(op_xor), CST(p)
C_zeq(l) | label l; | OP(op_zeq), CST((arith)l)
C_zge(l) | label l; | OP(op_zge), CST((arith)l)
C_zgt(l) | label l; | OP(op_zgt), CST((arith)l)
C_zle(l) | label l; | OP(op_zle), CST((arith)l)
C_zlt(l) | label l; | OP(op_zlt), CST((arith)l)
C_zne(l) | label l; | OP(op_zne), CST((arith)l)
%
C_df_dlb(l) | label l; | DLB(l)
C_df_dnam(s) | char *s; | DNAM(s)
C_df_ilb(l) | label l; | ILB(l)
%
C_bss_cst(n, w, i) | arith n, w; int i; |
PS(ps_bss), DCST(n), CST(w), CST((arith)i)
%
C_con_icon(val, siz) | char *val; arith siz; |
PS(ps_con), WCON(sp_icon, val, siz), CEND()
C_con_ucon(val, siz) | char *val; arith siz; |
PS(ps_con), WCON(sp_ucon, val, siz), CEND()
C_con_fcon(val, siz) | char *val; arith siz; |
PS(ps_con), WCON(sp_fcon, val, siz), CEND()
C_con_scon(str, siz) | char *str; arith siz; | PS(ps_con), CSTR(str), CEND()
C_con_dnam(str, val) | char *str; arith val; |
PS(ps_con), NOFF(str, val), CEND()
C_con_dlb(l, val) | label l; arith val; |
PS(ps_con), DOFF(l, val), CEND()
C_con_pnam(str) | char *str; | PS(ps_con), PNAM(str), CEND()
%
C_rom_cst(l) | arith l; | PS(ps_rom), CST(l), CEND()
C_rom_icon(val, siz) | char *val; arith siz; |
PS(ps_rom), WCON(sp_icon, val, siz), CEND()
C_rom_fcon(val, siz) | char *val; arith siz; |
PS(ps_rom), WCON(sp_fcon, val, siz), CEND()
C_rom_ilb(l) | label l; | PS(ps_rom), ILB(l), CEND()
%
C_cst(l) | arith l; | CST(l)
C_icon(val, siz) | char *val; arith siz; | WCON(sp_icon, val, siz)
C_ucon(val, siz) | char *val; arith siz; | WCON(sp_ucon, val, siz)
C_fcon(val, siz) | char *val; arith siz; | WCON(sp_fcon, val, siz)
C_scon(str, siz) | char *str; arith siz; | CSTR(str)
C_dnam(str, val) | char *str; arith val; | NOFF(str, val)
C_dlb(l, val) | label l; arith val; | DOFF(l, val)
C_pnam(str) | char *str; | PNAM(str)
C_ilb(l) | label l; | ILB(l)
%
C_pro_narg(p1) | char *p1; | PS(ps_pro), PNAM(p1), CEND()
C_end(l) | arith l; | PS(ps_end), CST(l)
%
C_exa(s) | char *s; | PS(ps_exa), DNAM(s)
C_exp(s) | char *s; | PS(ps_exp), PNAM(s)
C_ina_pt(l) | label l; | PS(ps_ina), DLB(l)
C_ina(s) | char *s; | PS(ps_ina), DNAM(s)
C_inp(s) | char *s; | PS(ps_inp), PNAM(s)
%
C_ms_err() | | PS(ps_mes), CST((arith)ms_err), CEND()
C_ms_emx(p1, p2) | arith p1, p2; |
PS(ps_mes), CST((arith)ms_emx), CST(p1), CST(p2), CEND()
C_ms_reg(a, b, c, d) | arith a, b; int c, d; |
PS(ps_mes), CST((arith)ms_reg), CST(a), CST(b), CST((arith)c), CST((arith)d), CEND()
C_ms_src(l, s) | arith l; char *s; |
PS(ps_mes), CST((arith)ms_src), CST(l), CSTR(s), CEND()
C_ms_flt() | | PS(ps_mes), CST((arith)ms_flt), CEND()
C_ms_par(l) | arith l; | PS(ps_mes), CST((arith)ms_par), CST(l), CEND()
C_ms_gto() | | PS(ps_mes), CST((arith)ms_gto), CEND()

View file

@ -1,102 +0,0 @@
/* $Header$ */
/* EXPRESSION DESCRIPTOR */
/* What we want to define is the struct expr, but since it contains
a union of various goodies, we define them first; so be patient.
*/
struct value {
struct idf *vl_idf; /* idf of an external name or 0 */
arith vl_value; /* constant, or offset if idf != 0 */
};
struct string {
char *sg_value; /* string of characters repr. the constant */
label sg_datlab; /* global data-label */
};
struct floating {
char *fl_value; /* pointer to string repr. the fp const. */
label fl_datlab; /* global data_label */
};
struct oper {
struct type *op_type; /* resulting type of the operation */
struct expr *op_left;
int op_oper; /* the symbol of the operator */
struct expr *op_right;
};
/* The following constants indicate the class of the expression: */
#define Value 0 /* it is a value known at load time */
#define String 1 /* it is a string constant */
#define Float 2 /* it is a floating point constant */
#define Oper 3 /* it is a run-time expression */
#define Type 4 /* only its type is relevant */
struct expr {
struct expr *next;
char *ex_file; /* the file it (probably) comes from */
unsigned int ex_line; /* the line it (probably) comes from */
struct type *ex_type;
char ex_lvalue;
char ex_flags;
int ex_class;
int ex_depth;
union {
struct value ex_value;
struct string ex_string;
struct floating ex_float;
struct oper ex_oper;
} ex_object;
};
/* some abbreviated selections */
#define VL_VALUE ex_object.ex_value.vl_value
#define VL_IDF ex_object.ex_value.vl_idf
#define SG_VALUE ex_object.ex_string.sg_value
#define SG_DATLAB ex_object.ex_string.sg_datlab
#define FL_VALUE ex_object.ex_float.fl_value
#define FL_DATLAB ex_object.ex_float.fl_datlab
#define OP_TYPE ex_object.ex_oper.op_type
#define OP_LEFT ex_object.ex_oper.op_left
#define OP_OPER ex_object.ex_oper.op_oper
#define OP_RIGHT ex_object.ex_oper.op_right
#define EXPRTYPE(e) ((e)->ex_type->tp_fund)
/* An expression is a `load-time constant' if it is of the form
<idf> +/- <integral> or <integral>;
it is a `compile-time constant' if it is an <integral>.
*/
#define is_ld_cst(e) ((e)->ex_lvalue == 0 && (e)->ex_class == Value)
#define is_cp_cst(e) (is_ld_cst(e) && (e)->VL_IDF == 0)
/* a floating constant expression ?
*/
#define is_fp_cst(e) ((e)->ex_class == Float)
/* some bits for the ex_flag field, to keep track of various
interesting properties of an expression.
*/
#define EX_SIZEOF 001 /* contains sizeof operator */
#define EX_CAST 002 /* contains cast */
#define EX_LOGICAL 004 /* contains logical operator */
#define EX_COMMA 010 /* contains expression comma */
#define EX_PARENS 020 /* the top level is parenthesized */
#define NILEXPR ((struct expr *)0)
extern struct expr *intexpr(), *new_oper();
/* allocation definitions of struct expr */
/* ALLOCDEF "expr" */
extern char *st_alloc();
extern struct expr *h_expr;
#define new_expr() ((struct expr *) \
st_alloc((char **)&h_expr, sizeof(struct expr)))
#define free_expr(p) st_free(p, h_expr, sizeof(struct expr))
#define ISCOMMA(e) ((e)->ex_class == Oper && (e)->OP_OPER == INITCOMMA)

View file

@ -1,9 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* FAULTY DEFINITIONS */
#define faulty(tp) ((tp)_faulty(__FILE__, __LINE__))
#define fault() (_faulty(__FILE__, __LINE__))

View file

@ -1,20 +0,0 @@
/* $Header$ */
/* FIELD DESCRIPTOR */
struct field { /* for field specifiers */
struct field *next;
arith fd_mask;
int fd_shift;
int fd_width;
struct sdef *fd_sdef; /* upward pointer */
};
/* allocation definitions of struct field */
/* ALLOCDEF "field" */
extern char *st_alloc();
extern struct field *h_field;
#define new_field() ((struct field *) \
st_alloc((char **)&h_field, sizeof(struct field)))
#define free_field(p) st_free(p, h_field, sizeof(struct field))

View file

@ -1,68 +0,0 @@
/* $Header$ */
/* IDENTIFIER DESCRIPTOR */
#include "nopp.h"
/* Since the % operation in the calculation of the hash function
turns out to be expensive, it is replaced by the cheaper XOR (^).
Each character of the identifier is xored with an 8-bit mask which
depends on the position of the character; the sum of these results
is the hash value. The random masks are obtained from a
congruence generator in idf.c.
*/
#define HASHSIZE 256 /* must be a power of 2 */
#define HASH_X 0253 /* Knuth's X */
#define HASH_A 77 /* Knuth's a */
#define HASH_C 153 /* Knuth's c */
extern char hmask[]; /* the random masks */
#define HASHMASK (HASHSIZE-1) /* since it is a power of 2 */
#define STARTHASH() (0)
#define ENHASH(hs,ch,ps) (hs + (ch ^ hmask[ps]))
#define STOPHASH(hs) (hs & HASHMASK)
struct idstack_item { /* stack of identifiers */
struct idstack_item *next;
struct idf *is_idf;
};
/* allocation definitions of struct idstack_item */
/* ALLOCDEF "idstack_item" */
extern char *st_alloc();
extern struct idstack_item *h_idstack_item;
#define new_idstack_item() ((struct idstack_item *) \
st_alloc((char **)&h_idstack_item, sizeof(struct idstack_item)))
#define free_idstack_item(p) st_free(p, h_idstack_item, sizeof(struct idstack_item))
struct idf {
struct idf *next;
char *id_text;
#ifndef NOPP
struct macro *id_macro;
int id_resmac; /* if nonzero: keyword of macroproc. */
#endif NOPP
int id_reserved; /* non-zero for reserved words */
struct def *id_def; /* variables, typedefs, enum-constants */
struct sdef *id_sdef; /* selector tags */
struct tag *id_struct; /* struct and union tags */
struct tag *id_enum; /* enum tags */
int id_special; /* special action needed at occurrence */
};
/* allocation definitions of struct idf */
/* ALLOCDEF "idf" */
extern char *st_alloc();
extern struct idf *h_idf;
#define new_idf() ((struct idf *) \
st_alloc((char **)&h_idf, sizeof(struct idf)))
#define free_idf(p) st_free(p, h_idf, sizeof(struct idf))
extern struct idf *str2idf(), *idf_hashed();
extern int level;
extern struct idf *gen_idf();

View file

@ -1,624 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */
#include "nofloat.h"
#include <em.h>
#include "debug.h"
#include <alloc.h>
#include "nobitfield.h"
#include "arith.h"
#include "align.h"
#include "label.h"
#include "expr.h"
#include "type.h"
#include "struct.h"
#include "field.h"
#include "assert.h"
#include "Lpars.h"
#include "class.h"
#include "sizes.h"
#include "idf.h"
#include "level.h"
#include "def.h"
#define con_nullbyte() C_con_ucon("0", (arith)1)
char *symbol2str();
char *long2str();
char *strncpy();
struct expr *do_array(), *do_struct(), *IVAL();
extern char options[];
/* do_ival() performs the initialisation of a global variable
of type tp with the initialisation expression expr by calling IVAL().
Guided by type tp, the expression is evaluated.
*/
do_ival(tpp, ex)
struct type **tpp;
struct expr *ex;
{
if (IVAL(tpp, ex) != 0)
too_many_initialisers(ex);
}
/* IVAL() recursively guides the initialisation expression through the
different routines for the different types of initialisation:
- array initialisation
- struct initialisation
- fundamental type initialisation
Upto now, the initialisation of a union is not allowed!
An initialisation expression tree consists of normal expressions
which can be joined together by ',' nodes, which operator acts
like the lisp function "cons" to build lists.
IVAL() returns a pointer to the remaining expression tree.
*/
struct expr *
IVAL(tpp, ex)
struct type **tpp; /* type of global variable */
register struct expr *ex; /* initialiser expression */
{
register struct type *tp = *tpp;
switch (tp->tp_fund) {
case ARRAY: /* array initialisation */
if (valid_type(tp->tp_up, "array element") == 0)
return 0;
if (ISCOMMA(ex)) /* list of initialisation expressions */
return do_array(ex, tpp);
if (tp->tp_up->tp_fund == CHAR && ex->ex_class == String)
/* initialisation like char s[] = "I am a string" */
ch_array(tpp, ex);
else /* " int i[24] = 12;" */
check_and_pad(ex, tpp);
break;
case STRUCT: /* struct initialisation */
if (valid_type(tp, "struct") == 0)
return 0;
if (ISCOMMA(ex)) /* list of initialisation expressions */
return do_struct(ex, tp);
check_and_pad(ex, tpp); /* "struct foo f = 12;" */
break;
case UNION:
error("union initialisation not allowed");
break;
case ERRONEOUS:
break;
default: /* fundamental type */
if (ISCOMMA(ex)) { /* " int i = {12};" */
if (IVAL(tpp, ex->OP_LEFT) != 0)
too_many_initialisers(ex);
/* return remainings of the list for the
other members of the aggregate, if this
item belongs to an aggregate.
*/
return ex->OP_RIGHT;
}
check_ival(ex, tp); /* "int i = 12;" */
break;
}
return 0;
}
/* do_array() initialises the members of an array described
by type tp with the expressions in expr.
Two important cases:
- the number of members is known
- the number of members is not known
In the latter case, do_array() digests the whole expression
tree it is given.
In the former case, do_array() eats as many members from
the expression tree as are needed for the array.
If there are not sufficient members for the array, the remaining
members are padded with zeroes
*/
struct expr *
do_array(ex, tpp)
register struct expr *ex;
struct type **tpp;
{
register struct type *tp = *tpp;
register arith elem_count;
ASSERT(tp->tp_fund == ARRAY && ISCOMMA(ex));
/* the following test catches initialisations like
char c[] = {"just a string"};
or
char d[] = {{"just another string"}};
The use of the brackets causes this problem.
Note: although the implementation of such initialisations
is completely foolish, we did it!! (no applause, thank you)
*/
if (tp->tp_up->tp_fund == CHAR) {
register struct expr *f = ex->OP_LEFT, *g = NILEXPR;
while (ISCOMMA(f)) { /* eat the brackets!!! */
g = f;
f = f->OP_LEFT;
}
if (f->ex_class == String) { /* hallelujah, it's a string! */
ch_array(tpp, f);
return g ? g->OP_RIGHT : ex->OP_RIGHT;
}
/* else: just go on with the next part of this function */
if (g != 0)
ex = g;
}
if (tp->tp_size == (arith)-1) {
/* declared with unknown size: [] */
for (elem_count = 0; ex; elem_count++) {
/* eat whole initialisation expression */
if (ISCOMMA(ex->OP_LEFT)) { /* embraced member */
if (IVAL(&(tp->tp_up), ex->OP_LEFT) != 0)
too_many_initialisers(ex);
ex = ex->OP_RIGHT;
}
else {
if (aggregate_type(tp->tp_up))
ex = IVAL(&(tp->tp_up), ex);
else {
check_ival(ex->OP_LEFT, tp->tp_up);
ex = ex->OP_RIGHT;
}
}
}
/* set the proper size */
*tpp = construct_type(ARRAY, tp->tp_up, elem_count);
}
else { /* the number of members is already known */
arith dim = tp->tp_size / tp->tp_up->tp_size;
for (elem_count = 0; elem_count < dim && ex; elem_count++) {
if (ISCOMMA(ex->OP_LEFT)) { /* embraced member */
if (IVAL(&(tp->tp_up), ex->OP_LEFT) != 0)
too_many_initialisers(ex);
ex = ex->OP_RIGHT;
}
else {
if (aggregate_type(tp->tp_up))
ex = IVAL(&(tp->tp_up), ex);
else {
check_ival(ex->OP_LEFT, tp->tp_up);
ex = ex->OP_RIGHT;
}
}
}
if (ex && elem_count == dim)
/* all the members are initialised but there
remains a part of the expression tree which
is returned
*/
return ex;
if ((ex == 0) && elem_count < dim)
/* the expression tree is completely absorbed
but there are still members which must be
initialised with zeroes
*/
do
pad(tp->tp_up);
while (++elem_count < dim);
}
return 0;
}
/* do_struct() initialises a struct of type tp with the expression expr.
The main loop is just controlled by the definition of the selectors
during which alignment is taken care of.
*/
struct expr *
do_struct(ex, tp)
register struct expr *ex;
register struct type *tp;
{
register struct sdef *sd = tp->tp_sdef;
arith bytes_upto_here = (arith)0;
arith last_offset = (arith)-1;
ASSERT(tp->tp_fund == STRUCT && ISCOMMA(ex));
/* as long as there are selectors and there is an initialiser.. */
while (sd && ex) {
if (ISCOMMA(ex->OP_LEFT)) { /* embraced expression */
if (IVAL(&(sd->sd_type), ex->OP_LEFT) != 0)
too_many_initialisers(ex);
ex = ex->OP_RIGHT;
}
else {
if (aggregate_type(sd->sd_type))
/* selector is an aggregate itself */
ex = IVAL(&(sd->sd_type), ex);
else {
#ifdef NOBITFIELD
/* fundamental type, not embraced */
check_ival(ex->OP_LEFT, sd->sd_type);
ex = ex->OP_RIGHT;
#else
if (is_anon_idf(sd->sd_idf))
/* a hole in the struct due to
the use of ";:n;" in a struct
definition.
*/
put_bf(sd->sd_type, (arith)0);
else { /* fundamental type, not embraced */
check_ival(ex->OP_LEFT, sd->sd_type);
ex = ex->OP_RIGHT;
}
#endif NOBITFIELD
}
}
if (sd->sd_sdef) /* align upto the next selector boundary */
bytes_upto_here += zero_bytes(sd);
if (last_offset != sd->sd_offset) {
/* don't take the field-width more than once */
bytes_upto_here +=
size_of_type(sd->sd_type, "selector");
last_offset = sd->sd_offset;
}
sd = sd->sd_sdef;
}
/* perfect fit if (ex && (sd == 0)) holds */
if ((ex == 0) && (sd != 0)) {
/* there are selectors left which must be padded with zeroes */
do {
pad(sd->sd_type);
/* take care of the alignment restrictions */
if (sd->sd_sdef)
bytes_upto_here += zero_bytes(sd);
/* no field thrown-outs here */
bytes_upto_here +=
size_of_type(sd->sd_type, "selector");
} while (sd = sd->sd_sdef);
}
/* keep on aligning... */
while (bytes_upto_here++ < tp->tp_size)
con_nullbyte();
return ex;
}
/* check_and_pad() is given a simple initialisation expression
where the type can be either a simple or an aggregate type.
In the latter case, only the first member is initialised and
the rest is zeroed.
*/
check_and_pad(ex, tpp)
register struct expr *ex;
struct type **tpp;
{
/* ex is of a fundamental type */
register struct type *tp = *tpp;
if (tp->tp_fund == ARRAY) {
if (valid_type(tp->tp_up, "array element") == 0)
return;
check_and_pad(ex, &(tp->tp_up)); /* first member */
if (tp->tp_size == (arith)-1)
/* no size specified upto here: just
set it to the size of one member.
*/
tp = *tpp = construct_type(ARRAY, tp->tp_up, (arith)1);
else {
register int dim = tp->tp_size / tp->tp_up->tp_size;
/* pad remaining members with zeroes */
while (--dim > 0)
pad(tp->tp_up);
}
}
else
if (tp->tp_fund == STRUCT) {
register struct sdef *sd = tp->tp_sdef;
if (valid_type(tp, "struct") == 0)
return;
check_and_pad(ex, &(sd->sd_type));
/* next selector is aligned by adding extra zeroes */
if (sd->sd_sdef)
zero_bytes(sd);
while (sd = sd->sd_sdef) { /* pad remaining selectors */
pad(sd->sd_type);
if (sd->sd_sdef)
zero_bytes(sd);
}
}
else /* simple type */
check_ival(ex, tp);
}
/* pad() fills an element of type tp with zeroes.
If the element is an aggregate, pad() is called recursively.
*/
pad(tp)
register struct type *tp;
{
register arith sz = tp->tp_size;
switch (tp->tp_fund) {
case ARRAY:
if (valid_type(tp->tp_up, "array element") == 0)
return;
break;
case STRUCT:
if (valid_type(tp, "struct") == 0)
return;
break;
case UNION:
if (valid_type(tp, "union") == 0)
return;
if (options['R']) {
warning("initialisation of unions not allowed");
}
break;
#ifndef NOBITFIELD
case FIELD:
put_bf(tp, (arith)0);
return;
#endif NOBITFIELD
case ERRONEOUS:
return;
}
while (sz >= word_size) {
C_con_cst((arith) 0);
sz -= word_size;
}
while (sz) {
C_con_icon("0", (arith) 1);
sz--;
}
}
/* check_ival() checks whether the initialisation of an element
of a fundamental type is legal and, if so, performs the initialisation
by directly generating the necessary code.
No further comment is needed to explain the internal structure
of this straightforward function.
*/
check_ival(expr, tp)
register struct expr *expr;
register struct type *tp;
{
/* The philosophy here is that ch7cast puts an explicit
conversion node in front of the expression if the types
are not compatible. In this case, the initialisation
expression is no longer a constant.
*/
struct expr *ex = expr;
switch (tp->tp_fund) {
case CHAR:
case SHORT:
case INT:
case LONG:
case ENUM:
case POINTER:
ch7cast(&ex, '=', tp);
expr = ex;
#ifdef DEBUG
print_expr("init-expr after cast", expr);
#endif DEBUG
if (!is_ld_cst(expr))
illegal_init_cst(expr);
else
if (expr->VL_CLASS == Const)
con_int(expr);
else
if (expr->VL_CLASS == Name) {
register struct idf *idf = expr->VL_IDF;
if (idf->id_def->df_level >= L_LOCAL)
illegal_init_cst(expr);
else /* e.g., int f(); int p = f; */
if (idf->id_def->df_type->tp_fund == FUNCTION)
C_con_pnam(idf->id_text);
else /* e.g., int a; int *p = &a; */
C_con_dnam(idf->id_text, expr->VL_VALUE);
}
else {
ASSERT(expr->VL_CLASS == Label);
C_con_dlb(expr->VL_LBL, expr->VL_VALUE);
}
break;
#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
ch7cast(&ex, '=', tp);
expr = ex;
#ifdef DEBUG
print_expr("init-expr after cast", expr);
#endif DEBUG
if (expr->ex_class == Float)
C_con_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
else
if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) {
/* float f = 1; */
expr = expr->OP_RIGHT;
if (is_cp_cst(expr))
C_con_fcon(long2str((long)expr->VL_VALUE, 10),
tp->tp_size);
else
illegal_init_cst(expr);
}
else
illegal_init_cst(expr);
break;
#endif NOFLOAT
#ifndef NOBITFIELD
case FIELD:
ch7cast(&ex, '=', tp->tp_up);
expr = ex;
#ifdef DEBUG
print_expr("init-expr after cast", expr);
#endif DEBUG
if (is_cp_cst(expr))
put_bf(tp, expr->VL_VALUE);
else
illegal_init_cst(expr);
break;
#endif NOBITFIELD
case ERRONEOUS:
break;
default:
crash("check_ival");
}
}
/* ch_array() initialises an array of characters when given
a string constant.
Alignment is taken care of.
*/
ch_array(tpp, ex)
struct type **tpp; /* type tp = array of characters */
struct expr *ex;
{
register struct type *tp = *tpp;
register arith length = ex->SG_LEN;
char *s;
arith ntopad;
ASSERT(ex->ex_class == String);
if (tp->tp_size == (arith)-1) {
/* set the dimension */
tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
ntopad = align(tp->tp_size, word_size) - tp->tp_size;
}
else {
arith dim = tp->tp_size / tp->tp_up->tp_size;
extern char options[];
if (length > dim) {
if (options['R'])
too_many_initialisers(ex);
else { /* don't take the null byte into account */
if (length > dim + 1)
expr_warning(ex,
"too many initialisers");
length = dim;
}
}
ntopad = align(dim, word_size) - length;
}
/* throw out the characters of the already prepared string */
s = Malloc((unsigned) (length + ntopad));
clear(s, (int) (length + ntopad));
strncpy(s, ex->SG_VALUE, (int) length);
free(ex->SG_VALUE);
str_cst(s, (int) (length + ntopad));
free(s);
}
/* As long as some parts of the pipeline cannot handle very long string
constants, string constants are written out in chunks
*/
str_cst(str, len)
register char *str;
register int len;
{
arith chunksize = ((127 + word_size) / word_size) * word_size;
while (len > chunksize) {
C_con_scon(str, chunksize);
len -= chunksize;
str += chunksize;
}
C_con_scon(str, (arith) len);
}
#ifndef NOBITFIELD
/* put_bf() takes care of the initialisation of (bit-)field
selectors of a struct: each time such an initialisation takes place,
put_bf() is called instead of the normal code generating routines.
Put_bf() stores the given integral value into "field" and
"throws" the result of "field" out if the current selector
is the last of this number of fields stored at the same address.
*/
put_bf(tp, val)
struct type *tp;
arith val;
{
static long field = (arith)0;
static arith offset = (arith)-1;
register struct field *fd = tp->tp_field;
register struct sdef *sd = fd->fd_sdef;
static struct expr exp;
ASSERT(sd);
if (offset == (arith)-1) {
/* first bitfield in this field */
offset = sd->sd_offset;
exp.ex_type = tp->tp_up;
exp.ex_class = Value;
exp.VL_CLASS = Const;
}
if (val != 0) /* insert the value into "field" */
field |= (val & fd->fd_mask) << fd->fd_shift;
if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) {
/* the selector was the last stored at this address */
exp.VL_VALUE = field;
con_int(&exp);
field = (arith)0;
offset = (arith)-1;
}
}
#endif NOBITFIELD
int
zero_bytes(sd)
register struct sdef *sd;
{
/* fills the space between a selector of a struct
and the next selector of that struct with zero-bytes.
*/
register int n = sd->sd_sdef->sd_offset - sd->sd_offset -
size_of_type(sd->sd_type, "struct member");
register int count = n;
while (n-- > 0)
con_nullbyte();
return count;
}
int
valid_type(tp, str)
struct type *tp;
char *str;
{
if (tp->tp_size < 0) {
error("size of %s unknown", str);
return 0;
}
return 1;
}
con_int(ex)
register struct expr *ex;
{
register struct type *tp = ex->ex_type;
ASSERT(is_cp_cst(ex));
if (tp->tp_unsigned)
C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size);
else
C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);
}
illegal_init_cst(ex)
struct expr *ex;
{
expr_error(ex, "illegal initialisation constant");
}
too_many_initialisers(ex)
struct expr *ex;
{
expr_error(ex, "too many initialisers");
}
aggregate_type(tp)
register struct type *tp;
{
return tp->tp_fund == ARRAY || tp->tp_fund == STRUCT;
}

View file

@ -1,70 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
*The following functions are hacked to null-functions (i.e. they
* do nothing). This needs another solution in the future. !!???!!
*/
#include "lint.h"
#ifdef LINT
#include "arith.h"
#include "label.h"
C_close(){}
int C_busy(){return 0;}
/* More routines */
/* ARGSUSED */
CC_bhcst(ps_xxx,n,w,i) arith n,w; {}
/* ARGSUSED */
CC_crcst(ps_xxx,v) arith v; {}
/* ARGSUSED */
CC_crdlb(ps_xxx,v,s) label v; arith s; {}
/* ARGSUSED */
CC_crdnam(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crxcon(op,ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crilb(ps_xxx,v) label v; {}
/* ARGSUSED */
CC_crpnam(ps_xxx,v) char *v; {}
/* ARGSUSED */
CC_crscon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_cst(l) {}
/* ARGSUSED */
CC_dfdlb(l) label l; {}
/* ARGSUSED */
CC_dfdnam(s) char *s; {}
/* ARGSUSED */
CC_dfilb(l) label l; {}
/* ARGSUSED */
CC_end(l) arith l; {}
CC_msend() {}
/* ARGSUSED */
CC_msstart(ms) {}
/* ARGSUSED */
CC_opcst(op_xxx,c) arith c; {}
/* ARGSUSED */
CC_opdlb(op_xxx,g,o) label g; arith o; {}
/* ARGSUSED */
CC_opilb(op_xxx,b) label b; {}
/* ARGSUSED */
CC_oppnam(op_xxx,p) char *p; {}
/* ARGSUSED */
CC_pronarg(s) char *s; {}
/* ARGSUSED */
CC_psdlb(ps_xxx,l) label l; {}
/* ARGSUSED */
CC_psdnam(ps_xxx,s) char *s; {}
/* ARGSUSED */
CC_pspnam(ps_xxx,s) char *s; {}
/* ARGSUSED */
CC_scon(v,s) char *s; {}
#endif LINT

View file

@ -1,52 +0,0 @@
/* $Header$ */
/* PREPROCESSOR: DEFINITION OF MACRO DESCRIPTOR */
#include "nopp.h"
#ifndef NOPP
/* The flags of the mc_flag field of the macro structure. Note that
these flags can be set simultaneously.
*/
#define NOFLAG 0 /* no special flags */
#define FUNC 01 /* function attached */
#define PREDEF 02 /* predefined macro */
#define FORMALP 0200 /* mask for creating macro formal parameter */
/* The macro descriptor is very simple, except the fact that the
mc_text, which points to the replacement text, contains the
non-ascii characters \201, \202, etc, indicating the position of a
formal parameter in this text.
*/
struct macro {
struct macro *next;
char * mc_text; /* the replacement text */
int mc_nps; /* number of formal parameters */
int mc_length; /* length of replacement text */
char mc_flag; /* marking this macro */
};
/* allocation definitions of struct macro */
/* ALLOCDEF "macro" */
extern char *st_alloc();
extern struct macro *h_macro;
#define new_macro() ((struct macro *) \
st_alloc((char **)&h_macro, sizeof(struct macro)))
#define free_macro(p) st_free(p, h_macro, sizeof(struct macro))
/* `token' numbers of keywords of command-line processor
*/
#define K_UNKNOWN 0
#define K_DEFINE 1
#define K_ELIF 2
#define K_ELSE 3
#define K_ENDIF 4
#define K_IF 5
#define K_IFDEF 6
#define K_IFNDEF 7
#define K_INCLUDE 8
#define K_LINE 9
#define K_UNDEF 10
#endif NOPP

View file

@ -1,19 +0,0 @@
ed - $1 <<'--EOI--'
g/^%/d
g/^ /.-1,.j
1,$s/^\([^|]*\)|\([^|]*\)|\(.*\)$/\
\1 \2 {\
\3;\
}/
1i
/* EM COMPACT CODE -- PROCEDURAL INTERFACE (generated from emcode.def) */
#include "em.h"
#ifdef PROC_INTF
#include "label.h"
#include "arith.h"
.
$a
#endif PROC_INTF
.
1,$p
--EOI--

View file

@ -1,10 +0,0 @@
ed - $1 <<'--EOI--'
g/^%/d
g/^ /.-1,.j
1,$s/^\([^|]*\)|[^|]*|\(.*\)$/\
#define \1 (\2)/
1i
/* EM COMPACT CODE -- MACRO DEFINITIONS (generated from emcode.def) */
.
1,$p
--EOI--

View file

@ -1,9 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* Accepted if many characters of long names are significant */
/* $Header$ */
abcdefghijklmnopr() { }
abcdefghijklmnopq() { }
main() { }

View file

@ -1,46 +0,0 @@
/* $Header$ */
/* IDENTIFIER STACK DEFINITIONS */
/* The identifier stack is implemented as a stack of sets.
The stack is implemented by a doubly linked list,
the sets by singly linked lists.
*/
struct stack_level {
struct stack_level *next;
struct stack_level *sl_next; /* upward link */
struct stack_level *sl_previous; /* downward link */
struct stack_entry *sl_entry; /* sideward link */
arith sl_local_offset; /* @ for first coming object */
arith sl_max_block; /* maximum size of sub-block */
int sl_level;
};
/* allocation definitions of struct stack_level */
/* ALLOCDEF "stack_level" */
extern char *st_alloc();
extern struct stack_level *h_stack_level;
#define new_stack_level() ((struct stack_level *) \
st_alloc((char **)&h_stack_level, sizeof(struct stack_level)))
#define free_stack_level(p) st_free(p, h_stack_level, sizeof(struct stack_level))
struct stack_entry {
struct stack_entry *next;
struct idf *se_idf;
};
/* allocation definitions of struct stack_entry */
/* ALLOCDEF "stack_entry" */
extern char *st_alloc();
extern struct stack_entry *h_stack_entry;
#define new_stack_entry() ((struct stack_entry *) \
st_alloc((char **)&h_stack_entry, sizeof(struct stack_entry)))
#define free_stack_entry(p) st_free(p, h_stack_entry, sizeof(struct stack_entry))
extern struct stack_level *local_level;
extern struct stack_level *stack_level_of();
extern int level;

View file

@ -1,67 +0,0 @@
/* $Header$ */
/* S T R U C T U R E - S T O R A G E M A N A G E M E N T */
/* Assume that each structure contains a field "next", of pointer
type, as first tagfield.
struct xxx serves as a general structure: it just declares the
tagfield "next" as first field of a structure.
Please don't worry about any warnings when compiling this file
because some dirty tricks are performed to obtain the necessary
actions.
*/
#include "debug.h" /* UF */
#include "botch_free.h" /* UF */
#include "assert.h"
#include "alloc.h"
#include "storage.h"
struct xxx {
char *next;
};
char *
head_alloc(phead, size)
char **phead;
int size;
{
struct xxx *tmp;
if (*phead == 0) {
return Malloc(size);
}
tmp = (struct xxx *) (*phead);
*phead = (char *) tmp->next;
return (char *) tmp;
}
/* instead of Calloc: */
clear(ptr, n)
char *ptr;
int n;
{
ASSERT((long)ptr % sizeof (long) == 0);
while (n >= sizeof (long)) { /* high-speed clear loop */
*(long *)ptr = 0L;
ptr += sizeof (long), n -= sizeof (long);
}
while (n--)
*ptr++ = '\0';
}
#ifdef BOTCH_FREE
botch(ptr, n)
char *ptr;
int n;
{ /* Writes garbage over n chars starting from ptr.
Used to check if freed memory is used inappropriately.
*/
ASSERT((long)ptr % sizeof (long) == 0);
while (n >= sizeof (long)) { /* high-speed botch loop */
*(long *)ptr = 025252525252L;
ptr += sizeof (long), n -= sizeof (long);
}
while (n--)
*ptr++ = '\252';
}
#endif BOTCH_FREE

View file

@ -1,23 +0,0 @@
/* $Header$ */
/* S T R U C T U R E - S T O R A G E D E F I N I T I O N S */
/* Storage allocation is one of the most expensive operations in
the compiler and consequently much thought and experimentation
has gone into it. To simplify the hooking in of new super-fancy
algorithms, all allocating and freeing of storage for structs
goes through the macros
st_alloc(&head, size)
st_free(ptr, head, size)
which, hopefully, convey enough information.
*/
extern char *head_alloc();
#define st_alloc(headp, size) head_alloc((char **)headp, size)
#ifndef BOTCH_FREE
#define st_free(ptr, head, size) (ptr->next = head, head = ptr)
#else def BOTCH_FREE
#define st_free(ptr, head, size) (botch((char *)(ptr), size), \
ptr->next = head, head = ptr)
#endif BOTCH_FREE

View file

@ -1,277 +0,0 @@
/* $Header$ */
/* STRING MANIPULATION AND PRINT ROUTINES */
#include <system.h>
#include "string.h"
#include "nopp.h"
#include "str_params.h"
#include "arith.h"
doprnt(fp, fmt, argp)
File *fp;
char *fmt;
int argp[];
{
char buf[SSIZE];
sys_write(fp, buf, format(buf, fmt, (char *)argp));
}
/*VARARGS1*/
printf(fmt, args)
char *fmt;
char args;
{
char buf[SSIZE];
sys_write(STDOUT, buf, format(buf, fmt, &args));
}
/*VARARGS1*/
fprintf(fp, fmt, args)
File *fp;
char *fmt;
char args;
{
char buf[SSIZE];
sys_write(fp, buf, format(buf, fmt, &args));
}
/*VARARGS1*/
char *
sprintf(buf, fmt, args)
char *buf, *fmt;
char args;
{
buf[format(buf, fmt, &args)] = '\0';
return buf;
}
int
format(buf, fmt, argp)
char *buf, *fmt;
char *argp;
{
register char *pf = fmt, *pa = argp;
register char *pb = buf;
while (*pf) {
if (*pf == '%') {
register width, base, pad, npad;
char *arg;
char cbuf[2];
char *badformat = "<bad format>";
/* get padder */
if (*++pf == '0') {
pad = '0';
++pf;
}
else
pad = ' ';
/* get width */
width = 0;
while (*pf >= '0' && *pf <= '9')
width = 10 * width + *pf++ - '0';
/* get text and move pa */
if (*pf == 's') {
arg = *(char **)pa;
pa += sizeof(char *);
}
else
if (*pf == 'c') {
cbuf[0] = * (char *) pa;
cbuf[1] = '\0';
pa += sizeof(int);
arg = &cbuf[0];
}
else
if (*pf == 'l') {
/* alignment ??? */
if (base = integral(*++pf)) {
arg = int_str(*(long *)pa, base);
pa += sizeof(long);
}
else {
pf--;
arg = badformat;
}
}
else
if (base = integral(*pf)) {
arg = int_str((long)*(int *)pa, base);
pa += sizeof(int);
}
else
if (*pf == '%')
arg = "%";
else
arg = badformat;
npad = width - strlen(arg);
while (npad-- > 0)
*pb++ = pad;
while (*pb++ = *arg++);
pb--;
pf++;
}
else
*pb++ = *pf++;
}
return pb - buf;
}
integral(c)
{
switch (c) {
case 'b':
return -2;
case 'd':
return 10;
case 'o':
return -8;
case 'u':
return -10;
case 'x':
return -16;
}
return 0;
}
/* Integer to String translator
*/
char *
int_str(val, base)
register long val;
register base;
{
/* int_str() is a very simple integer to string converter.
base < 0 : unsigned.
base must be an element of [-16,-2] V [2,16].
*/
static char numbuf[MAXWIDTH];
static char vec[] = "0123456789ABCDEF";
register char *p = &numbuf[MAXWIDTH];
int sign = (base > 0);
*--p = '\0'; /* null-terminate string */
if (val) {
if (base > 0) {
if (val < (arith)0) {
if ((val = -val) < (arith)0)
goto overflow;
}
else
sign = 0;
}
else
if (base < 0) { /* unsigned */
base = -base;
if (val < (arith)0) {
register mod, i;
overflow:
/* this takes a rainy Sunday afternoon to explain */
/* ??? */
mod = 0;
for (i = 0; i < 8 * sizeof val; i++) {
mod <<= 1;
if (val < 0)
mod++;
val <<= 1;
if (mod >= base) {
mod -= base;
val++;
}
}
*--p = vec[mod];
}
}
do {
*--p = vec[(int) (val % base)];
val /= base;
} while (val != (arith)0);
if (sign)
*--p = '-'; /* don't forget it !! */
}
else
*--p = '0'; /* just a simple 0 */
return p;
}
/* return negative, zero or positive value if
resp. s < t, s == t or s > t
*/
int
strcmp(s, t)
register char *s, *t;
{
while (*s == *t++)
if (*s++ == '\0')
return 0;
return *s - *--t;
}
/* return length of s
*/
int
strlen(s)
char *s;
{
register char *b = s;
while (*b++)
;
return b - s - 1;
}
#ifndef NOPP
/* append t to s
*/
char *
strcat(s, t)
register char *s, *t;
{
register char *b = s;
while (*s++)
;
s--;
while (*s++ = *t++)
;
return b;
}
/* Copy t into s
*/
char *
strcpy(s, t)
register char *s, *t;
{
register char *b = s;
while (*s++ = *t++)
;
return b;
}
char *
rindex(str, chr)
register char *str, chr;
{
register char *retptr = 0;
while (*str)
if (*str++ == chr)
retptr = &str[-1];
return retptr;
}
#endif NOPP

View file

@ -1,13 +0,0 @@
/* $Header$ */
/* STRING-ROUTINE DEFINITIONS */
#define stdin 0
#define stdout 1
#define stderr 2
#define itos(n) int_str((long)(n), 10)
char *sprintf(); /* string.h */
char *int_str(); /* string.h */
char *strcpy(), *strcat(), *rindex();

View file

@ -1,44 +0,0 @@
/* $Header$ */
/* SELECTOR DESCRIPTOR */
struct sdef { /* for selectors */
struct sdef *next;
int sd_level;
struct idf *sd_idf; /* its name */
struct sdef *sd_sdef; /* the next selector */
struct type *sd_stype; /* the struct it belongs to */
struct type *sd_type; /* its type */
arith sd_offset;
};
extern char *st_alloc();
/* allocation definitions of struct sdef */
/* ALLOCDEF "sdef" */
extern char *st_alloc();
extern struct sdef *h_sdef;
#define new_sdef() ((struct sdef *) \
st_alloc((char **)&h_sdef, sizeof(struct sdef)))
#define free_sdef(p) st_free(p, h_sdef, sizeof(struct sdef))
struct tag { /* for struct-, union- and enum tags */
struct tag *next;
int tg_level;
int tg_busy; /* non-zero during declaration of struct/union pack */
struct type *tg_type;
};
/* allocation definitions of struct tag */
/* ALLOCDEF "tag" */
extern char *st_alloc();
extern struct tag *h_tag;
#define new_tag() ((struct tag *) \
st_alloc((char **)&h_tag, sizeof(struct tag)))
#define free_tag(p) st_free(p, h_tag, sizeof(struct tag))
struct sdef *idf2sdef();

View file

@ -1,40 +0,0 @@
/* $Header$ */
/* S W I T C H - T A B L E - S T R U C T U R E */
struct switch_hdr {
struct switch_hdr *next;
label sh_break;
label sh_default;
label sh_table;
int sh_nrofentries;
struct type *sh_type;
arith sh_lowerbd;
arith sh_upperbd;
struct case_entry *sh_entries;
};
/* allocation definitions of struct switch_hdr */
/* ALLOCDEF "switch_hdr" */
extern char *st_alloc();
extern struct switch_hdr *h_switch_hdr;
#define new_switch_hdr() ((struct switch_hdr *) \
st_alloc((char **)&h_switch_hdr, sizeof(struct switch_hdr)))
#define free_switch_hdr(p) st_free(p, h_switch_hdr, sizeof(struct switch_hdr))
struct case_entry {
struct case_entry *next;
label ce_label;
arith ce_value;
};
/* allocation definitions of struct case_entry */
/* ALLOCDEF "case_entry" */
extern char *st_alloc();
extern struct case_entry *h_case_entry;
#define new_case_entry() ((struct case_entry *) \
st_alloc((char **)&h_case_entry, sizeof(struct case_entry)))
#define free_case_entry(p) st_free(p, h_case_entry, sizeof(struct case_entry))

View file

@ -1,72 +0,0 @@
/* $Header$ */
/* SYSTEM DEPENDENT ROUTINES */
#include "system.h"
#include "inputtype.h"
#include <sys/stat.h>
extern long lseek();
int
xopen(name, flag, mode)
char *name;
{
if (name[0] == '-' && name[1] == '\0')
return (flag == OP_RDONLY) ? 0 : 1;
switch (flag) {
case OP_RDONLY:
return open(name, 0);
case OP_WRONLY:
return open(name, 1);
case OP_CREAT:
return creat(name, mode);
case OP_APPEND:
{
register fd;
if ((fd = open(name, 1)) < 0)
return -1;
lseek(fd, 0L, 2);
return fd;
}
}
/*NOTREACHED*/
}
int
xclose(fildes)
{
if (fildes != 0 && fildes != 1)
return close(fildes);
return -1;
}
#ifdef READ_IN_ONE
long
xfsize(fildes)
{
struct stat stbuf;
if (fstat(fildes, &stbuf) != 0)
return -1;
return stbuf.st_size;
}
#endif READ_IN_ONE
exit(n)
{
_exit(n);
}
xstop(how, stat)
{
switch (how) {
case S_ABORT:
abort();
case S_EXIT:
exit(stat);
}
/*NOTREACHED*/
}

View file

@ -1,34 +0,0 @@
/* $Header$ */
/* SYSTEM DEPENDANT DEFINITIONS */
#include <sys/types.h>
#include <errno.h>
#define OP_RDONLY 0 /* open for read */
#define OP_WRONLY 1 /* open for write */
#define OP_CREAT 2 /* create and open for write */
#define OP_APPEND 3 /* open for write at end */
#define sys_open(name, flag) xopen(name, flag, 0)
#define sys_close(fildes) xclose(fildes)
#define sys_read(fildes, buffer, nbytes) read(fildes, buffer, nbytes)
#define sys_write(fildes, buffer, nbytes) write(fildes, buffer, nbytes)
#define sys_creat(name, mode) xopen(name, OP_CREAT, mode)
#define sys_remove(name) unlink(name)
#define sys_fsize(fd) xfsize(fd)
#define sys_sbrk(incr) sbrk(incr)
#define sys_stop(how, stat) xstop(how, stat)
#define S_ABORT 1
#define S_EXIT 2
char *sbrk();
long xfsize();
extern int errno;
#define sys_errno errno
#define time_type time_t
#define sys_time(tloc) time(tloc)
time_type time();

View file

@ -1,300 +0,0 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* @cc tab.c -o $INSTALLDIR/tab@
tab - table generator
Author: Erik Baalbergen (..tjalk!erikb)
*/
#include <stdio.h>
#define MAXTAB 10000
#define MAXBUF 10000
#define COMCOM '-'
#define FILECOM '%'
int InputForm = 'c';
char OutputForm[MAXBUF] = "%s,\n";
int TabSize = 257;
char *Table[MAXTAB];
char *ProgCall;
main(argc, argv)
char *argv[];
{
ProgCall = *argv++;
argc--;
while (argc-- > 0) {
if (**argv == COMCOM) {
option(*argv++);
}
else {
process(*argv++, InputForm);
}
}
exit(0);
}
char *
Salloc(s)
char *s;
{
extern char *malloc(), *strcpy();
char *ns = malloc((unsigned int)strlen(s) + 1);
if (ns) {
strcpy(ns, s);
}
return ns;
}
option(str)
char *str;
{
/* note that *str indicates the source of the option:
either COMCOM (from command line) or FILECOM (from a file).
*/
extern char *sprintf();
switch (*++str) {
case ' ': /* command */
case '\t':
case '\0':
break;
case 'I':
InputForm = *++str;
break;
case 'f':
if (*++str == '\0') {
fprintf(stderr, "%s: -f: name expected\n", ProgCall);
exit(1);
}
DoFile(str);
break;
case 'F':
sprintf(OutputForm, "%s\n", ++str);
break;
case 'T':
printf("%s\n", ++str);
break;
case 'p':
PrintTable();
break;
case 'C':
ClearTable();
break;
case 'S':
{
register i = stoi(++str);
if (i <= 0 || i > MAXTAB) {
fprintf(stderr, "%s: size would exceed maximum\n",
ProgCall);
}
else {
TabSize = i;
}
break;
}
default:
fprintf(stderr, "%s: bad option -%s\n", ProgCall, str);
}
}
ClearTable()
{
register i;
for (i = 0; i < MAXTAB; i++) {
Table[i] = 0;
}
}
PrintTable()
{
register i;
for (i = 0; i < TabSize; i++) {
if (Table[i]) {
printf(OutputForm, Table[i]);
}
else {
printf(OutputForm, "0");
}
}
}
process(str, format)
char *str;
{
char *cstr = str;
char *Name = cstr; /* overwrite original string! */
/* strip of the entry name
*/
while (*str && *str != ':') {
if (*str == '\\') {
++str;
}
*cstr++ = *str++;
}
if (*str != ':') {
fprintf(stderr, "%s: bad specification: \"%s\", ignored\n",
ProgCall, Name);
return 0;
}
*cstr = '\0';
str++;
switch (format) {
case 'c':
return c_proc(str, Name);
default:
fprintf(stderr, "%s: bad input format\n", ProgCall);
}
return 0;
}
c_proc(str, Name)
char *str;
char *Name;
{
int ch, ch2;
int quoted();
while (*str) {
if (*str == '\\') {
ch = quoted(&str);
}
else {
ch = *str++;
}
if (*str == '-') {
if (*++str == '\\') {
ch2 = quoted(&str);
}
else {
if (ch2 = *str++);
else str--;
}
if (ch > ch2) {
fprintf(stderr, "%s: bad range\n", ProgCall);
return 0;
}
if (ch >= 0 && ch2 <= 255)
while (ch <= ch2)
Table[ch++] = Salloc(Name);
}
else {
if (ch >= 0 && ch <= 255)
Table[ch] = Salloc(Name);
}
}
return 1;
}
int
quoted(pstr)
char **pstr;
{
register int ch;
register int i;
register char *str = *pstr;
if ((*++str >= '0') && (*str <= '9')) {
ch = 0;
for (i = 0; i < 3; i++) {
ch = 8 * ch + *str - '0';
if (*++str < '0' || *str > '9')
break;
}
}
else {
switch (*str++) {
case 'n':
ch = '\n';
break;
case 't':
ch = '\t';
break;
case 'b':
ch = '\b';
break;
case 'r':
ch = '\r';
break;
case 'f':
ch = '\f';
break;
default :
ch = *str;
}
}
*pstr = str;
return ch & 0377;
}
int
stoi(str)
char *str;
{
register i = 0;
while (*str >= '0' && *str <= '9') {
i = i * 10 + *str++ - '0';
}
return i;
}
char *
getline(s, n, fp)
char *s;
FILE *fp;
{
register c = getc(fp);
char *str = s;
while (n--) {
if (c == EOF) {
return NULL;
}
else
if (c == '\n') {
*str++ = '\0';
return s;
}
*str++ = c;
c = getc(fp);
}
s[n - 1] = '\0';
return s;
}
#define BUFSIZE 1024
DoFile(name)
char *name;
{
char text[BUFSIZE];
FILE *fp;
if ((fp = fopen(name, "r")) == NULL) {
fprintf(stderr, "%s: cannot read file %s\n", ProgCall, name);
exit(1);
}
while (getline(text, BUFSIZE, fp) != NULL) {
if (text[0] == FILECOM) {
option(text);
}
else {
process(text, InputForm);
}
}
}

View file

@ -1,52 +0,0 @@
/* $Header$ */
/* TYPE DESCRIPTOR */
#include "nobitfield.h"
struct type {
struct type *next; /* used only with ARRAY */
short tp_fund; /* fundamental type */
char tp_unsigned;
int tp_align;
arith tp_size; /* -1 if declared but not defined */
struct idf *tp_idf; /* name of STRUCT, UNION or ENUM */
struct sdef *tp_sdef; /* to first selector */
struct type *tp_up; /* from FIELD, POINTER, ARRAY
or FUNCTION to fund. */
struct field *tp_field; /* field descriptor if fund == FIELD */
struct type *tp_pointer;/* to POINTER */
struct type *tp_array; /* to ARRAY */
struct type *tp_function;/* to FUNCTION */
};
extern struct type
*create_type(), *standard_type(), *construct_type(), *pointer_to(),
*array_of(), *function_of();
#ifndef NOBITFIELD
extern struct type *field_of();
#endif NOBITFIELD
extern struct type
*char_type, *uchar_type,
*short_type, *ushort_type,
*word_type, *uword_type,
*int_type, *uint_type,
*long_type, *ulong_type,
*float_type, *double_type,
*void_type, *label_type,
*string_type, *funint_type, *error_type;
extern struct type *pa_type; /* type.c */
extern arith size_of_type(), align();
/* allocation definitions of struct type */
/* ALLOCDEF "type" */
extern char *st_alloc();
extern struct type *h_type;
#define new_type() ((struct type *) \
st_alloc((char **)&h_type, sizeof(struct type)))
#define free_type(p) st_free(p, h_type, sizeof(struct type))

View file

@ -1,266 +0,0 @@
# MAKEFILE FOR (STAND_ALONE) CEM PREPROCESSOR
EMHOME=../../..
MODULES=$(EMHOME)/modules
MODULESLIB=$(MODULES)/lib
BIN=$(EMHOME)/lib
MANDIR=$(EMHOME)/man
# Some paths
# Libraries
SYSLIB = $(MODULESLIB)/libsystem.a
STRLIB = $(MODULESLIB)/libstring.a
PRTLIB = $(MODULESLIB)/libprint.a
ALLOCLIB = $(MODULESLIB)/liballoc.a
ASSERTLIB = $(MODULESLIB)/libassert.a
MALLOC = $(MODULESLIB)/malloc.o
LIBS = $(PRTLIB) $(STRLIB) $(ALLOCLIB) $(MALLOC) $(ASSERTLIB) $(SYSLIB)
LIB_INCLUDES = -I$(MODULES)/h -I$(MODULES)/pkg
# Where to install the preprocessor
CEMPP = $(BIN)/cpp.ansi
TABGEN = $(EMHOME)/bin/tabgen
# What C compiler to use and how
CC = cc
COPTIONS = -O
LDFLAGS =
# What parser generator to use and how
GEN = $(EMHOME)/bin/LLgen
GENOPTIONS =
# Special #defines during compilation
CDEFS = $(LIB_INCLUDES)
CFLAGS = $(CDEFS) $(COPTIONS)# # we cannot pass the COPTIONS to lint!
# Grammar files and their objects
LSRC = tokenfile.g expression.g
LCSRC = tokenfile.c expression.c Lpars.c
LOBJ = tokenfile.o expression.o Lpars.o
# Objects of hand-written C files
CSRC = LLlex.c LLmessage.c ch3bin.c ch3mon.c domacro.c \
error.c idf.c init.c input.c main.c options.c \
preprocess.c replace.c skip.c tokenname.c expr.c
COBJ = LLlex.o LLmessage.o ch3bin.o ch3mon.o domacro.o \
error.o idf.o init.o input.o main.o options.o \
preprocess.o replace.o skip.o tokenname.o next.o expr.o
PRFILES = Makefile Parameters \
make.hfiles make.tokcase make.tokfile LLlex.h bits.h file_info.h \
idf.h input.h interface.h macro.str replace.str \
class.h char.tab expression.g $(CSRC)
# Objects of other generated C files
GOBJ = char.o symbol2str.o
# generated source files
GSRC = char.c symbol2str.c next.c
# .h files generated by `make.allod'
STRSRC = macro.str replace.str
GSTRSRC = macro.h replace.h
# .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE!
GHSRC = errout.h idfsize.h ifdepth.h macbuf.h \
nparams.h numsize.h obufsize.h \
parbufsize.h pathlength.h strsize.h textsize.h \
botch_free.h debug.h inputtype.h dobits.h ln_prefix.h
# Other generated files, for 'make clean' only
GENERATED = tokenfile.g Lpars.h LLfiles LL.output lint.out \
Xref hfiles cfiles tags Makefile.old
all: cc
cc: cfiles
make "EMHOME="$(EMHOME) "CC=$(CC)" ncpp
hfiles: Parameters char.c
./make.hfiles Parameters
@touch hfiles
.SUFFIXES: .str .h
.str.h:
./make.allocd <$*.str >$*.h
char.c: char.tab
$(TABGEN) -fchar.tab > char.c
next.c: make.next $(STRSRC)
./make.next $(STRSRC) >next.c
macro.h: make.allocd
replace.h: make.allocd
LLfiles: $(LSRC)
$(GEN) $(GENOPTIONS) $(LSRC)
@touch LLfiles
tokenfile.g: tokenname.c make.tokfile
<tokenname.c ./make.tokfile >tokenfile.g
symbol2str.c: tokenname.c make.tokcase
<tokenname.c ./make.tokcase >symbol2str.c
# Objects needed for 'ncpp'
OBJ = $(COBJ) $(LOBJ) $(GOBJ)
SRC = $(CSRC) $(LCSRC) $(GSRC)
ncpp: $(OBJ) Makefile
$(CC) $(COPTIONS) $(LDFLAGS) $(OBJ) $(LIBS) -o ncpp
-size ncpp
cfiles: hfiles LLfiles $(GSRC) $(GSTRSRC)
@touch cfiles
install: all
rm -f $(CEMPP)
cp ncpp $(CEMPP)
rm -f $(MANDIR)/cpp.ansi.6
cp ncpp.6 $(MANDIR)/cpp.ansi.6
cmp: all
-cmp ncpp $(CEMPP)
-cmp ncpp.6 $(MANDIR)/cpp.ansi.6
pr:
@pr $(PRFILES)
opr:
make pr | opr
tags: cfiles
ctags $(SRC)
depend: cfiles
sed '/^#AUTOAUTO/,$$d' Makefile >Makefile.new
echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >>Makefile.new
$(EMHOME)/bin/mkdep $(SRC) | \
sed 's/\.c:/.o:/' >>Makefile.new
mv Makefile Makefile.old
mv Makefile.new Makefile
xref:
ctags -x `grep "\.[ch]" Files`|sed "s/).*/)/">Xref
lint: cfiles
lint -bx $(CDEFS) $(SRC) >lint.out
clean:
rm -f $(LCSRC) $(OBJ) $(GENERATED) $(GSRC) $(GHSRC) $(GSTRSRC) ncpp Out
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
LLlex.o: LLlex.h
LLlex.o: Lpars.h
LLlex.o: arith.h
LLlex.o: bits.h
LLlex.o: class.h
LLlex.o: dobits.h
LLlex.o: file_info.h
LLlex.o: idf.h
LLlex.o: idfsize.h
LLlex.o: input.h
LLlex.o: inputtype.h
LLlex.o: macro.h
LLlex.o: numsize.h
LLlex.o: strsize.h
LLmessage.o: LLlex.h
LLmessage.o: Lpars.h
LLmessage.o: arith.h
LLmessage.o: file_info.h
ch3bin.o: Lpars.h
ch3bin.o: arith.h
ch3mon.o: Lpars.h
ch3mon.o: arith.h
domacro.o: LLlex.h
domacro.o: Lpars.h
domacro.o: arith.h
domacro.o: bits.h
domacro.o: botch_free.h
domacro.o: class.h
domacro.o: dobits.h
domacro.o: file_info.h
domacro.o: idf.h
domacro.o: idfsize.h
domacro.o: ifdepth.h
domacro.o: input.h
domacro.o: inputtype.h
domacro.o: macbuf.h
domacro.o: macro.h
domacro.o: nparams.h
domacro.o: parbufsize.h
domacro.o: replace.h
domacro.o: textsize.h
error.o: LLlex.h
error.o: arith.h
error.o: errout.h
error.o: file_info.h
idf.o: idf.h
init.o: class.h
init.o: idf.h
init.o: macro.h
input.o: file_info.h
input.o: input.h
input.o: inputtype.h
main.o: arith.h
main.o: file_info.h
main.o: idf.h
main.o: idfsize.h
main.o: macro.h
options.o: class.h
options.o: idf.h
options.o: idfsize.h
options.o: macro.h
preprocess.o: LLlex.h
preprocess.o: arith.h
preprocess.o: bits.h
preprocess.o: class.h
preprocess.o: dobits.h
preprocess.o: file_info.h
preprocess.o: idf.h
preprocess.o: idfsize.h
preprocess.o: input.h
preprocess.o: inputtype.h
preprocess.o: ln_prefix.h
preprocess.o: macro.h
preprocess.o: obufsize.h
preprocess.o: textsize.h
replace.o: LLlex.h
replace.o: arith.h
replace.o: class.h
replace.o: file_info.h
replace.o: idf.h
replace.o: idfsize.h
replace.o: input.h
replace.o: inputtype.h
replace.o: macbuf.h
replace.o: macro.h
replace.o: nparams.h
replace.o: numsize.h
replace.o: pathlength.h
replace.o: replace.h
replace.o: strsize.h
skip.o: LLlex.h
skip.o: arith.h
skip.o: class.h
skip.o: file_info.h
skip.o: input.h
skip.o: inputtype.h
tokenname.o: LLlex.h
tokenname.o: Lpars.h
tokenname.o: arith.h
tokenname.o: file_info.h
tokenname.o: idf.h
expr.o: Lpars.h
tokenfile.o: Lpars.h
expression.o: LLlex.h
expression.o: Lpars.h
expression.o: arith.h
expression.o: file_info.h
Lpars.o: Lpars.h
char.o: class.h
symbol2str.o: Lpars.h

View file

@ -1,74 +0,0 @@
.TH NCPP 6ACK
.ad
.SH NAME
ncpp \- New C Pre-Processor
.SH SYNOPSIS
ncpp [\-options] [ file ]
.SH DESCRIPTION
.I Ncpp
reads a file, expands macros and include
files, and writes an input file for the C compiler.
All output is to standard output.
.br
The following options are supported.
.IP -\fBI\fIdirectory\fR
.br
add this directory to the list of
directories searched for #include "..." and #include <...>
commands. Note that there is no space between the
"-I" and the directory string. More than one -I command
is permitted.
.IP -\fBI\fR
end the list of directories to be searched, and also do not look in
default places.
.IP -\fBD\fIname\fR=\fItext\fR
.br
define
.I name
as a macro with
.I text
as its replacement text.
.IP -\fBD\fIname\fR
the same as -\fBD\fIname\fR=1.
.IP
.IP -\fBU\fIname\fR
.br
undefine the macro name
.IR name .
.IP -\fBC\fR
leave comments in. By default, C-comments are deleted.
.IP -\fBP\fR
do not generate line directives
.IP -\fBM\fIn\fR
set maximum identifier length to
.IR n .
.PP
The following names are always available unless undefined:
.RS
.IP __STDC__
A decimal constant 1, indicating that this is an ANSI C conforming
implementation.
.IP __FILE__
The input (or #include) file being compiled
(as a quoted string).
.IP __LINE__
The line number being compiled.
.IP __DATE__
The date of translation of the source file. This is a string
literal of the form "\fBMmm dd yyyy\fP".
.IP __TIME__
The time of translation of the source file. This is a string
literal of the form "\fBhh:mm:ss\fP".
.RE
.SH BUGS
The output may contain extra spaces, this prevents unintended
pasting of tokens.
.SH "SEE ALSO"
L. Rosler,
.I
Draft Proposed Standard - Programming Language C,
.R
ANSI X3J11 Language Subcommittee
.SH AUTHOR
Leendert van Doorn

View file

@ -1,152 +0,0 @@
w1
st2.w1_i 506
(*st3).w1_i 506
st1.w1_i 711
st2.w1_i 711
es2[2].w1_i 711
st2.w1_i 577
st2.w1_i -577
st1.w1_i 577
w2
s2t2: .w2_i 18000 .w2_d 3.141500
s2t3->w2_d 3.141500
w3
s3t2.w3_a[ 0] a
s3t2.w3_a[ 1] b
s3t2.w3_a[ 2] c
s3t2.w3_a[ 3] d
s3t2.w3_a[ 4] e
s3t2.w3_a[ 5] f
s3t2.w3_a[ 6] g
s3t2.w3_a[ 7] h
s3t2.w3_a[ 8] i
s3t2.w3_a[ 9] j
s3t2.w3_a[10] k
s3t2.w3_a[11] l
s3t2.w3_a[12] m
s3t2.w3_a[13] n
s3t2.w3_a[14] o
s3t2.w3_a[15] p
s3t2.w3_a[16] q
s3t2.w3_a[17] r
s3t2.w3_a[18] s
s3t2.w3_a[19] t
s3t2.w3_a[20] u
s3t2.w3_a[21] v
s3t2.w3_a[22] w
s3t2.w3_a[23] x
s3t2.w3_a[24] y
s3t2.w3_a[25] z
s3t2.w3_x 1.000000
s3t1.w3_a[ 0] A
s3t1.w3_a[ 1] B
s3t1.w3_a[ 2] C
s3t1.w3_a[ 3] D
s3t1.w3_a[ 4] E
s3t1.w3_a[ 5] F
s3t1.w3_a[ 6] G
s3t1.w3_a[ 7] H
s3t1.w3_a[ 8] I
s3t1.w3_a[ 9] J
s3t1.w3_a[10] K
s3t1.w3_a[11] L
s3t1.w3_a[12] M
s3t1.w3_a[13] N
s3t1.w3_a[14] O
s3t1.w3_a[15] P
s3t1.w3_a[16] Q
s3t1.w3_a[17] R
s3t1.w3_a[18] S
s3t1.w3_a[19] T
s3t1.w3_a[20] U
s3t1.w3_a[21] V
s3t1.w3_a[22] W
s3t1.w3_a[23] X
s3t1.w3_a[24] Y
s3t1.w3_a[25] Z
s3t1.w3_x 0.318319
structure parameters
before -1
str.w3_a[ 0] 1
str.w3_a[ 1] 2
str.w3_a[ 2] 3
str.w3_a[ 3] 4
str.w3_a[ 4] 5
str.w3_a[ 5] 6
str.w3_a[ 6] 7
str.w3_a[ 7] 8
str.w3_a[ 8] 9
str.w3_a[ 9] 10
str.w3_a[10] 11
str.w3_a[11] 12
str.w3_a[12] 13
str.w3_a[13] 14
str.w3_a[14] 15
str.w3_a[15] 16
str.w3_a[16] 17
str.w3_a[17] 18
str.w3_a[18] 19
str.w3_a[19] 20
str.w3_a[20] 21
str.w3_a[21] 22
str.w3_a[22] 23
str.w3_a[23] 24
str.w3_a[24] 25
str.w3_a[25] 26
str.w3_x 2.810000
after 1000
Stucture valued functions
myp.w3_a:
0 97
1 96
2 95
3 94
4 93
5 92
6 91
7 90
8 89
9 88
10 87
11 86
12 85
13 84
14 83
15 82
16 81
17 80
18 79
19 78
20 77
21 76
22 75
23 74
24 73
25 72
0 99
1 100
2 101
3 102
4 103
5 104
6 105
7 106
8 107
9 108
10 109
11 110
12 111
13 112
14 113
15 114
16 115
17 116
18 117
19 118
20 119
21 120
22 121
23 122
24 123
25 124

View file

@ -1,53 +0,0 @@
.SILENT:
CEM=acc
head:
echo use run
diffs: $P.cc.r $P.cem.r
echo two compiler diff
-diff $P.*.r
diffs3: $P.pcc.r $P.cc.r $P.cem.r
echo three compiler diff
-diff3 $P.*.r | tee diffs
egen: $P.e
echo comparing $P.e
-if test -f $P.e.g ; then diff -h $P.e $P.e.g ; else echo creating $P.e.g ; cp $P.e $P.e.g ; fi
rm -f $P.e
$P.e: $P.c
$(CEM) -c.e $P.c
$P.pcc.r: $P.pcc
echo running $P.pcc
-$P.pcc >$P.pcc.r
rm -f $P.pcc
$P.cc.r: $P.cc
echo running $P.cc
-$P.cc >$P.cc.r
rm -f $P.cc
$P.cem.r: $P.cem
echo running $P.cem
-$P.cem >$P.cem.r
rm -f $P.cem
$P.pcc: /tmp
echo pcc $P.c
pcc -o $P.pcc $P.c
$P.cc: /tmp
echo cc $P.c
cc -o $P.cc $P.c
$P.cem: /tmp
echo $(CEM) $P.c
$(CEM) -o $P.cem $P.c
gen: $P.cem.r
echo comparing $P
-if test -f $P.cem.g ; then diff -h $P.cem.r $P.cem.g ; else echo creating $P.cem.g ; cp $P.cem.r $P.cem.g ; fi
install cmp:
pr:
@pr `pwd`/$P.c `pwd`/$P.cem.g
opr:
make pr | opr
clean:
-rm -f $P.[kmsoe] $P.*.r core a.out *.old em_last em_runinf e.out

View file

@ -1,54 +0,0 @@
.SILENT:
CEM=i86 -DNOFLOAT
head:
echo use run
diffs: $P.cc.r $P.cem.r
echo two compiler diff
-diff $P.*.r
diffs3: $P.pcc.r $P.cc.r $P.cem.r
echo three compiler diff
-diff3 $P.*.r | tee diffs
egen: $P.e
echo comparing $P.e
-if test -f $P.e.g ; then diff -h $P.e $P.e.g ; else echo creating $P.e.g ; cp $P.e $P.e.g ; fi
rm -f $P.e
$P.e: $P.c $(CEM)
$(CEM) -c.e $P.c
$P.pcc.r: $P.pcc
echo running $P.pcc
-$P.pcc >$P.pcc.r
rm -f $P.pcc
$P.cc.r: $P.cc
echo running $P.cc
-$P.cc >$P.cc.r
rm -f $P.cc
$P.cem.r: $P.cem
echo running $P.cem
idl I7 $P.cem
-talk I7 >$P.cem.r
rm -f $P.cem
$P.pcc: $P.c /usr/lib/ccom
echo pcc $P.c
pcc -o $P.pcc $P.c
$P.cc: $P.c /lib/c0 /lib/c1
echo cc $P.c
cc -o $P.cc $P.c
$P.cem: $P.c
echo $(CEM) $P.c
$(CEM) -o $P.cem $P.c
gen: $P.cem.r
echo comparing $P
-if test -f $P.cem.g ; then diff -h $P.cem.r $P.cem.g ; else echo creating $P.cem.g ; cp $P.cem.r $P.cem.g ; fi
install cmp:
pr:
@pr `pwd`/$P.c `pwd`/$P.cem.g
opr:
make pr | opr
clean:
-rm -f $P.[kmsoe] $P.*.r core a.out *.old

View file

@ -1,53 +0,0 @@
.SILENT:
CEM=int -O
head:
echo use run
diffs: $P.cc.r $P.cem.r
echo two compiler diff
-diff $P.*.r
diffs3: $P.pcc.r $P.cc.r $P.cem.r
echo three compiler diff
-diff3 $P.*.r | tee diffs
egen: $P.e
echo comparing $P.e
-if test -f $P.e.g ; then diff -h $P.e $P.e.g ; else echo creating $P.e.g ; cp $P.e $P.e.g ; fi
rm -f $P.e
$P.e: $P.c $(CEM)
$(CEM) -c.e $P.c
$P.pcc.r: $P.pcc
echo running $P.pcc
-$P.pcc >$P.pcc.r
rm -f $P.pcc
$P.cc.r: $P.cc
echo running $P.cc
-$P.cc >$P.cc.r
rm -f $P.cc
$P.cem.r: $P.cem
echo running $P.cem
-/usr/evert/compile/a.out $P.cem >$P.cem.r
rm -f $P.cem
$P.pcc: $P.c /usr/lib/ccom
echo pcc $P.c
pcc -o $P.pcc $P.c
$P.cc: $P.c /lib/c0 /lib/c1
echo cc $P.c
cc -o $P.cc $P.c
$P.cem: $P.c
echo $(CEM) $P.c
$(CEM) -o $P.cem $P.c
gen: $P.cem.r
echo comparing $P
-if test -f $P.cem.g ; then diff -h $P.cem.r $P.cem.g ; else echo creating $P.cem.g ; cp $P.cem.r $P.cem.g ; fi
install cmp:
pr:
@pr `pwd`/$P.c `pwd`/$P.cem.g
opr:
make pr | opr
clean:
-rm -f $P.[kmsoe] $P.*.r core a.out *.old

View file

@ -1,174 +0,0 @@
Tue May 22 15:12:22 MDT 1984
***** ctconv
acc conv.c
conv.c
"conv.c", line 41: warning: Overflow in constant expression
running conv.cem
comparing conv
***** ctdecl
acc decl.c
decl.c
running decl.cem
comparing decl
***** ctdivers
acc ops.c
ops.c
running ops.cem
comparing ops
***** cterr
acc bugs.c
bugs.c
"bugs.c", line 92: warning: Overflow in constant expression
running bugs.cem
comparing bugs
9,$c9,$
< compl_ind
< END
---
> END
***** ctest1
acc test.c
test.c
running test.cem
comparing test
***** ctest2
acc t7.c
t7.c
"t7.c", line 161: warning: statement not reached
"t7.c", line 178: warning: statement not reached
"t7.c", line 182: warning: statement not reached
"t7.c", line 186: warning: statement not reached
"t7.c", line 190: warning: statement not reached
"t7.c", line 194: warning: statement not reached
"t7.c", line 198: warning: statement not reached
"t7.c", line 205: warning: statement not reached
"t7.c", line 207: warning: statement not reached
"t7.c", line 211: warning: statement not reached
"t7.c", line 213: warning: statement not reached
"t7.c", line 287: warning: statement not reached
"t7.c", line 294: warning: statement not reached
"t7.c", line 300: warning: statement not reached
"t7.c", line 307: warning: statement not reached
"t7.c", line 343: warning: statement not reached
"t7.c", line 344: warning: statement not reached
"t7.c", line 345: warning: statement not reached
"t7.c", line 346: warning: statement not reached
"t7.c", line 348: warning: statement not reached
"t7.c", line 452: warning: statement not reached
"t7.c", line 561: warning: statement not reached
"t7.c", line 589: warning: statement not reached
running t7.cem
comparing t7
***** ctest3
acc test2.c
test2.c
running test2.cem
comparing test2
***** ctest5
acc test1.c
test1.c
"test1.c", line 101: warning: Illegal shift count in constant expression
"test1.c", line 370: warning: illegal pointer combination
"test1.c", line 371: warning: illegal pointer combination
"test1.c", line 372: warning: illegal pointer combination
"test1.c", line 384: warning: illegal pointer combination
"test1.c", line 407: warning: illegal pointer combination
"test1.c", line 408: warning: illegal pointer combination
"test1.c", line 409: warning: illegal pointer combination
"test1.c", line 421: warning: illegal pointer combination
running test1.cem
comparing test1
***** ctgen
`bf.c' is up to date.
acc bf.c
bf.c
running bf.cem
comparing bf
`cel.c' is up to date.
acc cel.c
cel.c
running cel.cem
comparing cel
`clu.c' is up to date.
acc clu.c
clu.c
"clu.c", line 60: warning: Overflow in constant expression
"clu.c", line 66: warning: Overflow in constant expression
running clu.cem
comparing clu
28c28
< x *= 40000 0
---
> x *= 40000 6784
65c65
< y = ( x *= 40000 ) 0 0
---
> y = ( x *= 40000 ) 6784 6784
102c102
< no if ( x *= 40000 ) yes() ; else no() 0
---
> yes if ( x *= 40000 ) yes() ; else no() 6784
`ec.c' is up to date.
acc ec.c
ec.c
"ec.c", line 58: warning: Overflow in constant expression
"ec.c", line 64: warning: Overflow in constant expression
running ec.cem
comparing ec
`ef.c' is up to date.
acc ef.c
ef.c
running ef.cem
comparing ef
`ei.c' is up to date.
acc ei.c
ei.c
"ei.c", line 22: warning: Overflow in constant expression
"ei.c", line 65: warning: Overflow in constant expression
"ei.c", line 108: warning: Overflow in constant expression
running ei.cem
comparing ei
`el.c' is up to date.
acc el.c
el.c
running el.cem
comparing el
`eu.c' is up to date.
acc eu.c
eu.c
"eu.c", line 58: warning: Overflow in constant expression
"eu.c", line 64: warning: Overflow in constant expression
running eu.cem
comparing eu
28c28
< x *= 40000 0
---
> x *= 40000 6784
65c65
< y = ( x *= 40000 ) 0 0
---
> y = ( x *= 40000 ) 6784 6784
102c102
< no if ( x *= 40000 ) yes() ; else no() 0
---
> yes if ( x *= 40000 ) yes() ; else no() 6784
`id.c' is up to date.
acc id.c
id.c
running id.cem
comparing id
`lc.c' is up to date.
acc lc.c
lc.c
"lc.c", line 60: warning: Overflow in constant expression
"lc.c", line 66: warning: Overflow in constant expression
running lc.cem
comparing lc
`ld.c' is up to date.
acc ld.c
ld.c
running ld.cem
comparing ld
`lf.c' is up to date.
acc lf.c
lf.c

View file

@ -1,66 +0,0 @@
: $Header$
: This script makes an archive. The only option it knows is -o, which
: creates a library.
rm -f OLIST
case $# in
0)
AR=tar
OLIB=libsrc
echo 'cf libsrc' > OLIST
;;
1)
if [ "X$1" != "X-o" ]
then
echo $0: unrecognised option, I only know -o >&2
exit 1
fi
AR=$ASAR
echo "rv $OLIB" > OLIST
;;
*)
echo $0: too many arguments >&2
exit 1
;;
esac
if [ "X$AR" = "X" ]
then
echo EEK -- internal error, no archiver >&2
exit 1
fi
if [ $AR = tar ]
then
echo LIST >> OLIST
echo MakeArch >> OLIST
echo Makefile >> OLIST
echo make.proto >> OLIST
echo head_ac.e >> OLIST
fi
DIRS=`cat LIST`
for i in $DIRS
do
cd $i
if make "MACH=$MACH" "MACHFL=$MACHFL" "SUF=$SUF" $AR -f ../Makefile
then
cd ..
if [ $AR = tar ]
then
echo $i/Makefile >> OLIST
echo $i/LIST >> OLIST
fi
for j in `cat $i/OLIST`
do
echo $i/$j >> OLIST
done
else
exit 1
fi
done
$AR `cat OLIST`
${RANLIB-:} $OLIB

View file

@ -1,50 +0,0 @@
# $Header$
# This Makefile is used for building the source archive as well as the
# actual library.
EMHOME=../../..
MACH=acc
MACHFL=-O -L -Rcem=$(EMHOME)/lib/em_cemcom.ansi -I../headers $(DEFS)
PREF=ac
SUB=
ASAR=arch
HEADSRC=$(HOME)
OLIB=tail_$(PREF)$(SUB)
install:
MakeArch
-mkdir $(EMHOME)/include/tail_ac
( cd headers; tar cf - `cat LIST` ) | ( cd $(EMHOME)/include/tail_ac ; tar xf - )
clean:
rm -f OLIST */OLIST
(cd ctype; make clean)
(cd stdlib; make clean)
headcp: head
../../install head_$(PREF).$(SUF) head_$(PREF)
rm -f head_$(PREF).$(SUF)
head: head_$(PREF).e
make -r -f make.proto "CC=$(MACH)" "CFLAGS=-I$(EMHOME)/h $(MACHFL)" head_$(PREF).$(SUF)
tail: lib
tailcp: tail
../../install $(OLIB)
rm -f $(OLIB)
lib:
MACH=$(MACH) MACHFL="$(MACHFL) -LIB" ASAR=$(ASAR) SUF=$(SUF) \
OLIB=$(OLIB) MakeArch -o
ar aal arch:
@rm -f OLIST
@sed 's/\.[ce]/.$(SUF)/' < LIST | sed '/\.h/D' > OLIST
make -r -f ../make.proto "CC=$(MACH)" "CFLAGS=$(MACHFL)" `cat OLIST`
# arch doesn't work recursively, tar does, which is what we actually want
tar:
@rm -f OLIST
make `cat LIST`
cp LIST OLIST

Some files were not shown because too many files have changed in this diff Show more