Просмотр исходного кода

redesign of ival, other minor changes

ceriel 37 лет назад
Родитель
Сommit
21e14a6f0a
42 измененных файлов с 1143 добавлено и 339 удалено
  1. 5 3
      lang/cem/cemcom/LLlex.c
  2. 79 25
      lang/cem/cemcom/Makefile.erik
  3. 13 8
      lang/cem/cemcom/Parameters
  4. 16 0
      lang/cem/cemcom/align.h
  5. 47 36
      lang/cem/cemcom/arith.c
  6. 1 1
      lang/cem/cemcom/atw.h
  7. 42 37
      lang/cem/cemcom/ch7.c
  8. 6 2
      lang/cem/cemcom/ch7bin.c
  9. 4 4
      lang/cem/cemcom/ch7mon.c
  10. 5 5
      lang/cem/cemcom/code.c
  11. 4 0
      lang/cem/cemcom/code.str
  12. 11 18
      lang/cem/cemcom/conversion.c
  13. 52 36
      lang/cem/cemcom/declar.g
  14. 4 0
      lang/cem/cemcom/declar.str
  15. 7 0
      lang/cem/cemcom/decspecs.c
  16. 4 0
      lang/cem/cemcom/decspecs.str
  17. 4 0
      lang/cem/cemcom/def.str
  18. 24 61
      lang/cem/cemcom/eval.c
  19. 5 0
      lang/cem/cemcom/expr.c
  20. 5 1
      lang/cem/cemcom/expr.str
  21. 10 35
      lang/cem/cemcom/expression.g
  22. 4 0
      lang/cem/cemcom/field.str
  23. 9 0
      lang/cem/cemcom/idf.c
  24. 4 0
      lang/cem/cemcom/idf.str
  25. 1 2
      lang/cem/cemcom/input.c
  26. 656 0
      lang/cem/cemcom/ival.g
  27. 8 26
      lang/cem/cemcom/label.c
  28. 12 0
      lang/cem/cemcom/label.h
  29. 4 0
      lang/cem/cemcom/macro.str
  30. 8 0
      lang/cem/cemcom/main.c
  31. 18 5
      lang/cem/cemcom/options.c
  32. 5 7
      lang/cem/cemcom/program.g
  33. 15 0
      lang/cem/cemcom/sizes.h
  34. 9 7
      lang/cem/cemcom/stack.c
  35. 4 0
      lang/cem/cemcom/stack.str
  36. 6 16
      lang/cem/cemcom/statement.g
  37. 4 0
      lang/cem/cemcom/stmt.str
  38. 11 2
      lang/cem/cemcom/struct.c
  39. 4 0
      lang/cem/cemcom/struct.str
  40. 3 0
      lang/cem/cemcom/switch.c
  41. 5 1
      lang/cem/cemcom/switch.str
  42. 5 1
      lang/cem/cemcom/type.str

+ 5 - 3
lang/cem/cemcom/LLlex.c

@@ -25,14 +25,16 @@
 /* Data about the token yielded */
 struct token dot, ahead, aside;
 
+#ifndef NOPP
 int ReplaceMacros = 1;		/* replacing macros			*/
-int EoiForNewline = 0;		/* return EOI upon encountering newline	*/
 int PreProcKeys = 0;		/* return preprocessor key		*/
-int AccFileSpecifier = 0;	/* return filespecifier <...>		*/
 int AccDefined = 0;		/* accept "defined(...)"		*/
 int UnknownIdIsZero = 0;	/* interpret unknown id as integer 0	*/
-int SkipEscNewline = 0;		/* how to interpret backslash-newline	*/
 int Unstacked = 0;		/* an unstack is done 			*/
+#endif
+int SkipEscNewline = 0;		/* how to interpret backslash-newline	*/
+int AccFileSpecifier = 0;	/* return filespecifier <...>		*/
+int EoiForNewline = 0;		/* return EOI upon encountering newline	*/
 int File_Inserted = 0;		/* a file has just been inserted	*/
 
 #define MAX_LL_DEPTH	2

+ 79 - 25
lang/cem/cemcom/Makefile.erik

@@ -60,9 +60,9 @@ CDEFS =		$(MAP) $(EM_INCLUDES) $(LIB_INCLUDES)
 CFLAGS =	$(CDEFS) $(COPTIONS) -O# we cannot pass the COPTIONS to lint!
 
 # Grammar files and their objects
-LSRC =	tokenfile.g declar.g statement.g expression.g program.g
-GLCSRC = tokenfile.c declar.c statement.c expression.c program.c
-LOBJ =	tokenfile.o declar.o statement.o expression.o program.o Lpars.o
+LSRC =	tokenfile.g declar.g statement.g expression.g program.g ival.g
+GLCSRC = tokenfile.c declar.c statement.c expression.c program.c ival.c
+LOBJ =	tokenfile.o declar.o statement.o expression.o program.o Lpars.o ival.o
 
 # Objects of hand-written C files
 COBJ =	main.o idf.o declarator.o decspecs.o struct.o \
@@ -71,7 +71,7 @@ COBJ =	main.o idf.o declarator.o decspecs.o struct.o \
 	tokenname.o LLlex.o LLmessage.o \
 	input.o domacro.o replace.o init.o options.o \
 	scan.o skip.o stack.o type.o ch7mon.o label.o eval.o \
-	switch.o ival.o conversion.o \
+	switch.o conversion.o \
 	blocks.o dataflow.o Version.o
 
 # Objects of other generated C files
@@ -79,13 +79,13 @@ GOBJ =	char.o symbol2str.o next.o
 
 # generated source files
 GSRC =	char.c symbol2str.c next.c \
-	code.h declar.h decspecs.h def.h expr.h field.h \
+	code.h declar.h decspecs.h def.h expr.h field.h  estack.h \
 	idf.h macro.h stack.h stmt.h struct.h switch.h type.h
 
 # .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE!
 GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
 	idepth.h idfsize.h ifdepth.h inputtype.h inumlength.h lapbuf.h \
-	maxincl.h nobitfield.h nofloat.h nopp.h \
+	maxincl.h nobitfield.h nofloat.h nopp.h noRoption.h nocross.h \
 	nparams.h numsize.h parbufsize.h pathlength.h \
 	strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h
 
@@ -95,6 +95,7 @@ GENERATED = tab tokenfile.g Lpars.h LLfiles LL.output lint.out \
 
 # include files containing ALLOCDEF specifications
 NEXTFILES = code.str declar.str decspecs.str def.str expr.str field.str \
+	estack.str \
 	idf.str macro.str stack.str stmt.str struct.str switch.str type.str
 
 .SUFFIXES: .str .h
@@ -138,6 +139,7 @@ code.h:		make.allocd
 declar.h:	make.allocd
 decspecs.h:	make.allocd
 def.h:		make.allocd
+estack.h:	make.allocd
 expr.h:		make.allocd
 field.h:	make.allocd
 idf.h:		make.allocd
@@ -217,6 +219,7 @@ sim:	cfiles
 #AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
 main.o: LLlex.h
 main.o: Lpars.h
+main.o: align.h
 main.o: arith.h
 main.o: debug.h
 main.o: declar.h
@@ -226,9 +229,12 @@ main.o: input.h
 main.o: inputtype.h
 main.o: level.h
 main.o: maxincl.h
+main.o: noRoption.h
 main.o: nobitfield.h
+main.o: nocross.h
 main.o: nofloat.h
 main.o: nopp.h
+main.o: sizes.h
 main.o: spec_arith.h
 main.o: specials.h
 main.o: target_sizes.h
@@ -250,7 +256,9 @@ idf.o: idf.h
 idf.o: idfsize.h
 idf.o: label.h
 idf.o: level.h
+idf.o: noRoption.h
 idf.o: nobitfield.h
+idf.o: nocross.h
 idf.o: nofloat.h
 idf.o: nopp.h
 idf.o: sizes.h
@@ -258,6 +266,7 @@ idf.o: spec_arith.h
 idf.o: specials.h
 idf.o: stack.h
 idf.o: struct.h
+idf.o: target_sizes.h
 idf.o: type.h
 declarator.o: Lpars.h
 declarator.o: arith.h
@@ -267,16 +276,19 @@ declarator.o: expr.h
 declarator.o: idf.h
 declarator.o: label.h
 declarator.o: nobitfield.h
+declarator.o: nocross.h
 declarator.o: nofloat.h
 declarator.o: nopp.h
 declarator.o: sizes.h
 declarator.o: spec_arith.h
+declarator.o: target_sizes.h
 declarator.o: type.h
 decspecs.o: Lpars.h
 decspecs.o: arith.h
 decspecs.o: decspecs.h
 decspecs.o: def.h
 decspecs.o: level.h
+decspecs.o: noRoption.h
 decspecs.o: nobitfield.h
 decspecs.o: nofloat.h
 decspecs.o: spec_arith.h
@@ -293,13 +305,16 @@ struct.o: field.h
 struct.o: file_info.h
 struct.o: idf.h
 struct.o: level.h
+struct.o: noRoption.h
 struct.o: nobitfield.h
+struct.o: nocross.h
 struct.o: nofloat.h
 struct.o: nopp.h
 struct.o: sizes.h
 struct.o: spec_arith.h
 struct.o: stack.h
 struct.o: struct.h
+struct.o: target_sizes.h
 struct.o: type.h
 expr.o: LLlex.h
 expr.o: Lpars.h
@@ -313,11 +328,14 @@ expr.o: file_info.h
 expr.o: idf.h
 expr.o: label.h
 expr.o: level.h
+expr.o: noRoption.h
 expr.o: nobitfield.h
+expr.o: nocross.h
 expr.o: nofloat.h
 expr.o: nopp.h
 expr.o: sizes.h
 expr.o: spec_arith.h
+expr.o: target_sizes.h
 expr.o: type.h
 ch7.o: Lpars.h
 ch7.o: arith.h
@@ -339,6 +357,7 @@ ch7bin.o: botch_free.h
 ch7bin.o: expr.h
 ch7bin.o: idf.h
 ch7bin.o: label.h
+ch7bin.o: noRoption.h
 ch7bin.o: nobitfield.h
 ch7bin.o: nofloat.h
 ch7bin.o: nopp.h
@@ -353,6 +372,7 @@ cstoper.o: expr.h
 cstoper.o: idf.h
 cstoper.o: label.h
 cstoper.o: nobitfield.h
+cstoper.o: nocross.h
 cstoper.o: nofloat.h
 cstoper.o: nopp.h
 cstoper.o: sizes.h
@@ -367,6 +387,7 @@ arith.o: field.h
 arith.o: idf.h
 arith.o: label.h
 arith.o: mes.h
+arith.o: noRoption.h
 arith.o: nobitfield.h
 arith.o: nofloat.h
 arith.o: nopp.h
@@ -374,6 +395,7 @@ arith.o: spec_arith.h
 arith.o: type.h
 code.o: LLlex.h
 code.o: Lpars.h
+code.o: align.h
 code.o: arith.h
 code.o: assert.h
 code.o: atw.h
@@ -390,7 +412,9 @@ code.o: idf.h
 code.o: label.h
 code.o: level.h
 code.o: mes.h
+code.o: noRoption.h
 code.o: nobitfield.h
+code.o: nocross.h
 code.o: nofloat.h
 code.o: nopp.h
 code.o: sizes.h
@@ -398,6 +422,7 @@ code.o: spec_arith.h
 code.o: specials.h
 code.o: stack.h
 code.o: stmt.h
+code.o: target_sizes.h
 code.o: type.h
 code.o: use_tmp.h
 dumpidf.o: Lpars.h
@@ -438,10 +463,12 @@ field.o: field.h
 field.o: idf.h
 field.o: label.h
 field.o: nobitfield.h
+field.o: nocross.h
 field.o: nofloat.h
 field.o: nopp.h
 field.o: sizes.h
 field.o: spec_arith.h
+field.o: target_sizes.h
 field.o: type.h
 tokenname.o: LLlex.h
 tokenname.o: Lpars.h
@@ -463,12 +490,14 @@ LLlex.o: file_info.h
 LLlex.o: idf.h
 LLlex.o: idfsize.h
 LLlex.o: input.h
+LLlex.o: nocross.h
 LLlex.o: nofloat.h
 LLlex.o: nopp.h
 LLlex.o: numsize.h
 LLlex.o: sizes.h
 LLlex.o: spec_arith.h
 LLlex.o: strsize.h
+LLlex.o: target_sizes.h
 LLmessage.o: LLlex.h
 LLmessage.o: Lpars.h
 LLmessage.o: arith.h
@@ -531,11 +560,14 @@ options.o: idf.h
 options.o: idfsize.h
 options.o: macro.h
 options.o: maxincl.h
+options.o: noRoption.h
 options.o: nobitfield.h
+options.o: nocross.h
 options.o: nofloat.h
 options.o: nopp.h
 options.o: sizes.h
 options.o: spec_arith.h
+options.o: target_sizes.h
 options.o: use_tmp.h
 scan.o: class.h
 scan.o: idf.h
@@ -562,6 +594,7 @@ stack.o: def.h
 stack.o: idf.h
 stack.o: level.h
 stack.o: mes.h
+stack.o: noRoption.h
 stack.o: nobitfield.h
 stack.o: nofloat.h
 stack.o: nopp.h
@@ -576,10 +609,12 @@ type.o: botch_free.h
 type.o: def.h
 type.o: idf.h
 type.o: nobitfield.h
+type.o: nocross.h
 type.o: nofloat.h
 type.o: nopp.h
 type.o: sizes.h
 type.o: spec_arith.h
+type.o: target_sizes.h
 type.o: type.h
 ch7mon.o: Lpars.h
 ch7mon.o: arith.h
@@ -599,6 +634,7 @@ label.o: def.h
 label.o: idf.h
 label.o: label.h
 label.o: level.h
+label.o: noRoption.h
 label.o: nobitfield.h
 label.o: nofloat.h
 label.o: nopp.h
@@ -619,11 +655,13 @@ eval.o: label.h
 eval.o: level.h
 eval.o: mes.h
 eval.o: nobitfield.h
+eval.o: nocross.h
 eval.o: nofloat.h
 eval.o: nopp.h
 eval.o: sizes.h
 eval.o: spec_arith.h
 eval.o: stack.h
+eval.o: target_sizes.h
 eval.o: type.h
 switch.o: Lpars.h
 switch.o: arith.h
@@ -635,45 +673,32 @@ switch.o: density.h
 switch.o: expr.h
 switch.o: idf.h
 switch.o: label.h
+switch.o: noRoption.h
 switch.o: nobitfield.h
 switch.o: nofloat.h
 switch.o: nopp.h
 switch.o: spec_arith.h
 switch.o: switch.h
 switch.o: type.h
-ival.o: Lpars.h
-ival.o: align.h
-ival.o: arith.h
-ival.o: assert.h
-ival.o: class.h
-ival.o: debug.h
-ival.o: def.h
-ival.o: expr.h
-ival.o: field.h
-ival.o: idf.h
-ival.o: label.h
-ival.o: level.h
-ival.o: nobitfield.h
-ival.o: nofloat.h
-ival.o: nopp.h
-ival.o: sizes.h
-ival.o: spec_arith.h
-ival.o: struct.h
-ival.o: type.h
 conversion.o: Lpars.h
 conversion.o: arith.h
 conversion.o: nobitfield.h
+conversion.o: nocross.h
 conversion.o: nofloat.h
 conversion.o: sizes.h
 conversion.o: spec_arith.h
+conversion.o: target_sizes.h
 conversion.o: type.h
+blocks.o: align.h
 blocks.o: arith.h
 blocks.o: atw.h
 blocks.o: label.h
+blocks.o: nocross.h
 blocks.o: nofloat.h
 blocks.o: sizes.h
 blocks.o: spec_arith.h
 blocks.o: stack.h
+blocks.o: target_sizes.h
 dataflow.o: dataflow.h
 tokenfile.o: Lpars.h
 declar.o: LLlex.h
@@ -688,12 +713,15 @@ declar.o: field.h
 declar.o: file_info.h
 declar.o: idf.h
 declar.o: label.h
+declar.o: level.h
 declar.o: nobitfield.h
+declar.o: nocross.h
 declar.o: nofloat.h
 declar.o: nopp.h
 declar.o: sizes.h
 declar.o: spec_arith.h
 declar.o: struct.h
+declar.o: target_sizes.h
 declar.o: type.h
 statement.o: LLlex.h
 statement.o: Lpars.h
@@ -719,6 +747,7 @@ expression.o: expr.h
 expression.o: file_info.h
 expression.o: idf.h
 expression.o: label.h
+expression.o: noRoption.h
 expression.o: nobitfield.h
 expression.o: nofloat.h
 expression.o: nopp.h
@@ -741,5 +770,30 @@ program.o: nopp.h
 program.o: spec_arith.h
 program.o: type.h
 Lpars.o: Lpars.h
+ival.o: LLlex.h
+ival.o: Lpars.h
+ival.o: align.h
+ival.o: arith.h
+ival.o: assert.h
+ival.o: class.h
+ival.o: debug.h
+ival.o: def.h
+ival.o: estack.h
+ival.o: expr.h
+ival.o: field.h
+ival.o: file_info.h
+ival.o: idf.h
+ival.o: label.h
+ival.o: level.h
+ival.o: noRoption.h
+ival.o: nobitfield.h
+ival.o: nocross.h
+ival.o: nofloat.h
+ival.o: nopp.h
+ival.o: sizes.h
+ival.o: spec_arith.h
+ival.o: struct.h
+ival.o: target_sizes.h
+ival.o: type.h
 char.o: class.h
 symbol2str.o: Lpars.h

+ 13 - 8
lang/cem/cemcom/Parameters

@@ -2,10 +2,6 @@
 #define PATHLENGTH	1024	/* max. length of path to file		*/
 
 
-!File: idepth.h
-#define	IDEPTH		100	/* maximum nr of stacked input buffers	*/
-
-
 !File: errout.h
 #define	ERROUT		STDERR	/* file pointer for writing messages	*/
 #define	MAXERR_LINE	5	/* maximum number of error messages given
@@ -78,7 +74,7 @@
 
 
 !File: botch_free.h
-#undef BOTCH_FREE	1	/* botch freed memory, as a check	*/
+#undef BOTCH_FREE	1	/* when defined, botch freed memory, as a check	*/
 
 
 !File: dataflow.h
@@ -109,11 +105,11 @@
 
 
 !File: nopp.h
-#undef NOPP		1	/* use built-int preprocessor	*/
+#undef NOPP		1	/* if NOT defined, use built-int preprocessor */
 
 
 !File: nobitfield.h
-#undef NOBITFIELD	1	/* implement bitfields	*/
+#undef NOBITFIELD	1	/* if NOT defined, implement bitfields	*/
 
 
 !File: spec_arith.h
@@ -126,5 +122,14 @@
 
 
 !File: nofloat.h
-#undef NOFLOAT			/* floats implemented by default */
+#undef NOFLOAT		1	/* if NOT defined, floats are implemented */
+
+
+!File: noRoption.h
+#undef NOROPTION	1	/* if NOT defined, R option is implemented */
+
+
+!File: nocross.h
+#undef NOCROSS		1	/* if NOT defined, cross compiler */
+
 

+ 16 - 0
lang/cem/cemcom/align.h

@@ -6,7 +6,10 @@
 /*	 A L I G N M E N T   D E F I N I T I O N S	*/
 
 #include "nofloat.h"
+#include "nocross.h"
+#include "target_sizes.h"
 
+#ifndef NOCROSS
 extern int
 	short_align, word_align, int_align, long_align,
 #ifndef NOFLOAT
@@ -14,5 +17,18 @@ extern int
 #endif NOFLOAT
 	pointer_align,
 	struct_align, union_align;
+#else NOCROSS
+#define short_align	((int)AL_SHORT)
+#define word_align	((int)AL_WORD)
+#define int_align	((int)AL_INT)
+#define long_align	((int)AL_LONG)
+#ifndef NOFLOAT
+#define float_align	((int)AL_FLOAT)
+#define double_align	((int)AL_DOUBLE)
+#endif NOFLOAT
+#define pointer_align	((int)AL_POINTER)
+#define struct_align	((int)AL_STRUCT)
+#define union_align	((int)AL_UNION)
+#endif NOCROSS
 
 extern arith align();

+ 47 - 36
lang/cem/cemcom/arith.c

@@ -23,6 +23,7 @@
 #include	"Lpars.h"
 #include	"field.h"
 #include	"mes.h"
+#include	"noRoption.h"
 
 extern char *symbol2str();
 extern char options[];
@@ -80,9 +81,9 @@ relbalance(e1p, oper, e2p)
 		of the relational operator oper.
 	*/
 	if ((*e1p)->ex_type->tp_fund == FUNCTION)
-		function2pointer(e1p);
+		function2pointer(*e1p);
 	if ((*e2p)->ex_type->tp_fund == FUNCTION)
-		function2pointer(e2p);
+		function2pointer(*e2p);
 	if ((*e1p)->ex_type->tp_fund == POINTER)
 		ch76pointer(e2p, oper, (*e1p)->ex_type);
 	else
@@ -98,28 +99,33 @@ relbalance(e1p, oper, e2p)
 }
 
 ch76pointer(expp, oper, tp)
-	register struct expr **expp;
+	struct expr **expp;
 	register struct type *tp;
 {
 	/*	Checks whether *expp may be compared to tp using oper,
 		as described in chapter 7.6 and 7.7.
 		tp is known to be a pointer.
 	*/
-	if ((*expp)->ex_type->tp_fund == POINTER)	{
-		if ((*expp)->ex_type != tp)
+	register struct expr *exp = *expp;
+
+	if (exp->ex_type->tp_fund == POINTER)	{
+		if (exp->ex_type != tp)
 			ch7cast(expp, oper, tp);
 	}
 	else
-	if (	is_integral_type((*expp)->ex_type) &&
+	if (	is_integral_type(exp->ex_type)
+#ifndef NOROPTION
+		&&
 		(	!options['R'] /* we don't care */ ||
 			(oper == EQUAL || oper == NOTEQUAL || oper == ':')
 		)
+#endif NOROPTION
 	)		/* ch 7.7 */
 		ch7cast(expp, CAST, tp);
 	else	{
-		expr_error(*expp, "%s on %s and pointer",
+		expr_error(exp, "%s on %s and pointer",
 				symbol2str(oper),
-				symbol2str((*expp)->ex_type->tp_fund)
+				symbol2str(exp->ex_type->tp_fund)
 			);
 		ch7cast(expp, oper, tp);
 	}
@@ -152,11 +158,13 @@ any2arith(expp, oper)
 			/* allowed by K & R */
 		}
 		else
+#ifndef NOROPTION
 		if (!options['R'])	{
 			/* allowed by us */
 		}
 		else
 			expr_warning(*expp, "%s on enum", symbol2str(oper));
+#endif NOROPTION
 		int2int(expp, int_type);
 		break;
 #ifndef	NOFLOAT
@@ -183,16 +191,18 @@ any2arith(expp, oper)
 }
 
 erroneous2int(expp)
-	register struct expr **expp;
+	struct expr **expp;
 {
 	/*	the (erroneous) expression *expp is replaced by an
 		int expression
 	*/
-	int flags = (*expp)->ex_flags;
+	register struct expr *exp = *expp;
+	int flags = exp->ex_flags;
 	
-	free_expression(*expp);
-	*expp = intexpr((arith)0, INT);
-	(*expp)->ex_flags = (flags | EX_ERROR);
+	free_expression(exp);
+	exp = intexpr((arith)0, INT);
+	exp->ex_flags = (flags | EX_ERROR);
+	*expp = exp;
 }
 
 struct expr *
@@ -215,17 +225,18 @@ arith2arith(tp, oper, expr)
 
 int
 int2int(expp, tp)
-	register struct expr **expp;
+	struct expr **expp;
 	register struct type *tp;
 {
 	/*	The expression *expp, which is of some integral type, is
 		converted to the integral type tp.
 	*/
+	register struct expr *exp = *expp;
 	
-	if (is_cp_cst(*expp))	{
-		register struct type *tp1 = (*expp)->ex_type;
+	if (is_cp_cst(exp))	{
+		register struct type *tp1 = exp->ex_type;
 
-		(*expp)->ex_type = tp;
+		exp->ex_type = tp;
 		if (! tp1->tp_unsigned && tp->tp_unsigned) {
 			/*	Avoid "unreal" overflow warnings, such as
 				caused by f.i.:
@@ -233,20 +244,21 @@ int2int(expp, tp)
 					unsigned int y = -1;
 			*/
 			extern long full_mask[];
-			long remainder = (*expp)->VL_VALUE &
+			long remainder = exp->VL_VALUE &
 						~full_mask[tp->tp_size];
 
 			if (remainder == 0 ||
 			    remainder == ~full_mask[tp->tp_size]) {
-				(*expp)->VL_VALUE &= ~remainder;
+				exp->VL_VALUE &= ~remainder;
 			}
 		}
-		cut_size(*expp);
+		cut_size(exp);
 	}
 	else	{
-		*expp = arith2arith(tp, INT2INT, *expp);
+		exp = arith2arith(tp, INT2INT, exp);
 	}
-	return (*expp)->ex_type->tp_fund;
+	*expp = exp;
+	return exp->ex_type->tp_fund;
 }
 
 #ifndef NOFLOAT
@@ -294,33 +306,30 @@ float2float(expp, tp)
 }
 #endif NOFLOAT
 
-array2pointer(expp)
-	register struct expr **expp;
+array2pointer(exp)
+	register struct expr *exp;
 {
 	/*	The expression, which must be an array, is converted
 		to a pointer.
 	*/
-	(*expp)->ex_type =
-		construct_type(POINTER, (*expp)->ex_type->tp_up, (arith)0);
+	exp->ex_type = construct_type(POINTER, exp->ex_type->tp_up, (arith)0);
 }
 
-function2pointer(expp)
-	register struct expr **expp;
+function2pointer(exp)
+	register struct expr *exp;
 {
 	/*	The expression, which must be a function, is converted
 		to a pointer to the function.
 	*/
-	(*expp)->ex_type =
-		construct_type(POINTER, (*expp)->ex_type, (arith)0);
+	exp->ex_type = construct_type(POINTER, exp->ex_type, (arith)0);
 }
 
-string2pointer(expp)
-	struct expr **expp;
+string2pointer(ex)
+	register struct expr *ex;
 {
 	/*	The expression, which must be a string constant, is converted
 		to a pointer to the string-containing area.
 	*/
-	register struct expr *ex = *expp;
 	label lbl = data_label();
 
 	code_string(ex->SG_VALUE, ex->SG_LEN, lbl);
@@ -351,7 +360,7 @@ opnd2logical(expp, oper)
 	int fund;
 
 	if ((*expp)->ex_type->tp_fund == FUNCTION)
-		function2pointer(expp);
+		function2pointer(*expp);
 #ifndef NOBITFIELD
 	else
 	if ((*expp)->ex_type->tp_fund == FIELD)
@@ -408,6 +417,7 @@ is_test_op(oper)
 	/*NOTREACHED*/
 }
 
+#ifdef ____
 int
 is_arith_op(oper)
 {
@@ -452,6 +462,7 @@ is_asgn_op(oper)
 		return 0;
 	}
 }
+#endif
 
 any2opnd(expp, oper)
 	register struct expr **expp;
@@ -468,11 +479,11 @@ any2opnd(expp, oper)
 		any2arith(expp, oper);
 		break;
 	case ARRAY:
-		array2pointer(expp);
+		array2pointer(*expp);
 		break;
 	case POINTER:
 		if ((*expp)->ex_class == String)
-			string2pointer(expp);
+			string2pointer(*expp);
 		break;
 #ifndef NOBITFIELD
 	case FIELD:

+ 1 - 1
lang/cem/cemcom/atw.h

@@ -5,6 +5,6 @@
 /* $Header$ */
 /* Align To Word boundary Definition	*/
 
-extern arith word_size;
+#include "sizes.h"
 
 #define	ATW(arg)	((((arg) + word_size - 1) / word_size) * word_size)

+ 42 - 37
lang/cem/cemcom/ch7.c

@@ -27,13 +27,14 @@ extern char *symbol2str();
 */
 
 ch7sel(expp, oper, idf)
-	register struct expr **expp;
+	struct expr **expp;
 	struct idf *idf;
 {
 	/*	The selector idf is applied to *expp; oper may be '.' or
 		ARROW.
 	*/
-	register struct type *tp = (*expp)->ex_type;
+	register struct expr *exp = *expp;
+	register struct type *tp = exp->ex_type;
 	register struct sdef *sd;
 
 	if (oper == ARROW)	{
@@ -54,21 +55,22 @@ ch7sel(expp, oper, idf)
 				tp = sd->sd_stype;
 				break;
 			default:
-				expr_error(*expp, "-> applied to %s",
+				expr_error(exp, "-> applied to %s",
 					symbol2str(tp->tp_fund));
 			case ERRONEOUS:
-				(*expp)->ex_type = error_type;
+				exp->ex_type = error_type;
 				return;
 			}
 		} /* tp->tp_fund != POINTER */
 	} /* oper == ARROW */
 	else { /* oper == '.' */
 		/* filter out illegal expressions "non_lvalue.sel" */
-		if (!(*expp)->ex_lvalue) {
-			expr_error(*expp, "dot requires lvalue");
+		if (!exp->ex_lvalue) {
+			expr_error(exp, "dot requires lvalue");
 			return;
 		}
 	}
+	exp = *expp;
 	switch (tp->tp_fund)	{
 	case POINTER:	/* for int *p;	p->next = ...	*/
 	case STRUCT:
@@ -83,10 +85,10 @@ ch7sel(expp, oper, idf)
 		break;
 	default:
 		if (!is_anon_idf(idf))
-			expr_error(*expp, "selector %s applied to %s",
+			expr_error(exp, "selector %s applied to %s",
 				idf->id_text, symbol2str(tp->tp_fund));
 	case ERRONEOUS:
-		(*expp)->ex_type = error_type;
+		exp->ex_type = error_type;
 		return;
 	}
 	sd = idf2sdef(idf, tp);
@@ -99,36 +101,37 @@ ch7sel(expp, oper, idf)
 				The code performing these conversions is
 				extremely obscure.
 		*/
-		if ((*expp)->ex_class == Value)	{
+		if (exp->ex_class == Value)	{
 			/*	It is an object we know the address of; so
 				we can calculate the address of the
 				selected member 
 			*/
-			(*expp)->VL_VALUE += sd->sd_offset;
-			(*expp)->ex_type = sd->sd_type;
-			if ((*expp)->ex_type == error_type)
-				(*expp)->ex_flags |= EX_ERROR;
+			exp->VL_VALUE += sd->sd_offset;
+			exp->ex_type = sd->sd_type;
+			if (exp->ex_type == error_type)
+				exp->ex_flags |= EX_ERROR;
 		}
 		else
-		if ((*expp)->ex_class == Oper)	{
-			struct oper *op = &((*expp)->ex_object.ex_oper);
+		if (exp->ex_class == Oper)	{
+			struct oper *op = &(exp->ex_object.ex_oper);
 			
 			if (op->op_oper == '.' || op->op_oper == ARROW)	{
 				ASSERT(is_cp_cst(op->op_right));
 				op->op_right->VL_VALUE += sd->sd_offset;
-				(*expp)->ex_type = sd->sd_type;
-				if ((*expp)->ex_type == error_type)
-					(*expp)->ex_flags |= EX_ERROR;
+				exp->ex_type = sd->sd_type;
+				if (exp->ex_type == error_type)
+					exp->ex_flags |= EX_ERROR;
 			}
 			else
-				*expp = new_oper(sd->sd_type, *expp, '.',
+				exp = new_oper(sd->sd_type, exp, '.',
 						intexpr(sd->sd_offset, INT));
 		}
 	}
 	else /* oper == ARROW */
-		*expp = new_oper(sd->sd_type,
-			*expp, oper, intexpr(sd->sd_offset, INT));
-	(*expp)->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
+		exp = new_oper(sd->sd_type,
+			exp, oper, intexpr(sd->sd_offset, INT));
+	exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
+	*expp = exp;
 }
 
 ch7incr(expp, oper)
@@ -152,11 +155,11 @@ ch7cast(expp, oper, tp)
 	register struct type *oldtp;
 
 	if ((*expp)->ex_type->tp_fund == FUNCTION)
-		function2pointer(expp);
+		function2pointer(*expp);
 	if ((*expp)->ex_type->tp_fund == ARRAY)
-		array2pointer(expp);
+		array2pointer(*expp);
 	if ((*expp)->ex_class == String)
-		string2pointer(expp);
+		string2pointer(*expp);
 	oldtp = (*expp)->ex_type;
 #ifndef NOBITFIELD
 	if (oldtp->tp_fund == FIELD)	{
@@ -276,7 +279,7 @@ ch7cast(expp, oper, tp)
 }
 
 ch7asgn(expp, oper, expr)
-	register struct expr **expp;
+	struct expr **expp;
 	struct expr *expr;
 {
 	/*	The assignment operators.
@@ -292,17 +295,18 @@ ch7asgn(expp, oper, expr)
 			      f     (typeof (f op e))e
 		EVAL should however take care of evaluating (typeof (f op e))f
 	*/
-	int fund = (*expp)->ex_type->tp_fund;
+	register struct expr *exp = *expp;
+	int fund = exp->ex_type->tp_fund;
 	struct type *tp;
 
 	/* We expect an lvalue */
-	if (!(*expp)->ex_lvalue)	{
-		expr_error(*expp, "no lvalue in lhs of %s", symbol2str(oper));
-		(*expp)->ex_depth = 99;	/* no direct store/load at EVAL() */
+	if (!exp->ex_lvalue)	{
+		expr_error(exp, "no lvalue in lhs of %s", symbol2str(oper));
+		exp->ex_depth = 99;	/* no direct store/load at EVAL() */
 			/* what is 99 ??? DG */
 	}
 	if (oper == '=') {
-		ch7cast(&expr, oper, (*expp)->ex_type);
+		ch7cast(&expr, oper, exp->ex_type);
 		tp = expr->ex_type;
 	}
 	else {	/* turn e into e' where typeof(e') = typeof (f op e) */
@@ -310,7 +314,7 @@ ch7asgn(expp, oper, expr)
 
 		/* this is really $#@&*%$# ! */
 		extmp->ex_lvalue = 1;
-		extmp->ex_type = (*expp)->ex_type;
+		extmp->ex_type = exp->ex_type;
 		ch7bin(&extmp, oper, expr);
 		/* Note that ch7bin creates a tree of the expression
 			((typeof (f op e))f op (typeof (f op e))e),
@@ -330,14 +334,15 @@ ch7asgn(expp, oper, expr)
 	}
 #ifndef NOBITFIELD
 	if (fund == FIELD)
-		*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
+		exp = new_oper(exp->ex_type->tp_up, exp, oper, expr);
 	else
-		*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
+		exp = new_oper(exp->ex_type, exp, oper, expr);
 #else NOBITFIELD
-	*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
+	exp = new_oper(exp->ex_type, exp, oper, expr);
 #endif NOBITFIELD
-	(*expp)->OP_TYPE = tp;	/* for EVAL() */
-	(*expp)->ex_flags |= EX_SIDEEFFECTS;
+	exp->OP_TYPE = tp;	/* for EVAL() */
+	exp->ex_flags |= EX_SIDEEFFECTS;
+	*expp = exp;
 }
 
 /*	Some interesting (?) questions answered.

+ 6 - 2
lang/cem/cemcom/ch7bin.c

@@ -15,6 +15,7 @@
 #include	"label.h"
 #include	"expr.h"
 #include	"Lpars.h"
+#include	"noRoption.h"
 
 extern char options[];
 extern char *symbol2str();
@@ -68,8 +69,10 @@ ch7bin(expp, oper, expr)
 		if (	(*expp)->ex_type->tp_fund == POINTER &&
 			(*expp)->ex_type->tp_up->tp_fund == FUNCTION
 		)	{
+#ifndef NOROPTION
 			if (options['R'])
 				warning("function pointer called");
+#endif NOROPTION
 			ch7mon('*', expp);
 		}
 		if ((*expp)->ex_type->tp_fund != FUNCTION)	{
@@ -85,7 +88,7 @@ ch7bin(expp, oper, expr)
 		break;
 	case PARCOMMA:				/* RM 7.1 */
 		if ((*expp)->ex_type->tp_fund == FUNCTION)
-			function2pointer(expp);
+			function2pointer(*expp);
 		*expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
 		break;
 	case '%':
@@ -271,7 +274,8 @@ pntminuspnt(expp, oper, expr)
 }
 
 mk_binop(expp, oper, expr, commutative)
-	register struct expr **expp, *expr;
+	struct expr **expp;
+	register struct expr *expr;
 {
 	/*	Constructs in *expp the operation indicated by the operands.
 		"commutative" indicates wether "oper" is a commutative

+ 4 - 4
lang/cem/cemcom/ch7mon.c

@@ -32,7 +32,7 @@ ch7mon(oper, expp)
 	case '*':			/* RM 7.2 */
 		/* no FIELD type allowed	*/
 		if ((*expp)->ex_type->tp_fund == ARRAY)
-			array2pointer(expp);
+			array2pointer(*expp);
 		if ((*expp)->ex_type->tp_fund != POINTER)	{
 			expr_error(*expp,
 				"* applied to non-pointer (%s)",
@@ -54,12 +54,12 @@ ch7mon(oper, expp)
 	case '&':
 		if ((*expp)->ex_type->tp_fund == ARRAY) {
 			warning("& before array: ignored");
-			array2pointer(expp);
+			array2pointer(*expp);
 		}
 		else
 		if ((*expp)->ex_type->tp_fund == FUNCTION) {
 			warning("& before function: ignored");
-			function2pointer(expp);
+			function2pointer(*expp);
 		}
 		else
 #ifndef NOBITFIELD
@@ -131,7 +131,7 @@ ch7mon(oper, expp)
 		break;
 	case '!':
 		if ((*expp)->ex_type->tp_fund == FUNCTION)
-			function2pointer(expp);
+			function2pointer(*expp);
 		if ((*expp)->ex_type->tp_fund != POINTER)
 			any2arith(expp, oper);
 		opnd2test(expp, '!');

+ 5 - 5
lang/cem/cemcom/code.c

@@ -31,6 +31,7 @@
 #include	"atw.h"
 #include	"assert.h"
 #include	"align.h"
+#include	"noRoption.h"
 
 label lab_count = 1;
 label datlab_count = 1;
@@ -301,7 +302,8 @@ code_declaration(idf, expr, lvl, sc)
 	/*	code_declaration() does the actual declaration of the
 		variable indicated by "idf" on declaration level "lvl".
 		If the variable is initialised, the expression is given
-		in "expr".
+		in "expr", but for global and static initialisations it
+		is just non-zero, as the expression is not parsed yet.
 		There are some cases to be considered:
 		-	filter out typedefs, they don't correspond to code;
 		-	global variables, coded only if initialized;
@@ -343,8 +345,6 @@ code_declaration(idf, expr, lvl, sc)
 			code_scope(text, def);
 			def->df_alloc = ALLOC_DONE;
 			C_df_dnam(text);
-			do_ival(&(def->df_type), expr);
-			free_expression(expr);
 		}
 	}
 	else
@@ -361,8 +361,6 @@ code_declaration(idf, expr, lvl, sc)
 			*/
 			C_df_dlb((label)def->df_address);
 			if (expr) { /* there is an initialisation */
-				do_ival(&(def->df_type), expr);
-				free_expression(expr);
 			}
 			else {	/* produce blank space */
 				if (size <= 0) {
@@ -414,6 +412,7 @@ loc_init(expr, id)
 		return;
 	}
 	if (ISCOMMA(e))	{	/* embraced: int i = {12};	*/
+#ifndef NOROPTION
 		if (options['R'])	{
 			if (ISCOMMA(e->OP_LEFT)) /* int i = {{1}} */
 				expr_error(e, "extra braces not allowed");
@@ -421,6 +420,7 @@ loc_init(expr, id)
 			if (e->OP_RIGHT != 0) /* int i = {1 , 2} */
 				expr_error(e, "too many initializers");
 		}
+#endif NOROPTION
 		while (e)	{
 			loc_init(e->OP_LEFT, id);
 			e = e->OP_RIGHT;

+ 4 - 0
lang/cem/cemcom/code.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /*	C O D E - G E N E R A T O R   D E F I N I T I O N S	*/
 

+ 11 - 18
lang/cem/cemcom/conversion.c

@@ -33,31 +33,24 @@ conversion(from_type, to_type)
 {
 	register arith from_size = from_type->tp_size;
 	register arith to_size = to_type->tp_size;
+	int from_fund = fundamental(from_type);
+	int to_fund = fundamental(to_type);
 
-	if (from_type == to_type)	/* a little optimisation */
-		return;
 	if (to_size < word_size) to_size = word_size;
-	switch (fundamental(from_type))	{
+	if (from_size == to_size && from_fund == to_fund)
+		return;
+	switch (from_fund)	{
 	case T_SIGNED:
-		switch (fundamental(to_type))	{
+		switch (to_fund)	{
 		case T_SIGNED:
 			C_loc(from_size);
 			C_loc(to_size);
 			C_cii();
 			break;
 		case T_UNSIGNED:
-			if (from_size < word_size) {
-				C_loc(from_size);
-				C_loc(word_size);
-				C_cii();
-				from_size = word_size;
-			}
-			C_loc(from_size);
-			C_loc(to_size);
-			C_ciu();
-			break;
 #ifndef NOFLOAT
 		case T_FLOATING:
+#endif NOOFLOAT
 			if (from_size < word_size) {
 				C_loc(from_size);
 				C_loc(word_size);
@@ -66,16 +59,16 @@ conversion(from_type, to_type)
 			}
 			C_loc(from_size);
 			C_loc(to_size);
-			C_cif();
+			if (to_fund == T_UNSIGNED) C_ciu();
+			else C_cif();
 			break;
-#endif NOFLOAT
 		}
 		break;
 	case T_UNSIGNED:
 		if (from_size < word_size) from_size = word_size;
 		C_loc(from_size);
 		C_loc(to_size);
-		switch (fundamental(to_type))	{
+		switch (to_fund)	{
 		case T_SIGNED:
 			C_cui();
 			break;
@@ -93,7 +86,7 @@ conversion(from_type, to_type)
 	case T_FLOATING:
 		C_loc(from_size);
 		C_loc(to_size);
-		switch (fundamental(to_type))	{
+		switch (to_fund)	{
 		case T_SIGNED:
 			C_cfi();
 			break;

+ 52 - 36
lang/cem/cemcom/declar.g

@@ -21,6 +21,7 @@
 #include	"label.h"
 #include	"expr.h"
 #include	"sizes.h"
+#include	"level.h"
 
 extern char options[];
 }
@@ -83,22 +84,20 @@ other_specifier(register struct decspecs *ds;):
 	[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
 	{	if (ds->ds_sc_given)
 			error("repeated storage class specifier");
-		else	{
-			ds->ds_sc_given = 1;
-			ds->ds_sc = DOT;
-		}
+		ds->ds_sc_given = 1;
+		ds->ds_sc = DOT;
 	}
 |
 	[ SHORT | LONG ]
 	{	if (ds->ds_size)
 			error("repeated size specifier");
-		else	ds->ds_size = DOT;
+		ds->ds_size = DOT;
 	}
 |
 	UNSIGNED
 	{	if (ds->ds_unsigned)
 			error("unsigned specified twice");
-		else	ds->ds_unsigned = 1;
+		ds->ds_unsigned = 1;
 	}
 ;
 
@@ -137,7 +136,6 @@ init_declarator_list(struct decspecs *ds;):
 init_declarator(register struct decspecs *ds;)
 	{
 		struct declarator Dc;
-		struct expr *expr = (struct expr *) 0;
 	}
 :
 	{
@@ -149,14 +147,57 @@ init_declarator(register struct decspecs *ds;)
 		reject_params(&Dc);
 		declare_idf(ds, &Dc, level);
 	}
-	initializer(Dc.dc_idf, &expr)?
-	{
-		code_declaration(Dc.dc_idf, expr, level, ds->ds_sc);
-	}
+	[
+		initializer(Dc.dc_idf, ds->ds_sc)
+	|
+		{ code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); }
+	]
 ]
 	{remove_declarator(&Dc);}
 ;
 
+/* 8.6: initializer */
+initializer(struct idf *idf; int sc;)
+	{
+		struct expr *expr = (struct expr *) 0;
+		int globalflag = level == L_GLOBAL ||
+				 (level == L_LOCAL && sc == STATIC);
+	}
+:
+	{	if (idf->id_def->df_type->tp_fund == FUNCTION)	{
+			error("illegal initialization of function");
+		}
+	}
+	[
+		'='
+	|
+		empty
+		{warning("old-fashioned initialization, insert =");}
+		/*	This causes trouble at declarator and at
+			external_definition, q.v.
+		*/
+	]
+	{	if (globalflag) {
+			struct expr ex;
+			code_declaration(idf, &ex, level, sc);
+	  	}
+	}
+	initial_value(globalflag ? &(idf->id_def->df_type) : (struct type **)0,
+			&expr)
+	{	if (! globalflag) {
+			if (idf->id_def->df_type->tp_fund == FUNCTION)	{
+				free_expression(expr);
+				expr = 0;
+			}
+			code_declaration(idf, expr, level, sc);
+#ifdef	DEBUG
+			print_expr("initializer-expression", expr);
+#endif	DEBUG
+	  	}
+	  	init_idf(idf);
+	}
+;
+
 /*
 	Functions yielding pointers to functions must be declared as, e.g.,
 		int (*hehe(par1, par2))() char *par1, *par2;	{}
@@ -398,31 +439,6 @@ bit_expression(struct field **fd;)
 	}
 ;
 
-/* 8.6 */
-initializer(register struct idf *idf; register struct expr **expp;) :
-	[
-		'='
-	|
-		empty
-		{warning("old-fashioned initialization, insert =");}
-		/*	This causes trouble at declarator and at
-			external_definition, q.v.
-		*/
-	]
-	initial_value(expp)
-	{
-		if (idf->id_def->df_type->tp_fund == FUNCTION)	{
-			error("illegal initialization of function");
-			free_expression(*expp);
-			*expp = 0;
-		}
-		init_idf(idf);
-#ifdef	DEBUG
-		print_expr("initializer-expression", *expp);
-#endif	DEBUG
-	}
-;
-
 /* 8.7 */
 cast(struct type **tpp;)	{struct declarator Dc;} :
 	{Dc = null_declarator;}

+ 4 - 0
lang/cem/cemcom/declar.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* DEFINITION OF DECLARATOR DESCRIPTORS */
 

+ 7 - 0
lang/cem/cemcom/decspecs.c

@@ -12,6 +12,7 @@
 #include	"type.h"
 #include	"level.h"
 #include	"def.h"
+#include	"noRoption.h"
 
 extern char options[];
 extern int level;
@@ -75,21 +76,27 @@ do_decspecs(ds)
 	if (ds->ds_unsigned)	{
 		switch (tp->tp_fund)	{
 		case CHAR:
+#ifndef NOROPTION
 			if (options['R'])
 				warning("unsigned char not allowed");
+#endif
 			tp = uchar_type;
 			break;
 		case SHORT:
+#ifndef NOROPTION
 			if (options['R'])
 				warning("unsigned short not allowed");
+#endif
 			tp = ushort_type;
 			break;
 		case INT:
 			tp = uint_type;
 			break;
 		case LONG:
+#ifndef NOROPTION
 			if (options['R'])
 				warning("unsigned long not allowed");
+#endif
 			tp = ulong_type;
 			break;
 		default:

+ 4 - 0
lang/cem/cemcom/decspecs.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* DECLARATION SPECIFIER DEFINITION */
 

+ 4 - 0
lang/cem/cemcom/def.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* IDENTIFIER DEFINITION DESCRIPTOR */
 

+ 24 - 61
lang/cem/cemcom/eval.c

@@ -73,9 +73,7 @@ EVAL(expr, val, code, true_label, false_label)
 		break;
 	case String:	/* a string constant	*/
 		if (gencode) {
-			struct expr *ex = expr;
-			string2pointer(&ex);
-			expr = ex;
+			string2pointer(expr);
 			C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
 		}
 		break;
@@ -522,72 +520,37 @@ EVAL(expr, val, code, true_label, false_label)
 			C_df_ilb(l_end);
 			break;
 		}
-		case AND:
-			if (true_label == 0) {
-				label l_true = text_label();
-				label l_false = text_label();
-				label l_maybe = text_label();
-				label l_end = text_label();
+		case OR:
+		case AND: {
+			label l_false, l_true, l_maybe;
 
-				EVAL(left, RVAL, TRUE, l_maybe, l_false);
-				C_df_ilb(l_maybe);
-				if (gencode) {
-					EVAL(right, RVAL, TRUE, l_true,
-						l_false);
-					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 {
-					EVAL(right, RVAL, FALSE, l_false,
-						l_false);
-					C_df_ilb(l_false);
-				}
+			l_maybe = text_label();
+			if (true_label) {
+				l_false = false_label;
+				l_true = true_label;
 			}
 			else {
-				label l_maybe = text_label();
-
-				EVAL(left, RVAL, TRUE, l_maybe, false_label);
-				C_df_ilb(l_maybe);
-				EVAL(right, RVAL, gencode, true_label,
-					false_label);
+				l_false = text_label();
+				l_true = gencode ? text_label(): l_false;
 			}
-			break;
-		case OR:
-			if (true_label == 0) {
-				label l_true = text_label();
-				label l_false = text_label();
-				label l_maybe = text_label();
+
+			EVAL(left, RVAL, TRUE, oper == AND ? l_maybe : l_true,
+					       oper == AND ? l_false : l_maybe);
+			C_df_ilb(l_maybe);
+			EVAL(right, RVAL, gencode, l_true, l_false);
+			if (gencode && !true_label) {
 				label l_end = text_label();
 
-				EVAL(left, RVAL, TRUE, l_true, l_maybe);
-				C_df_ilb(l_maybe);
-				if (gencode) {
-					EVAL(right, RVAL, TRUE, l_true,
-						l_false);
-					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 {
-					EVAL(right, RVAL, FALSE, l_true,
-						l_true);
-					C_df_ilb(l_true);
-				}
+				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 {
-				label l_maybe = text_label();
-
-				EVAL(left, RVAL, TRUE, true_label, l_maybe);
-				C_df_ilb(l_maybe);
-				EVAL(right, RVAL, gencode, true_label,
-					false_label);
+				if (! true_label) C_df_ilb(l_false);
+			}
 			}
 			break;
 		case '!':

+ 5 - 0
lang/cem/cemcom/expr.c

@@ -20,6 +20,7 @@
 #include	"declar.h"
 #include	"sizes.h"
 #include	"level.h"
+#include	"noRoption.h"
 
 extern char *symbol2str();
 extern char options[];
@@ -94,6 +95,7 @@ rank_of(oper)
 	/*NOTREACHED*/
 }
 
+#ifndef NOROPTION
 int
 rank_of_expression(ex)
 	register struct expr *ex;
@@ -117,6 +119,7 @@ check_conditional(expr, oper, pos_descr)
 		expr_warning(expr, "%s %s is ungrammatical",
 			symbol2str(expr->OP_OPER), pos_descr);
 }
+#endif
 
 dot2expr(expp)
 	struct expr **expp;
@@ -396,6 +399,7 @@ chk_cst_expr(expp)
 	else
 	if (!is_ld_cst(expr))
 		expr_error(expr, "expression is not constant"), err++;
+#ifndef NOROPTION
 	if (options['R'])	{
 		if (flags & EX_CAST)
 			expr_warning(expr, "cast in constant expression");
@@ -406,6 +410,7 @@ chk_cst_expr(expp)
 			expr_warning(expr,
 				"expression comma in constant expression");
 	}
+#endif NOROPTION
 	if (err)
 		erroneous2int(expp);
 }

+ 5 - 1
lang/cem/cemcom/expr.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* EXPRESSION DESCRIPTOR */
 
@@ -101,6 +105,6 @@ struct expr	{
 
 extern struct expr *intexpr(), *new_oper();
 
-/* ALLOCDEF "expr" 50 */
+/* ALLOCDEF "expr" 20 */
 
 #define	ISCOMMA(e) ((e)->ex_class == Oper && (e)->OP_OPER == INITCOMMA)

+ 10 - 35
lang/cem/cemcom/expression.g

@@ -12,43 +12,12 @@
 #include	"idf.h"
 #include	"label.h"
 #include	"expr.h"
+#include	"noRoption.h"
 
 extern char options[];
 extern struct expr *intexpr();
 }
 
-/* 7 */
-initial_value(struct expr **expp;) :
-	assignment_expression(expp)
-		{
-			if ((*expp)->ex_type->tp_fund == ARRAY)
-				array2pointer(expp);
-		}
-|
-	initial_value_pack(expp)
-;
-
-initial_value_pack(struct expr **expp;) :
-	'{'
-	initial_value_list(expp)
-	'}'
-;
-
-initial_value_list(struct expr **expp;)
-	{struct expr *e1;}
-:
-	{*expp = NILEXPR;}
-	initial_value(&e1)
-	{init_expression(&expp, e1);}
-	[%while (AHEAD != '}')		/* >>> conflict on ',' */
-		','
-		initial_value(&e1)
-		{init_expression(&expp, e1);}
-	]*
-	','?				/* optional trailing comma */
-;
-
-
 /* 7.1 */
 primary(register struct expr **expp;) :
 	IDENTIFIER
@@ -224,11 +193,17 @@ conditional_expression(struct expr **expp;)
 	binary_expression(rank_of('?') - 1, expp)
 	[	'?'
 		expression(&e1)
-		{check_conditional(e1, '?', "between ? and :");}
+		{
+#ifndef NOROPTION
+			check_conditional(e1, '?', "between ? and :");
+#endif
+		}
 		':'
 		assignment_expression(&e2)
-		{check_conditional(e2, '=', "after :");}
-		{
+		{	
+#ifndef NOROPTION
+			check_conditional(e2, '=', "after :");
+#endif
 			ch7bin(&e1, ':', e2);
 			opnd2test(expp, '?');
 			ch7bin(expp, '?', e1);

+ 4 - 0
lang/cem/cemcom/field.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* FIELD DESCRIPTOR */
 

+ 9 - 0
lang/cem/cemcom/idf.c

@@ -27,6 +27,7 @@
 #include	"Lpars.h"
 #include	"assert.h"
 #include	"specials.h"	/* registration of special identifiers	*/
+#include	"noRoption.h"
 
 int idfsize = IDFSIZE;
 extern char options[];
@@ -252,6 +253,7 @@ declare_idf(ds, dc, lvl)
 			sc =	lvl == L_GLOBAL ? GLOBAL
 				: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
 				: AUTO;
+#ifndef NOROPTION
 	if (options['R']) { /* some special K & R tests */
 		/* is it also an enum? */
 		if (idf->id_enum && idf->id_enum->tg_level == level)
@@ -260,6 +262,7 @@ declare_idf(ds, dc, lvl)
 		if (def && def->df_level == L_UNIVERSAL)
 			warning("redeclaring reserved word %s", idf->id_text);
 	}
+#endif
 	if (def && def->df_level >= lvl)	{
 		/*	There is already a declaration for idf on this
 			level, or even more inside.
@@ -294,12 +297,14 @@ declare_idf(ds, dc, lvl)
 		/*	extern declaration inside function is treated the
 			same way as global extern declaration
 		*/
+#ifndef NOROPTION
 		if (	options['R'] &&
 			(sc == STATIC && type->tp_fund == FUNCTION)
 		)
 			if (!is_anon_idf(idf))
 				warning("non-global static function %s",
 					idf->id_text);
+#endif
 		declare_idf(ds, dc, L_GLOBAL);
 	}
 	else	{ /* fill in the def block */
@@ -447,9 +452,11 @@ global_redecl(idf, new_sc, tp)
 				error("cannot redeclare %s to static",
 					idf->id_text);
 			else	{
+#ifndef NOROPTION
 				if (options['R'])
 					warning("%s redeclared to static",
 						idf->id_text);
+#endif
 				def->df_sc = STATIC;
 			}
 			break;
@@ -488,9 +495,11 @@ global_redecl(idf, new_sc, tp)
 			def->df_sc = new_sc;
 			break;
 		case STATIC:
+#ifndef NOROPTION
 			if (options['R'])
 				warning("%s was implicitly declared as extern",
 					idf->id_text);
+#endif
 			def->df_sc = new_sc;
 			break;
 		default:

+ 4 - 0
lang/cem/cemcom/idf.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* IDENTIFIER DESCRIPTOR */
 

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

@@ -29,14 +29,13 @@ getwdir(fn)
 
 	if (fn[0] == '\0' || (fn[0] == '/' && p == &fn[0])) /* absolute path */
 		return "";
-	else
 	if (p) {
 		*p = '\0';
 		fn = Salloc(fn, p - &fn[0] + 1);
 		*p = '/';
 		return fn;
 	}
-	else return ".";
+	return ".";
 }
 #endif NOPP
 

+ 656 - 0
lang/cem/cemcom/ival.g

@@ -0,0 +1,656 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+/* $Header$ */
+/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */
+
+{
+#include	"nofloat.h"
+#include	<em.h>
+#include	"debug.h"
+#include	<alloc.h>
+#include	"nobitfield.h"
+#include	"arith.h"
+#include	"align.h"
+#include	"label.h"
+#include	"expr.h"
+#include	"type.h"
+#include	"struct.h"
+#include	"field.h"
+#include	"assert.h"
+#include	"Lpars.h"
+#include	"class.h"
+#include	"sizes.h"
+#include	"idf.h"
+#include	"level.h"
+#include	"def.h"
+#include	"LLlex.h"
+#include	"noRoption.h"
+#include	"estack.h"
+
+#define con_nullbyte()	C_con_ucon("0", (arith)1)
+#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)
+
+char *long2str();
+char *strncpy();
+extern char options[];
+static int gen_error;
+struct type **gen_tphead(), **gen_tpmiddle();
+struct sdef *gen_align_to_next();
+}
+
+/*	initial_value recursively guides the initialisation expression.
+	Upto now, the initialisation of a union is not allowed!
+*/
+/* 7 */
+initial_value(register struct type **tpp; register struct expr **expp;) :
+			{ if (tpp) gen_tpcheck(tpp, 0); }
+[
+	assignment_expression(expp)
+			{ if ((*expp)->ex_type->tp_fund == ARRAY)
+				array2pointer(*expp);
+			  if (tpp) {
+			  	gen_simple_exp(tpp, expp);
+			  	free_expression(*expp);
+				*expp = 0;
+			  }
+			}
+|
+	initial_value_pack(tpp, expp)
+]
+;
+
+initial_value_pack(struct type **tpp; struct expr **expp;) :
+	'{'
+	initial_value_list(tpp, expp)
+	'}'
+;
+
+initial_value_list(register struct type *tpp; struct expr **expp;)
+	{ struct expr *e1;
+	  register struct type **tpp2 = 0;
+	}
+:
+			{ if (tpp) tpp2 = gen_tphead(tpp, 0); }
+	initial_value(tpp2, &e1)
+			{ if (!tpp) init_expression(&expp, e1); }
+	[%while (AHEAD != '}')		/* >>> conflict on ',' */
+		','
+			{ if (tpp) tpp2 = gen_tpmiddle(); }
+		initial_value(tpp2, &e1)
+			{ if (!tpp) init_expression(&expp, e1); }
+	]*
+			{ if (tpp) gen_tpend(); }
+	','?				/* optional trailing comma */
+;
+
+{
+gen_tpcheck(tpp, union_allowed)
+	struct type **tpp;
+{
+	register struct type *tp;
+
+	if (gen_error) return;
+	switch((tp = *tpp)->tp_fund) {
+	case ARRAY:
+		if (! valid_type(tp->tp_up, "array element"))
+			gen_error = 1;
+		break;
+	case STRUCT:
+		if (! valid_type(tp, "struct"))
+			gen_error = 1;
+		break;
+	case UNION:
+		if (! union_allowed) {
+			error("union initialisation not allowed");
+			gen_error = 1;
+			break;
+		}
+		if (! valid_type(tp, "union"))
+			gen_error = 1;
+		break;
+	}
+}
+
+gen_simple_exp(tpp, expp)
+	struct type **tpp;
+	struct expr **expp;
+{
+	register struct type *tp;
+
+	if (gen_error) return;
+	tp = *tpp;
+	switch(tp->tp_fund) {
+	case ARRAY:
+		if ((*expp)->ex_class == String && tp->tp_up->tp_fund == CHAR) {
+			ch_array(tpp,*expp);
+			break;
+		}
+		/* Fall through */
+	case STRUCT:
+		check_and_pad(expp, tpp);
+		break;
+	case ERRONEOUS:
+		gen_error = 1;
+		break;
+	default:
+		check_ival(expp, tp);
+		break;
+	}
+}
+
+struct e_stack *p_stack;
+
+struct type **
+arr_elem(tpp, p)
+	struct type **tpp;
+	struct e_stack *p;
+{
+	register struct type *tp = *tpp;
+
+	if (tp->tp_up->tp_fund == CHAR && AHEAD == STRING && p->elem_count == 1) {
+		p->nelem = 1;
+		return tpp;
+	}
+	if (AHEAD == '{' || ! aggregate_type(tp->tp_up))
+		return &(tp->tp_up);
+	return gen_tphead(&(tp->tp_up), 1);
+}
+
+struct sdef *
+next_field(sd, p)
+	register struct sdef *sd;
+	register struct e_stack *p;
+{
+	if (sd->sd_sdef)
+		p->bytes_upto_here += zero_bytes(sd);
+	if (p->last_offset != sd->sd_offset) {
+		p->bytes_upto_here +=
+			size_of_type(sd->sd_type, "selector");
+		p->last_offset = sd->sd_offset;
+	}
+	return sd->sd_sdef;
+}
+
+struct type **
+gen_tphead(tpp, nest)
+	struct type **tpp;
+{
+	register struct type *tp = *tpp;
+	register struct e_stack *p = new_e_stack();
+	register struct sdef *sd;
+
+	if (gen_error) return tpp;
+	p->next = p_stack;
+	p_stack = p;
+	p->s_nested = nest;
+	p->s_tpp = tpp;
+	switch(tp->tp_fund) {
+	case ARRAY:
+		p->nelem = -1;
+		p->elem_count = 1;
+		if (tp->tp_size != (arith) -1) {
+			p->nelem = (tp->tp_size / tp->tp_up->tp_size);
+		}
+		return arr_elem(tpp, p);
+	case STRUCT:
+		p->s_def = sd = tp->tp_sdef;
+		p->bytes_upto_here = 0;
+		p->last_offset = -1;
+#ifndef NOBITFIELD
+		while (sd && is_anon_idf(sd->sd_idf)) {
+			put_bf(sd->sd_type, (arith) 0);
+			sd = next_field(sd, p);
+		}
+#endif
+		p->s_def = sd;
+		if (AHEAD != '{' && aggregate_type(sd->sd_type)) {
+			return gen_tphead(&(sd->sd_type), 1);
+		}
+		return &(sd->sd_type);
+	default:
+		p->nelem = 1;
+		p->elem_count = 1;
+		return tpp;
+	}
+}
+
+struct type **
+gen_tpmiddle()
+{
+	register struct type *tp;
+	register struct sdef *sd;
+	register struct e_stack *p = p_stack;
+
+	if (gen_error) return p->s_tpp;
+again:
+	tp = *(p->s_tpp);
+	switch(tp->tp_fund) {
+	default:
+		if (p->elem_count == p->nelem && p->s_nested) {
+			p = p->next;
+			free_e_stack(p_stack);
+			p_stack = p;
+			goto again;
+		}
+		p->elem_count++;
+		if (p->nelem >= 0 && p->elem_count > p->nelem) {
+			too_many_initialisers();
+			return p->s_tpp;
+		}
+		if (tp->tp_fund == ARRAY) {
+			return arr_elem(p->s_tpp, p);
+		}
+		return p->s_tpp;
+	case STRUCT:
+		sd = gen_align_to_next(p);
+		if (! sd) {
+			while (p->bytes_upto_here++ < tp->tp_size)
+				con_nullbyte();
+			if (p->s_nested) {
+				p = p->next;
+				free_e_stack(p_stack);
+				p_stack = p;
+				goto again;
+			}
+			too_many_initialisers();
+			return p->s_tpp;
+		}
+		if (AHEAD != '{' && aggregate_type(sd->sd_type)) {
+			return gen_tphead(&(sd->sd_type), 1);
+		}
+		return &(sd->sd_type);
+	}
+}
+
+struct sdef *
+gen_align_to_next(p)
+	register struct e_stack *p;
+{
+	register struct sdef *sd = p->s_def;
+
+	if (! sd) return sd;
+#ifndef NOBITFIELD
+	do {
+		if (is_anon_idf(sd->sd_idf)) put_bf(sd->sd_type, (arith) 0);
+#endif
+		sd = next_field(sd, p);
+#ifndef NOBITFIELD
+	} while (sd && is_anon_idf(sd->sd_idf));
+#endif
+	p->s_def = sd;
+	return sd;
+}
+
+gen_tpend()
+{
+	register struct e_stack *p = p_stack;
+	register struct type *tp;
+	register struct sdef *sd;
+	int getout = 0;
+
+	while (!getout) {
+	    if (!gen_error) {
+		tp = *(p->s_tpp);
+		switch(tp->tp_fund) {
+		case ARRAY:
+			if (tp->tp_size == -1) {
+				*(p->s_tpp) = construct_type(ARRAY,
+					tp->tp_up, p->elem_count);
+			}
+			else {
+				while (p->nelem-- > p->elem_count) {
+					pad(tp->tp_up);
+				}
+			}
+			break;
+		case STRUCT:
+			sd = gen_align_to_next(p);
+			while (sd) {
+				pad(sd->sd_type);
+				if (sd->sd_sdef)
+					p->bytes_upto_here += zero_bytes(sd);
+				p->bytes_upto_here +=
+					size_of_type(sd->sd_type, "selector");
+				sd = sd->sd_sdef;
+			}
+			while (p->bytes_upto_here++ < tp->tp_size)
+				con_nullbyte();
+			break;
+		}
+	    }
+	    if (! p->s_nested) getout = 1;
+	    p = p->next;
+	    free_e_stack(p_stack);
+	    p_stack = p;
+	}
+	gen_error = 0;
+}
+
+/*	check_and_pad() is given a simple initialisation expression
+	where the type can be either a simple or an aggregate type.
+	In the latter case, only the first member is initialised and
+	the rest is zeroed.
+*/
+check_and_pad(expp, tpp)
+	struct type **tpp;
+	struct expr **expp;
+{
+	/* ex is of a fundamental type	*/
+	register struct type *tp = *tpp;
+	register struct expr *ex = *expp;
+
+	if (tp->tp_fund == ARRAY) {
+		check_and_pad(expp, &(tp->tp_up));	/* first member	*/
+		if (tp->tp_size == (arith)-1)
+			/*	no size specified upto here: just
+				set it to the size of one member.
+			*/
+			tp = *tpp = construct_type(ARRAY, tp->tp_up, (arith)1);
+		else {
+			register int dim = tp->tp_size / tp->tp_up->tp_size;
+			/* pad remaining members with zeroes */
+			while (--dim > 0)
+				pad(tp->tp_up);
+		}
+	}
+	else
+	if (tp->tp_fund == STRUCT) {
+		register struct sdef *sd = tp->tp_sdef;
+
+		check_and_pad(expp, &(sd->sd_type));
+		/* next selector is aligned by adding extra zeroes */
+		if (sd->sd_sdef)
+			zero_bytes(sd);
+		while (sd = sd->sd_sdef) { /* pad remaining selectors	*/
+			pad(sd->sd_type);
+			if (sd->sd_sdef)
+				zero_bytes(sd);
+		}
+	}
+	else	/* simple type	*/
+		check_ival(expp, tp);
+}
+
+/*	pad() fills an element of type tp with zeroes.
+	If the element is an aggregate, pad() is called recursively.
+*/
+pad(tpx)
+	struct type *tpx;
+{
+	register struct type *tp = tpx;
+	register arith sz = tp->tp_size;
+
+	gen_tpcheck(&tpx, 1);
+	if (gen_error) return;
+	switch (tp->tp_fund) {
+	case UNION:
+#ifndef NOROPTION
+		if (options['R']) {
+			warning("initialisation of unions not allowed");
+		}
+#endif
+		break;
+#ifndef NOBITFIELD
+	case FIELD:
+		put_bf(tp, (arith)0);
+		return;
+#endif NOBITFIELD
+		default:
+			break;
+	}
+
+	while (sz >= word_size) {
+		C_con_cst((arith) 0);
+		sz -= word_size;
+	}
+	while (sz) {
+		C_con_icon("0", (arith) 1);
+		sz--;
+	}
+}
+
+/*	check_ival() checks whether the initialisation of an element
+	of a fundamental type is legal and, if so, performs the initialisation
+	by directly generating the necessary code.
+	No further comment is needed to explain the internal structure
+	of this straightforward function.
+*/
+check_ival(expp, tp)
+	register struct type *tp;
+	struct expr **expp;
+{
+	/*	The philosophy here is that ch7cast puts an explicit
+		conversion node in front of the expression if the types
+		are not compatible.  In this case, the initialisation
+		expression is no longer a constant.
+	*/
+	register struct expr *expr = *expp;
+	
+	switch (tp->tp_fund) {
+	case CHAR:
+	case SHORT:
+	case INT:
+	case LONG:
+	case ENUM:
+	case POINTER:
+		ch7cast(expp, '=', tp);
+		expr = *expp;
+#ifdef DEBUG
+		print_expr("init-expr after cast", expr);
+#endif DEBUG
+		if (!is_ld_cst(expr))
+			illegal_init_cst(expr);
+		else
+		if (expr->VL_CLASS == Const)
+			con_int(expr);
+		else
+		if (expr->VL_CLASS == Name) {
+			register struct idf *idf = expr->VL_IDF;
+
+			if (idf->id_def->df_level >= L_LOCAL)
+				illegal_init_cst(expr);
+			else	/* e.g., int f(); int p = f; */
+			if (idf->id_def->df_type->tp_fund == FUNCTION)
+				C_con_pnam(idf->id_text);
+			else	/* e.g., int a; int *p = &a; */
+				C_con_dnam(idf->id_text, expr->VL_VALUE);
+		}
+		else {
+			ASSERT(expr->VL_CLASS == Label);
+			C_con_dlb(expr->VL_LBL, expr->VL_VALUE);
+		}
+		break;
+#ifndef NOFLOAT
+	case FLOAT:
+	case DOUBLE:
+		ch7cast(expp, '=', tp);
+		expr = *expp;
+#ifdef DEBUG
+		print_expr("init-expr after cast", expr);
+#endif DEBUG
+		if (expr->ex_class == Float)
+			C_con_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
+		else
+		if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) {
+			/* float f = 1; */
+			expr = expr->OP_RIGHT;
+			if (is_cp_cst(expr))
+				C_con_fcon(long2str((long)expr->VL_VALUE, 10),
+					tp->tp_size);
+			else 
+				illegal_init_cst(expr);
+		}
+		else
+			illegal_init_cst(expr);
+		break;
+#endif NOFLOAT
+
+#ifndef NOBITFIELD
+	case FIELD:
+		ch7cast(expp, '=', tp->tp_up);
+		expr = *expp;
+#ifdef DEBUG
+		print_expr("init-expr after cast", expr);
+#endif DEBUG
+		if (is_cp_cst(expr))
+			put_bf(tp, expr->VL_VALUE);
+		else
+			illegal_init_cst(expr);
+		break;
+#endif NOBITFIELD
+
+	case ERRONEOUS:
+		break;
+	default:
+		crash("check_ival");
+	}
+}
+
+/*	ch_array() initialises an array of characters when given
+	a string constant.
+	Alignment is taken care of.
+*/
+ch_array(tpp, ex)
+	struct type **tpp;	/* type tp = array of characters	*/
+	struct expr *ex;
+{
+	register struct type *tp = *tpp;
+	register arith length = ex->SG_LEN;
+	char *s;
+	arith ntopad;
+
+	ASSERT(ex->ex_class == String);
+	if (tp->tp_size == (arith)-1) {
+		/* set the dimension	*/
+		tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
+		ntopad = align(tp->tp_size, word_size) - tp->tp_size;
+	}
+	else {
+		arith dim = tp->tp_size / tp->tp_up->tp_size;
+		extern char options[];
+
+		if (length > dim) {
+			expr_warning(ex, "too many initialisers");
+			length = dim;
+		}
+		ntopad = align(dim, word_size) - length;
+	}
+	/* throw out the characters of the already prepared string	*/
+	s = Malloc((unsigned) (length + ntopad));
+	clear(s, (int) (length + ntopad));
+	strncpy(s, ex->SG_VALUE, (int) length);
+	free(ex->SG_VALUE);
+	str_cst(s, (int) (length + ntopad));
+	free(s);
+}
+
+/*	As long as some parts of the pipeline cannot handle very long string
+	constants, string constants are written out in chunks
+*/
+str_cst(str, len)
+	register char *str;
+	register int len;
+{
+	arith chunksize = ((127 + word_size) / word_size) * word_size;
+
+	while (len > chunksize) {
+		C_con_scon(str, chunksize);
+		len -= chunksize;
+		str += chunksize;
+	}
+	C_con_scon(str, (arith) len);
+}
+
+#ifndef NOBITFIELD
+/*	put_bf() takes care of the initialisation of (bit-)field
+	selectors of a struct: each time such an initialisation takes place,
+	put_bf() is called instead of the normal code generating routines.
+	Put_bf() stores the given integral value into "field" and
+	"throws" the result of "field" out if the current selector
+	is the last of this number of fields stored at the same address.
+*/
+put_bf(tp, val)
+	struct type *tp;
+	arith val;
+{
+	static long field = (arith)0;
+	static arith offset = (arith)-1;
+	register struct field *fd = tp->tp_field;
+	register struct sdef *sd =  fd->fd_sdef;
+	static struct expr exp;
+
+	ASSERT(sd);
+	if (offset == (arith)-1) {
+		/* first bitfield in this field	*/
+		offset = sd->sd_offset;
+		exp.ex_type = tp->tp_up;
+		exp.ex_class = Value;
+		exp.VL_CLASS = Const;
+	}
+	if (val != 0)	/* insert the value into "field"	*/
+		field |= (val & fd->fd_mask) << fd->fd_shift;
+	if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) {
+		/* the selector was the last stored at this address	*/
+		exp.VL_VALUE = field;
+		con_int(&exp);
+		field = (arith)0;
+		offset = (arith)-1;
+	}
+}
+#endif NOBITFIELD
+
+int
+zero_bytes(sd)
+	register struct sdef *sd;
+{
+	/*	fills the space between a selector of a struct
+		and the next selector of that struct with zero-bytes.
+	*/
+	register int n = sd->sd_sdef->sd_offset - sd->sd_offset -
+		size_of_type(sd->sd_type, "struct member");
+	register int count = n;
+
+	while (n-- > 0)
+		con_nullbyte();
+	return count;
+}
+
+int
+valid_type(tp, str)
+	struct type *tp;
+	char *str;
+{
+	if (tp->tp_size < 0) {
+		error("size of %s unknown", str);
+		return 0;
+	}
+	return 1;
+}
+
+con_int(ex)
+	register struct expr *ex;
+{
+	register struct type *tp = ex->ex_type;
+
+	ASSERT(is_cp_cst(ex));
+	if (tp->tp_unsigned)
+		C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size);
+	else
+		C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);
+}
+
+illegal_init_cst(ex)
+	struct expr *ex;
+{
+	expr_error(ex, "illegal initialisation constant");
+	gen_error = 1;
+}
+
+too_many_initialisers()
+{
+	error("too many initialisers");
+	gen_error = 1;
+}
+}

+ 8 - 26
lang/cem/cemcom/label.c

@@ -12,29 +12,10 @@
 #include	"arith.h"
 #include	"def.h"
 #include	"type.h"
+#include	"noRoption.h"
 
 extern char options[];
 
-define_label(idf)
-	struct idf *idf;
-{
-	/*	The identifier idf is defined as a label. If it is new,
-		it is entered into the idf list with the largest possible
-		scope, i.e., on the lowest possible level.
-	*/
-	enter_label(idf, 1);
-}
-
-apply_label(idf)
-	struct idf *idf;
-{
-	/*	The identifier idf is applied as a label. It may or may
-		not be there, and if it is there, it may be from a
-		declaration or another application.
-	*/
-	enter_label(idf, 0);
-}
-
 enter_label(idf, defining)
 	register struct idf *idf;
 {
@@ -52,21 +33,22 @@ enter_label(idf, defining)
 								idf->id_text);
 		}
 		else	{		/* there may still be room for it */
-			int deflevel = def->df_level;
-			
+#ifndef NOROPTION
 			if (options['R'] && def->df_sc == TYPEDEF)
 				warning("label %s is also a typedef",
 					idf->id_text);
+#endif
 			
-			if (deflevel == level)	/* but alas, no */
+			if (def->df_level == level)	/* but alas, no */
 				error("%s is not a label", idf->id_text);
 			else	{
-				int lvl;
+				register int lvl = def->df_level + 1;
 				
-				if (options['R'] && deflevel > L_LOCAL)
+#ifndef NOROPTION
+				if (options['R'] && def->df_level > L_LOCAL)
 					warning("label %s is not function-wide",
 								idf->id_text);
-				lvl = deflevel + 1;
+#endif
 				if (lvl < L_LOCAL)
 					lvl = L_LOCAL;
 				add_def(idf, LABEL, label_type, lvl);

+ 12 - 0
lang/cem/cemcom/label.h

@@ -14,3 +14,15 @@ extern label lab_count;
 
 extern label datlab_count;
 #define	data_label()	(datlab_count++)	/* returns a new data label */
+
+#define define_label(idf) enter_label(idf, 1);
+	/*	The identifier idf is defined as a label. If it is new,
+		it is entered into the idf list with the largest possible
+		scope, i.e., on the lowest possible level.
+	*/
+
+#define apply_label(idf) enter_label(idf, 0);
+	/*	The identifier idf is applied as a label. It may or may
+		not be there, and if it is there, it may be from a
+		declaration or another application.
+	*/

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

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* PREPROCESSOR: DEFINITION OF MACRO DESCRIPTOR */
 

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

@@ -24,6 +24,10 @@
 #include	"LLlex.h"
 #include	<alloc.h>
 #include	"specials.h"
+#include	"noRoption.h"
+#include	"nocross.h"
+#include	"sizes.h"
+#include	"align.h"
 
 extern struct tokenname tkidf[], tkother[];
 extern char *symbol2str();
@@ -45,6 +49,7 @@ struct sp_id special_ids[] =	{
 	{0, 0}
 };
 
+#ifndef NOCROSS
 arith
 	short_size = SZ_SHORT,
 	word_size = SZ_WORD,
@@ -69,6 +74,7 @@ int
 	pointer_align = AL_POINTER,
 	struct_align = AL_STRUCT,
 	union_align = AL_UNION;
+#endif NOCROSS
 
 #ifndef NOPP
 arith ifval;	/* ifval will contain the result of the #if expression	*/
@@ -232,8 +238,10 @@ init()
 	reserve(tkidf);		/* mark the C reserved words as such	*/
 	init_specials(special_ids);	/* mark special ids as such	*/
 
+#ifndef NOROPTION
 	if (options['R'])
 		reserve(tkother);
+#endif
 
 	char_type = standard_type(CHAR, 0, 1, (arith)1);
 	uchar_type = standard_type(CHAR, UNSIGNED, 1, (arith)1);

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

@@ -20,6 +20,7 @@
 #include	"align.h"
 #include	"use_tmp.h"
 #include	"dataflow.h"
+#include	"noRoption.h"
 
 #ifndef NOPP
 extern char *inctable[MAXINCL];
@@ -53,9 +54,16 @@ do_option(text)
 	case 'L' :			/* no fil/lin */
 	case 'n':			/* use no registers */
 	case 'w':			/* no warnings will be given */
+#ifndef NOROPTION
 	case 'R':			/* strict version */
+#endif
 		options[*(text-1)] = 1;
 		break;
+#ifdef NOROPTION
+	case 'R':
+		warning("-R option not implemented");
+		break;
+#endif
 
 #ifdef ___XXX___
 deleted, is now a debug-flag
@@ -118,11 +126,11 @@ deleted, is now a debug-flag
 	case 'I' :	/* -Ipath : insert "path" into include list	*/
 #ifndef NOPP
 		if (*text)	{
-			register int i = inc_pos++;
+			int i = inc_pos++;
 			register char *new = text;
 			
 			while (new)	{
-				register char *tmp = inctable[i];
+				char *tmp = inctable[i];
 				
 				inctable[i++] = new;
 				if (i == MAXINCL)
@@ -176,7 +184,7 @@ deleted, is now a debug-flag
 		
 	case 'U' :	{	/* -Uname :	undefine predefined	*/
 #ifndef NOPP
-		struct idf *idef;
+		register struct idf *idef;
 
 		if (*text)	{
 			if ((idef = str2idf(text))->id_macro) {
@@ -191,8 +199,12 @@ deleted, is now a debug-flag
 	}
 
 	case 'V' :	/* set object sizes and alignment requirements	*/
+#ifdef NOCROSS
+		warning("-V option ignored");
+		break;
+#else NOCROSS
 	{
-		arith size, align;
+		register arith size, align;
 		char c;
 
 		while (c = *text++)	{
@@ -270,12 +282,13 @@ deleted, is now a debug-flag
 		}
 		break;
 	}
+#endif NOCROSS
 	}
 }
 
 int
 txt2int(tp)
-	char **tp;
+	register char **tp;
 {
 	/*	the integer pointed to by *tp is read, while increasing
 		*tp; the resulting value is yielded.

+ 5 - 7
lang/cem/cemcom/program.g

@@ -148,15 +148,13 @@ ext_decl_specifiers(struct decspecs *ds;) :
 ;
 
 non_function(register struct decspecs *ds; register struct declarator *dc;)
-	{
-		struct expr *expr = (struct expr *) 0;
-	}
 :
 	{reject_params(dc);}
-	initializer(dc->dc_idf, &expr)?
-	{
-		code_declaration(dc->dc_idf, expr, level, ds->ds_sc);
-	}
+	[
+		initializer(dc->dc_idf, ds->ds_sc)
+	|
+		{ code_declaration(dc->dc_idf, (struct excpr *) 0, level, ds->ds_sc); }
+	]
 	[
 		','
 		init_declarator(ds)

+ 15 - 0
lang/cem/cemcom/sizes.h

@@ -6,12 +6,27 @@
 /* VARIOUS TARGET MACHINE SIZE DESCRIPTORS */
 
 #include "nofloat.h"
+#include "nocross.h"
+#include "target_sizes.h"
 
+#ifndef NOCROSS
 extern arith
 	short_size, word_size, dword_size, int_size, long_size,
 #ifndef NOFLOAT
 	float_size, double_size,
 #endif NOFLOAT
 	pointer_size;
+#else NOCROSS
+#define short_size	(SZ_SHORT)
+#define word_size	(SZ_WORD)
+#define dword_size	(2*SZ_WORD)
+#define int_size	(SZ_INT)
+#define long_size	(SZ_LONG)
+#ifndef NOFLOAT
+#define float_size	(SZ_FLOAT)
+#define double_size	(SZ_DOUBLE)
+#endif NOFLOAT
+#define pointer_size	(SZ_POINTER)
+#endif NOCROSS
 
 extern arith max_int, max_unsigned;	/* cstoper.c	*/

+ 9 - 7
lang/cem/cemcom/stack.c

@@ -21,6 +21,7 @@
 #include	"struct.h"
 #include	"level.h"
 #include	"mes.h"
+#include	"noRoption.h"
 
 /* #include	<em_reg.h> */
 
@@ -75,16 +76,15 @@ stack_level_of(lvl)
 		The stack should probably be an array, to be extended with
 		realloc where needed.
 	*/
+	register struct stack_level *stl;
+
 	if (lvl == level)
 		return local_level;
-	else	{
-		register struct stack_level *stl = &UniversalLevel;
+	stl = &UniversalLevel;
 		
-		while (stl->sl_level != lvl)
-			stl = stl->sl_next;
-		return stl;
-	}
-	/*NOTREACHED*/
+	while (stl->sl_level != lvl)
+		stl = stl->sl_next;
+	return stl;
 }
 
 unstack_level()
@@ -238,11 +238,13 @@ unstack_world()
 			&& !def->df_initialized
 		)	{
 			/* orphaned static function */
+#ifndef NOROPTION
 			if (options['R'])
 				warning("static function %s never defined, %s",
 					idf->id_text,
 					"changed to extern"
 				);
+#endif
 			def->df_sc = EXTERN;
 		}
 		

+ 4 - 0
lang/cem/cemcom/stack.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* IDENTIFIER STACK DEFINITIONS */
 

+ 6 - 16
lang/cem/cemcom/statement.g

@@ -53,9 +53,13 @@ statement
 |
 	default_statement
 |
-	break_statement
+	BREAK
+	{code_break();}
+	';'
 |
-	continue_statement
+	CONTINUE
+	{code_continue();}
+	';'
 |
 	return_statement
 |
@@ -316,20 +320,6 @@ default_statement
 	statement
 ;
 
-break_statement
-:
-	BREAK
-	{code_break();}
-	';'
-;
-
-continue_statement
-:
-	CONTINUE
-	{code_continue();}
-	';'
-;
-
 return_statement
 	{	struct expr *expr = 0;
 	}

+ 4 - 0
lang/cem/cemcom/stmt.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /*	S T A T E M E N T - B L O C K   D E F I N I T I O N S	*/
 

+ 11 - 2
lang/cem/cemcom/struct.c

@@ -22,6 +22,7 @@
 #include	"level.h"
 #include	"assert.h"
 #include	"sizes.h"
+#include	"noRoption.h"
 
 /*	Type of previous selector declared with a field width specified,
 	if any.  If a selector is declared with no field with it is set to 0.
@@ -76,11 +77,13 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)	/* this is horrible */
 	register struct sdef *newsdef;
 	int lvl = tg->tg_level;
 	
+#ifndef NOROPTION
 	if (options['R'] && !is_anon_idf(idf))	{
 		/* a K & R test */
 		if (idf->id_struct && idf->id_struct->tg_level == level)
 			warning("%s is also a struct/union tag", idf->id_text);
 	}
+#endif
 
 	if (stp->tp_fund == STRUCT)	{
 #ifndef NOBITFIELD
@@ -110,12 +113,14 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)	/* this is horrible */
 	}
 	
 	check_selector(idf, stp);
+#ifndef NOROPTION
 	if (options['R'])	{
 		if (	sdef && sdef->sd_level == lvl &&
-			sdef->sd_offset != offset
-		)				/* RM 8.7 */
+			( sdef->sd_offset != offset || sdef->sd_type != tp )
+		)				/* RM 8.5 */
 			warning("selector %s redeclared", idf->id_text);
 	}
+#endif
 
 	newsdef = new_sdef();
 	newsdef->sd_sdef = (struct sdef *) 0;
@@ -195,6 +200,7 @@ declare_struct(fund, idf, tpp)
 		idf = gen_idf();
 	tgp = (fund == ENUM ? &idf->id_enum : &idf->id_struct);
 	
+#ifndef NOROPTION
 	if (options['R'] && !is_anon_idf(idf))	{
 		/* a K & R test */
 		if (	fund != ENUM &&
@@ -208,6 +214,7 @@ declare_struct(fund, idf, tpp)
 			warning("%s is also a variable", idf->id_text);
 		}
 	}
+#endif
 	
 	tg = *tgp;
 	if (tg && tg->tg_type->tp_size < 0 && tg->tg_type->tp_fund == fund) {
@@ -220,9 +227,11 @@ declare_struct(fund, idf, tpp)
 			declare_struct(fund, gen_idf(), tpp);
 		}
 		else {
+#ifndef NOROPTION
 			if (options['R'] && tg->tg_level != level)
 				warning("%s declares %s in different range",
 					idf->id_text, symbol2str(fund));
+#endif
 			*tpp = tg->tg_type;
 		}
 	}

+ 4 - 0
lang/cem/cemcom/struct.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* SELECTOR DESCRIPTOR */
 

+ 3 - 0
lang/cem/cemcom/switch.c

@@ -20,6 +20,7 @@
 #include	"assert.h"
 #include	"expr.h"
 #include	"type.h"
+#include	"noRoption.h"
 
 extern char options[];
 
@@ -47,8 +48,10 @@ code_startswitch(expp)
 	
 	switch (fund) {
 	case LONG:
+#ifndef NOROPTION
 		if (options['R'])
 			warning("long in switch (cast to int)");
+#endif
 		int2int(expp, int_type);
 		break;
 #ifndef NOFLOAT

+ 5 - 1
lang/cem/cemcom/switch.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /*		S W I T C H - T A B L E - S T R U C T U R E		*/
 
@@ -21,4 +25,4 @@ struct case_entry	{
 	arith ce_value;
 };
 
-/* ALLOCDEF "case_entry" 40 */
+/* ALLOCDEF "case_entry" 20 */

+ 5 - 1
lang/cem/cemcom/type.str

@@ -1,3 +1,7 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
 /* $Header$ */
 /* TYPE DESCRIPTOR */
 
@@ -44,4 +48,4 @@ extern struct type *pa_type;	/* type.c	*/
 
 extern arith size_of_type(), align();
 
-/* ALLOCDEF "type" 50 */
+/* ALLOCDEF "type" 20 */