Merge deletion of many undead files.
This commit is contained in:
commit
7ef9b79c11
|
@ -1,3 +0,0 @@
|
|||
p=/proj/em/Work
|
||||
sh TakeAction 'make distr' $p/distr/Action
|
||||
sh TakeAction 'make distr' $p/distr/Action1
|
35
Makefile
35
Makefile
|
@ -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 ) \
|
||||
)
|
|
@ -1 +0,0 @@
|
|||
exec /usr/em/doc/em/int/em /usr/em/doc/em/int/tables ${1-e.out} core
|
|
@ -1,3 +0,0 @@
|
|||
name "EM tables"
|
||||
dir etc
|
||||
end
|
|
@ -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
|
26
distr/f.attf
26
distr/f.attf
|
@ -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
|
|
@ -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) > $@
|
|
@ -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.
|
|
@ -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
|
323
doc/cref.doc
323
doc/cref.doc
|
@ -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).
|
|
@ -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
|
|
@ -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
|
1122
doc/em/addend.n
1122
doc/em/addend.n
File diff suppressed because it is too large
Load diff
|
@ -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
|
488
doc/em/app.nr
488
doc/em/app.nr
|
@ -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
|
|
@ -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
|
376
doc/em/iotrap.nr
376
doc/em/iotrap.nr
|
@ -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
|
2922
doc/em/itables
2922
doc/em/itables
File diff suppressed because it is too large
Load diff
|
@ -1,5 +0,0 @@
|
|||
|
||||
case $# in
|
||||
1) make "$1".t ; ntlp "$1".t^lpr ;;
|
||||
*) echo $0 heeft een argument nodig ;;
|
||||
esac
|
|
@ -1,4 +0,0 @@
|
|||
case $# in
|
||||
1) make $1.t ; ntout $1.t ;;
|
||||
*) echo $0 heeft een argument nodig ;;
|
||||
esac
|
|
@ -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
|
|
@ -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
|
|
@ -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 > $@
|
|
@ -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) > $@
|
|
@ -1 +0,0 @@
|
|||
0
|
|
@ -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
|
289
etc/pc_errors
289
etc/pc_errors
|
@ -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
|
107
etc/pc_rt_errors
107
etc/pc_rt_errors
|
@ -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
|
|
@ -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
|
67
first/ckpath
67
first/ckpath
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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);
|
||||
}
|
26
h/pc_size.h
26
h/pc_size.h
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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");
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 + 1*/]; /* 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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() { }
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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))
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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))
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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++);
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
|
|
@ -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()
|
|
@ -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)
|
|
@ -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__))
|
|
@ -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))
|
||||
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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--
|
|
@ -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--
|
|
@ -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() { }
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
|
@ -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();
|
|
@ -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))
|
||||
|
|
@ -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*/
|
||||
}
|
|
@ -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();
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
Reference in a new issue