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,138 +1,138 @@ | ||||||
| !File: lint.h | !File: lint.h | ||||||
| /*#define	LINT		1	/* if defined, 'lint' is produced	*/ | /*#define	LINT		1	*//* if defined, 'lint' is produced	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: pathlength.h | !File: pathlength.h | ||||||
| #define PATHLENGTH	1024	/* max. length of path to file		*/ | #define PATHLENGTH	1024	/* max. length of path to file		*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: errout.h | !File: errout.h | ||||||
| #define	ERROUT		STDERR	/* file pointer for writing messages	*/ | #define	ERROUT		STDERR	/* file pointer for writing messages	*/ | ||||||
| #define	ERR_SHADOW	5	/* a syntax error overshadows error messages | #define	ERR_SHADOW	5	/* a syntax error overshadows error messages | ||||||
| 					until ERR_SHADOW symbols have been | 					until ERR_SHADOW symbols have been | ||||||
| 					accepted without syntax error */ | 					accepted without syntax error */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: idfsize.h | !File: idfsize.h | ||||||
| #define	IDFSIZE	64	/* maximum significant length of an identifier	*/ | #define	IDFSIZE	64	/* maximum significant length of an identifier	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: numsize.h | !File: numsize.h | ||||||
| #define	NUMSIZE	256	/* maximum length of a numeric constant		*/ | #define	NUMSIZE	256	/* maximum length of a numeric constant		*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: nparams.h | !File: nparams.h | ||||||
| #define	NPARAMS 32	/* maximum number of parameters 		*/ | #define	NPARAMS 32	/* maximum number of parameters 		*/ | ||||||
| #define	STDC_NPARAMS 31	/* ANSI limit on number of parameters		*/ | #define	STDC_NPARAMS 31	/* ANSI limit on number of parameters		*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: ifdepth.h | !File: ifdepth.h | ||||||
| #define	IFDEPTH	256	/* maximum number of nested if-constructions	*/ | #define	IFDEPTH	256	/* maximum number of nested if-constructions	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: density.h | !File: density.h | ||||||
| #define	DENSITY	3	/* see switch.[ch] for an explanation		*/ | #define	DENSITY	3	/* see switch.[ch] for an explanation		*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: macbuf.h | !File: macbuf.h | ||||||
| #define	LAPBUF	128	/* initial size of macro replacement buffer	*/ | #define	LAPBUF	128	/* initial size of macro replacement buffer	*/ | ||||||
| #define ARGBUF	128	/* initial size of macro parameter buffer(s)	*/ | #define ARGBUF	128	/* initial size of macro parameter buffer(s)	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: strsize.h | !File: strsize.h | ||||||
| #define ISTRSIZE	32	/* minimum number of bytes allocated for | #define ISTRSIZE	32	/* minimum number of bytes allocated for | ||||||
| 					storing a string		*/ | 					storing a string		*/ | ||||||
| #define RSTRSIZE	16	/* step size in enlarging the memory for | #define RSTRSIZE	16	/* step size in enlarging the memory for | ||||||
| 					the storage of a string		*/ | 					the storage of a string		*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: trgt_sizes.h | !File: trgt_sizes.h | ||||||
| #define MAXSIZE		8	/* the maximum of the SZ_* constants	*/ | #define MAXSIZE		8	/* the maximum of the SZ_* constants	*/ | ||||||
| 
 | 
 | ||||||
| /* target machine sizes	*/ | /* target machine sizes	*/ | ||||||
| #define	SZ_CHAR		1 | #define	SZ_CHAR		1 | ||||||
| #define	SZ_SHORT	2 | #define	SZ_SHORT	2 | ||||||
| #define SZ_WORD		4 | #define SZ_WORD		4 | ||||||
| #define	SZ_INT		4 | #define	SZ_INT		4 | ||||||
| #define	SZ_LONG		4 | #define	SZ_LONG		4 | ||||||
| #define	SZ_FLOAT	4 | #define	SZ_FLOAT	4 | ||||||
| #define	SZ_DOUBLE	8 | #define	SZ_DOUBLE	8 | ||||||
| #define	SZ_LNGDBL	8	/* for now */ | #define	SZ_LNGDBL	8	/* for now */ | ||||||
| #define	SZ_POINTER	4 | #define	SZ_POINTER	4 | ||||||
| 
 | 
 | ||||||
| /* target machine alignment requirements	*/ | /* target machine alignment requirements	*/ | ||||||
| #define	AL_CHAR		1 | #define	AL_CHAR		1 | ||||||
| #define	AL_SHORT	SZ_SHORT | #define	AL_SHORT	SZ_SHORT | ||||||
| #define AL_WORD		SZ_WORD | #define AL_WORD		SZ_WORD | ||||||
| #define	AL_INT		SZ_WORD | #define	AL_INT		SZ_WORD | ||||||
| #define	AL_LONG		SZ_WORD | #define	AL_LONG		SZ_WORD | ||||||
| #define	AL_FLOAT	SZ_WORD | #define	AL_FLOAT	SZ_WORD | ||||||
| #define	AL_DOUBLE	SZ_WORD | #define	AL_DOUBLE	SZ_WORD | ||||||
| #define	AL_LNGDBL	SZ_WORD | #define	AL_LNGDBL	SZ_WORD | ||||||
| #define	AL_POINTER	SZ_WORD | #define	AL_POINTER	SZ_WORD | ||||||
| #define AL_STRUCT	1 | #define AL_STRUCT	1 | ||||||
| #define AL_UNION	1 | #define AL_UNION	1 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: botch_free.h | !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 | !File: dataflow.h | ||||||
| #define DATAFLOW	1	/* produce some compile-time xref	*/ | #define DATAFLOW	1	/* produce some compile-time xref	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: debug.h | !File: debug.h | ||||||
| /*#define DEBUG		1	/* perform various self-tests		*/ | /*#define DEBUG		1	*//* perform various self-tests		*/ | ||||||
| #define NDEBUG		1	/* disable assertions			*/ | #define NDEBUG		1	/* disable assertions			*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: use_tmp.h | !File: use_tmp.h | ||||||
| #define PREPEND_SCOPES	1	/* collect exa, exp, ina and inp commands | #define PREPEND_SCOPES	1	/* collect exa, exp, ina and inp commands | ||||||
| 					and if USE_TMP is defined let them | 					and if USE_TMP is defined let them | ||||||
| 					precede the rest of the generated | 					precede the rest of the generated | ||||||
| 					compact code	*/ | 					compact code	*/ | ||||||
| #define USE_TMP		1	/* use C_insertpart, C_endpart mechanism | #define USE_TMP		1	/* use C_insertpart, C_endpart mechanism | ||||||
| 					to generate EM-code in the order needed | 					to generate EM-code in the order needed | ||||||
| 					for the code-generators. If not defined, | 					for the code-generators. If not defined, | ||||||
| 					the old-style peephole optimizer is | 					the old-style peephole optimizer is | ||||||
| 					needed.	*/ | 					needed.	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: parbufsize.h | !File: parbufsize.h | ||||||
| #define PARBUFSIZE	1024 | #define PARBUFSIZE	1024 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: textsize.h | !File: textsize.h | ||||||
| #define ITEXTSIZE	32	/* 1st piece of memory for repl. text	*/ | #define ITEXTSIZE	32	/* 1st piece of memory for repl. text	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: inputtype.h | !File: inputtype.h | ||||||
| #define INP_READ_IN_ONE	1	/* read input file in one	*/ | #define INP_READ_IN_ONE	1	/* read input file in one	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: nobitfield.h | !File: nobitfield.h | ||||||
| /*#define NOBITFIELD	1	/* if NOT defined, implement bitfields	*/ | /*#define NOBITFIELD	1	*//* if NOT defined, implement bitfields	*/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: spec_arith.h | !File: spec_arith.h | ||||||
| /* describes internal compiler arithmetics */ | /* describes internal compiler arithmetics */ | ||||||
| #undef	SPECIAL_ARITHMETICS	/* something different from native long */ | #undef	SPECIAL_ARITHMETICS	/* something different from native long */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: static.h | !File: static.h | ||||||
| #define GSTATIC			/* for large global "static" arrays */ | #define GSTATIC			/* for large global "static" arrays */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: nocross.h | !File: nocross.h | ||||||
| /*#define NOCROSS		1	/* if NOT defined, cross compiler */ | /*#define NOCROSS		1	*//* if NOT defined, cross compiler */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: regcount.h | !File: regcount.h | ||||||
| /*#define REGCOUNT		1	/* count occurrences for register messages */ | /*#define REGCOUNT		1	*//* count occurrences for register messages */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| !File: dbsymtab.h | !File: dbsymtab.h | ||||||
| #define DBSYMTAB	1	/* ability to produce symbol table for debugger */ | #define DBSYMTAB	1	/* ability to produce symbol table for debugger */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										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 "Lpars.h" | ||||||
| #include "class.h" | #include "class.h" | ||||||
| #include "sizes.h" | #include "sizes.h" | ||||||
|  | #include "error.h" | ||||||
|  | #include "domacro.h" | ||||||
| #include "specials.h" /* registration of special identifiers */ | #include "specials.h" /* registration of special identifiers */ | ||||||
| 
 | 
 | ||||||
| /* Data about the token yielded */ | /* Data about the token yielded */ | ||||||
|  | @ -41,7 +43,16 @@ extern arith full_mask[]; | ||||||
| extern int lint_skip_comment; | extern int lint_skip_comment; | ||||||
| #endif | #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.
 | 	/*	LLlex() plays the role of Lexical Analyzer for the C parser.
 | ||||||
| 	    The look-ahead and putting aside of tokens are taken into | 	    The look-ahead and putting aside of tokens are taken into | ||||||
|  | @ -72,10 +83,8 @@ int LLlex() | ||||||
| 	return DOT; | 	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
 | 	/*	GetToken() is the actual token recognizer. It calls the
 | ||||||
| 	    control line interpreter if it encounters a "\n{w}*#" | 	    control line interpreter if it encounters a "\n{w}*#" | ||||||
|  | @ -379,7 +388,7 @@ go_on: /* rescan, the following character has been read	*/ | ||||||
| 	/*NOTREACHED*/ | 	/*NOTREACHED*/ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| arith char_constant(nm) char* nm; | static arith char_constant(char* nm) | ||||||
| { | { | ||||||
| 	register arith val = 0; | 	register arith val = 0; | ||||||
| 	register int ch; | 	register int ch; | ||||||
|  | @ -413,8 +422,7 @@ arith char_constant(nm) char* nm; | ||||||
| 	return val; | 	return val; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char* string_token(nm, stop_char, plen) char* nm; | static char* string_token(char *nm, int stop_char, int *plen) | ||||||
| int* plen; |  | ||||||
| { | { | ||||||
| 	register int ch; | 	register int ch; | ||||||
| 	register int str_size; | 	register int str_size; | ||||||
|  | @ -447,7 +455,7 @@ int* plen; | ||||||
| 	return str; | 	return str; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int quoted(ch) register int ch; | static int quoted(register int ch) | ||||||
| { | { | ||||||
| 	/*	quoted() replaces an escaped character sequence by the
 | 	/*	quoted() replaces an escaped character sequence by the
 | ||||||
| 	    character meant. | 	    character meant. | ||||||
|  | @ -510,12 +518,12 @@ int quoted(ch) register int ch; | ||||||
| 	return ch & 0377; | 	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; | 	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
 | 	/*	The routines GetChar and trigraph parses the trigraph
 | ||||||
| 	    sequences and removes occurences of \\\n. | 	    sequences and removes occurences of \\\n. | ||||||
|  | @ -529,8 +537,7 @@ int GetChar() | ||||||
| /* strflt2tok only checks the syntax of the floating-point number and
 | /* strflt2tok only checks the syntax of the floating-point number and
 | ||||||
|  * selects the right type for the number. |  * selects the right type for the number. | ||||||
|  */ |  */ | ||||||
| strflt2tok(fltbuf, ptok) char fltbuf[]; | static void strflt2tok(char fltbuf[], struct token* ptok) | ||||||
| struct token* ptok; |  | ||||||
| { | { | ||||||
| 	register char* cp = fltbuf; | 	register char* cp = fltbuf; | ||||||
| 	int malformed = 0; | 	int malformed = 0; | ||||||
|  | @ -584,8 +591,7 @@ struct token* ptok; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| strint2tok(intbuf, ptok) char intbuf[]; | static void strint2tok(char intbuf[], struct token* ptok) | ||||||
| struct token* ptok; |  | ||||||
| { | { | ||||||
| 	register char* cp = intbuf; | 	register char* cp = intbuf; | ||||||
| 	int base = 10; | 	int base = 10; | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ | ||||||
| 	called a "symbol", but it may have other information associated | 	called a "symbol", but it may have other information associated | ||||||
| 	to it. | 	to it. | ||||||
| */ | */ | ||||||
|  | #ifndef LLLEX_H_ | ||||||
|  | #define LLLEX_H_ | ||||||
| 
 | 
 | ||||||
| #include "file_info.h" | #include "file_info.h" | ||||||
| 
 | 
 | ||||||
|  | @ -56,3 +58,9 @@ extern int err_occurred;	/* "error.c"	*/ | ||||||
| #define	ASIDE	aside.tk_symb | #define	ASIDE	aside.tk_symb | ||||||
| 
 | 
 | ||||||
| #define EOF	(-1) | #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	"arith.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| 
 | 
 | ||||||
| LLmessage(tk)	{ | static void insert_token(int ); | ||||||
|  | 
 | ||||||
|  | void LLmessage(int tk) | ||||||
|  | { | ||||||
| 	err_occurred = 1; | 	err_occurred = 1; | ||||||
| 	if (tk < 0)	{ | 	if (tk < 0) | ||||||
|  | 	{ | ||||||
| 		error("end of file expected"); | 		error("end of file expected"); | ||||||
| 	} | 	} | ||||||
| 	else if (tk)	{ | 	else if (tk) | ||||||
|  | 	{ | ||||||
| #ifndef LLNONCORR | #ifndef LLNONCORR | ||||||
| 		error("%s missing before %s", symbol2str(tk), symbol2str(DOT)); | 		error("%s missing before %s", symbol2str(tk), symbol2str(DOT)); | ||||||
| #endif | #endif | ||||||
| 		insert_token(tk); | 		insert_token(tk); | ||||||
| 	} | 	} | ||||||
| 	else	{ | 	else | ||||||
|  | 	{ | ||||||
| #ifndef LLNONCORR | #ifndef LLNONCORR | ||||||
| 		error("%s deleted", symbol2str(DOT)); | 		error("%s deleted", symbol2str(DOT)); | ||||||
| #else | #else | ||||||
|  | @ -34,14 +41,14 @@ LLmessage(tk)	{ | ||||||
| 	tk_nmb_at_last_syn_err = token_nmb; | 	tk_nmb_at_last_syn_err = token_nmb; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| insert_token(tk) | static void insert_token(int tk) | ||||||
| 	int tk; |  | ||||||
| { | { | ||||||
| 	aside = dot; | 	aside = dot; | ||||||
| 
 | 
 | ||||||
| 	DOT = tk; | 	DOT = tk; | ||||||
| 
 | 
 | ||||||
| 	switch (tk)	{ | 	switch (tk) | ||||||
|  | 	{ | ||||||
| 	/* The operands need some body */ | 	/* The operands need some body */ | ||||||
| 	case IDENTIFIER: | 	case IDENTIFIER: | ||||||
| 		dot.tk_idf = gen_idf(); | 		dot.tk_idf = gen_idf(); | ||||||
|  |  | ||||||
|  | @ -24,16 +24,19 @@ | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"field.h" | #include	"field.h" | ||||||
| #include	"mes.h" | #include	"mes.h" | ||||||
|  | #include    "cstoper.h" | ||||||
|  | #include    "ch3bin.h" | ||||||
|  | #include    "ch3.h" | ||||||
|  | #include    "error.h" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| extern char options[]; | extern char options[]; | ||||||
| extern arith flt_flt2arith(); | extern arith flt_flt2arith(); | ||||||
| extern label code_string(); | extern label code_string(); | ||||||
| 
 | 
 | ||||||
| void | /* 3.1.2.5 */ | ||||||
| arithbalance(e1p, oper, e2p)	/* 3.1.2.5 */ | void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p) | ||||||
| 	register struct expr **e1p, **e2p; |  | ||||||
| 	int oper; |  | ||||||
| { | { | ||||||
| 	/*	The expressions *e1p and *e2p are balanced to be operands
 | 	/*	The expressions *e1p and *e2p are balanced to be operands
 | ||||||
| 		of the arithmetic operator oper. | 		of the arithmetic operator oper. | ||||||
|  | @ -171,8 +174,7 @@ arithbalance(e1p, oper, e2p)	/* 3.1.2.5 */ | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| relbalance(e1p, oper, e2p) | void relbalance(register struct expr **e1p, int oper, register struct expr **e2p) | ||||||
| 	register struct expr **e1p, **e2p; |  | ||||||
| { | { | ||||||
| 	/*	The expressions *e1p and *e2p are balanced to be operands
 | 	/*	The expressions *e1p and *e2p are balanced to be operands
 | ||||||
| 		of the relational operator oper, or the ':'. | 		of the relational operator oper, or the ':'. | ||||||
|  | @ -204,9 +206,7 @@ relbalance(e1p, oper, e2p) | ||||||
| 		arithbalance(e1p, oper, e2p); | 		arithbalance(e1p, oper, e2p); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ch3pointer(expp, oper, tp) | void ch3pointer(struct expr **expp, int oper, register struct type *tp) | ||||||
| 	struct expr **expp; |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	Checks whether *expp may be compared to tp using oper,
 | 	/*	Checks whether *expp may be compared to tp using oper,
 | ||||||
| 		as described in chapter 3.3.8 and 3.3.9. | 		as described in chapter 3.3.8 and 3.3.9. | ||||||
|  | @ -238,9 +238,7 @@ ch3pointer(expp, oper, tp) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| any2arith(expp, oper) | any2arith(register struct expr **expp, register int oper) | ||||||
| 	register struct expr **expp; |  | ||||||
| 	register int oper; |  | ||||||
| { | { | ||||||
| 	/*	Turns any expression into int_type, long_type,
 | 	/*	Turns any expression into int_type, long_type,
 | ||||||
| 		float_type, double_type or lngdbl_type. | 		float_type, double_type or lngdbl_type. | ||||||
|  | @ -295,8 +293,7 @@ any2arith(expp, oper) | ||||||
| 	return (*expp)->ex_type->tp_fund; | 	return (*expp)->ex_type->tp_fund; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| erroneous2int(expp) | void erroneous2int(struct expr **expp) | ||||||
| 	struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	the (erroneous) expression *expp is replaced by an
 | 	/*	the (erroneous) expression *expp is replaced by an
 | ||||||
| 		int expression | 		int expression | ||||||
|  | @ -310,11 +307,7 @@ erroneous2int(expp) | ||||||
| 	*expp = exp; | 	*expp = exp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct expr * | struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr) | ||||||
| arith2arith(tp, oper, expr) |  | ||||||
| 	struct type *tp; |  | ||||||
| 	int oper; |  | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	arith2arith constructs a new expression containing a
 | 	/*	arith2arith constructs a new expression containing a
 | ||||||
| 		run-time conversion between some arithmetic types. | 		run-time conversion between some arithmetic types. | ||||||
|  | @ -328,10 +321,7 @@ arith2arith(tp, oper, expr) | ||||||
| 	return new_oper(tp, new, oper, expr); | 	return new_oper(tp, new, oper, expr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int int2int(struct expr **expp, register struct type *tp) | ||||||
| int2int(expp, tp) |  | ||||||
| 	struct expr **expp; |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	The expression *expp, which is of some integral type, is
 | 	/*	The expression *expp, which is of some integral type, is
 | ||||||
| 		converted to the integral type tp. | 		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
 | /* With compile-time constants, we don't set fp_used, since this is done
 | ||||||
|  * only when necessary in eval.c. |  * only when necessary in eval.c. | ||||||
|  */ |  */ | ||||||
| int2float(expp, tp) | void int2float(register struct expr **expp, struct type *tp) | ||||||
| 	register struct expr **expp; |  | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	The expression *expp, which is of some integral type, is
 | 	/*	The expression *expp, which is of some integral type, is
 | ||||||
| 		converted to the floating type tp. | 		converted to the floating type tp. | ||||||
|  | @ -390,9 +378,7 @@ int2float(expp, tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float2int(expp, tp) | void float2int(struct expr **expp, struct type *tp) | ||||||
| 	struct expr **expp; |  | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	The expression *expp, which is of some floating type, is
 | 	/*	The expression *expp, which is of some floating type, is
 | ||||||
| 		converted to the integral type tp. | 		converted to the integral type tp. | ||||||
|  | @ -418,9 +404,7 @@ float2int(expp, tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float2float(expp, tp) | void float2float(register struct expr **expp, struct type *tp) | ||||||
| 	register struct expr **expp; |  | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	The expression *expp, which is of some floating type, is
 | 	/*	The expression *expp, which is of some floating type, is
 | ||||||
| 		converted to the floating type tp. | 		converted to the floating type tp. | ||||||
|  | @ -436,8 +420,7 @@ float2float(expp, tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| array2pointer(exp) | void array2pointer(register struct expr *exp) | ||||||
| 	register struct expr *exp; |  | ||||||
| { | { | ||||||
| 	/*	The expression, which must be an array, is converted
 | 	/*	The expression, which must be an array, is converted
 | ||||||
| 		to a pointer. | 		to a pointer. | ||||||
|  | @ -447,8 +430,7 @@ array2pointer(exp) | ||||||
| 				    , (arith)0, NO_PROTO); | 				    , (arith)0, NO_PROTO); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function2pointer(exp) | void function2pointer(register struct expr *exp) | ||||||
| 	register struct expr *exp; |  | ||||||
| { | { | ||||||
| 	/*	The expression, which must be a function, is converted
 | 	/*	The expression, which must be a function, is converted
 | ||||||
| 		to a pointer to the function. | 		to a pointer to the function. | ||||||
|  | @ -457,8 +439,7 @@ function2pointer(exp) | ||||||
| 				     (arith)0, NO_PROTO); | 				     (arith)0, NO_PROTO); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| string2pointer(ex) | void string2pointer(register struct expr *ex) | ||||||
| 	register struct expr *ex; |  | ||||||
| { | { | ||||||
| 	/*	The expression, which must be a string constant, is converted
 | 	/*	The expression, which must be a string constant, is converted
 | ||||||
| 		to a pointer to the string-containing area. | 		to a pointer to the string-containing area. | ||||||
|  | @ -472,9 +453,7 @@ string2pointer(ex) | ||||||
| 	ex->VL_VALUE = (arith)0; | 	ex->VL_VALUE = (arith)0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| opnd2integral(expp, oper) | void opnd2integral(register struct expr **expp, int oper) | ||||||
| 	register struct expr **expp; |  | ||||||
| 	int oper; |  | ||||||
| { | { | ||||||
| 	register int fund = (*expp)->ex_type->tp_fund; | 	register int fund = (*expp)->ex_type->tp_fund; | ||||||
| 
 | 
 | ||||||
|  | @ -486,9 +465,7 @@ opnd2integral(expp, oper) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| opnd2logical(expp, oper) | void opnd2logical(register struct expr **expp, int oper) | ||||||
| 	register struct expr **expp; |  | ||||||
| 	int oper; |  | ||||||
| { | { | ||||||
| 	int fund = (*expp)->ex_type->tp_fund; | 	int fund = (*expp)->ex_type->tp_fund; | ||||||
| 
 | 
 | ||||||
|  | @ -525,8 +502,7 @@ opnd2logical(expp, oper) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| opnd2test(expp, oper) | opnd2test(register struct expr **expp, int oper) | ||||||
| 	register struct expr **expp; |  | ||||||
| { | { | ||||||
| 	opnd2logical(expp, oper); | 	opnd2logical(expp, oper); | ||||||
| 	if ((*expp)->ex_class == Oper) { | 	if ((*expp)->ex_class == Oper) { | ||||||
|  | @ -550,9 +526,7 @@ opnd2test(expp, oper) | ||||||
| 	ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT)); | 	ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void any2opnd(register struct expr **expp, int oper) | ||||||
| any2opnd(expp, oper) |  | ||||||
| 	register struct expr **expp; |  | ||||||
| { | { | ||||||
| 	if (!*expp) | 	if (!*expp) | ||||||
| 		return; | 		return; | ||||||
|  | @ -584,8 +558,7 @@ any2opnd(expp, oper) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| any2parameter(expp) | void any2parameter(register struct expr **expp) | ||||||
| 	register struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	To handle default argument promotions
 | 	/*	To handle default argument promotions
 | ||||||
| 	*/ | 	*/ | ||||||
|  | @ -598,8 +571,7 @@ any2parameter(expp) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef NOBITFIELD | #ifndef NOBITFIELD | ||||||
| field2arith(expp) | void field2arith(register struct expr **expp) | ||||||
| 	register struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	The expression to extract the bitfield value from the
 | 	/*	The expression to extract the bitfield value from the
 | ||||||
| 		memory word is put in the tree. | 		memory word is put in the tree. | ||||||
|  | @ -630,8 +602,7 @@ field2arith(expp) | ||||||
| /*	switch_sign_fp() negates the given floating constant expression,
 | /*	switch_sign_fp() negates the given floating constant expression,
 | ||||||
|  *	and frees the string representing the old value. |  *	and frees the string representing the old value. | ||||||
|  */ |  */ | ||||||
| switch_sign_fp(expr) | void switch_sign_fp(register struct expr *expr) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	flt_umin(&(expr->FL_ARITH)); | 	flt_umin(&(expr->FL_ARITH)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -12,12 +12,15 @@ | ||||||
| 	to save storage on small machines, SPECIAL_ARITHMETICS will | 	to save storage on small machines, SPECIAL_ARITHMETICS will | ||||||
| 	be handy. | 	be handy. | ||||||
| */ | */ | ||||||
|  | #ifndef ARITH_H_ | ||||||
|  | #define ARITH_H_ | ||||||
| 
 | 
 | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
| 
 | 
 | ||||||
| #ifndef	SPECIAL_ARITHMETICS | #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 */ | #else	/* SPECIAL_ARITHMETICS */ | ||||||
| 
 | 
 | ||||||
|  | @ -27,6 +30,32 @@ | ||||||
| 
 | 
 | ||||||
| #endif	/* SPECIAL_ARITHMETICS */ | #endif	/* SPECIAL_ARITHMETICS */ | ||||||
| 
 | 
 | ||||||
|  | struct expr; | ||||||
|  | struct type; | ||||||
|  | 
 | ||||||
| #define	arith_size	(sizeof(arith)) | #define	arith_size	(sizeof(arith)) | ||||||
| #define	arith_sign	((arith) 1 << (arith_size * 8 - 1)) | #define	arith_sign	((arith) 1 << (arith_size * 8 - 1)) | ||||||
| #define	max_arith	(~arith_sign) | #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 "label.h" | ||||||
| #include "stack.h" | #include "stack.h" | ||||||
| #include "Lpars.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 LocalPtrVar()	NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER) | ||||||
| #define LocalIntVar()	NewLocal(int_size, int_align, reg_any, REGISTER) | #define LocalIntVar()	NewLocal(int_size, int_align, reg_any, REGISTER) | ||||||
| #endif /* STB */ | #endif /* STB */ | ||||||
|  | @ -52,9 +55,7 @@ extern arith NewLocal(); | ||||||
| 	while we need a loop to store the stack block into a memory object. | 	while we need a loop to store the stack block into a memory object. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| suitable_sz(sz, al) | int suitable_sz(arith sz, int al) | ||||||
| 	arith sz; |  | ||||||
| 	int al; |  | ||||||
| { | { | ||||||
| 	return	((int)sz % (int)word_size == 0 && al % word_align == 0) || | 	return	((int)sz % (int)word_size == 0 && al % word_align == 0) || | ||||||
| 		( | 		( | ||||||
|  | @ -64,9 +65,7 @@ suitable_sz(sz, al) | ||||||
| 		); | 		); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| store_block(sz, al) | void store_block(arith sz, int al) | ||||||
| 	arith sz; |  | ||||||
| 	int al; |  | ||||||
| { | { | ||||||
| 	if (suitable_sz(sz, al)) | 	if (suitable_sz(sz, al)) | ||||||
| 		C_sti(sz); | 		C_sti(sz); | ||||||
|  | @ -102,9 +101,7 @@ store_block(sz, al) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| load_block(sz, al) | void load_block(arith sz, int al) | ||||||
| 	arith sz; |  | ||||||
| 	int al; |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| 	if (suitable_sz(sz, al)) | 	if (suitable_sz(sz, al)) | ||||||
|  | @ -138,9 +135,7 @@ load_block(sz, al) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| copy_block(sz, al) | void copy_block(arith sz, int al) | ||||||
| 	arith sz; |  | ||||||
| 	int al; |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| 	if (suitable_sz(sz, al)) | 	if (suitable_sz(sz, al)) | ||||||
|  | @ -167,8 +162,7 @@ copy_block(sz, al) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef STB | #ifndef STB | ||||||
| copy_loop(sz, src, dst) | void copy_loop(arith sz, arith src, arith dst) | ||||||
| 	arith sz, src, dst; |  | ||||||
| { | { | ||||||
| 	/* generate inline byte-copy loop */ | 	/* generate inline byte-copy loop */ | ||||||
| 	label l_cont = text_label(), l_stop = text_label(); | 	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	"parameters.h" | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
|  | #include    "ch3.h" | ||||||
| #include    "idf.h" | #include    "idf.h" | ||||||
| #include	"proto.h" | #include	"proto.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
|  | @ -17,23 +18,22 @@ | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | #include    "error.h" | ||||||
|  | #include    "ch3bin.h" | ||||||
| #include	"file_info.h" | #include	"file_info.h" | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| extern struct type *qualifier_type(); | extern struct type *qualifier_type(); | ||||||
| 
 | 
 | ||||||
| void ch3cast(); | 
 | ||||||
| 
 | 
 | ||||||
| /*	Most expression-handling routines have a pointer to a
 | /*	Most expression-handling routines have a pointer to a
 | ||||||
| 	(struct type *) as first parameter. The object under the pointer | 	(struct type *) as first parameter. The object under the pointer | ||||||
| 	gets updated in the process. | 	gets updated in the process. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| void | void ch3sel(struct expr **expp, int oper, struct idf *idf) | ||||||
| ch3sel(expp, oper, idf) |  | ||||||
| 	struct expr **expp; |  | ||||||
| 	struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	The selector idf is applied to *expp; oper may be '.' or
 | 	/*	The selector idf is applied to *expp; oper may be '.' or
 | ||||||
| 		ARROW. | 		ARROW. | ||||||
|  | @ -163,8 +163,7 @@ ch3sel(expp, oper, idf) | ||||||
| 	*expp = exp; | 	*expp = exp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ch3incr(expp, oper) | void ch3incr(struct expr **expp, int oper) | ||||||
| 	struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	The monadic prefix/postfix incr/decr operator oper is
 | 	/*	The monadic prefix/postfix incr/decr operator oper is
 | ||||||
| 		applied to *expp. | 		applied to *expp. | ||||||
|  | @ -172,10 +171,7 @@ ch3incr(expp, oper) | ||||||
| 	ch3asgn(expp, oper, intexpr((arith)1, INT)); | 	ch3asgn(expp, oper, intexpr((arith)1, INT)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void ch3cast(register struct expr **expp, int oper, register struct type *tp) | ||||||
| ch3cast(expp, oper, tp) |  | ||||||
| 	register struct expr **expp; |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	The expression *expp is cast to type tp; the cast is
 | 	/*	The expression *expp is cast to type tp; the cast is
 | ||||||
| 		caused by the operator oper.  If the cast has | 		caused by the operator oper.  If the cast has | ||||||
|  | @ -412,9 +408,7 @@ ch3cast(expp, oper, tp) | ||||||
| 
 | 
 | ||||||
| /*	Determine whether two types are equal.
 | /*	Determine whether two types are equal.
 | ||||||
| */ | */ | ||||||
| equal_type(tp, otp, qual_lev, diag) | int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag) | ||||||
| 	register struct type *tp, *otp; |  | ||||||
| 	int qual_lev, diag; |  | ||||||
| { | { | ||||||
| 	 if (tp == otp) | 	 if (tp == otp) | ||||||
| 		return 1; | 		return 1; | ||||||
|  | @ -475,8 +469,7 @@ equal_type(tp, otp, qual_lev, diag) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| check_pseudoproto(pl, opl, diag) | int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag) | ||||||
| 	register struct proto *pl, *opl; |  | ||||||
| { | { | ||||||
| 	int retval = 1; | 	int retval = 1; | ||||||
| 
 | 
 | ||||||
|  | @ -519,9 +512,7 @@ check_pseudoproto(pl, opl, diag) | ||||||
| 	return retval; | 	return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| legal_mixture(tp, otp, diag) | int legal_mixture(struct type *tp, struct type *otp, int diag) | ||||||
| 	struct type *tp, *otp; |  | ||||||
| 	int diag; |  | ||||||
| { | { | ||||||
| 	struct proto *pl = tp->tp_proto, *opl = otp->tp_proto; | 	struct proto *pl = tp->tp_proto, *opl = otp->tp_proto; | ||||||
| 	int retval = 1; | 	int retval = 1; | ||||||
|  | @ -562,9 +553,7 @@ legal_mixture(tp, otp, diag) | ||||||
| 	return retval; | 	return retval; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| equal_proto(pl, opl, diag) | int equal_proto(register struct proto *pl, register struct proto *opl, int diag) | ||||||
| 	register struct proto *pl, *opl; |  | ||||||
| 	int diag; |  | ||||||
| { | { | ||||||
| 	if (pl == opl) | 	if (pl == opl) | ||||||
| 		return 1; | 		return 1; | ||||||
|  | @ -586,9 +575,7 @@ equal_proto(pl, opl, diag) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* check if a type has a consqualified member */ | /* check if a type has a consqualified member */ | ||||||
| recurqual(tp, qual) | int recurqual(struct type *tp, int qual) | ||||||
| struct type *tp; |  | ||||||
| int qual; |  | ||||||
| { | { | ||||||
| 	register struct sdef *sdf; | 	register struct sdef *sdf; | ||||||
| 
 | 
 | ||||||
|  | @ -610,9 +597,7 @@ int qual; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ch3asgn(expp, oper, expr) | void ch3asgn(struct expr **expp, int oper, struct expr *expr) | ||||||
| 	struct expr **expp; |  | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	The assignment operators.
 | 	/*	The assignment operators.
 | ||||||
| 		"f op= e" should be interpreted as | 		"f op= e" should be interpreted as | ||||||
|  | @ -687,9 +672,7 @@ ch3asgn(expp, oper, expr) | ||||||
| 
 | 
 | ||||||
| /*	Some interesting (?) questions answered.
 | /*	Some interesting (?) questions answered.
 | ||||||
| */ | */ | ||||||
| int | int is_integral_type(register struct type *tp) | ||||||
| is_integral_type(tp) |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	switch (tp->tp_fund)	{ | 	switch (tp->tp_fund)	{ | ||||||
| 	case CHAR: | 	case CHAR: | ||||||
|  | @ -707,9 +690,7 @@ is_integral_type(tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int is_arith_type(register struct type *tp) | ||||||
| is_arith_type(tp) |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	switch (tp->tp_fund)	{ | 	switch (tp->tp_fund)	{ | ||||||
| 	case CHAR: | 	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	"expr.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"sizes.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 options[]; | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
|  | @ -34,10 +40,7 @@ void pntminuspnt(); | ||||||
| #define commutative_binop(expp, oper, expr)	mk_binop(expp, oper, expr, 1) | #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) | #define non_commutative_relop(expp, oper, expr)	mk_binop(expp, oper, expr, 1) | ||||||
| 
 | 
 | ||||||
| void | void ch3bin(register struct expr **expp, int oper, struct expr *expr) | ||||||
| ch3bin(expp, oper, expr) |  | ||||||
| 	register struct expr **expp; |  | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	apply binary operator oper between *expp and expr.
 | 	/*	apply binary operator oper between *expp and expr.
 | ||||||
| 		NB: don't swap operands if op is one of the op= operators!!! | 		NB: don't swap operands if op is one of the op= operators!!! | ||||||
|  | @ -295,9 +298,7 @@ ch3bin(expp, oper, expr) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr) | ||||||
| pntminuspnt(expp, oper, expr) |  | ||||||
| 	register struct expr **expp, *expr; |  | ||||||
| { | { | ||||||
| 	/*	Subtracting two pointers is so complicated it merits a
 | 	/*	Subtracting two pointers is so complicated it merits a
 | ||||||
| 		routine of its own. | 		routine of its own. | ||||||
|  | @ -328,8 +329,7 @@ pntminuspnt(expp, oper, expr) | ||||||
|  * when the arguments are switched.  This is special for some relational |  * when the arguments are switched.  This is special for some relational | ||||||
|  * operators. |  * operators. | ||||||
|  */ |  */ | ||||||
| int | int arg_switched(int oper) | ||||||
| arg_switched(oper) |  | ||||||
| { | { | ||||||
| 	switch (oper) { | 	switch (oper) { | ||||||
| 	case '<':	return '>'; | 	case '<':	return '>'; | ||||||
|  | @ -340,9 +340,7 @@ arg_switched(oper) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| mk_binop(expp, oper, expr, commutative) | void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative) | ||||||
| 	struct expr **expp; |  | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	Constructs in *expp the operation indicated by the operands.
 | 	/*	Constructs in *expp the operation indicated by the operands.
 | ||||||
| 		"commutative" indicates whether "oper" is a commutative | 		"commutative" indicates whether "oper" is a commutative | ||||||
|  | @ -366,8 +364,7 @@ mk_binop(expp, oper, expr, commutative) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pointer_arithmetic(expp1, oper, expp2) | void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2) | ||||||
| 	register struct expr **expp1, **expp2; |  | ||||||
| { | { | ||||||
| 	int typ; | 	int typ; | ||||||
| 	/*	prepares the integral expression expp2 in order to
 | 	/*	prepares the integral expression expp2 in order to
 | ||||||
|  | @ -387,8 +384,7 @@ pointer_arithmetic(expp1, oper, expp2) | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pointer_binary(expp, oper, expr) | void pointer_binary(register struct expr **expp, int oper, register struct expr *expr) | ||||||
| 	register struct expr **expp, *expr; |  | ||||||
| { | { | ||||||
| 	/*	constructs the pointer arithmetic expression out of
 | 	/*	constructs the pointer arithmetic expression out of
 | ||||||
| 		a pointer expression, a binary operator and an integral | 		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$ */ | /* $Id$ */ | ||||||
| /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */ | /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */ | ||||||
| 
 | 
 | ||||||
|  | #include    "ch3mon.h" | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | @ -16,13 +17,15 @@ | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
|  | #include    "ch3.h" | ||||||
|  | #include    "error.h" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| extern arith full_mask[/*MAXSIZE + 1*/];	/* cstoper.c */ | extern arith full_mask[/*MAXSIZE + 1*/];	/* cstoper.c */ | ||||||
| char *symbol2str(); | char *symbol2str(); | ||||||
| 
 | 
 | ||||||
| ch3mon(oper, expp) | void ch3mon(int oper, register struct expr **expp) | ||||||
| 	register struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	The monadic prefix operator oper is applied to *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	"expr.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"stack.h" | #include	"stack.h" | ||||||
|  | #include    "blocks.h" | ||||||
|  | #include    "struct.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
|  | #include    "dataflow.h" | ||||||
|  | #include    "conversion.h" | ||||||
| #include	"decspecs.h" | #include	"decspecs.h" | ||||||
| #include	"declar.h" | #include	"declar.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"specials.h" | #include	"specials.h" | ||||||
| #include	"atw.h" | #include	"atw.h" | ||||||
|  | #include    "ch3.h" | ||||||
|  | #include    "eval.h" | ||||||
|  | #include    "stab.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
|  | #include    "util.h" | ||||||
|  | #include    "error.h" | ||||||
|  | 
 | ||||||
| #ifdef	LINT | #ifdef	LINT | ||||||
| #include	"l_lint.h" | #include	"l_lint.h" | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
|  | @ -46,7 +56,10 @@ label lab_count = 1; | ||||||
| label datlab_count = 1; | label datlab_count = 1; | ||||||
| 
 | 
 | ||||||
| int fp_used; | int fp_used; | ||||||
| extern arith NewLocal();	/* util.c	*/ | 
 | ||||||
|  | extern void str_cst(register char *, register int, int);  /* ival.c */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* global function info */ | /* global function info */ | ||||||
| char *func_name; | char *func_name; | ||||||
|  | @ -67,8 +80,7 @@ extern char *source; | ||||||
| void loc_init(); | void loc_init(); | ||||||
| 
 | 
 | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
| init_code(dst_file) | void init_code(char *dst_file) | ||||||
| 	char *dst_file; |  | ||||||
| { | { | ||||||
| 	/*	init_code() initialises the output file on which the
 | 	/*	init_code() initialises the output file on which the
 | ||||||
| 		compact EM code is written | 		compact EM code is written | ||||||
|  | @ -105,10 +117,7 @@ init_code(dst_file) | ||||||
| 
 | 
 | ||||||
| struct string_cst *str_list = 0; | struct string_cst *str_list = 0; | ||||||
| 
 | 
 | ||||||
| label | label code_string(char* val, int len) | ||||||
| code_string(val, len) |  | ||||||
| 	char *val; |  | ||||||
| 	int len; |  | ||||||
| { | { | ||||||
| 	register struct string_cst *sc = new_string_cst(); | 	register struct string_cst *sc = new_string_cst(); | ||||||
| 	label dlb = data_label(); | 	label dlb = data_label(); | ||||||
|  | @ -122,8 +131,7 @@ code_string(val, len) | ||||||
| 	return dlb; | 	return dlb; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| def_strings(sc) | void def_strings(register struct string_cst *sc) | ||||||
| 	register struct string_cst *sc; |  | ||||||
| { | { | ||||||
| 	while (sc) { | 	while (sc) { | ||||||
| 		struct string_cst *sc1 = 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() is called from program.g after each external definition */ | ||||||
| flush_strings() { | void flush_strings(void) { | ||||||
| 	if (str_list) { | 	if (str_list) { | ||||||
| 		def_strings(str_list); | 		def_strings(str_list); | ||||||
| 		str_list = 0; | 		str_list = 0; | ||||||
|  | @ -145,7 +153,7 @@ flush_strings() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
| end_code() | void end_code(void) | ||||||
| { | { | ||||||
| 	/*	end_code() performs the actions to be taken when closing
 | 	/*	end_code() performs the actions to be taken when closing
 | ||||||
| 		the output stream. | 		the output stream. | ||||||
|  | @ -160,7 +168,7 @@ end_code() | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 
 | 
 | ||||||
| #ifdef	PREPEND_SCOPES | #ifdef	PREPEND_SCOPES | ||||||
| prepend_scopes() | void prepend_scopes(void) | ||||||
| { | { | ||||||
| 	/*	prepend_scopes() runs down the list of global idf's
 | 	/*	prepend_scopes() runs down the list of global idf's
 | ||||||
| 		and generates those exa's, exp's, ina's and inp's | 		and generates those exa's, exp's, ina's and inp's | ||||||
|  | @ -185,9 +193,7 @@ prepend_scopes() | ||||||
| } | } | ||||||
| #endif	/* PREPEND_SCOPES */ | #endif	/* PREPEND_SCOPES */ | ||||||
| 
 | 
 | ||||||
| code_scope(text, def) | void code_scope(char* text, register struct def *def) | ||||||
| 	char *text; |  | ||||||
| 	register struct def *def; |  | ||||||
| { | { | ||||||
| 	/*	generates code for one name, text, of the storage class
 | 	/*	generates code for one name, text, of the storage class
 | ||||||
| 		as given by def, if meaningful. | 		as given by def, if meaningful. | ||||||
|  | @ -218,9 +224,7 @@ static int struct_return; | ||||||
| static char *last_fn_given = (char *)0; | static char *last_fn_given = (char *)0; | ||||||
| static label file_name_label; | static label file_name_label; | ||||||
| 
 | 
 | ||||||
| begin_proc(ds, idf)		/* to be called when entering a procedure */ | void begin_proc(struct decspecs *ds, struct idf *idf)		/* to be called when entering a procedure */ | ||||||
| 	struct decspecs *ds; |  | ||||||
| 	struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	begin_proc() is called at the entrance of a new function
 | 	/*	begin_proc() is called at the entrance of a new function
 | ||||||
| 		and performs the necessary code generation: | 		and performs the necessary code generation: | ||||||
|  | @ -317,8 +321,7 @@ begin_proc(ds, idf)		/* to be called when entering a procedure */ | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| end_proc(fbytes) | void end_proc(arith fbytes) | ||||||
| 	arith fbytes; |  | ||||||
| { | { | ||||||
| 	/*	end_proc() deals with the code to be generated at the end of
 | 	/*	end_proc() deals with the code to be generated at the end of
 | ||||||
| 		a function, as there is: | 		a function, as there is: | ||||||
|  | @ -388,7 +391,7 @@ end_proc(fbytes) | ||||||
| 	options['n'] = optionsn; | 	options['n'] = optionsn; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_return() | void do_return(void) | ||||||
| { | { | ||||||
| 	/*	do_return handles the case of a return without expression.
 | 	/*	do_return handles the case of a return without expression.
 | ||||||
| 		This version branches to the return label, which is | 		This version branches to the return label, which is | ||||||
|  | @ -401,8 +404,7 @@ do_return() | ||||||
| 	C_bra(return2_label); | 	C_bra(return2_label); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_return_expr(expr) | void do_return_expr(struct expr *expr) | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	do_return_expr() generates the expression and the jump for
 | 	/*	do_return_expr() generates the expression and the jump for
 | ||||||
| 		a return statement with an expression. | 		a return statement with an expression. | ||||||
|  | @ -418,11 +420,11 @@ do_return_expr(expr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| code_declaration(idf, expr, lvl, sc) | code_declaration( | ||||||
| 	register struct idf *idf;	/* idf to be declared	*/ | 	register struct idf *idf,	/* idf to be declared	*/ | ||||||
| 	struct expr *expr;	/* initialisation; NULL if absent	*/ | 	struct expr *expr,	/* initialisation; NULL if absent	*/ | ||||||
| 	int lvl;		/* declaration level	*/ | 	int lvl,		/* declaration level	*/ | ||||||
| 	int sc;			/* storage class, as in the declaration */ | 	int sc)		/* storage class, as in the declaration */ | ||||||
| { | { | ||||||
| 	/*	code_declaration() does the actual declaration of the
 | 	/*	code_declaration() does the actual declaration of the
 | ||||||
| 		variable indicated by "idf" on declaration level "lvl". | 		variable indicated by "idf" on declaration level "lvl". | ||||||
|  | @ -530,10 +532,7 @@ code_declaration(idf, expr, lvl, sc) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void loc_init(struct expr *expr, struct idf *id) | ||||||
| loc_init(expr, id) |  | ||||||
| 	struct expr *expr; |  | ||||||
| 	struct idf *id; |  | ||||||
| { | { | ||||||
| 	/*	loc_init() generates code for the assignment of
 | 	/*	loc_init() generates code for the assignment of
 | ||||||
| 		expression expr to the local variable described by id. | 		expression expr to the local variable described by id. | ||||||
|  | @ -609,8 +608,7 @@ loc_init(expr, id) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bss(idf) | void bss(register struct idf *idf) | ||||||
| 	register struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	bss() allocates bss space for the global idf.
 | 	/*	bss() allocates bss space for the global idf.
 | ||||||
| 	*/ | 	*/ | ||||||
|  | @ -640,9 +638,7 @@ bss(idf) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| formal_cvt(hasproto,df) | void formal_cvt(int hasproto, register struct def *df) | ||||||
| 	int hasproto; |  | ||||||
| 	register struct def *df; |  | ||||||
| { | { | ||||||
| 	/*	formal_cvt() converts a formal parameter of type char or
 | 	/*	formal_cvt() converts a formal parameter of type char or
 | ||||||
| 		short from int to that type. It also converts a formal | 		short from int to that type. It also converts a formal | ||||||
|  | @ -672,9 +668,7 @@ formal_cvt(hasproto,df) | ||||||
| #ifdef	LINT | #ifdef	LINT | ||||||
| /*ARGSUSED*/ | /*ARGSUSED*/ | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| code_expr(expr, val, code, tlbl, flbl) | void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl) | ||||||
| 	struct expr *expr; |  | ||||||
| 	label tlbl, flbl; |  | ||||||
| { | { | ||||||
| 	/*	code_expr() is the parser's interface to the expression code
 | 	/*	code_expr() is the parser's interface to the expression code
 | ||||||
| 		generator.  If line number trace is wanted, it generates a | 		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 | 	which are the only ones that are stacked, only the top of | ||||||
| 	the stack is interesting. | 	the stack is interesting. | ||||||
| */ | */ | ||||||
| code_break() | void code_break(void) | ||||||
| { | { | ||||||
| 	register struct stmt_block *stmt_block = stmt_stack; | 	register struct stmt_block *stmt_block = stmt_stack; | ||||||
| 
 | 
 | ||||||
|  | @ -726,7 +720,7 @@ code_break() | ||||||
| 	innermost statement in which continue has a meaning. | 	innermost statement in which continue has a meaning. | ||||||
| */ | */ | ||||||
| void | void | ||||||
| code_continue() | code_continue(void) | ||||||
| { | { | ||||||
| 	register struct stmt_block *stmt_block = stmt_stack; | 	register struct stmt_block *stmt_block = stmt_stack; | ||||||
| 
 | 
 | ||||||
|  | @ -743,8 +737,7 @@ code_continue() | ||||||
| 	error("continue not inside for, while or do"); | 	error("continue not inside for, while or do"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| stack_stmt(break_label, cont_label) | void stack_stmt(label break_label, label cont_label) | ||||||
| 	label break_label, cont_label; |  | ||||||
| { | { | ||||||
| 	register struct stmt_block *stmt_block = new_stmt_block(); | 	register struct stmt_block *stmt_block = new_stmt_block(); | ||||||
| 
 | 
 | ||||||
|  | @ -754,7 +747,7 @@ stack_stmt(break_label, cont_label) | ||||||
| 	stmt_stack = stmt_block; | 	stmt_stack = stmt_block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unstack_stmt() | void unstack_stmt(void) | ||||||
| { | { | ||||||
| 	/*	unstack_stmt() unstacks the data of a statement
 | 	/*	unstack_stmt() unstacks the data of a statement
 | ||||||
| 		which may contain break or continue | 		which may contain break or continue | ||||||
|  | @ -766,8 +759,7 @@ unstack_stmt() | ||||||
| 
 | 
 | ||||||
| static label prc_name; | static label prc_name; | ||||||
| 
 | 
 | ||||||
| prc_entry(name) | void prc_entry(char* name) | ||||||
| 	char *name; |  | ||||||
| { | { | ||||||
| 	if (options['p']) { | 	if (options['p']) { | ||||||
| 		C_df_dlb(prc_name = data_label()); | 		C_df_dlb(prc_name = data_label()); | ||||||
|  | @ -778,7 +770,7 @@ prc_entry(name) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| prc_exit() | void prc_exit(void) | ||||||
| { | { | ||||||
| 	if (options['p']) { | 	if (options['p']) { | ||||||
| 		C_lae_dlb(prc_name, (arith) 0); | 		C_lae_dlb(prc_name, (arith) 0); | ||||||
|  | @ -788,9 +780,7 @@ prc_exit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef DBSYMTAB | #ifdef DBSYMTAB | ||||||
| db_line(file, line) | void db_line(char *file, unsigned int line) | ||||||
| 	char		*file; |  | ||||||
| 	unsigned int	line; |  | ||||||
| { | { | ||||||
| 	static unsigned oldline; | 	static unsigned oldline; | ||||||
| 	static char	*oldfile; | 	static char	*oldfile; | ||||||
|  |  | ||||||
|  | @ -2,9 +2,15 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef CODE_H_ | ||||||
|  | #define CODE_H_ | ||||||
| /* $Id$ */ | /* $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	*/ | /*	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	{	/* storing string constants */ | ||||||
| 	struct string_cst *next; | 	struct string_cst *next; | ||||||
| 	char *sc_value; | 	char *sc_value; | ||||||
|  | @ -20,3 +26,44 @@ extern struct string_cst *str_list; | ||||||
| #define	RVAL	1 | #define	RVAL	1 | ||||||
| #define	FALSE	0 | #define	FALSE	0 | ||||||
| #define	TRUE	1 | #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" | #include	"parameters.h" | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
| 
 | 
 | ||||||
|  | #include    "conversion.h" | ||||||
| #include	<em.h> | #include	<em.h> | ||||||
|  | #include    "interface.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | #include    "error.h" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #define	T_SIGNED		1 | #define	T_SIGNED		1 | ||||||
| #define	T_UNSIGNED		2 | #define	T_UNSIGNED		2 | ||||||
|  | @ -27,10 +31,9 @@ | ||||||
| 		C?? | 		C?? | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| static int convtype(); | static int convtype(register struct type *); | ||||||
| 
 | 
 | ||||||
| conversion(from_type, to_type) | void conversion(register struct type *from_type, register struct type *to_type) | ||||||
| 	register struct type *from_type, *to_type; |  | ||||||
| { | { | ||||||
| 	register arith from_size = from_type->tp_size; | 	register arith from_size = from_type->tp_size; | ||||||
| 	register arith to_size = to_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:
 | /*	convtype() returns in which category a given type falls:
 | ||||||
| 	signed, unsigned or floating | 	signed, unsigned or floating | ||||||
| */ | */ | ||||||
| static int | static int convtype(register struct type *tp) | ||||||
| convtype(tp) |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	switch (tp->tp_fund)	{ | 	switch (tp->tp_fund)	{ | ||||||
| 	case CHAR: | 	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		*/ | /*	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	<assert.h> | ||||||
|  | #include    "cstoper.h" | ||||||
| #include    "parameters.h" | #include    "parameters.h" | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
|  | @ -14,6 +15,7 @@ | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| /* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */ | /* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */ | ||||||
| arith full_mask[MAXSIZE + 1]; | arith full_mask[MAXSIZE + 1]; | ||||||
|  | @ -23,8 +25,7 @@ arith max_unsigned;	/* maximum unsigned on target machine	*/ | ||||||
| #endif /* NOCROSS */ | #endif /* NOCROSS */ | ||||||
| extern int ResultKnown; | extern int ResultKnown; | ||||||
| 
 | 
 | ||||||
| cstbin(expp, oper, expr) | void cstbin(register struct expr **expp, int oper, register struct expr *expr) | ||||||
| 	register struct expr **expp, *expr; |  | ||||||
| { | { | ||||||
| 	/*	The operation oper is performed on the constant
 | 	/*	The operation oper is performed on the constant
 | ||||||
| 		expressions *expp(ld) and expr(ct), and the result restored in | 		expressions *expp(ld) and expr(ct), and the result restored in | ||||||
|  | @ -134,8 +135,7 @@ cstbin(expp, oper, expr) | ||||||
| 	free_expression(expr); | 	free_expression(expr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| cut_size(expr) | void cut_size(register struct expr *expr) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	The constant value of the expression expr is made to
 | 	/*	The constant value of the expression expr is made to
 | ||||||
| 		conform to the size of the type of the expression. | 		conform to the size of the type of the expression. | ||||||
|  | @ -170,7 +170,7 @@ cut_size(expr) | ||||||
| 	expr->VL_VALUE = o1; | 	expr->VL_VALUE = o1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| init_cst() | void init_cst(void) | ||||||
| { | { | ||||||
| 	register int i = 0; | 	register int i = 0; | ||||||
| 	register arith bt = (arith)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	"parameters.h"	/* UF */ | ||||||
|  | #include    "dataflow.h" | ||||||
|  | #include    "print.h" | ||||||
| 
 | 
 | ||||||
| #ifdef	DATAFLOW | #ifdef	DATAFLOW | ||||||
| char *CurrentFunction = 0; | char *CurrentFunction = 0; | ||||||
| int NumberOfCalls; | int NumberOfCalls; | ||||||
| 
 | 
 | ||||||
| DfaStartFunction(nm) | void DfaStartFunction(char* nm) | ||||||
| 	char *nm; |  | ||||||
| { | { | ||||||
| 	CurrentFunction = nm; | 	CurrentFunction = nm; | ||||||
| 	NumberOfCalls = 0; | 	NumberOfCalls = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DfaEndFunction() | void DfaEndFunction(void) | ||||||
| { | { | ||||||
| 	if (NumberOfCalls == 0) | 	if (NumberOfCalls == 0) | ||||||
| 		print("DFA: %s: --none--\n", CurrentFunction); | 		print("DFA: %s: --none--\n", CurrentFunction); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DfaCallFunction(s) | void DfaCallFunction(char* s) | ||||||
| 	char *s; |  | ||||||
| { | { | ||||||
| 	print("DFA: %s: %s\n", CurrentFunction, s); | 	print("DFA: %s: %s\n", CurrentFunction, s); | ||||||
| 	++NumberOfCalls; | 	++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_ */ | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -2,6 +2,9 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  |  #ifndef DECLAR_H_ | ||||||
|  |  #define DECLAR_H_ | ||||||
|  |   | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* DEFINITION OF DECLARATOR DESCRIPTORS */ | /* DEFINITION OF DECLARATOR DESCRIPTORS */ | ||||||
| 
 | 
 | ||||||
|  | @ -39,3 +42,5 @@ struct decl_unary	{ | ||||||
| 
 | 
 | ||||||
| extern struct type *declare_type(); | extern struct type *declare_type(); | ||||||
| extern struct declarator null_declarator; | 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		*/ | /*	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	"parameters.h" | ||||||
|  | #include    "declarator.h" | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
|  | @ -14,18 +15,20 @@ | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"declar.h" | #include	"declar.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
|  | #include    "idf.h" | ||||||
| #include	"label.h" | #include	"label.h" | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| struct declarator null_declarator; | struct declarator null_declarator; | ||||||
| 
 | 
 | ||||||
| struct type * | struct type * | ||||||
| declare_type(tp, dc) | declare_type( | ||||||
| 	struct type *tp; | 	struct type *tp, | ||||||
| 	struct declarator *dc; | 	struct declarator *dc) | ||||||
| { | { | ||||||
| 	/*	Applies the decl_unary list starting at dc->dc_decl_unary
 | 	/*	Applies the decl_unary list starting at dc->dc_decl_unary
 | ||||||
| 		to the type tp and returns the result. | 		to the type tp and returns the result. | ||||||
|  | @ -43,12 +46,7 @@ declare_type(tp, dc) | ||||||
| 	return tp; | 	return tp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| add_decl_unary(dc, fund, qual,  count, fm, pl) | void add_decl_unary(register struct declarator *dc, int fund, int qual,  arith count, struct formal *fm, struct proto *pl) | ||||||
| 	register struct declarator *dc; |  | ||||||
| 	int qual; |  | ||||||
| 	arith count; |  | ||||||
| 	struct formal *fm; |  | ||||||
| 	struct proto *pl; |  | ||||||
| { | { | ||||||
| 	/*	A decl_unary describing a constructor with fundamental
 | 	/*	A decl_unary describing a constructor with fundamental
 | ||||||
| 		type fund and with size count is inserted in front of the | 		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; | 	dc->dc_decl_unary = new; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| remove_declarator(dc) | void remove_declarator(struct declarator *dc) | ||||||
| 	struct declarator *dc; |  | ||||||
| { | { | ||||||
| 	/*	The decl_unary list starting at dc->dc_decl_unary is
 | 	/*	The decl_unary list starting at dc->dc_decl_unary is
 | ||||||
| 		removed. | 		removed. | ||||||
|  | @ -91,8 +88,7 @@ remove_declarator(dc) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| reject_params(dc) | void reject_params(register struct declarator *dc) | ||||||
| 	register struct declarator *dc; |  | ||||||
| { | { | ||||||
| 	/*	The declarator is checked to have no parameters, if it
 | 	/*	The declarator is checked to have no parameters, if it
 | ||||||
| 		is an old-style function.  If it is a new-style function, | 		is an old-style function.  If it is a new-style function, | ||||||
|  | @ -120,8 +116,7 @@ reject_params(dc) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| check_array_subscript(expr) | void check_array_subscript(register struct expr *expr) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	arith size = expr->VL_VALUE; | 	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	*/ | /*	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	<assert.h> | ||||||
| #include	"Lpars.h" |  | ||||||
| #include	"decspecs.h" | #include	"decspecs.h" | ||||||
|  | #include	"Lpars.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| extern int level; | extern int level; | ||||||
|  | @ -20,36 +21,35 @@ extern struct type *qualifier_type(); | ||||||
| 
 | 
 | ||||||
| struct decspecs null_decspecs; | struct decspecs null_decspecs; | ||||||
| 
 | 
 | ||||||
| do_decspecs(ds) | void do_decspecs(register struct decspecs *ds) | ||||||
| 	register struct decspecs *ds; |  | ||||||
| { | { | ||||||
| 	/*	The provisional decspecs ds as obtained from the program
 | 	/*	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; | 	register struct type *tp = ds->ds_type; | ||||||
| 	 | 
 | ||||||
| 	assert(level != L_FORMAL1); | 	assert(level != L_FORMAL1); | ||||||
| 	 | 
 | ||||||
| 	if (	level == L_GLOBAL && | 	if (level == L_GLOBAL && (ds->ds_sc == AUTO || ds->ds_sc == REGISTER)) | ||||||
| 		(ds->ds_sc == AUTO || ds->ds_sc == REGISTER) | 	{ | ||||||
| 	)	{ | 		error("no global %s variable allowed", symbol2str(ds->ds_sc)); | ||||||
| 		error("no global %s variable allowed", |  | ||||||
| 			symbol2str(ds->ds_sc)); |  | ||||||
| 		ds->ds_sc = GLOBAL; | 		ds->ds_sc = GLOBAL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (level == L_FORMAL2)	{ | 	if (level == L_FORMAL2) | ||||||
| 		if (ds->ds_sc_given && | 	{ | ||||||
| 		    ds->ds_sc != REGISTER){ | 		if (ds->ds_sc_given && ds->ds_sc != REGISTER) | ||||||
|  | 		{ | ||||||
| 			error("%s formal illegal", symbol2str(ds->ds_sc)); | 			error("%s formal illegal", symbol2str(ds->ds_sc)); | ||||||
| 			ds->ds_sc = FORMAL; | 			ds->ds_sc = FORMAL; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*	Since type qualifiers may be associated with types by means
 | 	/*	Since type qualifiers may be associated with types by means
 | ||||||
| 		of typedefs, we have to perform same basic tests down here. | 	 of typedefs, we have to perform same basic tests down here. | ||||||
| 	*/ | 	 */ | ||||||
| 	if (tp != (struct type *)0) { | 	if (tp != (struct type *) 0) | ||||||
|  | 	{ | ||||||
| 		if ((ds->ds_typequal & TQ_VOLATILE) && (tp->tp_typequal & TQ_VOLATILE)) | 		if ((ds->ds_typequal & TQ_VOLATILE) && (tp->tp_typequal & TQ_VOLATILE)) | ||||||
| 			error("indirect repeated type qualifier"); | 			error("indirect repeated type qualifier"); | ||||||
| 		if ((ds->ds_typequal & TQ_CONST) && (tp->tp_typequal & TQ_CONST)) | 		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
 | 	/*	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. */ | 	/* some adjustments as described in 3.5.2. */ | ||||||
| 	if (tp == 0) { | 	if (tp == 0) | ||||||
|  | 	{ | ||||||
| 		ds->ds_notypegiven = 1; | 		ds->ds_notypegiven = 1; | ||||||
| 		tp = int_type; | 		tp = int_type; | ||||||
| 	} | 	} | ||||||
| 	if (ds->ds_size) { | 	if (ds->ds_size) | ||||||
|  | 	{ | ||||||
| 		register int ds_isshort = (ds->ds_size == SHORT); | 		register int ds_isshort = (ds->ds_size == SHORT); | ||||||
| 
 | 
 | ||||||
| 		if (ds->ds_typedef) goto SIZE_ERROR;		/* yes */ | 		if (ds->ds_typedef) | ||||||
| 		if (tp == int_type) { | 			goto SIZE_ERROR; | ||||||
| 			if (ds_isshort) tp = short_type; | 		/* yes */ | ||||||
| 			else tp = long_type; | 		if (tp == int_type) | ||||||
| 		} else if (tp == double_type && !ds_isshort ) { | 		{ | ||||||
|  | 			if (ds_isshort) | ||||||
|  | 				tp = short_type; | ||||||
|  | 			else | ||||||
|  | 				tp = long_type; | ||||||
|  | 		} | ||||||
|  | 		else if (tp == double_type && !ds_isshort) | ||||||
|  | 		{ | ||||||
| 			tp = lngdbl_type; | 			tp = lngdbl_type; | ||||||
| 		} else { | 		} | ||||||
| 	SIZE_ERROR: | 		else | ||||||
| 			error("%s with illegal type",symbol2str(ds->ds_size)); | 		{ | ||||||
|  | 			SIZE_ERROR: error("%s with illegal type", symbol2str(ds->ds_size)); | ||||||
| 		} | 		} | ||||||
| 		ds->ds_notypegiven = 0; | 		ds->ds_notypegiven = 0; | ||||||
| 	} | 	} | ||||||
| 	if (ds->ds_unsigned) { | 	if (ds->ds_unsigned) | ||||||
|  | 	{ | ||||||
| 		register int ds_isunsigned = (ds->ds_unsigned == 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), | 		 * All integral types are signed by default (char too), | ||||||
| 		 * so the case that ds->ds_unsigned == SIGNED can be ignored. | 		 * so the case that ds->ds_unsigned == SIGNED can be ignored. | ||||||
| 		 */ | 		 */ | ||||||
| 		if (tp == schar_type) { | 		if (tp == schar_type) | ||||||
| 			if (ds_isunsigned) tp = uchar_type; | 		{ | ||||||
| 		} else if (tp == short_type) { | 			if (ds_isunsigned) | ||||||
| 			if (ds_isunsigned) tp = ushort_type; | 				tp = uchar_type; | ||||||
| 		} else if (tp == int_type) { | 		} | ||||||
| 			if (ds_isunsigned) tp = uint_type; | 		else if (tp == short_type) | ||||||
| 		} else if (tp == long_type) { | 		{ | ||||||
| 			if (ds_isunsigned) tp = ulong_type; | 			if (ds_isunsigned) | ||||||
| 		} else { | 				tp = ushort_type; | ||||||
| 	SIGN_ERROR: | 		} | ||||||
| 			error("%s with illegal type" | 		else if (tp == int_type) | ||||||
| 				, symbol2str(ds->ds_unsigned)); | 		{ | ||||||
|  | 			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; | 		ds->ds_notypegiven = 0; | ||||||
| 	} | 	} | ||||||
|  | @ -108,15 +133,12 @@ do_decspecs(ds) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*	Make tp into a qualified type. This is not as trivial as it
 | /*	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 |  may seem. If tp is a fundamental type the qualified type is | ||||||
| 	either existent or will be generated. |  either existent or will be generated. | ||||||
| 	In case of a complex type the top of the type list will be |  In case of a complex type the top of the type list will be | ||||||
| 	replaced by a qualified version. |  replaced by a qualified version. | ||||||
| */ |  */ | ||||||
| struct type * | struct type *qualifier_type(register struct type *tp, int typequal) | ||||||
| qualifier_type(tp, typequal) |  | ||||||
| 	register struct type *tp; |  | ||||||
| 	int typequal; |  | ||||||
| { | { | ||||||
| 	register struct type *dtp = tp; | 	register struct type *dtp = tp; | ||||||
| 	register int fund = tp->tp_fund; | 	register int fund = tp->tp_fund; | ||||||
|  | @ -124,32 +146,34 @@ qualifier_type(tp, typequal) | ||||||
| 	while (dtp && dtp->tp_typequal != typequal) | 	while (dtp && dtp->tp_typequal != typequal) | ||||||
| 		dtp = dtp->next; | 		dtp = dtp->next; | ||||||
| 
 | 
 | ||||||
| 	if (!dtp) { | 	if (!dtp) | ||||||
|  | 	{ | ||||||
| 		dtp = create_type(fund); | 		dtp = create_type(fund); | ||||||
| 		dtp->tp_unsigned = tp->tp_unsigned; | 		dtp->tp_unsigned = tp->tp_unsigned; | ||||||
| 		dtp->tp_align = tp->tp_align; | 		dtp->tp_align = tp->tp_align; | ||||||
| 		dtp->tp_typequal = typequal; | 		dtp->tp_typequal = typequal; | ||||||
| 		dtp->tp_size = tp->tp_size; | 		dtp->tp_size = tp->tp_size; | ||||||
| #if 0 | #if 0 | ||||||
| /* The tp_function field does not exist now. See the comment in the
 | 		/* The tp_function field does not exist now. See the comment in the
 | ||||||
|    function_of() routine. | 		 function_of() routine. | ||||||
| */ | 		 */ | ||||||
| 		dtp->tp_function = tp->tp_function; | 		dtp->tp_function = tp->tp_function; | ||||||
| #endif | #endif | ||||||
| 		switch (fund) { | 		switch (fund) | ||||||
|  | 		{ | ||||||
| 		case ARRAY: | 		case ARRAY: | ||||||
| 			if (typequal) { | 			if (typequal) | ||||||
| 			    tp->tp_up = qualifier_type(tp->tp_up, typequal); | 			{ | ||||||
| 			    dtp->tp_typequal = typequal = 0; | 				tp->tp_up = qualifier_type(tp->tp_up, typequal); | ||||||
|  | 				dtp->tp_typequal = typequal = 0; | ||||||
| 			} | 			} | ||||||
| 			goto nottagged; | 			goto nottagged; | ||||||
| 		case FIELD: | 		case FIELD: | ||||||
| 			dtp->tp_field = tp->tp_field; | 			dtp->tp_field = tp->tp_field; | ||||||
| 			/* fallthrough */ | 			/* fallthrough */ | ||||||
| 		case POINTER: | 		case POINTER: | ||||||
| 		case FUNCTION:			/* dont't assign tp_proto */ | 		case FUNCTION: /* dont't assign tp_proto */ | ||||||
| 		nottagged: | 			nottagged: dtp->tp_up = tp->tp_up; | ||||||
| 			dtp->tp_up = tp->tp_up; |  | ||||||
| 			break; | 			break; | ||||||
| 		case STRUCT: | 		case STRUCT: | ||||||
| 		case UNION: | 		case UNION: | ||||||
|  | @ -163,6 +187,6 @@ qualifier_type(tp, typequal) | ||||||
| 		dtp->next = tp->next; /* don't know head or tail */ | 		dtp->next = tp->next; /* don't know head or tail */ | ||||||
| 		tp->next = dtp; | 		tp->next = dtp; | ||||||
| 	} | 	} | ||||||
| 	return(dtp); | 	return (dtp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef DECSPECS_H_ | ||||||
|  | #define DECSPECS_H_ | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* DECLARATION SPECIFIER DEFINITION */ | /* DECLARATION SPECIFIER DEFINITION */ | ||||||
| 
 | 
 | ||||||
|  | @ -19,3 +22,10 @@ struct decspecs	{ | ||||||
| 
 | 
 | ||||||
| extern struct type *qualifier_type(); | extern struct type *qualifier_type(); | ||||||
| extern struct decspecs null_decspecs; | 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. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef DEF_H_ | ||||||
|  | #define DEF_H_ | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* IDENTIFIER DEFINITION DESCRIPTOR */ | /* IDENTIFIER DEFINITION DESCRIPTOR */ | ||||||
| 
 | 
 | ||||||
|  | @ -38,3 +41,5 @@ struct def	{		/* for ordinary tags */ | ||||||
| #define REG_BONUS	10	/* register candidate, declared as such */ | #define REG_BONUS	10	/* register candidate, declared as such */ | ||||||
| 
 | 
 | ||||||
| /* ALLOCDEF "def" 50 */ | /* ALLOCDEF "def" 50 */ | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | @ -8,12 +8,17 @@ | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include "domacro.h" | ||||||
| #include "parameters.h" | #include "parameters.h" | ||||||
| #include "idf.h" | #include "idf.h" | ||||||
|  | #include "interface.h" | ||||||
| #include "arith.h" | #include "arith.h" | ||||||
| #include "LLlex.h" | #include "LLlex.h" | ||||||
| #include "Lpars.h" | #include "Lpars.h" | ||||||
| #include "input.h" | #include "input.h" | ||||||
|  | #include "pragma.h" | ||||||
|  | #include "skip.h" | ||||||
|  | #include "error.h" | ||||||
| 
 | 
 | ||||||
| #ifdef DBSYMTAB | #ifdef DBSYMTAB | ||||||
| #include <stb.h> | #include <stb.h> | ||||||
|  | @ -23,7 +28,9 @@ int IncludeLevel = 0; | ||||||
| 
 | 
 | ||||||
| extern char options[]; | 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
 | 	/*	returns a pointer to the descriptor of the identifier that is
 | ||||||
| 	    read from the input stream. When the input does not contain | 	    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; | 	return tk.tk_idf; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| domacro() | void domacro(void) | ||||||
| { | { | ||||||
| 	int tok; | 	int tok; | ||||||
| 	struct token tk; | 	struct token tk; | ||||||
|  | @ -70,7 +77,7 @@ domacro() | ||||||
| 	SkipToNewLine(); | 	SkipToNewLine(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_line(l) unsigned int l; | static void do_line(unsigned int l) | ||||||
| { | { | ||||||
| 	struct token tk; | 	struct token tk; | ||||||
| 	int t = GetToken(&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	*/ | /*	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	"parameters.h" | ||||||
|  | #include    "error.h" | ||||||
| #if __STDC__ | #if __STDC__ | ||||||
| #include	<stdarg.h> | #include	<stdarg.h> | ||||||
| #else | #else | ||||||
|  | @ -17,13 +18,15 @@ | ||||||
| #else | #else | ||||||
| #include	"l_em.h" | #include	"l_em.h" | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 
 | #include    <stdio.h> | ||||||
| #include	"tokenname.h" | #include	"tokenname.h" | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
|  | #include    "interface.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"label.h" | #include	"label.h" | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
|  | #include    "print.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| 
 | 
 | ||||||
| /*	This file contains the error-message and diagnostic
 | /*	This file contains the error-message and diagnostic
 | ||||||
|  | @ -56,12 +59,11 @@ extern char loptions[]; | ||||||
| 	FileName, expression errors get their information from the | 	FileName, expression errors get their information from the | ||||||
| 	expression, whereas other errors use the information in the token. | 	expression, whereas other errors use the information in the token. | ||||||
| */ | */ | ||||||
| 
 | static void _error(int, char *, unsigned int, char*, va_list); | ||||||
| static void _error(); |  | ||||||
| 
 | 
 | ||||||
| #if __STDC__ | #if __STDC__ | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| error(char *fmt, ...) | void error(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -73,7 +75,7 @@ error(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| expr_error(struct expr *expr, char *fmt, ...) | void expr_error(struct expr *expr, char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -89,7 +91,7 @@ expr_error(struct expr *expr, char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| lexstrict(char *fmt, ...) | void lexstrict(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -101,7 +103,7 @@ lexstrict(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| strict(char *fmt, ...) | void strict(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -113,7 +115,7 @@ strict(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| expr_strict(struct expr *expr, char *fmt, ...) | void expr_strict(struct expr *expr, char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -129,7 +131,7 @@ expr_strict(struct expr *expr, char *fmt, ...) | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| debug(char *fmt, ...) | void debug(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -142,7 +144,7 @@ debug(char *fmt, ...) | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| warning(char *fmt, ...) | void warning(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -154,7 +156,7 @@ warning(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| expr_warning(struct expr *expr, char *fmt, ...) | void expr_warning(struct expr *expr, char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -171,7 +173,7 @@ expr_warning(struct expr *expr, char *fmt, ...) | ||||||
| #ifdef	LINT | #ifdef	LINT | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| def_warning(struct def *def, char *fmt, ...) | void def_warning(struct def *def, char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -184,7 +186,7 @@ def_warning(struct def *def, char *fmt, ...) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| hwarning(char *fmt, ...) | void hwarning(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -197,7 +199,7 @@ hwarning(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| awarning(char *fmt, ...) | void awarning(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -212,7 +214,7 @@ awarning(char *fmt, ...) | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| lexerror(char *fmt, ...) | void lexerror(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -224,7 +226,7 @@ lexerror(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| lexwarning(char *fmt, ...) | void lexwarning(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -236,7 +238,7 @@ lexwarning(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| crash(char *fmt, ...) | void crash(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -256,7 +258,7 @@ crash(char *fmt, ...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| fatal(char *fmt, ...) | void fatal(char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 
 | 
 | ||||||
|  | @ -272,7 +274,7 @@ fatal(char *fmt, ...) | ||||||
| } | } | ||||||
| #else | #else | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| error(va_alist)				/* fmt, args */ | void error(va_alist)				/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -286,7 +288,7 @@ error(va_alist)				/* fmt, args */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| expr_error(va_alist)			/* expr, fmt, args */ | void expr_error(va_alist)			/* expr, fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -306,7 +308,7 @@ expr_error(va_alist)			/* expr, fmt, args */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| lexstrict(va_alist) | void lexstrict(va_alist) | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -320,7 +322,7 @@ lexstrict(va_alist) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| strict(va_alist) | void strict(va_alist) | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -334,7 +336,7 @@ strict(va_alist) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| expr_strict(va_alist)			/* expr, fmt, args */ | void expr_strict(va_alist)			/* expr, fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -354,7 +356,7 @@ expr_strict(va_alist)			/* expr, fmt, args */ | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| debug(va_alist) | void debug(va_alist) | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -369,7 +371,7 @@ debug(va_alist) | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| warning(va_alist) | void warning(va_alist) | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -383,7 +385,7 @@ warning(va_alist) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| expr_warning(va_alist)			/* expr, fmt, args */ | void expr_warning(va_alist)			/* expr, fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -404,7 +406,7 @@ expr_warning(va_alist)			/* expr, fmt, args */ | ||||||
| #ifdef	LINT | #ifdef	LINT | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| def_warning(va_alist)			/* def, fmt, args */ | void def_warning(va_alist)			/* def, fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -421,7 +423,7 @@ def_warning(va_alist)			/* def, fmt, args */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| hwarning(va_alist)			/* fmt, args */ | void hwarning(va_alist)			/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -436,7 +438,7 @@ hwarning(va_alist)			/* fmt, args */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| awarning(va_alist)			/* fmt, args */ | void awarning(va_alist)			/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -453,7 +455,7 @@ awarning(va_alist)			/* fmt, args */ | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| lexerror(va_alist)			/* fmt, args */ | void lexerror(va_alist)			/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -467,7 +469,7 @@ lexerror(va_alist)			/* fmt, args */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| lexwarning(va_alist)			/* fmt, args */ | void lexwarning(va_alist)			/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -481,7 +483,7 @@ lexwarning(va_alist)			/* fmt, args */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| crash(va_alist)				/* fmt, args */ | void crash(va_alist)				/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -503,7 +505,7 @@ crash(va_alist)				/* fmt, args */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*VARARGS*/ | /*VARARGS*/ | ||||||
| fatal(va_alist)				/* fmt, args */ | void fatal(va_alist)				/* fmt, args */ | ||||||
| 	va_dcl | 	va_dcl | ||||||
| { | { | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | @ -521,13 +523,7 @@ fatal(va_alist)				/* fmt, args */ | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| static void | static void _error(int class, char *fn, unsigned int ln, char* fmt, va_list ap) | ||||||
| _error(class, fn, ln, fmt, ap) |  | ||||||
| 	int class; |  | ||||||
| 	char *fn; |  | ||||||
| 	unsigned int ln; |  | ||||||
| 	char *fmt; |  | ||||||
| 	va_list ap; |  | ||||||
| { | { | ||||||
| 	char *remark; | 	char *remark; | ||||||
| 	 | 	 | ||||||
|  | @ -614,9 +610,9 @@ _error(class, fn, ln, fmt, ap) | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 	 | 	 | ||||||
| 	if (fn) | 	if (fn) | ||||||
| 		fprint(ERROUT, "\"%s\", line %u: ", fn, ln); | 		fprint(stderr, "\"%s\", line %u: ", fn, ln); | ||||||
| 	if (remark) | 	if (remark) | ||||||
| 		fprint(ERROUT, "%s ", remark); | 		fprint(stderr, "%s ", remark); | ||||||
| 	doprnt(ERROUT, fmt, ap);		/* contents of error */ | 	doprnt(stderr, fmt, ap);		/* contents of error */ | ||||||
| 	fprint(ERROUT, "\n"); | 	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. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  |  #ifndef ESTACK_H_ | ||||||
|  |  #define ESTACK_H_ | ||||||
|  |   | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* EXPRESSION STACK */ | /* EXPRESSION STACK */ | ||||||
| /* Used for global initializations */ | /* Used for global initializations */ | ||||||
|  | @ -19,3 +22,5 @@ struct e_stack { | ||||||
| #define last_offset	s_cnt2 | #define last_offset	s_cnt2 | ||||||
| #define elem_count	s_cnt1 | #define elem_count	s_cnt1 | ||||||
| #define nelem		s_cnt2 | #define nelem		s_cnt2 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -14,6 +14,8 @@ | ||||||
| #include	<em_reg.h> | #include	<em_reg.h> | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
|  | #include    "interface.h" | ||||||
|  | #include    "eval.h" | ||||||
| #include    "idf.h" | #include    "idf.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
|  | @ -22,13 +24,21 @@ | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
|  | #include    "field.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
|  | #include    "conversion.h" | ||||||
| #include	"stack.h" | #include	"stack.h" | ||||||
|  | #include    "struct.h" | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
| #include	"mes.h" | #include	"mes.h" | ||||||
| #include	"atw.h" | #include	"atw.h" | ||||||
|  | #include    "ch3.h" | ||||||
|  | #include    "util.h" | ||||||
|  | #include    "blocks.h" | ||||||
|  | #include    "dataflow.h" | ||||||
| #include	"specials.h" | #include	"specials.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| #define	CRASH()		crash("EVAL: CRASH at line %u", __LINE__) | #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) | #define LocalPtrVar()	NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER) | ||||||
| extern int	err_occurred; /* error.c */ | 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
 | /*	EVAL() is the main expression-tree evaluator, which turns
 | ||||||
| 	any legal expression tree into EM code. parameters.h: | 	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) | 		labels, in case they are specified (i.e. are non-zero) | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| void | void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label) | ||||||
| EVAL(expr, val, code, true_label, false_label) |  | ||||||
| 	register struct expr *expr; |  | ||||||
| 	int val, code; |  | ||||||
| 	label true_label, false_label; |  | ||||||
| { | { | ||||||
| 	int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE)); | 	int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE)); | ||||||
| 	register int gencode = code == TRUE; | 	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() serves as an auxiliary function of EVAL	*/ | ||||||
| compare(relop, lbl) | static void compare(int relop, label lbl) | ||||||
| 	int relop; |  | ||||||
| 	label lbl; |  | ||||||
| { | { | ||||||
| 	switch (relop) { | 	switch (relop) { | ||||||
| 	case '<': | 	case '<': | ||||||
|  | @ -688,8 +696,7 @@ compare(relop, lbl) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*	truthvalue() serves as an auxiliary function of EVAL	*/ | /*	truthvalue() serves as an auxiliary function of EVAL	*/ | ||||||
| truthvalue(relop) | static void truthvalue(int relop) | ||||||
| 	int relop; |  | ||||||
| { | { | ||||||
| 	switch (relop)	{ | 	switch (relop)	{ | ||||||
| 	case '<': | 	case '<': | ||||||
|  | @ -717,12 +724,10 @@ truthvalue(relop) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*	assop() generates the opcode of an assignment operators op=	*/ | /*	assop() generates the opcode of an assignment operators op=	*/ | ||||||
| assop(type, oper) | void assop(register struct type *type, int oper) | ||||||
| 	register struct type *type; |  | ||||||
| 	int oper; |  | ||||||
| { | { | ||||||
| 	register arith size; | 	register arith size; | ||||||
| 	register uns = type->tp_unsigned; | 	register int uns = type->tp_unsigned; | ||||||
| 
 | 
 | ||||||
| 	if ((int)(size = type->tp_size) < (int)word_size) | 	if ((int)(size = type->tp_size) < (int)word_size) | ||||||
| 		size = word_size; | 		size = word_size; | ||||||
|  | @ -822,8 +827,7 @@ assop(type, oper) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ptr_add(size) | static void ptr_add(arith size) | ||||||
| 	arith size; |  | ||||||
| { | { | ||||||
| 	if (size != pointer_size) { | 	if (size != pointer_size) { | ||||||
| 		C_loc(size); | 		C_loc(size); | ||||||
|  | @ -840,10 +844,7 @@ ptr_add(size) | ||||||
| 	- into a local static variable | 	- into a local static variable | ||||||
| 	- absolute addressing | 	- absolute addressing | ||||||
| */ | */ | ||||||
| void | void store_val(register struct value *vl, register struct type *tp) | ||||||
| store_val(vl, tp) |  | ||||||
| 	register struct value *vl; |  | ||||||
| 	register struct type *tp; |  | ||||||
| { | { | ||||||
| 	register int inword = 0; | 	register int inword = 0; | ||||||
| 	register int indword = 0; | 	register int indword = 0; | ||||||
|  | @ -911,11 +912,10 @@ store_val(vl, tp) | ||||||
| 	- global variable | 	- global variable | ||||||
| 	- static variable | 	- static variable | ||||||
| 	- local variable | 	- local variable | ||||||
|  | 
 | ||||||
|  | 	rlval generate rlval or lval | ||||||
| */ | */ | ||||||
| void | void load_val(register struct expr *expr, int rlval) | ||||||
| load_val(expr, rlval) |  | ||||||
| 	register struct expr *expr; /* expression containing the value	*/ |  | ||||||
| 	int rlval;		/* generate either LVAL or RVAL		*/ |  | ||||||
| { | { | ||||||
| 	register struct type *tp = expr->ex_type; | 	register struct type *tp = expr->ex_type; | ||||||
| 	int rvalue = (rlval == RVAL && expr->ex_lvalue != 0); | 	int rvalue = (rlval == RVAL && expr->ex_lvalue != 0); | ||||||
|  | @ -1012,8 +1012,7 @@ load_val(expr, rlval) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| load_cst(val, siz) | void load_cst(arith val, arith siz) | ||||||
| 	arith val, siz; |  | ||||||
| { | { | ||||||
| 	if ((int)siz <= (int)word_size) | 	if ((int)siz <= (int)word_size) | ||||||
| 		C_loc(val); | 		C_loc(val); | ||||||
|  | @ -1030,8 +1029,7 @@ load_cst(val, siz) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| operands(expr, gencode) | static void operands(register struct expr *expr, int gencode) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL); | 	EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL); | ||||||
| 	EVAL(expr->OP_RIGHT, 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	"parameters.h" | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
|  | #include    "expr.h" | ||||||
| #include    "idf.h" | #include    "idf.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
|  | @ -22,20 +23,21 @@ | ||||||
| #include	"declar.h" | #include	"declar.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
|  | #include    "cstoper.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| extern char options[]; | extern char options[]; | ||||||
| extern int InSizeof; | extern int InSizeof; | ||||||
| 
 | 
 | ||||||
| int | int rank_of(int oper) | ||||||
| rank_of(oper) |  | ||||||
| 	int oper; |  | ||||||
| { | { | ||||||
| 	/*	The rank of the operator oper is returned.
 | 	/*	The rank of the operator oper is returned.
 | ||||||
| 	*/ | 	 */ | ||||||
| 	switch (oper)	{ | 	switch (oper) | ||||||
|  | 	{ | ||||||
| 	default: | 	default: | ||||||
| 		return 0;			/* INT2INT etc. */ | 		return 0; /* INT2INT etc. */ | ||||||
| 	case '[': | 	case '[': | ||||||
| 	case '(': | 	case '(': | ||||||
| 	case '.': | 	case '.': | ||||||
|  | @ -48,7 +50,7 @@ rank_of(oper) | ||||||
| 	case CAST: | 	case CAST: | ||||||
| 	case SIZEOF: | 	case SIZEOF: | ||||||
| 	case ADDRESSOF: | 	case ADDRESSOF: | ||||||
| 		return 2;			/* monadic */ | 		return 2; /* monadic */ | ||||||
| 	case '*': | 	case '*': | ||||||
| 	case '/': | 	case '/': | ||||||
| 	case '%': | 	case '%': | ||||||
|  | @ -98,18 +100,18 @@ rank_of(oper) | ||||||
| 	/*NOTREACHED*/ | 	/*NOTREACHED*/ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| dot2expr(expp) | void dot2expr(struct expr **expp) | ||||||
| 	struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	The token in dot is converted into an expression, a
 | 	/*	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(); | 	register struct expr *ex = new_expr(); | ||||||
| 
 | 
 | ||||||
| 	*expp = ex; | 	*expp = ex; | ||||||
| 	ex->ex_file = dot.tk_file; | 	ex->ex_file = dot.tk_file; | ||||||
| 	ex->ex_line = dot.tk_line; | 	ex->ex_line = dot.tk_line; | ||||||
| 	switch (DOT)	{ | 	switch (DOT) | ||||||
|  | 	{ | ||||||
| 	case IDENTIFIER: | 	case IDENTIFIER: | ||||||
| 		idf2expr(ex); | 		idf2expr(ex); | ||||||
| 		break; | 		break; | ||||||
|  | @ -125,25 +127,27 @@ dot2expr(expp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| idf2expr(expr) | void idf2expr(register struct expr *expr) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	Dot contains an identifier which is turned into an
 | 	/*	Dot contains an identifier which is turned into an
 | ||||||
| 		expression. | 	 expression. | ||||||
| 		Note that this constitutes an applied occurrence of | 	 Note that this constitutes an applied occurrence of | ||||||
| 		the identifier. | 	 the identifier. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct idf *idf = dot.tk_idf;	/* != 0*/ | 	register struct idf *idf = dot.tk_idf; /* != 0*/ | ||||||
| 	register struct def *def = idf->id_def; | 	register struct def *def = idf->id_def; | ||||||
| 	 | 
 | ||||||
| 	if (def == 0)	{ | 	if (def == 0) | ||||||
| 		if (AHEAD == '(') { | 	{ | ||||||
|  | 		if (AHEAD == '(') | ||||||
|  | 		{ | ||||||
| 			/* function call, declare name implicitly (3.3.2.2) */ | 			/* function call, declare name implicitly (3.3.2.2) */ | ||||||
| 			if (!options['o']) | 			if (!options['o']) | ||||||
| 				warning("implicit declaration of function %s" | 				warning("implicit declaration of function %s", idf->id_text); | ||||||
| 					, idf->id_text); |  | ||||||
| 			add_def(idf, EXTERN, funint_type, level); | 			add_def(idf, EXTERN, funint_type, level); | ||||||
| 		} else	{ | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
| 			if (!is_anon_idf(idf)) | 			if (!is_anon_idf(idf)) | ||||||
| 				error("%s undefined", idf->id_text); | 				error("%s undefined", idf->id_text); | ||||||
| 			/* declare idf anyway */ | 			/* declare idf anyway */ | ||||||
|  | @ -153,8 +157,10 @@ idf2expr(expr) | ||||||
| 	} | 	} | ||||||
| 	/* now def != 0 */ | 	/* now def != 0 */ | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
| 	if (!InSizeof) { | 	if (!InSizeof) | ||||||
| 		if (! def->df_used) { | 	{ | ||||||
|  | 		if (!def->df_used) | ||||||
|  | 		{ | ||||||
| #ifndef PREPEND_SCOPES | #ifndef PREPEND_SCOPES | ||||||
| 			code_scope(idf->id_text, def); | 			code_scope(idf->id_text, def); | ||||||
| #endif /* PREPEND_SCOPES */ | #endif /* PREPEND_SCOPES */ | ||||||
|  | @ -163,46 +169,45 @@ idf2expr(expr) | ||||||
| 	} | 	} | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 	expr->ex_type = def->df_type; | 	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_flags |= EX_ERROR; | ||||||
| 	} | 	} | ||||||
| 	expr->ex_lvalue = | 	expr->ex_lvalue = | ||||||
| 		(	def->df_type->tp_fund == FUNCTION || | 			(def->df_type->tp_fund == FUNCTION || def->df_type->tp_fund == ARRAY | ||||||
| 			def->df_type->tp_fund == ARRAY || | 					|| def->df_sc == ENUM) ? 0 : 1; | ||||||
| 			def->df_sc == ENUM |  | ||||||
| 		) ? 0 : 1; |  | ||||||
| 	if (def->df_type->tp_typequal & TQ_CONST) | 	if (def->df_type->tp_typequal & TQ_CONST) | ||||||
| 		expr->ex_flags |= EX_READONLY; | 		expr->ex_flags |= EX_READONLY; | ||||||
| 	if (def->df_type->tp_typequal & TQ_VOLATILE) | 	if (def->df_type->tp_typequal & TQ_VOLATILE) | ||||||
| 		expr->ex_flags |= EX_VOLATILE; | 		expr->ex_flags |= EX_VOLATILE; | ||||||
| 	expr->ex_class = Value; | 	expr->ex_class = Value; | ||||||
| 	if (def->df_sc == ENUM)	{ | 	if (def->df_sc == ENUM) | ||||||
|  | 	{ | ||||||
| 		expr->VL_CLASS = Const; | 		expr->VL_CLASS = Const; | ||||||
| 		expr->VL_VALUE = def->df_address; | 		expr->VL_VALUE = def->df_address; | ||||||
| 	} | 	} | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
| 	else | 	else if (def->df_sc == STATIC && def->df_level >= L_LOCAL) | ||||||
| 	if (def->df_sc == STATIC && def->df_level >= L_LOCAL) { | 	{ | ||||||
| 		expr->VL_CLASS = Label; | 		expr->VL_CLASS = Label; | ||||||
| 		expr->VL_LBL = def->df_address; | 		expr->VL_LBL = def->df_address; | ||||||
| 		expr->VL_VALUE = (arith)0; | 		expr->VL_VALUE = (arith) 0; | ||||||
| 	} | 	} | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 	else { | 	else | ||||||
|  | 	{ | ||||||
| 		expr->VL_CLASS = Name; | 		expr->VL_CLASS = Name; | ||||||
| 		expr->VL_IDF = idf; | 		expr->VL_IDF = idf; | ||||||
| 		expr->VL_VALUE = (arith)0; | 		expr->VL_VALUE = (arith) 0; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| string2expr(expp, str, len) | void string2expr(register struct expr **expp, char *str, int len) | ||||||
| 	register struct expr **expp; | 
 | ||||||
| 	int len; |  | ||||||
| 	char *str; |  | ||||||
| { | { | ||||||
| 	/*	The string in the argument is converted into an expression,
 | 	/*	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(); | 	register struct expr *ex = new_expr(); | ||||||
| 
 | 
 | ||||||
| 	*expp = ex; | 	*expp = ex; | ||||||
|  | @ -217,25 +222,24 @@ string2expr(expp, str, len) | ||||||
| 	ex->SG_LEN = len; | 	ex->SG_LEN = len; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int2expr(expr) | void int2expr(struct expr *expr) | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	Dot contains an integer constant which is turned
 | 	/*	Dot contains an integer constant which is turned
 | ||||||
| 		into an expression. | 	 into an expression. | ||||||
| 	*/ | 	 */ | ||||||
| 	fill_int_expr(expr, dot.tk_ival, dot.tk_fund); | 	fill_int_expr(expr, dot.tk_ival, dot.tk_fund); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float2expr(expr) | void float2expr(register struct expr *expr) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	Dot contains a floating point constant which is turned
 | 	/*	Dot contains a floating point constant which is turned
 | ||||||
| 		into an expression. | 	 into an expression. | ||||||
| 	*/ | 	 */ | ||||||
| 	register int fund; | 	register int fund; | ||||||
| 
 | 
 | ||||||
| 	fund = dot.tk_fund; | 	fund = dot.tk_fund; | ||||||
| 	switch (fund) { | 	switch (fund) | ||||||
|  | 	{ | ||||||
| 	case FLOAT: | 	case FLOAT: | ||||||
| 		expr->ex_type = float_type; | 		expr->ex_type = float_type; | ||||||
| 		break; | 		break; | ||||||
|  | @ -253,17 +257,15 @@ float2expr(expr) | ||||||
| 	free(dot.tk_fval); | 	free(dot.tk_fval); | ||||||
| 	assert(flt_status != FLT_NOFLT); | 	assert(flt_status != FLT_NOFLT); | ||||||
| 	if (flt_status == FLT_OVFL) | 	if (flt_status == FLT_OVFL) | ||||||
| 		expr_warning(expr,"internal floating point overflow"); | 		expr_warning(expr, "internal floating point overflow"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct expr* | struct expr*intexpr( | ||||||
| intexpr(ivalue, fund) | arith ivalue, int fund) | ||||||
| 	arith ivalue; |  | ||||||
| 	int fund; |  | ||||||
| { | { | ||||||
| 	/*	The value ivalue is turned into an integer expression of
 | 	/*	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(); | 	register struct expr *expr = new_expr(); | ||||||
| 
 | 
 | ||||||
| 	expr->ex_file = dot.tk_file; | 	expr->ex_file = dot.tk_file; | ||||||
|  | @ -272,15 +274,14 @@ intexpr(ivalue, fund) | ||||||
| 	return expr; | 	return expr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fill_int_expr(ex, ivalue, fund) | void fill_int_expr(register struct expr *ex, | ||||||
| 	register struct expr *ex; | arith ivalue, int fund) | ||||||
| 	arith ivalue; |  | ||||||
| 	int fund; |  | ||||||
| { | { | ||||||
| 	/*	Details derived from ivalue and fund are put into the
 | 	/*	Details derived from ivalue and fund are put into the
 | ||||||
| 		constant integer expression ex. | 	 constant integer expression ex. | ||||||
| 	*/ | 	 */ | ||||||
| 	switch (fund) { | 	switch (fund) | ||||||
|  | 	{ | ||||||
| 	case INT: | 	case INT: | ||||||
| 		ex->ex_type = int_type; | 		ex->ex_type = int_type; | ||||||
| 		break; | 		break; | ||||||
|  | @ -288,7 +289,7 @@ fill_int_expr(ex, ivalue, fund) | ||||||
| 		ex->ex_type = uint_type; | 		ex->ex_type = uint_type; | ||||||
| 		break; | 		break; | ||||||
| 	case LONG: | 	case LONG: | ||||||
| 		ex->ex_type =  long_type; | 		ex->ex_type = long_type; | ||||||
| 		break; | 		break; | ||||||
| 	case ULONG: | 	case ULONG: | ||||||
| 		ex->ex_type = ulong_type; | 		ex->ex_type = ulong_type; | ||||||
|  | @ -303,38 +304,38 @@ fill_int_expr(ex, ivalue, fund) | ||||||
| 	cut_size(ex); | 	cut_size(ex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct expr * | struct expr *new_oper(struct type *tp, register struct expr *e1, int oper, | ||||||
| new_oper(tp, e1, oper, e2) | 		register struct expr *e2) | ||||||
| 	struct type *tp; |  | ||||||
| 	register struct expr *e1, *e2; |  | ||||||
| { | { | ||||||
| 	/*	A new expression is constructed which consists of the
 | 	/*	A new expression is constructed which consists of the
 | ||||||
| 		operator oper which has e1 and e2 as operands; for a | 	 operator oper which has e1 and e2 as operands; for a | ||||||
| 		monadic operator e1 == NILEXPR. | 	 monadic operator e1 == NILEXPR. | ||||||
| 		During the construction of the right recursive initialisation | 	 During the construction of the right recursive initialisation | ||||||
| 		tree it is possible for e2 to be NILEXPR. | 	 tree it is possible for e2 to be NILEXPR. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct expr *expr = new_expr(); | 	register struct expr *expr = new_expr(); | ||||||
| 	register struct oper *op; | 	register struct oper *op; | ||||||
| 
 | 
 | ||||||
| 	if (e2)	{ | 	if (e2) | ||||||
|  | 	{ | ||||||
| 		register struct expr *e = e2; | 		register struct expr *e = e2; | ||||||
| 		 | 
 | ||||||
| 		while (e->ex_class == Oper && e->OP_LEFT) | 		while (e->ex_class == Oper && e->OP_LEFT) | ||||||
| 			e = e->OP_LEFT; | 			e = e->OP_LEFT; | ||||||
| 		expr->ex_file = e->ex_file; | 		expr->ex_file = e->ex_file; | ||||||
| 		expr->ex_line = e->ex_line; | 		expr->ex_line = e->ex_line; | ||||||
| 	} | 	} | ||||||
| 	else | 	else if (e1) | ||||||
| 	if (e1)	{ | 	{ | ||||||
| 		register struct expr *e = e1; | 		register struct expr *e = e1; | ||||||
| 		 | 
 | ||||||
| 		while (e->ex_class == Oper && e->OP_RIGHT) | 		while (e->ex_class == Oper && e->OP_RIGHT) | ||||||
| 			e = e->OP_RIGHT; | 			e = e->OP_RIGHT; | ||||||
| 		expr->ex_file = e->ex_file; | 		expr->ex_file = e->ex_file; | ||||||
| 		expr->ex_line = e->ex_line; | 		expr->ex_line = e->ex_line; | ||||||
| 	} | 	} | ||||||
| 	else	{ | 	else | ||||||
|  | 	{ | ||||||
| 		expr->ex_file = dot.tk_file; | 		expr->ex_file = dot.tk_file; | ||||||
| 		expr->ex_line = dot.tk_line; | 		expr->ex_line = dot.tk_line; | ||||||
| 	} | 	} | ||||||
|  | @ -342,20 +343,22 @@ new_oper(tp, e1, oper, e2) | ||||||
| 	expr->ex_type = tp; | 	expr->ex_type = tp; | ||||||
| 	expr->ex_class = Oper; | 	expr->ex_class = Oper; | ||||||
| 	/* combine depths and flags of both expressions */ | 	/* combine depths and flags of both expressions */ | ||||||
| 	if (e2)	{ | 	if (e2) | ||||||
|  | 	{ | ||||||
| 		int e1_depth = e1 ? e1->ex_depth : 0; | 		int e1_depth = e1 ? e1->ex_depth : 0; | ||||||
| 		int e1_flags = e1 ? e1->ex_flags : 0; | 		int e1_flags = e1 ? e1->ex_flags : 0; | ||||||
| 		 | 
 | ||||||
| 		expr->ex_depth = | 		expr->ex_depth = (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) | ||||||
| 			(e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1; | 				+ 1; | ||||||
| 		expr->ex_flags = (e1_flags | e2->ex_flags) | 		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 | 	 * A function call should be evaluated first when possible.  Just say | ||||||
| 	 * that the expression tree is very deep. | 	 * that the expression tree is very deep. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (oper == '(') { | 	if (oper == '(') | ||||||
|  | 	{ | ||||||
| 		expr->ex_depth = 50; | 		expr->ex_depth = 50; | ||||||
| 	} | 	} | ||||||
| 	op = &expr->ex_object.ex_oper; | 	op = &expr->ex_object.ex_oper; | ||||||
|  | @ -369,42 +372,42 @@ new_oper(tp, e1, oper, e2) | ||||||
| 	return expr; | 	return expr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void chk_cst_expr(struct expr **expp) | ||||||
| chk_cst_expr(expp) |  | ||||||
| 	struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	The expression expr is checked for constancy.
 | 	/*	The expression expr is checked for constancy.
 | ||||||
| 	 | 
 | ||||||
| 		There are 6 places where constant expressions occur in C: | 	 There are 6 places where constant expressions occur in C: | ||||||
| 		1.	after #if | 	 1.	after #if | ||||||
| 		2.	in a global initialization | 	 2.	in a global initialization | ||||||
| 		3.	as size in an array declaration | 	 3.	as size in an array declaration | ||||||
| 		4.	as value in an enum declaration | 	 4.	as value in an enum declaration | ||||||
| 		5.	as width in a bit field | 	 5.	as width in a bit field | ||||||
| 		6.	as case value in a switch | 	 6.	as case value in a switch | ||||||
| 		 | 
 | ||||||
| 		The constant expression in a global initialization is | 	 The constant expression in a global initialization is | ||||||
| 		handled separately (by IVAL()). | 	 handled separately (by IVAL()). | ||||||
| 		 | 
 | ||||||
| 		There are various disparate restrictions on each of | 	 There are various disparate restrictions on each of | ||||||
| 		the others in the various C compilers.  I have tried some | 	 the others in the various C compilers.  I have tried some | ||||||
| 		hypotheses to unify them, but all have failed. | 	 hypotheses to unify them, but all have failed. | ||||||
| 		 | 
 | ||||||
| 		Special problems (of which there is only one, sizeof in | 	 Special problems (of which there is only one, sizeof in | ||||||
| 		Preprocessor #if) have to be dealt with locally | 	 Preprocessor #if) have to be dealt with locally | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct expr *expr = *expp; | 	register struct expr *expr = *expp; | ||||||
| 	 | 
 | ||||||
| #ifdef	DEBUG | #ifdef	DEBUG | ||||||
| 	print_expr("constant_expression", expr); | 	print_expr("constant_expression", expr); | ||||||
| #endif	/* DEBUG */ | #endif	/* DEBUG */ | ||||||
| 	switch(expr->ex_type->tp_fund) { | 	switch (expr->ex_type->tp_fund) | ||||||
|  | 	{ | ||||||
| 	case CHAR: | 	case CHAR: | ||||||
| 	case SHORT: | 	case SHORT: | ||||||
| 	case INT: | 	case INT: | ||||||
| 	case ENUM: | 	case ENUM: | ||||||
| 	case LONG: | 	case LONG: | ||||||
| 		if (is_ld_cst(expr)) { | 		if (is_ld_cst(expr)) | ||||||
|  | 		{ | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		expr_error(expr, "expression is not constant"); | 		expr_error(expr, "expression is not constant"); | ||||||
|  | @ -416,67 +419,58 @@ chk_cst_expr(expp) | ||||||
| 	erroneous2int(expp); | 	erroneous2int(expp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| init_expression(eppp, expr) | void init_expression(register struct expr ***eppp, struct expr *expr) | ||||||
| 	register struct expr ***eppp; |  | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	The expression expr is added to the tree designated
 | 	/*	The expression expr is added to the tree designated
 | ||||||
| 		indirectly by **eppp. | 	 indirectly by **eppp. | ||||||
| 		The natural form of a tree representing an | 	 The natural form of a tree representing an | ||||||
| 		initial_value_list is right-recursive, ie. with the | 	 initial_value_list is right-recursive, ie. with the | ||||||
| 		left-most comma as main operator. The iterative grammar in | 	 left-most comma as main operator. The iterative grammar in | ||||||
| 		expression.g, however, tends to produce a left-recursive | 	 expression.g, however, tends to produce a left-recursive | ||||||
| 		tree, ie. one with the right-most comma as its main | 	 tree, ie. one with the right-most comma as its main | ||||||
| 		operator. | 	 operator. | ||||||
| 		To produce a right-recursive tree from the iterative | 	 To produce a right-recursive tree from the iterative | ||||||
| 		grammar, we keep track of the address of the pointer where | 	 grammar, we keep track of the address of the pointer where | ||||||
| 		the next expression must be hooked in. | 	 the next expression must be hooked in. | ||||||
| 	*/ | 	 */ | ||||||
| 	**eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR); | 	**eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR); | ||||||
| 	*eppp = &(**eppp)->OP_RIGHT; | 	*eppp = &(**eppp)->OP_RIGHT; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int is_ld_cst(register struct expr *expr) | ||||||
| is_ld_cst(expr) |  | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	An expression is a `load-time constant' if it is of the form
 | 	/*	An expression is a `load-time constant' if it is of the form
 | ||||||
| 		<idf> +/- <integral> or <integral>. | 	 <idf> +/- <integral> or <integral>. | ||||||
| 	*/ | 	 */ | ||||||
| #ifdef	LINT | #ifdef	LINT | ||||||
| 	if (expr->ex_class == String) | 	if (expr->ex_class == String) | ||||||
| 		return 1; | 	return 1; | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| 	return expr->ex_lvalue == 0 && expr->ex_class == Value; | 	return expr->ex_lvalue == 0 && expr->ex_class == Value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int is_cp_cst(struct expr *expr) | ||||||
| is_cp_cst(expr) |  | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	An expression is a `compile-time constant' if it is a
 | 	/*	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; | 	return is_ld_cst(expr) && expr->VL_CLASS == Const; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int is_fp_cst(struct expr *expr) | ||||||
| is_fp_cst(expr) |  | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	An expression is a `floating-point constant' if it consists
 | 	/*	An expression is a `floating-point constant' if it consists
 | ||||||
| 		of the float only. | 	 of the float only. | ||||||
| 	*/ | 	 */ | ||||||
| 	return expr->ex_class == Float; | 	return expr->ex_class == Float; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int is_zero_cst(register struct expr *expr) | ||||||
| is_zero_cst(expr) |  | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	flt_arith var; | 	flt_arith var; | ||||||
| 
 | 
 | ||||||
| 	switch(expr->ex_class) { | 	switch (expr->ex_class) | ||||||
|  | 	{ | ||||||
| 	case Value: | 	case Value: | ||||||
| 		return expr->VL_VALUE == 0; | 		return expr->VL_VALUE == 0; | ||||||
| 	case Float: | 	case Float: | ||||||
|  | @ -486,13 +480,14 @@ is_zero_cst(expr) | ||||||
| 	/*NOTREACHED*/ | 	/*NOTREACHED*/ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| free_expression(expr) | void free_expression(register struct expr *expr) | ||||||
| 	register struct expr *expr; |  | ||||||
| { | { | ||||||
| 	/*	The expression expr is freed recursively.
 | 	/*	The expression expr is freed recursively.
 | ||||||
| 	*/ | 	 */ | ||||||
| 	if (expr) { | 	if (expr) | ||||||
| 		if (expr->ex_class == Oper)	{ | 	{ | ||||||
|  | 		if (expr->ex_class == Oper) | ||||||
|  | 		{ | ||||||
| 			free_expression(expr->OP_LEFT); | 			free_expression(expr->OP_LEFT); | ||||||
| 			free_expression(expr->OP_RIGHT); | 			free_expression(expr->OP_RIGHT); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -4,6 +4,13 @@ | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* EXPRESSION DESCRIPTOR */ | /* 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 | /*	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. | 	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 */ | /* 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 | ||||||
|  | @ -1,349 +1,354 @@ | ||||||
| /* | /* | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /*	EXPRESSION SYNTAX PARSER	*/ | /*	EXPRESSION SYNTAX PARSER	*/ | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"label.h" | #include	"label.h" | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"code.h" | #include	"code.h" | ||||||
| #include	"sizes.h" | #include    "error.h" | ||||||
| 
 | #include    "ch3.h" | ||||||
| extern struct expr *intexpr(); | #include    "ch3bin.h" | ||||||
| int InSizeof = 0;	/* inside a sizeof- expression */ | #include    "ch3mon.h" | ||||||
| int ResultKnown = 0;	/* result of the expression is already known */ | #include    "proto.h" | ||||||
| 
 | #include	"sizes.h" | ||||||
| /* Since the grammar in the standard is not LL(n), it is modified so that | 
 | ||||||
|  * it accepts basically the same grammar. This means that there is no 1-1 | extern struct expr *intexpr(); | ||||||
|  * mapping from the grammar in the standard to the grammar given here. | int InSizeof = 0;	/* inside a sizeof- expression */ | ||||||
|  * Such is life. | int ResultKnown = 0;	/* result of the expression is already known */ | ||||||
|  */ | 
 | ||||||
| } | /* Since the grammar in the standard is not LL(n), it is modified so that | ||||||
| 
 |  * it accepts basically the same grammar. This means that there is no 1-1 | ||||||
| /* 3.3.1 */ |  * mapping from the grammar in the standard to the grammar given here. | ||||||
| primary(register struct expr **expp;) : |  * Such is life. | ||||||
| 	IDENTIFIER |  */ | ||||||
| 	{dot2expr(expp);} | } | ||||||
| | | 
 | ||||||
| 	constant(expp) | /* 3.3.1 */ | ||||||
| | | primary(register struct expr **expp;) : | ||||||
| 	string(expp) | 	IDENTIFIER | ||||||
| | | 	{dot2expr(expp);} | ||||||
| 	'(' expression(expp) ')' | | | ||||||
| 	{ (*expp)->ex_flags |= EX_PARENS; } | 	constant(expp) | ||||||
| ; | | | ||||||
| 
 | 	string(expp) | ||||||
| 
 | | | ||||||
| /* Character string literals that are adjacent tokens | 	'(' expression(expp) ')' | ||||||
|  * are concatenated into a single character string | 	{ (*expp)->ex_flags |= EX_PARENS; } | ||||||
|  * literal. | ; | ||||||
|  */ | 
 | ||||||
| string(register struct expr **expp;) | 
 | ||||||
| 	{	register int i, len; | /* Character string literals that are adjacent tokens | ||||||
| 		register char *str; |  * are concatenated into a single character string | ||||||
| 		register int fund; |  * literal. | ||||||
| 	} |  */ | ||||||
| : | string(register struct expr **expp;) | ||||||
| 	STRING | 	{	register int i, len; | ||||||
| 	{	str = dot.tk_bts; | 		register char *str; | ||||||
| 		len = dot.tk_len; | 		register int fund; | ||||||
| 		fund = dot.tk_fund; | 	} | ||||||
| 	} | : | ||||||
| 	[ | 	STRING | ||||||
| 		STRING | 	{	str = dot.tk_bts; | ||||||
| 		{	/* A pasted string keeps the type of the first | 		len = dot.tk_len; | ||||||
| 			 * string literal. | 		fund = dot.tk_fund; | ||||||
| 			 * The pasting of normal strings and wide | 	} | ||||||
| 			 * character strings are stated as having an | 	[ | ||||||
| 			 * undefined behaviour. | 		STRING | ||||||
| 			 */ | 		{	/* A pasted string keeps the type of the first | ||||||
| 			if (dot.tk_fund != fund) | 			 * string literal. | ||||||
| 				warning("illegal pasting of string literals"); | 			 * The pasting of normal strings and wide | ||||||
| 			str = Realloc(str, (unsigned) (--len + dot.tk_len)); | 			 * character strings are stated as having an | ||||||
| 			for (i = 0; i < dot.tk_len; i++) | 			 * undefined behaviour. | ||||||
| 				str[len++] = dot.tk_bts[i]; | 			 */ | ||||||
| 		} | 			if (dot.tk_fund != fund) | ||||||
| 	]* | 				warning("illegal pasting of string literals"); | ||||||
| 	{ string2expr(expp, str, len); } | 			str = Realloc(str, (unsigned) (--len + dot.tk_len)); | ||||||
| ; | 			for (i = 0; i < dot.tk_len; i++) | ||||||
| 
 | 				str[len++] = dot.tk_bts[i]; | ||||||
| /* 3.3.2 */ | 		} | ||||||
| postfix_expression(register struct expr **expp;) | 	]* | ||||||
| 	{ int oper;  | 	{ string2expr(expp, str, len); } | ||||||
| 	  struct expr *e1 = 0; | ; | ||||||
| 	  struct idf *idf; | 
 | ||||||
| 	} | /* 3.3.2 */ | ||||||
| : | postfix_expression(register struct expr **expp;) | ||||||
| 	primary(expp) | 	{ int oper;  | ||||||
| 	[ | 	  struct expr *e1 = 0; | ||||||
| 		'[' expression(&e1) ']' | 	  struct idf *idf; | ||||||
| 			{ ch3bin(expp, '[', e1); e1 = 0; } | 	} | ||||||
| 	| | : | ||||||
| 		'(' parameter_list(&e1)? ')' | 	primary(expp) | ||||||
| 			{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; } | 	[ | ||||||
| 	| | 		'[' expression(&e1) ']' | ||||||
| 		[ '.' | ARROW ]			{ oper = DOT; } | 			{ ch3bin(expp, '[', e1); e1 = 0; } | ||||||
| 		identifier(&idf)		{ ch3sel(expp, oper, idf); } | 	| | ||||||
| 	| | 		'(' parameter_list(&e1)? ')' | ||||||
| 		[ | 			{ ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; } | ||||||
| 			PLUSPLUS	{ oper = POSTINCR; } | 	| | ||||||
| 		| | 		[ '.' | ARROW ]			{ oper = DOT; } | ||||||
| 			MINMIN		{ oper = POSTDECR; } | 		identifier(&idf)		{ ch3sel(expp, oper, idf); } | ||||||
| 		] | 	| | ||||||
| 		    { ch3incr(expp, oper); } | 		[ | ||||||
| 	]* | 			PLUSPLUS	{ oper = POSTINCR; } | ||||||
| ; | 		| | ||||||
| 
 | 			MINMIN		{ oper = POSTDECR; } | ||||||
| parameter_list(struct expr **expp;) | 		] | ||||||
| 	{struct expr *e1 = 0;} | 		    { ch3incr(expp, oper); } | ||||||
| : | 	]* | ||||||
| 	assignment_expression(expp) | ; | ||||||
| 	{any2opnd(expp, PARCOMMA);} | 
 | ||||||
| 	[ %persistent | parameter_list(struct expr **expp;) | ||||||
| 		',' | 	{struct expr *e1 = 0;} | ||||||
| 		assignment_expression(&e1) | : | ||||||
| 		{any2opnd(&e1, PARCOMMA);} | 	assignment_expression(expp) | ||||||
| 		{ch3bin(expp, PARCOMMA, e1);} | 	{any2opnd(expp, PARCOMMA);} | ||||||
| 	]* | 	[ %persistent | ||||||
| ; | 		',' | ||||||
| 
 | 		assignment_expression(&e1) | ||||||
| %first	first_of_type_specifier, type_specifier; | 		{any2opnd(&e1, PARCOMMA);} | ||||||
| 
 | 		{ch3bin(expp, PARCOMMA, e1);} | ||||||
| /* 3.3.3 & 3.3.4 */ | 	]* | ||||||
| unary(register struct expr **expp;) | ; | ||||||
| 	{struct type *tp; int oper;} | 
 | ||||||
| : | %first	first_of_type_specifier, type_specifier; | ||||||
| %if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) | 
 | ||||||
| 	cast(&tp) unary(expp) | /* 3.3.3 & 3.3.4 */ | ||||||
| 	{	ch3cast(expp, CAST, tp); | unary(register struct expr **expp;) | ||||||
| 		(*expp)->ex_flags |= EX_CAST; | 	{struct type *tp; int oper;} | ||||||
| 		if (int_size != pointer_size) | : | ||||||
| 			(*expp)->ex_flags &= ~EX_PTRDIFF; | %if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) | ||||||
| 	} | 	cast(&tp) unary(expp) | ||||||
| | | 	{	ch3cast(expp, CAST, tp); | ||||||
| 	postfix_expression(expp) | 		(*expp)->ex_flags |= EX_CAST; | ||||||
| | | 		if (int_size != pointer_size) | ||||||
| 	unop(&oper) unary(expp) | 			(*expp)->ex_flags &= ~EX_PTRDIFF; | ||||||
| 	{ch3mon(oper, expp);} | 	} | ||||||
| | | | | ||||||
| 	size_of(expp) | 	postfix_expression(expp) | ||||||
| ; | | | ||||||
| 
 | 	unop(&oper) unary(expp) | ||||||
| /* When an identifier is used in a sizeof()-expression, we must stil not | 	{ch3mon(oper, expp);} | ||||||
|  * mark it as used. | | | ||||||
|  * extern int i;  ....  sizeof(i)  .... need not have a definition for i | 	size_of(expp) | ||||||
|  */ | ; | ||||||
| size_of(register struct expr **expp;) | 
 | ||||||
| 	{struct type *tp;} | /* When an identifier is used in a sizeof()-expression, we must stil not | ||||||
| : |  * mark it as used. | ||||||
| 	SIZEOF { InSizeof++; }	/* handle (sizeof(sizeof(int))) too */ |  * extern int i;  ....  sizeof(i)  .... need not have a definition for i | ||||||
| 	[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) |  */ | ||||||
| 		cast(&tp) | size_of(register struct expr **expp;) | ||||||
| 		{ | 	{struct type *tp;} | ||||||
| 			*expp = intexpr(size_of_type(tp, "type"), UNSIGNED); | : | ||||||
| 			(*expp)->ex_flags |= EX_SIZEOF; | 	SIZEOF { InSizeof++; }	/* handle (sizeof(sizeof(int))) too */ | ||||||
| 		} | 	[%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER) | ||||||
| 	| | 		cast(&tp) | ||||||
| 		unary(expp) | 		{ | ||||||
| 		{ch3mon(SIZEOF, expp);} | 			*expp = intexpr(size_of_type(tp, "type"), UNSIGNED); | ||||||
| 	] | 			(*expp)->ex_flags |= EX_SIZEOF; | ||||||
| 	{ InSizeof--; } | 		} | ||||||
| ; | 	| | ||||||
| 
 | 		unary(expp) | ||||||
| /* 3.3.5-3.3.17 */ | 		{ch3mon(SIZEOF, expp);} | ||||||
| /*	The set of operators in C is stratified in 15 levels, with level | 	] | ||||||
| 	N being treated in RM 7.N (although this is not the standard | 	{ InSizeof--; } | ||||||
| 	anymore). The standard describes this in phrase-structure-grammar, | ; | ||||||
| 	which we are unable to parse. The description that follows comes | 
 | ||||||
| 	from the old C-compiler. | /* 3.3.5-3.3.17 */ | ||||||
| 
 | /*	The set of operators in C is stratified in 15 levels, with level | ||||||
| 	In principle each operator is assigned a rank, ranging | 	N being treated in RM 7.N (although this is not the standard | ||||||
| 	from 1 to 15.  Such an expression can be parsed by a construct | 	anymore). The standard describes this in phrase-structure-grammar, | ||||||
| 	like: | 	which we are unable to parse. The description that follows comes | ||||||
| 		binary_expression(int maxrank;) | 	from the old C-compiler. | ||||||
| 			{int oper;} | 
 | ||||||
| 		: | 	In principle each operator is assigned a rank, ranging | ||||||
| 			binary_expression(maxrank - 1) | 	from 1 to 15.  Such an expression can be parsed by a construct | ||||||
| 			[%if (rank_of(DOT) <= maxrank) | 	like: | ||||||
| 				binop(&oper) | 		binary_expression(int maxrank;) | ||||||
| 				binary_expression(rank_of(oper)-1) | 			{int oper;} | ||||||
| 			]? | 		: | ||||||
| 		; | 			binary_expression(maxrank - 1) | ||||||
| 	except that some call of 'unary' is necessary, depending on the | 			[%if (rank_of(DOT) <= maxrank) | ||||||
| 	grammar. | 				binop(&oper) | ||||||
| 	 | 				binary_expression(rank_of(oper)-1) | ||||||
| 	This simple view is marred by three complications: | 			]? | ||||||
| 	1.	Level 15 (comma operator) is not allowed in many | 		; | ||||||
| 		contexts and is different. | 	except that some call of 'unary' is necessary, depending on the | ||||||
| 	2.	Level 13 (conditional operator) is a ternary operator, | 	grammar. | ||||||
| 		which does not fit this scheme at all. | 	 | ||||||
| 	3.	Level 14 (assignment operators) group right-to-left, as | 	This simple view is marred by three complications: | ||||||
| 		opposed to 2-12, which group left-to-right (or are | 	1.	Level 15 (comma operator) is not allowed in many | ||||||
| 		immaterial). | 		contexts and is different. | ||||||
| 	4.	The operators in level 14 start with operators in levels | 	2.	Level 13 (conditional operator) is a ternary operator, | ||||||
| 		2-13 (RM 7.14: The two parts of a compound assignment | 		which does not fit this scheme at all. | ||||||
| 		operator are separate tokens.)  This causes LL1 problems. | 	3.	Level 14 (assignment operators) group right-to-left, as | ||||||
| 	This forces us to have four rules: | 		opposed to 2-12, which group left-to-right (or are | ||||||
| 		binary_expression	for level 2-12 | 		immaterial). | ||||||
| 		conditional_expression	for level 13 | 	4.	The operators in level 14 start with operators in levels | ||||||
| 		assignment_expression	for level 14 and | 		2-13 (RM 7.14: The two parts of a compound assignment | ||||||
| 		expression		for the most general expression | 		operator are separate tokens.)  This causes LL1 problems. | ||||||
| */ | 	This forces us to have four rules: | ||||||
| 
 | 		binary_expression	for level 2-12 | ||||||
| binary_expression(int maxrank; struct expr **expp;) | 		conditional_expression	for level 13 | ||||||
| 	{int oper, OldResultKnown; struct expr *e1;} | 		assignment_expression	for level 14 and | ||||||
| : | 		expression		for the most general expression | ||||||
| 	unary(expp) | */ | ||||||
| 	[%while (rank_of(DOT) <= maxrank ) | 
 | ||||||
| 		/*	'?', '=', and ',' are no binops | binary_expression(int maxrank; struct expr **expp;) | ||||||
| 		 */ | 	{int oper, OldResultKnown; struct expr *e1;} | ||||||
| 		binop(&oper) | : | ||||||
| 		{ OldResultKnown = ResultKnown; | 	unary(expp) | ||||||
| 		  if (oper == OR || oper == AND) { | 	[%while (rank_of(DOT) <= maxrank ) | ||||||
| 			  if (is_cp_cst(*expp) || is_fp_cst(*expp)) { | 		/*	'?', '=', and ',' are no binops | ||||||
| 				  if (is_zero_cst(*expp)) { | 		 */ | ||||||
| 					  if (oper == AND) ResultKnown++; | 		binop(&oper) | ||||||
| 				  } else if (oper == OR) ResultKnown++; | 		{ OldResultKnown = ResultKnown; | ||||||
| 			  } | 		  if (oper == OR || oper == AND) { | ||||||
| 		  } | 			  if (is_cp_cst(*expp) || is_fp_cst(*expp)) { | ||||||
| 		} | 				  if (is_zero_cst(*expp)) { | ||||||
| 		binary_expression(rank_of(oper)-1, &e1) | 					  if (oper == AND) ResultKnown++; | ||||||
| 		{ | 				  } else if (oper == OR) ResultKnown++; | ||||||
| 			ch3bin(expp, oper, e1); | 			  } | ||||||
| 			ResultKnown = OldResultKnown; | 		  } | ||||||
| 		} | 		} | ||||||
| 	]* | 		binary_expression(rank_of(oper)-1, &e1) | ||||||
| ; | 		{ | ||||||
| 
 | 			ch3bin(expp, oper, e1); | ||||||
| /* 3.3.15 */ | 			ResultKnown = OldResultKnown; | ||||||
| conditional_expression(struct expr **expp;) | 		} | ||||||
| 	{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;} | 	]* | ||||||
| : | ; | ||||||
| 	/* allow all binary operators */ | 
 | ||||||
| 	binary_expression(rank_of('?') - 1, expp) | /* 3.3.15 */ | ||||||
| 	[	'?' | conditional_expression(struct expr **expp;) | ||||||
| 		{ OldResultKnown = ResultKnown; | 	{struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;} | ||||||
| 		  if (is_cp_cst(*expp) || is_fp_cst(*expp)) { | : | ||||||
| 			  ConstExpr++; | 	/* allow all binary operators */ | ||||||
| 			  if (is_zero_cst(*expp)) ResultKnown++; | 	binary_expression(rank_of('?') - 1, expp) | ||||||
| 		  } | 	[	'?' | ||||||
| 		} | 		{ OldResultKnown = ResultKnown; | ||||||
| 		expression(&e1) | 		  if (is_cp_cst(*expp) || is_fp_cst(*expp)) { | ||||||
| 		':' | 			  ConstExpr++; | ||||||
| 		{ if (ConstExpr) { | 			  if (is_zero_cst(*expp)) ResultKnown++; | ||||||
| 			if (OldResultKnown == ResultKnown) ResultKnown++; | 		  } | ||||||
| 			else ResultKnown = OldResultKnown; | 		} | ||||||
| 		  } | 		expression(&e1) | ||||||
| 		} | 		':' | ||||||
| 		conditional_expression(&e2) | 		{ if (ConstExpr) { | ||||||
| 		{	 | 			if (OldResultKnown == ResultKnown) ResultKnown++; | ||||||
| 			ResultKnown = OldResultKnown; | 			else ResultKnown = OldResultKnown; | ||||||
| 			ch3bin(&e1, ':', e2); | 		  } | ||||||
| 			opnd2test(expp, '?'); | 		} | ||||||
| 			ch3bin(expp, '?', e1); | 		conditional_expression(&e2) | ||||||
| 		} | 		{	 | ||||||
| 	]? | 			ResultKnown = OldResultKnown; | ||||||
| ; | 			ch3bin(&e1, ':', e2); | ||||||
| 
 | 			opnd2test(expp, '?'); | ||||||
| /* 3.3.16 */ | 			ch3bin(expp, '?', e1); | ||||||
| assignment_expression(struct expr **expp;) | 		} | ||||||
| 	{ int oper; | 	]? | ||||||
| 	  struct expr *e1 = 0; | ; | ||||||
| 	} | 
 | ||||||
| : | /* 3.3.16 */ | ||||||
| 	conditional_expression(expp) | assignment_expression(struct expr **expp;) | ||||||
| 	[ | 	{ int oper; | ||||||
| 		asgnop(&oper) | 	  struct expr *e1 = 0; | ||||||
| 		assignment_expression(&e1) | 	} | ||||||
| 		{ch3asgn(expp, oper, e1);} | : | ||||||
| 	| | 	conditional_expression(expp) | ||||||
| 		empty		/* LLgen artefact ??? */ | 	[ | ||||||
| 	] | 		asgnop(&oper) | ||||||
| ; | 		assignment_expression(&e1) | ||||||
| 
 | 		{ch3asgn(expp, oper, e1);} | ||||||
| /* 3.3.17 */ | 	| | ||||||
| expression(struct expr **expp;) | 		empty		/* LLgen artefact ??? */ | ||||||
| 	{struct expr *e1;} | 	] | ||||||
| : | ; | ||||||
| 	assignment_expression(expp) | 
 | ||||||
| 	[	',' | /* 3.3.17 */ | ||||||
| 		assignment_expression(&e1) | expression(struct expr **expp;) | ||||||
| 		{ | 	{struct expr *e1;} | ||||||
| 			ch3bin(expp, ',', e1); | : | ||||||
| 		} | 	assignment_expression(expp) | ||||||
| 	]* | 	[	',' | ||||||
| ; | 		assignment_expression(&e1) | ||||||
| 
 | 		{ | ||||||
| unop(int *oper;) : | 			ch3bin(expp, ',', e1); | ||||||
| 	['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN] | 		} | ||||||
| 	{   if (DOT == '&') DOT = ADDRESSOF; | 	]* | ||||||
| 	    *oper = DOT; | ; | ||||||
| 	} | 
 | ||||||
| ; | unop(int *oper;) : | ||||||
| 
 | 	['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN] | ||||||
| multop: | 	{   if (DOT == '&') DOT = ADDRESSOF; | ||||||
| 	'*' | '/' | '%' | 	    *oper = DOT; | ||||||
| ; | 	} | ||||||
| 
 | ; | ||||||
| addop: | 
 | ||||||
| 	'+' | '-' | multop: | ||||||
| ; | 	'*' | '/' | '%' | ||||||
| 
 | ; | ||||||
| shiftop: | 
 | ||||||
| 	LEFT | RIGHT | addop: | ||||||
| ; | 	'+' | '-' | ||||||
| 
 | ; | ||||||
| relop: | 
 | ||||||
| 	'<' | '>' | LESSEQ | GREATEREQ | shiftop: | ||||||
| ; | 	LEFT | RIGHT | ||||||
| 
 | ; | ||||||
| eqop: | 
 | ||||||
| 	EQUAL | NOTEQUAL | relop: | ||||||
| ; | 	'<' | '>' | LESSEQ | GREATEREQ | ||||||
| 
 | ; | ||||||
| arithop: | 
 | ||||||
| 	multop | addop | shiftop | eqop: | ||||||
| | | 	EQUAL | NOTEQUAL | ||||||
| 	'&' | '^' | '|' | ; | ||||||
| ; | 
 | ||||||
| 
 | arithop: | ||||||
| binop(int *oper;) : | 	multop | addop | shiftop | ||||||
| 	[ arithop | relop | eqop | AND | OR ] | | | ||||||
| 	{*oper = DOT;} | 	'&' | '^' | '|' | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| asgnop(register int *oper;): | binop(int *oper;) : | ||||||
| 	[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB  | 	[ arithop | relop | eqop | AND | OR ] | ||||||
| 	| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ] | 	{*oper = DOT;} | ||||||
| 	{ *oper = DOT; } | ; | ||||||
| 
 | 
 | ||||||
| ; | asgnop(register int *oper;): | ||||||
| 
 | 	[ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB  | ||||||
| constant(struct expr **expp;) : | 	| LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ] | ||||||
| [ | 	{ *oper = DOT; } | ||||||
| 	INTEGER | 
 | ||||||
| | | ; | ||||||
| 	FLOATING | 
 | ||||||
| ]	{dot2expr(expp);} | constant(struct expr **expp;) : | ||||||
| ; | [ | ||||||
| 
 | 	INTEGER | ||||||
| /* 3.4 */ | | | ||||||
| constant_expression (struct expr **expp;) : | 	FLOATING | ||||||
| 	conditional_expression(expp) | ]	{dot2expr(expp);} | ||||||
| 	{ chk_cst_expr(expp); } | ; | ||||||
| ; | 
 | ||||||
| 
 | /* 3.4 */ | ||||||
| identifier(struct idf **idfp;) : | constant_expression (struct expr **expp;) : | ||||||
| [ IDENTIFIER | 	conditional_expression(expp) | ||||||
| | TYPE_IDENTIFIER | 	{ chk_cst_expr(expp); } | ||||||
| ] | ; | ||||||
| 	{ *idfp = dot.tk_idf; } | 
 | ||||||
| ; | identifier(struct idf **idfp;) : | ||||||
|  | [ IDENTIFIER | ||||||
|  | | TYPE_IDENTIFIER | ||||||
|  | ] | ||||||
|  | 	{ *idfp = dot.tk_idf; } | ||||||
|  | ; | ||||||
|  |  | ||||||
|  | @ -23,8 +23,11 @@ | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"field.h" | #include	"field.h" | ||||||
|  | #include    "util.h" | ||||||
|  | #include    "conversion.h" | ||||||
|  | #include    "eval.h" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| arith NewLocal();		/* util.c	*/ |  | ||||||
| extern arith full_mask[];	/* cstoper.c	*/ | extern arith full_mask[];	/* cstoper.c	*/ | ||||||
| 
 | 
 | ||||||
| /*	Eval_field() evaluates expressions involving bit fields.
 | /*	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; | 	[3]	atype: the type in which the bitfield arithmetic is done; | ||||||
| 		and in which bitfields are stored! | 		and in which bitfields are stored! | ||||||
| */ | */ | ||||||
| eval_field(expr, code) | void eval_field( | ||||||
| 	struct expr *expr; | 	struct expr *expr, | ||||||
| 	int code; | 	int code) | ||||||
| { | { | ||||||
| 	int op = expr->OP_OPER; | 	int op = expr->OP_OPER; | ||||||
| 	register struct expr *leftop = expr->OP_LEFT; | 	register struct expr *leftop = expr->OP_LEFT; | ||||||
|  | @ -126,12 +129,12 @@ eval_field(expr, code) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| store_field(fd, uns, code, leftop, tmpvar) | void store_field( | ||||||
| 	register struct field *fd; | 	register struct field *fd, | ||||||
| 	int uns; | 	int uns, | ||||||
| 	int code; | 	int code, | ||||||
| 	register struct expr *leftop; | 	register struct expr *leftop, | ||||||
| 	arith tmpvar; | 	arith tmpvar) | ||||||
| { | { | ||||||
| 	C_loc(fd->fd_mask); | 	C_loc(fd->fd_mask); | ||||||
| 	C_and(word_size); | 	C_and(word_size); | ||||||
|  |  | ||||||
|  | @ -2,6 +2,11 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef FIELD_H_ | ||||||
|  | #define FIELD_H_ | ||||||
|  | 
 | ||||||
|  | #include "arith.h" | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* FIELD DESCRIPTOR */ | /* FIELD DESCRIPTOR */ | ||||||
| 
 | 
 | ||||||
|  | @ -13,3 +18,20 @@ struct field	{	/* for field specifiers	*/ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* ALLOCDEF "field" 10 */ | /* 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	"parameters.h" | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
|  | #include    "fltcstoper.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"label.h" | #include	"label.h" | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| extern int ResultKnown; | extern int ResultKnown; | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
| 
 | 
 | ||||||
| fltcstbin(expp, oper, expr) | void fltcstbin(register struct expr **expp, int oper, register struct expr *expr) | ||||||
| 	register struct expr **expp, *expr; |  | ||||||
| { | { | ||||||
| 	/*	The operation oper is performed on the constant
 | 	/*	The operation oper is performed on the constant
 | ||||||
| 		expressions *expp(ld) and expr(ct), and the result restored in | 		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	"declar.h" | ||||||
| #include	"decspecs.h" | #include	"decspecs.h" | ||||||
| #include	"sizes.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" | #include	"Lpars.h" | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
|  | @ -37,91 +43,92 @@ extern char *symbol2str(); | ||||||
| 
 | 
 | ||||||
| #include <idf_pkg.body> | #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
 | 	/*	A new idf is created out of nowhere, to serve as an
 | ||||||
| 		anonymous name. | 	 anonymous name. | ||||||
| 	*/ | 	 */ | ||||||
| 	static int name_cnt; | 	static int name_cnt; | ||||||
| 	char *s = Malloc(strlen(dot.tk_file) + 50); | 	char *s = Malloc(strlen(dot.tk_file) + 50); | ||||||
| 
 | 
 | ||||||
| 	sprint(s, "#%d in %s, line %u", | 	sprint(s, "#%d in %s, line %u", ++name_cnt, dot.tk_file, dot.tk_line); | ||||||
| 			++name_cnt, dot.tk_file, dot.tk_line); | 	s = Realloc(s, strlen(s) + 1); | ||||||
| 	s = Realloc(s, strlen(s)+1); |  | ||||||
| 	return str2idf(s, 0); | 	return str2idf(s, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int is_anon_idf(struct idf *idf) | ||||||
| is_anon_idf(idf) |  | ||||||
| 	struct idf *idf; |  | ||||||
| { | { | ||||||
| 	return idf->id_text[0] == '#'; | 	return idf->id_text[0] == '#'; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| declare_idf(ds, dc, lvl) | void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl) | ||||||
| 	struct decspecs *ds; |  | ||||||
| 	struct declarator *dc; |  | ||||||
| { | { | ||||||
| 	/*	The identifier inside dc is declared on the level lvl, with
 | 	/*	The identifier inside dc is declared on the level lvl, with
 | ||||||
| 		properties deduced from the decspecs ds and the declarator | 	 properties deduced from the decspecs ds and the declarator | ||||||
| 		dc. | 	 dc. | ||||||
| 		The level is given explicitly to be able to insert, e.g., | 	 The level is given explicitly to be able to insert, e.g., | ||||||
| 		labels on the outermost level inside the function. | 	 labels on the outermost level inside the function. | ||||||
| 		This routine implements the rich semantics of C | 	 This routine implements the rich semantics of C | ||||||
| 		declarations. | 	 declarations. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct idf *idf = dc->dc_idf; | 	register struct idf *idf = dc->dc_idf; | ||||||
| 	register int sc = ds->ds_sc; | 	register int sc = ds->ds_sc; | ||||||
| 		/*	This local copy is essential:
 | 	/*	This local copy is essential:
 | ||||||
| 				char b(), c; | 	 char b(), c; | ||||||
| 			makes b GLOBAL and c AUTO. | 	 makes b GLOBAL and c AUTO. | ||||||
| 		*/ | 	 */ | ||||||
| 	register struct def *def = idf->id_def;		/* may be NULL */ | 	register struct def *def = idf->id_def; /* may be NULL */ | ||||||
| 	register struct type *type; | 	register struct type *type; | ||||||
| 	struct stack_level *stl = stack_level_of(lvl); | 	struct stack_level *stl = stack_level_of(lvl); | ||||||
| 	char formal_array = 0; | 	char formal_array = 0; | ||||||
| 	 | 
 | ||||||
| 	/* determine the present type */ | 	/* 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
 | 		/*	at the L_FORMAL1 level there is no type specified yet
 | ||||||
| 		*/ | 		 */ | ||||||
| 		assert(lvl == L_FORMAL1); | 		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 */ | 		/* combine the decspecs and the declarator into one type */ | ||||||
| 		type = declare_type(ds->ds_type, dc); | 		type = declare_type(ds->ds_type, dc); | ||||||
| 		if (type->tp_size <= (arith)0 && | 		if (type->tp_size <= (arith) 0 && actual_declaration(sc, type)) | ||||||
| 		    actual_declaration(sc, type))	{ | 		{ | ||||||
| 			if (type->tp_size == (arith) -1) { | 			if (type->tp_size == (arith) -1) | ||||||
|  | 			{ | ||||||
| 				/* the type is not yet known,
 | 				/* the type is not yet known,
 | ||||||
| 				   but it has to be: | 				 but it has to be: | ||||||
| 				*/ | 				 */ | ||||||
| 				if (type->tp_fund != VOID) { | 				if (type->tp_fund != VOID) | ||||||
| 				    if (level != L_GLOBAL) | 				{ | ||||||
| 					error("unknown %s-type", | 					if (level != L_GLOBAL) | ||||||
| 						symbol2str(type->tp_fund)); | 						error("unknown %s-type", symbol2str(type->tp_fund)); | ||||||
| 				} else	error("void is not a complete type"); | 				} | ||||||
|  | 				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 */ | 	/* some additional work for formal definitions */ | ||||||
| 	if (lvl == L_FORMAL2)	{ | 	if (lvl == L_FORMAL2) | ||||||
| 		switch (type->tp_fund)	{ | 	{ | ||||||
|  | 		switch (type->tp_fund) | ||||||
|  | 		{ | ||||||
| 		case FUNCTION: | 		case FUNCTION: | ||||||
| 			warning("%s is a function; cannot be formal", | 			warning("%s is a function; cannot be formal", idf->id_text); | ||||||
| 				idf->id_text); | 			type = construct_type(POINTER, type, 0, (arith) 0, | ||||||
| 			type = construct_type(POINTER, type, 0, (arith)0, | 			NO_PROTO); | ||||||
| 					      NO_PROTO); |  | ||||||
| 			break; | 			break; | ||||||
| 		case ARRAY:	/* 3.7.1 */ | 		case ARRAY: /* 3.7.1 */ | ||||||
| 			type = construct_type(POINTER, type->tp_up, 0, (arith)0, | 			type = construct_type(POINTER, type->tp_up, 0, (arith) 0, | ||||||
| 					      NO_PROTO); | 			NO_PROTO); | ||||||
| 			formal_array = 1; | 			formal_array = 1; | ||||||
| 			break; | 			break; | ||||||
| 		case FLOAT: | 		case FLOAT: | ||||||
|  | @ -135,72 +142,77 @@ declare_idf(ds, dc, lvl) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	/*	The tests on types, postponed from do_decspecs(), can now
 | 	/*	The tests on types, postponed from do_decspecs(), can now
 | ||||||
| 		be performed. | 	 be performed. | ||||||
| 	*/ | 	 */ | ||||||
| 	/* update the storage class */ | 	/* update the storage class */ | ||||||
| 	if (type && type->tp_fund == FUNCTION)	{ | 	if (type && type->tp_fund == FUNCTION) | ||||||
| 		if (lvl != L_GLOBAL)  {		/* 3.5.1 */ | 	{ | ||||||
|  | 		if (lvl != L_GLOBAL) | ||||||
|  | 		{ /* 3.5.1 */ | ||||||
| 			if (sc == 0) | 			if (sc == 0) | ||||||
| 				sc = GLOBAL; | 				sc = GLOBAL; | ||||||
| 			else if (sc != EXTERN && sc != TYPEDEF) { | 			else if (sc != EXTERN && sc != TYPEDEF) | ||||||
| 				error("illegal storage class %s for function with block-scope" | 			{ | ||||||
| 					, symbol2str(sc)); | 				error("illegal storage class %s for function with block-scope", | ||||||
|  | 						symbol2str(sc)); | ||||||
| 				ds->ds_sc = sc = EXTERN; | 				ds->ds_sc = sc = EXTERN; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else if (sc == 0) | 		else if (sc == 0) | ||||||
| 			sc = GLOBAL; | 			sc = GLOBAL; | ||||||
| 	} | 	} | ||||||
| 	else	/* non-FUNCTION */ | 	else /* non-FUNCTION */ | ||||||
| 		if (sc == 0) | 	if (sc == 0) | ||||||
| 			sc =	lvl == L_GLOBAL ? GLOBAL | 		sc = lvl == L_GLOBAL ? GLOBAL : | ||||||
| 				: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL | 				lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL : AUTO; | ||||||
| 				: AUTO; |  | ||||||
| 
 | 
 | ||||||
| #ifdef	LINT | #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 */ | #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); | 		error("%s redeclared", idf->id_text); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (def &&  | 	if (def | ||||||
| 	    ( def->df_level == lvl || | 			&& (def->df_level == lvl || (lvl != L_GLOBAL && def->df_level > lvl) | ||||||
| 	      ( lvl != L_GLOBAL && def->df_level > lvl ) || | 					|| (lvl == L_GLOBAL && def->df_level == L_PROTO && def->next | ||||||
| 	      (lvl == L_GLOBAL | 							&& def->next->df_level == L_GLOBAL))) | ||||||
| 	       && def->df_level == L_PROTO | 	{ | ||||||
| 	       && def->next && def->next->df_level == L_GLOBAL) |  | ||||||
| 	   ))	{ |  | ||||||
| 		/*	There is already a declaration for idf on this
 | 		/*	There is already a declaration for idf on this
 | ||||||
| 			level, or even more inside. | 		 level, or even more inside. | ||||||
| 			The rules differ for different levels. | 		 The rules differ for different levels. | ||||||
| 		*/ | 		 */ | ||||||
| 		switch (lvl)	{ | 		switch (lvl) | ||||||
|  | 		{ | ||||||
| 		case L_GLOBAL: | 		case L_GLOBAL: | ||||||
| 			global_redecl(idf, sc, type); | 			global_redecl(idf, sc, type); | ||||||
| 			def->df_file = idf->id_file; | 			def->df_file = idf->id_file; | ||||||
| 			def->df_line = idf->id_line; | 			def->df_line = idf->id_line; | ||||||
| 			break; | 			break; | ||||||
| 		case L_FORMAL1:	/* formal declaration */ | 		case L_FORMAL1: /* formal declaration */ | ||||||
| 			error("formal %s redeclared", idf->id_text); | 			error("formal %s redeclared", idf->id_text); | ||||||
| 			break; | 			break; | ||||||
| 		case L_FORMAL2:	/* formal definition */ | 		case L_FORMAL2: /* formal definition */ | ||||||
| 		default:	/* local */ | 		default: /* local */ | ||||||
| 			if (sc != EXTERN) error("%s redeclared", idf->id_text); | 			if (sc != EXTERN) | ||||||
|  | 				error("%s redeclared", idf->id_text); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else	/* the idf is unknown on this level */ | 	else /* the idf is unknown on this level */ | ||||||
| 	if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf))	{ | 	if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf)) | ||||||
|  | 	{ | ||||||
| 		/* formal declaration, update only */ | 		/* formal declaration, update only */ | ||||||
| 		def->df_type = type; | 		def->df_type = type; | ||||||
| 		def->df_formal_array = formal_array; | 		def->df_formal_array = formal_array; | ||||||
| 		def->df_sc = sc; | 		def->df_sc = sc; | ||||||
| 		def->df_level = L_FORMAL2;	/* CJ */ | 		def->df_level = L_FORMAL2; /* CJ */ | ||||||
| 		def->df_file = idf->id_file; | 		def->df_file = idf->id_file; | ||||||
| 		def->df_line = idf->id_line; | 		def->df_line = idf->id_line; | ||||||
| 	} | 	} | ||||||
| 	else	{ /* fill in the def block */ | 	else | ||||||
|  | 	{ /* fill in the def block */ | ||||||
| 		register struct def *newdef = new_def(); | 		register struct def *newdef = new_def(); | ||||||
| 
 | 
 | ||||||
| 		newdef->next = def; | 		newdef->next = def; | ||||||
|  | @ -218,28 +230,27 @@ declare_idf(ds, dc, lvl) | ||||||
| 		update_ahead(idf); | 		update_ahead(idf); | ||||||
| 		stack_idf(idf, stl); | 		stack_idf(idf, stl); | ||||||
| 		/*	We now calculate the address.
 | 		/*	We now calculate the address.
 | ||||||
| 			Globals have names and don't get addresses, they | 		 Globals have names and don't get addresses, they | ||||||
| 			get numbers instead (through data_label()). | 		 get numbers instead (through data_label()). | ||||||
| 			Formals are handled by declare_formals(). | 		 Formals are handled by declare_formals(). | ||||||
| 			So here we hand out local addresses only. | 		 So here we hand out local addresses only. | ||||||
| 		*/ | 		 */ | ||||||
| 		if (lvl >= L_LOCAL)	{ | 		if (lvl >= L_LOCAL) | ||||||
|  | 		{ | ||||||
| 			assert(sc); | 			assert(sc); | ||||||
| 			switch (sc)	{ | 			switch (sc) | ||||||
|  | 			{ | ||||||
| 			case REGISTER: | 			case REGISTER: | ||||||
| 			case AUTO: | 			case AUTO: | ||||||
| 				if (type->tp_size == (arith)-1 | 				if (type->tp_size == (arith) -1 && type->tp_fund != ARRAY) | ||||||
| 					&& type->tp_fund != ARRAY) { | 				{ | ||||||
| 					error("size of local %s unknown", | 					error("size of local %s unknown", idf->id_text); | ||||||
| 						idf->id_text); | 					/** type = idf->id_def->df_type = int_type; **/ | ||||||
| 				/** type = idf->id_def->df_type = int_type; **/ |  | ||||||
| 				} | 				} | ||||||
| 				if (type->tp_size != (arith) -1) { | 				if (type->tp_size != (arith) -1) | ||||||
| 				    newdef->df_address = | 				{ | ||||||
| 					NewLocal(type->tp_size, | 					newdef->df_address = NewLocal(type->tp_size, type->tp_align, | ||||||
| 						 type->tp_align, | 							regtype(type), sc); | ||||||
| 						 regtype(type), |  | ||||||
| 						 sc); |  | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case STATIC: | 			case STATIC: | ||||||
|  | @ -250,21 +261,19 @@ declare_idf(ds, dc, lvl) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int actual_declaration(int sc, struct type *tp) | ||||||
| actual_declaration(sc, tp) |  | ||||||
| 	int sc; |  | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	An actual_declaration needs space, right here and now.
 | 	/*	An actual_declaration needs space, right here and now.
 | ||||||
| 	*/ | 	 */ | ||||||
| 	register int fund = tp->tp_fund; | 	register int fund = tp->tp_fund; | ||||||
| 	 | 
 | ||||||
| 	if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */ | 	if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */ | ||||||
| 		return 0; | 		return 0; | ||||||
| 	if (fund == FUNCTION || fund == ARRAY) | 	if (fund == FUNCTION || fund == ARRAY) | ||||||
| 		/* allocation solved in other ways */ | 		/* allocation solved in other ways */ | ||||||
| 		return 0; | 		return 0; | ||||||
| 	if (sc == EXTERN && fund == VOID) { | 	if (sc == EXTERN && fund == VOID) | ||||||
|  | 	{ | ||||||
| 		/* strange, but should be accepted */ | 		/* strange, but should be accepted */ | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  | @ -272,51 +281,59 @@ actual_declaration(sc, tp) | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void global_redecl(register struct idf *idf, int new_sc, struct type *tp) | ||||||
| global_redecl(idf, new_sc, tp) |  | ||||||
| 	register struct idf *idf; |  | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	A global identifier may be declared several times,
 | 	/*	A global identifier may be declared several times,
 | ||||||
| 		provided the declarations do not conflict; they might | 	 provided the declarations do not conflict; they might | ||||||
| 		conflict in type (or supplement each other in the case of | 	 conflict in type (or supplement each other in the case of | ||||||
| 		an array) or they might conflict or supplement each other | 	 an array) or they might conflict or supplement each other | ||||||
| 		in storage class. | 	 in storage class. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct def *def = idf->id_def; | 	register struct def *def = idf->id_def; | ||||||
| 
 | 
 | ||||||
| 	while (def->df_level != L_GLOBAL) def = def->next; | 	while (def->df_level != L_GLOBAL) | ||||||
| 	if (!equal_type(tp, def->df_type, 0, 1)) { | 		def = def->next; | ||||||
|  | 	if (!equal_type(tp, def->df_type, 0, 1)) | ||||||
|  | 	{ | ||||||
| 		error("redeclaration of %s with different type", idf->id_text); | 		error("redeclaration of %s with different type", idf->id_text); | ||||||
| 		return; | 		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 */ | 		/* 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 */ | 			/* 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; | 			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 */ | 		/* see 3.1.2.2 */ | ||||||
| 		new_sc = EXTERN; | 		new_sc = EXTERN; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*	Now we may be able to update the storage class.
 | 	/*	Now we may be able to update the storage class.
 | ||||||
| 		Clean out this mess as soon as we know all the possibilities | 	 Clean out this mess as soon as we know all the possibilities | ||||||
| 		for new_sc. | 	 for new_sc. | ||||||
| 		For now we have: | 	 For now we have: | ||||||
| 			EXTERN:		we have seen the word "extern" | 	 EXTERN:		we have seen the word "extern" | ||||||
| 			GLOBAL:		the item was declared on the outer | 	 GLOBAL:		the item was declared on the outer | ||||||
| 					level, without either "extern" or | 	 level, without either "extern" or | ||||||
| 					"static". | 	 "static". | ||||||
| 			STATIC:		we have seen the word "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: | 	case EXTERN: | ||||||
| 		switch (new_sc)	{	/* the new storage class */ | 		switch (new_sc) | ||||||
|  | 		{ /* the new storage class */ | ||||||
| 		case STATIC: | 		case STATIC: | ||||||
| 			warning("%s redeclared static", idf->id_text); | 			warning("%s redeclared static", idf->id_text); | ||||||
| 			/* fallthrough */ | 			/* fallthrough */ | ||||||
|  | @ -331,8 +348,9 @@ global_redecl(idf, new_sc, tp) | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case GLOBAL: | 	case GLOBAL: | ||||||
| 		switch (new_sc)	{	/* the new storage class */ | 		switch (new_sc) | ||||||
| 		case STATIC:		/* linkage disagreement */ | 		{ /* the new storage class */ | ||||||
|  | 		case STATIC: /* linkage disagreement */ | ||||||
| 			warning("%s redeclared static", idf->id_text); | 			warning("%s redeclared static", idf->id_text); | ||||||
| 			def->df_sc = new_sc; | 			def->df_sc = new_sc; | ||||||
| 			/* fallthrough */ | 			/* fallthrough */ | ||||||
|  | @ -345,8 +363,9 @@ global_redecl(idf, new_sc, tp) | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case STATIC: | 	case STATIC: | ||||||
| 		switch (new_sc)	{	/* the new storage class */ | 		switch (new_sc) | ||||||
| 		case GLOBAL:		/* linkage disagreement */ | 		{ /* the new storage class */ | ||||||
|  | 		case GLOBAL: /* linkage disagreement */ | ||||||
| 		case EXTERN: | 		case EXTERN: | ||||||
| 			warning("%s is already declared static", idf->id_text); | 			warning("%s is already declared static", idf->id_text); | ||||||
| 			/* fallthrough */ | 			/* fallthrough */ | ||||||
|  | @ -367,142 +386,147 @@ global_redecl(idf, new_sc, tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int good_formal(register struct def *def, register struct idf *idf) | ||||||
| good_formal(def, idf) |  | ||||||
| 	register struct def *def; |  | ||||||
| 	register struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	Succeeds if def is a proper L_FORMAL1 definition and
 | 	/*	Succeeds if def is a proper L_FORMAL1 definition and
 | ||||||
| 		gives an error message otherwise. | 	 gives an error message otherwise. | ||||||
| 	*/ | 	 */ | ||||||
| 	if (!def || def->df_level != L_FORMAL1)	{ /* not in parameter list */ | 	if (!def || def->df_level != L_FORMAL1) | ||||||
|  | 	{ /* not in parameter list */ | ||||||
| 		if (!is_anon_idf(idf)) | 		if (!is_anon_idf(idf)) | ||||||
| 			error("%s not in parameter list", idf->id_text); | 			error("%s not in parameter list", idf->id_text); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	assert(def->df_sc == FORMAL);	/* CJ */ | 	assert(def->df_sc == FORMAL); /* CJ */ | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| declare_params(dc) | void declare_params(struct declarator *dc) | ||||||
| 	struct declarator *dc; |  | ||||||
| { | { | ||||||
| 	/*	Declares the formal parameters if they exist.
 | 	/*	Declares the formal parameters if they exist.
 | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct formal *fm = dc->dc_formal; | 	register struct formal *fm = dc->dc_formal; | ||||||
| 
 | 
 | ||||||
| 	while (fm)	{ | 	while (fm) | ||||||
|  | 	{ | ||||||
| 		declare_parameter(fm->fm_idf); | 		declare_parameter(fm->fm_idf); | ||||||
| 		fm = fm->next; | 		fm = fm->next; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void idf_initialized(register struct idf *idf) | ||||||
| idf_initialized(idf) |  | ||||||
| 	register struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	The topmost definition of idf is set to initialized.
 | 	/*	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) | 	if (def->df_initialized) | ||||||
| 		error("multiple initialization of %s", idf->id_text); | 		error("multiple initialization of %s", idf->id_text); | ||||||
| 	if (def->df_sc == TYPEDEF)	{ | 	if (def->df_sc == TYPEDEF) | ||||||
|  | 	{ | ||||||
| 		error("typedef cannot be initialized"); | 		error("typedef cannot be initialized"); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	def->df_initialized = 1; | 	def->df_initialized = 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| declare_parameter(idf) | void declare_parameter(struct idf *idf) | ||||||
| 	struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	idf is declared as a formal.
 | 	/*	idf is declared as a formal.
 | ||||||
| 	*/ | 	 */ | ||||||
| 	add_def(idf, FORMAL, int_type, level); | 	add_def(idf, FORMAL, int_type, level); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| declare_enum(tp, idf, l) | void declare_enum(struct type *tp, struct idf *idf, arith l) | ||||||
| 	struct type *tp; |  | ||||||
| 	struct idf *idf; |  | ||||||
| 	arith l; |  | ||||||
| { | { | ||||||
| 	/*	idf is declared as an enum constant with value l.
 | 	/*	idf is declared as an enum constant with value l.
 | ||||||
| 	*/ | 	 */ | ||||||
| 	add_def(idf, ENUM, tp, level); | 	add_def(idf, ENUM, tp, level); | ||||||
| 	idf->id_def->df_address = l; | 	idf->id_def->df_address = l; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void check_formals(struct idf *idf, struct declarator *dc) | ||||||
| check_formals(idf, dc) |  | ||||||
| 	struct idf *idf; |  | ||||||
| 	struct declarator *dc; |  | ||||||
| { | { | ||||||
| 	register struct formal *fm = dc->dc_formal; | 	register struct formal *fm = dc->dc_formal; | ||||||
| 	register struct proto *pl = idf->id_def->df_type->tp_proto; | 	register struct proto *pl = idf->id_def->df_type->tp_proto; | ||||||
| 	register struct decl_unary *du = dc->dc_decl_unary; | 	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); | 		error("illegal definition of %s", idf->id_text); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	while (du | 	while (du | ||||||
| 		&& (du->du_fund != FUNCTION | 			&& (du->du_fund != FUNCTION || du->next != (struct decl_unary *) 0)) | ||||||
| 		    || du->next != (struct decl_unary *) 0)) { | 	{ | ||||||
| 		du = du->next; | 		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,
 | 		/* Don't give a warning about an old-style definition,
 | ||||||
| 		 * since the arguments will be checked anyway. | 		 * since the arguments will be checked anyway. | ||||||
| 		 */ | 		 */ | ||||||
| 		if (pl->pl_flag & PL_ELLIPSIS) { | 		if (pl->pl_flag & PL_ELLIPSIS) | ||||||
| 		    if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN)) | 		{ | ||||||
| 			error("ellipsis terminator in previous declaration"); | 			if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN)) | ||||||
| 		    pl = pl->next; | 				error("ellipsis terminator in previous declaration"); | ||||||
|  | 			pl = pl->next; | ||||||
| 		} | 		} | ||||||
| 		else if (pl->pl_flag & PL_VOID) { | 		else if (pl->pl_flag & PL_VOID) | ||||||
| 		    pl = pl->next;			/* should be 0 */ | 		{ | ||||||
|  | 			pl = pl->next; /* should be 0 */ | ||||||
| 		} | 		} | ||||||
| 		while(fm && pl) { | 		while (fm && pl) | ||||||
| 		    if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type) | 		{ | ||||||
| 					, pl->pl_type, -1, 1)) { | 			if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type), | ||||||
| 			if (!(pl->pl_flag & PL_ERRGIVEN)) | 					pl->pl_type, -1, 1)) | ||||||
| 			    error("incorrect type for parameter %s" | 			{ | ||||||
| 						, fm->fm_idf->id_text); | 				if (!(pl->pl_flag & PL_ERRGIVEN)) | ||||||
| 			pl->pl_flag |= PL_ERRGIVEN; | 					error("incorrect type for parameter %s", | ||||||
| 		    } | 							fm->fm_idf->id_text); | ||||||
| 		    fm = fm->next; | 				pl->pl_flag |= PL_ERRGIVEN; | ||||||
| 		    pl = pl->next; | 			} | ||||||
|  | 			fm = fm->next; | ||||||
|  | 			pl = pl->next; | ||||||
| 		} | 		} | ||||||
| 		if (pl || fm) { | 		if (pl || fm) | ||||||
|  | 		{ | ||||||
| 			error("incorrect number of parameters"); | 			error("incorrect number of parameters"); | ||||||
| 		} | 		} | ||||||
| 	} else {			/* make a pseudo-prototype */ | 	} | ||||||
|  | 	else | ||||||
|  | 	{ /* make a pseudo-prototype */ | ||||||
| 		register struct proto *lpl = new_proto(); | 		register struct proto *lpl = new_proto(); | ||||||
| 
 | 
 | ||||||
| 		if (!options['o']) | 		if (!options['o']) | ||||||
| 			warning("'%s' old-fashioned function definition" | 			warning("'%s' old-fashioned function definition", | ||||||
| 					, dc->dc_idf->id_text); | 					dc->dc_idf->id_text); | ||||||
| 
 | 
 | ||||||
| 		while (fm) { | 		while (fm) | ||||||
| 			if (pl == 0) pl = lpl; | 		{ | ||||||
| 			else { | 			if (pl == 0) | ||||||
|  | 				pl = lpl; | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
| 				lpl->next = new_proto(); | 				lpl->next = new_proto(); | ||||||
| 				lpl = lpl->next; | 				lpl = lpl->next; | ||||||
| 			} | 			} | ||||||
| 			lpl->pl_flag = PL_FORMAL; | 			lpl->pl_flag = PL_FORMAL; | ||||||
| 			lpl->pl_idf = fm->fm_idf; | 			lpl->pl_idf = fm->fm_idf; | ||||||
| 			lpl->pl_type = | 			lpl->pl_type = promoted_type(fm->fm_idf->id_def->df_type); | ||||||
| 				    promoted_type(fm->fm_idf->id_def->df_type); |  | ||||||
| 			fm = fm->next; | 			fm = fm->next; | ||||||
| 		} | 		} | ||||||
| 		if (pl == 0) {		/* make func(void) */ | 		if (pl == 0) | ||||||
|  | 		{ /* make func(void) */ | ||||||
| 			pl = lpl; | 			pl = lpl; | ||||||
| 			pl->pl_type = void_type; | 			pl->pl_type = void_type; | ||||||
| 			pl->pl_flag = PL_FORMAL | PL_VOID; | 			pl->pl_flag = PL_FORMAL | PL_VOID; | ||||||
|  | @ -513,26 +537,26 @@ check_formals(idf, dc) | ||||||
| 	dc->dc_formal = 0; | 	dc->dc_formal = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| declare_formals(idf, fp) | void declare_formals(struct idf *idf, arith *fp) | ||||||
| 	struct idf *idf; |  | ||||||
| 	arith *fp; |  | ||||||
| { | { | ||||||
| 	/*	Declares those formals as int that haven't been declared
 | 	/*	Declares those formals as int that haven't been declared
 | ||||||
| 		by the user. | 	 by the user. | ||||||
| 		An address is assigned to each formal parameter. | 	 An address is assigned to each formal parameter. | ||||||
| 		The total size of the formals is returned in *fp; | 	 The total size of the formals is returned in *fp; | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry; | 	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; | 	register int nparams = 0; | ||||||
| 	int hasproto; | 	int hasproto; | ||||||
| 	struct def *df = idf->id_def; | 	struct def *df = idf->id_def; | ||||||
| 
 | 
 | ||||||
| 	/* When one of the formals has the same name as the function, 
 | 	/* When one of the formals has the same name as the function, 
 | ||||||
| 	   it hides the function def. Get it. | 	 it hides the function def. Get it. | ||||||
| 	*/ | 	 */ | ||||||
| 	while (se) { | 	while (se) | ||||||
| 		if (se->se_idf == idf) { | 	{ | ||||||
|  | 		if (se->se_idf == idf) | ||||||
|  | 		{ | ||||||
| 			df = df->next; | 			df = df->next; | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | @ -540,49 +564,53 @@ declare_formals(idf, fp) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	se = stack_level_of(L_FORMAL1)->sl_entry; | 	se = stack_level_of(L_FORMAL1)->sl_entry; | ||||||
| 	 | 
 | ||||||
| 	hasproto = df->df_type->tp_proto != 0; | 	hasproto = df->df_type->tp_proto != 0; | ||||||
| 
 | 
 | ||||||
| #ifdef	DEBUG | #ifdef	DEBUG | ||||||
| 	if (options['t']) | 	if (options['t']) | ||||||
| 		dumpidftab("start declare_formals", 0); | 	dumpidftab("start declare_formals", 0); | ||||||
| #endif	/* DEBUG */ | #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 */ | 		/* create space for address of return value */ | ||||||
| 		f_offset = pointer_size; | 		f_offset = pointer_size; | ||||||
| 	} | 	} | ||||||
| 	while (se)	{ | 	while (se) | ||||||
|  | 	{ | ||||||
| 		df = se->se_idf->id_def; | 		df = se->se_idf->id_def; | ||||||
| 		 | 
 | ||||||
| 		/* this stacklevel may also contain tags. ignore them */ | 		/* 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; | 			se = se->next; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		df->df_address = f_offset; | 		df->df_address = f_offset; | ||||||
| 		/*	the alignment convention for parameters is: align on
 | 		/*	the alignment convention for parameters is: align on
 | ||||||
| 			word boundaries, i.e. take care that the following | 		 word boundaries, i.e. take care that the following | ||||||
| 			parameter starts on a new word boundary. | 		 parameter starts on a new word boundary. | ||||||
| 		*/ | 		 */ | ||||||
| 		if (! hasproto  | 		if (!hasproto && df->df_type->tp_fund == FLOAT | ||||||
| 		    && df->df_type->tp_fund == FLOAT | 				&& df->df_type->tp_size != double_size) | ||||||
| 		    && df->df_type->tp_size != double_size) { | 		{ | ||||||
| 			f_offset = align(f_offset + double_size, (int) word_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, | 		RegisterAccount(df->df_address, df->df_type->tp_size, | ||||||
| 				regtype(df->df_type), | 				regtype(df->df_type), df->df_sc); | ||||||
| 				df->df_sc); |  | ||||||
| 		/* cvt int to char or short and double to float, if necessary
 | 		/* cvt int to char or short and double to float, if necessary
 | ||||||
| 		 */ | 		 */ | ||||||
| 		formal_cvt(hasproto, df); | 		formal_cvt(hasproto, df); | ||||||
| 
 | 
 | ||||||
| 		df->df_level = L_FORMAL2;	/* CJ */ | 		df->df_level = L_FORMAL2; /* CJ */ | ||||||
| 		if (nparams++ >= STDC_NPARAMS) | 		if (nparams++ >= STDC_NPARAMS) | ||||||
| 			strict("number of formal parameters exceeds ANSI limit"); | 			strict("number of formal parameters exceeds ANSI limit"); | ||||||
| #ifdef DBSYMTAB | #ifdef DBSYMTAB | ||||||
| 		if (options['g']) { | 		if (options['g']) | ||||||
|  | 		{ | ||||||
| 			stb_string(df, FORMAL, se->se_idf->id_text); | 			stb_string(df, FORMAL, se->se_idf->id_text); | ||||||
| 		} | 		} | ||||||
| #endif /* DBSYMTAB */ | #endif /* DBSYMTAB */ | ||||||
|  | @ -591,11 +619,10 @@ declare_formals(idf, fp) | ||||||
| 	*fp = f_offset; | 	*fp = f_offset; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int regtype(struct type *tp) | ||||||
| regtype(tp) |  | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	switch(tp->tp_fund) { | 	switch (tp->tp_fund) | ||||||
|  | 	{ | ||||||
| 	case INT: | 	case INT: | ||||||
| 	case LONG: | 	case LONG: | ||||||
| 		return reg_any; | 		return reg_any; | ||||||
|  | @ -609,18 +636,15 @@ regtype(tp) | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| add_def(idf, sc, tp, lvl) | void add_def(struct idf *idf, int sc, struct type *tp, int lvl) | ||||||
| 	struct idf *idf; |  | ||||||
| 	struct type *tp; |  | ||||||
| 	int lvl; |  | ||||||
| 	int sc; |  | ||||||
| { | { | ||||||
| 	/*	The identifier idf is declared on level lvl with storage
 | 	/*	The identifier idf is declared on level lvl with storage
 | ||||||
| 		class sc and type tp, through a faked C declaration. | 	 class sc and type tp, through a faked C declaration. | ||||||
| 		This is probably the wrong way to structure the problem, | 	 This is probably the wrong way to structure the problem, | ||||||
| 		but it will have to do for the time being. | 	 but it will have to do for the time being. | ||||||
| 	*/ | 	 */ | ||||||
| 	struct decspecs Ds; struct declarator Dc; | 	struct decspecs Ds; | ||||||
|  | 	struct declarator Dc; | ||||||
| 
 | 
 | ||||||
| 	Ds = null_decspecs; | 	Ds = null_decspecs; | ||||||
| 	Ds.ds_type = tp; | 	Ds.ds_type = tp; | ||||||
|  | @ -630,25 +654,24 @@ add_def(idf, sc, tp, lvl) | ||||||
| 	declare_idf(&Ds, &Dc, lvl); | 	declare_idf(&Ds, &Dc, lvl); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| update_ahead(idf) | void update_ahead(register struct idf *idf) | ||||||
| 	register struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	The tk_symb of the token ahead is updated in the light of new
 | 	/*	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; | 	register int tk_symb = AHEAD; | ||||||
| 
 | 
 | ||||||
| 	if (	(tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) && | 	if ((tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) | ||||||
| 		ahead.tk_idf == idf | 			&& ahead.tk_idf == idf) | ||||||
| 	) |  | ||||||
| 		AHEAD = idf->id_def && idf->id_def->df_sc == TYPEDEF ? | 		AHEAD = idf->id_def && idf->id_def->df_sc == TYPEDEF ? | ||||||
| 				TYPE_IDENTIFIER : IDENTIFIER; | 		TYPE_IDENTIFIER : | ||||||
|  | 																IDENTIFIER; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| free_formals(fm) | void free_formals(register struct formal *fm) | ||||||
| 	register struct formal *fm; |  | ||||||
| { | { | ||||||
| 	while (fm)	{ | 	while (fm) | ||||||
|  | 	{ | ||||||
| 		struct formal *tmp = fm->next; | 		struct formal *tmp = fm->next; | ||||||
| 
 | 
 | ||||||
| 		free_formal(fm); | 		free_formal(fm); | ||||||
|  |  | ||||||
|  | @ -2,10 +2,15 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef IDF_H_ | ||||||
|  | #define IDF_H_ | ||||||
|  | 
 | ||||||
|  |   | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* IDENTIFIER DESCRIPTOR */ | /* IDENTIFIER DESCRIPTOR */ | ||||||
| 
 | 
 | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
|  | #include    "arith.h" | ||||||
| 
 | 
 | ||||||
| struct id_u { | struct id_u { | ||||||
| 	int idd_reserved;	/* non-zero for reserved words		*/ | 	int idd_reserved;	/* non-zero for reserved words		*/ | ||||||
|  | @ -33,4 +38,28 @@ struct id_u { | ||||||
| #include <idf_pkg.spec> | #include <idf_pkg.spec> | ||||||
| 
 | 
 | ||||||
| extern int level; | 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 <string.h> | ||||||
| #include "file_info.h" | #include "file_info.h" | ||||||
| #include "input.h" | #include "input.h" | ||||||
|  | #include "error.h" | ||||||
| 
 | 
 | ||||||
| #define INP_PUSHBACK	3 | #define INP_PUSHBACK	3 | ||||||
| #define INP_TYPE	struct file_info | #define INP_TYPE	struct file_info | ||||||
|  | @ -20,14 +21,14 @@ struct file_info	finfo; | ||||||
| 
 | 
 | ||||||
| int	NoUnstack; | int	NoUnstack; | ||||||
| 
 | 
 | ||||||
| AtEoIT() | int AtEoIT(void) | ||||||
| { | { | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| extern char *source; | extern char *source; | ||||||
| 
 | 
 | ||||||
| AtEoIF() | int AtEoIF(void) | ||||||
| { | { | ||||||
| 	if (NoUnstack) lexerror("unexpected EOF"); | 	if (NoUnstack) lexerror("unexpected EOF"); | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -12,4 +12,4 @@ | ||||||
| #define UnGetChar()	((LexSave != EOI) ? ChPushBack(LexSave) : 0) | #define UnGetChar()	((LexSave != EOI) ? ChPushBack(LexSave) : 0) | ||||||
| 
 | 
 | ||||||
| extern	int LexSave;	/* last character read by GetChar		*/ | extern	int LexSave;	/* last character read by GetChar		*/ | ||||||
| extern 	int GetChar();	/* character input, with trigraph parsing	*/ | 
 | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -14,11 +14,12 @@ | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"stack.h" | #include	"stack.h" | ||||||
|  | #include    "error.h" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| 
 | 
 | ||||||
| enter_label(idf, defining) | void enter_label(register struct idf *idf, int defining) | ||||||
| 	register struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	The identifier idf is entered as a label. If it is new,
 | 	/*	The identifier idf is entered as a label. If it is new,
 | ||||||
| 		it is entered into the idf list with the largest possible | 		it is entered into the idf list with the largest possible | ||||||
|  | @ -45,8 +46,7 @@ enter_label(idf, defining) | ||||||
| 		def->df_initialized = 1; | 		def->df_initialized = 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unstack_label(idf) | void unstack_label(register struct idf *idf) | ||||||
| 	register struct idf *idf; |  | ||||||
| { | { | ||||||
| 	/*	The scope in which the label idf occurred is left.
 | 	/*	The scope in which the label idf occurred is left.
 | ||||||
| 	*/ | 	*/ | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /*		L A B E L   D E F I N I T I O N				*/ | /*		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" */ | #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 | 		not be there, and if it is there, it may be from a | ||||||
| 		declaration or another application. | 		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	"specials.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
|  | #include    "stack.h" | ||||||
| #include	"macro.h" | #include	"macro.h" | ||||||
|  | #include    "options.h" | ||||||
|  | #include    "error.h" | ||||||
|  | #include    "code.h" | ||||||
|  | #include    "cstoper.h" | ||||||
|  | #include    "tokenname.h" | ||||||
| 
 | 
 | ||||||
| extern struct tokenname tkidf[]; | extern struct tokenname tkidf[]; | ||||||
| extern char *symbol2str(); | extern char *symbol2str(); | ||||||
|  | @ -34,7 +40,15 @@ struct sp_id special_ids[] =	{ | ||||||
| 	{0, 0} | 	{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 | #ifndef NOCROSS | ||||||
| arith | arith | ||||||
|  | @ -63,8 +77,7 @@ int | ||||||
| 
 | 
 | ||||||
| char *prog_name; | char *prog_name; | ||||||
| 
 | 
 | ||||||
| main(argc, argv) | int main(int argc, char *argv[]) | ||||||
| 	char *argv[]; |  | ||||||
| { | { | ||||||
| 	/* parse and interpret the command line options	*/ | 	/* parse and interpret the command line options	*/ | ||||||
| 	prog_name = argv[0]; | 	prog_name = argv[0]; | ||||||
|  | @ -104,8 +117,7 @@ char *source = 0; | ||||||
| char *nmlist = 0; | char *nmlist = 0; | ||||||
| #endif /* GEN_NM_LIST */ | #endif /* GEN_NM_LIST */ | ||||||
| 
 | 
 | ||||||
| compile(argc, argv) | void compile(int argc, char *argv[]) | ||||||
| 	char *argv[]; |  | ||||||
| { | { | ||||||
| 	char *result; | 	char *result; | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
|  | @ -190,7 +202,7 @@ compile(argc, argv) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| init() | static void init(void) | ||||||
| { | { | ||||||
| 	init_cst();	/* initialize variables of "cstoper.c"		*/ | 	init_cst();	/* initialize variables of "cstoper.c"		*/ | ||||||
| 	reserve(tkidf);		/* mark the C reserved words as such	*/ | 	reserve(tkidf);		/* mark the C reserved words as such	*/ | ||||||
|  | @ -255,8 +267,7 @@ init() | ||||||
| 	stack_level(); | 	stack_level(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| init_specials(si) | static void init_specials(register struct sp_id *si) | ||||||
| 	register struct sp_id *si; |  | ||||||
| { | { | ||||||
| 	while (si->si_identifier)	{ | 	while (si->si_identifier)	{ | ||||||
| 		struct idf *idf = str2idf(si->si_identifier, 0); | 		struct idf *idf = str2idf(si->si_identifier, 0); | ||||||
|  | @ -269,7 +280,7 @@ init_specials(si) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| Info() | void Info(void) | ||||||
| { | { | ||||||
| 	extern int cnt_string_cst, cnt_formal, | 	extern int cnt_string_cst, cnt_formal, | ||||||
| 		    cnt_decl_unary, cnt_def, cnt_expr, cnt_field, | 		    cnt_decl_unary, cnt_def, cnt_expr, cnt_field, | ||||||
|  | @ -301,14 +312,12 @@ Info() | ||||||
| } | } | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| void | void No_Mem(void)				/* called by alloc package */ | ||||||
| No_Mem()				/* called by alloc package */ |  | ||||||
| { | { | ||||||
| 	fatal("out of memory"); | 	fatal("out of memory"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void C_failed(void)				/* called by EM_code module */ | ||||||
| C_failed()				/* called by EM_code module */ |  | ||||||
| { | { | ||||||
| 	fatal("write failed"); | 	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	<stdlib.h> | ||||||
| #include	<string.h> | #include	<string.h> | ||||||
| #include	<alloc.h> | #include	<alloc.h> | ||||||
|  | #include    "options.h" | ||||||
| #include	"class.h" | #include	"class.h" | ||||||
| #include	"macro.h" | #include	"macro.h" | ||||||
| #include	"idf.h" | #include	"idf.h" | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| char options[128];			/* one for every char	*/ | char options[128];			/* one for every char	*/ | ||||||
| #ifdef	LINT | #ifdef	LINT | ||||||
|  | @ -24,10 +26,11 @@ char loptions[128];			/* one for every char	*/ | ||||||
| extern int idfsize; | extern int idfsize; | ||||||
| extern int density; | extern int density; | ||||||
| 
 | 
 | ||||||
| static int txt2int(); |  | ||||||
| 
 | 
 | ||||||
| do_option(text) | 
 | ||||||
| 	char *text; | static int txt2int(register char **); | ||||||
|  | 
 | ||||||
|  | void do_option(char *text) | ||||||
| { | { | ||||||
| 	register char opt; | 	register char opt; | ||||||
| 
 | 
 | ||||||
|  | @ -209,9 +212,7 @@ next_option:			/* to allow combined one-char options */ | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int txt2int(register char **tp) | ||||||
| txt2int(tp) |  | ||||||
| 	register char **tp; |  | ||||||
| { | { | ||||||
| 	/*	the integer pointed to by *tp is read, while increasing
 | 	/*	the integer pointed to by *tp is read, while increasing
 | ||||||
| 		*tp; the resulting value is yielded. | 		*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 */ | /* PREPROCESSOR: PRAGMA INTERPRETER */ | ||||||
| 
 | 
 | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
|  | #include    "pragma.h" | ||||||
|  | #include    "skip.h" | ||||||
| 
 | 
 | ||||||
| #define P_UNKNOWN	0 | #define P_UNKNOWN	0 | ||||||
| #define NR_PRAGMAS	0 | #define NR_PRAGMAS	0 | ||||||
| 
 | 
 | ||||||
| struct pkey { | struct pkey | ||||||
|  | { | ||||||
| 	char *pk_name; | 	char *pk_name; | ||||||
| 	int pk_key; | 	int pk_key; | ||||||
| } pragmas[NR_PRAGMAS + 1] = { | } pragmas[NR_PRAGMAS + 1] = | ||||||
| 	{0,		P_UNKNOWN} | { | ||||||
| }; | { 0, P_UNKNOWN } }; | ||||||
| 
 | 
 | ||||||
| extern struct idf *GetIdentifier(); | extern struct idf *GetIdentifier(); | ||||||
| 
 | 
 | ||||||
| do_pragma() | void do_pragma(void) | ||||||
| { | { | ||||||
| #if	NR_PRAGMAS | #if	NR_PRAGMAS | ||||||
| 	register struct pkey *pkp = &pragmas[0]; | 	register struct pkey *pkp = &pragmas[0]; | ||||||
| #endif | #endif | ||||||
| 	register struct idf *id = GetIdentifier(1); | 	register struct idf *id = GetIdentifier(1); | ||||||
| 
 | 
 | ||||||
| 	if (id != (struct idf *)0) { | 	if (id != (struct idf *) 0) | ||||||
|  | 	{ | ||||||
| #if	NR_PRAGMAS | #if	NR_PRAGMAS | ||||||
| 		while(pkp->pk_name) { | 		while(pkp->pk_name) | ||||||
|  | 		{ | ||||||
| 			if (strcmp(pkp->pk_name, id->id_text) == 0) | 			if (strcmp(pkp->pk_name, id->id_text) == 0) | ||||||
| 				break; | 			break; | ||||||
| 			pkp++; | 			pkp++; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		switch (pkp->pk_key) { | 		switch (pkp->pk_key) | ||||||
| 		case P_UNKNOWN: | 		{ | ||||||
| 		default: | 			case P_UNKNOWN: | ||||||
|  | 			default: | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| #endif | #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_ */ | ||||||
|  | @ -1,224 +1,227 @@ | ||||||
| /* | /* | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* PROGRAM PARSER */ | /* PROGRAM PARSER */ | ||||||
| 
 | 
 | ||||||
| /*	The presence of typedef declarations renders it impossible to | /*	The presence of typedef declarations renders it impossible to | ||||||
| 	make a context-free grammar of C. Consequently we need | 	make a context-free grammar of C. Consequently we need | ||||||
| 	context-sensitive parsing techniques, the simplest one being | 	context-sensitive parsing techniques, the simplest one being | ||||||
| 	a subtle cooperation between the parser and the lexical scanner. | 	a subtle cooperation between the parser and the lexical scanner. | ||||||
| 	The lexical scanner has to know whether to return IDENTIFIER | 	The lexical scanner has to know whether to return IDENTIFIER | ||||||
| 	or TYPE_IDENTIFIER for a given tag, and it obtains this information | 	or TYPE_IDENTIFIER for a given tag, and it obtains this information | ||||||
| 	from the definition list, as constructed by the parser. | 	from the definition list, as constructed by the parser. | ||||||
| 	The present grammar is essentially LL(2), and is processed by | 	The present grammar is essentially LL(2), and is processed by | ||||||
| 	a parser generator which accepts LL(1) with tie breaking rules | 	a parser generator which accepts LL(1) with tie breaking rules | ||||||
| 	in C, of the form %if(cond) and %while(cond). To solve the LL(1) | 	in C, of the form %if(cond) and %while(cond). To solve the LL(1) | ||||||
| 	ambiguities, the lexical scanner does a one symbol look-ahead. | 	ambiguities, the lexical scanner does a one symbol look-ahead. | ||||||
| 	This symbol, however, cannot always be correctly assessed, since | 	This symbol, however, cannot always be correctly assessed, since | ||||||
| 	the present symbol may cause a change in the definition list | 	the present symbol may cause a change in the definition list | ||||||
| 	which causes the identification of the look-ahead symbol to be | 	which causes the identification of the look-ahead symbol to be | ||||||
| 	invalidated. | 	invalidated. | ||||||
| 	The lexical scanner relies on the parser (or its routines) to | 	The lexical scanner relies on the parser (or its routines) to | ||||||
| 	detect this situation and then update the look-ahead symbol. | 	detect this situation and then update the look-ahead symbol. | ||||||
| 	An alternative approach would be to reassess the look-ahead symbol | 	An alternative approach would be to reassess the look-ahead symbol | ||||||
| 	in the lexical scanner when it is promoted to dot symbol. This | 	in the lexical scanner when it is promoted to dot symbol. This | ||||||
| 	would be more beautiful but less correct, since then for a short | 	would be more beautiful but less correct, since then for a short | ||||||
| 	while there would be a discrepancy between the look-ahead symbol | 	while there would be a discrepancy between the look-ahead symbol | ||||||
| 	and the definition list; I think it would nevertheless work in | 	and the definition list; I think it would nevertheless work in | ||||||
| 	correct programs. | 	correct programs. | ||||||
| 	A third solution would be to enter the identifier as soon as it | 	A third solution would be to enter the identifier as soon as it | ||||||
| 	is found; its storage class is then known, although its full type | 	is found; its storage class is then known, although its full type | ||||||
| 	isn't. We would have to fill that in afterwards. | 	isn't. We would have to fill that in afterwards. | ||||||
| 
 | 
 | ||||||
| 	At block exit the situation is even worse. Upon reading the | 	At block exit the situation is even worse. Upon reading the | ||||||
| 	closing brace, the names declared inside the function are cleared | 	closing brace, the names declared inside the function are cleared | ||||||
| 	from the name list. This action may expose a type identifier that | 	from the name list. This action may expose a type identifier that | ||||||
| 	is the same as the identifier in the look-ahead symbol. This | 	is the same as the identifier in the look-ahead symbol. This | ||||||
| 	situation certainly invalidates the third solution, and casts | 	situation certainly invalidates the third solution, and casts | ||||||
| 	doubts upon the second. | 	doubts upon the second. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| %lexical	LLlex; | %lexical	LLlex; | ||||||
| %start		C_program, program; | %start		C_program, program; | ||||||
| %start		If_expr, control_if_expression; | %start		If_expr, control_if_expression; | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
| #include	<flt_arith.h> | #include	<flt_arith.h> | ||||||
| #include	"arith.h" | #include	"arith.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"label.h" | #include	"label.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"declar.h" | #include	"declar.h" | ||||||
| #include	"decspecs.h" | #include	"decspecs.h" | ||||||
| #include	"code.h" | #include	"code.h" | ||||||
| #include	"expr.h" | #include	"expr.h" | ||||||
| #include	"def.h" | #include	"def.h" | ||||||
| #include    "stack.h" | #include    "idf.h" | ||||||
| #ifdef	LINT | #include    "declarator.h" | ||||||
| #include	"l_lint.h" | #include    "stack.h" | ||||||
| #endif	/* LINT */ | #include    "proto.h" | ||||||
| 
 | #include    "error.h" | ||||||
| extern error(); | #ifdef	LINT | ||||||
| } | #include	"l_lint.h" | ||||||
| 
 | #endif	/* LINT */ | ||||||
| control_if_expression | 
 | ||||||
| 	{ | } | ||||||
| 		struct expr *exprX; | 
 | ||||||
| 	} | control_if_expression | ||||||
| : | 	{ | ||||||
| 	constant_expression(&exprX) | 		struct expr *exprX; | ||||||
| 		{ | 	} | ||||||
| 		} | : | ||||||
| ; | 	constant_expression(&exprX) | ||||||
| 
 | 		{ | ||||||
| /* 3.7 */ | 		} | ||||||
| program: | ; | ||||||
| 	[%persistent external_definition]* | 
 | ||||||
| 	{ unstack_world(); } | /* 3.7 */ | ||||||
| ; | program: | ||||||
| 
 | 	[%persistent external_definition]* | ||||||
| /*	A C identifier definition is remarkable in that it formulates | 	{ unstack_world(); } | ||||||
| 	the declaration in a way different from most other languages: | ; | ||||||
| 	e.g., rather than defining x as a pointer-to-integer, it defines | 
 | ||||||
| 	*x as an integer and lets the compiler deduce that x is actually | /*	A C identifier definition is remarkable in that it formulates | ||||||
| 	pointer-to-integer.  This has profound consequences, both for the | 	the declaration in a way different from most other languages: | ||||||
| 	structure of an identifier definition and for the compiler. | 	e.g., rather than defining x as a pointer-to-integer, it defines | ||||||
| 	 | 	*x as an integer and lets the compiler deduce that x is actually | ||||||
| 	A definition starts with a decl_specifiers, which contains things | 	pointer-to-integer.  This has profound consequences, both for the | ||||||
| 	like | 	structure of an identifier definition and for the compiler. | ||||||
| 		typedef int | 	 | ||||||
| 	which is implicitly repeated for every definition in the list, and | 	A definition starts with a decl_specifiers, which contains things | ||||||
| 	then for each identifier a declarator is given, of the form | 	like | ||||||
| 		*a() | 		typedef int | ||||||
| 	or so.  The decl_specifiers is kept in a struct decspecs, to be | 	which is implicitly repeated for every definition in the list, and | ||||||
| 	used again and again, while the declarator is stored in a struct | 	then for each identifier a declarator is given, of the form | ||||||
| 	declarator, only to be passed to declare_idf together with the | 		*a() | ||||||
| 	struct decspecs. | 	or so.  The decl_specifiers is kept in a struct decspecs, to be | ||||||
| 
 | 	used again and again, while the declarator is stored in a struct | ||||||
| 	With the introduction of prototypes, extra problems for the scope | 	declarator, only to be passed to declare_idf together with the | ||||||
| 	administration were introduced as well.  We can have, for example, | 	struct decspecs. | ||||||
| 	int x(double x); | 
 | ||||||
| 	and | 	With the introduction of prototypes, extra problems for the scope | ||||||
| 	int x(double x) { ... use(x) ... } | 	administration were introduced as well.  We can have, for example, | ||||||
| 	In the first case, the parameter name can be forgotten, whereas in | 	int x(double x); | ||||||
| 	the second case, the parameter should have a block scope.  The | 	and | ||||||
| 	problem lies in the fact that the parameter's type is known before | 	int x(double x) { ... use(x) ... } | ||||||
| 	the type of the function, which causes the def structure to be on | 	In the first case, the parameter name can be forgotten, whereas in | ||||||
| 	the end of the list.  Our solution is as follows: | 	the second case, the parameter should have a block scope.  The | ||||||
| 	1-  In case of a declaration, throw the parameter identifier away | 	problem lies in the fact that the parameter's type is known before | ||||||
| 	    before the declaration of the outer x. | 	the type of the function, which causes the def structure to be on | ||||||
| 	2-  In case of a definition, the function begin_proc() changes the | 	the end of the list.  Our solution is as follows: | ||||||
| 	    def list for the identifier.  This means that declare_idf() | 	1-  In case of a declaration, throw the parameter identifier away | ||||||
| 	    contains an extra test in case we already saw a declaration of | 	    before the declaration of the outer x. | ||||||
| 	    such a function, because this function is called before | 	2-  In case of a definition, the function begin_proc() changes the | ||||||
| 	    begin_proc(). | 	    def list for the identifier.  This means that declare_idf() | ||||||
| */ | 	    contains an extra test in case we already saw a declaration of | ||||||
| 
 | 	    such a function, because this function is called before | ||||||
| external_definition | 	    begin_proc(). | ||||||
| 	{	struct decspecs Ds; | */ | ||||||
| 		struct	declarator Dc; | 
 | ||||||
| 	} | external_definition | ||||||
| : | 	{	struct decspecs Ds; | ||||||
| 	{	Ds = null_decspecs; | 		struct	declarator Dc; | ||||||
| 		Dc = null_declarator; | 	} | ||||||
| 	} | : | ||||||
| 	[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER) | 	{	Ds = null_decspecs; | ||||||
| 		decl_specifiers(&Ds) | 		Dc = null_declarator; | ||||||
| 	| | 	} | ||||||
| 		{do_decspecs(&Ds);} | 	[ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER) | ||||||
| 	] | 		decl_specifiers(&Ds) | ||||||
| 	[ | 	| | ||||||
| 		declarator(&Dc) | 		{do_decspecs(&Ds);} | ||||||
| 		{ | 	] | ||||||
| 			declare_idf(&Ds, &Dc, level); | 	[ | ||||||
| #ifdef	LINT | 		declarator(&Dc) | ||||||
| 			lint_ext_def(Dc.dc_idf, Ds.ds_sc); | 		{ | ||||||
| #endif	/* LINT */ | 			declare_idf(&Ds, &Dc, level); | ||||||
| 		} | #ifdef	LINT | ||||||
| 		[ | 			lint_ext_def(Dc.dc_idf, Ds.ds_sc); | ||||||
| 			function(&Ds, &Dc) | #endif	/* LINT */ | ||||||
| 		| | 		} | ||||||
| 			{	if (! Ds.ds_sc_given && ! Ds.ds_typequal && | 		[ | ||||||
| 				    Ds.ds_notypegiven) { | 			function(&Ds, &Dc) | ||||||
| 					strict("declaration specifiers missing"); | 		| | ||||||
| 				} | 			{	if (! Ds.ds_sc_given && ! Ds.ds_typequal && | ||||||
| 			} | 				    Ds.ds_notypegiven) { | ||||||
| 			non_function(&Ds, &Dc) | 					strict("declaration specifiers missing"); | ||||||
| 		] | 				} | ||||||
| 	| | 			} | ||||||
| 		{	if (! Ds.ds_sc_given && ! Ds.ds_typequal && | 			non_function(&Ds, &Dc) | ||||||
| 			    Ds.ds_notypegiven) { | 		] | ||||||
| 				strict("declaration missing"); | 	| | ||||||
| 			} | 		{	if (! Ds.ds_sc_given && ! Ds.ds_typequal && | ||||||
| 		} | 			    Ds.ds_notypegiven) { | ||||||
| 		';' | 				strict("declaration missing"); | ||||||
| 	] | 			} | ||||||
| 	{remove_declarator(&Dc); flush_strings(); } | 		} | ||||||
| ; | 		';' | ||||||
| 
 | 	] | ||||||
| non_function(register struct decspecs *ds; register struct declarator *dc;) | 	{remove_declarator(&Dc); flush_strings(); } | ||||||
| : | ; | ||||||
| 	{	reject_params(dc); | 
 | ||||||
| 	} | non_function(register struct decspecs *ds; register struct declarator *dc;) | ||||||
| 	[ | : | ||||||
| 		initializer(dc->dc_idf, ds->ds_sc) | 	{	reject_params(dc); | ||||||
| 	| | 	} | ||||||
| 		{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); } | 	[ | ||||||
| 	] | 		initializer(dc->dc_idf, ds->ds_sc) | ||||||
| 	{ | 	| | ||||||
| #ifdef	LINT | 		{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); } | ||||||
| 		lint_non_function_decl(ds, dc); | 	] | ||||||
| #endif	/* LINT */ | 	{ | ||||||
| 	} | #ifdef	LINT | ||||||
| 	[ | 		lint_non_function_decl(ds, dc); | ||||||
| 		',' | #endif	/* LINT */ | ||||||
| 		init_declarator(ds) | 	} | ||||||
| 	]* | 	[ | ||||||
| 	';' | 		',' | ||||||
| ; | 		init_declarator(ds) | ||||||
| 
 | 	]* | ||||||
| /* 3.7.1 */ | 	';' | ||||||
| function(struct decspecs *ds; struct declarator *dc;) | ; | ||||||
| 	{ | 
 | ||||||
| 		arith fbytes; | /* 3.7.1 */ | ||||||
| 		register struct idf *idf = dc->dc_idf; | function(struct decspecs *ds; struct declarator *dc;) | ||||||
| 	} | 	{ | ||||||
| : | 		arith fbytes; | ||||||
| 	{ | 		register struct idf *idf = dc->dc_idf; | ||||||
| #ifdef	LINT | 	} | ||||||
| 		lint_start_function(); | : | ||||||
| #endif	/* LINT */ | 	{ | ||||||
| 		idf_initialized(idf); | #ifdef	LINT | ||||||
| 		stack_level();		/* L_FORMAL1 declarations */ | 		lint_start_function(); | ||||||
| 		declare_params(dc); | #endif	/* LINT */ | ||||||
| 		begin_proc(ds, idf);	/* sets global function info */ | 		idf_initialized(idf); | ||||||
| 		stack_level();		/* L_FORMAL2 declarations */ | 		stack_level();		/* L_FORMAL1 declarations */ | ||||||
| 		declare_protos(dc); | 		declare_params(dc); | ||||||
| 	} | 		begin_proc(ds, idf);	/* sets global function info */ | ||||||
| 	declaration* | 		stack_level();		/* L_FORMAL2 declarations */ | ||||||
| 	{ | 		declare_protos(dc); | ||||||
| 		check_formals(idf, dc);		/* check style-mixtures */ | 	} | ||||||
| 		declare_formals(idf, &fbytes); | 	declaration* | ||||||
| #ifdef	LINT | 	{ | ||||||
| 		lint_formals(); | 		check_formals(idf, dc);		/* check style-mixtures */ | ||||||
| #endif	/* LINT */ | 		declare_formals(idf, &fbytes); | ||||||
| 	} | #ifdef	LINT | ||||||
| 	compound_statement | 		lint_formals(); | ||||||
| 	{ | #endif	/* LINT */ | ||||||
| 		end_proc(fbytes); | 	} | ||||||
| #ifdef	LINT | 	compound_statement | ||||||
| 		lint_implicit_return(); | 	{ | ||||||
| #endif	/* LINT */ | 		end_proc(fbytes); | ||||||
| 		unstack_level();	/* L_FORMAL2 declarations */ | #ifdef	LINT | ||||||
| #ifdef	LINT | 		lint_implicit_return(); | ||||||
| 		lint_end_formals(); | #endif	/* LINT */ | ||||||
| #endif	/* LINT */ | 		unstack_level();	/* L_FORMAL2 declarations */ | ||||||
| 		unstack_level();	/* L_FORMAL1 declarations */ | #ifdef	LINT | ||||||
| #ifdef	LINT | 		lint_end_formals(); | ||||||
| 		lint_end_function(); | #endif	/* LINT */ | ||||||
| #endif	/* LINT */ | 		unstack_level();	/* L_FORMAL1 declarations */ | ||||||
| 	} | #ifdef	LINT | ||||||
| ; | 		lint_end_function(); | ||||||
|  | #endif	/* LINT */ | ||||||
|  | 	} | ||||||
|  | ; | ||||||
|  |  | ||||||
|  | @ -23,20 +23,24 @@ | ||||||
| #include	"declar.h" | #include	"declar.h" | ||||||
| #include	"decspecs.h" | #include	"decspecs.h" | ||||||
| #include	"proto.h" | #include	"proto.h" | ||||||
|  | #include    "error.h" | ||||||
|  | #include    "ch3.h" | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| 
 | 
 | ||||||
| void | void check_for_void(register struct proto *pl) | ||||||
| check_for_void(pl) |  | ||||||
| 	register struct proto *pl; |  | ||||||
| { | { | ||||||
| 	register int errcnt = 0; | 	register int errcnt = 0; | ||||||
| 
 | 
 | ||||||
| 	if (!pl) return; | 	if (!pl) | ||||||
| 	if ((pl->pl_flag & PL_VOID) && !(pl->next)) return; | 		return; | ||||||
|  | 	if ((pl->pl_flag & PL_VOID) && !(pl->next)) | ||||||
|  | 		return; | ||||||
| 
 | 
 | ||||||
| 	while (pl) { | 	while (pl) | ||||||
| 		if (pl->pl_flag & PL_VOID) { | 	{ | ||||||
|  | 		if (pl->pl_flag & PL_VOID) | ||||||
|  | 		{ | ||||||
| 			if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN)) | 			if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN)) | ||||||
| 				error("illegal use of void in argument list"); | 				error("illegal use of void in argument list"); | ||||||
| 			pl->pl_flag |= PL_ERRGIVEN; | 			pl->pl_flag |= PL_ERRGIVEN; | ||||||
|  | @ -46,37 +50,35 @@ check_for_void(pl) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| add_proto(pl, ds, dc, lvl) | void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc, | ||||||
| 	struct proto *pl; | 		int lvl) | ||||||
| 	struct decspecs *ds; |  | ||||||
| 	struct declarator *dc; |  | ||||||
| 	int lvl; |  | ||||||
| { | { | ||||||
| 	/*	The full typed identifier or abstract type, described
 | 	/*	The full typed identifier or abstract type, described
 | ||||||
| 		by the structures decspecs and declarator are turned | 	 by the structures decspecs and declarator are turned | ||||||
| 		a into parameter type list structure. | 	 a into parameter type list structure. | ||||||
| 		The parameters will be declared at level L_FORMAL2, | 	 The parameters will be declared at level L_FORMAL2, | ||||||
| 		later on it's decided whether they were prototypes | 	 later on it's decided whether they were prototypes | ||||||
| 		or actual declarations. | 	 or actual declarations. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct idf *idf = dc->dc_idf; | 	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 int sc = ds->ds_sc; | ||||||
| 	register struct type *type; | 	register struct type *type; | ||||||
| 	char formal_array = 0; | 	char formal_array = 0; | ||||||
| 
 | 
 | ||||||
| 	assert(ds->ds_type != (struct type *)0); | 	assert(ds->ds_type != (struct type * )0); | ||||||
| 
 | 
 | ||||||
| 	pl->pl_flag = PL_FORMAL; | 	pl->pl_flag = PL_FORMAL; | ||||||
| 	type = declare_type(ds->ds_type, dc); | 	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(); | 		extern char *symbol2str(); | ||||||
| 		if (type->tp_fund != VOID) | 		if (type->tp_fund != VOID) | ||||||
| 			error("unknown %s-type", symbol2str(type->tp_fund)); | 			error("unknown %s-type", symbol2str(type->tp_fund)); | ||||||
| 		else { | 		else | ||||||
| 			if (idf != (struct idf *)0 | 		{ | ||||||
| 			    || ds->ds_sc_given | 			if (idf != (struct idf *) 0 || ds->ds_sc_given || ds->ds_typequal) | ||||||
| 			    || ds->ds_typequal) { | 			{ | ||||||
| 				error("illegal use of void in argument list"); | 				error("illegal use of void in argument list"); | ||||||
| 				pl->pl_flag |= PL_ERRGIVEN; | 				pl->pl_flag |= PL_ERRGIVEN; | ||||||
| 			} | 			} | ||||||
|  | @ -84,43 +86,54 @@ add_proto(pl, ds, dc, lvl) | ||||||
| 			pl->pl_flag |= PL_VOID; | 			pl->pl_flag |= PL_VOID; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (ds->ds_sc_given && ds->ds_sc != REGISTER) { | 	if (ds->ds_sc_given && ds->ds_sc != REGISTER) | ||||||
| 		if (!(pl->pl_flag & PL_ERRGIVEN)) { | 	{ | ||||||
| 		    if (ds->ds_sc != AUTO) { | 		if (!(pl->pl_flag & PL_ERRGIVEN)) | ||||||
| 			error("illegal storage class in parameter declaration"); | 		{ | ||||||
| 		    } else { | 			if (ds->ds_sc != AUTO) | ||||||
| 			warning("illegal storage class in parameter declaration"); | 			{ | ||||||
| 		    } | 				error("illegal storage class in parameter declaration"); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				warning("illegal storage class in parameter declaration"); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*	Perform some special conversions for parameters.
 | 	/*	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); | 		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); | 		type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO); | ||||||
| 		formal_array = 1; | 		formal_array = 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*	According to the standard we should ignore the storage
 | 	/*	According to the standard we should ignore the storage
 | ||||||
| 		class of a parameter, unless it's part of a function | 	 class of a parameter, unless it's part of a function | ||||||
| 		definition. | 	 definition. | ||||||
| 		However, in the routine declare_protos we don't know decspecs, | 	 However, in the routine declare_protos we don't know decspecs, | ||||||
| 		and therefore we can't complain up there. So we build up the | 	 and therefore we can't complain up there. So we build up the | ||||||
| 		storage class, and keep quiet until we reach declare_protos. | 	 storage class, and keep quiet until we reach declare_protos. | ||||||
| 	*/ | 	 */ | ||||||
| 	sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? | 	sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? 0 : | ||||||
| 				0 : sc == 0 ? FORMAL : REGISTER; | 			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 */ | 		/* redeclaration at the same level */ | ||||||
| 		error("parameter %s redeclared", idf->id_text); | 		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
 | 		/*	New definition, redefinition hides earlier one
 | ||||||
| 		*/ | 		 */ | ||||||
| 		register struct def *newdef = new_def(); | 		register struct def *newdef = new_def(); | ||||||
| 		 | 
 | ||||||
| 		newdef->next = def; | 		newdef->next = def; | ||||||
| 		newdef->df_level = lvl; | 		newdef->df_level = lvl; | ||||||
| 		newdef->df_sc = sc; | 		newdef->df_sc = sc; | ||||||
|  | @ -133,28 +146,28 @@ add_proto(pl, ds, dc, lvl) | ||||||
| 		/* newdef->df_firstbrace = 0; */ | 		/* newdef->df_firstbrace = 0; */ | ||||||
| #endif | #endif | ||||||
| 		/*	We can't put the idf onto the stack, since these kinds
 | 		/*	We can't put the idf onto the stack, since these kinds
 | ||||||
| 			of declaration may occurs at any level, and the idf | 		 of declaration may occurs at any level, and the idf | ||||||
| 			does not necessarily go at this level. E.g. | 		 does not necessarily go at this level. E.g. | ||||||
| 
 | 
 | ||||||
| 			f() { | 		 f() { | ||||||
| 			... | 		 ... | ||||||
| 				{ int func(int a, int b); | 		 { int func(int a, int b); | ||||||
| 				... | 		 ... | ||||||
| 				} | 		 } | ||||||
| 			} | 		 } | ||||||
| 
 | 
 | ||||||
| 			The idf's a and b declared in the prototype declaration | 		 The idf's a and b declared in the prototype declaration | ||||||
| 			do not go at any level, they are simply ignored. | 		 do not go at any level, they are simply ignored. | ||||||
| 			However, in | 		 However, in | ||||||
| 
 | 
 | ||||||
| 			f(int a, int b) { | 		 f(int a, int b) { | ||||||
| 			... | 		 ... | ||||||
| 			} | 		 } | ||||||
| 
 | 
 | ||||||
| 			They should go at level L_FORMAL2. But at this stage | 		 They should go at level L_FORMAL2. But at this stage | ||||||
| 			we don't know whether we have a prototype or function | 		 we don't know whether we have a prototype or function | ||||||
| 			definition. So, this process is postponed. | 		 definition. So, this process is postponed. | ||||||
| 		*/ | 		 */ | ||||||
| 		idf->id_def = newdef; | 		idf->id_def = newdef; | ||||||
| 		update_ahead(idf); | 		update_ahead(idf); | ||||||
| 	} | 	} | ||||||
|  | @ -163,35 +176,33 @@ add_proto(pl, ds, dc, lvl) | ||||||
| 	pl->pl_type = type; | 	pl->pl_type = type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct tag * | static struct tag * gettag(struct type *tp, struct idf **idpp) | ||||||
| gettag(tp, idpp) |  | ||||||
| struct type *tp; |  | ||||||
| struct idf **idpp; |  | ||||||
| { | { | ||||||
| 	struct tag *tg = (struct tag *)0; | 	struct tag *tg = (struct tag *) 0; | ||||||
| 	register int fund = tp->tp_fund; | 	register int fund = tp->tp_fund; | ||||||
| 
 | 
 | ||||||
|         while (fund == FIELD || fund == POINTER | 	while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION) | ||||||
|                 || fund == ARRAY || fund == FUNCTION) { | 	{ | ||||||
|                 tp = tp->tp_up; | 		tp = tp->tp_up; | ||||||
|                 fund = tp->tp_fund; | 		fund = tp->tp_fund; | ||||||
|         } | 	} | ||||||
| 	*idpp = tp->tp_idf; | 	*idpp = tp->tp_idf; | ||||||
| 	switch(tp->tp_fund) { | 	switch (tp->tp_fund) | ||||||
|  | 	{ | ||||||
| 	case ENUM: | 	case ENUM: | ||||||
| 	case UNION: | 	case UNION: | ||||||
| 	case STRUCT: tg = tp->tp_idf->id_tag; break; | 	case STRUCT: | ||||||
|  | 		tg = tp->tp_idf->id_tag; | ||||||
|  | 		break; | ||||||
| 	} | 	} | ||||||
| 	return tg; | 	return tg; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | void declare_protos(register struct declarator *dc) | ||||||
| declare_protos(dc) |  | ||||||
| 	register struct declarator *dc; |  | ||||||
| { | { | ||||||
| 	/*	At this points we know that the idf's in protolist are formal
 | 	/*	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); | 	struct stack_level *stl = stack_level_of(L_FORMAL1); | ||||||
| 	register struct decl_unary *du; | 	register struct decl_unary *du; | ||||||
| 	register struct type *type; | 	register struct type *type; | ||||||
|  | @ -200,31 +211,39 @@ declare_protos(dc) | ||||||
| 
 | 
 | ||||||
| #ifdef	DEBUG | #ifdef	DEBUG | ||||||
| 	if (options['t']) | 	if (options['t']) | ||||||
| 		dumpidftab("start declare_protos", 0); | 	dumpidftab("start declare_protos", 0); | ||||||
| #endif	/* DEBUG */ | #endif	/* DEBUG */ | ||||||
| 	du = dc->dc_decl_unary; | 	du = dc->dc_decl_unary; | ||||||
| 	while (du) { | 	while (du) | ||||||
| 		if (du->du_fund == FUNCTION) { | 	{ | ||||||
| 			if (du->next != (struct decl_unary *) 0) { | 		if (du->du_fund == FUNCTION) | ||||||
|  | 		{ | ||||||
|  | 			if (du->next != (struct decl_unary *) 0) | ||||||
|  | 			{ | ||||||
| 				remove_proto_idfs(du->du_proto); | 				remove_proto_idfs(du->du_proto); | ||||||
| 				du->du_proto = 0; | 				du->du_proto = 0; | ||||||
| 			} else break; | 			} | ||||||
|  | 			else | ||||||
|  | 				break; | ||||||
| 		} | 		} | ||||||
| 		du = du->next; | 		du = du->next; | ||||||
| 	} | 	} | ||||||
| 	pl = du ? du->du_proto : NO_PROTO; | 	pl = du ? du->du_proto : NO_PROTO; | ||||||
| 	if (pl) { | 	if (pl) | ||||||
|  | 	{ | ||||||
| #if	0 /* the id_proto member is deleted (???) */
 | #if	0 /* the id_proto member is deleted (???) */
 | ||||||
| 		idf->id_proto = 0; | 		idf->id_proto = 0; | ||||||
| #endif	/* 0 */ | #endif	/* 0 */ | ||||||
| 		do { | 		do | ||||||
|  | 		{ | ||||||
| 			struct tag *tg; | 			struct tag *tg; | ||||||
| 			struct idf *idp = 0; | 			struct idf *idp = 0; | ||||||
| 
 | 
 | ||||||
| 			type = pl->pl_type; | 			type = pl->pl_type; | ||||||
| 
 | 
 | ||||||
| 			/* `...' only for type checking */ | 			/* `...' only for type checking */ | ||||||
| 			if (pl->pl_flag & PL_ELLIPSIS) { | 			if (pl->pl_flag & PL_ELLIPSIS) | ||||||
|  | 			{ | ||||||
| 				pl = pl->next; | 				pl = pl->next; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -233,14 +252,15 @@ declare_protos(dc) | ||||||
| 			if (type->tp_fund == VOID) | 			if (type->tp_fund == VOID) | ||||||
| 				break; | 				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"); | 				error("no parameter identifier supplied"); | ||||||
| 				pl = pl->next; | 				pl = pl->next; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			/*	Postponed storage class checking.
 | 			/*	Postponed storage class checking.
 | ||||||
| 			*/ | 			 */ | ||||||
| 			if (def->df_sc == 0) | 			if (def->df_sc == 0) | ||||||
| 				error("illegal storage class in parameter declaration"); | 				error("illegal storage class in parameter declaration"); | ||||||
| 
 | 
 | ||||||
|  | @ -249,7 +269,8 @@ declare_protos(dc) | ||||||
| 			pl = pl->next; | 			pl = pl->next; | ||||||
| 
 | 
 | ||||||
| 			tg = gettag(type, &idp); | 			tg = gettag(type, &idp); | ||||||
| 			if (tg && tg->tg_level <= L_PROTO) { | 			if (tg && tg->tg_level <= L_PROTO) | ||||||
|  | 			{ | ||||||
| 				tg->tg_level = L_FORMAL2; | 				tg->tg_level = L_FORMAL2; | ||||||
| 				stack_idf(idp, stl); | 				stack_idf(idp, stl); | ||||||
| 			} | 			} | ||||||
|  | @ -257,43 +278,47 @@ declare_protos(dc) | ||||||
| 	} | 	} | ||||||
| #ifdef	DEBUG | #ifdef	DEBUG | ||||||
| 	if (options['t']) | 	if (options['t']) | ||||||
| 		dumpidftab("end declare_protos", 0); | 	dumpidftab("end declare_protos", 0); | ||||||
| #endif	/* DEBUG */ | #endif	/* DEBUG */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | void update_proto(register struct type *tp, register struct type *otp) | ||||||
| void |  | ||||||
| update_proto(tp, otp) |  | ||||||
| 	register struct type *tp, *otp; |  | ||||||
| { | { | ||||||
| 	/*	This routine performs the proto type updates.
 | 	/*	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(double g(int f(), int)); | 	 int f(double g(int f(), int)); | ||||||
| 		int f(double g(int f(long double), int)); | 	 int f(double g(int f(long double), int)); | ||||||
| 
 | 
 | ||||||
| 		The most accurate definition is the third line. | 	 The most accurate definition is the third line. | ||||||
| 		This routine will silently update all lists, | 	 This routine will silently update all lists, | ||||||
| 		and removes the redundant occupied space. | 	 and removes the redundant occupied space. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct proto *pl, *opl; | 	register struct proto *pl, *opl; | ||||||
| 
 | 
 | ||||||
| 	if (tp == otp) return; | 	if (tp == otp) | ||||||
| 	if (!tp || !otp) return; | 		return; | ||||||
|  | 	if (!tp || !otp) | ||||||
|  | 		return; | ||||||
| 
 | 
 | ||||||
| 	while (tp->tp_fund != FUNCTION) { | 	while (tp->tp_fund != FUNCTION) | ||||||
| 		if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) return; | 	{ | ||||||
|  | 		if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) | ||||||
|  | 			return; | ||||||
| 		tp = tp->tp_up; | 		tp = tp->tp_up; | ||||||
| 		otp = otp->tp_up; | 		otp = otp->tp_up; | ||||||
| 		if (!tp) return; | 		if (!tp) | ||||||
|  | 			return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	pl = tp->tp_proto; | 	pl = tp->tp_proto; | ||||||
| 	opl = otp->tp_proto; | 	opl = otp->tp_proto; | ||||||
| 	if (pl && opl) { | 	if (pl && opl) | ||||||
|  | 	{ | ||||||
| 		/* both have prototypes */ | 		/* both have prototypes */ | ||||||
| 		while (pl && opl) { | 		while (pl && opl) | ||||||
|  | 		{ | ||||||
| 			update_proto(pl->pl_type, opl->pl_type); | 			update_proto(pl->pl_type, opl->pl_type); | ||||||
| 			pl = pl->next; | 			pl = pl->next; | ||||||
| 			opl = opl->next; | 			opl = opl->next; | ||||||
|  | @ -302,9 +327,13 @@ update_proto(tp, otp) | ||||||
| 		 * a typedef. | 		 * a typedef. | ||||||
| 		 */ | 		 */ | ||||||
| 		otp->tp_proto = tp->tp_proto; | 		otp->tp_proto = tp->tp_proto; | ||||||
| 	} else if (opl) { | 	} | ||||||
|  | 	else if (opl) | ||||||
|  | 	{ | ||||||
| 		/* old decl has type */ | 		/* old decl has type */ | ||||||
| 	} else if (pl) { | 	} | ||||||
|  | 	else if (pl) | ||||||
|  | 	{ | ||||||
| 		otp->tp_proto = pl; | 		otp->tp_proto = pl; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -314,39 +343,44 @@ update_proto(tp, otp) | ||||||
| /* struct/union and enum tags can be declared inside prototypes
 | /* struct/union and enum tags can be declared inside prototypes
 | ||||||
|  * remove them from the symbol-table |  * remove them from the symbol-table | ||||||
|  */ |  */ | ||||||
| void | static void remove_proto_tag(struct type *tp) | ||||||
| remove_proto_tag(tp) |  | ||||||
| struct type *tp; |  | ||||||
| { | { | ||||||
| 	register struct idf *ident; | 	register struct idf *ident; | ||||||
| 	register struct tag *tgp, **tgpp; | 	register struct tag *tgp, **tgpp; | ||||||
| 	register int fund = tp->tp_fund; | 	register int fund = tp->tp_fund; | ||||||
| 
 | 
 | ||||||
| 	while (fund == FIELD || fund == POINTER | 	while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION) | ||||||
| 		|| fund == ARRAY || fund == FUNCTION) { | 	{ | ||||||
| 		tp = tp->tp_up; | 		tp = tp->tp_up; | ||||||
| 		fund = tp->tp_fund; | 		fund = tp->tp_fund; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ident = tp->tp_idf; | 	ident = tp->tp_idf; | ||||||
| 	switch (tp->tp_fund) { | 	switch (tp->tp_fund) | ||||||
|  | 	{ | ||||||
| 	case ENUM: | 	case ENUM: | ||||||
| 	case STRUCT: | 	case STRUCT: | ||||||
| 	case UNION: tgpp = &(ident->id_tag); break; | 	case UNION: | ||||||
| 	default: return; | 		tgpp = &(ident->id_tag); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	while((*tgpp) && (*tgpp)->tg_type != tp) { | 	while ((*tgpp) && (*tgpp)->tg_type != tp) | ||||||
|  | 	{ | ||||||
| 		tgpp = &((*tgpp)->next); | 		tgpp = &((*tgpp)->next); | ||||||
| 	} | 	} | ||||||
| 	if (!*tgpp) return; | 	if (!*tgpp) | ||||||
|  | 		return; | ||||||
| 
 | 
 | ||||||
| 	tgp = *tgpp; | 	tgp = *tgpp; | ||||||
| 	if (tgp->tg_level > L_PROTO) return; | 	if (tgp->tg_level > L_PROTO) | ||||||
|  | 		return; | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| 	if (options['t']) | 	if (options['t']) | ||||||
| 		print("Removing idf %s from list\n", | 	print("Removing idf %s from list\n", | ||||||
| 			ident->id_text); | 			ident->id_text); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -354,52 +388,55 @@ struct type *tp; | ||||||
| 	free_tag(tgp); | 	free_tag(tgp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| remove_proto_idfs(pl) | /*	Remove all the identifier definitions from the
 | ||||||
| 	register struct proto *pl; | 	 prototype list. */ | ||||||
|  | void remove_proto_idfs(register struct proto *pl) | ||||||
| { | { | ||||||
| 	/*	Remove all the identifier definitions from the
 | 
 | ||||||
| 		prototype list. |  | ||||||
| 	*/ |  | ||||||
| 	register struct def *def; | 	register struct def *def; | ||||||
| 
 | 
 | ||||||
| 	while (pl) { | 	while (pl) | ||||||
| 		if (pl->pl_idf) { | 	{ | ||||||
|  | 		if (pl->pl_idf) | ||||||
|  | 		{ | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| 			if (options['t']) | 			if (options['t']) | ||||||
| 				print("Removing idf %s from list\n", | 			print("Removing idf %s from list\n", | ||||||
| 					pl->pl_idf->id_text); | 					pl->pl_idf->id_text); | ||||||
| #endif | #endif | ||||||
| 			def = pl->pl_idf->id_def; | 			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; | 				pl->pl_idf->id_def = def->next; | ||||||
| 				free_def(def); | 				free_def(def); | ||||||
| 			} | 			} | ||||||
| 			pl->pl_idf = (struct idf *) 0; | 			pl->pl_idf = (struct idf *) 0; | ||||||
| 		} | 		} | ||||||
| 		if (pl->pl_type) { | 		if (pl->pl_type) | ||||||
|  | 		{ | ||||||
| 			remove_proto_tag(pl->pl_type); | 			remove_proto_tag(pl->pl_type); | ||||||
| 		} | 		} | ||||||
| 		pl = pl->next; | 		pl = pl->next; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void call_proto(register struct expr **expp) | ||||||
| call_proto(expp) |  | ||||||
| 	register struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	If the function specified by (*expp)->OP_LEFT has a prototype,
 | 	/*	If the function specified by (*expp)->OP_LEFT has a prototype,
 | ||||||
| 		the parameters are converted according the rules specified in | 	 the parameters are converted according the rules specified in | ||||||
| 		par. 3.3.2.2. E.i. the parameters are converted to the prototype | 	 par. 3.3.2.2. E.i. the parameters are converted to the prototype | ||||||
| 		counter parts as if by assignment. For the parameters falling | 	 counter parts as if by assignment. For the parameters falling | ||||||
| 		under ellipsis clause the old parameters conversion stuff | 	 under ellipsis clause the old parameters conversion stuff | ||||||
| 		applies. | 	 applies. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct expr *left = (*expp)->OP_LEFT; | 	register struct expr *left = (*expp)->OP_LEFT; | ||||||
| 	register struct expr *right = (*expp)->OP_RIGHT; | 	register struct expr *right = (*expp)->OP_RIGHT; | ||||||
| 	register struct proto *pl = NO_PROTO; | 	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; | 		register struct type *tp = left->ex_type; | ||||||
| 
 | 
 | ||||||
| 		while (tp && tp->tp_fund != FUNCTION && tp != error_type) | 		while (tp && tp->tp_fund != FUNCTION && tp != error_type) | ||||||
|  | @ -408,17 +445,20 @@ call_proto(expp) | ||||||
| 			pl = tp->tp_proto; | 			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 struct expr **ep = &((*expp)->OP_RIGHT); | ||||||
| 		register int ecnt = 0, pcnt = 0; | 		register int ecnt = 0, pcnt = 0; | ||||||
| 		struct expr **estack[NPARAMS]; | 		struct expr **estack[NPARAMS]; | ||||||
| 		struct proto *pstack[NPARAMS]; | 		struct proto *pstack[NPARAMS]; | ||||||
| 
 | 
 | ||||||
| 		/* stack up the parameter expressions */ | 		/* 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) | 			if (ecnt == STDC_NPARAMS) | ||||||
| 				expr_strict(right, "number of parameters exceeds ANSI limit"); | 				expr_strict(right, "number of parameters exceeds ANSI limit"); | ||||||
| 			if (ecnt >= NPARAMS-1) { | 			if (ecnt >= NPARAMS - 1) | ||||||
|  | 			{ | ||||||
| 				expr_error(right, "too many parameters"); | 				expr_error(right, "too many parameters"); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  | @ -429,45 +469,56 @@ call_proto(expp) | ||||||
| 		estack[ecnt] = ep; | 		estack[ecnt] = ep; | ||||||
| 
 | 
 | ||||||
| 		/*	Declarations like int f(void) do not expect any
 | 		/*	Declarations like int f(void) do not expect any
 | ||||||
| 			parameters. | 		 parameters. | ||||||
| 		*/ | 		 */ | ||||||
| 		if (pl && pl->pl_flag & PL_VOID) { | 		if (pl && pl->pl_flag & PL_VOID) | ||||||
|  | 		{ | ||||||
| 			expr_strict(*expp, "no parameters expected"); | 			expr_strict(*expp, "no parameters expected"); | ||||||
| 			pl = NO_PROTO; | 			pl = NO_PROTO; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/* stack up the prototypes */ | 		/* stack up the prototypes */ | ||||||
| 		if (pl) { | 		if (pl) | ||||||
|  | 		{ | ||||||
| 			pcnt--; | 			pcnt--; | ||||||
| 			do { | 			do | ||||||
|  | 			{ | ||||||
| 				/* stack prototypes */ | 				/* stack prototypes */ | ||||||
| 				pstack[++pcnt] = pl; | 				pstack[++pcnt] = pl; | ||||||
| 				pl = pl->next; | 				pl = pl->next; | ||||||
| 			} while (pl); | 			} while (pl); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else | ||||||
|  | 		{ | ||||||
| 			pstack[0] = &ellipsis; | 			pstack[0] = &ellipsis; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (ecnt; ecnt >= 0; ecnt--) { | 		for (ecnt; ecnt >= 0; ecnt--) | ||||||
|  | 		{ | ||||||
| 			/*	Only the parameters specified in the prototype
 | 			/*	Only the parameters specified in the prototype
 | ||||||
| 				are checked and converted. The parameters that | 			 are checked and converted. The parameters that | ||||||
| 				fall under the ellipsis clause are neither | 			 fall under the ellipsis clause are neither | ||||||
| 				checked nor converted ! | 			 checked nor converted ! | ||||||
| 			*/ | 			 */ | ||||||
| 			if (pcnt < 0) { | 			if (pcnt < 0) | ||||||
| 				expr_error(*expp, "more parameters than specified in prototype"); | 			{ | ||||||
|  | 				expr_error(*expp, | ||||||
|  | 						"more parameters than specified in prototype"); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) { | 			else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) | ||||||
| 				ch3cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type); | 			{ | ||||||
|  | 				ch3cast(estack[ecnt], CASTAB, pstack[pcnt]->pl_type); | ||||||
| 				pcnt--; | 				pcnt--; | ||||||
| 			} else | 			} | ||||||
|  | 			else | ||||||
| 				any2parameter(estack[ecnt]); | 				any2parameter(estack[ecnt]); | ||||||
| 		} | 		} | ||||||
| 		if (pcnt > 0 || (pcnt == 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS))) | 		if (pcnt > 0 || (pcnt == 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS))) | ||||||
| 			expr_error(*expp, "fewer parameters than specified in prototype"); | 			expr_error(*expp, "fewer parameters than specified in prototype"); | ||||||
| 	} else { | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
| 		if (pl && !(pl->pl_flag & PL_VOID)) | 		if (pl && !(pl->pl_flag & PL_VOID)) | ||||||
| 			expr_error(*expp, "fewer parameters than specified in prototype"); | 			expr_error(*expp, "fewer parameters than specified in prototype"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef PROTO_H | ||||||
|  | #define PROTO_H | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* PARAMETER TYPE LIST DEFINITION */ | /* PARAMETER TYPE LIST DEFINITION */ | ||||||
| 
 | 
 | ||||||
|  | @ -20,3 +23,20 @@ struct proto { | ||||||
| #define	PL_ERRGIVEN	0x08 | #define	PL_ERRGIVEN	0x08 | ||||||
| 
 | 
 | ||||||
| /* ALLOCDEF "proto" 20 */ | /* 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 "LLlex.h" | ||||||
| #include "class.h" | #include "class.h" | ||||||
| #include "input.h" | #include "input.h" | ||||||
|  | #include "skip.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| SkipToNewLine() | int SkipToNewLine(void) | ||||||
| { | { | ||||||
| 	register int ch; | 	register int ch; | ||||||
| 	register int garbage = 0; | 	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	<flt_arith.h> | ||||||
| #include	<stb.h> | #include	<stb.h> | ||||||
| 
 | 
 | ||||||
|  | #include    "stab.h" | ||||||
| #include    "idf.h" | #include    "idf.h" | ||||||
| #include	"LLlex.h" | #include	"LLlex.h" | ||||||
| #include	"stack.h" | #include	"stack.h" | ||||||
|  | @ -29,34 +30,34 @@ | ||||||
| #include	"field.h" | #include	"field.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
|  | #include    "print.h" | ||||||
| 
 | 
 | ||||||
| extern long	full_mask[]; | extern long full_mask[]; | ||||||
| extern char	*sprint(); |  | ||||||
| 
 | 
 | ||||||
| #define INCR_SIZE	64 | #define INCR_SIZE	64 | ||||||
| 
 | 
 | ||||||
| static struct db_str { | static struct db_str | ||||||
| 	unsigned	sz; | { | ||||||
| 	char		*base; | 	unsigned sz; | ||||||
| 	char		*currpos; | 	char *base; | ||||||
|  | 	char *currpos; | ||||||
| } db_str; | } db_str; | ||||||
| 
 | 
 | ||||||
| static | static void create_db_str(void) | ||||||
| create_db_str() |  | ||||||
| { | { | ||||||
| 	if (! db_str.base) { | 	if (!db_str.base) | ||||||
|  | 	{ | ||||||
| 		db_str.base = Malloc(INCR_SIZE); | 		db_str.base = Malloc(INCR_SIZE); | ||||||
| 		db_str.sz = INCR_SIZE; | 		db_str.sz = INCR_SIZE; | ||||||
| 	} | 	} | ||||||
| 	db_str.currpos = db_str.base; | 	db_str.currpos = db_str.base; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | static void addc_db_str(int c) | ||||||
| addc_db_str(c) |  | ||||||
| 	int	c; |  | ||||||
| { | { | ||||||
| 	int df = db_str.currpos - db_str.base; | 	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.sz += INCR_SIZE; | ||||||
| 		db_str.base = Realloc(db_str.base, db_str.sz); | 		db_str.base = Realloc(db_str.base, db_str.sz); | ||||||
| 		db_str.currpos = db_str.base + df; | 		db_str.currpos = db_str.base + df; | ||||||
|  | @ -65,34 +66,35 @@ addc_db_str(c) | ||||||
| 	*db_str.currpos = '\0'; | 	*db_str.currpos = '\0'; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static | static void adds_db_str(char *s) | ||||||
| adds_db_str(s) |  | ||||||
| 	char	*s; |  | ||||||
| { | { | ||||||
| 	while (*s) addc_db_str(*s++); | 	while (*s) | ||||||
|  | 		addc_db_str(*s++); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void stb_type(register struct type *tp) | ||||||
| stb_type(tp) |  | ||||||
| 	register struct type	*tp; |  | ||||||
| { | { | ||||||
| 	char		buf[128]; | 	char buf[128]; | ||||||
| 	static int	stb_count; | 	static int stb_count; | ||||||
| 	long		l; | 	long l; | ||||||
| 
 | 
 | ||||||
| 	if (tp->tp_dbindex > 0) { | 	if (tp->tp_dbindex > 0) | ||||||
|  | 	{ | ||||||
| 		adds_db_str(sprint(buf, "%d", tp->tp_dbindex)); | 		adds_db_str(sprint(buf, "%d", tp->tp_dbindex)); | ||||||
| 		return; | 		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)); | 		adds_db_str(sprint(buf, "%d", -tp->tp_dbindex)); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	if (tp->tp_dbindex <= 0) { | 	if (tp->tp_dbindex <= 0) | ||||||
|  | 	{ | ||||||
| 		tp->tp_dbindex = ++stb_count; | 		tp->tp_dbindex = ++stb_count; | ||||||
| 	} | 	} | ||||||
| 	adds_db_str(sprint(buf, "%d=", tp->tp_dbindex)); | 	adds_db_str(sprint(buf, "%d=", tp->tp_dbindex)); | ||||||
| 	switch(tp->tp_fund) { | 	switch (tp->tp_fund) | ||||||
|  | 	{ | ||||||
| 	/* simple types ... */ | 	/* simple types ... */ | ||||||
| 	case VOID: | 	case VOID: | ||||||
| 		adds_db_str(sprint(buf, "%d", void_type->tp_dbindex)); | 		adds_db_str(sprint(buf, "%d", void_type->tp_dbindex)); | ||||||
|  | @ -101,49 +103,44 @@ stb_type(tp) | ||||||
| 	case LONG: | 	case LONG: | ||||||
| 	case CHAR: | 	case CHAR: | ||||||
| 	case SHORT: | 	case SHORT: | ||||||
| 		 l = full_mask[(int)tp->tp_size]; | 		l = full_mask[(int) tp->tp_size]; | ||||||
| 		if (tp->tp_unsigned) { | 		if (tp->tp_unsigned) | ||||||
| 			adds_db_str(sprint(buf, | 		{ | ||||||
| 				"r%d;0;%ld", | 			adds_db_str(sprint(buf, "r%d;0;%ld", tp->tp_dbindex, l)); | ||||||
| 				tp->tp_dbindex, |  | ||||||
| 				l)); |  | ||||||
| 		} | 		} | ||||||
| 		else { | 		else | ||||||
| 			l &= ~ (1L << ((int)tp->tp_size * 8 - 1)); | 		{ | ||||||
| 			adds_db_str(sprint(buf, | 			l &= ~(1L << ((int) tp->tp_size * 8 - 1)); | ||||||
| 				"r%d;%ld;%ld", | 			adds_db_str(sprint(buf, "r%d;%ld;%ld", tp->tp_dbindex, -l - 1, l)); | ||||||
| 				tp->tp_dbindex, |  | ||||||
| 				-l-1, |  | ||||||
| 				l)); |  | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case FLOAT: | 	case FLOAT: | ||||||
| 	case DOUBLE: | 	case DOUBLE: | ||||||
| 	case LNGDBL: | 	case LNGDBL: | ||||||
| 		adds_db_str(sprint(buf, | 		adds_db_str( | ||||||
| 		       "r%d;%ld;0", | 				sprint(buf, "r%d;%ld;0", tp->tp_dbindex, (long) tp->tp_size)); | ||||||
| 		       tp->tp_dbindex, |  | ||||||
| 		       (long)tp->tp_size)); |  | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	/* constructed types ... */ | 		/* constructed types ... */ | ||||||
| 	case POINTER: | 	case POINTER: | ||||||
| 		addc_db_str('*'); | 		addc_db_str('*'); | ||||||
| 		stb_type(tp->tp_up); | 		stb_type(tp->tp_up); | ||||||
| 		break; | 		break; | ||||||
| 	case ARRAY: | 	case ARRAY: | ||||||
| 		if (tp->tp_size > 0) { | 		if (tp->tp_size > 0) | ||||||
|  | 		{ | ||||||
| 			adds_db_str("ar"); | 			adds_db_str("ar"); | ||||||
| 			stb_type(int_type); | 			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); | 			stb_type(tp->tp_up); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case ENUM: | 	case ENUM: | ||||||
| 		if (tp->tp_size < 0) { | 		if (tp->tp_size < 0) | ||||||
| 			adds_db_str(sprint(buf, | 		{ | ||||||
| 					   "xe%s:", | 			adds_db_str(sprint(buf, "xe%s:", tp->tp_idf->id_text)); | ||||||
| 					   tp->tp_idf->id_text)); |  | ||||||
| 			tp->tp_dbindex = -tp->tp_dbindex; | 			tp->tp_dbindex = -tp->tp_dbindex; | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | @ -151,15 +148,16 @@ stb_type(tp) | ||||||
| 		{ | 		{ | ||||||
| 			register struct stack_entry *se = local_level->sl_entry; | 			register struct stack_entry *se = local_level->sl_entry; | ||||||
| 
 | 
 | ||||||
| 			while (se) { | 			while (se) | ||||||
| 				register struct def	*edef = se->se_idf->id_def; | 			{ | ||||||
| 				while (edef) { | 				register struct def *edef = se->se_idf->id_def; | ||||||
| 					if (edef->df_type == tp && | 				while (edef) | ||||||
| 					    edef->df_sc == ENUM) { | 				{ | ||||||
| 						adds_db_str(sprint(buf, | 					if (edef->df_type == tp && edef->df_sc == ENUM) | ||||||
| 							"%s:%ld,", | 					{ | ||||||
| 							se->se_idf->id_text, | 						adds_db_str( | ||||||
| 							edef->df_address)); | 								sprint(buf, "%s:%ld,", se->se_idf->id_text, | ||||||
|  | 										edef->df_address)); | ||||||
| 					} | 					} | ||||||
| 					edef = edef->next; | 					edef = edef->next; | ||||||
| 				} | 				} | ||||||
|  | @ -170,37 +168,39 @@ stb_type(tp) | ||||||
| 		break; | 		break; | ||||||
| 	case STRUCT: | 	case STRUCT: | ||||||
| 	case UNION: | 	case UNION: | ||||||
| 		if (tp->tp_size < 0) { | 		if (tp->tp_size < 0) | ||||||
| 			adds_db_str(sprint(buf, | 		{ | ||||||
| 					   "x%c%s:", | 			adds_db_str( | ||||||
| 					   tp->tp_fund == STRUCT ? 's' : 'u', | 					sprint(buf, "x%c%s:", tp->tp_fund == STRUCT ? 's' : 'u', | ||||||
| 					   tp->tp_idf->id_text)); | 							tp->tp_idf->id_text)); | ||||||
| 			tp->tp_dbindex = -tp->tp_dbindex; | 			tp->tp_dbindex = -tp->tp_dbindex; | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		adds_db_str(sprint(buf, | 		adds_db_str( | ||||||
| 				   "%c%ld", | 				sprint(buf, "%c%ld", tp->tp_fund == STRUCT ? 's' : 'u', | ||||||
| 				   tp->tp_fund == STRUCT ? 's' : 'u', | 						tp->tp_size)); | ||||||
| 				   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); | 				adds_db_str(sdef->sd_idf->id_text); | ||||||
| 				addc_db_str(':'); | 				addc_db_str(':'); | ||||||
| 				if (sdef->sd_type->tp_fund == FIELD) { | 				if (sdef->sd_type->tp_fund == FIELD) | ||||||
|  | 				{ | ||||||
| 					stb_type(sdef->sd_type->tp_up); | 					stb_type(sdef->sd_type->tp_up); | ||||||
| 					adds_db_str(sprint(buf, | 					adds_db_str( | ||||||
| 						",%ld,%ld;", | 							sprint(buf, ",%ld,%ld;", | ||||||
| 						sdef->sd_offset*8+sdef->sd_type->tp_field->fd_shift, | 									sdef->sd_offset * 8 | ||||||
| 						sdef->sd_type->tp_field->fd_width)); | 											+ sdef->sd_type->tp_field->fd_shift, | ||||||
|  | 									sdef->sd_type->tp_field->fd_width)); | ||||||
| 				} | 				} | ||||||
| 				else { | 				else | ||||||
|  | 				{ | ||||||
| 					stb_type(sdef->sd_type); | 					stb_type(sdef->sd_type); | ||||||
| 					adds_db_str(sprint(buf, | 					adds_db_str( | ||||||
| 						",%ld,%ld;", | 							sprint(buf, ",%ld,%ld;", sdef->sd_offset * 8, | ||||||
| 						sdef->sd_offset*8, | 									sdef->sd_type->tp_size * 8)); | ||||||
| 						sdef->sd_type->tp_size*8)); |  | ||||||
| 				} | 				} | ||||||
| 				sdef = sdef->sd_sdef; | 				sdef = sdef->sd_sdef; | ||||||
| 			} | 			} | ||||||
|  | @ -213,9 +213,7 @@ stb_type(tp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| stb_tag(tg, str) | void stb_tag(register struct tag *tg, char *str) | ||||||
| 	register struct tag	*tg; |  | ||||||
| 	char			*str; |  | ||||||
| { | { | ||||||
| 	create_db_str(); | 	create_db_str(); | ||||||
| 	adds_db_str(str); | 	adds_db_str(str); | ||||||
|  | @ -223,16 +221,12 @@ stb_tag(tg, str) | ||||||
| 	stb_type(tg->tg_type); | 	stb_type(tg->tg_type); | ||||||
| 	addc_db_str(';'); | 	addc_db_str(';'); | ||||||
| 	C_ms_stb_cst(db_str.base, | 	C_ms_stb_cst(db_str.base, | ||||||
| 		     N_LSYM, | 	N_LSYM, | ||||||
| 		     tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 | 			tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 ? | ||||||
| 		       ? 0 | 					0 : (int) tg->tg_type->tp_size, (arith) 0); | ||||||
| 		       : (int)tg->tg_type->tp_size, |  | ||||||
| 		     (arith) 0); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| stb_typedef(tp, str) | void stb_typedef(register struct type *tp, char *str) | ||||||
| 	register struct type	*tp; |  | ||||||
| 	char			*str; |  | ||||||
| { | { | ||||||
| 	create_db_str(); | 	create_db_str(); | ||||||
| 	adds_db_str(str); | 	adds_db_str(str); | ||||||
|  | @ -240,23 +234,19 @@ stb_typedef(tp, str) | ||||||
| 	stb_type(tp); | 	stb_type(tp); | ||||||
| 	addc_db_str(';'); | 	addc_db_str(';'); | ||||||
| 	C_ms_stb_cst(db_str.base, | 	C_ms_stb_cst(db_str.base, | ||||||
| 		     N_LSYM, | 	N_LSYM, tp == void_type || tp->tp_size >= 32767 ? 0 : (int) tp->tp_size, | ||||||
| 		     tp == void_type || tp->tp_size >= 32767 | 			(arith) 0); | ||||||
| 		       ? 0 |  | ||||||
| 		       : (int)tp->tp_size, |  | ||||||
| 		     (arith) 0); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| stb_string(df, kind, str) | void stb_string(register struct def *df, int kind, char* str) | ||||||
| 	register struct def	*df; |  | ||||||
| 	char			*str; |  | ||||||
| { | { | ||||||
| 	register struct type	*tp = df->df_type; | 	register struct type *tp = df->df_type; | ||||||
| 
 | 
 | ||||||
| 	create_db_str(); | 	create_db_str(); | ||||||
| 	adds_db_str(str); | 	adds_db_str(str); | ||||||
| 	addc_db_str(':'); | 	addc_db_str(':'); | ||||||
| 	switch(kind) { | 	switch (kind) | ||||||
|  | 	{ | ||||||
| 	case FUNCTION: | 	case FUNCTION: | ||||||
| 		addc_db_str(df->df_sc == STATIC ? 'f' : 'F'); | 		addc_db_str(df->df_sc == STATIC ? 'f' : 'F'); | ||||||
| 		stb_type(tp->tp_up); | 		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); | 		C_ms_stb_pnam(db_str.base, N_FUN, 1 /* proclevel */, str); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		if (df->df_sc == FORMAL || | 		if (df->df_sc == FORMAL | ||||||
| 		    (df->df_sc == REGISTER && df->df_address >= 0)) { | 				|| (df->df_sc == REGISTER && df->df_address >= 0)) | ||||||
| 						/* value parameter */ | 		{ | ||||||
|  | 			/* value parameter */ | ||||||
| 			addc_db_str('p'); | 			addc_db_str('p'); | ||||||
| 			stb_type(tp); | 			stb_type(tp); | ||||||
| 			addc_db_str(';'); | 			addc_db_str(';'); | ||||||
| 			C_ms_stb_cst(db_str.base, N_PSYM, 0, df->df_address); | 			C_ms_stb_cst(db_str.base, N_PSYM, 0, df->df_address); | ||||||
| 		} | 		} | ||||||
| 		else if (df->df_sc != AUTO && df->df_sc != REGISTER) { | 		else if (df->df_sc != AUTO && df->df_sc != REGISTER) | ||||||
| 						/* global */ | 		{ | ||||||
|  | 			/* global */ | ||||||
| 			int stabtp = df->df_initialized ? N_STSYM : N_LCSYM; | 			int stabtp = df->df_initialized ? N_STSYM : N_LCSYM; | ||||||
| 			if (df->df_sc == STATIC) { | 			if (df->df_sc == STATIC) | ||||||
| 				if (df->df_level >= L_LOCAL) { | 			{ | ||||||
|  | 				if (df->df_level >= L_LOCAL) | ||||||
|  | 				{ | ||||||
| 					addc_db_str('V'); | 					addc_db_str('V'); | ||||||
| 				} | 				} | ||||||
| 				else { | 				else | ||||||
|  | 				{ | ||||||
| 					addc_db_str('S'); | 					addc_db_str('S'); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else { | 			else | ||||||
|  | 			{ | ||||||
| 				addc_db_str('G'); | 				addc_db_str('G'); | ||||||
| 			} | 			} | ||||||
| 			stb_type(tp); | 			stb_type(tp); | ||||||
| 			addc_db_str(';'); | 			addc_db_str(';'); | ||||||
| 			if (df->df_sc == STATIC && df->df_level >= L_LOCAL) { | 			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); | 			{ | ||||||
|  | 				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); | 				C_ms_stb_dnam(db_str.base, stabtp, 0, str, (arith) 0); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else {	/* local variable */ | 		else | ||||||
| 			stb_type(tp);	/* assign type num to avoid
 | 		{ /* local variable */ | ||||||
| 						   difficult to parse string */ | 			stb_type(tp); /* assign type num to avoid
 | ||||||
|  | 			 difficult to parse string */ | ||||||
| 			addc_db_str(';'); | 			addc_db_str(';'); | ||||||
| 			C_ms_stb_cst(db_str.base, N_LSYM, 0, df->df_address); | 			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	"struct.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
| #include	"mes.h" | #include	"mes.h" | ||||||
|  | #include    "code.h" | ||||||
|  | #include    "util.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| /* #include	<em_reg.h> */ | /* #include	<em_reg.h> */ | ||||||
| 
 | 
 | ||||||
|  | @ -41,7 +44,7 @@ struct stack_level *local_level = &UniversalLevel; | ||||||
| 
 | 
 | ||||||
| int level;	/* Always equal to local_level->sl_level. */ | 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.
 | 	/*	A new level is added on top of the identifier stack.
 | ||||||
| 	*/ | 	*/ | ||||||
| 	register struct stack_level *stl = new_stack_level(); | 	register struct stack_level *stl = new_stack_level(); | ||||||
|  | @ -57,10 +60,9 @@ stack_level()	{ | ||||||
| #endif	/* LINT */ | #endif	/* LINT */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void stack_idf( | ||||||
| stack_idf(idf, stl) | 	struct idf *idf, | ||||||
| 	struct idf *idf; | 	register struct stack_level *stl) | ||||||
| 	register struct stack_level *stl; |  | ||||||
| { | { | ||||||
| 	/*	The identifier idf is inserted in the stack on level stl,
 | 	/*	The identifier idf is inserted in the stack on level stl,
 | ||||||
| 		but only if it is not already present at this level. | 		but only if it is not already present at this level. | ||||||
|  | @ -81,8 +83,7 @@ stack_idf(idf, stl) | ||||||
| 	stl->sl_entry = se; | 	stl->sl_entry = se; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct stack_level * | struct stack_level *stack_level_of(int lvl) | ||||||
| stack_level_of(lvl) |  | ||||||
| { | { | ||||||
| 	/*	The stack_level corresponding to level lvl is returned.
 | 	/*	The stack_level corresponding to level lvl is returned.
 | ||||||
| 		The stack should probably be an array, to be extended with | 		The stack should probably be an array, to be extended with | ||||||
|  | @ -100,7 +101,7 @@ stack_level_of(lvl) | ||||||
| 	return stl; | 	return stl; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unstack_level() | void unstack_level(void) | ||||||
| { | { | ||||||
| 	/*	The top level of the identifier stack is removed.
 | 	/*	The top level of the identifier stack is removed.
 | ||||||
| 	*/ | 	*/ | ||||||
|  | @ -174,7 +175,7 @@ unstack_level() | ||||||
| #endif	/* DEBUG */ | #endif	/* DEBUG */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unstack_world() | void unstack_world(void) | ||||||
| { | { | ||||||
| 	/*	The global level of identifiers is scanned, and final
 | 	/*	The global level of identifiers is scanned, and final
 | ||||||
| 		decisions are taken about such issues as | 		decisions are taken about such issues as | ||||||
|  | @ -263,14 +264,13 @@ unstack_world() | ||||||
| extern char *nmlist;	/* BAH! -- main.c	*/ | extern char *nmlist;	/* BAH! -- main.c	*/ | ||||||
| static File *nfp = 0; | static File *nfp = 0; | ||||||
| 
 | 
 | ||||||
| open_name_list() | void open_name_list(void) | ||||||
| { | { | ||||||
| 	if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0) | 	if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0) | ||||||
| 		fatal("cannot create namelist %s", nmlist); | 		fatal("cannot create namelist %s", nmlist); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| namelist(nm) | void namelist(char *nm) | ||||||
| 	char *nm; |  | ||||||
| { | { | ||||||
| 	if (nmlist)	{ | 	if (nmlist)	{ | ||||||
| 		sys_write(nfp, nm, strlen(nm)); | 		sys_write(nfp, nm, strlen(nm)); | ||||||
|  |  | ||||||
|  | @ -2,9 +2,14 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef STACK_H_ | ||||||
|  | #define STACK_H_ | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* IDENTIFIER STACK DEFINITIONS */ | /* IDENTIFIER STACK DEFINITIONS */ | ||||||
| 
 | 
 | ||||||
|  | struct idf; | ||||||
|  | 
 | ||||||
| /*	The identifier stack is implemented as a stack of sets. | /*	The identifier stack is implemented as a stack of sets. | ||||||
| 	The stack is implemented by a doubly linked list, | 	The stack is implemented by a doubly linked list, | ||||||
| 	the sets by singly linked lists. | 	the sets by singly linked lists. | ||||||
|  | @ -30,5 +35,26 @@ struct stack_entry	{ | ||||||
| /* ALLOCDEF "stack_entry" 50 */ | /* ALLOCDEF "stack_entry" 50 */ | ||||||
| 
 | 
 | ||||||
| extern struct stack_level *local_level; | extern struct stack_level *local_level; | ||||||
| extern struct stack_level *stack_level_of(); |  | ||||||
| extern int level; | 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  | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -3,10 +3,10 @@ | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $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) | 	if (n > 0) | ||||||
| 		do | 		do | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef STMT_H_ | ||||||
|  | #define STMT_H_ | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $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	*/ | /*	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 */ | /* ALLOCDEF "stmt_block" 5 */ | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -19,16 +19,23 @@ | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
| #include	"level.h" | #include	"level.h" | ||||||
|  | #include    "ch3.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| /*	Type of previous selector declared with a field width specified,
 | /*	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. | 	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[]; | extern char options[]; | ||||||
| char *symbol2str(); | 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
 | /*	The semantics of the identification of structure/union tags is
 | ||||||
| 	obscure.  Some highly regarded compilers are found out to accept, | 	obscure.  Some highly regarded compilers are found out to accept, | ||||||
|  | @ -51,13 +58,13 @@ int lcm(); | ||||||
| 	as well). | 	as well). | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| add_sel(stp, tp, idf, sdefpp, szp, fd)	/* this is horrible */ | void add_sel( /* this is horrible */ | ||||||
| 	register struct type *stp;	/* type of the structure */ | 	register struct type *stp,	/* type of the structure */ | ||||||
| 	struct type *tp;		/* type of the selector */ | 	struct type *tp,		/* type of the selector */ | ||||||
| 	register struct idf *idf;	/* idf of the selector */ | 	register struct idf *idf,	/* idf of the selector */ | ||||||
| 	struct sdef ***sdefpp;	/* address of hook to selector definition */ | 	struct sdef ***sdefpp,	/* address of hook to selector definition */ | ||||||
| 	arith *szp;		/* pointer to struct size upto here */ | 	arith *szp,		/* pointer to struct size upto here */ | ||||||
| 	struct field *fd; | 	struct field *fd) | ||||||
| { | { | ||||||
| 	/*	The selector idf with type tp is added to two chains: the
 | 	/*	The selector idf with type tp is added to two chains: the
 | ||||||
| 		selector identification chain starting at idf->id_sdef, | 		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) | static void check_selector(register struct idf *idf, struct type *stp) | ||||||
| 	register struct idf *idf; |  | ||||||
| 	struct type *stp;	/* the type of the struct */ |  | ||||||
| { | { | ||||||
| 	/*	checks if idf occurs already as a selector in
 | 	/*	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; | 	register struct sdef *sdef = stp->tp_sdef; | ||||||
| 	 | 	 | ||||||
|  | @ -163,9 +169,7 @@ check_selector(idf, stp) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| declare_struct(fund, idf, tpp) | void declare_struct(int fund, register struct idf *idf, struct type **tpp) | ||||||
| 	register struct idf *idf; |  | ||||||
| 	struct type **tpp; |  | ||||||
| { | { | ||||||
| 	/*	A struct, union or enum (depending on fund) with tag (!)
 | 	/*	A struct, union or enum (depending on fund) with tag (!)
 | ||||||
| 		idf is declared, and its type (incomplete as it may be) is | 		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) | void apply_struct(int fund, | ||||||
| 	register struct idf *idf; | 	register struct idf *idf, | ||||||
| 	struct type **tpp; | 	struct type **tpp) | ||||||
| { | { | ||||||
| 	/*	The occurrence of a struct, union or enum (depending on
 | 	/*	The occurrence of a struct, union or enum (depending on
 | ||||||
| 		fund) with tag idf is noted. It may or may not have been | 		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); | 		declare_struct(fund, idf, tpp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct sdef * | struct sdef *idf2sdef( | ||||||
| idf2sdef(idf, tp) | 	register struct idf *idf, | ||||||
| 	register struct idf *idf; | 	struct type *tp) | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	/*	The identifier idf is identified as a selector
 | 	/*	The identifier idf is identified as a selector
 | ||||||
| 		in the struct tp. | 		in the struct tp. | ||||||
|  | @ -296,9 +299,7 @@ idf2sdef(idf, tp) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if	0 | #if	0 | ||||||
| int | int uniq_selector(register struct sdef *idf_sdef) | ||||||
| uniq_selector(idf_sdef) |  | ||||||
| 	register struct sdef *idf_sdef; |  | ||||||
| { | { | ||||||
| 	/*	Returns true if idf_sdef (which is guaranteed to exist)
 | 	/*	Returns true if idf_sdef (which is guaranteed to exist)
 | ||||||
| 		is unique for this level, i.e there is no other selector | 		is unique for this level, i.e there is no other selector | ||||||
|  | @ -324,12 +325,12 @@ uniq_selector(idf_sdef) | ||||||
| 
 | 
 | ||||||
| #ifndef NOBITFIELD | #ifndef NOBITFIELD | ||||||
| arith | arith | ||||||
| add_field(szp, fd, fdtpp, idf, stp) | add_field( | ||||||
| 	arith *szp;			/* size of struct upto here	*/ | 	arith *szp,			/* size of struct upto here	*/ | ||||||
| 	register struct field *fd;	/* bitfield, containing width	*/ | 	register struct field *fd,	/* bitfield, containing width	*/ | ||||||
| 	register struct type **fdtpp;	/* type of selector		*/ | 	register struct type **fdtpp,	/* type of selector		*/ | ||||||
| 	struct idf *idf;		/* name of selector		*/ | 	struct idf *idf,		/* name of selector		*/ | ||||||
| 	register struct type *stp;	/* current struct descriptor	*/ | 	register struct type *stp)	/* current struct descriptor	*/ | ||||||
| { | { | ||||||
| 	/*	The address where this selector is put is returned. If the
 | 	/*	The address where this selector is put is returned. If the
 | ||||||
| 		selector with specified width does not fit in the word, or | 		selector with specified width does not fit in the word, or | ||||||
|  | @ -438,18 +439,12 @@ add_field(szp, fd, fdtpp, idf, stp) | ||||||
| #endif /* NOBITFIELD */ | #endif /* NOBITFIELD */ | ||||||
| 
 | 
 | ||||||
| /* some utilities */ | /* some utilities */ | ||||||
| int | int is_struct_or_union(register int fund) | ||||||
| is_struct_or_union(fund) |  | ||||||
| 	register int fund; |  | ||||||
| { | { | ||||||
| 	return fund == STRUCT || fund == UNION; | 	return fund == STRUCT || fund == UNION; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*	Greatest Common Divisor
 | static int gcd(register int m, register int n) | ||||||
|  */ |  | ||||||
| int |  | ||||||
| gcd(m, n) |  | ||||||
| 	register int m, n; |  | ||||||
| { | { | ||||||
| 	register int r; | 	register int r; | ||||||
| 
 | 
 | ||||||
|  | @ -461,11 +456,8 @@ gcd(m, n) | ||||||
| 	return m; | 	return m; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*	Least Common Multiple
 | 
 | ||||||
|  */ | static int lcm(register int m, register int n) | ||||||
| int |  | ||||||
| lcm(m, n) |  | ||||||
| 	register int m, n; |  | ||||||
| { | { | ||||||
| 	return m * (n / gcd(m, n)); | 	return m * (n / gcd(m, n)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,17 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef STRUCT_H_ | ||||||
|  | #define STRUCT_H_ | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
|  | 
 | ||||||
|  | #include "arith.h" | ||||||
|  | 
 | ||||||
|  | struct type; | ||||||
|  | struct idf; | ||||||
|  | struct field; | ||||||
|  | 
 | ||||||
| /* SELECTOR DESCRIPTOR */ | /* SELECTOR DESCRIPTOR */ | ||||||
| 
 | 
 | ||||||
| struct sdef	{		/* for selectors */ | struct sdef	{		/* for selectors */ | ||||||
|  | @ -27,4 +37,26 @@ struct tag	{		/* for struct-, union- and enum tags */ | ||||||
| 
 | 
 | ||||||
| /* ALLOCDEF "tag" 10 */ | /* 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	"expr.h" | ||||||
| #include	"type.h" | #include	"type.h" | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
|  | #include    "switch.h" | ||||||
|  | #include    "eval.h" | ||||||
|  | #include    "ch3.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| 
 | 
 | ||||||
| int	density = DENSITY; | int	density = DENSITY; | ||||||
| 
 | 
 | ||||||
| compact(nr, low, up) | static int compact(int nr, arith low, arith up) | ||||||
| 	arith low, up; |  | ||||||
| { | { | ||||||
| 	/*	Careful! up - low might not fit in an arith. And then,
 | 	/*	Careful! up - low might not fit in an arith. And then,
 | ||||||
| 		the test "up-low < 0" might also not work to detect this | 		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. | 	For simplicity, we suppose int_size == word_size. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| code_startswitch(expp) | void code_startswitch(struct expr **expp) | ||||||
| 	struct expr **expp; |  | ||||||
| { | { | ||||||
| 	/*	Check the expression, stack a new case header and
 | 	/*	Check the expression, stack a new case header and
 | ||||||
| 		fill in the necessary fields. | 		fill in the necessary fields. | ||||||
|  | @ -85,7 +87,7 @@ code_startswitch(expp) | ||||||
| 	C_bra(l_table);			/* goto start of switch_table	*/ | 	C_bra(l_table);			/* goto start of switch_table	*/ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| code_endswitch() | void code_endswitch(void) | ||||||
| { | { | ||||||
| 	register struct switch_hdr *sh = switch_stack; | 	register struct switch_hdr *sh = switch_stack; | ||||||
| 	register label tablabel; | 	register label tablabel; | ||||||
|  | @ -158,9 +160,7 @@ code_endswitch() | ||||||
| 	unstack_stmt(); | 	unstack_stmt(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void code_case(struct expr *expr) | ||||||
| code_case(expr) |  | ||||||
| 	struct expr *expr; |  | ||||||
| { | { | ||||||
| 	register arith val; | 	register arith val; | ||||||
| 	register struct case_entry *ce; | 	register struct case_entry *ce; | ||||||
|  | @ -227,8 +227,7 @@ code_case(expr) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void code_default(void) | ||||||
| code_default() |  | ||||||
| { | { | ||||||
| 	register struct switch_hdr *sh = switch_stack; | 	register struct switch_hdr *sh = switch_stack; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,16 @@ | ||||||
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  * See the copyright notice in the ACK home directory, in the file "Copyright". |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  */ |  */ | ||||||
|  | #ifndef SWITCH_H_ | ||||||
|  | #define SWITCH_H_ | ||||||
|  | 
 | ||||||
| /* $Id$ */ | /* $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		*/ | /*		S W I T C H - T A B L E - S T R U C T U R E		*/ | ||||||
| 
 | 
 | ||||||
| struct switch_hdr	{ | struct switch_hdr	{ | ||||||
|  | @ -27,3 +36,12 @@ struct case_entry	{ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* ALLOCDEF "case_entry" 20 */ | /* 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	"LLlex.h" | ||||||
| #include	"tokenname.h" | #include	"tokenname.h" | ||||||
| #include	"Lpars.h" | #include	"Lpars.h" | ||||||
|  | #include    "error.h" | ||||||
| 
 | 
 | ||||||
| /*	To centralize the declaration of %tokens, their presence in this
 | /*	To centralize the declaration of %tokens, their presence in this
 | ||||||
| 	file is taken as their declaration. The Makefile will produce | 	file is taken as their declaration. The Makefile will produce | ||||||
|  | @ -132,8 +133,7 @@ struct tokenname tkfunny[] =	{	/* internal keywords */ | ||||||
| }; | }; | ||||||
| #endif	/* ____ */ | #endif	/* ____ */ | ||||||
| 
 | 
 | ||||||
| reserve(resv) | void reserve(register struct tokenname resv[]) | ||||||
| 	register struct tokenname resv[]; |  | ||||||
| { | { | ||||||
| 	/*	The names of the tokens described in resv are entered
 | 	/*	The names of the tokens described in resv are entered
 | ||||||
| 		as reserved words. | 		as reserved words. | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* TOKENNAME DEFINITION */ | /* TOKENNAME DEFINITION */ | ||||||
|  | #ifndef TOKENNAME_H_ | ||||||
|  | #define TOKENNAME_H_ | ||||||
| 
 | 
 | ||||||
| struct tokenname	{	/*	Used for defining the name of a
 | struct tokenname	{	/*	Used for defining the name of a
 | ||||||
| 					token as identified by its symbol | 					token as identified by its symbol | ||||||
|  | @ -11,3 +13,7 @@ struct tokenname	{	/*	Used for defining the name of a | ||||||
| 	int tn_symbol; | 	int tn_symbol; | ||||||
| 	char *tn_name; | 	char *tn_name; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | void reserve(register struct tokenname resv[]); | ||||||
|  | 
 | ||||||
|  | #endif /* TOKENNAME_H_ */ | ||||||
|  |  | ||||||
|  | @ -16,68 +16,59 @@ | ||||||
| #include	"sizes.h" | #include	"sizes.h" | ||||||
| #include	"align.h" | #include	"align.h" | ||||||
| #include	"decspecs.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
 | /*	To be created dynamically in main() from defaults or from command
 | ||||||
| 	line parameters. |  line parameters. | ||||||
| */ |  */ | ||||||
| struct type | struct type *schar_type, *uchar_type, *short_type, *ushort_type, *word_type, | ||||||
| 	*schar_type, *uchar_type, | 		*uword_type, *int_type, *uint_type, *long_type, *ulong_type, | ||||||
| 	*short_type, *ushort_type, | 		*float_type, *double_type, *lngdbl_type, *void_type, *string_type, | ||||||
| 	*word_type, *uword_type, | 		*funint_type, *error_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 * | struct type *create_type(int fund) | ||||||
| create_type(fund) |  | ||||||
| 	int fund; |  | ||||||
| { | { | ||||||
| 	/*	A brand new struct type is created, and its tp_fund set
 | 	/*	A brand new struct type is created, and its tp_fund set
 | ||||||
| 		to fund. | 	 to fund. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct type *ntp = new_type(); | 	register struct type *ntp = new_type(); | ||||||
| 
 | 
 | ||||||
| 	ntp->tp_fund = fund; | 	ntp->tp_fund = fund; | ||||||
| 	ntp->tp_size = (arith)-1; | 	ntp->tp_size = (arith) -1; | ||||||
| 
 | 
 | ||||||
| 	return ntp; | 	return ntp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | struct type *promoted_type(struct type *tp) | ||||||
| promoted_type(tp) |  | ||||||
| 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) | 		if (tp->tp_unsigned && (int) tp->tp_size == (int) int_size) | ||||||
| 			return uint_type; | 			return uint_type; | ||||||
| 		else return int_type; | 		else | ||||||
| 	} else if (tp->tp_fund == FLOAT) | 			return int_type; | ||||||
|  | 	} | ||||||
|  | 	else if (tp->tp_fund == FLOAT) | ||||||
| 		return double_type; | 		return double_type; | ||||||
| 	else return tp; | 	else | ||||||
|  | 		return tp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | struct type *construct_type(int fund, register struct type *tp, int qual, | ||||||
| construct_type(fund, tp, qual, count, pl) | arith count, /* for fund == ARRAY only */ | ||||||
| 	register struct type *tp; | register struct proto *pl) | ||||||
| 	register struct proto *pl; |  | ||||||
| 	arith count; /* for fund == ARRAY only */ |  | ||||||
| 	int qual; |  | ||||||
| { | { | ||||||
| 	/*	fund must be a type constructor: FIELD, FUNCTION, POINTER or
 | 	/*	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; | 	register struct type *dtp; | ||||||
| 
 | 
 | ||||||
| 	switch (fund)	{ | 	switch (fund) | ||||||
|  | 	{ | ||||||
| #ifndef NOBITFIELD | #ifndef NOBITFIELD | ||||||
| 	case FIELD: | 	case FIELD: | ||||||
| 		dtp = field_of(tp, qual); | 		dtp = field_of(tp, qual); | ||||||
|  | @ -85,11 +76,13 @@ construct_type(fund, tp, qual, count, pl) | ||||||
| #endif /* NOBITFIELD */ | #endif /* NOBITFIELD */ | ||||||
| 
 | 
 | ||||||
| 	case FUNCTION: | 	case FUNCTION: | ||||||
| 		if (tp->tp_fund == FUNCTION)	{ | 		if (tp->tp_fund == FUNCTION) | ||||||
|  | 		{ | ||||||
| 			error("function cannot yield function"); | 			error("function cannot yield function"); | ||||||
| 			return error_type; | 			return error_type; | ||||||
| 		} | 		} | ||||||
| 		if (tp->tp_fund == ARRAY)	{ | 		if (tp->tp_fund == ARRAY) | ||||||
|  | 		{ | ||||||
| 			error("function cannot yield array"); | 			error("function cannot yield array"); | ||||||
| 			return error_type; | 			return error_type; | ||||||
| 		} | 		} | ||||||
|  | @ -100,7 +93,8 @@ construct_type(fund, tp, qual, count, pl) | ||||||
| 		dtp = pointer_to(tp, qual); | 		dtp = pointer_to(tp, qual); | ||||||
| 		break; | 		break; | ||||||
| 	case ARRAY: | 	case ARRAY: | ||||||
| 		if (tp->tp_fund == VOID) { | 		if (tp->tp_fund == VOID) | ||||||
|  | 		{ | ||||||
| 			error("cannot construct array of void"); | 			error("cannot construct array of void"); | ||||||
| 			count = (arith) -1; | 			count = (arith) -1; | ||||||
| 		} | 		} | ||||||
|  | @ -113,14 +107,10 @@ construct_type(fund, tp, qual, count, pl) | ||||||
| 	return dtp; | 	return dtp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | struct type *function_of(register struct type *tp, struct proto *pl, int qual) | ||||||
| function_of(tp, pl, qual) |  | ||||||
| 	register struct type *tp; |  | ||||||
| 	struct proto *pl; |  | ||||||
| 	int qual; |  | ||||||
| { | { | ||||||
| #if 0 | #if 0 | ||||||
| /* See comment below */ | 	/* See comment below */ | ||||||
| 	register struct type *dtp = tp->tp_function; | 	register struct type *dtp = tp->tp_function; | ||||||
| #else | #else | ||||||
| 	register struct type *dtp; | 	register struct type *dtp; | ||||||
|  | @ -128,30 +118,31 @@ function_of(tp, pl, qual) | ||||||
| 
 | 
 | ||||||
| 	/* look for a type with the right qualifier */ | 	/* look for a type with the right qualifier */ | ||||||
| #if 0 | #if 0 | ||||||
| /* the code doesn't work in the following case:
 | 	/* the code doesn't work in the following case:
 | ||||||
| 	int func(); | 	 int func(); | ||||||
| 	int func(int a, int b) { return q(a); } | 	 int func(int a, int b) { return q(a); } | ||||||
|    because updating the type works inside the data-structures for that type | 	 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 | 	 thus, a new type is created for very function. This may change in the | ||||||
|    future, when declarations with empty parameter lists become obsolete. | 	 future, when declarations with empty parameter lists become obsolete. | ||||||
|    When it does, change type.str, decspecs.c, and this routine. Search for | 	 When it does, change type.str, decspecs.c, and this routine. Search for | ||||||
|    the function_of pattern to find the places. | 	 the function_of pattern to find the places. | ||||||
| */ | 	 */ | ||||||
| 	while (dtp && (dtp->tp_typequal != qual || dtp->tp_proto != pl)) | 	while (dtp && (dtp->tp_typequal != qual || dtp->tp_proto != pl)) | ||||||
| 		dtp = dtp->next; | 	dtp = dtp->next; | ||||||
| #else | #else | ||||||
| 	dtp = 0; | 	dtp = 0; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	if (!dtp)	{ | 	if (!dtp) | ||||||
|  | 	{ | ||||||
| 		dtp = create_type(FUNCTION); | 		dtp = create_type(FUNCTION); | ||||||
| 		dtp->tp_up = tp; | 		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_align = pointer_align; | ||||||
| 		dtp->tp_typequal = qual; | 		dtp->tp_typequal = qual; | ||||||
| 		dtp->tp_proto = pl; | 		dtp->tp_proto = pl; | ||||||
| #if 0 | #if 0 | ||||||
| /* See comment above */ | 		/* See comment above */ | ||||||
| 		dtp->next = tp->tp_function; | 		dtp->next = tp->tp_function; | ||||||
| 		tp->tp_function = dtp; | 		tp->tp_function = dtp; | ||||||
| #endif | #endif | ||||||
|  | @ -159,10 +150,7 @@ function_of(tp, pl, qual) | ||||||
| 	return dtp; | 	return dtp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | struct type *pointer_to(register struct type *tp, int qual) | ||||||
| pointer_to(tp, qual) |  | ||||||
| 	register struct type *tp; |  | ||||||
| 	int qual; |  | ||||||
| { | { | ||||||
| 	register struct type *dtp = tp->tp_pointer; | 	register struct type *dtp = tp->tp_pointer; | ||||||
| 
 | 
 | ||||||
|  | @ -170,7 +158,8 @@ pointer_to(tp, qual) | ||||||
| 	while (dtp && dtp->tp_typequal != qual) | 	while (dtp && dtp->tp_typequal != qual) | ||||||
| 		dtp = dtp->next; | 		dtp = dtp->next; | ||||||
| 
 | 
 | ||||||
| 	if (!dtp)	{ | 	if (!dtp) | ||||||
|  | 	{ | ||||||
| 		dtp = create_type(POINTER); | 		dtp = create_type(POINTER); | ||||||
| 		dtp->tp_unsigned = 1; | 		dtp->tp_unsigned = 1; | ||||||
| 		dtp->tp_up = tp; | 		dtp->tp_up = tp; | ||||||
|  | @ -183,11 +172,7 @@ pointer_to(tp, qual) | ||||||
| 	return dtp; | 	return dtp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | struct type * array_of(register struct type *tp, arith count, int qual) | ||||||
| array_of(tp, count, qual) |  | ||||||
| 	register struct type *tp; |  | ||||||
| 	arith count; |  | ||||||
| 	int qual; |  | ||||||
| { | { | ||||||
| 	register struct type *dtp = tp->tp_array; | 	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)) | 	while (dtp && (dtp->tp_nel != count || dtp->tp_typequal != qual)) | ||||||
| 		dtp = dtp->next; | 		dtp = dtp->next; | ||||||
| 
 | 
 | ||||||
| 	if (!dtp)	{ | 	if (!dtp) | ||||||
|  | 	{ | ||||||
| 		dtp = create_type(ARRAY); | 		dtp = create_type(ARRAY); | ||||||
| 		dtp->tp_up = tp; | 		dtp->tp_up = tp; | ||||||
| 		dtp->tp_nel = count; | 		dtp->tp_nel = count; | ||||||
|  | @ -203,19 +189,18 @@ array_of(tp, count, qual) | ||||||
| 		dtp->tp_typequal = qual; | 		dtp->tp_typequal = qual; | ||||||
| 		dtp->next = tp->tp_array; | 		dtp->next = tp->tp_array; | ||||||
| 		tp->tp_array = dtp; | 		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; | 			dtp->tp_size = count * tp->tp_size; | ||||||
| 		} | 		} | ||||||
| 		else	dtp->tp_size = -1; | 		else | ||||||
|  | 			dtp->tp_size = -1; | ||||||
| 	} | 	} | ||||||
| 	return dtp; | 	return dtp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef NOBITFIELD | #ifndef NOBITFIELD | ||||||
| struct type * | struct type * field_of(register struct type *tp, int qual) | ||||||
| field_of(tp, qual) |  | ||||||
| 	register struct type *tp; |  | ||||||
| 	int qual; |  | ||||||
| { | { | ||||||
| 	register struct type *dtp = create_type(FIELD); | 	register struct type *dtp = create_type(FIELD); | ||||||
| 
 | 
 | ||||||
|  | @ -227,53 +212,47 @@ field_of(tp, qual) | ||||||
| } | } | ||||||
| #endif /* NOBITFIELD */ | #endif /* NOBITFIELD */ | ||||||
| 
 | 
 | ||||||
| arith | arith size_of_type(struct type *tp, char nm[]) | ||||||
| size_of_type(tp, nm) |  | ||||||
| 	struct type *tp; |  | ||||||
| 	char nm[]; |  | ||||||
| { | { | ||||||
| 	arith sz = tp->tp_size; | 	arith sz = tp->tp_size; | ||||||
| 
 | 
 | ||||||
| 	if (sz < 0)	{ | 	if (sz < 0) | ||||||
|  | 	{ | ||||||
| 		error("size of %s unknown", nm); | 		error("size of %s unknown", nm); | ||||||
| 		sz = (arith)1; | 		sz = (arith) 1; | ||||||
| 	} | 	} | ||||||
| 	return sz; | 	return sz; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| idf2type(idf, tpp) | void idf2type(struct idf *idf, struct type **tpp) | ||||||
| 	struct idf *idf; |  | ||||||
| 	struct type **tpp; |  | ||||||
| { | { | ||||||
| 	/*	Decoding  a typedef-ed identifier or basic type: if the
 | 	/*	Decoding  a typedef-ed identifier or basic type: if the
 | ||||||
| 		size is yet unknown we have to make copy of the type | 	 size is yet unknown we have to make copy of the type | ||||||
| 		descriptor to prevent garbage at the initialisation of | 	 descriptor to prevent garbage at the initialisation of | ||||||
| 		arrays with unknown size. | 	 arrays with unknown size. | ||||||
| 	*/ | 	 */ | ||||||
| 	register struct type *tp = idf->id_def->df_type; | 	register struct type *tp = idf->id_def->df_type; | ||||||
| 
 | 
 | ||||||
| 	if (*tpp) error("multiple types in declaration"); | 	if (*tpp) | ||||||
| 	if (	tp->tp_size < (arith)0 && tp->tp_fund == ARRAY)	{ | 		error("multiple types in declaration"); | ||||||
|  | 	if (tp->tp_size < (arith) 0 && tp->tp_fund == ARRAY) | ||||||
|  | 	{ | ||||||
| 		*tpp = new_type(); | 		*tpp = new_type(); | ||||||
| 		**tpp = *tp; | 		**tpp = *tp; | ||||||
| 			/* this is really a structure assignment, AAGH!!! */ | 		/* this is really a structure assignment, AAGH!!! */ | ||||||
| 	} | 	} | ||||||
| 	else	{ | 	else | ||||||
|  | 	{ | ||||||
| 		*tpp = tp; | 		*tpp = tp; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| arith | arith align(arith pos, int al) | ||||||
| align(pos, al) |  | ||||||
| 	arith pos; |  | ||||||
| 	int al; |  | ||||||
| { | { | ||||||
| 	return ((pos + al - 1) / al) * al; | 	return ((pos + al - 1) / al) * al; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct type * | struct type * standard_type(int fund, int sgn, int algn, arith sz) | ||||||
| standard_type(fund, sgn, algn, sz) |  | ||||||
| 	int algn; arith sz; |  | ||||||
| { | { | ||||||
| 	register struct type *tp = create_type(fund); | 	register struct type *tp = create_type(fund); | ||||||
| 
 | 
 | ||||||
|  | @ -284,25 +263,29 @@ standard_type(fund, sgn, algn, sz) | ||||||
| 	return tp; | 	return tp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| completed(tp) | void completed(struct type *tp) | ||||||
| 	struct type *tp; |  | ||||||
| { | { | ||||||
| 	register struct type *atp = tp->tp_array; | 	register struct type *atp = tp->tp_array; | ||||||
| 	register struct type *etp = tp; | 	register struct type *etp = tp; | ||||||
| 
 | 
 | ||||||
| 	switch(etp->tp_fund) { | 	switch (etp->tp_fund) | ||||||
|  | 	{ | ||||||
| 	case STRUCT: | 	case STRUCT: | ||||||
| 	case UNION: | 	case UNION: | ||||||
| 	case ENUM: | 	case ENUM: | ||||||
| 		while (etp = etp->next) { | 		while (etp = etp->next) | ||||||
| 			if (! etp->tp_sdef) etp->tp_sdef = tp->tp_sdef; | 		{ | ||||||
|  | 			if (!etp->tp_sdef) | ||||||
|  | 				etp->tp_sdef = tp->tp_sdef; | ||||||
| 			etp->tp_size = tp->tp_size; | 			etp->tp_size = tp->tp_size; | ||||||
| 			etp->tp_align = tp->tp_align; | 			etp->tp_align = tp->tp_align; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	while (atp) { | 	while (atp) | ||||||
| 		if (atp->tp_nel >= 0) { | 	{ | ||||||
|  | 		if (atp->tp_nel >= 0) | ||||||
|  | 		{ | ||||||
| 			atp->tp_size = atp->tp_nel * tp->tp_size; | 			atp->tp_size = atp->tp_nel * tp->tp_size; | ||||||
| 		} | 		} | ||||||
| 		atp = atp->next; | 		atp = atp->next; | ||||||
|  |  | ||||||
|  | @ -4,8 +4,13 @@ | ||||||
|  */ |  */ | ||||||
| /* $Id$ */ | /* $Id$ */ | ||||||
| /* TYPE DESCRIPTOR */ | /* TYPE DESCRIPTOR */ | ||||||
|  | #ifndef TYPE_H_ | ||||||
|  | #define TYPE_H_ | ||||||
| 
 | 
 | ||||||
| #include	"parameters.h" | #include	"parameters.h" | ||||||
|  | #include    "arith.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| struct type	{ | struct type	{ | ||||||
| 	struct type *next;	/* used for ARRAY and for qualifiers */ | 	struct type *next;	/* used for ARRAY and for qualifiers */ | ||||||
|  | @ -59,13 +64,6 @@ struct type	{ | ||||||
| #define	TQ_VOLATILE	0x01 | #define	TQ_VOLATILE	0x01 | ||||||
| #define	TQ_CONST	0x02 | #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 | extern struct type | ||||||
| 	*schar_type, *uchar_type, | 	*schar_type, *uchar_type, | ||||||
|  | @ -79,6 +77,24 @@ extern struct type | ||||||
| 
 | 
 | ||||||
| extern struct type *pa_type;	/* type.c	*/ | 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 */ | /* ALLOCDEF "type" 50 */ | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -41,16 +41,14 @@ static int	loc_id; | ||||||
| 
 | 
 | ||||||
| extern char options[]; | extern char options[]; | ||||||
| 
 | 
 | ||||||
| LocalInit() | void LocalInit(void) | ||||||
| { | { | ||||||
| #ifdef USE_TMP | #ifdef USE_TMP | ||||||
| 	C_insertpart(loc_id = C_getid()); | 	C_insertpart(loc_id = C_getid()); | ||||||
| #endif /* USE_TMP */ | #endif /* USE_TMP */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| arith | arith LocalSpace(arith sz, int al) | ||||||
| LocalSpace(sz, al) |  | ||||||
| 	arith sz; |  | ||||||
| { | { | ||||||
| 	register struct stack_level *stl = local_level; | 	register struct stack_level *stl = local_level; | ||||||
| 
 | 
 | ||||||
|  | @ -61,9 +59,7 @@ LocalSpace(sz, al) | ||||||
| #define TABSIZ 32 | #define TABSIZ 32 | ||||||
| static struct localvar *regs[TABSIZ]; | static struct localvar *regs[TABSIZ]; | ||||||
| 
 | 
 | ||||||
| arith | arith NewLocal(arith sz, int al, int regtype, int sc) | ||||||
| NewLocal(sz, al, regtype, sc) |  | ||||||
| 	arith sz; |  | ||||||
| { | { | ||||||
| 	register struct localvar *tmp = FreeTmps; | 	register struct localvar *tmp = FreeTmps; | ||||||
| 	struct localvar *prev = 0; | 	struct localvar *prev = 0; | ||||||
|  | @ -98,8 +94,7 @@ NewLocal(sz, al, regtype, sc) | ||||||
| 	return tmp->t_offset; | 	return tmp->t_offset; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FreeLocal(off) | void FreeLocal(arith off) | ||||||
| 	arith off; |  | ||||||
| { | { | ||||||
| 	int index = (int) (off >> 2) & (TABSIZ - 1); | 	int index = (int) (off >> 2) & (TABSIZ - 1); | ||||||
| 	register struct localvar *tmp = regs[index]; | 	register struct localvar *tmp = regs[index]; | ||||||
|  | @ -117,7 +112,7 @@ FreeLocal(off) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LocalFinish() | void LocalFinish(void) | ||||||
| { | { | ||||||
| 	register struct localvar *tmp, *tmp1; | 	register struct localvar *tmp, *tmp1; | ||||||
| 	register int i; | 	register int i; | ||||||
|  | @ -163,9 +158,7 @@ LocalFinish() | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void RegisterAccount(arith offset, arith size, int regtype, int sc) | ||||||
| RegisterAccount(offset, size, regtype, sc) |  | ||||||
| 	arith offset, size; |  | ||||||
| { | { | ||||||
| 	register struct localvar *p; | 	register struct localvar *p; | ||||||
| 	int index; | 	int index; | ||||||
|  | @ -183,9 +176,7 @@ RegisterAccount(offset, size, regtype, sc) | ||||||
| 	regs[index] = p; | 	regs[index] = p; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct localvar * | static struct localvar *find_reg(arith off) | ||||||
| find_reg(off) |  | ||||||
| 	arith off; |  | ||||||
| { | { | ||||||
| 	register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)]; | 	register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)]; | ||||||
| 
 | 
 | ||||||
|  | @ -193,8 +184,7 @@ find_reg(off) | ||||||
| 	return p; | 	return p; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LoadLocal(off, sz) | void LoadLocal(arith off, arith sz) | ||||||
| 	arith off, sz; |  | ||||||
| { | { | ||||||
| 	register struct localvar *p = find_reg(off); | 	register struct localvar *p = find_reg(off); | ||||||
| 
 | 
 | ||||||
|  | @ -213,8 +203,7 @@ LoadLocal(off, sz) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| StoreLocal(off, sz) | void StoreLocal(arith off, arith sz) | ||||||
| 	arith off, sz; |  | ||||||
| { | { | ||||||
| 	register struct localvar *p = find_reg(off); | 	register struct localvar *p = find_reg(off); | ||||||
| 
 | 
 | ||||||
|  | @ -234,8 +223,7 @@ StoreLocal(off, sz) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifndef	LINT | #ifndef	LINT | ||||||
| AddrLocal(off) | void AddrLocal(arith off) | ||||||
| 	arith off; |  | ||||||
| { | { | ||||||
| 	register struct localvar *p = find_reg(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 { | ||||||
| 	struct localvar	*next; | 	struct localvar	*next; | ||||||
| 	arith		t_offset;	/* offset from LocalBase */ | 	arith		t_offset;	/* offset from LocalBase */ | ||||||
|  | @ -9,3 +14,18 @@ struct localvar { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* ALLOCDEF "localvar" 10 */ | /* 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