fixup commit for tag 'release-6-0-pre-3'
This commit is contained in:
		
							parent
							
								
									54ce3f451b
								
							
						
					
					
						commit
						58e5e12ead
					
				
					 675 changed files with 111 additions and 45781 deletions
				
			
		|  | @ -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 +0,0 @@ | |||
| cp .distr $DESTDIR/$1 | ||||
|  | @ -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,26 +1,29 @@ | |||
| /* $Id$ */ | ||||
| /*
 | ||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Basic system types and major/minor device constructing/busting macros. | ||||
|  */ | ||||
| /* $Header$ */ | ||||
| 
 | ||||
| #if	!defined(_SYS_TYPES_H) | ||||
| #define	_SYS_TYPES_H | ||||
| #if     !defined(_SYS_TYPES_H) | ||||
| #define _SYS_TYPES_H | ||||
| 
 | ||||
| #if	!defined(_SIZE_T) | ||||
| #define	_SIZE_T | ||||
| typedef unsigned int	size_t;		/* type returned by sizeof */ | ||||
| #endif	/* _SIZE_T */ | ||||
| #ifdef __STDC__ | ||||
| #if     !defined(_SIZE_T) | ||||
| #define _SIZE_T | ||||
| typedef unsigned int    size_t;         /* type returned by sizeof */ | ||||
| #endif  /* _SIZE_T */ | ||||
| 
 | ||||
| #if	!defined(_TIME_T) | ||||
| #define	_TIME_T | ||||
| typedef	unsigned long	time_t; | ||||
| #endif	/* TIME_T */ | ||||
| #if     !defined(_TIME_T) | ||||
| #define _TIME_T | ||||
| typedef unsigned long   time_t; | ||||
| #endif  /* TIME_T */ | ||||
| #endif | ||||
| 
 | ||||
| #if	!defined(_POSIX_SOURCE) | ||||
| #if !defined(_POSIX_SOURCE) | ||||
| 
 | ||||
| /* major part of a device */ | ||||
| #define	major(x)	((int)(((unsigned)(x)>>8)&0377)) | ||||
|  | @ -39,20 +42,18 @@ typedef	unsigned long	u_long; | |||
| typedef	struct	_physadr { int r[1]; } *physadr; | ||||
| typedef	long	daddr_t; | ||||
| typedef	char *	caddr_t; | ||||
| #if	defined(__BSD4_2) | ||||
| #if defined(__BSD4_2) | ||||
| typedef	u_long ino_t; | ||||
| #else | ||||
| typedef	u_short ino_t; | ||||
| #endif | ||||
| typedef	long	swblk_t; | ||||
| 
 | ||||
| #include <sys/stdtypes.h> | ||||
| 
 | ||||
| typedef	long	label_t[14]; | ||||
| typedef	short	dev_t; | ||||
| #if	defined(__BSD4_2) | ||||
| typedef	int	off_t;			/* see lseek(2) */ | ||||
| #else | ||||
| typedef	long	off_t; | ||||
| #endif | ||||
| 
 | ||||
| /* system V compatibility: */ | ||||
| typedef unsigned int	uint; | ||||
|  | @ -61,17 +62,18 @@ typedef unsigned char	uchar_t; | |||
| typedef short		cnt_t; | ||||
| typedef long		paddr_t; | ||||
| typedef long		key_t; | ||||
| #else	/* _POSIX_SOURCE */ | ||||
| #if	defined(_MINIX) | ||||
| typedef unsigned short	dev_t;	/* hold (major|minor) device pair */ | ||||
| typedef unsigned char	gid_t;	/* group id */ | ||||
| typedef unsigned short	ino_t;	/* i-node number */ | ||||
| typedef unsigned short	mode_t;	/* mode number within an i-node */ | ||||
| typedef unsigned char	nlink_t; /* number-of-links field within an i-node */ | ||||
| typedef long		off_t;	/* offsets within a file */ | ||||
| typedef int		pid_t;	/* type for pids (must be signed) */ | ||||
| typedef unsigned short	uid_t;	/* user id */ | ||||
| #endif	/* _MINIX */ | ||||
| #endif	/* _POSIX_SOURCE */ | ||||
| 
 | ||||
| #endif	/* _SYS_TYPES_H */ | ||||
| #else	/* _POSIX_SOURCE */ | ||||
| #if     defined(_MINIX) | ||||
| typedef unsigned short  dev_t;  /* hold (major|minor) device pair */ | ||||
| typedef unsigned char   gid_t;  /* group id */ | ||||
| typedef unsigned short  ino_t;  /* i-node number */ | ||||
| typedef unsigned short  mode_t; /* mode number within an i-node */ | ||||
| typedef unsigned char   nlink_t; /* number-of-links field within an i-node */ | ||||
| typedef long            off_t;  /* offsets within a file */ | ||||
| typedef int             pid_t;  /* type for pids (must be signed) */ | ||||
| typedef unsigned short  uid_t;  /* user id */ | ||||
| #endif  /* _MINIX */ | ||||
| #endif  /* _POSIX_SOURCE */ | ||||
| 
 | ||||
| #endif /* _SYS_TYPES_H */ | ||||
|  | @ -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 | ||||
							
								
								
									
										79
									
								
								include/_tail_mon/sys/types.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								include/_tail_mon/sys/types.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | |||
| /* $Id$ */ | ||||
| /*
 | ||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Basic system types and major/minor device constructing/busting macros. | ||||
|  */ | ||||
| 
 | ||||
| #if     !defined(_SYS_TYPES_H) | ||||
| #define _SYS_TYPES_H | ||||
| 
 | ||||
| #ifdef __STDC__ | ||||
| #if     !defined(_SIZE_T) | ||||
| #define _SIZE_T | ||||
| typedef unsigned int    size_t;         /* type returned by sizeof */ | ||||
| #endif  /* _SIZE_T */ | ||||
| 
 | ||||
| #if     !defined(_TIME_T) | ||||
| #define _TIME_T | ||||
| typedef unsigned long   time_t; | ||||
| #endif  /* TIME_T */ | ||||
| #endif | ||||
| 
 | ||||
| #if !defined(_POSIX_SOURCE) | ||||
| 
 | ||||
| /* major part of a device */ | ||||
| #define	major(x)	((int)(((unsigned)(x)>>8)&0377)) | ||||
| 
 | ||||
| /* minor part of a device */ | ||||
| #define	minor(x)	((int)((x)&0377)) | ||||
| 
 | ||||
| /* make a device number */ | ||||
| #define	makedev(x,y)	((dev_t)(((x)<<8) | (y))) | ||||
| 
 | ||||
| typedef	unsigned char	u_char; | ||||
| typedef	unsigned short	u_short; | ||||
| typedef	unsigned int	u_int; | ||||
| typedef	unsigned long	u_long; | ||||
| 
 | ||||
| typedef	struct	_physadr { int r[1]; } *physadr; | ||||
| typedef	long	daddr_t; | ||||
| typedef	char *	caddr_t; | ||||
| #if defined(__BSD4_2) | ||||
| typedef	u_long ino_t; | ||||
| #else | ||||
| typedef	u_short ino_t; | ||||
| #endif | ||||
| typedef	long	swblk_t; | ||||
| 
 | ||||
| #include <sys/stdtypes.h> | ||||
| 
 | ||||
| typedef	long	label_t[14]; | ||||
| typedef	short	dev_t; | ||||
| typedef	long	off_t; | ||||
| 
 | ||||
| /* system V compatibility: */ | ||||
| typedef unsigned int	uint; | ||||
| typedef unsigned short	ushort; | ||||
| typedef unsigned char	uchar_t; | ||||
| typedef short		cnt_t; | ||||
| typedef long		paddr_t; | ||||
| typedef long		key_t; | ||||
| 
 | ||||
| #else	/* _POSIX_SOURCE */ | ||||
| #if     defined(_MINIX) | ||||
| typedef unsigned short  dev_t;  /* hold (major|minor) device pair */ | ||||
| typedef unsigned char   gid_t;  /* group id */ | ||||
| typedef unsigned short  ino_t;  /* i-node number */ | ||||
| typedef unsigned short  mode_t; /* mode number within an i-node */ | ||||
| typedef unsigned char   nlink_t; /* number-of-links field within an i-node */ | ||||
| typedef long            off_t;  /* offsets within a file */ | ||||
| typedef int             pid_t;  /* type for pids (must be signed) */ | ||||
| typedef unsigned short  uid_t;  /* user id */ | ||||
| #endif  /* _MINIX */ | ||||
| #endif  /* _POSIX_SOURCE */ | ||||
| 
 | ||||
| #endif /* _SYS_TYPES_H */ | ||||
|  | @ -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 | ||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		
		Reference in a new issue