Переглянути джерело

many changes: fixes and efficiency-oriented

ceriel 37 роки тому
батько
коміт
f7690cec10

+ 2 - 2
lang/cem/cemcom/Makefile.erik

@@ -236,10 +236,10 @@ input.o: file_info.h input.h inputtype.h nopp.h
 domacro.o: LLlex.h Lpars.h arith.h assert.h botch_free.h class.h debug.h file_info.h idf.h idfsize.h ifdepth.h input.h interface.h macro.h nofloat.h nopp.h nparams.h parbufsize.h spec_arith.h textsize.h
 replace.o: LLlex.h arith.h assert.h class.h debug.h file_info.h idf.h input.h interface.h macro.h nofloat.h nopp.h pathlength.h spec_arith.h static.h strsize.h
 init.o: class.h idf.h interface.h macro.h nopp.h
-options.o: align.h arith.h botch_free.h class.h idf.h idfsize.h macro.h maxincl.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h use_tmp.h
+options.o: align.h arith.h botch_free.h class.h dataflow.h idf.h idfsize.h macro.h maxincl.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h use_tmp.h
 scan.o: class.h idf.h input.h interface.h lapbuf.h macro.h nopp.h nparams.h
 skip.o: LLlex.h arith.h class.h file_info.h input.h interface.h nofloat.h nopp.h spec_arith.h
-stack.o: Lpars.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h struct.h type.h use_tmp.h
+stack.o: Lpars.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nofloat.h nopp.h spec_arith.h stack.h struct.h type.h
 type.o: Lpars.h align.h arith.h botch_free.h def.h idf.h nobitfield.h nofloat.h nopp.h sizes.h spec_arith.h type.h
 ch7mon.o: Lpars.h arith.h botch_free.h def.h expr.h idf.h label.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h
 label.o: Lpars.h arith.h def.h idf.h label.h level.h nobitfield.h nofloat.h nopp.h spec_arith.h type.h

+ 2 - 2
lang/cem/cemcom/Parameters

@@ -13,7 +13,7 @@
 
 
 !File: idfsize.h
-#define	IDFSIZE	30	/* maximum significant length of an identifier	*/
+#define	IDFSIZE	64	/* maximum significant length of an identifier	*/
 
 
 !File: numsize.h
@@ -86,7 +86,7 @@
 
 
 !File: debug.h
-#define DEBUG		1	/* perform various self-tests		*/
+#undef DEBUG		1	/* perform various self-tests		*/
 
 
 !File: use_tmp.h

+ 1 - 0
lang/cem/cemcom/Version.c

@@ -0,0 +1 @@
+static char Version[] = "ACK CEM compiler Version 3.1";

+ 24 - 6
lang/cem/cemcom/arith.c

@@ -124,6 +124,7 @@ ch76pointer(expp, oper, tp)
 int
 any2arith(expp, oper)
 	register struct expr **expp;
+	register int oper;
 {
 	/*	Turns any expression into int_type, long_type or
 		double_type.
@@ -211,14 +212,31 @@ arith2arith(tp, oper, expr)
 int
 int2int(expp, tp)
 	register struct expr **expp;
-	struct type *tp;
+	register struct type *tp;
 {
 	/*	The expression *expp, which is of some integral type, is
 		converted to the integral type tp.
 	*/
 	
 	if (is_cp_cst(*expp))	{
+		register struct type *tp1 = (*expp)->ex_type;
+
 		(*expp)->ex_type = tp;
+		if (! tp1->tp_unsigned && tp->tp_unsigned) {
+			/*	Avoid "unreal" overflow warnings, such as
+				caused by f.i.:
+					unsigned int x = ~0;
+					unsigned int y = -1;
+			*/
+			extern long full_mask[];
+			long remainder = (*expp)->VL_VALUE &
+						~full_mask[tp->tp_size];
+
+			if (remainder == 0 ||
+			    remainder == ~full_mask[tp->tp_size]) {
+				(*expp)->VL_VALUE &= ~remainder;
+			}
+		}
 		cut_size(*expp);
 	}
 	else	{
@@ -230,7 +248,7 @@ int2int(expp, tp)
 #ifndef NOFLOAT
 int
 int2float(expp, tp)
-	struct expr **expp;
+	register struct expr **expp;
 	struct type *tp;
 {
 	/*	The expression *expp, which is of some integral type, is
@@ -255,7 +273,7 @@ float2int(expp, tp)
 }
 
 float2float(expp, tp)
-	struct expr **expp;
+	register struct expr **expp;
 	struct type *tp;
 {
 	/*	The expression *expp, which is of some floating type, is
@@ -273,7 +291,7 @@ float2float(expp, tp)
 #endif NOFLOAT
 
 array2pointer(expp)
-	struct expr **expp;
+	register struct expr **expp;
 {
 	/*	The expression, which must be an array, is converted
 		to a pointer.
@@ -326,7 +344,7 @@ opnd2logical(expp, oper)
 	register struct expr **expp;
 	int oper;
 {
-	register int fund;
+	int fund;
 
 	if ((*expp)->ex_type->tp_fund == FUNCTION)
 		function2pointer(expp);
@@ -478,7 +496,7 @@ field2arith(expp)
 		ch7bin(expp, '&', intexpr(fd->fd_mask, INT));
 	}
 	else	{	/* take care of the sign bit: sign extend if needed */
-		register arith bits_in_type = atype->tp_size * 8;
+		arith bits_in_type = atype->tp_size * 8;
 
 		ch7bin(expp, LEFT,
 			intexpr(bits_in_type - fd->fd_width - fd->fd_shift,

+ 2 - 2
lang/cem/cemcom/asm.c

@@ -1,12 +1,12 @@
 /* $Header$ */
 /*		A S M			*/
 
+/*ARGSUSED*/
 code_asm(s, l)
 	char *s;
 	int l;
 {
 	/*	'asm' '(' string ')' ';'
 	*/
-	s = s; l = l;
-	error("\"asm instruction not implemented", s);
+	error("\"asm\" instruction not implemented");
 }

+ 1 - 3
lang/cem/cemcom/cem.c

@@ -166,6 +166,7 @@ main(argc, argv)
 
 	set_traps(trap);
 	ProgCall = *argv++;
+	append(&CEM_FLAGS, "-L");
 	while (--argc > 0) {
 		if (*(str = *argv++) != '-') {
 			append(&SRCFILES, str);
@@ -269,9 +270,6 @@ main(argc, argv)
 		case 'O':
 			append(&O_FLAGS, "-O");
 			break;
-		case 'p':
-			append(&CEM_FLAGS, "-p");
-			break;
 		case 'R':
 			if (str[2] == '\0')
 				append(&CEM_FLAGS, str);

+ 8 - 16
lang/cem/cemcom/cemcom.1

@@ -16,23 +16,12 @@ When the preprocessor is invoked to run stand-alone, \fIdestination\fP
 needs not be specified.
 .br
 \fIOptions\fP is a, possibly empty, sequence of the following combinations:
-.IP \fB\-C\fR
-list the sequence of input tokens while maintaining the comments.
 .IP \fB\-D\fIname\fR=\fItext\fR
 .br
 define \fIname\fR as a macro with \fItext\fR as its replacement text.
 .IP \fB\-D\fIname\fR
 .br
 the same as \fB\-D\fIname\fR=1.
-.IP \fB\-E\fR
-list the sequence of input tokens and delete any comments.
-Control lines of the form
-.RS
-.RS
-#\fBline\fR <\fIinteger\fR> "\fIfilename\fR"
-.RE
-are generated whenever needed.
-.RE
 .IP \fB\-I\fIdirname\fR
 .br
 insert \fIdirname\fR in the list of include directories.
@@ -46,8 +35,13 @@ machine.
 don't generate the EM \fBfil\fR and \fBlin\fR instructions 
 that usually are generated to enable
 an interpreter to keep track of the current location in the source code.
-.IP \fB\-P\fR
-like \fB\-E\fR but without #\fBline\fR control lines.
+.IP \fB\-p\fR
+generate code at each procedure entry to call the routine
+.BR procentry ,
+and at each return to call the routine
+.BE procexit .
+These routines are supplied with one parameter, a pointer to a
+string containing the name of the procedure.
 .IP \fB\-R\fR
 interpret the input as restricted C (according to the language as 
 described in \fIThe C programming language\fR by Kernighan and Ritchie.)
@@ -75,12 +69,10 @@ This feature can be used in various shell scripts and surrounding programs
 to force a certain option to be handed over to \fBcemcom\fR.
 .LP
 .SH FILES
-.IR /usr/em/lib/em_cemcom :
+.IR ~em/lib/em_cemcom :
 the compiler
 .SH DIAGNOSTICS
 All warning and error messages are written on standard error output.
-.SH BUGS
-Feel free to report them to erikb@vu44.uucp
 .SH REFERENCE
 Baalbergen, E.H., D. Grune, M. Waage ;"\fIThe CEM compiler\fR", 
 Informatica Manual IM-4

+ 2 - 2
lang/cem/cemcom/ch7.c

@@ -340,7 +340,7 @@ ch7asgn(expp, oper, expr)
 */
 int
 is_integral_type(tp)
-	struct type *tp;
+	register struct type *tp;
 {
 	switch (tp->tp_fund)	{
 	case CHAR:
@@ -360,7 +360,7 @@ is_integral_type(tp)
 
 int
 is_arith_type(tp)
-	struct type *tp;
+	register struct type *tp;
 {
 	switch (tp->tp_fund)	{
 	case CHAR:

+ 29 - 2
lang/cem/cemcom/code.c

@@ -203,6 +203,7 @@ begin_proc(name, def)	/* to be called when entering a procedure	*/
 	lab_count = (label) 1;
 	return_label = text_label();
 	return_expr_occurred = 0;
+	prc_entry(name);
 	if (! options['L'])	{	/* profiling */
 		if (strcmp(last_fn_given, FileName) != 0)	{
 			/* previous function came from other file */
@@ -237,9 +238,11 @@ end_proc(fbytes, nbytes)
 	if (options['d'])
 		DfaEndFunction();
 #endif	DATAFLOW
+	prc_exit();
 	C_ret((arith)0);
 	if (return_expr_occurred != 0)	{
 		C_df_ilb(return_label);
+		prc_exit();
 		if (func_res_label != 0)	{
 			C_lae_dlb(func_res_label, (arith)0);
 			store_block(func_tp->tp_size, func_tp->tp_align);
@@ -268,6 +271,7 @@ do_return()
 {
 	/*	do_return generates a direct return */
 	/*	isn't a jump to the return label smarter ??? */
+	prc_exit();
 	C_ret((arith)0);
 }
 
@@ -386,7 +390,7 @@ code_declaration(idf, expr, lvl, sc)
 
 loc_init(expr, id)
 	struct expr *expr;
-	struct idf *id;
+	register struct idf *id;
 {
 	/*	loc_init() generates code for the assignment of
 		expression expr to the local variable described by id.
@@ -550,6 +554,29 @@ unstack_stmt()
 		which may contain break or continue
 	*/
 	register struct stmt_block *sbp = stmt_stack;
-	stmt_stack = stmt_stack->next;
+	stmt_stack = sbp->next;
 	free_stmt_block(sbp);
 }
+
+static label l1;
+
+prc_entry(name)
+	char *name;
+{
+	if (options['p']) {
+		C_df_dlb(l1 = data_label());
+		C_rom_scon(name, (arith) (strlen(name) + 1));
+		C_lae_dlb(l1);
+		C_cal("procentry");
+		C_asp(pointer_size);
+	}
+}
+
+prc_exit()
+{
+	if (options['p']) {
+		C_lae_dlb(l1);
+		C_cal("procexit");
+		C_asp(pointer_size);
+	}
+}

+ 5 - 7
lang/cem/cemcom/conversion.c

@@ -25,15 +25,13 @@
 */
 
 conversion(from_type, to_type)
-	struct type *from_type, *to_type;
+	register struct type *from_type, *to_type;
 {
-	arith from_size;
-	arith to_size;
+	register arith from_size = from_type->tp_size;
+	register arith to_size = to_type->tp_size;
 
 	if (from_type == to_type)	/* a little optimisation */
 		return;
-	from_size = from_type->tp_size;
-	to_size = to_type->tp_size;
 	switch (fundamental(from_type))	{
 	case T_SIGNED:
 		switch (fundamental(to_type))	{
@@ -50,7 +48,7 @@ conversion(from_type, to_type)
 #ifndef NOFLOAT
 		case T_FLOATING:
 			C_loc(from_size < word_size ? word_size : from_size);
-			C_loc(to_size < word_size ? word_size : to_size);
+			C_loc(to_size);
 			C_cif();
 			break;
 #endif NOFLOAT
@@ -75,7 +73,7 @@ conversion(from_type, to_type)
 		break;
 #ifndef NOFLOAT
 	case T_FLOATING:
-		C_loc(from_size < word_size ? word_size : from_size);
+		C_loc(from_size);
 		C_loc(to_size < word_size ? word_size : to_size);
 		switch (fundamental(to_type))	{
 		case T_SIGNED:

+ 1 - 1
lang/cem/cemcom/cstoper.c

@@ -184,7 +184,7 @@ cut_size(expr)
 	/*	The constant value of the expression expr is made to
 		conform to the size of the type of the expression.
 	*/
-	arith o1 = expr->VL_VALUE;
+	register arith o1 = expr->VL_VALUE;
 	int uns = expr->ex_type->tp_unsigned;
 	int size = (int) expr->ex_type->tp_size;
 

+ 16 - 25
lang/cem/cemcom/declar.g

@@ -56,7 +56,7 @@ declaration
 	makes all hope of writing a specific grammar for typedefs illusory.
 */
 
-decl_specifiers	/* non-empty */ (struct decspecs *ds;)
+decl_specifiers	/* non-empty */ (register struct decspecs *ds;)
 	/*	Reads a non-empty decl_specifiers and fills the struct
 		decspecs *ds.
 	*/
@@ -75,8 +75,7 @@ decl_specifiers	/* non-empty */ (struct decspecs *ds;)
 ;
 
 /* 8.1 */
-other_specifier(struct decspecs *ds;):
-[
+other_specifier(register struct decspecs *ds;):
 	[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
 	{	if (ds->ds_sc_given)
 			error("repeated storage class specifier");
@@ -97,7 +96,6 @@ other_specifier(struct decspecs *ds;):
 			error("unsigned specified twice");
 		else	ds->ds_unsigned = 1;
 	}
-]
 ;
 
 /* 8.2 */
@@ -117,15 +115,13 @@ type_specifier(struct type **tpp;)
 	{*tpp = Ds.ds_type;}
 ;
 
-single_type_specifier(struct decspecs *ds;):
-[
+single_type_specifier(register struct decspecs *ds;):
 	TYPE_IDENTIFIER		/* this includes INT, CHAR, etc. */
 	{idf2type(dot.tk_idf, &ds->ds_type);}
 |
 	struct_or_union_specifier(&ds->ds_type)
 |
 	enum_specifier(&ds->ds_type)
-]
 ;
 
 /* 8.3 */
@@ -134,7 +130,7 @@ init_declarator_list(struct decspecs *ds;):
 	[ ',' init_declarator(ds) ]*
 ;
 
-init_declarator(struct decspecs *ds;)
+init_declarator(register struct decspecs *ds;)
 	{
 		struct declarator Dc;
 		struct expr *expr = (struct expr *) 0;
@@ -164,13 +160,12 @@ init_declarator(struct decspecs *ds;)
 	we just include the (formal) parameter list in the declarator
 	description list dc.
 */
-declarator(struct declarator *dc;)
+declarator(register struct declarator *dc;)
 	{
 		arith count;
 		struct formal *fm = 0;
 	}
 :
-[
 	primary_declarator(dc)
 	[%while(1)			/*	int i (M + 2) / 4;
 						is a function, not an
@@ -190,15 +185,12 @@ declarator(struct declarator *dc;)
 |
 	'*' declarator(dc)
 	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
-]
 ;
 
-primary_declarator(struct declarator *dc;) :
-[
+primary_declarator(register struct declarator *dc;) :
 	identifier(&dc->dc_idf)
 |
 	'(' declarator(dc) ')'
-]
 ;
 
 arrayer(arith *sizep;)
@@ -229,7 +221,7 @@ formal(struct formal **fmp;)
 :
 	identifier(&idf)
 	{
-		struct formal *new = new_formal();
+		register struct formal *new = new_formal();
 		
 		new->fm_idf = idf;
 		new->next = *fmp;
@@ -238,7 +230,7 @@ formal(struct formal **fmp;)
 ;
 
 /* Change 2 */
-enum_specifier(struct type **tpp;)
+enum_specifier(register struct type **tpp;)
 	{
 		struct idf *idf;
 		arith l = (arith)0;
@@ -260,7 +252,7 @@ enum_specifier(struct type **tpp;)
 	]
 ;
 
-enumerator_pack(struct type *tp; arith *lp;) :
+enumerator_pack(register struct type *tp; arith *lp;) :
 	'{'
 	enumerator(tp, lp)
 	[%while(AHEAD != '}')		/* >>> conflict on ',' */
@@ -294,10 +286,11 @@ enumerator(struct type *tp; arith *lp;)
 ;
 
 /* 8.5 */
-struct_or_union_specifier(struct type **tpp;)
+struct_or_union_specifier(register struct type **tpp;)
 	{
 		int fund;
-		struct idf *idf;
+		struct idf *idfX;
+		register struct idf *idf;
 	}
 :
 	[ STRUCT | UNION ]
@@ -308,7 +301,7 @@ struct_or_union_specifier(struct type **tpp;)
 		}
 		struct_declaration_pack(*tpp)
 	|
-		identifier(&idf)
+		identifier(&idfX)	{ idf = idfX; }
 		[
 			{
 				declare_struct(fund, idf, tpp);
@@ -325,7 +318,7 @@ struct_or_union_specifier(struct type **tpp;)
 	]
 ;
 
-struct_declaration_pack(struct type *stp;)
+struct_declaration_pack(register struct type *stp;)
 	{
 		struct sdef **sdefp = &stp->tp_sdef;
 		arith size = (arith)0;
@@ -402,7 +395,7 @@ bit_expression(struct field **fd;)
 ;
 
 /* 8.6 */
-initializer(struct idf *idf; struct expr **expp;) :
+initializer(register struct idf *idf; register struct expr **expp;) :
 	[
 		'='
 	|
@@ -440,10 +433,9 @@ cast(struct type **tpp;)	{struct declarator Dc;} :
 /*	This code is an abject copy of that of 'declarator', for lack of
 	a two-level grammar.
 */
-abstract_declarator(struct declarator *dc;)
+abstract_declarator(register struct declarator *dc;)
 	{arith count;}
 :
-[
 	primary_abstract_declarator(dc)
 	[
 		'(' ')'
@@ -455,7 +447,6 @@ abstract_declarator(struct declarator *dc;)
 |
 	'*' abstract_declarator(dc)
 	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
-]
 ;
 
 primary_abstract_declarator(struct declarator *dc;) :

+ 5 - 18
lang/cem/cemcom/eval.c

@@ -554,11 +554,11 @@ EVAL(expr, val, code, true_label, false_label)
 				if (gencode) {
 					EVAL(right, RVAL, TRUE, l_true,
 						l_false);
-					C_df_ilb(l_false);
-					C_loc((arith)0);
-					C_bra(l_end);
 					C_df_ilb(l_true);
 					C_loc((arith)1);
+					C_bra(l_end);
+					C_df_ilb(l_false);
+					C_loc((arith)0);
 					C_df_ilb(l_end);
 				}
 				else {
@@ -578,23 +578,10 @@ EVAL(expr, val, code, true_label, false_label)
 			break;
 		case '!':
 			if (true_label == 0) {
+				EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
 				if (gencode) {
-					label l_true = text_label();
-					label l_false = text_label();
-					label l_end = text_label();
-
-					EVAL(right, RVAL, TRUE, l_false,
-						l_true);
-					C_df_ilb(l_false);
-					C_loc((arith)0);
-					C_bra(l_end);
-					C_df_ilb(l_true);
-					C_loc((arith)1);
-					C_df_ilb(l_end);
+					C_teq();
 				}
-				else
-					EVAL(right, RVAL, FALSE, NO_LABEL,
-						NO_LABEL);
 			}
 			else
 				EVAL(right, RVAL, gencode, false_label,

+ 12 - 10
lang/cem/cemcom/expr.c

@@ -102,7 +102,7 @@ rank_of_expression(ex)
 }
 
 check_conditional(expr, oper, pos_descr)
-	struct expr *expr;
+	register struct expr *expr;
 	char *pos_descr;
 {
 	/*	Warn if restricted C is in effect and the expression expr,
@@ -115,27 +115,29 @@ check_conditional(expr, oper, pos_descr)
 }
 
 dot2expr(expp)
-	register struct expr **expp;
+	struct expr **expp;
 {
 	/*	The token in dot is converted into an expression, a
 		pointer to which is stored in *expp.
 	*/
-	*expp = new_expr();
-	(*expp)->ex_file = dot.tk_file;
-	(*expp)->ex_line = dot.tk_line;
+	register struct expr *ex = new_expr();
+
+	*expp = ex;
+	ex->ex_file = dot.tk_file;
+	ex->ex_line = dot.tk_line;
 	switch (DOT)	{
 	case IDENTIFIER:
-		idf2expr(*expp);
+		idf2expr(ex);
 		break;
 	case STRING:
-		string2expr(*expp);
+		string2expr(ex);
 		break;
 	case INTEGER:
-		int2expr(*expp);
+		int2expr(ex);
 		break;
 #ifndef NOFLOAT
 	case FLOATING:
-		float2expr(*expp);
+		float2expr(ex);
 		break;
 #endif NOFLOAT
 	default:
@@ -294,7 +296,7 @@ fill_int_expr(ex, ivalue, fund)
 struct expr *
 new_oper(tp, e1, oper, e2)
 	struct type *tp;
-	struct expr *e1, *e2;
+	register struct expr *e1, *e2;
 {
 	/*	A new expression is constructed which consists of the
 		operator oper which has e1 and e2 as operands; for a

+ 6 - 15
lang/cem/cemcom/expression.g

@@ -15,7 +15,6 @@ extern struct expr *intexpr();
 
 /* 7 */
 initial_value(struct expr **expp;) :
-[
 	assignment_expression(expp)
 		{
 			if ((*expp)->ex_type->tp_fund == ARRAY)
@@ -23,7 +22,6 @@ initial_value(struct expr **expp;) :
 		}
 |
 	initial_value_pack(expp)
-]
 ;
 
 initial_value_pack(struct expr **expp;) :
@@ -48,8 +46,7 @@ initial_value_list(struct expr **expp;)
 
 
 /* 7.1 */
-primary(struct expr **expp;) :
-[
+primary(register struct expr **expp;) :
 	IDENTIFIER
 	{dot2expr(expp);}
 |
@@ -60,10 +57,9 @@ primary(struct expr **expp;) :
 |
 	'(' expression(expp) ')'
 	{(*expp)->ex_flags |= EX_PARENS;}
-]
 ;
 
-secundary(struct expr **expp;) :
+secundary(register struct expr **expp;) :
 	primary(expp)
 	[
 		index_pack(expp)
@@ -124,10 +120,10 @@ postfixed(struct expr **expp;)
 
 %first	first_of_type_specifier, type_specifier;
 
-unary(struct expr **expp;)
+unary(register struct expr **expp;)
 	{struct type *tp; int oper;}
 :
-[%if (first_of_type_specifier(AHEAD))
+%if (first_of_type_specifier(AHEAD))
 	cast(&tp) unary(expp)
 	{	ch7cast(expp, CAST, tp);
 		(*expp)->ex_flags |= EX_CAST;
@@ -139,10 +135,9 @@ unary(struct expr **expp;)
 	{ch7mon(oper, expp);}
 |
 	size_of(expp)
-]
 ;
 
-size_of(struct expr **expp;)
+size_of(register struct expr **expp;)
 	{struct type *tp;}
 :
 	SIZEOF
@@ -273,11 +268,9 @@ unop(int *oper;) :
 ;
 
 postop(int *oper;):
-[
 	PLUSPLUS {*oper = POSTINCR;}
 |
 	MINMIN {*oper = POSTDECR;}
-]
 ;
 
 multop:
@@ -311,8 +304,7 @@ binop(int *oper;) :
 	{*oper = DOT;}
 ;
 
-asgnop(int *oper;):
-[
+asgnop(register int *oper;):
 	'=' {*oper = DOT;}
 |
 	'+' '=' {*oper = PLUSAB;}
@@ -344,7 +336,6 @@ asgnop(int *oper;):
 				symbol2str(DOT));
 			*oper = DOT;
 		}
-]
 ;
 
 constant(struct expr **expp;) :

+ 1 - 1
lang/cem/cemcom/init.c

@@ -46,7 +46,7 @@ init_pp()
 		register struct mkey *mk = &mkey[0];
 
 		while (mk->mk_reserved)	{
-			struct idf *idf = str2idf(mk->mk_reserved);
+			register struct idf *idf = str2idf(mk->mk_reserved);
 			
 			if (idf->id_resmac)
 				fatal("maximum identifier length insufficient");

+ 1 - 1
lang/cem/cemcom/input.c

@@ -12,7 +12,7 @@ struct file_info	finfo;
 #ifndef NOPP
 char *
 getwdir(fn)
-	char *fn;
+	register char *fn;
 {
 	register char *p;
 	char *strrindex();

+ 3 - 3
lang/cem/cemcom/label.c

@@ -32,7 +32,7 @@ apply_label(idf)
 }
 
 enter_label(idf, defining)
-	struct idf *idf;
+	register struct idf *idf;
 {
 	/*	The identifier idf is entered as a label. If it is new,
 		it is entered into the idf list with the largest possible
@@ -40,7 +40,7 @@ enter_label(idf, defining)
 		If defining, the label comes from a label statement.
 	*/
 	if (idf->id_def)	{
-		struct def *def = idf->id_def;
+		register struct def *def = idf->id_def;
 		
 		if (def->df_sc == LABEL)	{
 			if (defining && def->df_initialized)
@@ -79,7 +79,7 @@ enter_label(idf, defining)
 }
 
 unstack_label(idf)
-	struct idf *idf;
+	register struct idf *idf;
 {
 	/*	The scope in which the label idf occurred is left.
 	*/

+ 8 - 0
lang/cem/cemcom/macro.str

@@ -29,6 +29,14 @@ struct macro	{
 
 /* ALLOCDEF "macro" 20 */
 
+struct mlist {
+	struct mlist *next;
+	struct macro *m_mac;
+	char *m_repl;
+};
+
+/* ALLOCDEF "mlist" 20 */
+
 /* `token' numbers of keywords of command-line processor
 */
 #define	K_UNKNOWN	0

+ 13 - 8
lang/cem/cemcom/main.c

@@ -109,7 +109,6 @@ main(argc, argv)
 }
 
 char *source = 0;
-char *destination = 0;
 
 char *nmlist = 0;
 
@@ -127,16 +126,21 @@ compile(argc, argv)
 	char tmpf[256];
 #endif
 	char *result;
+	register char *destination = 0;
 
+#ifdef DEBUG
 #ifndef NOPP
-	int pp_only = options['E'] || options['P'];
+	int pp_only = options['E'] || options['P'] || options['C'];
 #endif NOPP
+#endif
 
 	switch (argc) {
 	case 1:
+#ifdef DEBUG
 #ifndef NOPP
 		if (!pp_only)
 #endif NOPP
+#endif
 			fatal("%s: destination file not specified", prog_name);
 		break;
 	case 2:
@@ -173,21 +177,22 @@ compile(argc, argv)
 #endif NOPP
 	PushLex();
 
+#ifdef DEBUG
 #ifndef NOPP
 	if (pp_only) /* run the preprocessor as if it is stand-alone	*/
 		preprocess();
-	else	{
+	else
 #endif NOPP
+#endif DEBUG
+	{
 
 #ifdef	USE_TMP
 		if (!options['N']) {
 			init_code(tmpfile);
 		}
 		else
-			init_code(destination);
-#else	USE_TMP
-		init_code(destination);
 #endif	USE_TMP
+		init_code(destination);
 
 		/* compile the source text			*/
 		C_program();
@@ -208,9 +213,7 @@ compile(argc, argv)
 		if (options['f'] || options['t'])
 			dumpidftab("end of main", options['f'] ? 0 : 0);
 #endif	DEBUG
-#ifndef NOPP
 	}
-#endif	NOPP
 	PopLex();
 }
 
@@ -302,6 +305,7 @@ init_specials(si)
 	}
 }
 
+#ifdef DEBUG
 #ifndef NOPP
 preprocess()
 {
@@ -373,6 +377,7 @@ preprocess()
 	}
 }
 #endif NOPP
+#endif DEBUG
 
 #ifdef USE_TMP
 AppendFile(src, dst)

+ 19 - 14
lang/cem/cemcom/options.c

@@ -15,6 +15,7 @@
 #include	"sizes.h"
 #include	"align.h"
 #include	"use_tmp.h"
+#include	"dataflow.h"
 
 #ifndef NOPP
 extern char *inctable[MAXINCL];
@@ -41,6 +42,19 @@ do_option(text)
 		options[*text] = 1;	/* flags, debug options etc.	*/
 		break;
 
+#ifdef DATAFLOW
+	case 'd':
+#endif DATAFLOW
+	case 'p':			/* procentry/procexit */
+	case 'L' :			/* no fil/lin */
+	case 'n':			/* use no registers */
+	case 'w':			/* no warnings will be given */
+	case 'R':			/* strict version */
+		options[*(text-1)] = 1;
+		break;
+
+#ifdef ___XXX___
+deleted, is now a debug-flag
 	case 'C' :	/* E option + comment output		*/
 #ifndef NOPP
 		options['E'] = 1;
@@ -49,6 +63,7 @@ do_option(text)
 		warning("-C option ignored");
 #endif NOPP
 		break;
+#endif ___XXX___
 
 	case 'D' :	{	/* -Dname :	predefine name		*/
 #ifndef NOPP
@@ -86,6 +101,7 @@ do_option(text)
 		break;
 	}
 
+#ifdef ___XXX___
 	case 'E' :	/* run preprocessor only, with #<int>	*/
 #ifndef NOPP
 		options['E'] = 1;
@@ -93,6 +109,7 @@ do_option(text)
 		warning("-E option ignored");
 #endif NOPP
 		break;
+#endif ___XXX___
 
 	case 'I' :	/* -Ipath : insert "path" into include list	*/
 #ifndef NOPP
@@ -115,10 +132,6 @@ do_option(text)
 #endif NOPP
 		break;
 
-	case 'L' :
-		options['L'] = 1;	/* no fil/lin */
-		break;
-
 	case 'M':	/* maximum identifier length */
 		idfsize = txt2int(&text);
 		if (*text || idfsize <= 0)
@@ -135,6 +148,7 @@ do_option(text)
 #endif USE_TMP
 		break;
 
+#ifdef ___XXX___
 	case 'P' :	/* run preprocessor stand-alone, without #'s	*/
 #ifndef NOPP
 		options['E'] = 1;
@@ -143,10 +157,7 @@ do_option(text)
 		warning("-P option ignored");
 #endif NOPP
 		break;
-
-	case 'R':
-		options['R'] = 1;
-		break;
+#endif ___XXX___
 
 #ifdef USE_TMP
 	case 'T' :
@@ -255,12 +266,6 @@ do_option(text)
 		}
 		break;
 	}
-	case 'n':
-		options['n'] = 1;	/* use no registers	*/
-		break;
-	case 'w':
-		options['w'] = 1;	/* no warnings will be given	*/
-		break;
 	}
 }
 

+ 6 - 8
lang/cem/cemcom/program.g

@@ -63,12 +63,13 @@ extern error();
 
 control_if_expression
 	{
-		struct expr *expr;
+		struct expr *exprX;
 	}
 :
-	constant_expression(&expr)
+	constant_expression(&exprX)
 		{
 #ifndef NOPP
+			register struct expr *expr = exprX;
 			if (expr->ex_flags & EX_SIZEOF)
 				expr_error(expr,
 					"sizeof not allowed in preprocessor");
@@ -113,7 +114,6 @@ external_definition
 		Ds = null_decspecs;
 		Dc = null_declarator;
 	}
-[
 	ext_decl_specifiers(&Ds)
 	[
 		declarator(&Dc)
@@ -133,19 +133,17 @@ external_definition
 	{remove_declarator(&Dc);}
 |
 	asm_statement			/* top level, would you believe */
-]
 ;
 
 ext_decl_specifiers(struct decspecs *ds;) :
-[%prefer /* the thin ice in  R.M. 11.1 */
+%prefer /* the thin ice in  R.M. 11.1 */
 	decl_specifiers(ds)
 |
 	empty
 	{do_decspecs(ds);}
-]
 ;
 
-non_function(struct decspecs *ds; struct declarator *dc;)
+non_function(register struct decspecs *ds; register struct declarator *dc;)
 	{
 		struct expr *expr = (struct expr *) 0;
 	}
@@ -168,7 +166,7 @@ function(struct declarator *dc;)
 		arith fbytes, nbytes;
 	}
 :
-	{	struct idf *idf = dc->dc_idf;
+	{	register struct idf *idf = dc->dc_idf;
 		
 		init_idf(idf);
 		stack_level();		/* L_FORMAL1 declarations */

+ 27 - 12
lang/cem/cemcom/replace.c

@@ -21,7 +21,7 @@
 char *strcpy(), *strcat();
 char *long2str();
 
-PRIVATE struct macro	*ReplaceList;	/* list of currently active macros */
+PRIVATE struct mlist	*ReplaceList;	/* list of currently active macros */
 
 EXPORT int
 replace(idef)
@@ -37,7 +37,8 @@ replace(idef)
 		some error has occurred.
 	*/
 	register struct macro *mac = idef->id_macro;
-	register char c;
+	register struct mlist *repl;
+	register int c;
 	char **actpars, **getactuals();
 	char *reptext, *macro2buffer();
 	int size;
@@ -74,24 +75,34 @@ replace(idef)
 		if (mac->mc_flag & FUNC) {
 			struct idf *param = str2idf(*actpars);
 
+			repl = new_mlist();
 			if (param->id_macro) 
 				reptext = "1";
 			else
 				reptext = "0";
 			InsertText(reptext, 1);
-			mac->next = ReplaceList;
-			ReplaceList = mac;
+			repl->next = ReplaceList;
+			ReplaceList = repl;
+			repl->m_mac = mac;
 			return 1;
 		}
 	}
+	repl = new_mlist();
+	repl->m_mac = mac;
 	if (mac->mc_flag & FUNC) /* this macro leads to special action	*/
 		macro_func(idef);
-	if (mac->mc_nps <= 0)
+	if (mac->mc_nps <= 0) {
+		reptext = mac->mc_text;
+		size = mac->mc_length;
 		mac->mc_flag |= NOREPLACE;
-	reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
+	}
+	else {
+		reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
+		repl->m_repl = reptext;
+	}
 	InsertText(reptext, size);
-	mac->next = ReplaceList;
-	ReplaceList = mac;
+	repl->next = ReplaceList;
+	ReplaceList = repl;
 	return 1;
 }
 
@@ -181,14 +192,18 @@ DoUnstack()
 EXPORT
 EnableMacros()
 {
-	register struct macro *p = ReplaceList;
+	register struct mlist *p = ReplaceList;
 
 	ASSERT(Unstacked > 0);
 	while (Unstacked > 0) {
+		struct mlist *nxt = p->next;
+
 		ASSERT(p != 0);
-		p->mc_flag &= ~NOREPLACE;
-		p->mc_count = 0;
-		p = p->next;
+		p->m_mac->mc_flag &= ~NOREPLACE;
+		if (p->m_mac->mc_count) p->m_mac->mc_count--;
+		if (p->m_repl) free(p->m_repl);
+		free_mlist(p);
+		p = nxt;
 		Unstacked--;
 	}
 	ReplaceList = p;

+ 1 - 1
lang/cem/cemcom/scan.c

@@ -31,7 +31,7 @@ PRIVATE int nr_of_params;	/* number of actuals read until now	*/
 
 PRIVATE char **
 getactuals(idef)
-	struct idf *idef;
+	register struct idf *idef;
 {
 	/*	getactuals() collects the actual parameters and turns them
 		into a list of strings, a pointer to which is returned.

+ 4 - 3
lang/cem/cemcom/stack.c

@@ -40,12 +40,13 @@ stack_level()	{
 	/*	A new level is added on top of the identifier stack.
 	*/
 	register struct stack_level *stl = new_stack_level();
+	register struct stack_level *loclev = local_level;
 	
-	local_level->sl_next = stl;
-	stl->sl_previous = local_level;
+	loclev->sl_next = stl;
+	stl->sl_previous = loclev;
 	stl->sl_level = ++level;
 	stl->sl_local_offset =
-	stl->sl_max_block = local_level->sl_local_offset;
+	stl->sl_max_block = loclev->sl_local_offset;
 	local_level = stl;
 }
 

+ 1 - 2
lang/cem/cemcom/statement.g

@@ -28,7 +28,7 @@ extern int level;
 /* 9 */
 statement
 :
-[%if (AHEAD != ':')
+%if (AHEAD != ':')
 	expression_statement
 |
 	label ':' statement
@@ -60,7 +60,6 @@ statement
 	';'
 |
 	asm_statement
-]
 ;
 
 expression_statement