fixup commit for tag 'release-6-0-pre-4'
This commit is contained in:
parent
9d2d5606ea
commit
7273130b4c
|
@ -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*/]; /* 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