Better ANSI C compatibility and portability:
+ Addition of function prototypes and include files. + Change function definitions to ANSI C style. + Initial support for CMake + Scripts to generate compiler header is now sed based.
This commit is contained in:
		
							parent
							
								
									e70690c510
								
							
						
					
					
						commit
						750a6bc684
					
				
					 82 changed files with 5184 additions and 4082 deletions
				
			
		|  | @ -1,5 +1,5 @@ | |||
| !File: lint.h | ||||
| /*#define	LINT		1	/* if defined, 'lint' is produced	*/ | ||||
| /*#define	LINT		1	*//* if defined, 'lint' is produced	*/ | ||||
| 
 | ||||
| 
 | ||||
| !File: pathlength.h | ||||
|  | @ -75,7 +75,7 @@ | |||
| 
 | ||||
| 
 | ||||
| !File: botch_free.h | ||||
| /*#define BOTCH_FREE	1	/* when defined, botch freed memory, as a check	*/ | ||||
| /*#define BOTCH_FREE	1*	*//* when defined, botch freed memory, as a check	*/ | ||||
| 
 | ||||
| 
 | ||||
| !File: dataflow.h | ||||
|  | @ -83,7 +83,7 @@ | |||
| 
 | ||||
| 
 | ||||
| !File: debug.h | ||||
| /*#define DEBUG		1	/* perform various self-tests		*/ | ||||
| /*#define DEBUG		1	*//* perform various self-tests		*/ | ||||
| #define NDEBUG		1	/* disable assertions			*/ | ||||
| 
 | ||||
| 
 | ||||
|  | @ -112,7 +112,7 @@ | |||
| 
 | ||||
| 
 | ||||
| !File: nobitfield.h | ||||
| /*#define NOBITFIELD	1	/* if NOT defined, implement bitfields	*/ | ||||
| /*#define NOBITFIELD	1	*//* if NOT defined, implement bitfields	*/ | ||||
| 
 | ||||
| 
 | ||||
| !File: spec_arith.h | ||||
|  | @ -125,11 +125,11 @@ | |||
| 
 | ||||
| 
 | ||||
| !File: nocross.h | ||||
| /*#define NOCROSS		1	/* if NOT defined, cross compiler */ | ||||
| /*#define NOCROSS		1	*//* if NOT defined, cross compiler */ | ||||
| 
 | ||||
| 
 | ||||
| !File: regcount.h | ||||
| /*#define REGCOUNT		1	/* count occurrences for register messages */ | ||||
| /*#define REGCOUNT		1	*//* count occurrences for register messages */ | ||||
| 
 | ||||
| 
 | ||||
| !File: dbsymtab.h | ||||
|  |  | |||
							
								
								
									
										318
									
								
								lang/cem/cemcom.ansi/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								lang/cem/cemcom.ansi/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,318 @@ | |||
| cmake_minimum_required (VERSION 3.0) | ||||
| project(em_cemcom.ansi) | ||||
| 
 | ||||
| 
 | ||||
| ################################## | ||||
| # Location of built scripts. | ||||
| ################################## | ||||
| set(PROJECT_SCRIPTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../util/scripts) | ||||
| 
 | ||||
| set(SRC_C | ||||
| 	align.h | ||||
| 	arith.c | ||||
| 	arith.h | ||||
| 	atw.h | ||||
| 	blocks.c | ||||
| 	blocks.h | ||||
| 	ch3.c | ||||
| 	ch3.h | ||||
| 	ch3bin.c | ||||
| 	ch3bin.h | ||||
| 	ch3mon.c | ||||
| 	ch3mon.h | ||||
| 	class.h | ||||
| 	code.c | ||||
| 	conversion.c | ||||
| 	conversion.h | ||||
| 	cstoper.c | ||||
| 	cstoper.h | ||||
| 	dataflow.c | ||||
| 	dataflow.h | ||||
| 	declarator.c | ||||
| 	declarator.h | ||||
| 	decspecs.c | ||||
| 	decspecs.h | ||||
| 	domacro.c | ||||
| 	domacro.h | ||||
| 	dumpidf.c | ||||
| 	error.c | ||||
| 	error.h | ||||
| 	eval.c | ||||
| 	eval.h | ||||
| 	expr.c | ||||
| 	field.c | ||||
| 	file_info.h | ||||
| 	fltcstoper.c | ||||
| 	fltcstoper.h | ||||
| 	idf.c | ||||
| 	input.c | ||||
| 	input.h | ||||
| 	interface.h | ||||
| 	idf.c | ||||
| 	input.c | ||||
| 	input.h | ||||
| 	l_class.h | ||||
| 	l_comment.c | ||||
| 	l_comment.h | ||||
| 	l_em.h | ||||
| 	l_ev_ord.c | ||||
| 	l_lint.c | ||||
| 	l_lint.h | ||||
| 	l_misc.c | ||||
| 	l_outdef.c | ||||
| 	l_states.c | ||||
| 	label.c | ||||
| 	label.h | ||||
| 	level.h | ||||
| 	LLlex.c | ||||
| 	LLlex.h | ||||
| 	LLmessage.c | ||||
| 	main.c | ||||
| 	mes.h | ||||
| 	options.c | ||||
| 	options.h | ||||
| 	pragma.c | ||||
| 	pragma.h | ||||
| 	proto.c | ||||
| 	sizes.h | ||||
| 	skip.c | ||||
| 	skip.h | ||||
| 	specials.h | ||||
| 	stab.c | ||||
| 	stab.h | ||||
| 	stack.c | ||||
| 	stb.c | ||||
| 	struct.c | ||||
| 	switch.c | ||||
| 	tokenname.c | ||||
| 	tokenname.h | ||||
| 	type.c | ||||
| 	util.c | ||||
| ) | ||||
| 
 | ||||
| set(INCLUDE_DIRS | ||||
|  . | ||||
|  ${CMAKE_CURRENT_BINARY_DIR} | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/../include | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/../../../modules/src/idf | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/../../../modules/src/input | ||||
| ) | ||||
| 
 | ||||
| ############################################ | ||||
| # LLgen inputs | ||||
| ############################################ | ||||
| 
 | ||||
| set(GEN_G | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/tokenfile.g | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| set(SRC_G | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/program.g | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/declar.g | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/expression.g | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/statement.g | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/ival.g | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| ############################################ | ||||
| # LLgen outputs | ||||
| ############################################ | ||||
| 
 | ||||
| set(GEN_SRC  | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/program.c  | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/declar.c  | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/expression.c  | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/statement.c | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/ival.c | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/tokenfile.c | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/Lpars.c | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/Lpars.h | ||||
|  ${CMAKE_CURRENT_BINARY_DIR}/Lncor.c | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| set(GFILES | ||||
|  ${GEN_G} | ||||
|  ${SRC_G} | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ############################################ | ||||
| # Configuration parameters generated files | ||||
| ############################################ | ||||
| 
 | ||||
| set(GEN_H_CONFIG | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/parameters.h | ||||
| ) | ||||
| 
 | ||||
| set(GEN_OTHERS | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/code.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/declar.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/def.h	 | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/expr.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/field.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/estack.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/util.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/proto.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/replace.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/idf.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/macro.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/stack.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/stmt.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/struct.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/switch.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/type.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/l_brace.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/l_state.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/l_outdef.h | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/next.c | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| set(CFILES | ||||
| 	${SRC_C} | ||||
| 	${GEN_SRC} | ||||
| 	${GEN_H_CONFIG} | ||||
| 	${GEN_OTHERS} | ||||
| 	symbol2str.c | ||||
| 	char.c | ||||
| ) | ||||
| 
 | ||||
| set(LLGENOPTIONS | ||||
|  -n | ||||
| ) | ||||
| 
 | ||||
| ############################################### | ||||
| # Generate the compile time configuration file  | ||||
| ############################################### | ||||
| add_custom_command( | ||||
|     OUTPUT ${GEN_H_CONFIG} BigPars mkparams.sed | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${PROJECT_SCRIPTS_SOURCE_DIR}/mkparams.sed | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/mkparams.sed | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${CMAKE_CURRENT_SOURCE_DIR}/BigPars | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/BigPars                       | ||||
|     COMMAND sed -f ${PROJECT_SCRIPTS_SOURCE_DIR}/mkparams.sed ${CMAKE_CURRENT_BINARY_DIR}/BigPars>parameters.h | ||||
|     DEPENDS BigPars) | ||||
|      | ||||
| ############################################### | ||||
| # Generate other source files | ||||
| ###############################################      | ||||
| 
 | ||||
| 
 | ||||
| add_custom_command( | ||||
|     OUTPUT ${GEN_OTHERS} mkalloc1.sed mkalloc2.sed mknext.sed | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${PROJECT_SCRIPTS_SOURCE_DIR}/mkalloc1.sed | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${PROJECT_SCRIPTS_SOURCE_DIR}/mkalloc2.sed | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${PROJECT_SCRIPTS_SOURCE_DIR}/mknext.sed | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed    | ||||
|                  | ||||
| 
 | ||||
|                  | ||||
|                                                      | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/code.str>code.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/declar.str>declar.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/def.str>def.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/expr.str>expr.h       | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/field.str>field.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/estack.str>estack.h       | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/util.str>util.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/proto.str>proto.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/idf.str>idf.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/macro.str>macro.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/stack.str>stack.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/stmt.str>stmt.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/struct.str>struct.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/switch.str>switch.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/type.str>type.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_brace.str>l_brace.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_state.str>l_state.h | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_outdef.str>l_outdef.h | ||||
|     # Create next file from above files | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${CMAKE_CURRENT_SOURCE_DIR}/next.str | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/code.str>>next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/declar.str>>next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/def.str>>next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/expr.str>>next.c   | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/field.str>>next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/estack.str>>next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/util.str>>next.c  | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/proto.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/idf.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/macro.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/stack.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/stmt.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/struct.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/switch.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/type.str>>next.c | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_brace.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_state.str>>next.c       | ||||
|     COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_outdef.str>>next.c       | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| add_custom_command( | ||||
| 	OUTPUT char.c | ||||
| 	COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../../../util/cmisc/tabgen -f${CMAKE_CURRENT_SOURCE_DIR}/char.tab >char.c | ||||
| ) | ||||
| 
 | ||||
| ############################################### | ||||
| # Generate the LLGen source files  | ||||
| # NOTE: Order of input file is important | ||||
| ###############################################  | ||||
| 
 | ||||
| add_custom_command( | ||||
|     OUTPUT tokenfile.g mktkfile.sed | ||||
|     COMMAND ${CMAKE_COMMAND} -E copy | ||||
|                 ${PROJECT_SCRIPTS_SOURCE_DIR}/mktkfile.sed | ||||
|                 ${CMAKE_CURRENT_BINARY_DIR}/mktkfile.sed     | ||||
|     COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mktkfile.sed ${CMAKE_CURRENT_SOURCE_DIR}/tokenname.c>tokenfile.g | ||||
| ) | ||||
| 
 | ||||
| add_custom_command( | ||||
|     OUTPUT ${GEN_SRC} | ||||
|     COMMAND  ${CMAKE_COMMAND} -E env LLGEN_LIB_DIR=${CMAKE_CURRENT_SOURCE_DIR}/../../../util/LLgen/lib ${CMAKE_CURRENT_BINARY_DIR}/../../../util/LLgen/LLgen ${LLGENOPTIONS} ${GEN_G} ${SRC_G} | ||||
|     DEPENDS LLgen tokenfile.g) | ||||
|      | ||||
|      | ||||
| add_custom_command( | ||||
|    OUTPUT symbol2str.c | ||||
|    COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tokcaseh.in >symbol2str.c  | ||||
|    COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/tokcase.sed ${CMAKE_CURRENT_SOURCE_DIR}/tokenname.c >>symbol2str.c  | ||||
|    COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tokcasee.in >>symbol2str.c  | ||||
| )      | ||||
|   | ||||
| 
 | ||||
| add_executable(${PROJECT_NAME} ${CFILES}) | ||||
| target_compile_definitions(${PROJECT_NAME} PUBLIC NORCSID=1) | ||||
| target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS}) | ||||
| 
 | ||||
| target_link_libraries(${PROJECT_NAME} emheaders emh flt alloc print string system em_data eme em_mes) | ||||
| 
 | ||||
| install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) | ||||
| install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cemcom.ansi.1 DESTINATION man OPTIONAL) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -17,6 +17,8 @@ | |||
| #include "Lpars.h" | ||||
| #include "class.h" | ||||
| #include "sizes.h" | ||||
| #include "error.h" | ||||
| #include "domacro.h" | ||||
| #include "specials.h" /* registration of special identifiers */ | ||||
| 
 | ||||
| /* Data about the token yielded */ | ||||
|  | @ -41,7 +43,16 @@ extern arith full_mask[]; | |||
| extern int lint_skip_comment; | ||||
| #endif | ||||
| 
 | ||||
| int LLlex() | ||||
| 
 | ||||
| /* Internal function declarations */ | ||||
| static arith char_constant(char*); | ||||
| static char* string_token(char *, int , int *); | ||||
| static int quoted(register int); | ||||
| static int hex_val(register int); | ||||
| static void strflt2tok(char [], struct token *); | ||||
| static void strint2tok(char [], struct token *); | ||||
| 
 | ||||
| int LLlex(void) | ||||
| { | ||||
| 	/*	LLlex() plays the role of Lexical Analyzer for the C parser.
 | ||||
| 	    The look-ahead and putting aside of tokens are taken into | ||||
|  | @ -72,10 +83,8 @@ int LLlex() | |||
| 	return DOT; | ||||
| } | ||||
| 
 | ||||
| char* string_token(); | ||||
| arith char_constant(); | ||||
| 
 | ||||
| int GetToken(ptok) register struct token* ptok; | ||||
| int GetToken(register struct token* ptok) | ||||
| { | ||||
| 	/*	GetToken() is the actual token recognizer. It calls the
 | ||||
| 	    control line interpreter if it encounters a "\n{w}*#" | ||||
|  | @ -379,7 +388,7 @@ go_on: /* rescan, the following character has been read	*/ | |||
| 	/*NOTREACHED*/ | ||||
| } | ||||
| 
 | ||||
| arith char_constant(nm) char* nm; | ||||
| static arith char_constant(char* nm) | ||||
| { | ||||
| 	register arith val = 0; | ||||
| 	register int ch; | ||||
|  | @ -413,8 +422,7 @@ arith char_constant(nm) char* nm; | |||
| 	return val; | ||||
| } | ||||
| 
 | ||||
| char* string_token(nm, stop_char, plen) char* nm; | ||||
| int* plen; | ||||
| static char* string_token(char *nm, int stop_char, int *plen) | ||||
| { | ||||
| 	register int ch; | ||||
| 	register int str_size; | ||||
|  | @ -447,7 +455,7 @@ int* plen; | |||
| 	return str; | ||||
| } | ||||
| 
 | ||||
| int quoted(ch) register int ch; | ||||
| static int quoted(register int ch) | ||||
| { | ||||
| 	/*	quoted() replaces an escaped character sequence by the
 | ||||
| 	    character meant. | ||||
|  | @ -510,12 +518,12 @@ int quoted(ch) register int ch; | |||
| 	return ch & 0377; | ||||
| } | ||||
| 
 | ||||
| int hex_val(ch) register int ch; | ||||
| static int hex_val(register int ch) | ||||
| { | ||||
| 	return is_dig(ch) ? ch - '0' : is_hex(ch) ? (ch - 'a' + 10) & 017 : -1; | ||||
| } | ||||
| 
 | ||||
| int GetChar() | ||||
| int GetChar(void) | ||||
| { | ||||
| 	/*	The routines GetChar and trigraph parses the trigraph
 | ||||
| 	    sequences and removes occurences of \\\n. | ||||
|  | @ -529,8 +537,7 @@ int GetChar() | |||
| /* strflt2tok only checks the syntax of the floating-point number and
 | ||||
|  * selects the right type for the number. | ||||
|  */ | ||||
| strflt2tok(fltbuf, ptok) char fltbuf[]; | ||||
| struct token* ptok; | ||||
| static void strflt2tok(char fltbuf[], struct token* ptok) | ||||
| { | ||||
| 	register char* cp = fltbuf; | ||||
| 	int malformed = 0; | ||||
|  | @ -584,8 +591,7 @@ struct token* ptok; | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| strint2tok(intbuf, ptok) char intbuf[]; | ||||
| struct token* ptok; | ||||
| static void strint2tok(char intbuf[], struct token* ptok) | ||||
| { | ||||
| 	register char* cp = intbuf; | ||||
| 	int base = 10; | ||||
|  |  | |||
|  | @ -9,6 +9,8 @@ | |||
| 	called a "symbol", but it may have other information associated | ||||
| 	to it. | ||||
| */ | ||||
| #ifndef LLLEX_H_ | ||||
| #define LLLEX_H_ | ||||
| 
 | ||||
| #include "file_info.h" | ||||
| 
 | ||||
|  | @ -56,3 +58,9 @@ extern int err_occurred;	/* "error.c"	*/ | |||
| #define	ASIDE	aside.tk_symb | ||||
| 
 | ||||
| #define EOF	(-1) | ||||
| 
 | ||||
| int GetChar(void); | ||||
| int LLlex(void); | ||||
| int GetToken(register struct token* ptok); | ||||
| 
 | ||||
| #endif /* LLLEX_H_ */ | ||||
|  |  | |||
|  | @ -10,21 +10,28 @@ | |||
| #include	"arith.h" | ||||
| #include	"LLlex.h" | ||||
| #include	"Lpars.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| extern char *symbol2str(); | ||||
| 
 | ||||
| LLmessage(tk)	{ | ||||
| static void insert_token(int ); | ||||
| 
 | ||||
| void LLmessage(int tk) | ||||
| { | ||||
| 	err_occurred = 1; | ||||
| 	if (tk < 0)	{ | ||||
| 	if (tk < 0) | ||||
| 	{ | ||||
| 		error("end of file expected"); | ||||
| 	} | ||||
| 	else if (tk)	{ | ||||
| 	else if (tk) | ||||
| 	{ | ||||
| #ifndef LLNONCORR | ||||
| 		error("%s missing before %s", symbol2str(tk), symbol2str(DOT)); | ||||
| #endif | ||||
| 		insert_token(tk); | ||||
| 	} | ||||
| 	else	{ | ||||
| 	else | ||||
| 	{ | ||||
| #ifndef LLNONCORR | ||||
| 		error("%s deleted", symbol2str(DOT)); | ||||
| #else | ||||
|  | @ -34,14 +41,14 @@ LLmessage(tk)	{ | |||
| 	tk_nmb_at_last_syn_err = token_nmb; | ||||
| } | ||||
| 
 | ||||
| insert_token(tk) | ||||
| 	int tk; | ||||
| static void insert_token(int tk) | ||||
| { | ||||
| 	aside = dot; | ||||
| 
 | ||||
| 	DOT = tk; | ||||
| 
 | ||||
| 	switch (tk)	{ | ||||
| 	switch (tk) | ||||
| 	{ | ||||
| 	/* The operands need some body */ | ||||
| 	case IDENTIFIER: | ||||
| 		dot.tk_idf = gen_idf(); | ||||
|  |  | |||
|  | @ -24,16 +24,19 @@ | |||
| #include	"Lpars.h" | ||||
| #include	"field.h" | ||||
| #include	"mes.h" | ||||
| #include    "cstoper.h" | ||||
| #include    "ch3bin.h" | ||||
| #include    "ch3.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| 
 | ||||
| extern char *symbol2str(); | ||||
| extern char options[]; | ||||
| extern arith flt_flt2arith(); | ||||
| extern label code_string(); | ||||
| 
 | ||||
| void | ||||
| arithbalance(e1p, oper, e2p)	/* 3.1.2.5 */ | ||||
| 	register struct expr **e1p, **e2p; | ||||
| 	int oper; | ||||
| /* 3.1.2.5 */ | ||||
| void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p) | ||||
| { | ||||
| 	/*	The expressions *e1p and *e2p are balanced to be operands
 | ||||
| 		of the arithmetic operator oper. | ||||
|  | @ -171,8 +174,7 @@ arithbalance(e1p, oper, e2p)	/* 3.1.2.5 */ | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| relbalance(e1p, oper, e2p) | ||||
| 	register struct expr **e1p, **e2p; | ||||
| void relbalance(register struct expr **e1p, int oper, register struct expr **e2p) | ||||
| { | ||||
| 	/*	The expressions *e1p and *e2p are balanced to be operands
 | ||||
| 		of the relational operator oper, or the ':'. | ||||
|  | @ -204,9 +206,7 @@ relbalance(e1p, oper, e2p) | |||
| 		arithbalance(e1p, oper, e2p); | ||||
| } | ||||
| 
 | ||||
| ch3pointer(expp, oper, tp) | ||||
| 	struct expr **expp; | ||||
| 	register struct type *tp; | ||||
| void ch3pointer(struct expr **expp, int oper, register struct type *tp) | ||||
| { | ||||
| 	/*	Checks whether *expp may be compared to tp using oper,
 | ||||
| 		as described in chapter 3.3.8 and 3.3.9. | ||||
|  | @ -238,9 +238,7 @@ ch3pointer(expp, oper, tp) | |||
| } | ||||
| 
 | ||||
| int | ||||
| any2arith(expp, oper) | ||||
| 	register struct expr **expp; | ||||
| 	register int oper; | ||||
| any2arith(register struct expr **expp, register int oper) | ||||
| { | ||||
| 	/*	Turns any expression into int_type, long_type,
 | ||||
| 		float_type, double_type or lngdbl_type. | ||||
|  | @ -295,8 +293,7 @@ any2arith(expp, oper) | |||
| 	return (*expp)->ex_type->tp_fund; | ||||
| } | ||||
| 
 | ||||
| erroneous2int(expp) | ||||
| 	struct expr **expp; | ||||
| void erroneous2int(struct expr **expp) | ||||
| { | ||||
| 	/*	the (erroneous) expression *expp is replaced by an
 | ||||
| 		int expression | ||||
|  | @ -310,11 +307,7 @@ erroneous2int(expp) | |||
| 	*expp = exp; | ||||
| } | ||||
| 
 | ||||
| struct expr * | ||||
| arith2arith(tp, oper, expr) | ||||
| 	struct type *tp; | ||||
| 	int oper; | ||||
| 	register struct expr *expr; | ||||
| struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr) | ||||
| { | ||||
| 	/*	arith2arith constructs a new expression containing a
 | ||||
| 		run-time conversion between some arithmetic types. | ||||
|  | @ -328,10 +321,7 @@ arith2arith(tp, oper, expr) | |||
| 	return new_oper(tp, new, oper, expr); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| int2int(expp, tp) | ||||
| 	struct expr **expp; | ||||
| 	register struct type *tp; | ||||
| int int2int(struct expr **expp, register struct type *tp) | ||||
| { | ||||
| 	/*	The expression *expp, which is of some integral type, is
 | ||||
| 		converted to the integral type tp. | ||||
|  | @ -369,9 +359,7 @@ int2int(expp, tp) | |||
| /* With compile-time constants, we don't set fp_used, since this is done
 | ||||
|  * only when necessary in eval.c. | ||||
|  */ | ||||
| int2float(expp, tp) | ||||
| 	register struct expr **expp; | ||||
| 	struct type *tp; | ||||
| void int2float(register struct expr **expp, struct type *tp) | ||||
| { | ||||
| 	/*	The expression *expp, which is of some integral type, is
 | ||||
| 		converted to the floating type tp. | ||||
|  | @ -390,9 +378,7 @@ int2float(expp, tp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| float2int(expp, tp) | ||||
| 	struct expr **expp; | ||||
| 	struct type *tp; | ||||
| void float2int(struct expr **expp, struct type *tp) | ||||
| { | ||||
| 	/*	The expression *expp, which is of some floating type, is
 | ||||
| 		converted to the integral type tp. | ||||
|  | @ -418,9 +404,7 @@ float2int(expp, tp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| float2float(expp, tp) | ||||
| 	register struct expr **expp; | ||||
| 	struct type *tp; | ||||
| void float2float(register struct expr **expp, struct type *tp) | ||||
| { | ||||
| 	/*	The expression *expp, which is of some floating type, is
 | ||||
| 		converted to the floating type tp. | ||||
|  | @ -436,8 +420,7 @@ float2float(expp, tp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| array2pointer(exp) | ||||
| 	register struct expr *exp; | ||||
| void array2pointer(register struct expr *exp) | ||||
| { | ||||
| 	/*	The expression, which must be an array, is converted
 | ||||
| 		to a pointer. | ||||
|  | @ -447,8 +430,7 @@ array2pointer(exp) | |||
| 				    , (arith)0, NO_PROTO); | ||||
| } | ||||
| 
 | ||||
| function2pointer(exp) | ||||
| 	register struct expr *exp; | ||||
| void function2pointer(register struct expr *exp) | ||||
| { | ||||
| 	/*	The expression, which must be a function, is converted
 | ||||
| 		to a pointer to the function. | ||||
|  | @ -457,8 +439,7 @@ function2pointer(exp) | |||
| 				     (arith)0, NO_PROTO); | ||||
| } | ||||
| 
 | ||||
| string2pointer(ex) | ||||
| 	register struct expr *ex; | ||||
| void string2pointer(register struct expr *ex) | ||||
| { | ||||
| 	/*	The expression, which must be a string constant, is converted
 | ||||
| 		to a pointer to the string-containing area. | ||||
|  | @ -472,9 +453,7 @@ string2pointer(ex) | |||
| 	ex->VL_VALUE = (arith)0; | ||||
| } | ||||
| 
 | ||||
| opnd2integral(expp, oper) | ||||
| 	register struct expr **expp; | ||||
| 	int oper; | ||||
| void opnd2integral(register struct expr **expp, int oper) | ||||
| { | ||||
| 	register int fund = (*expp)->ex_type->tp_fund; | ||||
| 
 | ||||
|  | @ -486,9 +465,7 @@ opnd2integral(expp, oper) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| opnd2logical(expp, oper) | ||||
| 	register struct expr **expp; | ||||
| 	int oper; | ||||
| void opnd2logical(register struct expr **expp, int oper) | ||||
| { | ||||
| 	int fund = (*expp)->ex_type->tp_fund; | ||||
| 
 | ||||
|  | @ -525,8 +502,7 @@ opnd2logical(expp, oper) | |||
| } | ||||
| 
 | ||||
| void | ||||
| opnd2test(expp, oper) | ||||
| 	register struct expr **expp; | ||||
| opnd2test(register struct expr **expp, int oper) | ||||
| { | ||||
| 	opnd2logical(expp, oper); | ||||
| 	if ((*expp)->ex_class == Oper) { | ||||
|  | @ -550,9 +526,7 @@ opnd2test(expp, oper) | |||
| 	ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT)); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| any2opnd(expp, oper) | ||||
| 	register struct expr **expp; | ||||
| void any2opnd(register struct expr **expp, int oper) | ||||
| { | ||||
| 	if (!*expp) | ||||
| 		return; | ||||
|  | @ -584,8 +558,7 @@ any2opnd(expp, oper) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| any2parameter(expp) | ||||
| 	register struct expr **expp; | ||||
| void any2parameter(register struct expr **expp) | ||||
| { | ||||
| 	/*	To handle default argument promotions
 | ||||
| 	*/ | ||||
|  | @ -598,8 +571,7 @@ any2parameter(expp) | |||
| } | ||||
| 
 | ||||
| #ifndef NOBITFIELD | ||||
| field2arith(expp) | ||||
| 	register struct expr **expp; | ||||
| void field2arith(register struct expr **expp) | ||||
| { | ||||
| 	/*	The expression to extract the bitfield value from the
 | ||||
| 		memory word is put in the tree. | ||||
|  | @ -630,8 +602,7 @@ field2arith(expp) | |||
| /*	switch_sign_fp() negates the given floating constant expression,
 | ||||
|  *	and frees the string representing the old value. | ||||
|  */ | ||||
| switch_sign_fp(expr) | ||||
| 	register struct expr *expr; | ||||
| void switch_sign_fp(register struct expr *expr) | ||||
| { | ||||
| 	flt_umin(&(expr->FL_ARITH)); | ||||
| } | ||||
|  |  | |||
|  | @ -12,12 +12,15 @@ | |||
| 	to save storage on small machines, SPECIAL_ARITHMETICS will | ||||
| 	be handy. | ||||
| */ | ||||
| #ifndef ARITH_H_ | ||||
| #define ARITH_H_ | ||||
| 
 | ||||
| #include	"parameters.h" | ||||
| 
 | ||||
| #ifndef	SPECIAL_ARITHMETICS | ||||
| 
 | ||||
| #include <em_arith.h>		/* obtain definition of "arith"	*/ | ||||
| #include    <em_arith.h>		/* obtain definition of "arith"	*/ | ||||
| #include	<flt_arith.h> | ||||
| 
 | ||||
| #else	/* SPECIAL_ARITHMETICS */ | ||||
| 
 | ||||
|  | @ -27,6 +30,32 @@ | |||
| 
 | ||||
| #endif	/* SPECIAL_ARITHMETICS */ | ||||
| 
 | ||||
| struct expr; | ||||
| struct type; | ||||
| 
 | ||||
| #define	arith_size	(sizeof(arith)) | ||||
| #define	arith_sign	((arith) 1 << (arith_size * 8 - 1)) | ||||
| #define	max_arith	(~arith_sign) | ||||
| 
 | ||||
| void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p); | ||||
| void relbalance(register struct expr **e1p, int oper, register struct expr **e2p); | ||||
| void ch3pointer(struct expr **expp, int oper, register struct type *tp); | ||||
| int any2arith(register struct expr **expp, register int oper); | ||||
| void erroneous2int(struct expr **expp); | ||||
| struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr); | ||||
| int int2int(struct expr **expp, register struct type *tp); | ||||
| void int2float(register struct expr **expp, struct type *tp); | ||||
| void float2int(struct expr **expp, struct type *tp); | ||||
| void float2float(register struct expr **expp, struct type *tp); | ||||
| void array2pointer(register struct expr *exp); | ||||
| void function2pointer(register struct expr *exp); | ||||
| void string2pointer(register struct expr *ex); | ||||
| void opnd2integral(register struct expr **expp, int oper); | ||||
| void opnd2logical(register struct expr **expp, int oper); | ||||
| void opnd2test(register struct expr **expp, int oper); | ||||
| void any2opnd(register struct expr **expp, int oper); | ||||
| void any2parameter(register struct expr **expp); | ||||
| void field2arith(register struct expr **expp); | ||||
| void switch_sign_fp(register struct expr *expr); | ||||
| 
 | ||||
| #endif /* ARITH_H_ */ | ||||
|  |  | |||
|  | @ -18,7 +18,10 @@ | |||
| #include "label.h" | ||||
| #include "stack.h" | ||||
| #include "Lpars.h" | ||||
| extern arith NewLocal(); | ||||
| #include "blocks.h" | ||||
| #include "macro.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| #define LocalPtrVar()	NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER) | ||||
| #define LocalIntVar()	NewLocal(int_size, int_align, reg_any, REGISTER) | ||||
| #endif /* STB */ | ||||
|  | @ -52,9 +55,7 @@ extern arith NewLocal(); | |||
| 	while we need a loop to store the stack block into a memory object. | ||||
| */ | ||||
| 
 | ||||
| suitable_sz(sz, al) | ||||
| 	arith sz; | ||||
| 	int al; | ||||
| int suitable_sz(arith sz, int al) | ||||
| { | ||||
| 	return	((int)sz % (int)word_size == 0 && al % word_align == 0) || | ||||
| 		( | ||||
|  | @ -64,9 +65,7 @@ suitable_sz(sz, al) | |||
| 		); | ||||
| } | ||||
| 
 | ||||
| store_block(sz, al) | ||||
| 	arith sz; | ||||
| 	int al; | ||||
| void store_block(arith sz, int al) | ||||
| { | ||||
| 	if (suitable_sz(sz, al)) | ||||
| 		C_sti(sz); | ||||
|  | @ -102,9 +101,7 @@ store_block(sz, al) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| load_block(sz, al) | ||||
| 	arith sz; | ||||
| 	int al; | ||||
| void load_block(arith sz, int al) | ||||
| { | ||||
| 
 | ||||
| 	if (suitable_sz(sz, al)) | ||||
|  | @ -138,9 +135,7 @@ load_block(sz, al) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| copy_block(sz, al) | ||||
| 	arith sz; | ||||
| 	int al; | ||||
| void copy_block(arith sz, int al) | ||||
| { | ||||
| 
 | ||||
| 	if (suitable_sz(sz, al)) | ||||
|  | @ -167,8 +162,7 @@ copy_block(sz, al) | |||
| } | ||||
| 
 | ||||
| #ifndef STB | ||||
| copy_loop(sz, src, dst) | ||||
| 	arith sz, src, dst; | ||||
| void copy_loop(arith sz, arith src, arith dst) | ||||
| { | ||||
| 	/* generate inline byte-copy loop */ | ||||
| 	label l_cont = text_label(), l_stop = text_label(); | ||||
|  |  | |||
							
								
								
									
										20
									
								
								lang/cem/cemcom.ansi/blocks.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								lang/cem/cemcom.ansi/blocks.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory, | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  * | ||||
|  */ | ||||
| #ifndef BLOCKS_H_ | ||||
| #define BLOCKS_H_ | ||||
| 
 | ||||
| #include "parameters.h" | ||||
| #include "arith.h" | ||||
| 
 | ||||
| int suitable_sz(arith sz, int al); | ||||
| void store_block(arith sz, int al); | ||||
| void load_block(arith sz, int al); | ||||
| void copy_block(arith sz, int al); | ||||
| void copy_loop(arith sz, arith src, arith dst); | ||||
| 
 | ||||
| #endif /* BLOCKS_H_ */ | ||||
|  | @ -9,6 +9,7 @@ | |||
| #include	"parameters.h" | ||||
| #include	<flt_arith.h> | ||||
| #include	"arith.h" | ||||
| #include    "ch3.h" | ||||
| #include    "idf.h" | ||||
| #include	"proto.h" | ||||
| #include	"type.h" | ||||
|  | @ -17,23 +18,22 @@ | |||
| #include	"expr.h" | ||||
| #include	"def.h" | ||||
| #include	"Lpars.h" | ||||
| #include    "error.h" | ||||
| #include    "ch3bin.h" | ||||
| #include	"file_info.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
| extern char *symbol2str(); | ||||
| extern struct type *qualifier_type(); | ||||
| 
 | ||||
| void ch3cast(); | ||||
| 
 | ||||
| 
 | ||||
| /*	Most expression-handling routines have a pointer to a
 | ||||
| 	(struct type *) as first parameter. The object under the pointer | ||||
| 	gets updated in the process. | ||||
| */ | ||||
| 
 | ||||
| void | ||||
| ch3sel(expp, oper, idf) | ||||
| 	struct expr **expp; | ||||
| 	struct idf *idf; | ||||
| void ch3sel(struct expr **expp, int oper, struct idf *idf) | ||||
| { | ||||
| 	/*	The selector idf is applied to *expp; oper may be '.' or
 | ||||
| 		ARROW. | ||||
|  | @ -163,8 +163,7 @@ ch3sel(expp, oper, idf) | |||
| 	*expp = exp; | ||||
| } | ||||
| 
 | ||||
| ch3incr(expp, oper) | ||||
| 	struct expr **expp; | ||||
| void ch3incr(struct expr **expp, int oper) | ||||
| { | ||||
| 	/*	The monadic prefix/postfix incr/decr operator oper is
 | ||||
| 		applied to *expp. | ||||
|  | @ -172,10 +171,7 @@ ch3incr(expp, oper) | |||
| 	ch3asgn(expp, oper, intexpr((arith)1, INT)); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ch3cast(expp, oper, tp) | ||||
| 	register struct expr **expp; | ||||
| 	register struct type *tp; | ||||
| void ch3cast(register struct expr **expp, int oper, register struct type *tp) | ||||
| { | ||||
| 	/*	The expression *expp is cast to type tp; the cast is
 | ||||
| 		caused by the operator oper.  If the cast has | ||||
|  | @ -412,9 +408,7 @@ ch3cast(expp, oper, tp) | |||
| 
 | ||||
| /*	Determine whether two types are equal.
 | ||||
| */ | ||||
| equal_type(tp, otp, qual_lev, diag) | ||||
| 	register struct type *tp, *otp; | ||||
| 	int qual_lev, diag; | ||||
| int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag) | ||||
| { | ||||
| 	 if (tp == otp) | ||||
| 		return 1; | ||||
|  | @ -475,8 +469,7 @@ equal_type(tp, otp, qual_lev, diag) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| check_pseudoproto(pl, opl, diag) | ||||
| 	register struct proto *pl, *opl; | ||||
| int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag) | ||||
| { | ||||
| 	int retval = 1; | ||||
| 
 | ||||
|  | @ -519,9 +512,7 @@ check_pseudoproto(pl, opl, diag) | |||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| legal_mixture(tp, otp, diag) | ||||
| 	struct type *tp, *otp; | ||||
| 	int diag; | ||||
| int legal_mixture(struct type *tp, struct type *otp, int diag) | ||||
| { | ||||
| 	struct proto *pl = tp->tp_proto, *opl = otp->tp_proto; | ||||
| 	int retval = 1; | ||||
|  | @ -562,9 +553,7 @@ legal_mixture(tp, otp, diag) | |||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| equal_proto(pl, opl, diag) | ||||
| 	register struct proto *pl, *opl; | ||||
| 	int diag; | ||||
| int equal_proto(register struct proto *pl, register struct proto *opl, int diag) | ||||
| { | ||||
| 	if (pl == opl) | ||||
| 		return 1; | ||||
|  | @ -586,9 +575,7 @@ equal_proto(pl, opl, diag) | |||
| } | ||||
| 
 | ||||
| /* check if a type has a consqualified member */ | ||||
| recurqual(tp, qual) | ||||
| struct type *tp; | ||||
| int qual; | ||||
| int recurqual(struct type *tp, int qual) | ||||
| { | ||||
| 	register struct sdef *sdf; | ||||
| 
 | ||||
|  | @ -610,9 +597,7 @@ int qual; | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| ch3asgn(expp, oper, expr) | ||||
| 	struct expr **expp; | ||||
| 	struct expr *expr; | ||||
| void ch3asgn(struct expr **expp, int oper, struct expr *expr) | ||||
| { | ||||
| 	/*	The assignment operators.
 | ||||
| 		"f op= e" should be interpreted as | ||||
|  | @ -687,9 +672,7 @@ ch3asgn(expp, oper, expr) | |||
| 
 | ||||
| /*	Some interesting (?) questions answered.
 | ||||
| */ | ||||
| int | ||||
| is_integral_type(tp) | ||||
| 	register struct type *tp; | ||||
| int is_integral_type(register struct type *tp) | ||||
| { | ||||
| 	switch (tp->tp_fund)	{ | ||||
| 	case CHAR: | ||||
|  | @ -707,9 +690,7 @@ is_integral_type(tp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| int | ||||
| is_arith_type(tp) | ||||
| 	register struct type *tp; | ||||
| int is_arith_type(register struct type *tp) | ||||
| { | ||||
| 	switch (tp->tp_fund)	{ | ||||
| 	case CHAR: | ||||
|  |  | |||
							
								
								
									
										29
									
								
								lang/cem/cemcom.ansi/ch3.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lang/cem/cemcom.ansi/ch3.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| /*  Copyright (c) 2019 ACK Project. See the file Copyright in
 | ||||
|  *  the project root directory for more information. | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  * | ||||
|  */ | ||||
| #ifndef CH3_H_ | ||||
| #define CH3_H_ | ||||
| 
 | ||||
| /* Structure forward declarations. */ | ||||
| struct expr; | ||||
| struct type; | ||||
| struct proto; | ||||
| struct idf; | ||||
| 
 | ||||
| 
 | ||||
| void ch3sel(struct expr **expp, int oper, struct idf *idf); | ||||
| void ch3incr(struct expr **expp, int oper); | ||||
| void ch3cast(register struct expr **expp, int oper, register struct type *tp); | ||||
| int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag); | ||||
| int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag); | ||||
| int legal_mixture(struct type *tp, struct type *otp, int diag); | ||||
| int equal_proto(register struct proto *pl, register struct proto *opl, int diag); | ||||
| int recurqual(struct type *tp, int qual); | ||||
| void ch3asgn(struct expr **expp, int oper, struct expr *expr); | ||||
| int is_integral_type(register struct type *tp); | ||||
| int is_arith_type(register struct type *tp); | ||||
| 
 | ||||
| #endif /* CH3_H_ */ | ||||
|  | @ -15,6 +15,12 @@ | |||
| #include	"expr.h" | ||||
| #include	"Lpars.h" | ||||
| #include	"sizes.h" | ||||
| #include    "ch3bin.h" | ||||
| #include    "ch3mon.h" | ||||
| #include    "ch3.h" | ||||
| #include    "error.h" | ||||
| #include    "cstoper.h" | ||||
| #include    "fltcstoper.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
| extern char *symbol2str(); | ||||
|  | @ -34,10 +40,7 @@ void pntminuspnt(); | |||
| #define commutative_binop(expp, oper, expr)	mk_binop(expp, oper, expr, 1) | ||||
| #define non_commutative_relop(expp, oper, expr)	mk_binop(expp, oper, expr, 1) | ||||
| 
 | ||||
| void | ||||
| ch3bin(expp, oper, expr) | ||||
| 	register struct expr **expp; | ||||
| 	struct expr *expr; | ||||
| void ch3bin(register struct expr **expp, int oper, struct expr *expr) | ||||
| { | ||||
| 	/*	apply binary operator oper between *expp and expr.
 | ||||
| 		NB: don't swap operands if op is one of the op= operators!!! | ||||
|  | @ -295,9 +298,7 @@ ch3bin(expp, oper, expr) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| pntminuspnt(expp, oper, expr) | ||||
| 	register struct expr **expp, *expr; | ||||
| void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr) | ||||
| { | ||||
| 	/*	Subtracting two pointers is so complicated it merits a
 | ||||
| 		routine of its own. | ||||
|  | @ -328,8 +329,7 @@ pntminuspnt(expp, oper, expr) | |||
|  * when the arguments are switched.  This is special for some relational | ||||
|  * operators. | ||||
|  */ | ||||
| int | ||||
| arg_switched(oper) | ||||
| int arg_switched(int oper) | ||||
| { | ||||
| 	switch (oper) { | ||||
| 	case '<':	return '>'; | ||||
|  | @ -340,9 +340,7 @@ arg_switched(oper) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| mk_binop(expp, oper, expr, commutative) | ||||
| 	struct expr **expp; | ||||
| 	register struct expr *expr; | ||||
| void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative) | ||||
| { | ||||
| 	/*	Constructs in *expp the operation indicated by the operands.
 | ||||
| 		"commutative" indicates whether "oper" is a commutative | ||||
|  | @ -366,8 +364,7 @@ mk_binop(expp, oper, expr, commutative) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pointer_arithmetic(expp1, oper, expp2) | ||||
| 	register struct expr **expp1, **expp2; | ||||
| void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2) | ||||
| { | ||||
| 	int typ; | ||||
| 	/*	prepares the integral expression expp2 in order to
 | ||||
|  | @ -387,8 +384,7 @@ pointer_arithmetic(expp1, oper, expp2) | |||
| 	); | ||||
| } | ||||
| 
 | ||||
| pointer_binary(expp, oper, expr) | ||||
| 	register struct expr **expp, *expr; | ||||
| void pointer_binary(register struct expr **expp, int oper, register struct expr *expr) | ||||
| { | ||||
| 	/*	constructs the pointer arithmetic expression out of
 | ||||
| 		a pointer expression, a binary operator and an integral | ||||
|  |  | |||
							
								
								
									
										21
									
								
								lang/cem/cemcom.ansi/ch3bin.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								lang/cem/cemcom.ansi/ch3bin.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory, | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  * | ||||
|  */ | ||||
| #ifndef CH3BIN_H_ | ||||
| #define CH3BIN_H_ | ||||
| 
 | ||||
| struct expr; | ||||
| 
 | ||||
| void ch3bin(register struct expr **expp, int oper, struct expr *expr); | ||||
| void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr); | ||||
| int arg_switched(int oper); | ||||
| void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative); | ||||
| void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2); | ||||
| void pointer_binary(register struct expr **expp, int oper, register struct expr *expr); | ||||
| 
 | ||||
| 
 | ||||
| #endif /* CH3BIN_H_ */ | ||||
|  | @ -5,6 +5,7 @@ | |||
| /* $Id$ */ | ||||
| /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */ | ||||
| 
 | ||||
| #include    "ch3mon.h" | ||||
| #include	"parameters.h" | ||||
| #include	<alloc.h> | ||||
| #include	"Lpars.h" | ||||
|  | @ -16,13 +17,15 @@ | |||
| #include	"expr.h" | ||||
| #include	"def.h" | ||||
| #include	"sizes.h" | ||||
| #include    "ch3.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| 
 | ||||
| extern char options[]; | ||||
| extern arith full_mask[/*MAXSIZE + 1*/];	/* cstoper.c */ | ||||
| char *symbol2str(); | ||||
| 
 | ||||
| ch3mon(oper, expp) | ||||
| 	register struct expr **expp; | ||||
| void ch3mon(int oper, register struct expr **expp) | ||||
| { | ||||
| 	/*	The monadic prefix operator oper is applied to *expp.
 | ||||
| 	*/ | ||||
|  |  | |||
							
								
								
									
										22
									
								
								lang/cem/cemcom.ansi/ch3mon.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								lang/cem/cemcom.ansi/ch3mon.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef CH3MON_H_ | ||||
| #define CH3MON_H_ | ||||
| 
 | ||||
| struct expr; | ||||
| 
 | ||||
| void ch3mon(int oper, register struct expr **expp); | ||||
| void ch3bin(register struct expr **expp, int oper, struct expr *expr); | ||||
| void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr); | ||||
| int arg_switched(int oper); | ||||
| void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative); | ||||
| void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2); | ||||
| void pointer_binary(register struct expr **expp, int oper, register struct expr *expr); | ||||
| 
 | ||||
| 
 | ||||
| #endif /* CH3MON_H_ */ | ||||
|  | @ -27,14 +27,24 @@ | |||
| #include	"expr.h" | ||||
| #include	"sizes.h" | ||||
| #include	"stack.h" | ||||
| #include    "blocks.h" | ||||
| #include    "struct.h" | ||||
| #include	"level.h" | ||||
| #include    "dataflow.h" | ||||
| #include    "conversion.h" | ||||
| #include	"decspecs.h" | ||||
| #include	"declar.h" | ||||
| #include	"Lpars.h" | ||||
| #include	"specials.h" | ||||
| #include	"atw.h" | ||||
| #include    "ch3.h" | ||||
| #include    "eval.h" | ||||
| #include    "stab.h" | ||||
| #include	"LLlex.h" | ||||
| #include	"align.h" | ||||
| #include    "util.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| #ifdef	LINT | ||||
| #include	"l_lint.h" | ||||
| #endif	/* LINT */ | ||||
|  | @ -46,7 +56,10 @@ label lab_count = 1; | |||
| label datlab_count = 1; | ||||
| 
 | ||||
| int fp_used; | ||||
| extern arith NewLocal();	/* util.c	*/ | ||||
| 
 | ||||
| extern void str_cst(register char *, register int, int);  /* ival.c */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* global function info */ | ||||
| char *func_name; | ||||
|  | @ -67,8 +80,7 @@ extern char *source; | |||
| void loc_init(); | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| init_code(dst_file) | ||||
| 	char *dst_file; | ||||
| void init_code(char *dst_file) | ||||
| { | ||||
| 	/*	init_code() initialises the output file on which the
 | ||||
| 		compact EM code is written | ||||
|  | @ -105,10 +117,7 @@ init_code(dst_file) | |||
| 
 | ||||
| struct string_cst *str_list = 0; | ||||
| 
 | ||||
| label | ||||
| code_string(val, len) | ||||
| 	char *val; | ||||
| 	int len; | ||||
| label code_string(char* val, int len) | ||||
| { | ||||
| 	register struct string_cst *sc = new_string_cst(); | ||||
| 	label dlb = data_label(); | ||||
|  | @ -122,8 +131,7 @@ code_string(val, len) | |||
| 	return dlb; | ||||
| } | ||||
| 
 | ||||
| def_strings(sc) | ||||
| 	register struct string_cst *sc; | ||||
| void def_strings(register struct string_cst *sc) | ||||
| { | ||||
| 	while (sc) { | ||||
| 		struct string_cst *sc1 = sc; | ||||
|  | @ -137,7 +145,7 @@ def_strings(sc) | |||
| } | ||||
| 
 | ||||
| /* flush_strings() is called from program.g after each external definition */ | ||||
| flush_strings() { | ||||
| void flush_strings(void) { | ||||
| 	if (str_list) { | ||||
| 		def_strings(str_list); | ||||
| 		str_list = 0; | ||||
|  | @ -145,7 +153,7 @@ flush_strings() { | |||
| } | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| end_code() | ||||
| void end_code(void) | ||||
| { | ||||
| 	/*	end_code() performs the actions to be taken when closing
 | ||||
| 		the output stream. | ||||
|  | @ -160,7 +168,7 @@ end_code() | |||
| #endif	/* LINT */ | ||||
| 
 | ||||
| #ifdef	PREPEND_SCOPES | ||||
| prepend_scopes() | ||||
| void prepend_scopes(void) | ||||
| { | ||||
| 	/*	prepend_scopes() runs down the list of global idf's
 | ||||
| 		and generates those exa's, exp's, ina's and inp's | ||||
|  | @ -185,9 +193,7 @@ prepend_scopes() | |||
| } | ||||
| #endif	/* PREPEND_SCOPES */ | ||||
| 
 | ||||
| code_scope(text, def) | ||||
| 	char *text; | ||||
| 	register struct def *def; | ||||
| void code_scope(char* text, register struct def *def) | ||||
| { | ||||
| 	/*	generates code for one name, text, of the storage class
 | ||||
| 		as given by def, if meaningful. | ||||
|  | @ -218,9 +224,7 @@ static int struct_return; | |||
| static char *last_fn_given = (char *)0; | ||||
| static label file_name_label; | ||||
| 
 | ||||
| begin_proc(ds, idf)		/* to be called when entering a procedure */ | ||||
| 	struct decspecs *ds; | ||||
| 	struct idf *idf; | ||||
| void begin_proc(struct decspecs *ds, struct idf *idf)		/* to be called when entering a procedure */ | ||||
| { | ||||
| 	/*	begin_proc() is called at the entrance of a new function
 | ||||
| 		and performs the necessary code generation: | ||||
|  | @ -317,8 +321,7 @@ begin_proc(ds, idf)		/* to be called when entering a procedure */ | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| end_proc(fbytes) | ||||
| 	arith fbytes; | ||||
| void end_proc(arith fbytes) | ||||
| { | ||||
| 	/*	end_proc() deals with the code to be generated at the end of
 | ||||
| 		a function, as there is: | ||||
|  | @ -388,7 +391,7 @@ end_proc(fbytes) | |||
| 	options['n'] = optionsn; | ||||
| } | ||||
| 
 | ||||
| do_return() | ||||
| void do_return(void) | ||||
| { | ||||
| 	/*	do_return handles the case of a return without expression.
 | ||||
| 		This version branches to the return label, which is | ||||
|  | @ -401,8 +404,7 @@ do_return() | |||
| 	C_bra(return2_label); | ||||
| } | ||||
| 
 | ||||
| do_return_expr(expr) | ||||
| 	struct expr *expr; | ||||
| void do_return_expr(struct expr *expr) | ||||
| { | ||||
| 	/*	do_return_expr() generates the expression and the jump for
 | ||||
| 		a return statement with an expression. | ||||
|  | @ -418,11 +420,11 @@ do_return_expr(expr) | |||
| } | ||||
| 
 | ||||
| void | ||||
| code_declaration(idf, expr, lvl, sc) | ||||
| 	register struct idf *idf;	/* idf to be declared	*/ | ||||
| 	struct expr *expr;	/* initialisation; NULL if absent	*/ | ||||
| 	int lvl;		/* declaration level	*/ | ||||
| 	int sc;			/* storage class, as in the declaration */ | ||||
| code_declaration( | ||||
| 	register struct idf *idf,	/* idf to be declared	*/ | ||||
| 	struct expr *expr,	/* initialisation; NULL if absent	*/ | ||||
| 	int lvl,		/* declaration level	*/ | ||||
| 	int sc)		/* storage class, as in the declaration */ | ||||
| { | ||||
| 	/*	code_declaration() does the actual declaration of the
 | ||||
| 		variable indicated by "idf" on declaration level "lvl". | ||||
|  | @ -530,10 +532,7 @@ code_declaration(idf, expr, lvl, sc) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| loc_init(expr, id) | ||||
| 	struct expr *expr; | ||||
| 	struct idf *id; | ||||
| void loc_init(struct expr *expr, struct idf *id) | ||||
| { | ||||
| 	/*	loc_init() generates code for the assignment of
 | ||||
| 		expression expr to the local variable described by id. | ||||
|  | @ -609,8 +608,7 @@ loc_init(expr, id) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| bss(idf) | ||||
| 	register struct idf *idf; | ||||
| void bss(register struct idf *idf) | ||||
| { | ||||
| 	/*	bss() allocates bss space for the global idf.
 | ||||
| 	*/ | ||||
|  | @ -640,9 +638,7 @@ bss(idf) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| formal_cvt(hasproto,df) | ||||
| 	int hasproto; | ||||
| 	register struct def *df; | ||||
| void formal_cvt(int hasproto, register struct def *df) | ||||
| { | ||||
| 	/*	formal_cvt() converts a formal parameter of type char or
 | ||||
| 		short from int to that type. It also converts a formal | ||||
|  | @ -672,9 +668,7 @@ formal_cvt(hasproto,df) | |||
| #ifdef	LINT | ||||
| /*ARGSUSED*/ | ||||
| #endif	/* LINT */ | ||||
| code_expr(expr, val, code, tlbl, flbl) | ||||
| 	struct expr *expr; | ||||
| 	label tlbl, flbl; | ||||
| void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl) | ||||
| { | ||||
| 	/*	code_expr() is the parser's interface to the expression code
 | ||||
| 		generator.  If line number trace is wanted, it generates a | ||||
|  | @ -707,7 +701,7 @@ static struct stmt_block *stmt_stack;	/* top of statement stack */ | |||
| 	which are the only ones that are stacked, only the top of | ||||
| 	the stack is interesting. | ||||
| */ | ||||
| code_break() | ||||
| void code_break(void) | ||||
| { | ||||
| 	register struct stmt_block *stmt_block = stmt_stack; | ||||
| 
 | ||||
|  | @ -726,7 +720,7 @@ code_break() | |||
| 	innermost statement in which continue has a meaning. | ||||
| */ | ||||
| void | ||||
| code_continue() | ||||
| code_continue(void) | ||||
| { | ||||
| 	register struct stmt_block *stmt_block = stmt_stack; | ||||
| 
 | ||||
|  | @ -743,8 +737,7 @@ code_continue() | |||
| 	error("continue not inside for, while or do"); | ||||
| } | ||||
| 
 | ||||
| stack_stmt(break_label, cont_label) | ||||
| 	label break_label, cont_label; | ||||
| void stack_stmt(label break_label, label cont_label) | ||||
| { | ||||
| 	register struct stmt_block *stmt_block = new_stmt_block(); | ||||
| 
 | ||||
|  | @ -754,7 +747,7 @@ stack_stmt(break_label, cont_label) | |||
| 	stmt_stack = stmt_block; | ||||
| } | ||||
| 
 | ||||
| unstack_stmt() | ||||
| void unstack_stmt(void) | ||||
| { | ||||
| 	/*	unstack_stmt() unstacks the data of a statement
 | ||||
| 		which may contain break or continue | ||||
|  | @ -766,8 +759,7 @@ unstack_stmt() | |||
| 
 | ||||
| static label prc_name; | ||||
| 
 | ||||
| prc_entry(name) | ||||
| 	char *name; | ||||
| void prc_entry(char* name) | ||||
| { | ||||
| 	if (options['p']) { | ||||
| 		C_df_dlb(prc_name = data_label()); | ||||
|  | @ -778,7 +770,7 @@ prc_entry(name) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| prc_exit() | ||||
| void prc_exit(void) | ||||
| { | ||||
| 	if (options['p']) { | ||||
| 		C_lae_dlb(prc_name, (arith) 0); | ||||
|  | @ -788,9 +780,7 @@ prc_exit() | |||
| } | ||||
| 
 | ||||
| #ifdef DBSYMTAB | ||||
| db_line(file, line) | ||||
| 	char		*file; | ||||
| 	unsigned int	line; | ||||
| void db_line(char *file, unsigned int line) | ||||
| { | ||||
| 	static unsigned oldline; | ||||
| 	static char	*oldfile; | ||||
|  |  | |||
|  | @ -2,9 +2,15 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef CODE_H_ | ||||
| #define CODE_H_ | ||||
| /* $Id$ */ | ||||
| /*	C O D E - G E N E R A T O R   D E F I N I T I O N S	*/ | ||||
| 
 | ||||
| #include "arith.h" | ||||
| #include "label.h" | ||||
| 
 | ||||
| 
 | ||||
| struct string_cst	{	/* storing string constants */ | ||||
| 	struct string_cst *next; | ||||
| 	char *sc_value; | ||||
|  | @ -20,3 +26,44 @@ extern struct string_cst *str_list; | |||
| #define	RVAL	1 | ||||
| #define	FALSE	0 | ||||
| #define	TRUE	1 | ||||
| 
 | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| void init_code(char *dst_file); | ||||
| void end_code(void); | ||||
| #endif | ||||
| 
 | ||||
| struct expr; | ||||
| struct def; | ||||
| struct idf; | ||||
| 
 | ||||
| label code_string(char* val, int len); | ||||
| void def_strings(register struct string_cst *sc); | ||||
| void flush_strings(void); | ||||
| void code_scope(char* text, register struct def *def); | ||||
| void begin_proc(struct decspecs *ds, struct idf *idf); | ||||
| void end_proc(arith fbytes); | ||||
| void do_return(void); | ||||
| void do_return_expr(struct expr *expr); | ||||
| void code_declaration(register struct idf *idf, struct expr *expr,  | ||||
| 		int lvl, int sc); | ||||
| void loc_init(struct expr *expr, struct idf *id); | ||||
| void bss(register struct idf *idf); | ||||
| void formal_cvt(int hasproto, register struct def *df); | ||||
| void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl); | ||||
| void code_break(void); | ||||
| void code_continue(void); | ||||
| void stack_stmt(label break_label, label cont_label); | ||||
| void unstack_stmt(void); | ||||
| void prc_entry(char* name); | ||||
| void prc_exit(void); | ||||
| 
 | ||||
| #ifdef	PREPEND_SCOPES | ||||
| void prepend_scopes(void); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef DBSYMTAB | ||||
| void db_line(char *file, unsigned int line); | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -8,11 +8,15 @@ | |||
| #include	"parameters.h" | ||||
| #ifndef	LINT | ||||
| 
 | ||||
| #include    "conversion.h" | ||||
| #include	<em.h> | ||||
| #include    "interface.h" | ||||
| #include	"arith.h" | ||||
| #include	"type.h" | ||||
| #include	"sizes.h" | ||||
| #include	"Lpars.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| 
 | ||||
| #define	T_SIGNED		1 | ||||
| #define	T_UNSIGNED		2 | ||||
|  | @ -27,10 +31,9 @@ | |||
| 		C?? | ||||
| */ | ||||
| 
 | ||||
| static int convtype(); | ||||
| static int convtype(register struct type *); | ||||
| 
 | ||||
| conversion(from_type, to_type) | ||||
| 	register struct type *from_type, *to_type; | ||||
| void conversion(register struct type *from_type, register struct type *to_type) | ||||
| { | ||||
| 	register arith from_size = from_type->tp_size; | ||||
| 	register arith to_size = to_type->tp_size; | ||||
|  | @ -126,9 +129,7 @@ conversion(from_type, to_type) | |||
| /*	convtype() returns in which category a given type falls:
 | ||||
| 	signed, unsigned or floating | ||||
| */ | ||||
| static int | ||||
| convtype(tp) | ||||
| 	register struct type *tp; | ||||
| static int convtype(register struct type *tp) | ||||
| { | ||||
| 	switch (tp->tp_fund)	{ | ||||
| 	case CHAR: | ||||
|  |  | |||
							
								
								
									
										15
									
								
								lang/cem/cemcom.ansi/conversion.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lang/cem/cemcom.ansi/conversion.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef CONVERSION_H_ | ||||
| #define CONVERSION_H_ | ||||
| 
 | ||||
| struct type; | ||||
| 
 | ||||
| void conversion(register struct type *from_type, register struct type *to_type); | ||||
| 
 | ||||
| #endif /* CONVERSION_H_ */ | ||||
|  | @ -6,6 +6,7 @@ | |||
| /*	C O N S T A N T   E X P R E S S I O N   H A N D L I N G		*/ | ||||
| 
 | ||||
| #include	<assert.h> | ||||
| #include    "cstoper.h" | ||||
| #include    "parameters.h" | ||||
| #include	<flt_arith.h> | ||||
| #include	"arith.h" | ||||
|  | @ -14,6 +15,7 @@ | |||
| #include	"expr.h" | ||||
| #include	"sizes.h" | ||||
| #include	"Lpars.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| /* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */ | ||||
| arith full_mask[MAXSIZE + 1]; | ||||
|  | @ -23,8 +25,7 @@ arith max_unsigned;	/* maximum unsigned on target machine	*/ | |||
| #endif /* NOCROSS */ | ||||
| extern int ResultKnown; | ||||
| 
 | ||||
| cstbin(expp, oper, expr) | ||||
| 	register struct expr **expp, *expr; | ||||
| void cstbin(register struct expr **expp, int oper, register struct expr *expr) | ||||
| { | ||||
| 	/*	The operation oper is performed on the constant
 | ||||
| 		expressions *expp(ld) and expr(ct), and the result restored in | ||||
|  | @ -134,8 +135,7 @@ cstbin(expp, oper, expr) | |||
| 	free_expression(expr); | ||||
| } | ||||
| 
 | ||||
| cut_size(expr) | ||||
| 	register struct expr *expr; | ||||
| void cut_size(register struct expr *expr) | ||||
| { | ||||
| 	/*	The constant value of the expression expr is made to
 | ||||
| 		conform to the size of the type of the expression. | ||||
|  | @ -170,7 +170,7 @@ cut_size(expr) | |||
| 	expr->VL_VALUE = o1; | ||||
| } | ||||
| 
 | ||||
| init_cst() | ||||
| void init_cst(void) | ||||
| { | ||||
| 	register int i = 0; | ||||
| 	register arith bt = (arith)0; | ||||
|  |  | |||
							
								
								
									
										17
									
								
								lang/cem/cemcom.ansi/cstoper.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lang/cem/cemcom.ansi/cstoper.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef CSTOPER_H_ | ||||
| #define CSTOPER_H_ | ||||
| 
 | ||||
| struct expr; | ||||
| 
 | ||||
| void cstbin(register struct expr **expp, int oper, register struct expr *expr); | ||||
| void cut_size(register struct expr *expr); | ||||
| void init_cst(void); | ||||
| 
 | ||||
| #endif /* CSTOPER_H_ */ | ||||
|  | @ -10,26 +10,26 @@ | |||
| */ | ||||
| 
 | ||||
| #include	"parameters.h"	/* UF */ | ||||
| #include    "dataflow.h" | ||||
| #include    "print.h" | ||||
| 
 | ||||
| #ifdef	DATAFLOW | ||||
| char *CurrentFunction = 0; | ||||
| int NumberOfCalls; | ||||
| 
 | ||||
| DfaStartFunction(nm) | ||||
| 	char *nm; | ||||
| void DfaStartFunction(char* nm) | ||||
| { | ||||
| 	CurrentFunction = nm; | ||||
| 	NumberOfCalls = 0; | ||||
| } | ||||
| 
 | ||||
| DfaEndFunction() | ||||
| void DfaEndFunction(void) | ||||
| { | ||||
| 	if (NumberOfCalls == 0) | ||||
| 		print("DFA: %s: --none--\n", CurrentFunction); | ||||
| } | ||||
| 
 | ||||
| DfaCallFunction(s) | ||||
| 	char *s; | ||||
| void DfaCallFunction(char* s) | ||||
| { | ||||
| 	print("DFA: %s: %s\n", CurrentFunction, s); | ||||
| 	++NumberOfCalls; | ||||
|  |  | |||
							
								
								
									
										19
									
								
								lang/cem/cemcom.ansi/dataflow.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lang/cem/cemcom.ansi/dataflow.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef DATAFLOW_H_ | ||||
| #define DATAFLOW_H_ | ||||
| 
 | ||||
| #ifdef	DATAFLOW | ||||
| 
 | ||||
| void DfaStartFunction(char* nm); | ||||
| void DfaEndFunction(void); | ||||
| void DfaCallFunction(char* s); | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #endif /* DATAFLOW_H_ */ | ||||
|  | @ -19,12 +19,16 @@ | |||
| #include	"struct.h" | ||||
| #include	"field.h" | ||||
| #include	"decspecs.h" | ||||
| #include    "declarator.h" | ||||
| #include	"def.h" | ||||
| #include	"declar.h" | ||||
| #include	"label.h" | ||||
| #include	"expr.h" | ||||
| #include	"sizes.h" | ||||
| #include	"level.h" | ||||
| #include    "error.h" | ||||
| #include    "stab.h" | ||||
| 
 | ||||
| #ifdef	LINT | ||||
| #include	"l_lint.h" | ||||
| #endif	/* LINT */ | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
|  #ifndef DECLAR_H_ | ||||
|  #define DECLAR_H_ | ||||
|   | ||||
| /* $Id$ */ | ||||
| /* DEFINITION OF DECLARATOR DESCRIPTORS */ | ||||
| 
 | ||||
|  | @ -39,3 +42,5 @@ struct decl_unary	{ | |||
| 
 | ||||
| extern struct type *declare_type(); | ||||
| extern struct declarator null_declarator; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| /*	D E C L A R A T O R   M A N I P U L A T I O N		*/ | ||||
| 
 | ||||
| #include	"parameters.h" | ||||
| #include    "declarator.h" | ||||
| #include	<alloc.h> | ||||
| #include	<flt_arith.h> | ||||
| #include	"arith.h" | ||||
|  | @ -14,18 +15,20 @@ | |||
| #include	"Lpars.h" | ||||
| #include	"declar.h" | ||||
| #include	"def.h" | ||||
| #include    "idf.h" | ||||
| #include	"label.h" | ||||
| #include	"expr.h" | ||||
| #include	"sizes.h" | ||||
| #include	"level.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
| struct declarator null_declarator; | ||||
| 
 | ||||
| struct type * | ||||
| declare_type(tp, dc) | ||||
| 	struct type *tp; | ||||
| 	struct declarator *dc; | ||||
| declare_type( | ||||
| 	struct type *tp, | ||||
| 	struct declarator *dc) | ||||
| { | ||||
| 	/*	Applies the decl_unary list starting at dc->dc_decl_unary
 | ||||
| 		to the type tp and returns the result. | ||||
|  | @ -43,12 +46,7 @@ declare_type(tp, dc) | |||
| 	return tp; | ||||
| } | ||||
| 
 | ||||
| add_decl_unary(dc, fund, qual,  count, fm, pl) | ||||
| 	register struct declarator *dc; | ||||
| 	int qual; | ||||
| 	arith count; | ||||
| 	struct formal *fm; | ||||
| 	struct proto *pl; | ||||
| void add_decl_unary(register struct declarator *dc, int fund, int qual,  arith count, struct formal *fm, struct proto *pl) | ||||
| { | ||||
| 	/*	A decl_unary describing a constructor with fundamental
 | ||||
| 		type fund and with size count is inserted in front of the | ||||
|  | @ -75,8 +73,7 @@ add_decl_unary(dc, fund, qual,  count, fm, pl) | |||
| 	dc->dc_decl_unary = new; | ||||
| } | ||||
| 
 | ||||
| remove_declarator(dc) | ||||
| 	struct declarator *dc; | ||||
| void remove_declarator(struct declarator *dc) | ||||
| { | ||||
| 	/*	The decl_unary list starting at dc->dc_decl_unary is
 | ||||
| 		removed. | ||||
|  | @ -91,8 +88,7 @@ remove_declarator(dc) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| reject_params(dc) | ||||
| 	register struct declarator *dc; | ||||
| void reject_params(register struct declarator *dc) | ||||
| { | ||||
| 	/*	The declarator is checked to have no parameters, if it
 | ||||
| 		is an old-style function.  If it is a new-style function, | ||||
|  | @ -120,8 +116,7 @@ reject_params(dc) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| check_array_subscript(expr) | ||||
| 	register struct expr *expr; | ||||
| void check_array_subscript(register struct expr *expr) | ||||
| { | ||||
| 	arith size = expr->VL_VALUE; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										28
									
								
								lang/cem/cemcom.ansi/declarator.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lang/cem/cemcom.ansi/declarator.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef DECLARATOR_H_ | ||||
| #define DECLARATOR_H_ | ||||
| 
 | ||||
| #include "arith.h" | ||||
| 
 | ||||
| /* Forward declarations. */ | ||||
| struct type; | ||||
| struct declarator; | ||||
| struct formal; | ||||
| struct proto; | ||||
| struct expr; | ||||
| 
 | ||||
| struct type * | ||||
| declare_type(struct type *tp, struct declarator *dc); | ||||
| void add_decl_unary(register struct declarator *dc, int fund, int qual, | ||||
| 		arith count, struct formal *fm, struct proto *pl); | ||||
| void remove_declarator(struct declarator *dc); | ||||
| void reject_params(register struct declarator *dc); | ||||
| void check_array_subscript(register struct expr *expr); | ||||
| 
 | ||||
| #endif /* DECLARATOR_H_ */ | ||||
|  | @ -6,12 +6,13 @@ | |||
| /*	D E C L A R A T I O N   S P E C I F I E R   C H E C K I N G	*/ | ||||
| 
 | ||||
| #include	<assert.h> | ||||
| #include	"Lpars.h" | ||||
| #include	"decspecs.h" | ||||
| #include	"Lpars.h" | ||||
| #include	"arith.h" | ||||
| #include	"type.h" | ||||
| #include	"level.h" | ||||
| #include	"def.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
| extern int level; | ||||
|  | @ -20,36 +21,35 @@ extern struct type *qualifier_type(); | |||
| 
 | ||||
| struct decspecs null_decspecs; | ||||
| 
 | ||||
| do_decspecs(ds) | ||||
| 	register struct decspecs *ds; | ||||
| void do_decspecs(register struct decspecs *ds) | ||||
| { | ||||
| 	/*	The provisional decspecs ds as obtained from the program
 | ||||
| 		is turned into a legal consistent decspecs. | ||||
| 	*/ | ||||
| 	 is turned into a legal consistent decspecs. | ||||
| 	 */ | ||||
| 	register struct type *tp = ds->ds_type; | ||||
| 
 | ||||
| 	assert(level != L_FORMAL1); | ||||
| 
 | ||||
| 	if (	level == L_GLOBAL && | ||||
| 		(ds->ds_sc == AUTO || ds->ds_sc == REGISTER) | ||||
| 	)	{ | ||||
| 		error("no global %s variable allowed", | ||||
| 			symbol2str(ds->ds_sc)); | ||||
| 	if (level == L_GLOBAL && (ds->ds_sc == AUTO || ds->ds_sc == REGISTER)) | ||||
| 	{ | ||||
| 		error("no global %s variable allowed", symbol2str(ds->ds_sc)); | ||||
| 		ds->ds_sc = GLOBAL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (level == L_FORMAL2)	{ | ||||
| 		if (ds->ds_sc_given && | ||||
| 		    ds->ds_sc != REGISTER){ | ||||
| 	if (level == L_FORMAL2) | ||||
| 	{ | ||||
| 		if (ds->ds_sc_given && ds->ds_sc != REGISTER) | ||||
| 		{ | ||||
| 			error("%s formal illegal", symbol2str(ds->ds_sc)); | ||||
| 			ds->ds_sc = FORMAL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*	Since type qualifiers may be associated with types by means
 | ||||
| 		of typedefs, we have to perform same basic tests down here. | ||||
| 	*/ | ||||
| 	if (tp != (struct type *)0) { | ||||
| 	 of typedefs, we have to perform same basic tests down here. | ||||
| 	 */ | ||||
| 	if (tp != (struct type *) 0) | ||||
| 	{ | ||||
| 		if ((ds->ds_typequal & TQ_VOLATILE) && (tp->tp_typequal & TQ_VOLATILE)) | ||||
| 			error("indirect repeated type qualifier"); | ||||
| 		if ((ds->ds_typequal & TQ_CONST) && (tp->tp_typequal & TQ_CONST)) | ||||
|  | @ -58,49 +58,74 @@ do_decspecs(ds) | |||
| 	} | ||||
| 
 | ||||
| 	/*	The tests concerning types require a full knowledge of the
 | ||||
| 		type and will have to be postponed to declare_idf. | ||||
| 	*/ | ||||
| 	 type and will have to be postponed to declare_idf. | ||||
| 	 */ | ||||
| 
 | ||||
| 	/* some adjustments as described in 3.5.2. */ | ||||
| 	if (tp == 0) { | ||||
| 	if (tp == 0) | ||||
| 	{ | ||||
| 		ds->ds_notypegiven = 1; | ||||
| 		tp = int_type; | ||||
| 	} | ||||
| 	if (ds->ds_size) { | ||||
| 	if (ds->ds_size) | ||||
| 	{ | ||||
| 		register int ds_isshort = (ds->ds_size == SHORT); | ||||
| 
 | ||||
| 		if (ds->ds_typedef) goto SIZE_ERROR;		/* yes */ | ||||
| 		if (tp == int_type) { | ||||
| 			if (ds_isshort) tp = short_type; | ||||
| 			else tp = long_type; | ||||
| 		} else if (tp == double_type && !ds_isshort ) { | ||||
| 		if (ds->ds_typedef) | ||||
| 			goto SIZE_ERROR; | ||||
| 		/* yes */ | ||||
| 		if (tp == int_type) | ||||
| 		{ | ||||
| 			if (ds_isshort) | ||||
| 				tp = short_type; | ||||
| 			else | ||||
| 				tp = long_type; | ||||
| 		} | ||||
| 		else if (tp == double_type && !ds_isshort) | ||||
| 		{ | ||||
| 			tp = lngdbl_type; | ||||
| 		} else { | ||||
| 	SIZE_ERROR: | ||||
| 			error("%s with illegal type",symbol2str(ds->ds_size)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			SIZE_ERROR: error("%s with illegal type", symbol2str(ds->ds_size)); | ||||
| 		} | ||||
| 		ds->ds_notypegiven = 0; | ||||
| 	} | ||||
| 	if (ds->ds_unsigned) { | ||||
| 	if (ds->ds_unsigned) | ||||
| 	{ | ||||
| 		register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED); | ||||
| 
 | ||||
| 		if (ds->ds_typedef) goto SIGN_ERROR;		/* yes */ | ||||
| 		if (ds->ds_typedef) | ||||
| 			goto SIGN_ERROR; | ||||
| 		/* yes */ | ||||
| 		/*
 | ||||
| 		 * All integral types are signed by default (char too), | ||||
| 		 * so the case that ds->ds_unsigned == SIGNED can be ignored. | ||||
| 		 */ | ||||
| 		if (tp == schar_type) { | ||||
| 			if (ds_isunsigned) tp = uchar_type; | ||||
| 		} else if (tp == short_type) { | ||||
| 			if (ds_isunsigned) tp = ushort_type; | ||||
| 		} else if (tp == int_type) { | ||||
| 			if (ds_isunsigned) tp = uint_type; | ||||
| 		} else if (tp == long_type) { | ||||
| 			if (ds_isunsigned) tp = ulong_type; | ||||
| 		} else { | ||||
| 	SIGN_ERROR: | ||||
| 			error("%s with illegal type" | ||||
| 				, symbol2str(ds->ds_unsigned)); | ||||
| 		if (tp == schar_type) | ||||
| 		{ | ||||
| 			if (ds_isunsigned) | ||||
| 				tp = uchar_type; | ||||
| 		} | ||||
| 		else if (tp == short_type) | ||||
| 		{ | ||||
| 			if (ds_isunsigned) | ||||
| 				tp = ushort_type; | ||||
| 		} | ||||
| 		else if (tp == int_type) | ||||
| 		{ | ||||
| 			if (ds_isunsigned) | ||||
| 				tp = uint_type; | ||||
| 		} | ||||
| 		else if (tp == long_type) | ||||
| 		{ | ||||
| 			if (ds_isunsigned) | ||||
| 				tp = ulong_type; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			SIGN_ERROR: error("%s with illegal type", | ||||
| 					symbol2str(ds->ds_unsigned)); | ||||
| 		} | ||||
| 		ds->ds_notypegiven = 0; | ||||
| 	} | ||||
|  | @ -108,15 +133,12 @@ do_decspecs(ds) | |||
| } | ||||
| 
 | ||||
| /*	Make tp into a qualified type. This is not as trivial as it
 | ||||
| 	may seem. If tp is a fundamental type the qualified type is | ||||
| 	either existent or will be generated. | ||||
| 	In case of a complex type the top of the type list will be | ||||
| 	replaced by a qualified version. | ||||
| */ | ||||
| struct type * | ||||
| qualifier_type(tp, typequal) | ||||
| 	register struct type *tp; | ||||
| 	int typequal; | ||||
|  may seem. If tp is a fundamental type the qualified type is | ||||
|  either existent or will be generated. | ||||
|  In case of a complex type the top of the type list will be | ||||
|  replaced by a qualified version. | ||||
|  */ | ||||
| struct type *qualifier_type(register struct type *tp, int typequal) | ||||
| { | ||||
| 	register struct type *dtp = tp; | ||||
| 	register int fund = tp->tp_fund; | ||||
|  | @ -124,32 +146,34 @@ qualifier_type(tp, typequal) | |||
| 	while (dtp && dtp->tp_typequal != typequal) | ||||
| 		dtp = dtp->next; | ||||
| 
 | ||||
| 	if (!dtp) { | ||||
| 	if (!dtp) | ||||
| 	{ | ||||
| 		dtp = create_type(fund); | ||||
| 		dtp->tp_unsigned = tp->tp_unsigned; | ||||
| 		dtp->tp_align = tp->tp_align; | ||||
| 		dtp->tp_typequal = typequal; | ||||
| 		dtp->tp_size = tp->tp_size; | ||||
| #if 0 | ||||
| /* The tp_function field does not exist now. See the comment in the
 | ||||
|    function_of() routine. | ||||
| */ | ||||
| 		/* The tp_function field does not exist now. See the comment in the
 | ||||
| 		 function_of() routine. | ||||
| 		 */ | ||||
| 		dtp->tp_function = tp->tp_function; | ||||
| #endif | ||||
| 		switch (fund) { | ||||
| 		switch (fund) | ||||
| 		{ | ||||
| 		case ARRAY: | ||||
| 			if (typequal) { | ||||
| 			    tp->tp_up = qualifier_type(tp->tp_up, typequal); | ||||
| 			    dtp->tp_typequal = typequal = 0; | ||||
| 			if (typequal) | ||||
| 			{ | ||||
| 				tp->tp_up = qualifier_type(tp->tp_up, typequal); | ||||
| 				dtp->tp_typequal = typequal = 0; | ||||
| 			} | ||||
| 			goto nottagged; | ||||
| 		case FIELD: | ||||
| 			dtp->tp_field = tp->tp_field; | ||||
| 			/* fallthrough */ | ||||
| 		case POINTER: | ||||
| 		case FUNCTION:			/* dont't assign tp_proto */ | ||||
| 		nottagged: | ||||
| 			dtp->tp_up = tp->tp_up; | ||||
| 		case FUNCTION: /* dont't assign tp_proto */ | ||||
| 			nottagged: dtp->tp_up = tp->tp_up; | ||||
| 			break; | ||||
| 		case STRUCT: | ||||
| 		case UNION: | ||||
|  | @ -163,6 +187,6 @@ qualifier_type(tp, typequal) | |||
| 		dtp->next = tp->next; /* don't know head or tail */ | ||||
| 		tp->next = dtp; | ||||
| 	} | ||||
| 	return(dtp); | ||||
| 	return (dtp); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef DECSPECS_H_ | ||||
| #define DECSPECS_H_ | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| /* DECLARATION SPECIFIER DEFINITION */ | ||||
| 
 | ||||
|  | @ -19,3 +22,10 @@ struct decspecs	{ | |||
| 
 | ||||
| extern struct type *qualifier_type(); | ||||
| extern struct decspecs null_decspecs; | ||||
| 
 | ||||
| struct type; | ||||
| 
 | ||||
| void do_decspecs(register struct decspecs *ds); | ||||
| struct type *qualifier_type(register struct type *tp, int typequal); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef DEF_H_ | ||||
| #define DEF_H_ | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| /* IDENTIFIER DEFINITION DESCRIPTOR */ | ||||
| 
 | ||||
|  | @ -38,3 +41,5 @@ struct def	{		/* for ordinary tags */ | |||
| #define REG_BONUS	10	/* register candidate, declared as such */ | ||||
| 
 | ||||
| /* ALLOCDEF "def" 50 */ | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -8,12 +8,17 @@ | |||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include "domacro.h" | ||||
| #include "parameters.h" | ||||
| #include "idf.h" | ||||
| #include "interface.h" | ||||
| #include "arith.h" | ||||
| #include "LLlex.h" | ||||
| #include "Lpars.h" | ||||
| #include "input.h" | ||||
| #include "pragma.h" | ||||
| #include "skip.h" | ||||
| #include "error.h" | ||||
| 
 | ||||
| #ifdef DBSYMTAB | ||||
| #include <stb.h> | ||||
|  | @ -23,7 +28,9 @@ int IncludeLevel = 0; | |||
| 
 | ||||
| extern char options[]; | ||||
| 
 | ||||
| struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */ | ||||
| static void do_line(unsigned int); | ||||
| 
 | ||||
| struct idf* GetIdentifier(int skiponerr) /* skip the rest of the line on error */ | ||||
| { | ||||
| 	/*	returns a pointer to the descriptor of the identifier that is
 | ||||
| 	    read from the input stream. When the input does not contain | ||||
|  | @ -44,7 +51,7 @@ struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line | |||
| 	return tk.tk_idf; | ||||
| } | ||||
| 
 | ||||
| domacro() | ||||
| void domacro(void) | ||||
| { | ||||
| 	int tok; | ||||
| 	struct token tk; | ||||
|  | @ -70,7 +77,7 @@ domacro() | |||
| 	SkipToNewLine(); | ||||
| } | ||||
| 
 | ||||
| do_line(l) unsigned int l; | ||||
| static void do_line(unsigned int l) | ||||
| { | ||||
| 	struct token tk; | ||||
| 	int t = GetToken(&tk); | ||||
|  |  | |||
							
								
								
									
										16
									
								
								lang/cem/cemcom.ansi/domacro.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								lang/cem/cemcom.ansi/domacro.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef DOMACRO_H_ | ||||
| #define DOMACRO_H_ | ||||
| 
 | ||||
| struct idf; | ||||
| 
 | ||||
| struct idf* GetIdentifier(int skiponerr) ; | ||||
| void domacro(void); | ||||
| 
 | ||||
| #endif /* DOMACRO_H_ */ | ||||
|  | @ -6,6 +6,7 @@ | |||
| /*	E R R O R   A N D  D I A G N O S T I C   R O U T I N E S	*/ | ||||
| 
 | ||||
| #include	"parameters.h" | ||||
| #include    "error.h" | ||||
| #if __STDC__ | ||||
| #include	<stdarg.h> | ||||
| #else | ||||
|  | @ -17,13 +18,15 @@ | |||
| #else | ||||
| #include	"l_em.h" | ||||
| #endif	/* LINT */ | ||||
| 
 | ||||
| #include    <stdio.h> | ||||
| #include	"tokenname.h" | ||||
| #include	<flt_arith.h> | ||||
| #include    "interface.h" | ||||
| #include	"arith.h" | ||||
| #include	"label.h" | ||||
| #include	"expr.h" | ||||
| #include	"def.h" | ||||
| #include    "print.h" | ||||
| #include	"LLlex.h" | ||||
| 
 | ||||
| /*	This file contains the error-message and diagnostic
 | ||||
|  | @ -56,12 +59,11 @@ extern char loptions[]; | |||
| 	FileName, expression errors get their information from the | ||||
| 	expression, whereas other errors use the information in the token. | ||||
| */ | ||||
| 
 | ||||
| static void _error(); | ||||
| static void _error(int, char *, unsigned int, char*, va_list); | ||||
| 
 | ||||
| #if __STDC__ | ||||
| /*VARARGS*/ | ||||
| error(char *fmt, ...) | ||||
| void error(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -73,7 +75,7 @@ error(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| expr_error(struct expr *expr, char *fmt, ...) | ||||
| void expr_error(struct expr *expr, char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -89,7 +91,7 @@ expr_error(struct expr *expr, char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| lexstrict(char *fmt, ...) | ||||
| void lexstrict(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -101,7 +103,7 @@ lexstrict(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| strict(char *fmt, ...) | ||||
| void strict(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -113,7 +115,7 @@ strict(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| expr_strict(struct expr *expr, char *fmt, ...) | ||||
| void expr_strict(struct expr *expr, char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -129,7 +131,7 @@ expr_strict(struct expr *expr, char *fmt, ...) | |||
| 
 | ||||
| #ifdef DEBUG | ||||
| /*VARARGS*/ | ||||
| debug(char *fmt, ...) | ||||
| void debug(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -142,7 +144,7 @@ debug(char *fmt, ...) | |||
| #endif /* DEBUG */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| warning(char *fmt, ...) | ||||
| void warning(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -154,7 +156,7 @@ warning(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| expr_warning(struct expr *expr, char *fmt, ...) | ||||
| void expr_warning(struct expr *expr, char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -171,7 +173,7 @@ expr_warning(struct expr *expr, char *fmt, ...) | |||
| #ifdef	LINT | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| def_warning(struct def *def, char *fmt, ...) | ||||
| void def_warning(struct def *def, char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -184,7 +186,7 @@ def_warning(struct def *def, char *fmt, ...) | |||
| 
 | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| hwarning(char *fmt, ...) | ||||
| void hwarning(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -197,7 +199,7 @@ hwarning(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| awarning(char *fmt, ...) | ||||
| void awarning(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -212,7 +214,7 @@ awarning(char *fmt, ...) | |||
| #endif	/* LINT */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| lexerror(char *fmt, ...) | ||||
| void lexerror(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -224,7 +226,7 @@ lexerror(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| lexwarning(char *fmt, ...) | ||||
| void lexwarning(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -236,7 +238,7 @@ lexwarning(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| crash(char *fmt, ...) | ||||
| void crash(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -256,7 +258,7 @@ crash(char *fmt, ...) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| fatal(char *fmt, ...) | ||||
| void fatal(char *fmt, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 
 | ||||
|  | @ -272,7 +274,7 @@ fatal(char *fmt, ...) | |||
| } | ||||
| #else | ||||
| /*VARARGS*/ | ||||
| error(va_alist)				/* fmt, args */ | ||||
| void error(va_alist)				/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -286,7 +288,7 @@ error(va_alist)				/* fmt, args */ | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| expr_error(va_alist)			/* expr, fmt, args */ | ||||
| void expr_error(va_alist)			/* expr, fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -306,7 +308,7 @@ expr_error(va_alist)			/* expr, fmt, args */ | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| lexstrict(va_alist) | ||||
| void lexstrict(va_alist) | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -320,7 +322,7 @@ lexstrict(va_alist) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| strict(va_alist) | ||||
| void strict(va_alist) | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -334,7 +336,7 @@ strict(va_alist) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| expr_strict(va_alist)			/* expr, fmt, args */ | ||||
| void expr_strict(va_alist)			/* expr, fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -354,7 +356,7 @@ expr_strict(va_alist)			/* expr, fmt, args */ | |||
| 
 | ||||
| #ifdef DEBUG | ||||
| /*VARARGS*/ | ||||
| debug(va_alist) | ||||
| void debug(va_alist) | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -369,7 +371,7 @@ debug(va_alist) | |||
| #endif /* DEBUG */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| warning(va_alist) | ||||
| void warning(va_alist) | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -383,7 +385,7 @@ warning(va_alist) | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| expr_warning(va_alist)			/* expr, fmt, args */ | ||||
| void expr_warning(va_alist)			/* expr, fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -404,7 +406,7 @@ expr_warning(va_alist)			/* expr, fmt, args */ | |||
| #ifdef	LINT | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| def_warning(va_alist)			/* def, fmt, args */ | ||||
| void def_warning(va_alist)			/* def, fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -421,7 +423,7 @@ def_warning(va_alist)			/* def, fmt, args */ | |||
| 
 | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| hwarning(va_alist)			/* fmt, args */ | ||||
| void hwarning(va_alist)			/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -436,7 +438,7 @@ hwarning(va_alist)			/* fmt, args */ | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| awarning(va_alist)			/* fmt, args */ | ||||
| void awarning(va_alist)			/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -453,7 +455,7 @@ awarning(va_alist)			/* fmt, args */ | |||
| #endif	/* LINT */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| lexerror(va_alist)			/* fmt, args */ | ||||
| void lexerror(va_alist)			/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -467,7 +469,7 @@ lexerror(va_alist)			/* fmt, args */ | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| lexwarning(va_alist)			/* fmt, args */ | ||||
| void lexwarning(va_alist)			/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -481,7 +483,7 @@ lexwarning(va_alist)			/* fmt, args */ | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| crash(va_alist)				/* fmt, args */ | ||||
| void crash(va_alist)				/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -503,7 +505,7 @@ crash(va_alist)				/* fmt, args */ | |||
| } | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| fatal(va_alist)				/* fmt, args */ | ||||
| void fatal(va_alist)				/* fmt, args */ | ||||
| 	va_dcl | ||||
| { | ||||
| 	va_list ap; | ||||
|  | @ -521,13 +523,7 @@ fatal(va_alist)				/* fmt, args */ | |||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void | ||||
| _error(class, fn, ln, fmt, ap) | ||||
| 	int class; | ||||
| 	char *fn; | ||||
| 	unsigned int ln; | ||||
| 	char *fmt; | ||||
| 	va_list ap; | ||||
| static void _error(int class, char *fn, unsigned int ln, char* fmt, va_list ap) | ||||
| { | ||||
| 	char *remark; | ||||
| 	 | ||||
|  | @ -614,9 +610,9 @@ _error(class, fn, ln, fmt, ap) | |||
| #endif	/* LINT */ | ||||
| 	 | ||||
| 	if (fn) | ||||
| 		fprint(ERROUT, "\"%s\", line %u: ", fn, ln); | ||||
| 		fprint(stderr, "\"%s\", line %u: ", fn, ln); | ||||
| 	if (remark) | ||||
| 		fprint(ERROUT, "%s ", remark); | ||||
| 	doprnt(ERROUT, fmt, ap);		/* contents of error */ | ||||
| 	fprint(ERROUT, "\n"); | ||||
| 		fprint(stderr, "%s ", remark); | ||||
| 	doprnt(stderr, fmt, ap);		/* contents of error */ | ||||
| 	fprint(stderr, "\n"); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										94
									
								
								lang/cem/cemcom.ansi/error.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								lang/cem/cemcom.ansi/error.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef ERROR_H_ | ||||
| #define ERROR_H_ | ||||
| 
 | ||||
| struct expr; | ||||
| 
 | ||||
| #if __STDC__ | ||||
| /*VARARGS*/ | ||||
| void error(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void expr_error(struct expr *expr, char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void lexstrict(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void strict(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void expr_strict(struct expr *expr, char *fmt, ...); | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| /*VARARGS*/ | ||||
| void debug(char *fmt, ...); | ||||
| #endif /* DEBUG */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| void warning(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void expr_warning(struct expr *expr, char *fmt, ...); | ||||
| #ifdef	LINT | ||||
| /*VARARGS*/ | ||||
| void def_warning(struct def *def, char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void hwarning(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void awarning(char *fmt, ...); | ||||
| #endif	/* LINT */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| void lexerror(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void lexwarning(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void crash(char *fmt, ...); | ||||
| /*VARARGS*/ | ||||
| void fatal(char *fmt, ...); | ||||
| 
 | ||||
| #else | ||||
| /*VARARGS*/ | ||||
| void error(va_alist);				/* fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void expr_error(va_alist);			/* expr, fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void lexstrict(va_alist); | ||||
| /*VARARGS*/ | ||||
| void strict(va_alist); | ||||
| /*VARARGS*/ | ||||
| void expr_strict(va_alist);			/* expr, fmt, args */ | ||||
| #ifdef DEBUG | ||||
| /*VARARGS*/ | ||||
| void debug(va_alist); | ||||
| #endif /* DEBUG */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| void warning(va_alist); | ||||
| /*VARARGS*/ | ||||
| void expr_warning(va_alist);			/* expr, fmt, args */ | ||||
| #ifdef	LINT | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| void def_warning(va_alist);			/* def, fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void hwarning(va_alist);			/* fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void awarning(va_alist);			/* fmt, args */ | ||||
| #endif	/* LINT */ | ||||
| 
 | ||||
| /*VARARGS*/ | ||||
| void lexerror(va_alist);			/* fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void lexwarning(va_alist);			/* fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void crash(va_alist);				/* fmt, args */ | ||||
| /*VARARGS*/ | ||||
| void fatal(va_alist);				/* fmt, args */ | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif /* ERROR_H_ */ | ||||
|  | @ -2,6 +2,9 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
|  #ifndef ESTACK_H_ | ||||
|  #define ESTACK_H_ | ||||
|   | ||||
| /* $Id$ */ | ||||
| /* EXPRESSION STACK */ | ||||
| /* Used for global initializations */ | ||||
|  | @ -19,3 +22,5 @@ struct e_stack { | |||
| #define last_offset	s_cnt2 | ||||
| #define elem_count	s_cnt1 | ||||
| #define nelem		s_cnt2 | ||||
| 
 | ||||
| #endif | ||||
|  | @ -14,6 +14,8 @@ | |||
| #include	<em_reg.h> | ||||
| #include	<alloc.h> | ||||
| #include	<flt_arith.h> | ||||
| #include    "interface.h" | ||||
| #include    "eval.h" | ||||
| #include    "idf.h" | ||||
| #include	"arith.h" | ||||
| #include	"type.h" | ||||
|  | @ -22,13 +24,21 @@ | |||
| #include	"def.h" | ||||
| #include	"expr.h" | ||||
| #include	"sizes.h" | ||||
| #include    "field.h" | ||||
| #include	"Lpars.h" | ||||
| #include	"level.h" | ||||
| #include    "conversion.h" | ||||
| #include	"stack.h" | ||||
| #include    "struct.h" | ||||
| #include	"align.h" | ||||
| #include	"mes.h" | ||||
| #include	"atw.h" | ||||
| #include    "ch3.h" | ||||
| #include    "util.h" | ||||
| #include    "blocks.h" | ||||
| #include    "dataflow.h" | ||||
| #include	"specials.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| #define	CRASH()		crash("EVAL: CRASH at line %u", __LINE__) | ||||
| 
 | ||||
|  | @ -37,8 +47,12 @@ arith NewLocal();	/* util.c */ | |||
| #define LocalPtrVar()	NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER) | ||||
| extern int	err_occurred; /* error.c */ | ||||
| 
 | ||||
| void store_val(); | ||||
| void load_val(); | ||||
| 
 | ||||
| /* Forward internal declarations */ | ||||
| static void operands(register struct expr *, int); | ||||
| static void ptr_add(arith size); | ||||
| static void truthvalue(int relop); | ||||
| static void compare(int relop, label lbl); | ||||
| 
 | ||||
| /*	EVAL() is the main expression-tree evaluator, which turns
 | ||||
| 	any legal expression tree into EM code. parameters.h: | ||||
|  | @ -66,11 +80,7 @@ void load_val(); | |||
| 		labels, in case they are specified (i.e. are non-zero) | ||||
| */ | ||||
| 
 | ||||
| void | ||||
| EVAL(expr, val, code, true_label, false_label) | ||||
| 	register struct expr *expr; | ||||
| 	int val, code; | ||||
| 	label true_label, false_label; | ||||
| void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label) | ||||
| { | ||||
| 	int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE)); | ||||
| 	register int gencode = code == TRUE; | ||||
|  | @ -659,9 +669,7 @@ EVAL(expr, val, code, true_label, false_label) | |||
| } | ||||
| 
 | ||||
| /*	compare() serves as an auxiliary function of EVAL	*/ | ||||
| compare(relop, lbl) | ||||
| 	int relop; | ||||
| 	label lbl; | ||||
| static void compare(int relop, label lbl) | ||||
| { | ||||
| 	switch (relop) { | ||||
| 	case '<': | ||||
|  | @ -688,8 +696,7 @@ compare(relop, lbl) | |||
| } | ||||
| 
 | ||||
| /*	truthvalue() serves as an auxiliary function of EVAL	*/ | ||||
| truthvalue(relop) | ||||
| 	int relop; | ||||
| static void truthvalue(int relop) | ||||
| { | ||||
| 	switch (relop)	{ | ||||
| 	case '<': | ||||
|  | @ -717,12 +724,10 @@ truthvalue(relop) | |||
| 
 | ||||
| 
 | ||||
| /*	assop() generates the opcode of an assignment operators op=	*/ | ||||
| assop(type, oper) | ||||
| 	register struct type *type; | ||||
| 	int oper; | ||||
| void assop(register struct type *type, int oper) | ||||
| { | ||||
| 	register arith size; | ||||
| 	register uns = type->tp_unsigned; | ||||
| 	register int uns = type->tp_unsigned; | ||||
| 
 | ||||
| 	if ((int)(size = type->tp_size) < (int)word_size) | ||||
| 		size = word_size; | ||||
|  | @ -822,8 +827,7 @@ assop(type, oper) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| ptr_add(size) | ||||
| 	arith size; | ||||
| static void ptr_add(arith size) | ||||
| { | ||||
| 	if (size != pointer_size) { | ||||
| 		C_loc(size); | ||||
|  | @ -840,10 +844,7 @@ ptr_add(size) | |||
| 	- into a local static variable | ||||
| 	- absolute addressing | ||||
| */ | ||||
| void | ||||
| store_val(vl, tp) | ||||
| 	register struct value *vl; | ||||
| 	register struct type *tp; | ||||
| void store_val(register struct value *vl, register struct type *tp) | ||||
| { | ||||
| 	register int inword = 0; | ||||
| 	register int indword = 0; | ||||
|  | @ -911,11 +912,10 @@ store_val(vl, tp) | |||
| 	- global variable | ||||
| 	- static variable | ||||
| 	- local variable | ||||
| 
 | ||||
| 	rlval generate rlval or lval | ||||
| */ | ||||
| void | ||||
| load_val(expr, rlval) | ||||
| 	register struct expr *expr; /* expression containing the value	*/ | ||||
| 	int rlval;		/* generate either LVAL or RVAL		*/ | ||||
| void load_val(register struct expr *expr, int rlval) | ||||
| { | ||||
| 	register struct type *tp = expr->ex_type; | ||||
| 	int rvalue = (rlval == RVAL && expr->ex_lvalue != 0); | ||||
|  | @ -1012,8 +1012,7 @@ load_val(expr, rlval) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| load_cst(val, siz) | ||||
| 	arith val, siz; | ||||
| void load_cst(arith val, arith siz) | ||||
| { | ||||
| 	if ((int)siz <= (int)word_size) | ||||
| 		C_loc(val); | ||||
|  | @ -1030,8 +1029,7 @@ load_cst(val, siz) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| operands(expr, gencode) | ||||
| 	register struct expr *expr; | ||||
| static void operands(register struct expr *expr, int gencode) | ||||
| { | ||||
| 	EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL); | ||||
| 	EVAL(expr->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL); | ||||
|  |  | |||
							
								
								
									
										37
									
								
								lang/cem/cemcom.ansi/eval.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lang/cem/cemcom.ansi/eval.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-06 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef EVAL_H_ | ||||
| #define EVAL_H_ | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| 
 | ||||
| 
 | ||||
| #include <em.h> | ||||
| 
 | ||||
| struct expr; | ||||
| struct value; | ||||
| struct type; | ||||
| 
 | ||||
| void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label); | ||||
| 
 | ||||
| /*	assop() generates the opcode of an assignment operators op=	*/ | ||||
| void assop(register struct type *type, int oper); | ||||
| /*	store_val() generates code for a store operation.
 | ||||
| 	There are four ways of storing data: | ||||
| 	- into a global variable | ||||
| 	- into an automatic local variable | ||||
| 	- into a local static variable | ||||
| 	- absolute addressing | ||||
| */ | ||||
| void store_val(register struct value *vl, register struct type *tp); | ||||
| void load_val(register struct expr *expr, int rlval); | ||||
| void load_cst(arith val, arith siz); | ||||
| 
 | ||||
| #endif /* LINT */ | ||||
| 
 | ||||
| #endif /* EVAL_H_ */ | ||||
|  | @ -10,6 +10,7 @@ | |||
| #include	"parameters.h" | ||||
| #include	<alloc.h> | ||||
| #include	<flt_arith.h> | ||||
| #include    "expr.h" | ||||
| #include    "idf.h" | ||||
| #include	"arith.h" | ||||
| #include	"def.h" | ||||
|  | @ -22,20 +23,21 @@ | |||
| #include	"declar.h" | ||||
| #include	"sizes.h" | ||||
| #include	"level.h" | ||||
| #include    "cstoper.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| extern char *symbol2str(); | ||||
| extern char options[]; | ||||
| extern int InSizeof; | ||||
| 
 | ||||
| int | ||||
| rank_of(oper) | ||||
| 	int oper; | ||||
| int rank_of(int oper) | ||||
| { | ||||
| 	/*	The rank of the operator oper is returned.
 | ||||
| 	*/ | ||||
| 	switch (oper)	{ | ||||
| 	 */ | ||||
| 	switch (oper) | ||||
| 	{ | ||||
| 	default: | ||||
| 		return 0;			/* INT2INT etc. */ | ||||
| 		return 0; /* INT2INT etc. */ | ||||
| 	case '[': | ||||
| 	case '(': | ||||
| 	case '.': | ||||
|  | @ -48,7 +50,7 @@ rank_of(oper) | |||
| 	case CAST: | ||||
| 	case SIZEOF: | ||||
| 	case ADDRESSOF: | ||||
| 		return 2;			/* monadic */ | ||||
| 		return 2; /* monadic */ | ||||
| 	case '*': | ||||
| 	case '/': | ||||
| 	case '%': | ||||
|  | @ -98,18 +100,18 @@ rank_of(oper) | |||
| 	/*NOTREACHED*/ | ||||
| } | ||||
| 
 | ||||
| dot2expr(expp) | ||||
| 	struct expr **expp; | ||||
| void dot2expr(struct expr **expp) | ||||
| { | ||||
| 	/*	The token in dot is converted into an expression, a
 | ||||
| 		pointer to which is stored in *expp. | ||||
| 	*/ | ||||
| 	 pointer to which is stored in *expp. | ||||
| 	 */ | ||||
| 	register struct expr *ex = new_expr(); | ||||
| 
 | ||||
| 	*expp = ex; | ||||
| 	ex->ex_file = dot.tk_file; | ||||
| 	ex->ex_line = dot.tk_line; | ||||
| 	switch (DOT)	{ | ||||
| 	switch (DOT) | ||||
| 	{ | ||||
| 	case IDENTIFIER: | ||||
| 		idf2expr(ex); | ||||
| 		break; | ||||
|  | @ -125,25 +127,27 @@ dot2expr(expp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| idf2expr(expr) | ||||
| 	register struct expr *expr; | ||||
| void idf2expr(register struct expr *expr) | ||||
| { | ||||
| 	/*	Dot contains an identifier which is turned into an
 | ||||
| 		expression. | ||||
| 		Note that this constitutes an applied occurrence of | ||||
| 		the identifier. | ||||
| 	*/ | ||||
| 	register struct idf *idf = dot.tk_idf;	/* != 0*/ | ||||
| 	 expression. | ||||
| 	 Note that this constitutes an applied occurrence of | ||||
| 	 the identifier. | ||||
| 	 */ | ||||
| 	register struct idf *idf = dot.tk_idf; /* != 0*/ | ||||
| 	register struct def *def = idf->id_def; | ||||
| 
 | ||||
| 	if (def == 0)	{ | ||||
| 		if (AHEAD == '(') { | ||||
| 	if (def == 0) | ||||
| 	{ | ||||
| 		if (AHEAD == '(') | ||||
| 		{ | ||||
| 			/* function call, declare name implicitly (3.3.2.2) */ | ||||
| 			if (!options['o']) | ||||
| 				warning("implicit declaration of function %s" | ||||
| 					, idf->id_text); | ||||
| 				warning("implicit declaration of function %s", idf->id_text); | ||||
| 			add_def(idf, EXTERN, funint_type, level); | ||||
| 		} else	{ | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (!is_anon_idf(idf)) | ||||
| 				error("%s undefined", idf->id_text); | ||||
| 			/* declare idf anyway */ | ||||
|  | @ -153,8 +157,10 @@ idf2expr(expr) | |||
| 	} | ||||
| 	/* now def != 0 */ | ||||
| #ifndef	LINT | ||||
| 	if (!InSizeof) { | ||||
| 		if (! def->df_used) { | ||||
| 	if (!InSizeof) | ||||
| 	{ | ||||
| 		if (!def->df_used) | ||||
| 		{ | ||||
| #ifndef PREPEND_SCOPES | ||||
| 			code_scope(idf->id_text, def); | ||||
| #endif /* PREPEND_SCOPES */ | ||||
|  | @ -163,46 +169,45 @@ idf2expr(expr) | |||
| 	} | ||||
| #endif	/* LINT */ | ||||
| 	expr->ex_type = def->df_type; | ||||
| 	if (expr->ex_type == error_type) { | ||||
| 	if (expr->ex_type == error_type) | ||||
| 	{ | ||||
| 		expr->ex_flags |= EX_ERROR; | ||||
| 	} | ||||
| 	expr->ex_lvalue = | ||||
| 		(	def->df_type->tp_fund == FUNCTION || | ||||
| 			def->df_type->tp_fund == ARRAY || | ||||
| 			def->df_sc == ENUM | ||||
| 		) ? 0 : 1; | ||||
| 			(def->df_type->tp_fund == FUNCTION || def->df_type->tp_fund == ARRAY | ||||
| 					|| def->df_sc == ENUM) ? 0 : 1; | ||||
| 	if (def->df_type->tp_typequal & TQ_CONST) | ||||
| 		expr->ex_flags |= EX_READONLY; | ||||
| 	if (def->df_type->tp_typequal & TQ_VOLATILE) | ||||
| 		expr->ex_flags |= EX_VOLATILE; | ||||
| 	expr->ex_class = Value; | ||||
| 	if (def->df_sc == ENUM)	{ | ||||
| 	if (def->df_sc == ENUM) | ||||
| 	{ | ||||
| 		expr->VL_CLASS = Const; | ||||
| 		expr->VL_VALUE = def->df_address; | ||||
| 	} | ||||
| #ifndef	LINT | ||||
| 	else | ||||
| 	if (def->df_sc == STATIC && def->df_level >= L_LOCAL) { | ||||
| 	else if (def->df_sc == STATIC && def->df_level >= L_LOCAL) | ||||
| 	{ | ||||
| 		expr->VL_CLASS = Label; | ||||
| 		expr->VL_LBL = def->df_address; | ||||
| 		expr->VL_VALUE = (arith)0; | ||||
| 		expr->VL_VALUE = (arith) 0; | ||||
| 	} | ||||
| #endif	/* LINT */ | ||||
| 	else { | ||||
| 	else | ||||
| 	{ | ||||
| 		expr->VL_CLASS = Name; | ||||
| 		expr->VL_IDF = idf; | ||||
| 		expr->VL_VALUE = (arith)0; | ||||
| 		expr->VL_VALUE = (arith) 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| string2expr(expp, str, len) | ||||
| 	register struct expr **expp; | ||||
| 	int len; | ||||
| 	char *str; | ||||
| void string2expr(register struct expr **expp, char *str, int len) | ||||
| 
 | ||||
| { | ||||
| 	/*	The string in the argument is converted into an expression,
 | ||||
| 		a pointer to which is stored in *expp. | ||||
| 	*/ | ||||
| 	 a pointer to which is stored in *expp. | ||||
| 	 */ | ||||
| 	register struct expr *ex = new_expr(); | ||||
| 
 | ||||
| 	*expp = ex; | ||||
|  | @ -217,25 +222,24 @@ string2expr(expp, str, len) | |||
| 	ex->SG_LEN = len; | ||||
| } | ||||
| 
 | ||||
| int2expr(expr) | ||||
| 	struct expr *expr; | ||||
| void int2expr(struct expr *expr) | ||||
| { | ||||
| 	/*	Dot contains an integer constant which is turned
 | ||||
| 		into an expression. | ||||
| 	*/ | ||||
| 	 into an expression. | ||||
| 	 */ | ||||
| 	fill_int_expr(expr, dot.tk_ival, dot.tk_fund); | ||||
| } | ||||
| 
 | ||||
| float2expr(expr) | ||||
| 	register struct expr *expr; | ||||
| void float2expr(register struct expr *expr) | ||||
| { | ||||
| 	/*	Dot contains a floating point constant which is turned
 | ||||
| 		into an expression. | ||||
| 	*/ | ||||
| 	 into an expression. | ||||
| 	 */ | ||||
| 	register int fund; | ||||
| 
 | ||||
| 	fund = dot.tk_fund; | ||||
| 	switch (fund) { | ||||
| 	switch (fund) | ||||
| 	{ | ||||
| 	case FLOAT: | ||||
| 		expr->ex_type = float_type; | ||||
| 		break; | ||||
|  | @ -253,17 +257,15 @@ float2expr(expr) | |||
| 	free(dot.tk_fval); | ||||
| 	assert(flt_status != FLT_NOFLT); | ||||
| 	if (flt_status == FLT_OVFL) | ||||
| 		expr_warning(expr,"internal floating point overflow"); | ||||
| 		expr_warning(expr, "internal floating point overflow"); | ||||
| } | ||||
| 
 | ||||
| struct expr* | ||||
| intexpr(ivalue, fund) | ||||
| 	arith ivalue; | ||||
| 	int fund; | ||||
| struct expr*intexpr( | ||||
| arith ivalue, int fund) | ||||
| { | ||||
| 	/*	The value ivalue is turned into an integer expression of
 | ||||
| 		the size indicated by fund. | ||||
| 	*/ | ||||
| 	 the size indicated by fund. | ||||
| 	 */ | ||||
| 	register struct expr *expr = new_expr(); | ||||
| 
 | ||||
| 	expr->ex_file = dot.tk_file; | ||||
|  | @ -272,15 +274,14 @@ intexpr(ivalue, fund) | |||
| 	return expr; | ||||
| } | ||||
| 
 | ||||
| fill_int_expr(ex, ivalue, fund) | ||||
| 	register struct expr *ex; | ||||
| 	arith ivalue; | ||||
| 	int fund; | ||||
| void fill_int_expr(register struct expr *ex, | ||||
| arith ivalue, int fund) | ||||
| { | ||||
| 	/*	Details derived from ivalue and fund are put into the
 | ||||
| 		constant integer expression ex. | ||||
| 	*/ | ||||
| 	switch (fund) { | ||||
| 	 constant integer expression ex. | ||||
| 	 */ | ||||
| 	switch (fund) | ||||
| 	{ | ||||
| 	case INT: | ||||
| 		ex->ex_type = int_type; | ||||
| 		break; | ||||
|  | @ -288,7 +289,7 @@ fill_int_expr(ex, ivalue, fund) | |||
| 		ex->ex_type = uint_type; | ||||
| 		break; | ||||
| 	case LONG: | ||||
| 		ex->ex_type =  long_type; | ||||
| 		ex->ex_type = long_type; | ||||
| 		break; | ||||
| 	case ULONG: | ||||
| 		ex->ex_type = ulong_type; | ||||
|  | @ -303,21 +304,20 @@ fill_int_expr(ex, ivalue, fund) | |||
| 	cut_size(ex); | ||||
| } | ||||
| 
 | ||||
| struct expr * | ||||
| new_oper(tp, e1, oper, e2) | ||||
| 	struct type *tp; | ||||
| 	register struct expr *e1, *e2; | ||||
| struct expr *new_oper(struct type *tp, register struct expr *e1, int oper, | ||||
| 		register struct expr *e2) | ||||
| { | ||||
| 	/*	A new expression is constructed which consists of the
 | ||||
| 		operator oper which has e1 and e2 as operands; for a | ||||
| 		monadic operator e1 == NILEXPR. | ||||
| 		During the construction of the right recursive initialisation | ||||
| 		tree it is possible for e2 to be NILEXPR. | ||||
| 	*/ | ||||
| 	 operator oper which has e1 and e2 as operands; for a | ||||
| 	 monadic operator e1 == NILEXPR. | ||||
| 	 During the construction of the right recursive initialisation | ||||
| 	 tree it is possible for e2 to be NILEXPR. | ||||
| 	 */ | ||||
| 	register struct expr *expr = new_expr(); | ||||
| 	register struct oper *op; | ||||
| 
 | ||||
| 	if (e2)	{ | ||||
| 	if (e2) | ||||
| 	{ | ||||
| 		register struct expr *e = e2; | ||||
| 
 | ||||
| 		while (e->ex_class == Oper && e->OP_LEFT) | ||||
|  | @ -325,8 +325,8 @@ new_oper(tp, e1, oper, e2) | |||
| 		expr->ex_file = e->ex_file; | ||||
| 		expr->ex_line = e->ex_line; | ||||
| 	} | ||||
| 	else | ||||
| 	if (e1)	{ | ||||
| 	else if (e1) | ||||
| 	{ | ||||
| 		register struct expr *e = e1; | ||||
| 
 | ||||
| 		while (e->ex_class == Oper && e->OP_RIGHT) | ||||
|  | @ -334,7 +334,8 @@ new_oper(tp, e1, oper, e2) | |||
| 		expr->ex_file = e->ex_file; | ||||
| 		expr->ex_line = e->ex_line; | ||||
| 	} | ||||
| 	else	{ | ||||
| 	else | ||||
| 	{ | ||||
| 		expr->ex_file = dot.tk_file; | ||||
| 		expr->ex_line = dot.tk_line; | ||||
| 	} | ||||
|  | @ -342,20 +343,22 @@ new_oper(tp, e1, oper, e2) | |||
| 	expr->ex_type = tp; | ||||
| 	expr->ex_class = Oper; | ||||
| 	/* combine depths and flags of both expressions */ | ||||
| 	if (e2)	{ | ||||
| 	if (e2) | ||||
| 	{ | ||||
| 		int e1_depth = e1 ? e1->ex_depth : 0; | ||||
| 		int e1_flags = e1 ? e1->ex_flags : 0; | ||||
| 
 | ||||
| 		expr->ex_depth = | ||||
| 			(e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1; | ||||
| 		expr->ex_depth = (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) | ||||
| 				+ 1; | ||||
| 		expr->ex_flags = (e1_flags | e2->ex_flags) | ||||
| 			& ~(EX_PARENS | EX_READONLY | EX_VOLATILE ); | ||||
| 				& ~(EX_PARENS | EX_READONLY | EX_VOLATILE); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * A function call should be evaluated first when possible.  Just say | ||||
| 	 * that the expression tree is very deep. | ||||
| 	 */ | ||||
| 	if (oper == '(') { | ||||
| 	if (oper == '(') | ||||
| 	{ | ||||
| 		expr->ex_depth = 50; | ||||
| 	} | ||||
| 	op = &expr->ex_object.ex_oper; | ||||
|  | @ -369,42 +372,42 @@ new_oper(tp, e1, oper, e2) | |||
| 	return expr; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| chk_cst_expr(expp) | ||||
| 	struct expr **expp; | ||||
| void chk_cst_expr(struct expr **expp) | ||||
| { | ||||
| 	/*	The expression expr is checked for constancy.
 | ||||
| 
 | ||||
| 		There are 6 places where constant expressions occur in C: | ||||
| 		1.	after #if | ||||
| 		2.	in a global initialization | ||||
| 		3.	as size in an array declaration | ||||
| 		4.	as value in an enum declaration | ||||
| 		5.	as width in a bit field | ||||
| 		6.	as case value in a switch | ||||
| 	 There are 6 places where constant expressions occur in C: | ||||
| 	 1.	after #if | ||||
| 	 2.	in a global initialization | ||||
| 	 3.	as size in an array declaration | ||||
| 	 4.	as value in an enum declaration | ||||
| 	 5.	as width in a bit field | ||||
| 	 6.	as case value in a switch | ||||
| 
 | ||||
| 		The constant expression in a global initialization is | ||||
| 		handled separately (by IVAL()). | ||||
| 	 The constant expression in a global initialization is | ||||
| 	 handled separately (by IVAL()). | ||||
| 
 | ||||
| 		There are various disparate restrictions on each of | ||||
| 		the others in the various C compilers.  I have tried some | ||||
| 		hypotheses to unify them, but all have failed. | ||||
| 	 There are various disparate restrictions on each of | ||||
| 	 the others in the various C compilers.  I have tried some | ||||
| 	 hypotheses to unify them, but all have failed. | ||||
| 
 | ||||
| 		Special problems (of which there is only one, sizeof in | ||||
| 		Preprocessor #if) have to be dealt with locally | ||||
| 	*/ | ||||
| 	 Special problems (of which there is only one, sizeof in | ||||
| 	 Preprocessor #if) have to be dealt with locally | ||||
| 	 */ | ||||
| 	register struct expr *expr = *expp; | ||||
| 
 | ||||
| #ifdef	DEBUG | ||||
| 	print_expr("constant_expression", expr); | ||||
| #endif	/* DEBUG */ | ||||
| 	switch(expr->ex_type->tp_fund) { | ||||
| 	switch (expr->ex_type->tp_fund) | ||||
| 	{ | ||||
| 	case CHAR: | ||||
| 	case SHORT: | ||||
| 	case INT: | ||||
| 	case ENUM: | ||||
| 	case LONG: | ||||
| 		if (is_ld_cst(expr)) { | ||||
| 		if (is_ld_cst(expr)) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		expr_error(expr, "expression is not constant"); | ||||
|  | @ -416,67 +419,58 @@ chk_cst_expr(expp) | |||
| 	erroneous2int(expp); | ||||
| } | ||||
| 
 | ||||
| init_expression(eppp, expr) | ||||
| 	register struct expr ***eppp; | ||||
| 	struct expr *expr; | ||||
| void init_expression(register struct expr ***eppp, struct expr *expr) | ||||
| { | ||||
| 	/*	The expression expr is added to the tree designated
 | ||||
| 		indirectly by **eppp. | ||||
| 		The natural form of a tree representing an | ||||
| 		initial_value_list is right-recursive, ie. with the | ||||
| 		left-most comma as main operator. The iterative grammar in | ||||
| 		expression.g, however, tends to produce a left-recursive | ||||
| 		tree, ie. one with the right-most comma as its main | ||||
| 		operator. | ||||
| 		To produce a right-recursive tree from the iterative | ||||
| 		grammar, we keep track of the address of the pointer where | ||||
| 		the next expression must be hooked in. | ||||
| 	*/ | ||||
| 	 indirectly by **eppp. | ||||
| 	 The natural form of a tree representing an | ||||
| 	 initial_value_list is right-recursive, ie. with the | ||||
| 	 left-most comma as main operator. The iterative grammar in | ||||
| 	 expression.g, however, tends to produce a left-recursive | ||||
| 	 tree, ie. one with the right-most comma as its main | ||||
| 	 operator. | ||||
| 	 To produce a right-recursive tree from the iterative | ||||
| 	 grammar, we keep track of the address of the pointer where | ||||
| 	 the next expression must be hooked in. | ||||
| 	 */ | ||||
| 	**eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR); | ||||
| 	*eppp = &(**eppp)->OP_RIGHT; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| is_ld_cst(expr) | ||||
| 	register struct expr *expr; | ||||
| int is_ld_cst(register struct expr *expr) | ||||
| { | ||||
| 	/*	An expression is a `load-time constant' if it is of the form
 | ||||
| 		<idf> +/- <integral> or <integral>. | ||||
| 	*/ | ||||
| 	 <idf> +/- <integral> or <integral>. | ||||
| 	 */ | ||||
| #ifdef	LINT | ||||
| 	if (expr->ex_class == String) | ||||
| 		return 1; | ||||
| 	return 1; | ||||
| #endif	/* LINT */ | ||||
| 	return expr->ex_lvalue == 0 && expr->ex_class == Value; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| is_cp_cst(expr) | ||||
| 	struct expr *expr; | ||||
| int is_cp_cst(struct expr *expr) | ||||
| { | ||||
| 	/*	An expression is a `compile-time constant' if it is a
 | ||||
| 		load-time constant, and the idf is not there. | ||||
| 	*/ | ||||
| 	 load-time constant, and the idf is not there. | ||||
| 	 */ | ||||
| 	return is_ld_cst(expr) && expr->VL_CLASS == Const; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| is_fp_cst(expr) | ||||
| 	struct expr *expr; | ||||
| int is_fp_cst(struct expr *expr) | ||||
| { | ||||
| 	/*	An expression is a `floating-point constant' if it consists
 | ||||
| 		of the float only. | ||||
| 	*/ | ||||
| 	 of the float only. | ||||
| 	 */ | ||||
| 	return expr->ex_class == Float; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| is_zero_cst(expr) | ||||
| 	register struct expr *expr; | ||||
| int is_zero_cst(register struct expr *expr) | ||||
| { | ||||
| 	flt_arith var; | ||||
| 
 | ||||
| 	switch(expr->ex_class) { | ||||
| 	switch (expr->ex_class) | ||||
| 	{ | ||||
| 	case Value: | ||||
| 		return expr->VL_VALUE == 0; | ||||
| 	case Float: | ||||
|  | @ -486,13 +480,14 @@ is_zero_cst(expr) | |||
| 	/*NOTREACHED*/ | ||||
| } | ||||
| 
 | ||||
| free_expression(expr) | ||||
| 	register struct expr *expr; | ||||
| void free_expression(register struct expr *expr) | ||||
| { | ||||
| 	/*	The expression expr is freed recursively.
 | ||||
| 	*/ | ||||
| 	if (expr) { | ||||
| 		if (expr->ex_class == Oper)	{ | ||||
| 	 */ | ||||
| 	if (expr) | ||||
| 	{ | ||||
| 		if (expr->ex_class == Oper) | ||||
| 		{ | ||||
| 			free_expression(expr->OP_LEFT); | ||||
| 			free_expression(expr->OP_RIGHT); | ||||
| 		} | ||||
|  |  | |||
|  | @ -4,6 +4,13 @@ | |||
|  */ | ||||
| /* $Id$ */ | ||||
| /* EXPRESSION DESCRIPTOR */ | ||||
| #ifndef EXPR_H_ | ||||
| #define EXPR_H_ | ||||
| 
 | ||||
| #include "parameters.h" | ||||
| #include "arith.h" | ||||
| #include "label.h" | ||||
| #include "flt_arith.h" | ||||
| 
 | ||||
| /*	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. | ||||
|  | @ -97,3 +104,24 @@ extern struct expr *intexpr(), *new_oper(); | |||
| 
 | ||||
| /* ALLOCDEF "expr" 20 */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int rank_of(int oper); | ||||
| void dot2expr(struct expr **expp); | ||||
| void idf2expr(register struct expr *expr); | ||||
| void string2expr(register struct expr **expp, char *str, int len); | ||||
| void int2expr(struct expr *expr); | ||||
| void float2expr(register struct expr *expr); | ||||
| struct expr* intexpr(arith ivalue, int fund); | ||||
| void fill_int_expr(register struct expr *ex,arith ivalue, int fund); | ||||
| struct expr *new_oper(struct type *tp, register struct expr *e1, int oper, | ||||
| 		register struct expr *e2); | ||||
| void chk_cst_expr(struct expr **expp); | ||||
| void init_expression(register struct expr ***eppp, struct expr *expr); | ||||
| int is_ld_cst(register struct expr *expr); | ||||
| int is_cp_cst(struct expr *expr); | ||||
| int is_fp_cst(struct expr *expr); | ||||
| int is_zero_cst(register struct expr *expr); | ||||
| void free_expression(register struct expr *expr); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -15,6 +15,11 @@ | |||
| #include	"label.h" | ||||
| #include	"expr.h" | ||||
| #include	"code.h" | ||||
| #include    "error.h" | ||||
| #include    "ch3.h" | ||||
| #include    "ch3bin.h" | ||||
| #include    "ch3mon.h" | ||||
| #include    "proto.h" | ||||
| #include	"sizes.h" | ||||
| 
 | ||||
| extern struct expr *intexpr(); | ||||
|  |  | |||
|  | @ -23,8 +23,11 @@ | |||
| #include	"align.h" | ||||
| #include	"Lpars.h" | ||||
| #include	"field.h" | ||||
| #include    "util.h" | ||||
| #include    "conversion.h" | ||||
| #include    "eval.h" | ||||
| 
 | ||||
| 
 | ||||
| arith NewLocal();		/* util.c	*/ | ||||
| extern arith full_mask[];	/* cstoper.c	*/ | ||||
| 
 | ||||
| /*	Eval_field() evaluates expressions involving bit fields.
 | ||||
|  | @ -39,9 +42,9 @@ extern arith full_mask[];	/* cstoper.c	*/ | |||
| 	[3]	atype: the type in which the bitfield arithmetic is done; | ||||
| 		and in which bitfields are stored! | ||||
| */ | ||||
| eval_field(expr, code) | ||||
| 	struct expr *expr; | ||||
| 	int code; | ||||
| void eval_field( | ||||
| 	struct expr *expr, | ||||
| 	int code) | ||||
| { | ||||
| 	int op = expr->OP_OPER; | ||||
| 	register struct expr *leftop = expr->OP_LEFT; | ||||
|  | @ -126,12 +129,12 @@ eval_field(expr, code) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| store_field(fd, uns, code, leftop, tmpvar) | ||||
| 	register struct field *fd; | ||||
| 	int uns; | ||||
| 	int code; | ||||
| 	register struct expr *leftop; | ||||
| 	arith tmpvar; | ||||
| void store_field( | ||||
| 	register struct field *fd, | ||||
| 	int uns, | ||||
| 	int code, | ||||
| 	register struct expr *leftop, | ||||
| 	arith tmpvar) | ||||
| { | ||||
| 	C_loc(fd->fd_mask); | ||||
| 	C_and(word_size); | ||||
|  |  | |||
|  | @ -2,6 +2,11 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef FIELD_H_ | ||||
| #define FIELD_H_ | ||||
| 
 | ||||
| #include "arith.h" | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| /* FIELD DESCRIPTOR */ | ||||
| 
 | ||||
|  | @ -13,3 +18,20 @@ struct field	{	/* for field specifiers	*/ | |||
| }; | ||||
| 
 | ||||
| /* ALLOCDEF "field" 10 */ | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| 
 | ||||
| 
 | ||||
| #ifndef NOBITFIELD | ||||
| 
 | ||||
| struct expr; | ||||
| 
 | ||||
| void store_field(register struct field *fd, int uns, int code, | ||||
| 		register struct expr *leftop, arith tmpvar); | ||||
| void eval_field(struct expr *expr, int code); | ||||
| 
 | ||||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| #endif	/* LINT */ | ||||
| 
 | ||||
| #endif /* FIELD_H_ */ | ||||
|  | @ -10,18 +10,19 @@ | |||
| #include	"parameters.h" | ||||
| #include	<alloc.h> | ||||
| #include	<flt_arith.h> | ||||
| #include    "fltcstoper.h" | ||||
| #include	"arith.h" | ||||
| #include	"type.h" | ||||
| #include	"label.h" | ||||
| #include	"expr.h" | ||||
| #include	"sizes.h" | ||||
| #include	"Lpars.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| extern int ResultKnown; | ||||
| extern char *symbol2str(); | ||||
| 
 | ||||
| fltcstbin(expp, oper, expr) | ||||
| 	register struct expr **expp, *expr; | ||||
| void fltcstbin(register struct expr **expp, int oper, register struct expr *expr) | ||||
| { | ||||
| 	/*	The operation oper is performed on the constant
 | ||||
| 		expressions *expp(ld) and expr(ct), and the result restored in | ||||
|  |  | |||
							
								
								
									
										15
									
								
								lang/cem/cemcom.ansi/fltcstoper.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lang/cem/cemcom.ansi/fltcstoper.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-07 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef FLTCSTOPER_H_ | ||||
| #define FLTCSTOPER_H_ | ||||
| 
 | ||||
| struct expr; | ||||
| 
 | ||||
| void fltcstbin(register struct expr **expp, int oper, register struct expr *expr); | ||||
| 
 | ||||
| #endif /* FLTCSTOPER_H_ */ | ||||
|  | @ -25,6 +25,12 @@ | |||
| #include	"declar.h" | ||||
| #include	"decspecs.h" | ||||
| #include	"sizes.h" | ||||
| #include    "print.h" | ||||
| #include    "util.h" | ||||
| #include    "stab.h" | ||||
| #include    "code.h" | ||||
| #include    "error.h" | ||||
| #include    "ch3.h" | ||||
| #include	"Lpars.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
|  | @ -37,91 +43,92 @@ extern char *symbol2str(); | |||
| 
 | ||||
| #include <idf_pkg.body> | ||||
| 
 | ||||
| void global_redecl(); | ||||
| 
 | ||||
| struct idf * | ||||
| gen_idf() | ||||
| 
 | ||||
| struct idf *gen_idf(void) | ||||
| { | ||||
| 	/*	A new idf is created out of nowhere, to serve as an
 | ||||
| 		anonymous name. | ||||
| 	*/ | ||||
| 	 anonymous name. | ||||
| 	 */ | ||||
| 	static int name_cnt; | ||||
| 	char *s = Malloc(strlen(dot.tk_file) + 50); | ||||
| 
 | ||||
| 	sprint(s, "#%d in %s, line %u", | ||||
| 			++name_cnt, dot.tk_file, dot.tk_line); | ||||
| 	s = Realloc(s, strlen(s)+1); | ||||
| 	sprint(s, "#%d in %s, line %u", ++name_cnt, dot.tk_file, dot.tk_line); | ||||
| 	s = Realloc(s, strlen(s) + 1); | ||||
| 	return str2idf(s, 0); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| is_anon_idf(idf) | ||||
| 	struct idf *idf; | ||||
| int is_anon_idf(struct idf *idf) | ||||
| { | ||||
| 	return idf->id_text[0] == '#'; | ||||
| } | ||||
| 
 | ||||
| declare_idf(ds, dc, lvl) | ||||
| 	struct decspecs *ds; | ||||
| 	struct declarator *dc; | ||||
| void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl) | ||||
| { | ||||
| 	/*	The identifier inside dc is declared on the level lvl, with
 | ||||
| 		properties deduced from the decspecs ds and the declarator | ||||
| 		dc. | ||||
| 		The level is given explicitly to be able to insert, e.g., | ||||
| 		labels on the outermost level inside the function. | ||||
| 		This routine implements the rich semantics of C | ||||
| 		declarations. | ||||
| 	*/ | ||||
| 	 properties deduced from the decspecs ds and the declarator | ||||
| 	 dc. | ||||
| 	 The level is given explicitly to be able to insert, e.g., | ||||
| 	 labels on the outermost level inside the function. | ||||
| 	 This routine implements the rich semantics of C | ||||
| 	 declarations. | ||||
| 	 */ | ||||
| 	register struct idf *idf = dc->dc_idf; | ||||
| 	register int sc = ds->ds_sc; | ||||
| 		/*	This local copy is essential:
 | ||||
| 				char b(), c; | ||||
| 			makes b GLOBAL and c AUTO. | ||||
| 		*/ | ||||
| 	register struct def *def = idf->id_def;		/* may be NULL */ | ||||
| 	/*	This local copy is essential:
 | ||||
| 	 char b(), c; | ||||
| 	 makes b GLOBAL and c AUTO. | ||||
| 	 */ | ||||
| 	register struct def *def = idf->id_def; /* may be NULL */ | ||||
| 	register struct type *type; | ||||
| 	struct stack_level *stl = stack_level_of(lvl); | ||||
| 	char formal_array = 0; | ||||
| 
 | ||||
| 	/* determine the present type */ | ||||
| 	if (ds->ds_type == 0)	{ | ||||
| 	if (ds->ds_type == 0) | ||||
| 	{ | ||||
| 		/*	at the L_FORMAL1 level there is no type specified yet
 | ||||
| 		*/ | ||||
| 		 */ | ||||
| 		assert(lvl == L_FORMAL1); | ||||
| 		type = int_type;	/* may change at L_FORMAL2 */ | ||||
| 		type = int_type; /* may change at L_FORMAL2 */ | ||||
| 	} | ||||
| 	else	{ | ||||
| 	else | ||||
| 	{ | ||||
| 		/* combine the decspecs and the declarator into one type */ | ||||
| 		type = declare_type(ds->ds_type, dc); | ||||
| 		if (type->tp_size <= (arith)0 && | ||||
| 		    actual_declaration(sc, type))	{ | ||||
| 			if (type->tp_size == (arith) -1) { | ||||
| 		if (type->tp_size <= (arith) 0 && actual_declaration(sc, type)) | ||||
| 		{ | ||||
| 			if (type->tp_size == (arith) -1) | ||||
| 			{ | ||||
| 				/* the type is not yet known,
 | ||||
| 				   but it has to be: | ||||
| 				*/ | ||||
| 				if (type->tp_fund != VOID) { | ||||
| 				    if (level != L_GLOBAL) | ||||
| 					error("unknown %s-type", | ||||
| 						symbol2str(type->tp_fund)); | ||||
| 				} else	error("void is not a complete type"); | ||||
| 				 but it has to be: | ||||
| 				 */ | ||||
| 				if (type->tp_fund != VOID) | ||||
| 				{ | ||||
| 					if (level != L_GLOBAL) | ||||
| 						error("unknown %s-type", symbol2str(type->tp_fund)); | ||||
| 				} | ||||
| 				else | ||||
| 					error("void is not a complete type"); | ||||
| 			} | ||||
| 			else strict("%s has size 0", idf->id_text); | ||||
| 			else | ||||
| 				strict("%s has size 0", idf->id_text); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* some additional work for formal definitions */ | ||||
| 	if (lvl == L_FORMAL2)	{ | ||||
| 		switch (type->tp_fund)	{ | ||||
| 	if (lvl == L_FORMAL2) | ||||
| 	{ | ||||
| 		switch (type->tp_fund) | ||||
| 		{ | ||||
| 		case FUNCTION: | ||||
| 			warning("%s is a function; cannot be formal", | ||||
| 				idf->id_text); | ||||
| 			type = construct_type(POINTER, type, 0, (arith)0, | ||||
| 					      NO_PROTO); | ||||
| 			warning("%s is a function; cannot be formal", idf->id_text); | ||||
| 			type = construct_type(POINTER, type, 0, (arith) 0, | ||||
| 			NO_PROTO); | ||||
| 			break; | ||||
| 		case ARRAY:	/* 3.7.1 */ | ||||
| 			type = construct_type(POINTER, type->tp_up, 0, (arith)0, | ||||
| 					      NO_PROTO); | ||||
| 		case ARRAY: /* 3.7.1 */ | ||||
| 			type = construct_type(POINTER, type->tp_up, 0, (arith) 0, | ||||
| 			NO_PROTO); | ||||
| 			formal_array = 1; | ||||
| 			break; | ||||
| 		case FLOAT: | ||||
|  | @ -135,72 +142,77 @@ declare_idf(ds, dc, lvl) | |||
| 		} | ||||
| 	} | ||||
| 	/*	The tests on types, postponed from do_decspecs(), can now
 | ||||
| 		be performed. | ||||
| 	*/ | ||||
| 	 be performed. | ||||
| 	 */ | ||||
| 	/* update the storage class */ | ||||
| 	if (type && type->tp_fund == FUNCTION)	{ | ||||
| 		if (lvl != L_GLOBAL)  {		/* 3.5.1 */ | ||||
| 	if (type && type->tp_fund == FUNCTION) | ||||
| 	{ | ||||
| 		if (lvl != L_GLOBAL) | ||||
| 		{ /* 3.5.1 */ | ||||
| 			if (sc == 0) | ||||
| 				sc = GLOBAL; | ||||
| 			else if (sc != EXTERN && sc != TYPEDEF) { | ||||
| 				error("illegal storage class %s for function with block-scope" | ||||
| 					, symbol2str(sc)); | ||||
| 			else if (sc != EXTERN && sc != TYPEDEF) | ||||
| 			{ | ||||
| 				error("illegal storage class %s for function with block-scope", | ||||
| 						symbol2str(sc)); | ||||
| 				ds->ds_sc = sc = EXTERN; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (sc == 0) | ||||
| 			sc = GLOBAL; | ||||
| 	} | ||||
| 	else	/* non-FUNCTION */ | ||||
| 		if (sc == 0) | ||||
| 			sc =	lvl == L_GLOBAL ? GLOBAL | ||||
| 				: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL | ||||
| 				: AUTO; | ||||
| 	else /* non-FUNCTION */ | ||||
| 	if (sc == 0) | ||||
| 		sc = lvl == L_GLOBAL ? GLOBAL : | ||||
| 				lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL : AUTO; | ||||
| 
 | ||||
| #ifdef	LINT | ||||
| 	check_hiding(idf, lvl, sc);	/* of some idf by this idf */ | ||||
| 	check_hiding(idf, lvl, sc); /* of some idf by this idf */ | ||||
| #endif	/* LINT */ | ||||
| 	if (def && lvl == L_LOCAL && def->df_level == L_FORMAL2) { | ||||
| 	if (def && lvl == L_LOCAL && def->df_level == L_FORMAL2) | ||||
| 	{ | ||||
| 		error("%s redeclared", idf->id_text); | ||||
| 	} | ||||
| 
 | ||||
| 	if (def &&  | ||||
| 	    ( def->df_level == lvl || | ||||
| 	      ( lvl != L_GLOBAL && def->df_level > lvl ) || | ||||
| 	      (lvl == L_GLOBAL | ||||
| 	       && def->df_level == L_PROTO | ||||
| 	       && def->next && def->next->df_level == L_GLOBAL) | ||||
| 	   ))	{ | ||||
| 	if (def | ||||
| 			&& (def->df_level == lvl || (lvl != L_GLOBAL && def->df_level > lvl) | ||||
| 					|| (lvl == L_GLOBAL && def->df_level == L_PROTO && def->next | ||||
| 							&& def->next->df_level == L_GLOBAL))) | ||||
| 	{ | ||||
| 		/*	There is already a declaration for idf on this
 | ||||
| 			level, or even more inside. | ||||
| 			The rules differ for different levels. | ||||
| 		*/ | ||||
| 		switch (lvl)	{ | ||||
| 		 level, or even more inside. | ||||
| 		 The rules differ for different levels. | ||||
| 		 */ | ||||
| 		switch (lvl) | ||||
| 		{ | ||||
| 		case L_GLOBAL: | ||||
| 			global_redecl(idf, sc, type); | ||||
| 			def->df_file = idf->id_file; | ||||
| 			def->df_line = idf->id_line; | ||||
| 			break; | ||||
| 		case L_FORMAL1:	/* formal declaration */ | ||||
| 		case L_FORMAL1: /* formal declaration */ | ||||
| 			error("formal %s redeclared", idf->id_text); | ||||
| 			break; | ||||
| 		case L_FORMAL2:	/* formal definition */ | ||||
| 		default:	/* local */ | ||||
| 			if (sc != EXTERN) error("%s redeclared", idf->id_text); | ||||
| 		case L_FORMAL2: /* formal definition */ | ||||
| 		default: /* local */ | ||||
| 			if (sc != EXTERN) | ||||
| 				error("%s redeclared", idf->id_text); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	else	/* the idf is unknown on this level */ | ||||
| 	if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf))	{ | ||||
| 	else /* the idf is unknown on this level */ | ||||
| 	if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf)) | ||||
| 	{ | ||||
| 		/* formal declaration, update only */ | ||||
| 		def->df_type = type; | ||||
| 		def->df_formal_array = formal_array; | ||||
| 		def->df_sc = sc; | ||||
| 		def->df_level = L_FORMAL2;	/* CJ */ | ||||
| 		def->df_level = L_FORMAL2; /* CJ */ | ||||
| 		def->df_file = idf->id_file; | ||||
| 		def->df_line = idf->id_line; | ||||
| 	} | ||||
| 	else	{ /* fill in the def block */ | ||||
| 	else | ||||
| 	{ /* fill in the def block */ | ||||
| 		register struct def *newdef = new_def(); | ||||
| 
 | ||||
| 		newdef->next = def; | ||||
|  | @ -218,28 +230,27 @@ declare_idf(ds, dc, lvl) | |||
| 		update_ahead(idf); | ||||
| 		stack_idf(idf, stl); | ||||
| 		/*	We now calculate the address.
 | ||||
| 			Globals have names and don't get addresses, they | ||||
| 			get numbers instead (through data_label()). | ||||
| 			Formals are handled by declare_formals(). | ||||
| 			So here we hand out local addresses only. | ||||
| 		*/ | ||||
| 		if (lvl >= L_LOCAL)	{ | ||||
| 		 Globals have names and don't get addresses, they | ||||
| 		 get numbers instead (through data_label()). | ||||
| 		 Formals are handled by declare_formals(). | ||||
| 		 So here we hand out local addresses only. | ||||
| 		 */ | ||||
| 		if (lvl >= L_LOCAL) | ||||
| 		{ | ||||
| 			assert(sc); | ||||
| 			switch (sc)	{ | ||||
| 			switch (sc) | ||||
| 			{ | ||||
| 			case REGISTER: | ||||
| 			case AUTO: | ||||
| 				if (type->tp_size == (arith)-1 | ||||
| 					&& type->tp_fund != ARRAY) { | ||||
| 					error("size of local %s unknown", | ||||
| 						idf->id_text); | ||||
| 				/** type = idf->id_def->df_type = int_type; **/ | ||||
| 				if (type->tp_size == (arith) -1 && type->tp_fund != ARRAY) | ||||
| 				{ | ||||
| 					error("size of local %s unknown", idf->id_text); | ||||
| 					/** type = idf->id_def->df_type = int_type; **/ | ||||
| 				} | ||||
| 				if (type->tp_size != (arith) -1) { | ||||
| 				    newdef->df_address = | ||||
| 					NewLocal(type->tp_size, | ||||
| 						 type->tp_align, | ||||
| 						 regtype(type), | ||||
| 						 sc); | ||||
| 				if (type->tp_size != (arith) -1) | ||||
| 				{ | ||||
| 					newdef->df_address = NewLocal(type->tp_size, type->tp_align, | ||||
| 							regtype(type), sc); | ||||
| 				} | ||||
| 				break; | ||||
| 			case STATIC: | ||||
|  | @ -250,13 +261,10 @@ declare_idf(ds, dc, lvl) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| int | ||||
| actual_declaration(sc, tp) | ||||
| 	int sc; | ||||
| 	struct type *tp; | ||||
| int actual_declaration(int sc, struct type *tp) | ||||
| { | ||||
| 	/*	An actual_declaration needs space, right here and now.
 | ||||
| 	*/ | ||||
| 	 */ | ||||
| 	register int fund = tp->tp_fund; | ||||
| 
 | ||||
| 	if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */ | ||||
|  | @ -264,7 +272,8 @@ actual_declaration(sc, tp) | |||
| 	if (fund == FUNCTION || fund == ARRAY) | ||||
| 		/* allocation solved in other ways */ | ||||
| 		return 0; | ||||
| 	if (sc == EXTERN && fund == VOID) { | ||||
| 	if (sc == EXTERN && fund == VOID) | ||||
| 	{ | ||||
| 		/* strange, but should be accepted */ | ||||
| 		return 0; | ||||
| 	} | ||||
|  | @ -272,51 +281,59 @@ actual_declaration(sc, tp) | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| global_redecl(idf, new_sc, tp) | ||||
| 	register struct idf *idf; | ||||
| 	struct type *tp; | ||||
| void global_redecl(register struct idf *idf, int new_sc, struct type *tp) | ||||
| { | ||||
| 	/*	A global identifier may be declared several times,
 | ||||
| 		provided the declarations do not conflict; they might | ||||
| 		conflict in type (or supplement each other in the case of | ||||
| 		an array) or they might conflict or supplement each other | ||||
| 		in storage class. | ||||
| 	*/ | ||||
| 	 provided the declarations do not conflict; they might | ||||
| 	 conflict in type (or supplement each other in the case of | ||||
| 	 an array) or they might conflict or supplement each other | ||||
| 	 in storage class. | ||||
| 	 */ | ||||
| 	register struct def *def = idf->id_def; | ||||
| 
 | ||||
| 	while (def->df_level != L_GLOBAL) def = def->next; | ||||
| 	if (!equal_type(tp, def->df_type, 0, 1)) { | ||||
| 	while (def->df_level != L_GLOBAL) | ||||
| 		def = def->next; | ||||
| 	if (!equal_type(tp, def->df_type, 0, 1)) | ||||
| 	{ | ||||
| 		error("redeclaration of %s with different type", idf->id_text); | ||||
| 		return; | ||||
| 	} else	update_proto(tp, def->df_type); | ||||
| 	if (tp->tp_fund == ARRAY) { | ||||
| 	} | ||||
| 	else | ||||
| 		update_proto(tp, def->df_type); | ||||
| 	if (tp->tp_fund == ARRAY) | ||||
| 	{ | ||||
| 		/* Multiple array declaration; this may be interesting */ | ||||
| 		if (tp->tp_size < 0)	{		/* new decl has [] */ | ||||
| 		if (tp->tp_size < 0) | ||||
| 		{ /* new decl has [] */ | ||||
| 			/* nothing new */ | ||||
| 		} else | ||||
| 		if (def->df_type->tp_size < 0)	{	/* old decl has [] */ | ||||
| 		} | ||||
| 		else if (def->df_type->tp_size < 0) | ||||
| 		{ /* old decl has [] */ | ||||
| 			def->df_type = tp; | ||||
| 		} | ||||
| 	} if (tp->tp_fund == FUNCTION && new_sc == GLOBAL) { | ||||
| 	} | ||||
| 	if (tp->tp_fund == FUNCTION && new_sc == GLOBAL) | ||||
| 	{ | ||||
| 		/* see 3.1.2.2 */ | ||||
| 		new_sc = EXTERN; | ||||
| 	} | ||||
| 
 | ||||
| 	/*	Now we may be able to update the storage class.
 | ||||
| 		Clean out this mess as soon as we know all the possibilities | ||||
| 		for new_sc. | ||||
| 		For now we have: | ||||
| 			EXTERN:		we have seen the word "extern" | ||||
| 			GLOBAL:		the item was declared on the outer | ||||
| 					level, without either "extern" or | ||||
| 					"static". | ||||
| 			STATIC:		we have seen the word "static" | ||||
| 	*/ | ||||
| 	 Clean out this mess as soon as we know all the possibilities | ||||
| 	 for new_sc. | ||||
| 	 For now we have: | ||||
| 	 EXTERN:		we have seen the word "extern" | ||||
| 	 GLOBAL:		the item was declared on the outer | ||||
| 	 level, without either "extern" or | ||||
| 	 "static". | ||||
| 	 STATIC:		we have seen the word "static" | ||||
| 	 */ | ||||
| 
 | ||||
| 	switch (def->df_sc)	{	/* the old storage class */ | ||||
| 	switch (def->df_sc) | ||||
| 	{ /* the old storage class */ | ||||
| 	case EXTERN: | ||||
| 		switch (new_sc)	{	/* the new storage class */ | ||||
| 		switch (new_sc) | ||||
| 		{ /* the new storage class */ | ||||
| 		case STATIC: | ||||
| 			warning("%s redeclared static", idf->id_text); | ||||
| 			/* fallthrough */ | ||||
|  | @ -331,8 +348,9 @@ global_redecl(idf, new_sc, tp) | |||
| 		} | ||||
| 		break; | ||||
| 	case GLOBAL: | ||||
| 		switch (new_sc)	{	/* the new storage class */ | ||||
| 		case STATIC:		/* linkage disagreement */ | ||||
| 		switch (new_sc) | ||||
| 		{ /* the new storage class */ | ||||
| 		case STATIC: /* linkage disagreement */ | ||||
| 			warning("%s redeclared static", idf->id_text); | ||||
| 			def->df_sc = new_sc; | ||||
| 			/* fallthrough */ | ||||
|  | @ -345,8 +363,9 @@ global_redecl(idf, new_sc, tp) | |||
| 		} | ||||
| 		break; | ||||
| 	case STATIC: | ||||
| 		switch (new_sc)	{	/* the new storage class */ | ||||
| 		case GLOBAL:		/* linkage disagreement */ | ||||
| 		switch (new_sc) | ||||
| 		{ /* the new storage class */ | ||||
| 		case GLOBAL: /* linkage disagreement */ | ||||
| 		case EXTERN: | ||||
| 			warning("%s is already declared static", idf->id_text); | ||||
| 			/* fallthrough */ | ||||
|  | @ -367,142 +386,147 @@ global_redecl(idf, new_sc, tp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| int | ||||
| good_formal(def, idf) | ||||
| 	register struct def *def; | ||||
| 	register struct idf *idf; | ||||
| int good_formal(register struct def *def, register struct idf *idf) | ||||
| { | ||||
| 	/*	Succeeds if def is a proper L_FORMAL1 definition and
 | ||||
| 		gives an error message otherwise. | ||||
| 	*/ | ||||
| 	if (!def || def->df_level != L_FORMAL1)	{ /* not in parameter list */ | ||||
| 	 gives an error message otherwise. | ||||
| 	 */ | ||||
| 	if (!def || def->df_level != L_FORMAL1) | ||||
| 	{ /* not in parameter list */ | ||||
| 		if (!is_anon_idf(idf)) | ||||
| 			error("%s not in parameter list", idf->id_text); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	assert(def->df_sc == FORMAL);	/* CJ */ | ||||
| 	assert(def->df_sc == FORMAL); /* CJ */ | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| declare_params(dc) | ||||
| 	struct declarator *dc; | ||||
| void declare_params(struct declarator *dc) | ||||
| { | ||||
| 	/*	Declares the formal parameters if they exist.
 | ||||
| 	*/ | ||||
| 	 */ | ||||
| 	register struct formal *fm = dc->dc_formal; | ||||
| 
 | ||||
| 	while (fm)	{ | ||||
| 	while (fm) | ||||
| 	{ | ||||
| 		declare_parameter(fm->fm_idf); | ||||
| 		fm = fm->next; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| idf_initialized(idf) | ||||
| 	register struct idf *idf; | ||||
| void idf_initialized(register struct idf *idf) | ||||
| { | ||||
| 	/*	The topmost definition of idf is set to initialized.
 | ||||
| 	*/ | ||||
| 	register struct def *def = idf->id_def;	/* the topmost */ | ||||
| 	 */ | ||||
| 	register struct def *def = idf->id_def; /* the topmost */ | ||||
| 
 | ||||
| 	while (def->df_level <= L_PROTO) def = def->next; | ||||
| 	while (def->df_level <= L_PROTO) | ||||
| 		def = def->next; | ||||
| 	if (def->df_initialized) | ||||
| 		error("multiple initialization of %s", idf->id_text); | ||||
| 	if (def->df_sc == TYPEDEF)	{ | ||||
| 	if (def->df_sc == TYPEDEF) | ||||
| 	{ | ||||
| 		error("typedef cannot be initialized"); | ||||
| 		return; | ||||
| 	} | ||||
| 	def->df_initialized = 1; | ||||
| } | ||||
| 
 | ||||
| declare_parameter(idf) | ||||
| 	struct idf *idf; | ||||
| void declare_parameter(struct idf *idf) | ||||
| { | ||||
| 	/*	idf is declared as a formal.
 | ||||
| 	*/ | ||||
| 	 */ | ||||
| 	add_def(idf, FORMAL, int_type, level); | ||||
| } | ||||
| 
 | ||||
| declare_enum(tp, idf, l) | ||||
| 	struct type *tp; | ||||
| 	struct idf *idf; | ||||
| 	arith l; | ||||
| void declare_enum(struct type *tp, struct idf *idf, arith l) | ||||
| { | ||||
| 	/*	idf is declared as an enum constant with value l.
 | ||||
| 	*/ | ||||
| 	 */ | ||||
| 	add_def(idf, ENUM, tp, level); | ||||
| 	idf->id_def->df_address = l; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| check_formals(idf, dc) | ||||
| 	struct idf *idf; | ||||
| 	struct declarator *dc; | ||||
| void check_formals(struct idf *idf, struct declarator *dc) | ||||
| { | ||||
| 	register struct formal *fm = dc->dc_formal; | ||||
| 	register struct proto *pl = idf->id_def->df_type->tp_proto; | ||||
| 	register struct decl_unary *du = dc->dc_decl_unary; | ||||
| 
 | ||||
| 	if (!du) {	/* error or typdef'ed function */ | ||||
| 	if (!du) | ||||
| 	{ /* error or typdef'ed function */ | ||||
| 		error("illegal definition of %s", idf->id_text); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	while (du | ||||
| 		&& (du->du_fund != FUNCTION | ||||
| 		    || du->next != (struct decl_unary *) 0)) { | ||||
| 			&& (du->du_fund != FUNCTION || du->next != (struct decl_unary *) 0)) | ||||
| 	{ | ||||
| 		du = du->next; | ||||
| 	} | ||||
| 	if (!du) return;	/* terrible error, signalled earlier */ | ||||
| 	if (!du) | ||||
| 		return; /* terrible error, signalled earlier */ | ||||
| 
 | ||||
| 	if (du->du_proto) return; | ||||
| 	if (du->du_proto) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (pl) { | ||||
| 	if (pl) | ||||
| 	{ | ||||
| 		/* Don't give a warning about an old-style definition,
 | ||||
| 		 * since the arguments will be checked anyway. | ||||
| 		 */ | ||||
| 		if (pl->pl_flag & PL_ELLIPSIS) { | ||||
| 		    if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN)) | ||||
| 			error("ellipsis terminator in previous declaration"); | ||||
| 		    pl = pl->next; | ||||
| 		if (pl->pl_flag & PL_ELLIPSIS) | ||||
| 		{ | ||||
| 			if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN)) | ||||
| 				error("ellipsis terminator in previous declaration"); | ||||
| 			pl = pl->next; | ||||
| 		} | ||||
| 		else if (pl->pl_flag & PL_VOID) { | ||||
| 		    pl = pl->next;			/* should be 0 */ | ||||
| 		else if (pl->pl_flag & PL_VOID) | ||||
| 		{ | ||||
| 			pl = pl->next; /* should be 0 */ | ||||
| 		} | ||||
| 		while(fm && pl) { | ||||
| 		    if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type) | ||||
| 					, pl->pl_type, -1, 1)) { | ||||
| 			if (!(pl->pl_flag & PL_ERRGIVEN)) | ||||
| 			    error("incorrect type for parameter %s" | ||||
| 						, fm->fm_idf->id_text); | ||||
| 			pl->pl_flag |= PL_ERRGIVEN; | ||||
| 		    } | ||||
| 		    fm = fm->next; | ||||
| 		    pl = pl->next; | ||||
| 		while (fm && pl) | ||||
| 		{ | ||||
| 			if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type), | ||||
| 					pl->pl_type, -1, 1)) | ||||
| 			{ | ||||
| 				if (!(pl->pl_flag & PL_ERRGIVEN)) | ||||
| 					error("incorrect type for parameter %s", | ||||
| 							fm->fm_idf->id_text); | ||||
| 				pl->pl_flag |= PL_ERRGIVEN; | ||||
| 			} | ||||
| 			fm = fm->next; | ||||
| 			pl = pl->next; | ||||
| 		} | ||||
| 		if (pl || fm) { | ||||
| 		if (pl || fm) | ||||
| 		{ | ||||
| 			error("incorrect number of parameters"); | ||||
| 		} | ||||
| 	} else {			/* make a pseudo-prototype */ | ||||
| 	} | ||||
| 	else | ||||
| 	{ /* make a pseudo-prototype */ | ||||
| 		register struct proto *lpl = new_proto(); | ||||
| 
 | ||||
| 		if (!options['o']) | ||||
| 			warning("'%s' old-fashioned function definition" | ||||
| 					, dc->dc_idf->id_text); | ||||
| 			warning("'%s' old-fashioned function definition", | ||||
| 					dc->dc_idf->id_text); | ||||
| 
 | ||||
| 		while (fm) { | ||||
| 			if (pl == 0) pl = lpl; | ||||
| 			else { | ||||
| 		while (fm) | ||||
| 		{ | ||||
| 			if (pl == 0) | ||||
| 				pl = lpl; | ||||
| 			else | ||||
| 			{ | ||||
| 				lpl->next = new_proto(); | ||||
| 				lpl = lpl->next; | ||||
| 			} | ||||
| 			lpl->pl_flag = PL_FORMAL; | ||||
| 			lpl->pl_idf = fm->fm_idf; | ||||
| 			lpl->pl_type = | ||||
| 				    promoted_type(fm->fm_idf->id_def->df_type); | ||||
| 			lpl->pl_type = promoted_type(fm->fm_idf->id_def->df_type); | ||||
| 			fm = fm->next; | ||||
| 		} | ||||
| 		if (pl == 0) {		/* make func(void) */ | ||||
| 		if (pl == 0) | ||||
| 		{ /* make func(void) */ | ||||
| 			pl = lpl; | ||||
| 			pl->pl_type = void_type; | ||||
| 			pl->pl_flag = PL_FORMAL | PL_VOID; | ||||
|  | @ -513,26 +537,26 @@ check_formals(idf, dc) | |||
| 	dc->dc_formal = 0; | ||||
| } | ||||
| 
 | ||||
| declare_formals(idf, fp) | ||||
| 	struct idf *idf; | ||||
| 	arith *fp; | ||||
| void declare_formals(struct idf *idf, arith *fp) | ||||
| { | ||||
| 	/*	Declares those formals as int that haven't been declared
 | ||||
| 		by the user. | ||||
| 		An address is assigned to each formal parameter. | ||||
| 		The total size of the formals is returned in *fp; | ||||
| 	*/ | ||||
| 	 by the user. | ||||
| 	 An address is assigned to each formal parameter. | ||||
| 	 The total size of the formals is returned in *fp; | ||||
| 	 */ | ||||
| 	register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry; | ||||
| 	arith f_offset = (arith)0; | ||||
| 	arith f_offset = (arith) 0; | ||||
| 	register int nparams = 0; | ||||
| 	int hasproto; | ||||
| 	struct def *df = idf->id_def; | ||||
| 
 | ||||
| 	/* When one of the formals has the same name as the function, 
 | ||||
| 	   it hides the function def. Get it. | ||||
| 	*/ | ||||
| 	while (se) { | ||||
| 		if (se->se_idf == idf) { | ||||
| 	 it hides the function def. Get it. | ||||
| 	 */ | ||||
| 	while (se) | ||||
| 	{ | ||||
| 		if (se->se_idf == idf) | ||||
| 		{ | ||||
| 			df = df->next; | ||||
| 			break; | ||||
| 		} | ||||
|  | @ -545,44 +569,48 @@ declare_formals(idf, fp) | |||
| 
 | ||||
| #ifdef	DEBUG | ||||
| 	if (options['t']) | ||||
| 		dumpidftab("start declare_formals", 0); | ||||
| 	dumpidftab("start declare_formals", 0); | ||||
| #endif	/* DEBUG */ | ||||
| 	if (is_struct_or_union(df->df_type->tp_up->tp_fund)) { | ||||
| 	if (is_struct_or_union(df->df_type->tp_up->tp_fund)) | ||||
| 	{ | ||||
| 		/* create space for address of return value */ | ||||
| 		f_offset = pointer_size; | ||||
| 	} | ||||
| 	while (se)	{ | ||||
| 	while (se) | ||||
| 	{ | ||||
| 		df = se->se_idf->id_def; | ||||
| 
 | ||||
| 		/* this stacklevel may also contain tags. ignore them */ | ||||
| 		if (!df || df->df_level < L_FORMAL1 ) { | ||||
| 		if (!df || df->df_level < L_FORMAL1) | ||||
| 		{ | ||||
| 			se = se->next; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		df->df_address = f_offset; | ||||
| 		/*	the alignment convention for parameters is: align on
 | ||||
| 			word boundaries, i.e. take care that the following | ||||
| 			parameter starts on a new word boundary. | ||||
| 		*/ | ||||
| 		if (! hasproto  | ||||
| 		    && df->df_type->tp_fund == FLOAT | ||||
| 		    && df->df_type->tp_size != double_size) { | ||||
| 		 word boundaries, i.e. take care that the following | ||||
| 		 parameter starts on a new word boundary. | ||||
| 		 */ | ||||
| 		if (!hasproto && df->df_type->tp_fund == FLOAT | ||||
| 				&& df->df_type->tp_size != double_size) | ||||
| 		{ | ||||
| 			f_offset = align(f_offset + double_size, (int) word_size); | ||||
| 		} | ||||
| 		else f_offset = align(f_offset + df->df_type->tp_size, (int) word_size); | ||||
| 		else | ||||
| 			f_offset = align(f_offset + df->df_type->tp_size, (int) word_size); | ||||
| 		RegisterAccount(df->df_address, df->df_type->tp_size, | ||||
| 				regtype(df->df_type), | ||||
| 				df->df_sc); | ||||
| 				regtype(df->df_type), df->df_sc); | ||||
| 		/* cvt int to char or short and double to float, if necessary
 | ||||
| 		 */ | ||||
| 		formal_cvt(hasproto, df); | ||||
| 
 | ||||
| 		df->df_level = L_FORMAL2;	/* CJ */ | ||||
| 		df->df_level = L_FORMAL2; /* CJ */ | ||||
| 		if (nparams++ >= STDC_NPARAMS) | ||||
| 			strict("number of formal parameters exceeds ANSI limit"); | ||||
| #ifdef DBSYMTAB | ||||
| 		if (options['g']) { | ||||
| 		if (options['g']) | ||||
| 		{ | ||||
| 			stb_string(df, FORMAL, se->se_idf->id_text); | ||||
| 		} | ||||
| #endif /* DBSYMTAB */ | ||||
|  | @ -591,11 +619,10 @@ declare_formals(idf, fp) | |||
| 	*fp = f_offset; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| regtype(tp) | ||||
| 	struct type *tp; | ||||
| int regtype(struct type *tp) | ||||
| { | ||||
| 	switch(tp->tp_fund) { | ||||
| 	switch (tp->tp_fund) | ||||
| 	{ | ||||
| 	case INT: | ||||
| 	case LONG: | ||||
| 		return reg_any; | ||||
|  | @ -609,18 +636,15 @@ regtype(tp) | |||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| add_def(idf, sc, tp, lvl) | ||||
| 	struct idf *idf; | ||||
| 	struct type *tp; | ||||
| 	int lvl; | ||||
| 	int sc; | ||||
| void add_def(struct idf *idf, int sc, struct type *tp, int lvl) | ||||
| { | ||||
| 	/*	The identifier idf is declared on level lvl with storage
 | ||||
| 		class sc and type tp, through a faked C declaration. | ||||
| 		This is probably the wrong way to structure the problem, | ||||
| 		but it will have to do for the time being. | ||||
| 	*/ | ||||
| 	struct decspecs Ds; struct declarator Dc; | ||||
| 	 class sc and type tp, through a faked C declaration. | ||||
| 	 This is probably the wrong way to structure the problem, | ||||
| 	 but it will have to do for the time being. | ||||
| 	 */ | ||||
| 	struct decspecs Ds; | ||||
| 	struct declarator Dc; | ||||
| 
 | ||||
| 	Ds = null_decspecs; | ||||
| 	Ds.ds_type = tp; | ||||
|  | @ -630,25 +654,24 @@ add_def(idf, sc, tp, lvl) | |||
| 	declare_idf(&Ds, &Dc, lvl); | ||||
| } | ||||
| 
 | ||||
| update_ahead(idf) | ||||
| 	register struct idf *idf; | ||||
| void update_ahead(register struct idf *idf) | ||||
| { | ||||
| 	/*	The tk_symb of the token ahead is updated in the light of new
 | ||||
| 		information about the identifier idf. | ||||
| 	*/ | ||||
| 	 information about the identifier idf. | ||||
| 	 */ | ||||
| 	register int tk_symb = AHEAD; | ||||
| 
 | ||||
| 	if (	(tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) && | ||||
| 		ahead.tk_idf == idf | ||||
| 	) | ||||
| 	if ((tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) | ||||
| 			&& ahead.tk_idf == idf) | ||||
| 		AHEAD = idf->id_def && idf->id_def->df_sc == TYPEDEF ? | ||||
| 				TYPE_IDENTIFIER : IDENTIFIER; | ||||
| 		TYPE_IDENTIFIER : | ||||
| 																IDENTIFIER; | ||||
| } | ||||
| 
 | ||||
| free_formals(fm) | ||||
| 	register struct formal *fm; | ||||
| void free_formals(register struct formal *fm) | ||||
| { | ||||
| 	while (fm)	{ | ||||
| 	while (fm) | ||||
| 	{ | ||||
| 		struct formal *tmp = fm->next; | ||||
| 
 | ||||
| 		free_formal(fm); | ||||
|  |  | |||
|  | @ -2,10 +2,15 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef IDF_H_ | ||||
| #define IDF_H_ | ||||
| 
 | ||||
|   | ||||
| /* $Id$ */ | ||||
| /* IDENTIFIER DESCRIPTOR */ | ||||
| 
 | ||||
| #include	"parameters.h" | ||||
| #include    "arith.h" | ||||
| 
 | ||||
| struct id_u { | ||||
| 	int idd_reserved;	/* non-zero for reserved words		*/ | ||||
|  | @ -33,4 +38,28 @@ struct id_u { | |||
| #include <idf_pkg.spec> | ||||
| 
 | ||||
| extern int level; | ||||
| extern struct idf *gen_idf(); | ||||
| 
 | ||||
| struct decspecs; | ||||
| struct declarator; | ||||
| struct type; | ||||
| struct formal; | ||||
| 
 | ||||
| 
 | ||||
| struct idf *gen_idf(void); | ||||
| int is_anon_idf(struct idf *idf); | ||||
| void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl); | ||||
| int actual_declaration(int sc, struct type *tp); | ||||
| void global_redecl(register struct idf *idf, int new_sc, struct type *tp); | ||||
| int good_formal(register struct def *def, register struct idf *idf); | ||||
| void declare_params(struct declarator *dc); | ||||
| void idf_initialized(register struct idf *idf); | ||||
| void declare_parameter(struct idf *idf); | ||||
| void declare_enum(struct type *tp, struct idf *idf, arith l); | ||||
| void check_formals(struct idf *idf, struct declarator *dc); | ||||
| void declare_formals(struct idf *idf, arith *fp); | ||||
| int regtype(struct type *tp); | ||||
| void add_def(struct idf *idf, int sc, struct type *tp, int lvl); | ||||
| void update_ahead(register struct idf *idf); | ||||
| void free_formals(register struct formal *fm); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -10,6 +10,7 @@ | |||
| #include <string.h> | ||||
| #include "file_info.h" | ||||
| #include "input.h" | ||||
| #include "error.h" | ||||
| 
 | ||||
| #define INP_PUSHBACK	3 | ||||
| #define INP_TYPE	struct file_info | ||||
|  | @ -20,14 +21,14 @@ struct file_info	finfo; | |||
| 
 | ||||
| int	NoUnstack; | ||||
| 
 | ||||
| AtEoIT() | ||||
| int AtEoIT(void) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| extern char *source; | ||||
| 
 | ||||
| AtEoIF() | ||||
| int AtEoIF(void) | ||||
| { | ||||
| 	if (NoUnstack) lexerror("unexpected EOF"); | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -12,4 +12,4 @@ | |||
| #define UnGetChar()	((LexSave != EOI) ? ChPushBack(LexSave) : 0) | ||||
| 
 | ||||
| extern	int LexSave;	/* last character read by GetChar		*/ | ||||
| extern 	int GetChar();	/* character input, with trigraph parsing	*/ | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| #include	<ack_string.h> | ||||
| #include	<alloc.h> | ||||
| #include	<assert.h> | ||||
| #include    <string.h>  | ||||
| #include	<flt_arith.h> | ||||
| #include    "idf.h" | ||||
| #include	"arith.h" | ||||
|  | @ -31,25 +32,43 @@ | |||
| #include	"sizes.h" | ||||
| #include	"align.h" | ||||
| #include	"level.h" | ||||
| #include    "error.h" | ||||
| #include	"def.h" | ||||
| #include	"LLlex.h" | ||||
| #include	"estack.h" | ||||
| #include    "stack.h" | ||||
| #include    "ch3.h" | ||||
| 
 | ||||
| #define con_nullbyte()	C_con_ucon("0", (arith)1) | ||||
| #define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT) | ||||
| 
 | ||||
| char *strncpy(); | ||||
| extern char options[]; | ||||
| static int gen_error; | ||||
| static int pack_level; | ||||
| struct type **gen_tphead(), **gen_tpmiddle(); | ||||
| struct sdef *gen_align_to_next(); | ||||
| struct e_stack *p_stack; | ||||
| 
 | ||||
| void pad(); | ||||
| void gen_simple_exp(); | ||||
| void gen_tpcheck(); | ||||
| void gen_tpcheck(struct type **); | ||||
| void gen_simple_exp(struct type **, struct expr **); | ||||
| struct type **arr_elem(struct type **, struct e_stack *); | ||||
| struct sdef *next_field(register struct sdef *,register struct e_stack *); | ||||
| struct type **gen_tphead(struct type **, int); | ||||
| struct type **gen_tpmiddle(void); | ||||
| struct sdef *gen_align_to_next(register struct e_stack *); | ||||
| void gen_tpend(void); | ||||
| void check_and_pad(struct expr **, struct type **); | ||||
| void pad(struct type *); | ||||
| void check_ival(struct expr **, register struct type *); | ||||
| void ch_array(struct type **,	/* type tp = array of characters	*/ | ||||
| 	struct expr *); | ||||
| void str_cst(register char *, register int, int); | ||||
| #ifndef NOBITFIELD | ||||
| void put_bf(struct type *, arith ); | ||||
| #endif /* NOBITFIELD */ | ||||
| int zero_bytes(register struct sdef *); | ||||
| int valid_type(struct type *, char *); | ||||
| void con_int(register struct expr *); | ||||
| void illegal_init_cst(struct expr *); | ||||
| void too_many_initialisers(void); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  | @ -127,9 +146,7 @@ initial_value_list(register struct type **tpp; struct expr **expp;) | |||
| ; | ||||
| 
 | ||||
| { | ||||
| void | ||||
| gen_tpcheck(tpp) | ||||
| 	struct type **tpp; | ||||
| void gen_tpcheck(struct type **tpp) | ||||
| { | ||||
| 	register struct type *tp; | ||||
| 
 | ||||
|  | @ -153,10 +170,7 @@ gen_tpcheck(tpp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| gen_simple_exp(tpp, expp) | ||||
| 	struct type **tpp; | ||||
| 	struct expr **expp; | ||||
| void gen_simple_exp(struct type **tpp, struct expr **expp) | ||||
| { | ||||
| 	register struct type *tp; | ||||
| 
 | ||||
|  | @ -184,10 +198,7 @@ gen_simple_exp(tpp, expp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct type ** | ||||
| arr_elem(tpp, p) | ||||
| 	struct type **tpp; | ||||
| 	struct e_stack *p; | ||||
| struct type **arr_elem(struct type **tpp, struct e_stack *p) | ||||
| { | ||||
| 	register struct type *tp = *tpp; | ||||
| 
 | ||||
|  | @ -200,10 +211,8 @@ arr_elem(tpp, p) | |||
| 	return gen_tphead(&(tp->tp_up), 1); | ||||
| } | ||||
| 
 | ||||
| struct sdef * | ||||
| next_field(sd, p) | ||||
| 	register struct sdef *sd; | ||||
| 	register struct e_stack *p; | ||||
| struct sdef *next_field(register struct sdef *sd, | ||||
| 	register struct e_stack *p) | ||||
| { | ||||
| 	if (sd->sd_sdef) | ||||
| 		p->bytes_upto_here += zero_bytes(sd); | ||||
|  | @ -213,9 +222,7 @@ next_field(sd, p) | |||
| 	return sd->sd_sdef; | ||||
| } | ||||
| 
 | ||||
| struct type ** | ||||
| gen_tphead(tpp, nest) | ||||
| 	struct type **tpp; | ||||
| struct type **gen_tphead(struct type **tpp, int nest) | ||||
| { | ||||
| 	register struct type *tp = *tpp; | ||||
| 	register struct e_stack *p; | ||||
|  | @ -290,8 +297,7 @@ gen_tphead(tpp, nest) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct type ** | ||||
| gen_tpmiddle() | ||||
| struct type **gen_tpmiddle(void) | ||||
| { | ||||
| 	register struct type *tp; | ||||
| 	register struct sdef *sd; | ||||
|  | @ -349,9 +355,7 @@ again: | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct sdef * | ||||
| gen_align_to_next(p) | ||||
| 	register struct e_stack *p; | ||||
| struct sdef *gen_align_to_next(register struct e_stack *p) | ||||
| { | ||||
| 	register struct sdef *sd = p->s_def; | ||||
| 
 | ||||
|  | @ -368,7 +372,7 @@ gen_align_to_next(p) | |||
| 	return sd; | ||||
| } | ||||
| 
 | ||||
| gen_tpend() | ||||
| void gen_tpend(void) | ||||
| { | ||||
| 	register struct e_stack *p = p_stack; | ||||
| 	register struct type *tp; | ||||
|  | @ -424,9 +428,7 @@ gen_tpend() | |||
| 	In the latter case, only the first member is initialised and | ||||
| 	the rest is zeroed. | ||||
| */ | ||||
| check_and_pad(expp, tpp) | ||||
| 	struct type **tpp; | ||||
| 	struct expr **expp; | ||||
| void check_and_pad(struct expr **expp, struct type **tpp) | ||||
| { | ||||
| 	register struct type *tp = *tpp; | ||||
| 
 | ||||
|  | @ -472,9 +474,7 @@ check_and_pad(expp, tpp) | |||
| /*	pad() fills an element of type tp with zeroes. | ||||
| 	If the element is an aggregate, pad() is called recursively. | ||||
| */ | ||||
| void | ||||
| pad(tpx) | ||||
| 	struct type *tpx; | ||||
| void pad(struct type *tpx) | ||||
| { | ||||
| 	register struct type *tp = tpx; | ||||
| 	register arith sz = tp->tp_size; | ||||
|  | @ -504,9 +504,7 @@ pad(tpx) | |||
| 	No further comment is needed to explain the internal structure | ||||
| 	of this straightforward function. | ||||
| */ | ||||
| check_ival(expp, tp) | ||||
| 	register struct type *tp; | ||||
| 	struct expr **expp; | ||||
| void check_ival(struct expr **expp, register struct type *tp) | ||||
| { | ||||
| 	/*	The philosophy here is that ch3cast puts an explicit | ||||
| 		conversion node in front of the expression if the types | ||||
|  | @ -617,9 +615,8 @@ and also to prevent runtime coercions for compile-time constants. | |||
| 	a string constant. | ||||
| 	Alignment is taken care of. | ||||
| */ | ||||
| ch_array(tpp, ex) | ||||
| 	struct type **tpp;	/* type tp = array of characters	*/ | ||||
| 	struct expr *ex; | ||||
| void ch_array(struct type **tpp,	/* type tp = array of characters	*/ | ||||
| 	struct expr *ex) | ||||
| { | ||||
| 	register struct type *tp = *tpp; | ||||
| 	register int length = ex->SG_LEN, i; | ||||
|  | @ -659,10 +656,7 @@ ch_array(tpp, ex) | |||
| /*	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, inrom) | ||||
| 	register char *str; | ||||
| 	register int len; | ||||
| 	int inrom; | ||||
| void str_cst(register char *str, register int len, int inrom) | ||||
| { | ||||
| 	int chunksize = ((127 + (int) word_size) / (int) word_size) * (int) word_size; | ||||
| 
 | ||||
|  | @ -686,9 +680,7 @@ str_cst(str, len, inrom) | |||
| 	"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; | ||||
| void put_bf(struct type *tp, arith val) | ||||
| { | ||||
| 	static long field = (arith)0; | ||||
| 	static arith offset = (arith)-1; | ||||
|  | @ -716,9 +708,7 @@ put_bf(tp, val) | |||
| } | ||||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| int | ||||
| zero_bytes(sd) | ||||
| 	register struct sdef *sd; | ||||
| int zero_bytes(register struct sdef *sd) | ||||
| { | ||||
| 	/*	fills the space between a selector of a struct | ||||
| 		and the next selector of that struct with zero-bytes. | ||||
|  | @ -732,10 +722,7 @@ zero_bytes(sd) | |||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| valid_type(tp, str) | ||||
| 	struct type *tp; | ||||
| 	char *str; | ||||
| int valid_type(struct type *tp, char *str) | ||||
| { | ||||
| 	assert(tp!=(struct type *)0); | ||||
| 	if (tp->tp_size < 0) { | ||||
|  | @ -745,8 +732,7 @@ valid_type(tp, str) | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| con_int(ex) | ||||
| 	register struct expr *ex; | ||||
| void con_int(register struct expr *ex) | ||||
| { | ||||
| 	register struct type *tp = ex->ex_type; | ||||
| 
 | ||||
|  | @ -759,14 +745,13 @@ con_int(ex) | |||
| 		C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size); | ||||
| } | ||||
| 
 | ||||
| illegal_init_cst(ex) | ||||
| 	struct expr *ex; | ||||
| void illegal_init_cst(struct expr *ex) | ||||
| { | ||||
| 	expr_error(ex, "illegal initialization constant"); | ||||
| 	gen_error = pack_level; | ||||
| } | ||||
| 
 | ||||
| too_many_initialisers() | ||||
| void too_many_initialisers(void) | ||||
| { | ||||
| 	error("too many initializers"); | ||||
| 	gen_error = pack_level; | ||||
|  |  | |||
|  | @ -14,11 +14,12 @@ | |||
| #include	"def.h" | ||||
| #include	"type.h" | ||||
| #include	"stack.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| 
 | ||||
| extern char options[]; | ||||
| 
 | ||||
| enter_label(idf, defining) | ||||
| 	register struct idf *idf; | ||||
| void enter_label(register struct idf *idf, int defining) | ||||
| { | ||||
| 	/*	The identifier idf is entered as a label. If it is new,
 | ||||
| 		it is entered into the idf list with the largest possible | ||||
|  | @ -45,8 +46,7 @@ enter_label(idf, defining) | |||
| 		def->df_initialized = 1; | ||||
| } | ||||
| 
 | ||||
| unstack_label(idf) | ||||
| 	register struct idf *idf; | ||||
| void unstack_label(register struct idf *idf) | ||||
| { | ||||
| 	/*	The scope in which the label idf occurred is left.
 | ||||
| 	*/ | ||||
|  |  | |||
|  | @ -4,6 +4,8 @@ | |||
|  */ | ||||
| /* $Id$ */ | ||||
| /*		L A B E L   D E F I N I T I O N				*/ | ||||
| #ifndef LABEL_H_ | ||||
| #define LABEL_H_ | ||||
| 
 | ||||
| #include <em_label.h>		/* obtain definition of "label" */ | ||||
| 
 | ||||
|  | @ -26,3 +28,10 @@ extern label datlab_count; | |||
| 		not be there, and if it is there, it may be from a | ||||
| 		declaration or another application. | ||||
| 	*/ | ||||
| 
 | ||||
| struct idf; | ||||
| 
 | ||||
| void enter_label(register struct idf *idf, int defining); | ||||
| void unstack_label(register struct idf *idf); | ||||
| 
 | ||||
| #endif /* LABEL_H_ */ | ||||
|  |  | |||
|  | @ -23,7 +23,13 @@ | |||
| #include	"specials.h" | ||||
| #include	"sizes.h" | ||||
| #include	"align.h" | ||||
| #include    "stack.h" | ||||
| #include	"macro.h" | ||||
| #include    "options.h" | ||||
| #include    "error.h" | ||||
| #include    "code.h" | ||||
| #include    "cstoper.h" | ||||
| #include    "tokenname.h" | ||||
| 
 | ||||
| extern struct tokenname tkidf[]; | ||||
| extern char *symbol2str(); | ||||
|  | @ -34,7 +40,15 @@ struct sp_id special_ids[] =	{ | |||
| 	{0, 0} | ||||
| }; | ||||
| 
 | ||||
| void dependency(); | ||||
| void compile(int argc, char *argv[]); | ||||
| static void init(void); | ||||
| static void init_specials(register struct sp_id *si); | ||||
| #ifdef DEBUG | ||||
| void Info(void); | ||||
| #endif | ||||
| 
 | ||||
| extern void C_program(void); /* program.c */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef NOCROSS | ||||
| arith | ||||
|  | @ -63,8 +77,7 @@ int | |||
| 
 | ||||
| char *prog_name; | ||||
| 
 | ||||
| main(argc, argv) | ||||
| 	char *argv[]; | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
| 	/* parse and interpret the command line options	*/ | ||||
| 	prog_name = argv[0]; | ||||
|  | @ -104,8 +117,7 @@ char *source = 0; | |||
| char *nmlist = 0; | ||||
| #endif /* GEN_NM_LIST */ | ||||
| 
 | ||||
| compile(argc, argv) | ||||
| 	char *argv[]; | ||||
| void compile(int argc, char *argv[]) | ||||
| { | ||||
| 	char *result; | ||||
| #ifndef	LINT | ||||
|  | @ -190,7 +202,7 @@ compile(argc, argv) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| init() | ||||
| static void init(void) | ||||
| { | ||||
| 	init_cst();	/* initialize variables of "cstoper.c"		*/ | ||||
| 	reserve(tkidf);		/* mark the C reserved words as such	*/ | ||||
|  | @ -255,8 +267,7 @@ init() | |||
| 	stack_level(); | ||||
| } | ||||
| 
 | ||||
| init_specials(si) | ||||
| 	register struct sp_id *si; | ||||
| static void init_specials(register struct sp_id *si) | ||||
| { | ||||
| 	while (si->si_identifier)	{ | ||||
| 		struct idf *idf = str2idf(si->si_identifier, 0); | ||||
|  | @ -269,7 +280,7 @@ init_specials(si) | |||
| } | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| Info() | ||||
| void Info(void) | ||||
| { | ||||
| 	extern int cnt_string_cst, cnt_formal, | ||||
| 		    cnt_decl_unary, cnt_def, cnt_expr, cnt_field, | ||||
|  | @ -301,14 +312,12 @@ Info() | |||
| } | ||||
| #endif /* DEBUG */ | ||||
| 
 | ||||
| void | ||||
| No_Mem()				/* called by alloc package */ | ||||
| void No_Mem(void)				/* called by alloc package */ | ||||
| { | ||||
| 	fatal("out of memory"); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| C_failed()				/* called by EM_code module */ | ||||
| void C_failed(void)				/* called by EM_code module */ | ||||
| { | ||||
| 	fatal("write failed"); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										1
									
								
								lang/cem/cemcom.ansi/next.str
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lang/cem/cemcom.ansi/next.str
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| #include "parameters.h" | ||||
|  | @ -9,12 +9,14 @@ | |||
| #include	<stdlib.h> | ||||
| #include	<string.h> | ||||
| #include	<alloc.h> | ||||
| #include    "options.h" | ||||
| #include	"class.h" | ||||
| #include	"macro.h" | ||||
| #include	"idf.h" | ||||
| #include	"arith.h" | ||||
| #include	"sizes.h" | ||||
| #include	"align.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| char options[128];			/* one for every char	*/ | ||||
| #ifdef	LINT | ||||
|  | @ -24,10 +26,11 @@ char loptions[128];			/* one for every char	*/ | |||
| extern int idfsize; | ||||
| extern int density; | ||||
| 
 | ||||
| static int txt2int(); | ||||
| 
 | ||||
| do_option(text) | ||||
| 	char *text; | ||||
| 
 | ||||
| static int txt2int(register char **); | ||||
| 
 | ||||
| void do_option(char *text) | ||||
| { | ||||
| 	register char opt; | ||||
| 
 | ||||
|  | @ -209,9 +212,7 @@ next_option:			/* to allow combined one-char options */ | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| txt2int(tp) | ||||
| 	register char **tp; | ||||
| static int txt2int(register char **tp) | ||||
| { | ||||
| 	/*	the integer pointed to by *tp is read, while increasing
 | ||||
| 		*tp; the resulting value is yielded. | ||||
|  |  | |||
							
								
								
									
										13
									
								
								lang/cem/cemcom.ansi/options.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lang/cem/cemcom.ansi/options.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-07 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef OPTIONS_H_ | ||||
| #define OPTIONS_H_ | ||||
| 
 | ||||
| void do_option(char *text); | ||||
| 
 | ||||
| #endif /* OPTIONS_H_ */ | ||||
|  | @ -6,37 +6,43 @@ | |||
| /* PREPROCESSOR: PRAGMA INTERPRETER */ | ||||
| 
 | ||||
| #include	"parameters.h" | ||||
| #include    "pragma.h" | ||||
| #include    "skip.h" | ||||
| 
 | ||||
| #define P_UNKNOWN	0 | ||||
| #define NR_PRAGMAS	0 | ||||
| 
 | ||||
| struct pkey { | ||||
| struct pkey | ||||
| { | ||||
| 	char *pk_name; | ||||
| 	int pk_key; | ||||
| } pragmas[NR_PRAGMAS + 1] = { | ||||
| 	{0,		P_UNKNOWN} | ||||
| }; | ||||
| } pragmas[NR_PRAGMAS + 1] = | ||||
| { | ||||
| { 0, P_UNKNOWN } }; | ||||
| 
 | ||||
| extern struct idf *GetIdentifier(); | ||||
| 
 | ||||
| do_pragma() | ||||
| void do_pragma(void) | ||||
| { | ||||
| #if	NR_PRAGMAS | ||||
| 	register struct pkey *pkp = &pragmas[0]; | ||||
| #endif | ||||
| 	register struct idf *id = GetIdentifier(1); | ||||
| 
 | ||||
| 	if (id != (struct idf *)0) { | ||||
| 	if (id != (struct idf *) 0) | ||||
| 	{ | ||||
| #if	NR_PRAGMAS | ||||
| 		while(pkp->pk_name) { | ||||
| 		while(pkp->pk_name) | ||||
| 		{ | ||||
| 			if (strcmp(pkp->pk_name, id->id_text) == 0) | ||||
| 				break; | ||||
| 			break; | ||||
| 			pkp++; | ||||
| 		} | ||||
| 
 | ||||
| 		switch (pkp->pk_key) { | ||||
| 		case P_UNKNOWN: | ||||
| 		default: | ||||
| 		switch (pkp->pk_key) | ||||
| 		{ | ||||
| 			case P_UNKNOWN: | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										13
									
								
								lang/cem/cemcom.ansi/pragma.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lang/cem/cemcom.ansi/pragma.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-07 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef PRAGMA_H_ | ||||
| #define PRAGMA_H_ | ||||
| 
 | ||||
| void do_pragma(void); | ||||
| 
 | ||||
| #endif /* PRAGMA_H_ */ | ||||
|  | @ -56,12 +56,15 @@ | |||
| #include	"code.h" | ||||
| #include	"expr.h" | ||||
| #include	"def.h" | ||||
| #include    "idf.h" | ||||
| #include    "declarator.h" | ||||
| #include    "stack.h" | ||||
| #include    "proto.h" | ||||
| #include    "error.h" | ||||
| #ifdef	LINT | ||||
| #include	"l_lint.h" | ||||
| #endif	/* LINT */ | ||||
| 
 | ||||
| extern error(); | ||||
| } | ||||
| 
 | ||||
| control_if_expression | ||||
|  |  | |||
|  | @ -23,20 +23,24 @@ | |||
| #include	"declar.h" | ||||
| #include	"decspecs.h" | ||||
| #include	"proto.h" | ||||
| #include    "error.h" | ||||
| #include    "ch3.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
| 
 | ||||
| void | ||||
| check_for_void(pl) | ||||
| 	register struct proto *pl; | ||||
| void check_for_void(register struct proto *pl) | ||||
| { | ||||
| 	register int errcnt = 0; | ||||
| 
 | ||||
| 	if (!pl) return; | ||||
| 	if ((pl->pl_flag & PL_VOID) && !(pl->next)) return; | ||||
| 	if (!pl) | ||||
| 		return; | ||||
| 	if ((pl->pl_flag & PL_VOID) && !(pl->next)) | ||||
| 		return; | ||||
| 
 | ||||
| 	while (pl) { | ||||
| 		if (pl->pl_flag & PL_VOID) { | ||||
| 	while (pl) | ||||
| 	{ | ||||
| 		if (pl->pl_flag & PL_VOID) | ||||
| 		{ | ||||
| 			if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN)) | ||||
| 				error("illegal use of void in argument list"); | ||||
| 			pl->pl_flag |= PL_ERRGIVEN; | ||||
|  | @ -46,37 +50,35 @@ check_for_void(pl) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| add_proto(pl, ds, dc, lvl) | ||||
| 	struct proto *pl; | ||||
| 	struct decspecs *ds; | ||||
| 	struct declarator *dc; | ||||
| 	int lvl; | ||||
| void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc, | ||||
| 		int lvl) | ||||
| { | ||||
| 	/*	The full typed identifier or abstract type, described
 | ||||
| 		by the structures decspecs and declarator are turned | ||||
| 		a into parameter type list structure. | ||||
| 		The parameters will be declared at level L_FORMAL2, | ||||
| 		later on it's decided whether they were prototypes | ||||
| 		or actual declarations. | ||||
| 	*/ | ||||
| 	 by the structures decspecs and declarator are turned | ||||
| 	 a into parameter type list structure. | ||||
| 	 The parameters will be declared at level L_FORMAL2, | ||||
| 	 later on it's decided whether they were prototypes | ||||
| 	 or actual declarations. | ||||
| 	 */ | ||||
| 	register struct idf *idf = dc->dc_idf; | ||||
| 	register struct def *def = idf ? idf->id_def : (struct def *)0; | ||||
| 	register struct def *def = idf ? idf->id_def : (struct def *) 0; | ||||
| 	register int sc = ds->ds_sc; | ||||
| 	register struct type *type; | ||||
| 	char formal_array = 0; | ||||
| 
 | ||||
| 	assert(ds->ds_type != (struct type *)0); | ||||
| 	assert(ds->ds_type != (struct type * )0); | ||||
| 
 | ||||
| 	pl->pl_flag = PL_FORMAL; | ||||
| 	type = declare_type(ds->ds_type, dc); | ||||
| 	if (type->tp_size < (arith)0 && actual_declaration(sc, type)) { | ||||
| 	if (type->tp_size < (arith) 0 && actual_declaration(sc, type)) | ||||
| 	{ | ||||
| 		extern char *symbol2str(); | ||||
| 		if (type->tp_fund != VOID) | ||||
| 			error("unknown %s-type", symbol2str(type->tp_fund)); | ||||
| 		else { | ||||
| 			if (idf != (struct idf *)0 | ||||
| 			    || ds->ds_sc_given | ||||
| 			    || ds->ds_typequal) { | ||||
| 		else | ||||
| 		{ | ||||
| 			if (idf != (struct idf *) 0 || ds->ds_sc_given || ds->ds_typequal) | ||||
| 			{ | ||||
| 				error("illegal use of void in argument list"); | ||||
| 				pl->pl_flag |= PL_ERRGIVEN; | ||||
| 			} | ||||
|  | @ -84,41 +86,52 @@ add_proto(pl, ds, dc, lvl) | |||
| 			pl->pl_flag |= PL_VOID; | ||||
| 		} | ||||
| 	} | ||||
| 	if (ds->ds_sc_given && ds->ds_sc != REGISTER) { | ||||
| 		if (!(pl->pl_flag & PL_ERRGIVEN)) { | ||||
| 		    if (ds->ds_sc != AUTO) { | ||||
| 			error("illegal storage class in parameter declaration"); | ||||
| 		    } else { | ||||
| 			warning("illegal storage class in parameter declaration"); | ||||
| 		    } | ||||
| 	if (ds->ds_sc_given && ds->ds_sc != REGISTER) | ||||
| 	{ | ||||
| 		if (!(pl->pl_flag & PL_ERRGIVEN)) | ||||
| 		{ | ||||
| 			if (ds->ds_sc != AUTO) | ||||
| 			{ | ||||
| 				error("illegal storage class in parameter declaration"); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				warning("illegal storage class in parameter declaration"); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*	Perform some special conversions for parameters.
 | ||||
| 	*/ | ||||
| 	if (type->tp_fund == FUNCTION) { | ||||
| 	 */ | ||||
| 	if (type->tp_fund == FUNCTION) | ||||
| 	{ | ||||
| 		type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO); | ||||
| 	} else if (type->tp_fund == ARRAY) { | ||||
| 	} | ||||
| 	else if (type->tp_fund == ARRAY) | ||||
| 	{ | ||||
| 		type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO); | ||||
| 		formal_array = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	/*	According to the standard we should ignore the storage
 | ||||
| 		class of a parameter, unless it's part of a function | ||||
| 		definition. | ||||
| 		However, in the routine declare_protos we don't know decspecs, | ||||
| 		and therefore we can't complain up there. So we build up the | ||||
| 		storage class, and keep quiet until we reach declare_protos. | ||||
| 	*/ | ||||
| 	sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? | ||||
| 				0 : sc == 0 ? FORMAL : REGISTER; | ||||
| 	 class of a parameter, unless it's part of a function | ||||
| 	 definition. | ||||
| 	 However, in the routine declare_protos we don't know decspecs, | ||||
| 	 and therefore we can't complain up there. So we build up the | ||||
| 	 storage class, and keep quiet until we reach declare_protos. | ||||
| 	 */ | ||||
| 	sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? 0 : | ||||
| 			sc == 0 ? FORMAL : REGISTER; | ||||
| 
 | ||||
| 	if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */ )) { | ||||
| 	if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */)) | ||||
| 	{ | ||||
| 		/* redeclaration at the same level */ | ||||
| 		error("parameter %s redeclared", idf->id_text); | ||||
| 	} else if (idf != (struct idf *)0) { | ||||
| 	} | ||||
| 	else if (idf != (struct idf *) 0) | ||||
| 	{ | ||||
| 		/*	New definition, redefinition hides earlier one
 | ||||
| 		*/ | ||||
| 		 */ | ||||
| 		register struct def *newdef = new_def(); | ||||
| 
 | ||||
| 		newdef->next = def; | ||||
|  | @ -133,28 +146,28 @@ add_proto(pl, ds, dc, lvl) | |||
| 		/* newdef->df_firstbrace = 0; */ | ||||
| #endif | ||||
| 		/*	We can't put the idf onto the stack, since these kinds
 | ||||
| 			of declaration may occurs at any level, and the idf | ||||
| 			does not necessarily go at this level. E.g. | ||||
| 		 of declaration may occurs at any level, and the idf | ||||
| 		 does not necessarily go at this level. E.g. | ||||
| 
 | ||||
| 			f() { | ||||
| 			... | ||||
| 				{ int func(int a, int b); | ||||
| 				... | ||||
| 				} | ||||
| 			} | ||||
| 		 f() { | ||||
| 		 ... | ||||
| 		 { int func(int a, int b); | ||||
| 		 ... | ||||
| 		 } | ||||
| 		 } | ||||
| 
 | ||||
| 			The idf's a and b declared in the prototype declaration | ||||
| 			do not go at any level, they are simply ignored. | ||||
| 			However, in | ||||
| 		 The idf's a and b declared in the prototype declaration | ||||
| 		 do not go at any level, they are simply ignored. | ||||
| 		 However, in | ||||
| 
 | ||||
| 			f(int a, int b) { | ||||
| 			... | ||||
| 			} | ||||
| 		 f(int a, int b) { | ||||
| 		 ... | ||||
| 		 } | ||||
| 
 | ||||
| 			They should go at level L_FORMAL2. But at this stage | ||||
| 			we don't know whether we have a prototype or function | ||||
| 			definition. So, this process is postponed. | ||||
| 		*/ | ||||
| 		 They should go at level L_FORMAL2. But at this stage | ||||
| 		 we don't know whether we have a prototype or function | ||||
| 		 definition. So, this process is postponed. | ||||
| 		 */ | ||||
| 		idf->id_def = newdef; | ||||
| 		update_ahead(idf); | ||||
| 	} | ||||
|  | @ -163,35 +176,33 @@ add_proto(pl, ds, dc, lvl) | |||
| 	pl->pl_type = type; | ||||
| } | ||||
| 
 | ||||
| struct tag * | ||||
| gettag(tp, idpp) | ||||
| struct type *tp; | ||||
| struct idf **idpp; | ||||
| static struct tag * gettag(struct type *tp, struct idf **idpp) | ||||
| { | ||||
| 	struct tag *tg = (struct tag *)0; | ||||
| 	struct tag *tg = (struct tag *) 0; | ||||
| 	register int fund = tp->tp_fund; | ||||
| 
 | ||||
|         while (fund == FIELD || fund == POINTER | ||||
|                 || fund == ARRAY || fund == FUNCTION) { | ||||
|                 tp = tp->tp_up; | ||||
|                 fund = tp->tp_fund; | ||||
|         } | ||||
| 	while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION) | ||||
| 	{ | ||||
| 		tp = tp->tp_up; | ||||
| 		fund = tp->tp_fund; | ||||
| 	} | ||||
| 	*idpp = tp->tp_idf; | ||||
| 	switch(tp->tp_fund) { | ||||
| 	switch (tp->tp_fund) | ||||
| 	{ | ||||
| 	case ENUM: | ||||
| 	case UNION: | ||||
| 	case STRUCT: tg = tp->tp_idf->id_tag; break; | ||||
| 	case STRUCT: | ||||
| 		tg = tp->tp_idf->id_tag; | ||||
| 		break; | ||||
| 	} | ||||
| 	return tg; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| declare_protos(dc) | ||||
| 	register struct declarator *dc; | ||||
| void declare_protos(register struct declarator *dc) | ||||
| { | ||||
| 	/*	At this points we know that the idf's in protolist are formal
 | ||||
| 		parameters. So it's time to declare them at level L_FORMAL2. | ||||
| 	*/ | ||||
| 	 parameters. So it's time to declare them at level L_FORMAL2. | ||||
| 	 */ | ||||
| 	struct stack_level *stl = stack_level_of(L_FORMAL1); | ||||
| 	register struct decl_unary *du; | ||||
| 	register struct type *type; | ||||
|  | @ -200,31 +211,39 @@ declare_protos(dc) | |||
| 
 | ||||
| #ifdef	DEBUG | ||||
| 	if (options['t']) | ||||
| 		dumpidftab("start declare_protos", 0); | ||||
| 	dumpidftab("start declare_protos", 0); | ||||
| #endif	/* DEBUG */ | ||||
| 	du = dc->dc_decl_unary; | ||||
| 	while (du) { | ||||
| 		if (du->du_fund == FUNCTION) { | ||||
| 			if (du->next != (struct decl_unary *) 0) { | ||||
| 	while (du) | ||||
| 	{ | ||||
| 		if (du->du_fund == FUNCTION) | ||||
| 		{ | ||||
| 			if (du->next != (struct decl_unary *) 0) | ||||
| 			{ | ||||
| 				remove_proto_idfs(du->du_proto); | ||||
| 				du->du_proto = 0; | ||||
| 			} else break; | ||||
| 			} | ||||
| 			else | ||||
| 				break; | ||||
| 		} | ||||
| 		du = du->next; | ||||
| 	} | ||||
| 	pl = du ? du->du_proto : NO_PROTO; | ||||
| 	if (pl) { | ||||
| 	if (pl) | ||||
| 	{ | ||||
| #if	0 /* the id_proto member is deleted (???) */
 | ||||
| 		idf->id_proto = 0; | ||||
| #endif	/* 0 */ | ||||
| 		do { | ||||
| 		do | ||||
| 		{ | ||||
| 			struct tag *tg; | ||||
| 			struct idf *idp = 0; | ||||
| 
 | ||||
| 			type = pl->pl_type; | ||||
| 
 | ||||
| 			/* `...' only for type checking */ | ||||
| 			if (pl->pl_flag & PL_ELLIPSIS) { | ||||
| 			if (pl->pl_flag & PL_ELLIPSIS) | ||||
| 			{ | ||||
| 				pl = pl->next; | ||||
| 				continue; | ||||
| 			} | ||||
|  | @ -233,14 +252,15 @@ declare_protos(dc) | |||
| 			if (type->tp_fund == VOID) | ||||
| 				break; | ||||
| 
 | ||||
| 			if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) { | ||||
| 			if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) | ||||
| 			{ | ||||
| 				error("no parameter identifier supplied"); | ||||
| 				pl = pl->next; | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			/*	Postponed storage class checking.
 | ||||
| 			*/ | ||||
| 			 */ | ||||
| 			if (def->df_sc == 0) | ||||
| 				error("illegal storage class in parameter declaration"); | ||||
| 
 | ||||
|  | @ -249,7 +269,8 @@ declare_protos(dc) | |||
| 			pl = pl->next; | ||||
| 
 | ||||
| 			tg = gettag(type, &idp); | ||||
| 			if (tg && tg->tg_level <= L_PROTO) { | ||||
| 			if (tg && tg->tg_level <= L_PROTO) | ||||
| 			{ | ||||
| 				tg->tg_level = L_FORMAL2; | ||||
| 				stack_idf(idp, stl); | ||||
| 			} | ||||
|  | @ -257,43 +278,47 @@ declare_protos(dc) | |||
| 	} | ||||
| #ifdef	DEBUG | ||||
| 	if (options['t']) | ||||
| 		dumpidftab("end declare_protos", 0); | ||||
| 	dumpidftab("end declare_protos", 0); | ||||
| #endif	/* DEBUG */ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void | ||||
| update_proto(tp, otp) | ||||
| 	register struct type *tp, *otp; | ||||
| void update_proto(register struct type *tp, register struct type *otp) | ||||
| { | ||||
| 	/*	This routine performs the proto type updates.
 | ||||
| 		Consider the following code: | ||||
| 	 Consider the following code: | ||||
| 
 | ||||
| 		int f(double g()); | ||||
| 		int f(double g(int f(), int)); | ||||
| 		int f(double g(int f(long double), int)); | ||||
| 	 int f(double g()); | ||||
| 	 int f(double g(int f(), int)); | ||||
| 	 int f(double g(int f(long double), int)); | ||||
| 
 | ||||
| 		The most accurate definition is the third line. | ||||
| 		This routine will silently update all lists, | ||||
| 		and removes the redundant occupied space. | ||||
| 	*/ | ||||
| 	 The most accurate definition is the third line. | ||||
| 	 This routine will silently update all lists, | ||||
| 	 and removes the redundant occupied space. | ||||
| 	 */ | ||||
| 	register struct proto *pl, *opl; | ||||
| 
 | ||||
| 	if (tp == otp) return; | ||||
| 	if (!tp || !otp) return; | ||||
| 	if (tp == otp) | ||||
| 		return; | ||||
| 	if (!tp || !otp) | ||||
| 		return; | ||||
| 
 | ||||
| 	while (tp->tp_fund != FUNCTION) { | ||||
| 		if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) return; | ||||
| 	while (tp->tp_fund != FUNCTION) | ||||
| 	{ | ||||
| 		if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) | ||||
| 			return; | ||||
| 		tp = tp->tp_up; | ||||
| 		otp = otp->tp_up; | ||||
| 		if (!tp) return; | ||||
| 		if (!tp) | ||||
| 			return; | ||||
| 	} | ||||
| 
 | ||||
| 	pl = tp->tp_proto; | ||||
| 	opl = otp->tp_proto; | ||||
| 	if (pl && opl) { | ||||
| 	if (pl && opl) | ||||
| 	{ | ||||
| 		/* both have prototypes */ | ||||
| 		while (pl && opl) { | ||||
| 		while (pl && opl) | ||||
| 		{ | ||||
| 			update_proto(pl->pl_type, opl->pl_type); | ||||
| 			pl = pl->next; | ||||
| 			opl = opl->next; | ||||
|  | @ -302,9 +327,13 @@ update_proto(tp, otp) | |||
| 		 * a typedef. | ||||
| 		 */ | ||||
| 		otp->tp_proto = tp->tp_proto; | ||||
| 	} else if (opl) { | ||||
| 	} | ||||
| 	else if (opl) | ||||
| 	{ | ||||
| 		/* old decl has type */ | ||||
| 	} else if (pl) { | ||||
| 	} | ||||
| 	else if (pl) | ||||
| 	{ | ||||
| 		otp->tp_proto = pl; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -314,39 +343,44 @@ update_proto(tp, otp) | |||
| /* struct/union and enum tags can be declared inside prototypes
 | ||||
|  * remove them from the symbol-table | ||||
|  */ | ||||
| void | ||||
| remove_proto_tag(tp) | ||||
| struct type *tp; | ||||
| static void remove_proto_tag(struct type *tp) | ||||
| { | ||||
| 	register struct idf *ident; | ||||
| 	register struct tag *tgp, **tgpp; | ||||
| 	register int fund = tp->tp_fund; | ||||
| 
 | ||||
| 	while (fund == FIELD || fund == POINTER | ||||
| 		|| fund == ARRAY || fund == FUNCTION) { | ||||
| 	while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION) | ||||
| 	{ | ||||
| 		tp = tp->tp_up; | ||||
| 		fund = tp->tp_fund; | ||||
| 	} | ||||
| 
 | ||||
| 	ident = tp->tp_idf; | ||||
| 	switch (tp->tp_fund) { | ||||
| 	switch (tp->tp_fund) | ||||
| 	{ | ||||
| 	case ENUM: | ||||
| 	case STRUCT: | ||||
| 	case UNION: tgpp = &(ident->id_tag); break; | ||||
| 	default: return; | ||||
| 	case UNION: | ||||
| 		tgpp = &(ident->id_tag); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	while((*tgpp) && (*tgpp)->tg_type != tp) { | ||||
| 	while ((*tgpp) && (*tgpp)->tg_type != tp) | ||||
| 	{ | ||||
| 		tgpp = &((*tgpp)->next); | ||||
| 	} | ||||
| 	if (!*tgpp) return; | ||||
| 	if (!*tgpp) | ||||
| 		return; | ||||
| 
 | ||||
| 	tgp = *tgpp; | ||||
| 	if (tgp->tg_level > L_PROTO) return; | ||||
| 	if (tgp->tg_level > L_PROTO) | ||||
| 		return; | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| 	if (options['t']) | ||||
| 		print("Removing idf %s from list\n", | ||||
| 	print("Removing idf %s from list\n", | ||||
| 			ident->id_text); | ||||
| #endif | ||||
| 
 | ||||
|  | @ -354,52 +388,55 @@ struct type *tp; | |||
| 	free_tag(tgp); | ||||
| } | ||||
| 
 | ||||
| remove_proto_idfs(pl) | ||||
| 	register struct proto *pl; | ||||
| /*	Remove all the identifier definitions from the
 | ||||
| 	 prototype list. */ | ||||
| void remove_proto_idfs(register struct proto *pl) | ||||
| { | ||||
| 	/*	Remove all the identifier definitions from the
 | ||||
| 		prototype list. | ||||
| 	*/ | ||||
| 
 | ||||
| 	register struct def *def; | ||||
| 
 | ||||
| 	while (pl) { | ||||
| 		if (pl->pl_idf) { | ||||
| 	while (pl) | ||||
| 	{ | ||||
| 		if (pl->pl_idf) | ||||
| 		{ | ||||
| #ifdef DEBUG | ||||
| 			if (options['t']) | ||||
| 				print("Removing idf %s from list\n", | ||||
| 			print("Removing idf %s from list\n", | ||||
| 					pl->pl_idf->id_text); | ||||
| #endif | ||||
| 			def = pl->pl_idf->id_def; | ||||
| 			if (def && def->df_level <= L_PROTO) { | ||||
| 			if (def && def->df_level <= L_PROTO) | ||||
| 			{ | ||||
| 				pl->pl_idf->id_def = def->next; | ||||
| 				free_def(def); | ||||
| 			} | ||||
| 			pl->pl_idf = (struct idf *) 0; | ||||
| 		} | ||||
| 		if (pl->pl_type) { | ||||
| 		if (pl->pl_type) | ||||
| 		{ | ||||
| 			remove_proto_tag(pl->pl_type); | ||||
| 		} | ||||
| 		pl = pl->next; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| call_proto(expp) | ||||
| 	register struct expr **expp; | ||||
| void call_proto(register struct expr **expp) | ||||
| { | ||||
| 	/*	If the function specified by (*expp)->OP_LEFT has a prototype,
 | ||||
| 		the parameters are converted according the rules specified in | ||||
| 		par. 3.3.2.2. E.i. the parameters are converted to the prototype | ||||
| 		counter parts as if by assignment. For the parameters falling | ||||
| 		under ellipsis clause the old parameters conversion stuff | ||||
| 		applies. | ||||
| 	*/ | ||||
| 	 the parameters are converted according the rules specified in | ||||
| 	 par. 3.3.2.2. E.i. the parameters are converted to the prototype | ||||
| 	 counter parts as if by assignment. For the parameters falling | ||||
| 	 under ellipsis clause the old parameters conversion stuff | ||||
| 	 applies. | ||||
| 	 */ | ||||
| 	register struct expr *left = (*expp)->OP_LEFT; | ||||
| 	register struct expr *right = (*expp)->OP_RIGHT; | ||||
| 	register struct proto *pl = NO_PROTO; | ||||
| 	static struct proto ellipsis = { 0, 0, 0, PL_ELLIPSIS }; | ||||
| 	static struct proto ellipsis = | ||||
| 	{ 0, 0, 0, PL_ELLIPSIS }; | ||||
| 
 | ||||
| 	if (left != NILEXPR) {		/* in case of an error */ | ||||
| 	if (left != NILEXPR) | ||||
| 	{ /* in case of an error */ | ||||
| 		register struct type *tp = left->ex_type; | ||||
| 
 | ||||
| 		while (tp && tp->tp_fund != FUNCTION && tp != error_type) | ||||
|  | @ -408,17 +445,20 @@ call_proto(expp) | |||
| 			pl = tp->tp_proto; | ||||
| 	} | ||||
| 
 | ||||
| 	if (right != NILEXPR) {		/* function call with parameters */ | ||||
| 	if (right != NILEXPR) | ||||
| 	{ /* function call with parameters */ | ||||
| 		register struct expr **ep = &((*expp)->OP_RIGHT); | ||||
| 		register int ecnt = 0, pcnt = 0; | ||||
| 		struct expr **estack[NPARAMS]; | ||||
| 		struct proto *pstack[NPARAMS]; | ||||
| 
 | ||||
| 		/* stack up the parameter expressions */ | ||||
| 		while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) { | ||||
| 		while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) | ||||
| 		{ | ||||
| 			if (ecnt == STDC_NPARAMS) | ||||
| 				expr_strict(right, "number of parameters exceeds ANSI limit"); | ||||
| 			if (ecnt >= NPARAMS-1) { | ||||
| 			if (ecnt >= NPARAMS - 1) | ||||
| 			{ | ||||
| 				expr_error(right, "too many parameters"); | ||||
| 				return; | ||||
| 			} | ||||
|  | @ -429,45 +469,56 @@ call_proto(expp) | |||
| 		estack[ecnt] = ep; | ||||
| 
 | ||||
| 		/*	Declarations like int f(void) do not expect any
 | ||||
| 			parameters. | ||||
| 		*/ | ||||
| 		if (pl && pl->pl_flag & PL_VOID) { | ||||
| 		 parameters. | ||||
| 		 */ | ||||
| 		if (pl && pl->pl_flag & PL_VOID) | ||||
| 		{ | ||||
| 			expr_strict(*expp, "no parameters expected"); | ||||
| 			pl = NO_PROTO; | ||||
| 		} | ||||
| 
 | ||||
| 		/* stack up the prototypes */ | ||||
| 		if (pl) { | ||||
| 		if (pl) | ||||
| 		{ | ||||
| 			pcnt--; | ||||
| 			do { | ||||
| 			do | ||||
| 			{ | ||||
| 				/* stack prototypes */ | ||||
| 				pstack[++pcnt] = pl; | ||||
| 				pl = pl->next; | ||||
| 			} while (pl); | ||||
| 		} | ||||
| 		else { | ||||
| 		else | ||||
| 		{ | ||||
| 			pstack[0] = &ellipsis; | ||||
| 		} | ||||
| 
 | ||||
| 		for (ecnt; ecnt >= 0; ecnt--) { | ||||
| 		for (ecnt; ecnt >= 0; ecnt--) | ||||
| 		{ | ||||
| 			/*	Only the parameters specified in the prototype
 | ||||
| 				are checked and converted. The parameters that | ||||
| 				fall under the ellipsis clause are neither | ||||
| 				checked nor converted ! | ||||
| 			*/ | ||||
| 			if (pcnt < 0) { | ||||
| 				expr_error(*expp, "more parameters than specified in prototype"); | ||||
| 			 are checked and converted. The parameters that | ||||
| 			 fall under the ellipsis clause are neither | ||||
| 			 checked nor converted ! | ||||
| 			 */ | ||||
| 			if (pcnt < 0) | ||||
| 			{ | ||||
| 				expr_error(*expp, | ||||
| 						"more parameters than specified in prototype"); | ||||
| 				break; | ||||
| 			} | ||||
| 			else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) { | ||||
| 				ch3cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type); | ||||
| 			else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) | ||||
| 			{ | ||||
| 				ch3cast(estack[ecnt], CASTAB, pstack[pcnt]->pl_type); | ||||
| 				pcnt--; | ||||
| 			} else | ||||
| 			} | ||||
| 			else | ||||
| 				any2parameter(estack[ecnt]); | ||||
| 		} | ||||
| 		if (pcnt > 0 || (pcnt == 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS))) | ||||
| 			expr_error(*expp, "fewer parameters than specified in prototype"); | ||||
| 	} else { | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if (pl && !(pl->pl_flag & PL_VOID)) | ||||
| 			expr_error(*expp, "fewer parameters than specified in prototype"); | ||||
| 	} | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef PROTO_H | ||||
| #define PROTO_H | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| /* PARAMETER TYPE LIST DEFINITION */ | ||||
| 
 | ||||
|  | @ -20,3 +23,20 @@ struct proto { | |||
| #define	PL_ERRGIVEN	0x08 | ||||
| 
 | ||||
| /* ALLOCDEF "proto" 20 */ | ||||
| 
 | ||||
| /* Forward structure declarations */ | ||||
| struct expr; | ||||
| struct type; | ||||
| struct declarator; | ||||
| struct decspecs; | ||||
| 
 | ||||
| 
 | ||||
| void remove_proto_idfs(register struct proto *pl); | ||||
| void call_proto(register struct expr **expp); | ||||
| void update_proto(register struct type *tp, register struct type *otp); | ||||
| void declare_protos(register struct declarator *dc); | ||||
| void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc, | ||||
| 		int lvl); | ||||
| void check_for_void(register struct proto *pl); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -10,9 +10,10 @@ | |||
| #include "LLlex.h" | ||||
| #include "class.h" | ||||
| #include "input.h" | ||||
| #include "skip.h" | ||||
| 
 | ||||
| 
 | ||||
| SkipToNewLine() | ||||
| int SkipToNewLine(void) | ||||
| { | ||||
| 	register int ch; | ||||
| 	register int garbage = 0; | ||||
|  |  | |||
							
								
								
									
										13
									
								
								lang/cem/cemcom.ansi/skip.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lang/cem/cemcom.ansi/skip.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-07 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef SKIP_H_ | ||||
| #define SKIP_H_ | ||||
| 
 | ||||
| int SkipToNewLine(void); | ||||
| 
 | ||||
| #endif /* SKIP_H_ */ | ||||
|  | @ -20,6 +20,7 @@ | |||
| #include	<flt_arith.h> | ||||
| #include	<stb.h> | ||||
| 
 | ||||
| #include    "stab.h" | ||||
| #include    "idf.h" | ||||
| #include	"LLlex.h" | ||||
| #include	"stack.h" | ||||
|  | @ -29,34 +30,34 @@ | |||
| #include	"field.h" | ||||
| #include	"Lpars.h" | ||||
| #include	"level.h" | ||||
| #include    "print.h" | ||||
| 
 | ||||
| extern long	full_mask[]; | ||||
| extern char	*sprint(); | ||||
| extern long full_mask[]; | ||||
| 
 | ||||
| #define INCR_SIZE	64 | ||||
| 
 | ||||
| static struct db_str { | ||||
| 	unsigned	sz; | ||||
| 	char		*base; | ||||
| 	char		*currpos; | ||||
| static struct db_str | ||||
| { | ||||
| 	unsigned sz; | ||||
| 	char *base; | ||||
| 	char *currpos; | ||||
| } db_str; | ||||
| 
 | ||||
| static | ||||
| create_db_str() | ||||
| static void create_db_str(void) | ||||
| { | ||||
| 	if (! db_str.base) { | ||||
| 	if (!db_str.base) | ||||
| 	{ | ||||
| 		db_str.base = Malloc(INCR_SIZE); | ||||
| 		db_str.sz = INCR_SIZE; | ||||
| 	} | ||||
| 	db_str.currpos = db_str.base; | ||||
| } | ||||
| 
 | ||||
| static | ||||
| addc_db_str(c) | ||||
| 	int	c; | ||||
| static void addc_db_str(int c) | ||||
| { | ||||
| 	int df = db_str.currpos - db_str.base; | ||||
| 	if (df >= db_str.sz-1) { | ||||
| 	if (df >= db_str.sz - 1) | ||||
| 	{ | ||||
| 		db_str.sz += INCR_SIZE; | ||||
| 		db_str.base = Realloc(db_str.base, db_str.sz); | ||||
| 		db_str.currpos = db_str.base + df; | ||||
|  | @ -65,34 +66,35 @@ addc_db_str(c) | |||
| 	*db_str.currpos = '\0'; | ||||
| } | ||||
| 
 | ||||
| static | ||||
| adds_db_str(s) | ||||
| 	char	*s; | ||||
| static void adds_db_str(char *s) | ||||
| { | ||||
| 	while (*s) addc_db_str(*s++); | ||||
| 	while (*s) | ||||
| 		addc_db_str(*s++); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| stb_type(tp) | ||||
| 	register struct type	*tp; | ||||
| static void stb_type(register struct type *tp) | ||||
| { | ||||
| 	char		buf[128]; | ||||
| 	static int	stb_count; | ||||
| 	long		l; | ||||
| 	char buf[128]; | ||||
| 	static int stb_count; | ||||
| 	long l; | ||||
| 
 | ||||
| 	if (tp->tp_dbindex > 0) { | ||||
| 	if (tp->tp_dbindex > 0) | ||||
| 	{ | ||||
| 		adds_db_str(sprint(buf, "%d", tp->tp_dbindex)); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (tp->tp_dbindex < 0 && tp->tp_size < 0) { | ||||
| 	if (tp->tp_dbindex < 0 && tp->tp_size < 0) | ||||
| 	{ | ||||
| 		adds_db_str(sprint(buf, "%d", -tp->tp_dbindex)); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (tp->tp_dbindex <= 0) { | ||||
| 	if (tp->tp_dbindex <= 0) | ||||
| 	{ | ||||
| 		tp->tp_dbindex = ++stb_count; | ||||
| 	} | ||||
| 	adds_db_str(sprint(buf, "%d=", tp->tp_dbindex)); | ||||
| 	switch(tp->tp_fund) { | ||||
| 	switch (tp->tp_fund) | ||||
| 	{ | ||||
| 	/* simple types ... */ | ||||
| 	case VOID: | ||||
| 		adds_db_str(sprint(buf, "%d", void_type->tp_dbindex)); | ||||
|  | @ -101,49 +103,44 @@ stb_type(tp) | |||
| 	case LONG: | ||||
| 	case CHAR: | ||||
| 	case SHORT: | ||||
| 		 l = full_mask[(int)tp->tp_size]; | ||||
| 		if (tp->tp_unsigned) { | ||||
| 			adds_db_str(sprint(buf, | ||||
| 				"r%d;0;%ld", | ||||
| 				tp->tp_dbindex, | ||||
| 				l)); | ||||
| 		l = full_mask[(int) tp->tp_size]; | ||||
| 		if (tp->tp_unsigned) | ||||
| 		{ | ||||
| 			adds_db_str(sprint(buf, "r%d;0;%ld", tp->tp_dbindex, l)); | ||||
| 		} | ||||
| 		else { | ||||
| 			l &= ~ (1L << ((int)tp->tp_size * 8 - 1)); | ||||
| 			adds_db_str(sprint(buf, | ||||
| 				"r%d;%ld;%ld", | ||||
| 				tp->tp_dbindex, | ||||
| 				-l-1, | ||||
| 				l)); | ||||
| 		else | ||||
| 		{ | ||||
| 			l &= ~(1L << ((int) tp->tp_size * 8 - 1)); | ||||
| 			adds_db_str(sprint(buf, "r%d;%ld;%ld", tp->tp_dbindex, -l - 1, l)); | ||||
| 		} | ||||
| 		break; | ||||
| 	case FLOAT: | ||||
| 	case DOUBLE: | ||||
| 	case LNGDBL: | ||||
| 		adds_db_str(sprint(buf, | ||||
| 		       "r%d;%ld;0", | ||||
| 		       tp->tp_dbindex, | ||||
| 		       (long)tp->tp_size)); | ||||
| 		adds_db_str( | ||||
| 				sprint(buf, "r%d;%ld;0", tp->tp_dbindex, (long) tp->tp_size)); | ||||
| 		break; | ||||
| 
 | ||||
| 	/* constructed types ... */ | ||||
| 		/* constructed types ... */ | ||||
| 	case POINTER: | ||||
| 		addc_db_str('*'); | ||||
| 		stb_type(tp->tp_up); | ||||
| 		break; | ||||
| 	case ARRAY: | ||||
| 		if (tp->tp_size > 0) { | ||||
| 		if (tp->tp_size > 0) | ||||
| 		{ | ||||
| 			adds_db_str("ar"); | ||||
| 			stb_type(int_type); | ||||
| 			adds_db_str(sprint(buf, ";0;%ld;", tp->tp_size / tp->tp_up->tp_size - 1)); | ||||
| 			adds_db_str( | ||||
| 					sprint(buf, ";0;%ld;", | ||||
| 							tp->tp_size / tp->tp_up->tp_size - 1)); | ||||
| 			stb_type(tp->tp_up); | ||||
| 		} | ||||
| 		break; | ||||
| 	case ENUM: | ||||
| 		if (tp->tp_size < 0) { | ||||
| 			adds_db_str(sprint(buf, | ||||
| 					   "xe%s:", | ||||
| 					   tp->tp_idf->id_text)); | ||||
| 		if (tp->tp_size < 0) | ||||
| 		{ | ||||
| 			adds_db_str(sprint(buf, "xe%s:", tp->tp_idf->id_text)); | ||||
| 			tp->tp_dbindex = -tp->tp_dbindex; | ||||
| 			break; | ||||
| 		} | ||||
|  | @ -151,15 +148,16 @@ stb_type(tp) | |||
| 		{ | ||||
| 			register struct stack_entry *se = local_level->sl_entry; | ||||
| 
 | ||||
| 			while (se) { | ||||
| 				register struct def	*edef = se->se_idf->id_def; | ||||
| 				while (edef) { | ||||
| 					if (edef->df_type == tp && | ||||
| 					    edef->df_sc == ENUM) { | ||||
| 						adds_db_str(sprint(buf, | ||||
| 							"%s:%ld,", | ||||
| 							se->se_idf->id_text, | ||||
| 							edef->df_address)); | ||||
| 			while (se) | ||||
| 			{ | ||||
| 				register struct def *edef = se->se_idf->id_def; | ||||
| 				while (edef) | ||||
| 				{ | ||||
| 					if (edef->df_type == tp && edef->df_sc == ENUM) | ||||
| 					{ | ||||
| 						adds_db_str( | ||||
| 								sprint(buf, "%s:%ld,", se->se_idf->id_text, | ||||
| 										edef->df_address)); | ||||
| 					} | ||||
| 					edef = edef->next; | ||||
| 				} | ||||
|  | @ -170,37 +168,39 @@ stb_type(tp) | |||
| 		break; | ||||
| 	case STRUCT: | ||||
| 	case UNION: | ||||
| 		if (tp->tp_size < 0) { | ||||
| 			adds_db_str(sprint(buf, | ||||
| 					   "x%c%s:", | ||||
| 					   tp->tp_fund == STRUCT ? 's' : 'u', | ||||
| 					   tp->tp_idf->id_text)); | ||||
| 		if (tp->tp_size < 0) | ||||
| 		{ | ||||
| 			adds_db_str( | ||||
| 					sprint(buf, "x%c%s:", tp->tp_fund == STRUCT ? 's' : 'u', | ||||
| 							tp->tp_idf->id_text)); | ||||
| 			tp->tp_dbindex = -tp->tp_dbindex; | ||||
| 			break; | ||||
| 		} | ||||
| 		adds_db_str(sprint(buf, | ||||
| 				   "%c%ld", | ||||
| 				   tp->tp_fund == STRUCT ? 's' : 'u', | ||||
| 				   tp->tp_size)); | ||||
| 		adds_db_str( | ||||
| 				sprint(buf, "%c%ld", tp->tp_fund == STRUCT ? 's' : 'u', | ||||
| 						tp->tp_size)); | ||||
| 		{ | ||||
| 			register struct sdef	*sdef = tp->tp_sdef; | ||||
| 			register struct sdef *sdef = tp->tp_sdef; | ||||
| 
 | ||||
| 			while (sdef) { | ||||
| 			while (sdef) | ||||
| 			{ | ||||
| 				adds_db_str(sdef->sd_idf->id_text); | ||||
| 				addc_db_str(':'); | ||||
| 				if (sdef->sd_type->tp_fund == FIELD) { | ||||
| 				if (sdef->sd_type->tp_fund == FIELD) | ||||
| 				{ | ||||
| 					stb_type(sdef->sd_type->tp_up); | ||||
| 					adds_db_str(sprint(buf, | ||||
| 						",%ld,%ld;", | ||||
| 						sdef->sd_offset*8+sdef->sd_type->tp_field->fd_shift, | ||||
| 						sdef->sd_type->tp_field->fd_width)); | ||||
| 					adds_db_str( | ||||
| 							sprint(buf, ",%ld,%ld;", | ||||
| 									sdef->sd_offset * 8 | ||||
| 											+ sdef->sd_type->tp_field->fd_shift, | ||||
| 									sdef->sd_type->tp_field->fd_width)); | ||||
| 				} | ||||
| 				else { | ||||
| 				else | ||||
| 				{ | ||||
| 					stb_type(sdef->sd_type); | ||||
| 					adds_db_str(sprint(buf, | ||||
| 						",%ld,%ld;", | ||||
| 						sdef->sd_offset*8, | ||||
| 						sdef->sd_type->tp_size*8)); | ||||
| 					adds_db_str( | ||||
| 							sprint(buf, ",%ld,%ld;", sdef->sd_offset * 8, | ||||
| 									sdef->sd_type->tp_size * 8)); | ||||
| 				} | ||||
| 				sdef = sdef->sd_sdef; | ||||
| 			} | ||||
|  | @ -213,9 +213,7 @@ stb_type(tp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| stb_tag(tg, str) | ||||
| 	register struct tag	*tg; | ||||
| 	char			*str; | ||||
| void stb_tag(register struct tag *tg, char *str) | ||||
| { | ||||
| 	create_db_str(); | ||||
| 	adds_db_str(str); | ||||
|  | @ -223,16 +221,12 @@ stb_tag(tg, str) | |||
| 	stb_type(tg->tg_type); | ||||
| 	addc_db_str(';'); | ||||
| 	C_ms_stb_cst(db_str.base, | ||||
| 		     N_LSYM, | ||||
| 		     tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 | ||||
| 		       ? 0 | ||||
| 		       : (int)tg->tg_type->tp_size, | ||||
| 		     (arith) 0); | ||||
| 	N_LSYM, | ||||
| 			tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 ? | ||||
| 					0 : (int) tg->tg_type->tp_size, (arith) 0); | ||||
| } | ||||
| 
 | ||||
| stb_typedef(tp, str) | ||||
| 	register struct type	*tp; | ||||
| 	char			*str; | ||||
| void stb_typedef(register struct type *tp, char *str) | ||||
| { | ||||
| 	create_db_str(); | ||||
| 	adds_db_str(str); | ||||
|  | @ -240,23 +234,19 @@ stb_typedef(tp, str) | |||
| 	stb_type(tp); | ||||
| 	addc_db_str(';'); | ||||
| 	C_ms_stb_cst(db_str.base, | ||||
| 		     N_LSYM, | ||||
| 		     tp == void_type || tp->tp_size >= 32767 | ||||
| 		       ? 0 | ||||
| 		       : (int)tp->tp_size, | ||||
| 		     (arith) 0); | ||||
| 	N_LSYM, tp == void_type || tp->tp_size >= 32767 ? 0 : (int) tp->tp_size, | ||||
| 			(arith) 0); | ||||
| } | ||||
| 
 | ||||
| stb_string(df, kind, str) | ||||
| 	register struct def	*df; | ||||
| 	char			*str; | ||||
| void stb_string(register struct def *df, int kind, char* str) | ||||
| { | ||||
| 	register struct type	*tp = df->df_type; | ||||
| 	register struct type *tp = df->df_type; | ||||
| 
 | ||||
| 	create_db_str(); | ||||
| 	adds_db_str(str); | ||||
| 	addc_db_str(':'); | ||||
| 	switch(kind) { | ||||
| 	switch (kind) | ||||
| 	{ | ||||
| 	case FUNCTION: | ||||
| 		addc_db_str(df->df_sc == STATIC ? 'f' : 'F'); | ||||
| 		stb_type(tp->tp_up); | ||||
|  | @ -264,40 +254,50 @@ stb_string(df, kind, str) | |||
| 		C_ms_stb_pnam(db_str.base, N_FUN, 1 /* proclevel */, str); | ||||
| 		break; | ||||
| 	default: | ||||
| 		if (df->df_sc == FORMAL || | ||||
| 		    (df->df_sc == REGISTER && df->df_address >= 0)) { | ||||
| 						/* value parameter */ | ||||
| 		if (df->df_sc == FORMAL | ||||
| 				|| (df->df_sc == REGISTER && df->df_address >= 0)) | ||||
| 		{ | ||||
| 			/* value parameter */ | ||||
| 			addc_db_str('p'); | ||||
| 			stb_type(tp); | ||||
| 			addc_db_str(';'); | ||||
| 			C_ms_stb_cst(db_str.base, N_PSYM, 0, df->df_address); | ||||
| 		} | ||||
| 		else if (df->df_sc != AUTO && df->df_sc != REGISTER) { | ||||
| 						/* global */ | ||||
| 		else if (df->df_sc != AUTO && df->df_sc != REGISTER) | ||||
| 		{ | ||||
| 			/* global */ | ||||
| 			int stabtp = df->df_initialized ? N_STSYM : N_LCSYM; | ||||
| 			if (df->df_sc == STATIC) { | ||||
| 				if (df->df_level >= L_LOCAL) { | ||||
| 			if (df->df_sc == STATIC) | ||||
| 			{ | ||||
| 				if (df->df_level >= L_LOCAL) | ||||
| 				{ | ||||
| 					addc_db_str('V'); | ||||
| 				} | ||||
| 				else { | ||||
| 				else | ||||
| 				{ | ||||
| 					addc_db_str('S'); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 			else | ||||
| 			{ | ||||
| 				addc_db_str('G'); | ||||
| 			} | ||||
| 			stb_type(tp); | ||||
| 			addc_db_str(';'); | ||||
| 			if (df->df_sc == STATIC && df->df_level >= L_LOCAL) { | ||||
| 				C_ms_stb_dlb(db_str.base, stabtp, 0, (label) df->df_address, (arith) 0); | ||||
| 			if (df->df_sc == STATIC && df->df_level >= L_LOCAL) | ||||
| 			{ | ||||
| 				C_ms_stb_dlb(db_str.base, stabtp, 0, (label) df->df_address, | ||||
| 						(arith) 0); | ||||
| 			} | ||||
| 			else { | ||||
| 			else | ||||
| 			{ | ||||
| 				C_ms_stb_dnam(db_str.base, stabtp, 0, str, (arith) 0); | ||||
| 			} | ||||
| 		} | ||||
| 		else {	/* local variable */ | ||||
| 			stb_type(tp);	/* assign type num to avoid
 | ||||
| 						   difficult to parse string */ | ||||
| 		else | ||||
| 		{ /* local variable */ | ||||
| 			stb_type(tp); /* assign type num to avoid
 | ||||
| 			 difficult to parse string */ | ||||
| 			addc_db_str(';'); | ||||
| 			C_ms_stb_cst(db_str.base, N_LSYM, 0, df->df_address); | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										20
									
								
								lang/cem/cemcom.ansi/stab.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								lang/cem/cemcom.ansi/stab.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| /*  Copyright (c) 2019 ACK Project.
 | ||||
|  *  See the copyright notice in the ACK home directory,  | ||||
|  *  in the file "Copyright". | ||||
|  * | ||||
|  *  Created on: 2019-02-07 | ||||
|  *   | ||||
|  */ | ||||
| #ifndef STAB_H_ | ||||
| #define STAB_H_ | ||||
| 
 | ||||
| 
 | ||||
| struct def; | ||||
| struct type; | ||||
| struct tag; | ||||
| 
 | ||||
| void stb_tag(register struct tag *tg, char *str); | ||||
| void stb_typedef(register struct type *tp, char *str); | ||||
| void stb_string(register struct def *df, int kind, char* str); | ||||
| 
 | ||||
| #endif /* STAB_H_ */ | ||||
|  | @ -22,6 +22,9 @@ | |||
| #include	"struct.h" | ||||
| #include	"level.h" | ||||
| #include	"mes.h" | ||||
| #include    "code.h" | ||||
| #include    "util.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| /* #include	<em_reg.h> */ | ||||
| 
 | ||||
|  | @ -41,7 +44,7 @@ struct stack_level *local_level = &UniversalLevel; | |||
| 
 | ||||
| int level;	/* Always equal to local_level->sl_level. */ | ||||
| 
 | ||||
| stack_level()	{ | ||||
| void stack_level(void)	{ | ||||
| 	/*	A new level is added on top of the identifier stack.
 | ||||
| 	*/ | ||||
| 	register struct stack_level *stl = new_stack_level(); | ||||
|  | @ -57,10 +60,9 @@ stack_level()	{ | |||
| #endif	/* LINT */ | ||||
| } | ||||
| 
 | ||||
| void | ||||
| stack_idf(idf, stl) | ||||
| 	struct idf *idf; | ||||
| 	register struct stack_level *stl; | ||||
| void stack_idf( | ||||
| 	struct idf *idf, | ||||
| 	register struct stack_level *stl) | ||||
| { | ||||
| 	/*	The identifier idf is inserted in the stack on level stl,
 | ||||
| 		but only if it is not already present at this level. | ||||
|  | @ -81,8 +83,7 @@ stack_idf(idf, stl) | |||
| 	stl->sl_entry = se; | ||||
| } | ||||
| 
 | ||||
| struct stack_level * | ||||
| stack_level_of(lvl) | ||||
| struct stack_level *stack_level_of(int lvl) | ||||
| { | ||||
| 	/*	The stack_level corresponding to level lvl is returned.
 | ||||
| 		The stack should probably be an array, to be extended with | ||||
|  | @ -100,7 +101,7 @@ stack_level_of(lvl) | |||
| 	return stl; | ||||
| } | ||||
| 
 | ||||
| unstack_level() | ||||
| void unstack_level(void) | ||||
| { | ||||
| 	/*	The top level of the identifier stack is removed.
 | ||||
| 	*/ | ||||
|  | @ -174,7 +175,7 @@ unstack_level() | |||
| #endif	/* DEBUG */ | ||||
| } | ||||
| 
 | ||||
| unstack_world() | ||||
| void unstack_world(void) | ||||
| { | ||||
| 	/*	The global level of identifiers is scanned, and final
 | ||||
| 		decisions are taken about such issues as | ||||
|  | @ -263,14 +264,13 @@ unstack_world() | |||
| extern char *nmlist;	/* BAH! -- main.c	*/ | ||||
| static File *nfp = 0; | ||||
| 
 | ||||
| open_name_list() | ||||
| void open_name_list(void) | ||||
| { | ||||
| 	if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0) | ||||
| 		fatal("cannot create namelist %s", nmlist); | ||||
| } | ||||
| 
 | ||||
| namelist(nm) | ||||
| 	char *nm; | ||||
| void namelist(char *nm) | ||||
| { | ||||
| 	if (nmlist)	{ | ||||
| 		sys_write(nfp, nm, strlen(nm)); | ||||
|  |  | |||
|  | @ -2,9 +2,14 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef STACK_H_ | ||||
| #define STACK_H_ | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| /* IDENTIFIER STACK DEFINITIONS */ | ||||
| 
 | ||||
| struct idf; | ||||
| 
 | ||||
| /*	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. | ||||
|  | @ -30,5 +35,26 @@ struct stack_entry	{ | |||
| /* ALLOCDEF "stack_entry" 50 */ | ||||
| 
 | ||||
| extern struct stack_level *local_level; | ||||
| extern struct stack_level *stack_level_of(); | ||||
| extern int level; | ||||
| 
 | ||||
| /*	A new level is added on top of the identifier stack. */ | ||||
| void stack_level(void); | ||||
| /*	The identifier idf is inserted in the stack on level stl, | ||||
| 	but only if it is not already present at this level. | ||||
| */ | ||||
| void stack_idf(struct idf *idf, register struct stack_level *stl); | ||||
| /*The stack_level corresponding to level lvl is returned. | ||||
|   The stack should probably be an array, to be extended with | ||||
|  realloc where needed. | ||||
| */ | ||||
| struct stack_level *stack_level_of(int lvl); | ||||
| /* The top level of the identifier stack is removed. */ | ||||
| void unstack_level(void); | ||||
| void unstack_world(void); | ||||
| 
 | ||||
| #ifdef GEN_NM_LIST | ||||
| void open_name_list(void); | ||||
| void namelist(char *nm); | ||||
| #endif /* GEN_NM_LIST */ | ||||
| 
 | ||||
| #endif  | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ | |||
| #include	"code.h" | ||||
| #include	"stack.h" | ||||
| #include	"def.h" | ||||
| #include    "switch.h" | ||||
| #ifdef DBSYMTAB | ||||
| #include	<stb.h> | ||||
| #endif /* DBSYMTAB */ | ||||
|  |  | |||
|  | @ -3,10 +3,10 @@ | |||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| /* $Id$ */ | ||||
| /* library routine for copying structs */ | ||||
| 
 | ||||
| __stb(n, f, t) | ||||
| 	register char *f, *t; register n; | ||||
| 
 | ||||
| /* library routine for copying structs */ | ||||
| void __stb(register int n, register char *f, register char *t) | ||||
| { | ||||
| 	if (n > 0) | ||||
| 		do | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef STMT_H_ | ||||
| #define STMT_H_ | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| /*	S T A T E M E N T - B L O C K   D E F I N I T I O N S	*/ | ||||
| 
 | ||||
|  | @ -12,3 +15,5 @@ struct stmt_block	{ | |||
| }; | ||||
| 
 | ||||
| /* ALLOCDEF "stmt_block" 5 */ | ||||
| 
 | ||||
| #endif | ||||
|  | @ -19,16 +19,23 @@ | |||
| #include	"Lpars.h" | ||||
| #include	"align.h" | ||||
| #include	"level.h" | ||||
| #include    "ch3.h" | ||||
| #include	"sizes.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| /*	Type of previous selector declared with a field width specified,
 | ||||
| 	if any.  If a selector is declared with no field with it is set to 0. | ||||
| */ | ||||
| static field_busy = 0; | ||||
| static int field_busy = 0; | ||||
| 
 | ||||
| extern char options[]; | ||||
| char *symbol2str(); | ||||
| int lcm(); | ||||
| 
 | ||||
| static void check_selector(register struct idf *, struct type *); | ||||
| /*	Greatest Common Divisor */ | ||||
| static int gcd(register int , register int ); | ||||
| /*	Least Common Multiple */ | ||||
| static int lcm(register int, register int); | ||||
| 
 | ||||
| /*	The semantics of the identification of structure/union tags is
 | ||||
| 	obscure.  Some highly regarded compilers are found out to accept, | ||||
|  | @ -51,13 +58,13 @@ int lcm(); | |||
| 	as well). | ||||
| */ | ||||
| 
 | ||||
| add_sel(stp, tp, idf, sdefpp, szp, fd)	/* this is horrible */ | ||||
| 	register struct type *stp;	/* type of the structure */ | ||||
| 	struct type *tp;		/* type of the selector */ | ||||
| 	register struct idf *idf;	/* idf of the selector */ | ||||
| 	struct sdef ***sdefpp;	/* address of hook to selector definition */ | ||||
| 	arith *szp;		/* pointer to struct size upto here */ | ||||
| 	struct field *fd; | ||||
| void add_sel( /* this is horrible */ | ||||
| 	register struct type *stp,	/* type of the structure */ | ||||
| 	struct type *tp,		/* type of the selector */ | ||||
| 	register struct idf *idf,	/* idf of the selector */ | ||||
| 	struct sdef ***sdefpp,	/* address of hook to selector definition */ | ||||
| 	arith *szp,		/* pointer to struct size upto here */ | ||||
| 	struct field *fd) | ||||
| { | ||||
| 	/*	The selector idf with type tp is added to two chains: the
 | ||||
| 		selector identification chain starting at idf->id_sdef, | ||||
|  | @ -147,12 +154,11 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)	/* this is horrible */ | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| check_selector(idf, stp) | ||||
| 	register struct idf *idf; | ||||
| 	struct type *stp;	/* the type of the struct */ | ||||
| static void check_selector(register struct idf *idf, struct type *stp) | ||||
| { | ||||
| 	/*	checks if idf occurs already as a selector in
 | ||||
| 		struct or union *stp. | ||||
| 		struct or union *stp. "stp" indicates the type | ||||
| 		of the struct. | ||||
| 	*/ | ||||
| 	register struct sdef *sdef = stp->tp_sdef; | ||||
| 	 | ||||
|  | @ -163,9 +169,7 @@ check_selector(idf, stp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| declare_struct(fund, idf, tpp) | ||||
| 	register struct idf *idf; | ||||
| 	struct type **tpp; | ||||
| void declare_struct(int fund, register struct idf *idf, struct type **tpp) | ||||
| { | ||||
| 	/*	A struct, union or enum (depending on fund) with tag (!)
 | ||||
| 		idf is declared, and its type (incomplete as it may be) is | ||||
|  | @ -232,9 +236,9 @@ declare_struct(fund, idf, tpp) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| apply_struct(fund, idf, tpp) | ||||
| 	register struct idf *idf; | ||||
| 	struct type **tpp; | ||||
| void apply_struct(int fund, | ||||
| 	register struct idf *idf, | ||||
| 	struct type **tpp) | ||||
| { | ||||
| 	/*	The occurrence of a struct, union or enum (depending on
 | ||||
| 		fund) with tag idf is noted. It may or may not have been | ||||
|  | @ -258,10 +262,9 @@ apply_struct(fund, idf, tpp) | |||
| 		declare_struct(fund, idf, tpp); | ||||
| } | ||||
| 
 | ||||
| struct sdef * | ||||
| idf2sdef(idf, tp) | ||||
| 	register struct idf *idf; | ||||
| 	struct type *tp; | ||||
| struct sdef *idf2sdef( | ||||
| 	register struct idf *idf, | ||||
| 	struct type *tp) | ||||
| { | ||||
| 	/*	The identifier idf is identified as a selector
 | ||||
| 		in the struct tp. | ||||
|  | @ -296,9 +299,7 @@ idf2sdef(idf, tp) | |||
| } | ||||
| 
 | ||||
| #if	0 | ||||
| int | ||||
| uniq_selector(idf_sdef) | ||||
| 	register struct sdef *idf_sdef; | ||||
| int uniq_selector(register struct sdef *idf_sdef) | ||||
| { | ||||
| 	/*	Returns true if idf_sdef (which is guaranteed to exist)
 | ||||
| 		is unique for this level, i.e there is no other selector | ||||
|  | @ -324,12 +325,12 @@ uniq_selector(idf_sdef) | |||
| 
 | ||||
| #ifndef NOBITFIELD | ||||
| arith | ||||
| add_field(szp, fd, fdtpp, idf, stp) | ||||
| 	arith *szp;			/* size of struct upto here	*/ | ||||
| 	register struct field *fd;	/* bitfield, containing width	*/ | ||||
| 	register struct type **fdtpp;	/* type of selector		*/ | ||||
| 	struct idf *idf;		/* name of selector		*/ | ||||
| 	register struct type *stp;	/* current struct descriptor	*/ | ||||
| add_field( | ||||
| 	arith *szp,			/* size of struct upto here	*/ | ||||
| 	register struct field *fd,	/* bitfield, containing width	*/ | ||||
| 	register struct type **fdtpp,	/* type of selector		*/ | ||||
| 	struct idf *idf,		/* name of selector		*/ | ||||
| 	register struct type *stp)	/* current struct descriptor	*/ | ||||
| { | ||||
| 	/*	The address where this selector is put is returned. If the
 | ||||
| 		selector with specified width does not fit in the word, or | ||||
|  | @ -438,18 +439,12 @@ add_field(szp, fd, fdtpp, idf, stp) | |||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| /* some utilities */ | ||||
| int | ||||
| is_struct_or_union(fund) | ||||
| 	register int fund; | ||||
| int is_struct_or_union(register int fund) | ||||
| { | ||||
| 	return fund == STRUCT || fund == UNION; | ||||
| } | ||||
| 
 | ||||
| /*	Greatest Common Divisor
 | ||||
|  */ | ||||
| int | ||||
| gcd(m, n) | ||||
| 	register int m, n; | ||||
| static int gcd(register int m, register int n) | ||||
| { | ||||
| 	register int r; | ||||
| 
 | ||||
|  | @ -461,11 +456,8 @@ gcd(m, n) | |||
| 	return m; | ||||
| } | ||||
| 
 | ||||
| /*	Least Common Multiple
 | ||||
|  */ | ||||
| int | ||||
| lcm(m, n) | ||||
| 	register int m, n; | ||||
| 
 | ||||
| static int lcm(register int m, register int n) | ||||
| { | ||||
| 	return m * (n / gcd(m, n)); | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,17 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef STRUCT_H_ | ||||
| #define STRUCT_H_ | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| 
 | ||||
| #include "arith.h" | ||||
| 
 | ||||
| struct type; | ||||
| struct idf; | ||||
| struct field; | ||||
| 
 | ||||
| /* SELECTOR DESCRIPTOR */ | ||||
| 
 | ||||
| struct sdef	{		/* for selectors */ | ||||
|  | @ -27,4 +37,26 @@ struct tag	{		/* for struct-, union- and enum tags */ | |||
| 
 | ||||
| /* ALLOCDEF "tag" 10 */ | ||||
| 
 | ||||
| struct sdef *idf2sdef(); | ||||
| struct sdef *idf2sdef(register struct idf *idf, struct type *tp); | ||||
| void add_sel( | ||||
| 	register struct type *stp,	/* type of the structure */ | ||||
| 	struct type *tp,		/* type of the selector */ | ||||
| 	register struct idf *idf,	/* idf of the selector */ | ||||
| 	struct sdef ***sdefpp,	/* address of hook to selector definition */ | ||||
| 	arith *szp,		/* pointer to struct size upto here */ | ||||
| 	struct field *fd); | ||||
| void declare_struct(int fund, register struct idf *idf, struct type **tpp); | ||||
| void apply_struct(int fund, register struct idf *idf, struct type **tpp); | ||||
| int is_struct_or_union(register int fund); | ||||
| 
 | ||||
| #ifndef NOBITFIELD | ||||
| arith | ||||
| add_field( | ||||
| 	arith *szp,			/* size of struct upto here	*/ | ||||
| 	register struct field *fd,	/* bitfield, containing width	*/ | ||||
| 	register struct type **fdtpp,	/* type of selector		*/ | ||||
| 	struct idf *idf,		/* name of selector		*/ | ||||
| 	register struct type *stp);	/* current struct descriptor	*/ | ||||
| #endif	 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -23,13 +23,16 @@ | |||
| #include	"expr.h" | ||||
| #include	"type.h" | ||||
| #include	"sizes.h" | ||||
| #include    "switch.h" | ||||
| #include    "eval.h" | ||||
| #include    "ch3.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| extern char options[]; | ||||
| 
 | ||||
| int	density = DENSITY; | ||||
| 
 | ||||
| compact(nr, low, up) | ||||
| 	arith low, up; | ||||
| static int compact(int nr, arith low, arith up) | ||||
| { | ||||
| 	/*	Careful! up - low might not fit in an arith. And then,
 | ||||
| 		the test "up-low < 0" might also not work to detect this | ||||
|  | @ -49,8 +52,7 @@ static struct switch_hdr *switch_stack = 0; | |||
| 	For simplicity, we suppose int_size == word_size. | ||||
| */ | ||||
| 
 | ||||
| code_startswitch(expp) | ||||
| 	struct expr **expp; | ||||
| void code_startswitch(struct expr **expp) | ||||
| { | ||||
| 	/*	Check the expression, stack a new case header and
 | ||||
| 		fill in the necessary fields. | ||||
|  | @ -85,7 +87,7 @@ code_startswitch(expp) | |||
| 	C_bra(l_table);			/* goto start of switch_table	*/ | ||||
| } | ||||
| 
 | ||||
| code_endswitch() | ||||
| void code_endswitch(void) | ||||
| { | ||||
| 	register struct switch_hdr *sh = switch_stack; | ||||
| 	register label tablabel; | ||||
|  | @ -158,9 +160,7 @@ code_endswitch() | |||
| 	unstack_stmt(); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| code_case(expr) | ||||
| 	struct expr *expr; | ||||
| void code_case(struct expr *expr) | ||||
| { | ||||
| 	register arith val; | ||||
| 	register struct case_entry *ce; | ||||
|  | @ -227,8 +227,7 @@ code_case(expr) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| code_default() | ||||
| void code_default(void) | ||||
| { | ||||
| 	register struct switch_hdr *sh = switch_stack; | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,16 @@ | |||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||
|  */ | ||||
| #ifndef SWITCH_H_ | ||||
| #define SWITCH_H_ | ||||
| 
 | ||||
| /* $Id$ */ | ||||
| 
 | ||||
| #include "arith.h" | ||||
| 
 | ||||
| struct type; | ||||
| struct expr; | ||||
| 
 | ||||
| /*		S W I T C H - T A B L E - S T R U C T U R E		*/ | ||||
| 
 | ||||
| struct switch_hdr	{ | ||||
|  | @ -27,3 +36,12 @@ struct case_entry	{ | |||
| }; | ||||
| 
 | ||||
| /* ALLOCDEF "case_entry" 20 */ | ||||
| 
 | ||||
| void code_startswitch(struct expr **expp); | ||||
| void code_endswitch(void); | ||||
| void code_case(struct expr *expr); | ||||
| void code_default(void); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										3
									
								
								lang/cem/cemcom.ansi/tokcase.sed
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lang/cem/cemcom.ansi/tokcase.sed
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| /{[A-Z]/!d | ||||
| s/.*{\(.*\),.*\(".*"\).*$/	case \1 :\ | ||||
| 	return \2;/ | ||||
							
								
								
									
										16
									
								
								lang/cem/cemcom.ansi/tokcasee.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								lang/cem/cemcom.ansi/tokcasee.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| 	default: | ||||
| 		if (tok <= 0) return "end of file"; | ||||
| 		if (tok < 040 || tok >= 0177) { | ||||
| 			return "bad token"; | ||||
| 		} | ||||
| 		/* fall through */ | ||||
| 	case '\n': | ||||
| 	case '\f': | ||||
| 	case '\v': | ||||
| 	case '\r': | ||||
| 	case '\t': | ||||
| 		index = (index+2) & (SIZBUF-1); | ||||
| 		buf[index] = tok; | ||||
| 		return &buf[index]; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										12
									
								
								lang/cem/cemcom.ansi/tokcaseh.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lang/cem/cemcom.ansi/tokcaseh.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| /* Generated by make.tokcase */ | ||||
| /* $Id$ */ | ||||
| #include "Lpars.h" | ||||
| 
 | ||||
| char *symbol2str(int tok) | ||||
| { | ||||
| #define SIZBUF	8 | ||||
| 	/* allow for a few invocations in f.i. an argument list */ | ||||
| 	static char buf[SIZBUF]; | ||||
| 	static int index; | ||||
| 
 | ||||
| 	switch (tok) { | ||||
|  | @ -11,6 +11,7 @@ | |||
| #include	"LLlex.h" | ||||
| #include	"tokenname.h" | ||||
| #include	"Lpars.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| /*	To centralize the declaration of %tokens, their presence in this
 | ||||
| 	file is taken as their declaration. The Makefile will produce | ||||
|  | @ -132,8 +133,7 @@ struct tokenname tkfunny[] =	{	/* internal keywords */ | |||
| }; | ||||
| #endif	/* ____ */ | ||||
| 
 | ||||
| reserve(resv) | ||||
| 	register struct tokenname resv[]; | ||||
| void reserve(register struct tokenname resv[]) | ||||
| { | ||||
| 	/*	The names of the tokens described in resv are entered
 | ||||
| 		as reserved words. | ||||
|  |  | |||
|  | @ -4,6 +4,8 @@ | |||
|  */ | ||||
| /* $Id$ */ | ||||
| /* TOKENNAME DEFINITION */ | ||||
| #ifndef TOKENNAME_H_ | ||||
| #define TOKENNAME_H_ | ||||
| 
 | ||||
| struct tokenname	{	/*	Used for defining the name of a
 | ||||
| 					token as identified by its symbol | ||||
|  | @ -11,3 +13,7 @@ struct tokenname	{	/*	Used for defining the name of a | |||
| 	int tn_symbol; | ||||
| 	char *tn_name; | ||||
| }; | ||||
| 
 | ||||
| void reserve(register struct tokenname resv[]); | ||||
| 
 | ||||
| #endif /* TOKENNAME_H_ */ | ||||
|  |  | |||
|  | @ -16,68 +16,59 @@ | |||
| #include	"sizes.h" | ||||
| #include	"align.h" | ||||
| #include	"decspecs.h" | ||||
| #include    "error.h" | ||||
| 
 | ||||
| 
 | ||||
| extern struct type *function_of(), *array_of(); | ||||
| #ifndef NOBITFIELD | ||||
| extern struct type *field_of(); | ||||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| /*	To be created dynamically in main() from defaults or from command
 | ||||
| 	line parameters. | ||||
| */ | ||||
| struct type | ||||
| 	*schar_type, *uchar_type, | ||||
| 	*short_type, *ushort_type, | ||||
| 	*word_type, *uword_type, | ||||
| 	*int_type, *uint_type, | ||||
| 	*long_type, *ulong_type, | ||||
| 	*float_type, *double_type, *lngdbl_type, | ||||
| 	*void_type, | ||||
| 	*string_type, *funint_type, *error_type; | ||||
|  line parameters. | ||||
|  */ | ||||
| struct type *schar_type, *uchar_type, *short_type, *ushort_type, *word_type, | ||||
| 		*uword_type, *int_type, *uint_type, *long_type, *ulong_type, | ||||
| 		*float_type, *double_type, *lngdbl_type, *void_type, *string_type, | ||||
| 		*funint_type, *error_type; | ||||
| 
 | ||||
| struct type *pa_type;	/* Pointer-Arithmetic type	*/ | ||||
| struct type *pa_type; /* Pointer-Arithmetic type	*/ | ||||
| 
 | ||||
| struct type * | ||||
| create_type(fund) | ||||
| 	int fund; | ||||
| struct type *create_type(int fund) | ||||
| { | ||||
| 	/*	A brand new struct type is created, and its tp_fund set
 | ||||
| 		to fund. | ||||
| 	*/ | ||||
| 	 to fund. | ||||
| 	 */ | ||||
| 	register struct type *ntp = new_type(); | ||||
| 
 | ||||
| 	ntp->tp_fund = fund; | ||||
| 	ntp->tp_size = (arith)-1; | ||||
| 	ntp->tp_size = (arith) -1; | ||||
| 
 | ||||
| 	return ntp; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| promoted_type(tp) | ||||
| struct type *tp; | ||||
| struct type *promoted_type(struct type *tp) | ||||
| { | ||||
| 	if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) { | ||||
| 	if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) | ||||
| 	{ | ||||
| 		if (tp->tp_unsigned && (int) tp->tp_size == (int) int_size) | ||||
| 			return uint_type; | ||||
| 		else return int_type; | ||||
| 	} else if (tp->tp_fund == FLOAT) | ||||
| 		else | ||||
| 			return int_type; | ||||
| 	} | ||||
| 	else if (tp->tp_fund == FLOAT) | ||||
| 		return double_type; | ||||
| 	else return tp; | ||||
| 	else | ||||
| 		return tp; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| construct_type(fund, tp, qual, count, pl) | ||||
| 	register struct type *tp; | ||||
| 	register struct proto *pl; | ||||
| 	arith count; /* for fund == ARRAY only */ | ||||
| 	int qual; | ||||
| struct type *construct_type(int fund, register struct type *tp, int qual, | ||||
| arith count, /* for fund == ARRAY only */ | ||||
| register struct proto *pl) | ||||
| { | ||||
| 	/*	fund must be a type constructor: FIELD, FUNCTION, POINTER or
 | ||||
| 		ARRAY. The pointer to the constructed type is returned. | ||||
| 	*/ | ||||
| 	 ARRAY. The pointer to the constructed type is returned. | ||||
| 	 */ | ||||
| 	register struct type *dtp; | ||||
| 
 | ||||
| 	switch (fund)	{ | ||||
| 	switch (fund) | ||||
| 	{ | ||||
| #ifndef NOBITFIELD | ||||
| 	case FIELD: | ||||
| 		dtp = field_of(tp, qual); | ||||
|  | @ -85,11 +76,13 @@ construct_type(fund, tp, qual, count, pl) | |||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| 	case FUNCTION: | ||||
| 		if (tp->tp_fund == FUNCTION)	{ | ||||
| 		if (tp->tp_fund == FUNCTION) | ||||
| 		{ | ||||
| 			error("function cannot yield function"); | ||||
| 			return error_type; | ||||
| 		} | ||||
| 		if (tp->tp_fund == ARRAY)	{ | ||||
| 		if (tp->tp_fund == ARRAY) | ||||
| 		{ | ||||
| 			error("function cannot yield array"); | ||||
| 			return error_type; | ||||
| 		} | ||||
|  | @ -100,7 +93,8 @@ construct_type(fund, tp, qual, count, pl) | |||
| 		dtp = pointer_to(tp, qual); | ||||
| 		break; | ||||
| 	case ARRAY: | ||||
| 		if (tp->tp_fund == VOID) { | ||||
| 		if (tp->tp_fund == VOID) | ||||
| 		{ | ||||
| 			error("cannot construct array of void"); | ||||
| 			count = (arith) -1; | ||||
| 		} | ||||
|  | @ -113,14 +107,10 @@ construct_type(fund, tp, qual, count, pl) | |||
| 	return dtp; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| function_of(tp, pl, qual) | ||||
| 	register struct type *tp; | ||||
| 	struct proto *pl; | ||||
| 	int qual; | ||||
| struct type *function_of(register struct type *tp, struct proto *pl, int qual) | ||||
| { | ||||
| #if 0 | ||||
| /* See comment below */ | ||||
| 	/* See comment below */ | ||||
| 	register struct type *dtp = tp->tp_function; | ||||
| #else | ||||
| 	register struct type *dtp; | ||||
|  | @ -128,30 +118,31 @@ function_of(tp, pl, qual) | |||
| 
 | ||||
| 	/* look for a type with the right qualifier */ | ||||
| #if 0 | ||||
| /* the code doesn't work in the following case:
 | ||||
| 	int func(); | ||||
| 	int func(int a, int b) { return q(a); } | ||||
|    because updating the type works inside the data-structures for that type | ||||
|    thus, a new type is created for very function. This may change in the | ||||
|    future, when declarations with empty parameter lists become obsolete. | ||||
|    When it does, change type.str, decspecs.c, and this routine. Search for | ||||
|    the function_of pattern to find the places. | ||||
| */ | ||||
| 	/* the code doesn't work in the following case:
 | ||||
| 	 int func(); | ||||
| 	 int func(int a, int b) { return q(a); } | ||||
| 	 because updating the type works inside the data-structures for that type | ||||
| 	 thus, a new type is created for very function. This may change in the | ||||
| 	 future, when declarations with empty parameter lists become obsolete. | ||||
| 	 When it does, change type.str, decspecs.c, and this routine. Search for | ||||
| 	 the function_of pattern to find the places. | ||||
| 	 */ | ||||
| 	while (dtp && (dtp->tp_typequal != qual || dtp->tp_proto != pl)) | ||||
| 		dtp = dtp->next; | ||||
| 	dtp = dtp->next; | ||||
| #else | ||||
| 	dtp = 0; | ||||
| #endif | ||||
| 
 | ||||
| 	if (!dtp)	{ | ||||
| 	if (!dtp) | ||||
| 	{ | ||||
| 		dtp = create_type(FUNCTION); | ||||
| 		dtp->tp_up = tp; | ||||
| 		dtp->tp_size = -1;	/* function size is not known */ | ||||
| 		dtp->tp_size = -1; /* function size is not known */ | ||||
| 		dtp->tp_align = pointer_align; | ||||
| 		dtp->tp_typequal = qual; | ||||
| 		dtp->tp_proto = pl; | ||||
| #if 0 | ||||
| /* See comment above */ | ||||
| 		/* See comment above */ | ||||
| 		dtp->next = tp->tp_function; | ||||
| 		tp->tp_function = dtp; | ||||
| #endif | ||||
|  | @ -159,10 +150,7 @@ function_of(tp, pl, qual) | |||
| 	return dtp; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| pointer_to(tp, qual) | ||||
| 	register struct type *tp; | ||||
| 	int qual; | ||||
| struct type *pointer_to(register struct type *tp, int qual) | ||||
| { | ||||
| 	register struct type *dtp = tp->tp_pointer; | ||||
| 
 | ||||
|  | @ -170,7 +158,8 @@ pointer_to(tp, qual) | |||
| 	while (dtp && dtp->tp_typequal != qual) | ||||
| 		dtp = dtp->next; | ||||
| 
 | ||||
| 	if (!dtp)	{ | ||||
| 	if (!dtp) | ||||
| 	{ | ||||
| 		dtp = create_type(POINTER); | ||||
| 		dtp->tp_unsigned = 1; | ||||
| 		dtp->tp_up = tp; | ||||
|  | @ -183,11 +172,7 @@ pointer_to(tp, qual) | |||
| 	return dtp; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| array_of(tp, count, qual) | ||||
| 	register struct type *tp; | ||||
| 	arith count; | ||||
| 	int qual; | ||||
| struct type * array_of(register struct type *tp, arith count, int qual) | ||||
| { | ||||
| 	register struct type *dtp = tp->tp_array; | ||||
| 
 | ||||
|  | @ -195,7 +180,8 @@ array_of(tp, count, qual) | |||
| 	while (dtp && (dtp->tp_nel != count || dtp->tp_typequal != qual)) | ||||
| 		dtp = dtp->next; | ||||
| 
 | ||||
| 	if (!dtp)	{ | ||||
| 	if (!dtp) | ||||
| 	{ | ||||
| 		dtp = create_type(ARRAY); | ||||
| 		dtp->tp_up = tp; | ||||
| 		dtp->tp_nel = count; | ||||
|  | @ -203,19 +189,18 @@ array_of(tp, count, qual) | |||
| 		dtp->tp_typequal = qual; | ||||
| 		dtp->next = tp->tp_array; | ||||
| 		tp->tp_array = dtp; | ||||
| 		if (tp->tp_size >= 0 && count >= 0) { | ||||
| 		if (tp->tp_size >= 0 && count >= 0) | ||||
| 		{ | ||||
| 			dtp->tp_size = count * tp->tp_size; | ||||
| 		} | ||||
| 		else	dtp->tp_size = -1; | ||||
| 		else | ||||
| 			dtp->tp_size = -1; | ||||
| 	} | ||||
| 	return dtp; | ||||
| } | ||||
| 
 | ||||
| #ifndef NOBITFIELD | ||||
| struct type * | ||||
| field_of(tp, qual) | ||||
| 	register struct type *tp; | ||||
| 	int qual; | ||||
| struct type * field_of(register struct type *tp, int qual) | ||||
| { | ||||
| 	register struct type *dtp = create_type(FIELD); | ||||
| 
 | ||||
|  | @ -227,53 +212,47 @@ field_of(tp, qual) | |||
| } | ||||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| arith | ||||
| size_of_type(tp, nm) | ||||
| 	struct type *tp; | ||||
| 	char nm[]; | ||||
| arith size_of_type(struct type *tp, char nm[]) | ||||
| { | ||||
| 	arith sz = tp->tp_size; | ||||
| 
 | ||||
| 	if (sz < 0)	{ | ||||
| 	if (sz < 0) | ||||
| 	{ | ||||
| 		error("size of %s unknown", nm); | ||||
| 		sz = (arith)1; | ||||
| 		sz = (arith) 1; | ||||
| 	} | ||||
| 	return sz; | ||||
| } | ||||
| 
 | ||||
| idf2type(idf, tpp) | ||||
| 	struct idf *idf; | ||||
| 	struct type **tpp; | ||||
| void idf2type(struct idf *idf, struct type **tpp) | ||||
| { | ||||
| 	/*	Decoding  a typedef-ed identifier or basic type: if the
 | ||||
| 		size is yet unknown we have to make copy of the type | ||||
| 		descriptor to prevent garbage at the initialisation of | ||||
| 		arrays with unknown size. | ||||
| 	*/ | ||||
| 	 size is yet unknown we have to make copy of the type | ||||
| 	 descriptor to prevent garbage at the initialisation of | ||||
| 	 arrays with unknown size. | ||||
| 	 */ | ||||
| 	register struct type *tp = idf->id_def->df_type; | ||||
| 
 | ||||
| 	if (*tpp) error("multiple types in declaration"); | ||||
| 	if (	tp->tp_size < (arith)0 && tp->tp_fund == ARRAY)	{ | ||||
| 	if (*tpp) | ||||
| 		error("multiple types in declaration"); | ||||
| 	if (tp->tp_size < (arith) 0 && tp->tp_fund == ARRAY) | ||||
| 	{ | ||||
| 		*tpp = new_type(); | ||||
| 		**tpp = *tp; | ||||
| 			/* this is really a structure assignment, AAGH!!! */ | ||||
| 		/* this is really a structure assignment, AAGH!!! */ | ||||
| 	} | ||||
| 	else	{ | ||||
| 	else | ||||
| 	{ | ||||
| 		*tpp = tp; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| arith | ||||
| align(pos, al) | ||||
| 	arith pos; | ||||
| 	int al; | ||||
| arith align(arith pos, int al) | ||||
| { | ||||
| 	return ((pos + al - 1) / al) * al; | ||||
| } | ||||
| 
 | ||||
| struct type * | ||||
| standard_type(fund, sgn, algn, sz) | ||||
| 	int algn; arith sz; | ||||
| struct type * standard_type(int fund, int sgn, int algn, arith sz) | ||||
| { | ||||
| 	register struct type *tp = create_type(fund); | ||||
| 
 | ||||
|  | @ -284,25 +263,29 @@ standard_type(fund, sgn, algn, sz) | |||
| 	return tp; | ||||
| } | ||||
| 
 | ||||
| completed(tp) | ||||
| 	struct type *tp; | ||||
| void completed(struct type *tp) | ||||
| { | ||||
| 	register struct type *atp = tp->tp_array; | ||||
| 	register struct type *etp = tp; | ||||
| 
 | ||||
| 	switch(etp->tp_fund) { | ||||
| 	switch (etp->tp_fund) | ||||
| 	{ | ||||
| 	case STRUCT: | ||||
| 	case UNION: | ||||
| 	case ENUM: | ||||
| 		while (etp = etp->next) { | ||||
| 			if (! etp->tp_sdef) etp->tp_sdef = tp->tp_sdef; | ||||
| 		while (etp = etp->next) | ||||
| 		{ | ||||
| 			if (!etp->tp_sdef) | ||||
| 				etp->tp_sdef = tp->tp_sdef; | ||||
| 			etp->tp_size = tp->tp_size; | ||||
| 			etp->tp_align = tp->tp_align; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| 	while (atp) { | ||||
| 		if (atp->tp_nel >= 0) { | ||||
| 	while (atp) | ||||
| 	{ | ||||
| 		if (atp->tp_nel >= 0) | ||||
| 		{ | ||||
| 			atp->tp_size = atp->tp_nel * tp->tp_size; | ||||
| 		} | ||||
| 		atp = atp->next; | ||||
|  |  | |||
|  | @ -4,8 +4,13 @@ | |||
|  */ | ||||
| /* $Id$ */ | ||||
| /* TYPE DESCRIPTOR */ | ||||
| #ifndef TYPE_H_ | ||||
| #define TYPE_H_ | ||||
| 
 | ||||
| #include	"parameters.h" | ||||
| #include    "arith.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| struct type	{ | ||||
| 	struct type *next;	/* used for ARRAY and for qualifiers */ | ||||
|  | @ -59,13 +64,6 @@ struct type	{ | |||
| #define	TQ_VOLATILE	0x01 | ||||
| #define	TQ_CONST	0x02 | ||||
| 
 | ||||
| extern struct type | ||||
| 	*create_type(), *standard_type(), *construct_type(), *pointer_to(), | ||||
| 	*array_of(), *function_of(), *promoted_type(); | ||||
| 
 | ||||
| #ifndef NOBITFIELD | ||||
| extern struct type *field_of(); | ||||
| #endif /* NOBITFIELD */ | ||||
| 
 | ||||
| extern struct type | ||||
| 	*schar_type, *uchar_type, | ||||
|  | @ -79,6 +77,24 @@ extern struct type | |||
| 
 | ||||
| extern struct type *pa_type;	/* type.c	*/ | ||||
| 
 | ||||
| extern arith size_of_type(), align(); | ||||
| struct type *create_type(int fund); | ||||
| struct type *promoted_type(struct type *tp); | ||||
| struct type *construct_type(int fund, register struct type *tp, int qual, | ||||
| arith count, /* for fund == ARRAY only */ | ||||
|    register struct proto *pl); | ||||
| struct type *function_of(register struct type *tp, struct proto *pl, int qual); | ||||
| struct type *pointer_to(register struct type *tp, int qual); | ||||
| struct type * array_of(register struct type *tp, arith count, int qual); | ||||
| #ifndef NOBITFIELD | ||||
| struct type * field_of(register struct type *tp, int qual); | ||||
| #endif /* NOBITFIELD */ | ||||
| arith size_of_type(struct type *tp, char nm[]); | ||||
| void idf2type(struct idf *idf, struct type **tpp); | ||||
| arith align(arith pos, int al); | ||||
| struct type * standard_type(int fund, int sgn, int algn, arith sz); | ||||
| void completed(struct type *tp); | ||||
| 
 | ||||
| 
 | ||||
| /* ALLOCDEF "type" 50 */ | ||||
| 
 | ||||
| #endif | ||||
|  | @ -41,16 +41,14 @@ static int	loc_id; | |||
| 
 | ||||
| extern char options[]; | ||||
| 
 | ||||
| LocalInit() | ||||
| void LocalInit(void) | ||||
| { | ||||
| #ifdef USE_TMP | ||||
| 	C_insertpart(loc_id = C_getid()); | ||||
| #endif /* USE_TMP */ | ||||
| } | ||||
| 
 | ||||
| arith | ||||
| LocalSpace(sz, al) | ||||
| 	arith sz; | ||||
| arith LocalSpace(arith sz, int al) | ||||
| { | ||||
| 	register struct stack_level *stl = local_level; | ||||
| 
 | ||||
|  | @ -61,9 +59,7 @@ LocalSpace(sz, al) | |||
| #define TABSIZ 32 | ||||
| static struct localvar *regs[TABSIZ]; | ||||
| 
 | ||||
| arith | ||||
| NewLocal(sz, al, regtype, sc) | ||||
| 	arith sz; | ||||
| arith NewLocal(arith sz, int al, int regtype, int sc) | ||||
| { | ||||
| 	register struct localvar *tmp = FreeTmps; | ||||
| 	struct localvar *prev = 0; | ||||
|  | @ -98,8 +94,7 @@ NewLocal(sz, al, regtype, sc) | |||
| 	return tmp->t_offset; | ||||
| } | ||||
| 
 | ||||
| FreeLocal(off) | ||||
| 	arith off; | ||||
| void FreeLocal(arith off) | ||||
| { | ||||
| 	int index = (int) (off >> 2) & (TABSIZ - 1); | ||||
| 	register struct localvar *tmp = regs[index]; | ||||
|  | @ -117,7 +112,7 @@ FreeLocal(off) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| LocalFinish() | ||||
| void LocalFinish(void) | ||||
| { | ||||
| 	register struct localvar *tmp, *tmp1; | ||||
| 	register int i; | ||||
|  | @ -163,9 +158,7 @@ LocalFinish() | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| void | ||||
| RegisterAccount(offset, size, regtype, sc) | ||||
| 	arith offset, size; | ||||
| void RegisterAccount(arith offset, arith size, int regtype, int sc) | ||||
| { | ||||
| 	register struct localvar *p; | ||||
| 	int index; | ||||
|  | @ -183,9 +176,7 @@ RegisterAccount(offset, size, regtype, sc) | |||
| 	regs[index] = p; | ||||
| } | ||||
| 
 | ||||
| static struct localvar * | ||||
| find_reg(off) | ||||
| 	arith off; | ||||
| static struct localvar *find_reg(arith off) | ||||
| { | ||||
| 	register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)]; | ||||
| 
 | ||||
|  | @ -193,8 +184,7 @@ find_reg(off) | |||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| LoadLocal(off, sz) | ||||
| 	arith off, sz; | ||||
| void LoadLocal(arith off, arith sz) | ||||
| { | ||||
| 	register struct localvar *p = find_reg(off); | ||||
| 
 | ||||
|  | @ -213,8 +203,7 @@ LoadLocal(off, sz) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| StoreLocal(off, sz) | ||||
| 	arith off, sz; | ||||
| void StoreLocal(arith off, arith sz) | ||||
| { | ||||
| 	register struct localvar *p = find_reg(off); | ||||
| 
 | ||||
|  | @ -234,8 +223,7 @@ StoreLocal(off, sz) | |||
| } | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| AddrLocal(off) | ||||
| 	arith off; | ||||
| void AddrLocal(arith off) | ||||
| { | ||||
| 	register struct localvar *p = find_reg(off); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,8 @@ | |||
| #ifndef UTIL_H_ | ||||
| #define UTIL_H_ | ||||
| 
 | ||||
| #include "arith.h" | ||||
| 
 | ||||
| struct localvar { | ||||
| 	struct localvar	*next; | ||||
| 	arith		t_offset;	/* offset from LocalBase */ | ||||
|  | @ -9,3 +14,18 @@ struct localvar { | |||
| }; | ||||
| 
 | ||||
| /* ALLOCDEF "localvar" 10 */ | ||||
| 
 | ||||
| void LocalInit(void); | ||||
| arith LocalSpace(arith sz, int al); | ||||
| arith NewLocal(arith sz, int al, int regtype, int sc); | ||||
| void FreeLocal(arith off); | ||||
| void LocalFinish(void); | ||||
| void RegisterAccount(arith offset, arith size, int regtype, int sc); | ||||
| void LoadLocal(arith off, arith sz); | ||||
| void StoreLocal(arith off, arith sz); | ||||
| 
 | ||||
| #ifndef	LINT | ||||
| void AddrLocal(arith off); | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	Add table
		
		Reference in a new issue