Kaynağa Gözat

many changes: fixes and efficiency-oriented

ceriel 37 yıl önce
ebeveyn
işleme
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
 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
 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
 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
 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
 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
 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
 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
 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
 !File: idfsize.h
-#define	IDFSIZE	30	/* maximum significant length of an identifier	*/
+#define	IDFSIZE	64	/* maximum significant length of an identifier	*/
 
 
 
 
 !File: numsize.h
 !File: numsize.h
@@ -86,7 +86,7 @@
 
 
 
 
 !File: debug.h
 !File: debug.h
-#define DEBUG		1	/* perform various self-tests		*/
+#undef DEBUG		1	/* perform various self-tests		*/
 
 
 
 
 !File: use_tmp.h
 !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
 int
 any2arith(expp, oper)
 any2arith(expp, oper)
 	register struct expr **expp;
 	register struct expr **expp;
+	register int oper;
 {
 {
 	/*	Turns any expression into int_type, long_type or
 	/*	Turns any expression into int_type, long_type or
 		double_type.
 		double_type.
@@ -211,14 +212,31 @@ arith2arith(tp, oper, expr)
 int
 int
 int2int(expp, tp)
 int2int(expp, tp)
 	register struct expr **expp;
 	register struct expr **expp;
-	struct type *tp;
+	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.
 	*/
 	*/
 	
 	
 	if (is_cp_cst(*expp))	{
 	if (is_cp_cst(*expp))	{
+		register struct type *tp1 = (*expp)->ex_type;
+
 		(*expp)->ex_type = tp;
 		(*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);
 		cut_size(*expp);
 	}
 	}
 	else	{
 	else	{
@@ -230,7 +248,7 @@ int2int(expp, tp)
 #ifndef NOFLOAT
 #ifndef NOFLOAT
 int
 int
 int2float(expp, tp)
 int2float(expp, tp)
-	struct expr **expp;
+	register struct expr **expp;
 	struct type *tp;
 	struct type *tp;
 {
 {
 	/*	The expression *expp, which is of some integral type, is
 	/*	The expression *expp, which is of some integral type, is
@@ -255,7 +273,7 @@ float2int(expp, tp)
 }
 }
 
 
 float2float(expp, tp)
 float2float(expp, tp)
-	struct expr **expp;
+	register struct expr **expp;
 	struct type *tp;
 	struct type *tp;
 {
 {
 	/*	The expression *expp, which is of some floating type, is
 	/*	The expression *expp, which is of some floating type, is
@@ -273,7 +291,7 @@ float2float(expp, tp)
 #endif NOFLOAT
 #endif NOFLOAT
 
 
 array2pointer(expp)
 array2pointer(expp)
-	struct expr **expp;
+	register struct expr **expp;
 {
 {
 	/*	The expression, which must be an array, is converted
 	/*	The expression, which must be an array, is converted
 		to a pointer.
 		to a pointer.
@@ -326,7 +344,7 @@ opnd2logical(expp, oper)
 	register struct expr **expp;
 	register struct expr **expp;
 	int oper;
 	int oper;
 {
 {
-	register int fund;
+	int fund;
 
 
 	if ((*expp)->ex_type->tp_fund == FUNCTION)
 	if ((*expp)->ex_type->tp_fund == FUNCTION)
 		function2pointer(expp);
 		function2pointer(expp);
@@ -478,7 +496,7 @@ field2arith(expp)
 		ch7bin(expp, '&', intexpr(fd->fd_mask, INT));
 		ch7bin(expp, '&', intexpr(fd->fd_mask, INT));
 	}
 	}
 	else	{	/* take care of the sign bit: sign extend if needed */
 	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,
 		ch7bin(expp, LEFT,
 			intexpr(bits_in_type - fd->fd_width - fd->fd_shift,
 			intexpr(bits_in_type - fd->fd_width - fd->fd_shift,

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

@@ -1,12 +1,12 @@
 /* $Header$ */
 /* $Header$ */
 /*		A S M			*/
 /*		A S M			*/
 
 
+/*ARGSUSED*/
 code_asm(s, l)
 code_asm(s, l)
 	char *s;
 	char *s;
 	int l;
 	int l;
 {
 {
 	/*	'asm' '(' string ')' ';'
 	/*	'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);
 	set_traps(trap);
 	ProgCall = *argv++;
 	ProgCall = *argv++;
+	append(&CEM_FLAGS, "-L");
 	while (--argc > 0) {
 	while (--argc > 0) {
 		if (*(str = *argv++) != '-') {
 		if (*(str = *argv++) != '-') {
 			append(&SRCFILES, str);
 			append(&SRCFILES, str);
@@ -269,9 +270,6 @@ main(argc, argv)
 		case 'O':
 		case 'O':
 			append(&O_FLAGS, "-O");
 			append(&O_FLAGS, "-O");
 			break;
 			break;
-		case 'p':
-			append(&CEM_FLAGS, "-p");
-			break;
 		case 'R':
 		case 'R':
 			if (str[2] == '\0')
 			if (str[2] == '\0')
 				append(&CEM_FLAGS, str);
 				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.
 needs not be specified.
 .br
 .br
 \fIOptions\fP is a, possibly empty, sequence of the following combinations:
 \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
 .IP \fB\-D\fIname\fR=\fItext\fR
 .br
 .br
 define \fIname\fR as a macro with \fItext\fR as its replacement text.
 define \fIname\fR as a macro with \fItext\fR as its replacement text.
 .IP \fB\-D\fIname\fR
 .IP \fB\-D\fIname\fR
 .br
 .br
 the same as \fB\-D\fIname\fR=1.
 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
 .IP \fB\-I\fIdirname\fR
 .br
 .br
 insert \fIdirname\fR in the list of include directories.
 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 
 don't generate the EM \fBfil\fR and \fBlin\fR instructions 
 that usually are generated to enable
 that usually are generated to enable
 an interpreter to keep track of the current location in the source code.
 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
 .IP \fB\-R\fR
 interpret the input as restricted C (according to the language as 
 interpret the input as restricted C (according to the language as 
 described in \fIThe C programming language\fR by Kernighan and Ritchie.)
 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.
 to force a certain option to be handed over to \fBcemcom\fR.
 .LP
 .LP
 .SH FILES
 .SH FILES
-.IR /usr/em/lib/em_cemcom :
+.IR ~em/lib/em_cemcom :
 the compiler
 the compiler
 .SH DIAGNOSTICS
 .SH DIAGNOSTICS
 All warning and error messages are written on standard error output.
 All warning and error messages are written on standard error output.
-.SH BUGS
-Feel free to report them to erikb@vu44.uucp
 .SH REFERENCE
 .SH REFERENCE
 Baalbergen, E.H., D. Grune, M. Waage ;"\fIThe CEM compiler\fR", 
 Baalbergen, E.H., D. Grune, M. Waage ;"\fIThe CEM compiler\fR", 
 Informatica Manual IM-4
 Informatica Manual IM-4

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

@@ -340,7 +340,7 @@ ch7asgn(expp, oper, expr)
 */
 */
 int
 int
 is_integral_type(tp)
 is_integral_type(tp)
-	struct type *tp;
+	register struct type *tp;
 {
 {
 	switch (tp->tp_fund)	{
 	switch (tp->tp_fund)	{
 	case CHAR:
 	case CHAR:
@@ -360,7 +360,7 @@ is_integral_type(tp)
 
 
 int
 int
 is_arith_type(tp)
 is_arith_type(tp)
-	struct type *tp;
+	register struct type *tp;
 {
 {
 	switch (tp->tp_fund)	{
 	switch (tp->tp_fund)	{
 	case CHAR:
 	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;
 	lab_count = (label) 1;
 	return_label = text_label();
 	return_label = text_label();
 	return_expr_occurred = 0;
 	return_expr_occurred = 0;
+	prc_entry(name);
 	if (! options['L'])	{	/* profiling */
 	if (! options['L'])	{	/* profiling */
 		if (strcmp(last_fn_given, FileName) != 0)	{
 		if (strcmp(last_fn_given, FileName) != 0)	{
 			/* previous function came from other file */
 			/* previous function came from other file */
@@ -237,9 +238,11 @@ end_proc(fbytes, nbytes)
 	if (options['d'])
 	if (options['d'])
 		DfaEndFunction();
 		DfaEndFunction();
 #endif	DATAFLOW
 #endif	DATAFLOW
+	prc_exit();
 	C_ret((arith)0);
 	C_ret((arith)0);
 	if (return_expr_occurred != 0)	{
 	if (return_expr_occurred != 0)	{
 		C_df_ilb(return_label);
 		C_df_ilb(return_label);
+		prc_exit();
 		if (func_res_label != 0)	{
 		if (func_res_label != 0)	{
 			C_lae_dlb(func_res_label, (arith)0);
 			C_lae_dlb(func_res_label, (arith)0);
 			store_block(func_tp->tp_size, func_tp->tp_align);
 			store_block(func_tp->tp_size, func_tp->tp_align);
@@ -268,6 +271,7 @@ do_return()
 {
 {
 	/*	do_return generates a direct return */
 	/*	do_return generates a direct return */
 	/*	isn't a jump to the return label smarter ??? */
 	/*	isn't a jump to the return label smarter ??? */
+	prc_exit();
 	C_ret((arith)0);
 	C_ret((arith)0);
 }
 }
 
 
@@ -386,7 +390,7 @@ code_declaration(idf, expr, lvl, sc)
 
 
 loc_init(expr, id)
 loc_init(expr, id)
 	struct expr *expr;
 	struct expr *expr;
-	struct idf *id;
+	register 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.
@@ -550,6 +554,29 @@ unstack_stmt()
 		which may contain break or continue
 		which may contain break or continue
 	*/
 	*/
 	register struct stmt_block *sbp = stmt_stack;
 	register struct stmt_block *sbp = stmt_stack;
-	stmt_stack = stmt_stack->next;
+	stmt_stack = sbp->next;
 	free_stmt_block(sbp);
 	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)
 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 */
 	if (from_type == to_type)	/* a little optimisation */
 		return;
 		return;
-	from_size = from_type->tp_size;
-	to_size = to_type->tp_size;
 	switch (fundamental(from_type))	{
 	switch (fundamental(from_type))	{
 	case T_SIGNED:
 	case T_SIGNED:
 		switch (fundamental(to_type))	{
 		switch (fundamental(to_type))	{
@@ -50,7 +48,7 @@ conversion(from_type, to_type)
 #ifndef NOFLOAT
 #ifndef NOFLOAT
 		case T_FLOATING:
 		case T_FLOATING:
 			C_loc(from_size < word_size ? word_size : from_size);
 			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();
 			C_cif();
 			break;
 			break;
 #endif NOFLOAT
 #endif NOFLOAT
@@ -75,7 +73,7 @@ conversion(from_type, to_type)
 		break;
 		break;
 #ifndef NOFLOAT
 #ifndef NOFLOAT
 	case T_FLOATING:
 	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);
 		C_loc(to_size < word_size ? word_size : to_size);
 		switch (fundamental(to_type))	{
 		switch (fundamental(to_type))	{
 		case T_SIGNED:
 		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
 	/*	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.
 	*/
 	*/
-	arith o1 = expr->VL_VALUE;
+	register arith o1 = expr->VL_VALUE;
 	int uns = expr->ex_type->tp_unsigned;
 	int uns = expr->ex_type->tp_unsigned;
 	int size = (int) expr->ex_type->tp_size;
 	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.
 	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
 	/*	Reads a non-empty decl_specifiers and fills the struct
 		decspecs *ds.
 		decspecs *ds.
 	*/
 	*/
@@ -75,8 +75,7 @@ decl_specifiers	/* non-empty */ (struct decspecs *ds;)
 ;
 ;
 
 
 /* 8.1 */
 /* 8.1 */
-other_specifier(struct decspecs *ds;):
-[
+other_specifier(register struct decspecs *ds;):
 	[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
 	[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
 	{	if (ds->ds_sc_given)
 	{	if (ds->ds_sc_given)
 			error("repeated storage class specifier");
 			error("repeated storage class specifier");
@@ -97,7 +96,6 @@ other_specifier(struct decspecs *ds;):
 			error("unsigned specified twice");
 			error("unsigned specified twice");
 		else	ds->ds_unsigned = 1;
 		else	ds->ds_unsigned = 1;
 	}
 	}
-]
 ;
 ;
 
 
 /* 8.2 */
 /* 8.2 */
@@ -117,15 +115,13 @@ type_specifier(struct type **tpp;)
 	{*tpp = Ds.ds_type;}
 	{*tpp = Ds.ds_type;}
 ;
 ;
 
 
-single_type_specifier(struct decspecs *ds;):
-[
+single_type_specifier(register struct decspecs *ds;):
 	TYPE_IDENTIFIER		/* this includes INT, CHAR, etc. */
 	TYPE_IDENTIFIER		/* this includes INT, CHAR, etc. */
 	{idf2type(dot.tk_idf, &ds->ds_type);}
 	{idf2type(dot.tk_idf, &ds->ds_type);}
 |
 |
 	struct_or_union_specifier(&ds->ds_type)
 	struct_or_union_specifier(&ds->ds_type)
 |
 |
 	enum_specifier(&ds->ds_type)
 	enum_specifier(&ds->ds_type)
-]
 ;
 ;
 
 
 /* 8.3 */
 /* 8.3 */
@@ -134,7 +130,7 @@ init_declarator_list(struct decspecs *ds;):
 	[ ',' init_declarator(ds) ]*
 	[ ',' init_declarator(ds) ]*
 ;
 ;
 
 
-init_declarator(struct decspecs *ds;)
+init_declarator(register struct decspecs *ds;)
 	{
 	{
 		struct declarator Dc;
 		struct declarator Dc;
 		struct expr *expr = (struct expr *) 0;
 		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
 	we just include the (formal) parameter list in the declarator
 	description list dc.
 	description list dc.
 */
 */
-declarator(struct declarator *dc;)
+declarator(register struct declarator *dc;)
 	{
 	{
 		arith count;
 		arith count;
 		struct formal *fm = 0;
 		struct formal *fm = 0;
 	}
 	}
 :
 :
-[
 	primary_declarator(dc)
 	primary_declarator(dc)
 	[%while(1)			/*	int i (M + 2) / 4;
 	[%while(1)			/*	int i (M + 2) / 4;
 						is a function, not an
 						is a function, not an
@@ -190,15 +185,12 @@ declarator(struct declarator *dc;)
 |
 |
 	'*' declarator(dc)
 	'*' declarator(dc)
 	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
 	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
-]
 ;
 ;
 
 
-primary_declarator(struct declarator *dc;) :
-[
+primary_declarator(register struct declarator *dc;) :
 	identifier(&dc->dc_idf)
 	identifier(&dc->dc_idf)
 |
 |
 	'(' declarator(dc) ')'
 	'(' declarator(dc) ')'
-]
 ;
 ;
 
 
 arrayer(arith *sizep;)
 arrayer(arith *sizep;)
@@ -229,7 +221,7 @@ formal(struct formal **fmp;)
 :
 :
 	identifier(&idf)
 	identifier(&idf)
 	{
 	{
-		struct formal *new = new_formal();
+		register struct formal *new = new_formal();
 		
 		
 		new->fm_idf = idf;
 		new->fm_idf = idf;
 		new->next = *fmp;
 		new->next = *fmp;
@@ -238,7 +230,7 @@ formal(struct formal **fmp;)
 ;
 ;
 
 
 /* Change 2 */
 /* Change 2 */
-enum_specifier(struct type **tpp;)
+enum_specifier(register struct type **tpp;)
 	{
 	{
 		struct idf *idf;
 		struct idf *idf;
 		arith l = (arith)0;
 		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)
 	enumerator(tp, lp)
 	[%while(AHEAD != '}')		/* >>> conflict on ',' */
 	[%while(AHEAD != '}')		/* >>> conflict on ',' */
@@ -294,10 +286,11 @@ enumerator(struct type *tp; arith *lp;)
 ;
 ;
 
 
 /* 8.5 */
 /* 8.5 */
-struct_or_union_specifier(struct type **tpp;)
+struct_or_union_specifier(register struct type **tpp;)
 	{
 	{
 		int fund;
 		int fund;
-		struct idf *idf;
+		struct idf *idfX;
+		register struct idf *idf;
 	}
 	}
 :
 :
 	[ STRUCT | UNION ]
 	[ STRUCT | UNION ]
@@ -308,7 +301,7 @@ struct_or_union_specifier(struct type **tpp;)
 		}
 		}
 		struct_declaration_pack(*tpp)
 		struct_declaration_pack(*tpp)
 	|
 	|
-		identifier(&idf)
+		identifier(&idfX)	{ idf = idfX; }
 		[
 		[
 			{
 			{
 				declare_struct(fund, idf, tpp);
 				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;
 		struct sdef **sdefp = &stp->tp_sdef;
 		arith size = (arith)0;
 		arith size = (arith)0;
@@ -402,7 +395,7 @@ bit_expression(struct field **fd;)
 ;
 ;
 
 
 /* 8.6 */
 /* 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
 /*	This code is an abject copy of that of 'declarator', for lack of
 	a two-level grammar.
 	a two-level grammar.
 */
 */
-abstract_declarator(struct declarator *dc;)
+abstract_declarator(register struct declarator *dc;)
 	{arith count;}
 	{arith count;}
 :
 :
-[
 	primary_abstract_declarator(dc)
 	primary_abstract_declarator(dc)
 	[
 	[
 		'(' ')'
 		'(' ')'
@@ -455,7 +447,6 @@ abstract_declarator(struct declarator *dc;)
 |
 |
 	'*' abstract_declarator(dc)
 	'*' abstract_declarator(dc)
 	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
 	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
-]
 ;
 ;
 
 
 primary_abstract_declarator(struct declarator *dc;) :
 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) {
 				if (gencode) {
 					EVAL(right, RVAL, TRUE, l_true,
 					EVAL(right, RVAL, TRUE, l_true,
 						l_false);
 						l_false);
-					C_df_ilb(l_false);
-					C_loc((arith)0);
-					C_bra(l_end);
 					C_df_ilb(l_true);
 					C_df_ilb(l_true);
 					C_loc((arith)1);
 					C_loc((arith)1);
+					C_bra(l_end);
+					C_df_ilb(l_false);
+					C_loc((arith)0);
 					C_df_ilb(l_end);
 					C_df_ilb(l_end);
 				}
 				}
 				else {
 				else {
@@ -578,23 +578,10 @@ EVAL(expr, val, code, true_label, false_label)
 			break;
 			break;
 		case '!':
 		case '!':
 			if (true_label == 0) {
 			if (true_label == 0) {
+				EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
 				if (gencode) {
 				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
 			else
 				EVAL(right, RVAL, gencode, false_label,
 				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)
 check_conditional(expr, oper, pos_descr)
-	struct expr *expr;
+	register struct expr *expr;
 	char *pos_descr;
 	char *pos_descr;
 {
 {
 	/*	Warn if restricted C is in effect and the expression expr,
 	/*	Warn if restricted C is in effect and the expression expr,
@@ -115,27 +115,29 @@ check_conditional(expr, oper, pos_descr)
 }
 }
 
 
 dot2expr(expp)
 dot2expr(expp)
-	register 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.
 	*/
 	*/
-	*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)	{
 	switch (DOT)	{
 	case IDENTIFIER:
 	case IDENTIFIER:
-		idf2expr(*expp);
+		idf2expr(ex);
 		break;
 		break;
 	case STRING:
 	case STRING:
-		string2expr(*expp);
+		string2expr(ex);
 		break;
 		break;
 	case INTEGER:
 	case INTEGER:
-		int2expr(*expp);
+		int2expr(ex);
 		break;
 		break;
 #ifndef NOFLOAT
 #ifndef NOFLOAT
 	case FLOATING:
 	case FLOATING:
-		float2expr(*expp);
+		float2expr(ex);
 		break;
 		break;
 #endif NOFLOAT
 #endif NOFLOAT
 	default:
 	default:
@@ -294,7 +296,7 @@ fill_int_expr(ex, ivalue, fund)
 struct expr *
 struct expr *
 new_oper(tp, e1, oper, e2)
 new_oper(tp, e1, oper, e2)
 	struct type *tp;
 	struct type *tp;
-	struct expr *e1, *e2;
+	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

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

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

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

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

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

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

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

@@ -32,7 +32,7 @@ apply_label(idf)
 }
 }
 
 
 enter_label(idf, defining)
 enter_label(idf, defining)
-	struct idf *idf;
+	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
@@ -40,7 +40,7 @@ enter_label(idf, defining)
 		If defining, the label comes from a label statement.
 		If defining, the label comes from a label statement.
 	*/
 	*/
 	if (idf->id_def)	{
 	if (idf->id_def)	{
-		struct def *def = idf->id_def;
+		register struct def *def = idf->id_def;
 		
 		
 		if (def->df_sc == LABEL)	{
 		if (def->df_sc == LABEL)	{
 			if (defining && def->df_initialized)
 			if (defining && def->df_initialized)
@@ -79,7 +79,7 @@ enter_label(idf, defining)
 }
 }
 
 
 unstack_label(idf)
 unstack_label(idf)
-	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.
 	*/
 	*/

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

@@ -29,6 +29,14 @@ struct macro	{
 
 
 /* ALLOCDEF "macro" 20 */
 /* 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
 /* `token' numbers of keywords of command-line processor
 */
 */
 #define	K_UNKNOWN	0
 #define	K_UNKNOWN	0

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

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

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

@@ -15,6 +15,7 @@
 #include	"sizes.h"
 #include	"sizes.h"
 #include	"align.h"
 #include	"align.h"
 #include	"use_tmp.h"
 #include	"use_tmp.h"
+#include	"dataflow.h"
 
 
 #ifndef NOPP
 #ifndef NOPP
 extern char *inctable[MAXINCL];
 extern char *inctable[MAXINCL];
@@ -41,6 +42,19 @@ do_option(text)
 		options[*text] = 1;	/* flags, debug options etc.	*/
 		options[*text] = 1;	/* flags, debug options etc.	*/
 		break;
 		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		*/
 	case 'C' :	/* E option + comment output		*/
 #ifndef NOPP
 #ifndef NOPP
 		options['E'] = 1;
 		options['E'] = 1;
@@ -49,6 +63,7 @@ do_option(text)
 		warning("-C option ignored");
 		warning("-C option ignored");
 #endif NOPP
 #endif NOPP
 		break;
 		break;
+#endif ___XXX___
 
 
 	case 'D' :	{	/* -Dname :	predefine name		*/
 	case 'D' :	{	/* -Dname :	predefine name		*/
 #ifndef NOPP
 #ifndef NOPP
@@ -86,6 +101,7 @@ do_option(text)
 		break;
 		break;
 	}
 	}
 
 
+#ifdef ___XXX___
 	case 'E' :	/* run preprocessor only, with #<int>	*/
 	case 'E' :	/* run preprocessor only, with #<int>	*/
 #ifndef NOPP
 #ifndef NOPP
 		options['E'] = 1;
 		options['E'] = 1;
@@ -93,6 +109,7 @@ do_option(text)
 		warning("-E option ignored");
 		warning("-E option ignored");
 #endif NOPP
 #endif NOPP
 		break;
 		break;
+#endif ___XXX___
 
 
 	case 'I' :	/* -Ipath : insert "path" into include list	*/
 	case 'I' :	/* -Ipath : insert "path" into include list	*/
 #ifndef NOPP
 #ifndef NOPP
@@ -115,10 +132,6 @@ do_option(text)
 #endif NOPP
 #endif NOPP
 		break;
 		break;
 
 
-	case 'L' :
-		options['L'] = 1;	/* no fil/lin */
-		break;
-
 	case 'M':	/* maximum identifier length */
 	case 'M':	/* maximum identifier length */
 		idfsize = txt2int(&text);
 		idfsize = txt2int(&text);
 		if (*text || idfsize <= 0)
 		if (*text || idfsize <= 0)
@@ -135,6 +148,7 @@ do_option(text)
 #endif USE_TMP
 #endif USE_TMP
 		break;
 		break;
 
 
+#ifdef ___XXX___
 	case 'P' :	/* run preprocessor stand-alone, without #'s	*/
 	case 'P' :	/* run preprocessor stand-alone, without #'s	*/
 #ifndef NOPP
 #ifndef NOPP
 		options['E'] = 1;
 		options['E'] = 1;
@@ -143,10 +157,7 @@ do_option(text)
 		warning("-P option ignored");
 		warning("-P option ignored");
 #endif NOPP
 #endif NOPP
 		break;
 		break;
-
-	case 'R':
-		options['R'] = 1;
-		break;
+#endif ___XXX___
 
 
 #ifdef USE_TMP
 #ifdef USE_TMP
 	case 'T' :
 	case 'T' :
@@ -255,12 +266,6 @@ do_option(text)
 		}
 		}
 		break;
 		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
 control_if_expression
 	{
 	{
-		struct expr *expr;
+		struct expr *exprX;
 	}
 	}
 :
 :
-	constant_expression(&expr)
+	constant_expression(&exprX)
 		{
 		{
 #ifndef NOPP
 #ifndef NOPP
+			register struct expr *expr = exprX;
 			if (expr->ex_flags & EX_SIZEOF)
 			if (expr->ex_flags & EX_SIZEOF)
 				expr_error(expr,
 				expr_error(expr,
 					"sizeof not allowed in preprocessor");
 					"sizeof not allowed in preprocessor");
@@ -113,7 +114,6 @@ external_definition
 		Ds = null_decspecs;
 		Ds = null_decspecs;
 		Dc = null_declarator;
 		Dc = null_declarator;
 	}
 	}
-[
 	ext_decl_specifiers(&Ds)
 	ext_decl_specifiers(&Ds)
 	[
 	[
 		declarator(&Dc)
 		declarator(&Dc)
@@ -133,19 +133,17 @@ external_definition
 	{remove_declarator(&Dc);}
 	{remove_declarator(&Dc);}
 |
 |
 	asm_statement			/* top level, would you believe */
 	asm_statement			/* top level, would you believe */
-]
 ;
 ;
 
 
 ext_decl_specifiers(struct decspecs *ds;) :
 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)
 	decl_specifiers(ds)
 |
 |
 	empty
 	empty
 	{do_decspecs(ds);}
 	{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;
 		struct expr *expr = (struct expr *) 0;
 	}
 	}
@@ -168,7 +166,7 @@ function(struct declarator *dc;)
 		arith fbytes, nbytes;
 		arith fbytes, nbytes;
 	}
 	}
 :
 :
-	{	struct idf *idf = dc->dc_idf;
+	{	register struct idf *idf = dc->dc_idf;
 		
 		
 		init_idf(idf);
 		init_idf(idf);
 		stack_level();		/* L_FORMAL1 declarations */
 		stack_level();		/* L_FORMAL1 declarations */

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

@@ -21,7 +21,7 @@
 char *strcpy(), *strcat();
 char *strcpy(), *strcat();
 char *long2str();
 char *long2str();
 
 
-PRIVATE struct macro	*ReplaceList;	/* list of currently active macros */
+PRIVATE struct mlist	*ReplaceList;	/* list of currently active macros */
 
 
 EXPORT int
 EXPORT int
 replace(idef)
 replace(idef)
@@ -37,7 +37,8 @@ replace(idef)
 		some error has occurred.
 		some error has occurred.
 	*/
 	*/
 	register struct macro *mac = idef->id_macro;
 	register struct macro *mac = idef->id_macro;
-	register char c;
+	register struct mlist *repl;
+	register int c;
 	char **actpars, **getactuals();
 	char **actpars, **getactuals();
 	char *reptext, *macro2buffer();
 	char *reptext, *macro2buffer();
 	int size;
 	int size;
@@ -74,24 +75,34 @@ replace(idef)
 		if (mac->mc_flag & FUNC) {
 		if (mac->mc_flag & FUNC) {
 			struct idf *param = str2idf(*actpars);
 			struct idf *param = str2idf(*actpars);
 
 
+			repl = new_mlist();
 			if (param->id_macro) 
 			if (param->id_macro) 
 				reptext = "1";
 				reptext = "1";
 			else
 			else
 				reptext = "0";
 				reptext = "0";
 			InsertText(reptext, 1);
 			InsertText(reptext, 1);
-			mac->next = ReplaceList;
-			ReplaceList = mac;
+			repl->next = ReplaceList;
+			ReplaceList = repl;
+			repl->m_mac = mac;
 			return 1;
 			return 1;
 		}
 		}
 	}
 	}
+	repl = new_mlist();
+	repl->m_mac = mac;
 	if (mac->mc_flag & FUNC) /* this macro leads to special action	*/
 	if (mac->mc_flag & FUNC) /* this macro leads to special action	*/
 		macro_func(idef);
 		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;
 		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);
 	InsertText(reptext, size);
-	mac->next = ReplaceList;
-	ReplaceList = mac;
+	repl->next = ReplaceList;
+	ReplaceList = repl;
 	return 1;
 	return 1;
 }
 }
 
 
@@ -181,14 +192,18 @@ DoUnstack()
 EXPORT
 EXPORT
 EnableMacros()
 EnableMacros()
 {
 {
-	register struct macro *p = ReplaceList;
+	register struct mlist *p = ReplaceList;
 
 
 	ASSERT(Unstacked > 0);
 	ASSERT(Unstacked > 0);
 	while (Unstacked > 0) {
 	while (Unstacked > 0) {
+		struct mlist *nxt = p->next;
+
 		ASSERT(p != 0);
 		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--;
 		Unstacked--;
 	}
 	}
 	ReplaceList = p;
 	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 **
 PRIVATE char **
 getactuals(idef)
 getactuals(idef)
-	struct idf *idef;
+	register struct idf *idef;
 {
 {
 	/*	getactuals() collects the actual parameters and turns them
 	/*	getactuals() collects the actual parameters and turns them
 		into a list of strings, a pointer to which is returned.
 		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.
 	/*	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();
+	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_level = ++level;
 	stl->sl_local_offset =
 	stl->sl_local_offset =
-	stl->sl_max_block = local_level->sl_local_offset;
+	stl->sl_max_block = loclev->sl_local_offset;
 	local_level = stl;
 	local_level = stl;
 }
 }
 
 

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

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