Better ANSI C compatibility and portability:
authorcarl <cecodere@yahoo.ca>
Mon, 18 Feb 2019 16:42:15 +0000 (00:42 +0800)
committercarl <cecodere@yahoo.ca>
Mon, 18 Feb 2019 16:54:23 +0000 (00:54 +0800)
+ Addition of function prototypes and include files.
+ Change function definitions to ANSI C style.
+ Initial support for CMake
+ Scripts to generate compiler header is now sed based.

82 files changed:
lang/cem/cemcom.ansi/BigPars
lang/cem/cemcom.ansi/CMakeLists.txt [new file with mode: 0644]
lang/cem/cemcom.ansi/LLlex.c
lang/cem/cemcom.ansi/LLlex.h
lang/cem/cemcom.ansi/LLmessage.c
lang/cem/cemcom.ansi/arith.c
lang/cem/cemcom.ansi/arith.h
lang/cem/cemcom.ansi/blocks.c
lang/cem/cemcom.ansi/blocks.h [new file with mode: 0644]
lang/cem/cemcom.ansi/ch3.c
lang/cem/cemcom.ansi/ch3.h [new file with mode: 0644]
lang/cem/cemcom.ansi/ch3bin.c
lang/cem/cemcom.ansi/ch3bin.h [new file with mode: 0644]
lang/cem/cemcom.ansi/ch3mon.c
lang/cem/cemcom.ansi/ch3mon.h [new file with mode: 0644]
lang/cem/cemcom.ansi/code.c
lang/cem/cemcom.ansi/code.str
lang/cem/cemcom.ansi/conversion.c
lang/cem/cemcom.ansi/conversion.h [new file with mode: 0644]
lang/cem/cemcom.ansi/cstoper.c
lang/cem/cemcom.ansi/cstoper.h [new file with mode: 0644]
lang/cem/cemcom.ansi/dataflow.c
lang/cem/cemcom.ansi/dataflow.h [new file with mode: 0644]
lang/cem/cemcom.ansi/declar.g
lang/cem/cemcom.ansi/declar.str
lang/cem/cemcom.ansi/declarator.c
lang/cem/cemcom.ansi/declarator.h [new file with mode: 0644]
lang/cem/cemcom.ansi/decspecs.c
lang/cem/cemcom.ansi/decspecs.h
lang/cem/cemcom.ansi/def.str
lang/cem/cemcom.ansi/domacro.c
lang/cem/cemcom.ansi/domacro.h [new file with mode: 0644]
lang/cem/cemcom.ansi/error.c
lang/cem/cemcom.ansi/error.h [new file with mode: 0644]
lang/cem/cemcom.ansi/estack.str
lang/cem/cemcom.ansi/eval.c
lang/cem/cemcom.ansi/eval.h [new file with mode: 0644]
lang/cem/cemcom.ansi/expr.c
lang/cem/cemcom.ansi/expr.str
lang/cem/cemcom.ansi/expression.g
lang/cem/cemcom.ansi/field.c
lang/cem/cemcom.ansi/field.str
lang/cem/cemcom.ansi/fltcstoper.c
lang/cem/cemcom.ansi/fltcstoper.h [new file with mode: 0644]
lang/cem/cemcom.ansi/idf.c
lang/cem/cemcom.ansi/idf.str
lang/cem/cemcom.ansi/input.c
lang/cem/cemcom.ansi/input.h
lang/cem/cemcom.ansi/ival.g
lang/cem/cemcom.ansi/label.c
lang/cem/cemcom.ansi/label.h
lang/cem/cemcom.ansi/main.c
lang/cem/cemcom.ansi/next.str [new file with mode: 0644]
lang/cem/cemcom.ansi/options.c
lang/cem/cemcom.ansi/options.h [new file with mode: 0644]
lang/cem/cemcom.ansi/pragma.c
lang/cem/cemcom.ansi/pragma.h [new file with mode: 0644]
lang/cem/cemcom.ansi/program.g
lang/cem/cemcom.ansi/proto.c
lang/cem/cemcom.ansi/proto.str
lang/cem/cemcom.ansi/skip.c
lang/cem/cemcom.ansi/skip.h [new file with mode: 0644]
lang/cem/cemcom.ansi/stab.c
lang/cem/cemcom.ansi/stab.h [new file with mode: 0644]
lang/cem/cemcom.ansi/stack.c
lang/cem/cemcom.ansi/stack.str
lang/cem/cemcom.ansi/statement.g
lang/cem/cemcom.ansi/stb.c
lang/cem/cemcom.ansi/stmt.str
lang/cem/cemcom.ansi/struct.c
lang/cem/cemcom.ansi/struct.str
lang/cem/cemcom.ansi/switch.c
lang/cem/cemcom.ansi/switch.str
lang/cem/cemcom.ansi/tokcase.sed [new file with mode: 0644]
lang/cem/cemcom.ansi/tokcasee.in [new file with mode: 0644]
lang/cem/cemcom.ansi/tokcaseh.in [new file with mode: 0644]
lang/cem/cemcom.ansi/tokenname.c
lang/cem/cemcom.ansi/tokenname.h
lang/cem/cemcom.ansi/type.c
lang/cem/cemcom.ansi/type.str
lang/cem/cemcom.ansi/util.c
lang/cem/cemcom.ansi/util.str

index 6f4b097..bf92e22 100644 (file)
-!File: lint.h
-/*#define      LINT            1       /* if defined, 'lint' is produced       */
-
-
-!File: pathlength.h
-#define PATHLENGTH     1024    /* max. length of path to file          */
-
-
-!File: errout.h
-#define        ERROUT          STDERR  /* file pointer for writing messages    */
-#define        ERR_SHADOW      5       /* a syntax error overshadows error messages
-                                       until ERR_SHADOW symbols have been
-                                       accepted without syntax error */
-
-
-!File: idfsize.h
-#define        IDFSIZE 64      /* maximum significant length of an identifier  */
-
-
-!File: numsize.h
-#define        NUMSIZE 256     /* maximum length of a numeric constant         */
-
-
-!File: nparams.h
-#define        NPARAMS 32      /* maximum number of parameters                 */
-#define        STDC_NPARAMS 31 /* ANSI limit on number of parameters           */
-
-
-!File: ifdepth.h
-#define        IFDEPTH 256     /* maximum number of nested if-constructions    */
-
-
-!File: density.h
-#define        DENSITY 3       /* see switch.[ch] for an explanation           */
-
-
-!File: macbuf.h
-#define        LAPBUF  128     /* initial size of macro replacement buffer     */
-#define ARGBUF 128     /* initial size of macro parameter buffer(s)    */
-
-
-!File: strsize.h
-#define ISTRSIZE       32      /* minimum number of bytes allocated for
-                                       storing a string                */
-#define RSTRSIZE       16      /* step size in enlarging the memory for
-                                       the storage of a string         */
-
-
-!File: trgt_sizes.h
-#define MAXSIZE                8       /* the maximum of the SZ_* constants    */
-
-/* target machine sizes        */
-#define        SZ_CHAR         1
-#define        SZ_SHORT        2
-#define SZ_WORD                4
-#define        SZ_INT          4
-#define        SZ_LONG         4
-#define        SZ_FLOAT        4
-#define        SZ_DOUBLE       8
-#define        SZ_LNGDBL       8       /* for now */
-#define        SZ_POINTER      4
-
-/* target machine alignment requirements       */
-#define        AL_CHAR         1
-#define        AL_SHORT        SZ_SHORT
-#define AL_WORD                SZ_WORD
-#define        AL_INT          SZ_WORD
-#define        AL_LONG         SZ_WORD
-#define        AL_FLOAT        SZ_WORD
-#define        AL_DOUBLE       SZ_WORD
-#define        AL_LNGDBL       SZ_WORD
-#define        AL_POINTER      SZ_WORD
-#define AL_STRUCT      1
-#define AL_UNION       1
-
-
-!File: botch_free.h
-/*#define BOTCH_FREE   1       /* when defined, botch freed memory, as a check */
-
-
-!File: dataflow.h
-#define DATAFLOW       1       /* produce some compile-time xref       */
-
-
-!File: debug.h
-/*#define DEBUG                1       /* perform various self-tests           */
-#define NDEBUG         1       /* disable assertions                   */
-
-
-!File: use_tmp.h
-#define PREPEND_SCOPES 1       /* collect exa, exp, ina and inp commands
-                                       and if USE_TMP is defined let them
-                                       precede the rest of the generated
-                                       compact code    */
-#define USE_TMP                1       /* use C_insertpart, C_endpart mechanism
-                                       to generate EM-code in the order needed
-                                       for the code-generators. If not defined,
-                                       the old-style peephole optimizer is
-                                       needed. */
-
-
-!File: parbufsize.h
-#define PARBUFSIZE     1024
-
-
-!File: textsize.h
-#define ITEXTSIZE      32      /* 1st piece of memory for repl. text   */
-
-
-!File: inputtype.h
-#define INP_READ_IN_ONE        1       /* read input file in one       */
-
-
-!File: nobitfield.h
-/*#define NOBITFIELD   1       /* if NOT defined, implement bitfields  */
-
-
-!File: spec_arith.h
-/* describes internal compiler arithmetics */
-#undef SPECIAL_ARITHMETICS     /* something different from native long */
-
-
-!File: static.h
-#define GSTATIC                        /* for large global "static" arrays */
-
-
-!File: nocross.h
-/*#define NOCROSS              1       /* if NOT defined, cross compiler */
-
-
-!File: regcount.h
-/*#define REGCOUNT             1       /* count occurrences for register messages */
-
-
-!File: dbsymtab.h
-#define DBSYMTAB       1       /* ability to produce symbol table for debugger */
-
-
+!File: lint.h\r
+/*#define      LINT            1       *//* if defined, 'lint' is produced     */\r
+\r
+\r
+!File: pathlength.h\r
+#define PATHLENGTH     1024    /* max. length of path to file          */\r
+\r
+\r
+!File: errout.h\r
+#define        ERROUT          STDERR  /* file pointer for writing messages    */\r
+#define        ERR_SHADOW      5       /* a syntax error overshadows error messages\r
+                                       until ERR_SHADOW symbols have been\r
+                                       accepted without syntax error */\r
+\r
+\r
+!File: idfsize.h\r
+#define        IDFSIZE 64      /* maximum significant length of an identifier  */\r
+\r
+\r
+!File: numsize.h\r
+#define        NUMSIZE 256     /* maximum length of a numeric constant         */\r
+\r
+\r
+!File: nparams.h\r
+#define        NPARAMS 32      /* maximum number of parameters                 */\r
+#define        STDC_NPARAMS 31 /* ANSI limit on number of parameters           */\r
+\r
+\r
+!File: ifdepth.h\r
+#define        IFDEPTH 256     /* maximum number of nested if-constructions    */\r
+\r
+\r
+!File: density.h\r
+#define        DENSITY 3       /* see switch.[ch] for an explanation           */\r
+\r
+\r
+!File: macbuf.h\r
+#define        LAPBUF  128     /* initial size of macro replacement buffer     */\r
+#define ARGBUF 128     /* initial size of macro parameter buffer(s)    */\r
+\r
+\r
+!File: strsize.h\r
+#define ISTRSIZE       32      /* minimum number of bytes allocated for\r
+                                       storing a string                */\r
+#define RSTRSIZE       16      /* step size in enlarging the memory for\r
+                                       the storage of a string         */\r
+\r
+\r
+!File: trgt_sizes.h\r
+#define MAXSIZE                8       /* the maximum of the SZ_* constants    */\r
+\r
+/* target machine sizes        */\r
+#define        SZ_CHAR         1\r
+#define        SZ_SHORT        2\r
+#define SZ_WORD                4\r
+#define        SZ_INT          4\r
+#define        SZ_LONG         4\r
+#define        SZ_FLOAT        4\r
+#define        SZ_DOUBLE       8\r
+#define        SZ_LNGDBL       8       /* for now */\r
+#define        SZ_POINTER      4\r
+\r
+/* target machine alignment requirements       */\r
+#define        AL_CHAR         1\r
+#define        AL_SHORT        SZ_SHORT\r
+#define AL_WORD                SZ_WORD\r
+#define        AL_INT          SZ_WORD\r
+#define        AL_LONG         SZ_WORD\r
+#define        AL_FLOAT        SZ_WORD\r
+#define        AL_DOUBLE       SZ_WORD\r
+#define        AL_LNGDBL       SZ_WORD\r
+#define        AL_POINTER      SZ_WORD\r
+#define AL_STRUCT      1\r
+#define AL_UNION       1\r
+\r
+\r
+!File: botch_free.h\r
+/*#define BOTCH_FREE   1*      *//* when defined, botch freed memory, as a check       */\r
+\r
+\r
+!File: dataflow.h\r
+#define DATAFLOW       1       /* produce some compile-time xref       */\r
+\r
+\r
+!File: debug.h\r
+/*#define DEBUG                1       *//* perform various self-tests         */\r
+#define NDEBUG         1       /* disable assertions                   */\r
+\r
+\r
+!File: use_tmp.h\r
+#define PREPEND_SCOPES 1       /* collect exa, exp, ina and inp commands\r
+                                       and if USE_TMP is defined let them\r
+                                       precede the rest of the generated\r
+                                       compact code    */\r
+#define USE_TMP                1       /* use C_insertpart, C_endpart mechanism\r
+                                       to generate EM-code in the order needed\r
+                                       for the code-generators. If not defined,\r
+                                       the old-style peephole optimizer is\r
+                                       needed. */\r
+\r
+\r
+!File: parbufsize.h\r
+#define PARBUFSIZE     1024\r
+\r
+\r
+!File: textsize.h\r
+#define ITEXTSIZE      32      /* 1st piece of memory for repl. text   */\r
+\r
+\r
+!File: inputtype.h\r
+#define INP_READ_IN_ONE        1       /* read input file in one       */\r
+\r
+\r
+!File: nobitfield.h\r
+/*#define NOBITFIELD   1       *//* if NOT defined, implement bitfields        */\r
+\r
+\r
+!File: spec_arith.h\r
+/* describes internal compiler arithmetics */\r
+#undef SPECIAL_ARITHMETICS     /* something different from native long */\r
+\r
+\r
+!File: static.h\r
+#define GSTATIC                        /* for large global "static" arrays */\r
+\r
+\r
+!File: nocross.h\r
+/*#define NOCROSS              1       *//* if NOT defined, cross compiler */\r
+\r
+\r
+!File: regcount.h\r
+/*#define REGCOUNT             1       *//* count occurrences for register messages */\r
+\r
+\r
+!File: dbsymtab.h\r
+#define DBSYMTAB       1       /* ability to produce symbol table for debugger */\r
+\r
+\r
diff --git a/lang/cem/cemcom.ansi/CMakeLists.txt b/lang/cem/cemcom.ansi/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3777b04
--- /dev/null
@@ -0,0 +1,318 @@
+cmake_minimum_required (VERSION 3.0)
+project(em_cemcom.ansi)
+
+
+##################################
+# Location of built scripts.
+##################################
+set(PROJECT_SCRIPTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../util/scripts)
+
+set(SRC_C
+       align.h
+       arith.c
+       arith.h
+       atw.h
+       blocks.c
+       blocks.h
+       ch3.c
+       ch3.h
+       ch3bin.c
+       ch3bin.h
+       ch3mon.c
+       ch3mon.h
+       class.h
+       code.c
+       conversion.c
+       conversion.h
+       cstoper.c
+       cstoper.h
+       dataflow.c
+       dataflow.h
+       declarator.c
+       declarator.h
+       decspecs.c
+       decspecs.h
+       domacro.c
+       domacro.h
+       dumpidf.c
+       error.c
+       error.h
+       eval.c
+       eval.h
+       expr.c
+       field.c
+       file_info.h
+       fltcstoper.c
+       fltcstoper.h
+       idf.c
+       input.c
+       input.h
+       interface.h
+       idf.c
+       input.c
+       input.h
+       l_class.h
+       l_comment.c
+       l_comment.h
+       l_em.h
+       l_ev_ord.c
+       l_lint.c
+       l_lint.h
+       l_misc.c
+       l_outdef.c
+       l_states.c
+       label.c
+       label.h
+       level.h
+       LLlex.c
+       LLlex.h
+       LLmessage.c
+       main.c
+       mes.h
+       options.c
+       options.h
+       pragma.c
+       pragma.h
+       proto.c
+       sizes.h
+       skip.c
+       skip.h
+       specials.h
+       stab.c
+       stab.h
+       stack.c
+       stb.c
+       struct.c
+       switch.c
+       tokenname.c
+       tokenname.h
+       type.c
+       util.c
+)
+
+set(INCLUDE_DIRS
+ .
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../modules/src/idf
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../modules/src/input
+)
+
+############################################
+# LLgen inputs
+############################################
+
+set(GEN_G
+       ${CMAKE_CURRENT_BINARY_DIR}/tokenfile.g
+)
+
+
+
+set(SRC_G
+ ${CMAKE_CURRENT_SOURCE_DIR}/program.g
+ ${CMAKE_CURRENT_SOURCE_DIR}/declar.g
+ ${CMAKE_CURRENT_SOURCE_DIR}/expression.g
+ ${CMAKE_CURRENT_SOURCE_DIR}/statement.g
+ ${CMAKE_CURRENT_SOURCE_DIR}/ival.g
+)
+
+
+############################################
+# LLgen outputs
+############################################
+
+set(GEN_SRC 
+ ${CMAKE_CURRENT_BINARY_DIR}/program.c 
+ ${CMAKE_CURRENT_BINARY_DIR}/declar.c 
+ ${CMAKE_CURRENT_BINARY_DIR}/expression.c 
+ ${CMAKE_CURRENT_BINARY_DIR}/statement.c
+ ${CMAKE_CURRENT_BINARY_DIR}/ival.c
+ ${CMAKE_CURRENT_BINARY_DIR}/tokenfile.c
+ ${CMAKE_CURRENT_BINARY_DIR}/Lpars.c
+ ${CMAKE_CURRENT_BINARY_DIR}/Lpars.h
+ ${CMAKE_CURRENT_BINARY_DIR}/Lncor.c
+)
+
+
+
+
+
+
+set(GFILES
+ ${GEN_G}
+ ${SRC_G}
+)
+
+
+
+############################################
+# Configuration parameters generated files
+############################################
+
+set(GEN_H_CONFIG
+       ${CMAKE_CURRENT_BINARY_DIR}/parameters.h
+)
+
+set(GEN_OTHERS
+       ${CMAKE_CURRENT_BINARY_DIR}/code.h
+       ${CMAKE_CURRENT_BINARY_DIR}/declar.h
+       ${CMAKE_CURRENT_BINARY_DIR}/def.h       
+       ${CMAKE_CURRENT_BINARY_DIR}/expr.h
+       ${CMAKE_CURRENT_BINARY_DIR}/field.h
+       ${CMAKE_CURRENT_BINARY_DIR}/estack.h
+       ${CMAKE_CURRENT_BINARY_DIR}/util.h
+       ${CMAKE_CURRENT_BINARY_DIR}/proto.h
+       ${CMAKE_CURRENT_BINARY_DIR}/replace.h
+       ${CMAKE_CURRENT_BINARY_DIR}/idf.h
+       ${CMAKE_CURRENT_BINARY_DIR}/macro.h
+       ${CMAKE_CURRENT_BINARY_DIR}/stack.h
+       ${CMAKE_CURRENT_BINARY_DIR}/stmt.h
+       ${CMAKE_CURRENT_BINARY_DIR}/struct.h
+       ${CMAKE_CURRENT_BINARY_DIR}/switch.h
+       ${CMAKE_CURRENT_BINARY_DIR}/type.h
+       ${CMAKE_CURRENT_BINARY_DIR}/l_brace.h
+       ${CMAKE_CURRENT_BINARY_DIR}/l_state.h
+       ${CMAKE_CURRENT_BINARY_DIR}/l_outdef.h
+       ${CMAKE_CURRENT_BINARY_DIR}/next.c
+)
+
+
+
+
+
+
+set(CFILES
+       ${SRC_C}
+       ${GEN_SRC}
+       ${GEN_H_CONFIG}
+       ${GEN_OTHERS}
+       symbol2str.c
+       char.c
+)
+
+set(LLGENOPTIONS
+ -n
+)
+
+###############################################
+# Generate the compile time configuration file 
+###############################################
+add_custom_command(
+    OUTPUT ${GEN_H_CONFIG} BigPars mkparams.sed
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${PROJECT_SCRIPTS_SOURCE_DIR}/mkparams.sed
+                ${CMAKE_CURRENT_BINARY_DIR}/mkparams.sed
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${CMAKE_CURRENT_SOURCE_DIR}/BigPars
+                ${CMAKE_CURRENT_BINARY_DIR}/BigPars                      
+    COMMAND sed -f ${PROJECT_SCRIPTS_SOURCE_DIR}/mkparams.sed ${CMAKE_CURRENT_BINARY_DIR}/BigPars>parameters.h
+    DEPENDS BigPars)
+    
+###############################################
+# Generate other source files
+###############################################     
+
+
+add_custom_command(
+    OUTPUT ${GEN_OTHERS} mkalloc1.sed mkalloc2.sed mknext.sed
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${PROJECT_SCRIPTS_SOURCE_DIR}/mkalloc1.sed
+                ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${PROJECT_SCRIPTS_SOURCE_DIR}/mkalloc2.sed
+                ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${PROJECT_SCRIPTS_SOURCE_DIR}/mknext.sed
+                ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed   
+                
+
+                
+                                                    
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/code.str>code.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/declar.str>declar.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/def.str>def.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/expr.str>expr.h      
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/field.str>field.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/estack.str>estack.h      
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/util.str>util.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/proto.str>proto.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/idf.str>idf.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/macro.str>macro.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/stack.str>stack.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/stmt.str>stmt.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/struct.str>struct.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/switch.str>switch.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/type.str>type.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_brace.str>l_brace.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_state.str>l_state.h
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_outdef.str>l_outdef.h
+    # Create next file from above files
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${CMAKE_CURRENT_SOURCE_DIR}/next.str
+                ${CMAKE_CURRENT_BINARY_DIR}/next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/code.str>>next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/declar.str>>next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/def.str>>next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/expr.str>>next.c  
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/field.str>>next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/estack.str>>next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/util.str>>next.c 
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/proto.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/idf.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/macro.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/stack.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/stmt.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/struct.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/switch.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/type.str>>next.c
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_brace.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_state.str>>next.c      
+    COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_outdef.str>>next.c      
+)
+
+
+
+
+
+add_custom_command(
+       OUTPUT char.c
+       COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../../../util/cmisc/tabgen -f${CMAKE_CURRENT_SOURCE_DIR}/char.tab >char.c
+)
+
+###############################################
+# Generate the LLGen source files 
+# NOTE: Order of input file is important
+############################################### 
+
+add_custom_command(
+    OUTPUT tokenfile.g mktkfile.sed
+    COMMAND ${CMAKE_COMMAND} -E copy
+                ${PROJECT_SCRIPTS_SOURCE_DIR}/mktkfile.sed
+                ${CMAKE_CURRENT_BINARY_DIR}/mktkfile.sed    
+    COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mktkfile.sed ${CMAKE_CURRENT_SOURCE_DIR}/tokenname.c>tokenfile.g
+)
+
+add_custom_command(
+    OUTPUT ${GEN_SRC}
+    COMMAND  ${CMAKE_COMMAND} -E env LLGEN_LIB_DIR=${CMAKE_CURRENT_SOURCE_DIR}/../../../util/LLgen/lib ${CMAKE_CURRENT_BINARY_DIR}/../../../util/LLgen/LLgen ${LLGENOPTIONS} ${GEN_G} ${SRC_G}
+    DEPENDS LLgen tokenfile.g)
+    
+    
+add_custom_command(
+   OUTPUT symbol2str.c
+   COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tokcaseh.in >symbol2str.c 
+   COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/tokcase.sed ${CMAKE_CURRENT_SOURCE_DIR}/tokenname.c >>symbol2str.c 
+   COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tokcasee.in >>symbol2str.c 
+)     
+
+add_executable(${PROJECT_NAME} ${CFILES})
+target_compile_definitions(${PROJECT_NAME} PUBLIC NORCSID=1)
+target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS})
+
+target_link_libraries(${PROJECT_NAME} emheaders emh flt alloc print string system em_data eme em_mes)
+
+install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cemcom.ansi.1 DESTINATION man OPTIONAL)
+
+
index f0f5d5c..d4be034 100644 (file)
@@ -17,6 +17,8 @@
 #include "Lpars.h"
 #include "class.h"
 #include "sizes.h"
+#include "error.h"
+#include "domacro.h"
 #include "specials.h" /* registration of special identifiers */
 
 /* Data about the token yielded */
@@ -41,7 +43,16 @@ extern arith full_mask[];
 extern int lint_skip_comment;
 #endif
 
-int LLlex()
+
+/* Internal function declarations */
+static arith char_constant(char*);
+static char* string_token(char *, int , int *);
+static int quoted(register int);
+static int hex_val(register int);
+static void strflt2tok(char [], struct token *);
+static void strint2tok(char [], struct token *);
+
+int LLlex(void)
 {
        /*      LLlex() plays the role of Lexical Analyzer for the C parser.
            The look-ahead and putting aside of tokens are taken into
@@ -72,10 +83,8 @@ int LLlex()
        return DOT;
 }
 
-char* string_token();
-arith char_constant();
 
-int GetToken(ptok) register struct token* ptok;
+int GetToken(register struct token* ptok)
 {
        /*      GetToken() is the actual token recognizer. It calls the
            control line interpreter if it encounters a "\n{w}*#"
@@ -379,7 +388,7 @@ go_on: /* rescan, the following character has been read     */
        /*NOTREACHED*/
 }
 
-arith char_constant(nm) char* nm;
+static arith char_constant(char* nm)
 {
        register arith val = 0;
        register int ch;
@@ -413,8 +422,7 @@ arith char_constant(nm) char* nm;
        return val;
 }
 
-char* string_token(nm, stop_char, plen) char* nm;
-int* plen;
+static char* string_token(char *nm, int stop_char, int *plen)
 {
        register int ch;
        register int str_size;
@@ -447,7 +455,7 @@ int* plen;
        return str;
 }
 
-int quoted(ch) register int ch;
+static int quoted(register int ch)
 {
        /*      quoted() replaces an escaped character sequence by the
            character meant.
@@ -510,12 +518,12 @@ int quoted(ch) register int ch;
        return ch & 0377;
 }
 
-int hex_val(ch) register int ch;
+static int hex_val(register int ch)
 {
        return is_dig(ch) ? ch - '0' : is_hex(ch) ? (ch - 'a' + 10) & 017 : -1;
 }
 
-int GetChar()
+int GetChar(void)
 {
        /*      The routines GetChar and trigraph parses the trigraph
            sequences and removes occurences of \\\n.
@@ -529,8 +537,7 @@ int GetChar()
 /* strflt2tok only checks the syntax of the floating-point number and
  * selects the right type for the number.
  */
-strflt2tok(fltbuf, ptok) char fltbuf[];
-struct token* ptok;
+static void strflt2tok(char fltbuf[], struct token* ptok)
 {
        register char* cp = fltbuf;
        int malformed = 0;
@@ -584,8 +591,7 @@ struct token* ptok;
        }
 }
 
-strint2tok(intbuf, ptok) char intbuf[];
-struct token* ptok;
+static void strint2tok(char intbuf[], struct token* ptok)
 {
        register char* cp = intbuf;
        int base = 10;
index 678149d..a52f5ed 100644 (file)
@@ -9,6 +9,8 @@
        called a "symbol", but it may have other information associated
        to it.
 */
+#ifndef LLLEX_H_
+#define LLLEX_H_
 
 #include "file_info.h"
 
@@ -56,3 +58,9 @@ extern int err_occurred;      /* "error.c"    */
 #define        ASIDE   aside.tk_symb
 
 #define EOF    (-1)
+
+int GetChar(void);
+int LLlex(void);
+int GetToken(register struct token* ptok);
+
+#endif /* LLLEX_H_ */
index c88c5eb..299d4a8 100644 (file)
 #include       "arith.h"
 #include       "LLlex.h"
 #include       "Lpars.h"
+#include    "error.h"
 
 extern char *symbol2str();
 
-LLmessage(tk)  {
+static void insert_token(int );
+
+void LLmessage(int tk)
+{
        err_occurred = 1;
-       if (tk < 0)     {
+       if (tk < 0)
+       {
                error("end of file expected");
        }
-       else if (tk)    {
+       else if (tk)
+       {
 #ifndef LLNONCORR
                error("%s missing before %s", symbol2str(tk), symbol2str(DOT));
 #endif
                insert_token(tk);
        }
-       else    {
+       else
+       {
 #ifndef LLNONCORR
                error("%s deleted", symbol2str(DOT));
 #else
@@ -34,14 +41,14 @@ LLmessage(tk)       {
        tk_nmb_at_last_syn_err = token_nmb;
 }
 
-insert_token(tk)
-       int tk;
+static void insert_token(int tk)
 {
        aside = dot;
 
        DOT = tk;
 
-       switch (tk)     {
+       switch (tk)
+       {
        /* The operands need some body */
        case IDENTIFIER:
                dot.tk_idf = gen_idf();
index b402e4b..10d1499 100644 (file)
 #include       "Lpars.h"
 #include       "field.h"
 #include       "mes.h"
+#include    "cstoper.h"
+#include    "ch3bin.h"
+#include    "ch3.h"
+#include    "error.h"
+
 
 extern char *symbol2str();
 extern char options[];
 extern arith flt_flt2arith();
 extern label code_string();
 
-void
-arithbalance(e1p, oper, e2p)   /* 3.1.2.5 */
-       register struct expr **e1p, **e2p;
-       int oper;
+/* 3.1.2.5 */
+void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p)
 {
        /*      The expressions *e1p and *e2p are balanced to be operands
                of the arithmetic operator oper.
@@ -171,8 +174,7 @@ arithbalance(e1p, oper, e2p)        /* 3.1.2.5 */
        }
 }
 
-relbalance(e1p, oper, e2p)
-       register struct expr **e1p, **e2p;
+void relbalance(register struct expr **e1p, int oper, register struct expr **e2p)
 {
        /*      The expressions *e1p and *e2p are balanced to be operands
                of the relational operator oper, or the ':'.
@@ -204,9 +206,7 @@ relbalance(e1p, oper, e2p)
                arithbalance(e1p, oper, e2p);
 }
 
-ch3pointer(expp, oper, tp)
-       struct expr **expp;
-       register struct type *tp;
+void ch3pointer(struct expr **expp, int oper, register struct type *tp)
 {
        /*      Checks whether *expp may be compared to tp using oper,
                as described in chapter 3.3.8 and 3.3.9.
@@ -238,9 +238,7 @@ ch3pointer(expp, oper, tp)
 }
 
 int
-any2arith(expp, oper)
-       register struct expr **expp;
-       register int oper;
+any2arith(register struct expr **expp, register int oper)
 {
        /*      Turns any expression into int_type, long_type,
                float_type, double_type or lngdbl_type.
@@ -295,8 +293,7 @@ any2arith(expp, oper)
        return (*expp)->ex_type->tp_fund;
 }
 
-erroneous2int(expp)
-       struct expr **expp;
+void erroneous2int(struct expr **expp)
 {
        /*      the (erroneous) expression *expp is replaced by an
                int expression
@@ -310,11 +307,7 @@ erroneous2int(expp)
        *expp = exp;
 }
 
-struct expr *
-arith2arith(tp, oper, expr)
-       struct type *tp;
-       int oper;
-       register struct expr *expr;
+struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr)
 {
        /*      arith2arith constructs a new expression containing a
                run-time conversion between some arithmetic types.
@@ -328,10 +321,7 @@ arith2arith(tp, oper, expr)
        return new_oper(tp, new, oper, expr);
 }
 
-int
-int2int(expp, tp)
-       struct expr **expp;
-       register struct type *tp;
+int int2int(struct expr **expp, register struct type *tp)
 {
        /*      The expression *expp, which is of some integral type, is
                converted to the integral type tp.
@@ -369,9 +359,7 @@ int2int(expp, tp)
 /* With compile-time constants, we don't set fp_used, since this is done
  * only when necessary in eval.c.
  */
-int2float(expp, tp)
-       register struct expr **expp;
-       struct type *tp;
+void int2float(register struct expr **expp, struct type *tp)
 {
        /*      The expression *expp, which is of some integral type, is
                converted to the floating type tp.
@@ -390,9 +378,7 @@ int2float(expp, tp)
        }
 }
 
-float2int(expp, tp)
-       struct expr **expp;
-       struct type *tp;
+void float2int(struct expr **expp, struct type *tp)
 {
        /*      The expression *expp, which is of some floating type, is
                converted to the integral type tp.
@@ -418,9 +404,7 @@ float2int(expp, tp)
        }
 }
 
-float2float(expp, tp)
-       register struct expr **expp;
-       struct type *tp;
+void float2float(register struct expr **expp, struct type *tp)
 {
        /*      The expression *expp, which is of some floating type, is
                converted to the floating type tp.
@@ -436,8 +420,7 @@ float2float(expp, tp)
        }
 }
 
-array2pointer(exp)
-       register struct expr *exp;
+void array2pointer(register struct expr *exp)
 {
        /*      The expression, which must be an array, is converted
                to a pointer.
@@ -447,8 +430,7 @@ array2pointer(exp)
                                    , (arith)0, NO_PROTO);
 }
 
-function2pointer(exp)
-       register struct expr *exp;
+void function2pointer(register struct expr *exp)
 {
        /*      The expression, which must be a function, is converted
                to a pointer to the function.
@@ -457,8 +439,7 @@ function2pointer(exp)
                                     (arith)0, NO_PROTO);
 }
 
-string2pointer(ex)
-       register struct expr *ex;
+void string2pointer(register struct expr *ex)
 {
        /*      The expression, which must be a string constant, is converted
                to a pointer to the string-containing area.
@@ -472,9 +453,7 @@ string2pointer(ex)
        ex->VL_VALUE = (arith)0;
 }
 
-opnd2integral(expp, oper)
-       register struct expr **expp;
-       int oper;
+void opnd2integral(register struct expr **expp, int oper)
 {
        register int fund = (*expp)->ex_type->tp_fund;
 
@@ -486,9 +465,7 @@ opnd2integral(expp, oper)
        }
 }
 
-opnd2logical(expp, oper)
-       register struct expr **expp;
-       int oper;
+void opnd2logical(register struct expr **expp, int oper)
 {
        int fund = (*expp)->ex_type->tp_fund;
 
@@ -525,8 +502,7 @@ opnd2logical(expp, oper)
 }
 
 void
-opnd2test(expp, oper)
-       register struct expr **expp;
+opnd2test(register struct expr **expp, int oper)
 {
        opnd2logical(expp, oper);
        if ((*expp)->ex_class == Oper) {
@@ -550,9 +526,7 @@ opnd2test(expp, oper)
        ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT));
 }
 
-void
-any2opnd(expp, oper)
-       register struct expr **expp;
+void any2opnd(register struct expr **expp, int oper)
 {
        if (!*expp)
                return;
@@ -584,8 +558,7 @@ any2opnd(expp, oper)
        }
 }
 
-any2parameter(expp)
-       register struct expr **expp;
+void any2parameter(register struct expr **expp)
 {
        /*      To handle default argument promotions
        */
@@ -598,8 +571,7 @@ any2parameter(expp)
 }
 
 #ifndef NOBITFIELD
-field2arith(expp)
-       register struct expr **expp;
+void field2arith(register struct expr **expp)
 {
        /*      The expression to extract the bitfield value from the
                memory word is put in the tree.
@@ -630,8 +602,7 @@ field2arith(expp)
 /*     switch_sign_fp() negates the given floating constant expression,
  *     and frees the string representing the old value.
  */
-switch_sign_fp(expr)
-       register struct expr *expr;
+void switch_sign_fp(register struct expr *expr)
 {
        flt_umin(&(expr->FL_ARITH));
 }
index 4bb4034..65b0003 100644 (file)
        to save storage on small machines, SPECIAL_ARITHMETICS will
        be handy.
 */
+#ifndef ARITH_H_
+#define ARITH_H_
 
 #include       "parameters.h"
 
 #ifndef        SPECIAL_ARITHMETICS
 
-#include <em_arith.h>          /* obtain definition of "arith" */
+#include    <em_arith.h>               /* obtain definition of "arith" */
+#include       <flt_arith.h>
 
 #else  /* SPECIAL_ARITHMETICS */
 
 
 #endif /* SPECIAL_ARITHMETICS */
 
+struct expr;
+struct type;
+
 #define        arith_size      (sizeof(arith))
 #define        arith_sign      ((arith) 1 << (arith_size * 8 - 1))
 #define        max_arith       (~arith_sign)
+
+void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p);
+void relbalance(register struct expr **e1p, int oper, register struct expr **e2p);
+void ch3pointer(struct expr **expp, int oper, register struct type *tp);
+int any2arith(register struct expr **expp, register int oper);
+void erroneous2int(struct expr **expp);
+struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr);
+int int2int(struct expr **expp, register struct type *tp);
+void int2float(register struct expr **expp, struct type *tp);
+void float2int(struct expr **expp, struct type *tp);
+void float2float(register struct expr **expp, struct type *tp);
+void array2pointer(register struct expr *exp);
+void function2pointer(register struct expr *exp);
+void string2pointer(register struct expr *ex);
+void opnd2integral(register struct expr **expp, int oper);
+void opnd2logical(register struct expr **expp, int oper);
+void opnd2test(register struct expr **expp, int oper);
+void any2opnd(register struct expr **expp, int oper);
+void any2parameter(register struct expr **expp);
+void field2arith(register struct expr **expp);
+void switch_sign_fp(register struct expr *expr);
+
+#endif /* ARITH_H_ */
index 6d75a36..d4df8b7 100644 (file)
 #include "label.h"
 #include "stack.h"
 #include "Lpars.h"
-extern arith NewLocal();
+#include "blocks.h"
+#include "macro.h"
+#include "util.h"
+
 #define LocalPtrVar()  NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
 #define LocalIntVar()  NewLocal(int_size, int_align, reg_any, REGISTER)
 #endif /* STB */
@@ -52,9 +55,7 @@ extern arith NewLocal();
        while we need a loop to store the stack block into a memory object.
 */
 
-suitable_sz(sz, al)
-       arith sz;
-       int al;
+int suitable_sz(arith sz, int al)
 {
        return  ((int)sz % (int)word_size == 0 && al % word_align == 0) ||
                (
@@ -64,9 +65,7 @@ suitable_sz(sz, al)
                );
 }
 
-store_block(sz, al)
-       arith sz;
-       int al;
+void store_block(arith sz, int al)
 {
        if (suitable_sz(sz, al))
                C_sti(sz);
@@ -102,9 +101,7 @@ store_block(sz, al)
        }
 }
 
-load_block(sz, al)
-       arith sz;
-       int al;
+void load_block(arith sz, int al)
 {
 
        if (suitable_sz(sz, al))
@@ -138,9 +135,7 @@ load_block(sz, al)
        }
 }
 
-copy_block(sz, al)
-       arith sz;
-       int al;
+void copy_block(arith sz, int al)
 {
 
        if (suitable_sz(sz, al))
@@ -167,8 +162,7 @@ copy_block(sz, al)
 }
 
 #ifndef STB
-copy_loop(sz, src, dst)
-       arith sz, src, dst;
+void copy_loop(arith sz, arith src, arith dst)
 {
        /* generate inline byte-copy loop */
        label l_cont = text_label(), l_stop = text_label();
diff --git a/lang/cem/cemcom.ansi/blocks.h b/lang/cem/cemcom.ansi/blocks.h
new file mode 100644 (file)
index 0000000..45f18d4
--- /dev/null
@@ -0,0 +1,20 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory,
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *
+ */
+#ifndef BLOCKS_H_
+#define BLOCKS_H_
+
+#include "parameters.h"
+#include "arith.h"
+
+int suitable_sz(arith sz, int al);
+void store_block(arith sz, int al);
+void load_block(arith sz, int al);
+void copy_block(arith sz, int al);
+void copy_loop(arith sz, arith src, arith dst);
+
+#endif /* BLOCKS_H_ */
index 5354269..3132ccb 100644 (file)
@@ -9,6 +9,7 @@
 #include       "parameters.h"
 #include       <flt_arith.h>
 #include       "arith.h"
+#include    "ch3.h"
 #include    "idf.h"
 #include       "proto.h"
 #include       "type.h"
 #include       "expr.h"
 #include       "def.h"
 #include       "Lpars.h"
+#include    "error.h"
+#include    "ch3bin.h"
 #include       "file_info.h"
 
 extern char options[];
 extern char *symbol2str();
 extern struct type *qualifier_type();
 
-void ch3cast();
+
 
 /*     Most expression-handling routines have a pointer to a
        (struct type *) as first parameter. The object under the pointer
        gets updated in the process.
 */
 
-void
-ch3sel(expp, oper, idf)
-       struct expr **expp;
-       struct idf *idf;
+void ch3sel(struct expr **expp, int oper, struct idf *idf)
 {
        /*      The selector idf is applied to *expp; oper may be '.' or
                ARROW.
@@ -163,8 +163,7 @@ ch3sel(expp, oper, idf)
        *expp = exp;
 }
 
-ch3incr(expp, oper)
-       struct expr **expp;
+void ch3incr(struct expr **expp, int oper)
 {
        /*      The monadic prefix/postfix incr/decr operator oper is
                applied to *expp.
@@ -172,10 +171,7 @@ ch3incr(expp, oper)
        ch3asgn(expp, oper, intexpr((arith)1, INT));
 }
 
-void
-ch3cast(expp, oper, tp)
-       register struct expr **expp;
-       register struct type *tp;
+void ch3cast(register struct expr **expp, int oper, register struct type *tp)
 {
        /*      The expression *expp is cast to type tp; the cast is
                caused by the operator oper.  If the cast has
@@ -412,9 +408,7 @@ ch3cast(expp, oper, tp)
 
 /*     Determine whether two types are equal.
 */
-equal_type(tp, otp, qual_lev, diag)
-       register struct type *tp, *otp;
-       int qual_lev, diag;
+int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag)
 {
         if (tp == otp)
                return 1;
@@ -475,8 +469,7 @@ equal_type(tp, otp, qual_lev, diag)
        }
 }
 
-check_pseudoproto(pl, opl, diag)
-       register struct proto *pl, *opl;
+int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag)
 {
        int retval = 1;
 
@@ -519,9 +512,7 @@ check_pseudoproto(pl, opl, diag)
        return retval;
 }
 
-legal_mixture(tp, otp, diag)
-       struct type *tp, *otp;
-       int diag;
+int legal_mixture(struct type *tp, struct type *otp, int diag)
 {
        struct proto *pl = tp->tp_proto, *opl = otp->tp_proto;
        int retval = 1;
@@ -562,9 +553,7 @@ legal_mixture(tp, otp, diag)
        return retval;
 }
 
-equal_proto(pl, opl, diag)
-       register struct proto *pl, *opl;
-       int diag;
+int equal_proto(register struct proto *pl, register struct proto *opl, int diag)
 {
        if (pl == opl)
                return 1;
@@ -586,9 +575,7 @@ equal_proto(pl, opl, diag)
 }
 
 /* check if a type has a consqualified member */
-recurqual(tp, qual)
-struct type *tp;
-int qual;
+int recurqual(struct type *tp, int qual)
 {
        register struct sdef *sdf;
 
@@ -610,9 +597,7 @@ int qual;
        return 0;
 }
 
-ch3asgn(expp, oper, expr)
-       struct expr **expp;
-       struct expr *expr;
+void ch3asgn(struct expr **expp, int oper, struct expr *expr)
 {
        /*      The assignment operators.
                "f op= e" should be interpreted as
@@ -687,9 +672,7 @@ ch3asgn(expp, oper, expr)
 
 /*     Some interesting (?) questions answered.
 */
-int
-is_integral_type(tp)
-       register struct type *tp;
+int is_integral_type(register struct type *tp)
 {
        switch (tp->tp_fund)    {
        case CHAR:
@@ -707,9 +690,7 @@ is_integral_type(tp)
        }
 }
 
-int
-is_arith_type(tp)
-       register struct type *tp;
+int is_arith_type(register struct type *tp)
 {
        switch (tp->tp_fund)    {
        case CHAR:
diff --git a/lang/cem/cemcom.ansi/ch3.h b/lang/cem/cemcom.ansi/ch3.h
new file mode 100644 (file)
index 0000000..a8970f7
--- /dev/null
@@ -0,0 +1,29 @@
+/*  Copyright (c) 2019 ACK Project. See the file Copyright in
+ *  the project root directory for more information.
+ *
+ *  Created on: 2019-02-06
+ *
+ */
+#ifndef CH3_H_
+#define CH3_H_
+
+/* Structure forward declarations. */
+struct expr;
+struct type;
+struct proto;
+struct idf;
+
+
+void ch3sel(struct expr **expp, int oper, struct idf *idf);
+void ch3incr(struct expr **expp, int oper);
+void ch3cast(register struct expr **expp, int oper, register struct type *tp);
+int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag);
+int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag);
+int legal_mixture(struct type *tp, struct type *otp, int diag);
+int equal_proto(register struct proto *pl, register struct proto *opl, int diag);
+int recurqual(struct type *tp, int qual);
+void ch3asgn(struct expr **expp, int oper, struct expr *expr);
+int is_integral_type(register struct type *tp);
+int is_arith_type(register struct type *tp);
+
+#endif /* CH3_H_ */
index ba75c11..e692e98 100644 (file)
 #include       "expr.h"
 #include       "Lpars.h"
 #include       "sizes.h"
+#include    "ch3bin.h"
+#include    "ch3mon.h"
+#include    "ch3.h"
+#include    "error.h"
+#include    "cstoper.h"
+#include    "fltcstoper.h"
 
 extern char options[];
 extern char *symbol2str();
@@ -34,10 +40,7 @@ void pntminuspnt();
 #define commutative_binop(expp, oper, expr)    mk_binop(expp, oper, expr, 1)
 #define non_commutative_relop(expp, oper, expr)        mk_binop(expp, oper, expr, 1)
 
-void
-ch3bin(expp, oper, expr)
-       register struct expr **expp;
-       struct expr *expr;
+void ch3bin(register struct expr **expp, int oper, struct expr *expr)
 {
        /*      apply binary operator oper between *expp and expr.
                NB: don't swap operands if op is one of the op= operators!!!
@@ -295,9 +298,7 @@ ch3bin(expp, oper, expr)
        }
 }
 
-void
-pntminuspnt(expp, oper, expr)
-       register struct expr **expp, *expr;
+void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr)
 {
        /*      Subtracting two pointers is so complicated it merits a
                routine of its own.
@@ -328,8 +329,7 @@ pntminuspnt(expp, oper, expr)
  * when the arguments are switched.  This is special for some relational
  * operators.
  */
-int
-arg_switched(oper)
+int arg_switched(int oper)
 {
        switch (oper) {
        case '<':       return '>';
@@ -340,9 +340,7 @@ arg_switched(oper)
        }
 }
 
-mk_binop(expp, oper, expr, commutative)
-       struct expr **expp;
-       register struct expr *expr;
+void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative)
 {
        /*      Constructs in *expp the operation indicated by the operands.
                "commutative" indicates whether "oper" is a commutative
@@ -366,8 +364,7 @@ mk_binop(expp, oper, expr, commutative)
        }
 }
 
-pointer_arithmetic(expp1, oper, expp2)
-       register struct expr **expp1, **expp2;
+void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2)
 {
        int typ;
        /*      prepares the integral expression expp2 in order to
@@ -387,8 +384,7 @@ pointer_arithmetic(expp1, oper, expp2)
        );
 }
 
-pointer_binary(expp, oper, expr)
-       register struct expr **expp, *expr;
+void pointer_binary(register struct expr **expp, int oper, register struct expr *expr)
 {
        /*      constructs the pointer arithmetic expression out of
                a pointer expression, a binary operator and an integral
diff --git a/lang/cem/cemcom.ansi/ch3bin.h b/lang/cem/cemcom.ansi/ch3bin.h
new file mode 100644 (file)
index 0000000..bc6ea2d
--- /dev/null
@@ -0,0 +1,21 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory,
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *
+ */
+#ifndef CH3BIN_H_
+#define CH3BIN_H_
+
+struct expr;
+
+void ch3bin(register struct expr **expp, int oper, struct expr *expr);
+void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr);
+int arg_switched(int oper);
+void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative);
+void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2);
+void pointer_binary(register struct expr **expp, int oper, register struct expr *expr);
+
+
+#endif /* CH3BIN_H_ */
index 8cffc2c..a84a141 100644 (file)
@@ -5,6 +5,7 @@
 /* $Id$ */
 /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
 
+#include    "ch3mon.h"
 #include       "parameters.h"
 #include       <alloc.h>
 #include       "Lpars.h"
 #include       "expr.h"
 #include       "def.h"
 #include       "sizes.h"
+#include    "ch3.h"
+#include    "error.h"
+
 
 extern char options[];
 extern arith full_mask[/*MAXSIZE + 1*/];       /* cstoper.c */
 char *symbol2str();
 
-ch3mon(oper, expp)
-       register struct expr **expp;
+void ch3mon(int oper, register struct expr **expp)
 {
        /*      The monadic prefix operator oper is applied to *expp.
        */
diff --git a/lang/cem/cemcom.ansi/ch3mon.h b/lang/cem/cemcom.ansi/ch3mon.h
new file mode 100644 (file)
index 0000000..354738c
--- /dev/null
@@ -0,0 +1,22 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef CH3MON_H_
+#define CH3MON_H_
+
+struct expr;
+
+void ch3mon(int oper, register struct expr **expp);
+void ch3bin(register struct expr **expp, int oper, struct expr *expr);
+void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr);
+int arg_switched(int oper);
+void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative);
+void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2);
+void pointer_binary(register struct expr **expp, int oper, register struct expr *expr);
+
+
+#endif /* CH3MON_H_ */
index a6a898a..d507000 100644 (file)
 #include       "expr.h"
 #include       "sizes.h"
 #include       "stack.h"
+#include    "blocks.h"
+#include    "struct.h"
 #include       "level.h"
+#include    "dataflow.h"
+#include    "conversion.h"
 #include       "decspecs.h"
 #include       "declar.h"
 #include       "Lpars.h"
 #include       "specials.h"
 #include       "atw.h"
+#include    "ch3.h"
+#include    "eval.h"
+#include    "stab.h"
 #include       "LLlex.h"
 #include       "align.h"
+#include    "util.h"
+#include    "error.h"
+
 #ifdef LINT
 #include       "l_lint.h"
 #endif /* LINT */
@@ -46,7 +56,10 @@ label lab_count = 1;
 label datlab_count = 1;
 
 int fp_used;
-extern arith NewLocal();       /* util.c       */
+
+extern void str_cst(register char *, register int, int);  /* ival.c */
+
+
 
 /* global function info */
 char *func_name;
@@ -67,8 +80,7 @@ extern char *source;
 void loc_init();
 
 #ifndef        LINT
-init_code(dst_file)
-       char *dst_file;
+void init_code(char *dst_file)
 {
        /*      init_code() initialises the output file on which the
                compact EM code is written
@@ -105,10 +117,7 @@ init_code(dst_file)
 
 struct string_cst *str_list = 0;
 
-label
-code_string(val, len)
-       char *val;
-       int len;
+label code_string(char* val, int len)
 {
        register struct string_cst *sc = new_string_cst();
        label dlb = data_label();
@@ -122,8 +131,7 @@ code_string(val, len)
        return dlb;
 }
 
-def_strings(sc)
-       register struct string_cst *sc;
+void def_strings(register struct string_cst *sc)
 {
        while (sc) {
                struct string_cst *sc1 = sc;
@@ -137,7 +145,7 @@ def_strings(sc)
 }
 
 /* flush_strings() is called from program.g after each external definition */
-flush_strings() {
+void flush_strings(void) {
        if (str_list) {
                def_strings(str_list);
                str_list = 0;
@@ -145,7 +153,7 @@ flush_strings() {
 }
 
 #ifndef        LINT
-end_code()
+void end_code(void)
 {
        /*      end_code() performs the actions to be taken when closing
                the output stream.
@@ -160,7 +168,7 @@ end_code()
 #endif /* LINT */
 
 #ifdef PREPEND_SCOPES
-prepend_scopes()
+void prepend_scopes(void)
 {
        /*      prepend_scopes() runs down the list of global idf's
                and generates those exa's, exp's, ina's and inp's
@@ -185,9 +193,7 @@ prepend_scopes()
 }
 #endif /* PREPEND_SCOPES */
 
-code_scope(text, def)
-       char *text;
-       register struct def *def;
+void code_scope(char* text, register struct def *def)
 {
        /*      generates code for one name, text, of the storage class
                as given by def, if meaningful.
@@ -218,9 +224,7 @@ static int struct_return;
 static char *last_fn_given = (char *)0;
 static label file_name_label;
 
-begin_proc(ds, idf)            /* to be called when entering a procedure */
-       struct decspecs *ds;
-       struct idf *idf;
+void begin_proc(struct decspecs *ds, struct idf *idf)          /* to be called when entering a procedure */
 {
        /*      begin_proc() is called at the entrance of a new function
                and performs the necessary code generation:
@@ -317,8 +321,7 @@ begin_proc(ds, idf)         /* to be called when entering a procedure */
 #endif
 }
 
-end_proc(fbytes)
-       arith fbytes;
+void end_proc(arith fbytes)
 {
        /*      end_proc() deals with the code to be generated at the end of
                a function, as there is:
@@ -388,7 +391,7 @@ end_proc(fbytes)
        options['n'] = optionsn;
 }
 
-do_return()
+void do_return(void)
 {
        /*      do_return handles the case of a return without expression.
                This version branches to the return label, which is
@@ -401,8 +404,7 @@ do_return()
        C_bra(return2_label);
 }
 
-do_return_expr(expr)
-       struct expr *expr;
+void do_return_expr(struct expr *expr)
 {
        /*      do_return_expr() generates the expression and the jump for
                a return statement with an expression.
@@ -418,11 +420,11 @@ do_return_expr(expr)
 }
 
 void
-code_declaration(idf, expr, lvl, sc)
-       register struct idf *idf;       /* idf to be declared   */
-       struct expr *expr;      /* initialisation; NULL if absent       */
-       int lvl;                /* declaration level    */
-       int sc;                 /* storage class, as in the declaration */
+code_declaration(
+       register struct idf *idf,       /* idf to be declared   */
+       struct expr *expr,      /* initialisation; NULL if absent       */
+       int lvl,                /* declaration level    */
+       int sc)         /* storage class, as in the declaration */
 {
        /*      code_declaration() does the actual declaration of the
                variable indicated by "idf" on declaration level "lvl".
@@ -530,10 +532,7 @@ code_declaration(idf, expr, lvl, sc)
        }
 }
 
-void
-loc_init(expr, id)
-       struct expr *expr;
-       struct idf *id;
+void loc_init(struct expr *expr, struct idf *id)
 {
        /*      loc_init() generates code for the assignment of
                expression expr to the local variable described by id.
@@ -609,8 +608,7 @@ loc_init(expr, id)
        }
 }
 
-bss(idf)
-       register struct idf *idf;
+void bss(register struct idf *idf)
 {
        /*      bss() allocates bss space for the global idf.
        */
@@ -640,9 +638,7 @@ bss(idf)
        }
 }
 
-formal_cvt(hasproto,df)
-       int hasproto;
-       register struct def *df;
+void formal_cvt(int hasproto, register struct def *df)
 {
        /*      formal_cvt() converts a formal parameter of type char or
                short from int to that type. It also converts a formal
@@ -672,9 +668,7 @@ formal_cvt(hasproto,df)
 #ifdef LINT
 /*ARGSUSED*/
 #endif /* LINT */
-code_expr(expr, val, code, tlbl, flbl)
-       struct expr *expr;
-       label tlbl, flbl;
+void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl)
 {
        /*      code_expr() is the parser's interface to the expression code
                generator.  If line number trace is wanted, it generates a
@@ -707,7 +701,7 @@ static struct stmt_block *stmt_stack;       /* top of statement stack */
        which are the only ones that are stacked, only the top of
        the stack is interesting.
 */
-code_break()
+void code_break(void)
 {
        register struct stmt_block *stmt_block = stmt_stack;
 
@@ -726,7 +720,7 @@ code_break()
        innermost statement in which continue has a meaning.
 */
 void
-code_continue()
+code_continue(void)
 {
        register struct stmt_block *stmt_block = stmt_stack;
 
@@ -743,8 +737,7 @@ code_continue()
        error("continue not inside for, while or do");
 }
 
-stack_stmt(break_label, cont_label)
-       label break_label, cont_label;
+void stack_stmt(label break_label, label cont_label)
 {
        register struct stmt_block *stmt_block = new_stmt_block();
 
@@ -754,7 +747,7 @@ stack_stmt(break_label, cont_label)
        stmt_stack = stmt_block;
 }
 
-unstack_stmt()
+void unstack_stmt(void)
 {
        /*      unstack_stmt() unstacks the data of a statement
                which may contain break or continue
@@ -766,8 +759,7 @@ unstack_stmt()
 
 static label prc_name;
 
-prc_entry(name)
-       char *name;
+void prc_entry(char* name)
 {
        if (options['p']) {
                C_df_dlb(prc_name = data_label());
@@ -778,7 +770,7 @@ prc_entry(name)
        }
 }
 
-prc_exit()
+void prc_exit(void)
 {
        if (options['p']) {
                C_lae_dlb(prc_name, (arith) 0);
@@ -788,9 +780,7 @@ prc_exit()
 }
 
 #ifdef DBSYMTAB
-db_line(file, line)
-       char            *file;
-       unsigned int    line;
+void db_line(char *file, unsigned int line)
 {
        static unsigned oldline;
        static char     *oldfile;
index b818bbe..b377039 100644 (file)
@@ -2,9 +2,15 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef CODE_H_
+#define CODE_H_
 /* $Id$ */
 /*     C O D E - G E N E R A T O R   D E F I N I T I O N S     */
 
+#include "arith.h"
+#include "label.h"
+
+
 struct string_cst      {       /* storing string constants */
        struct string_cst *next;
        char *sc_value;
@@ -20,3 +26,44 @@ extern struct string_cst *str_list;
 #define        RVAL    1
 #define        FALSE   0
 #define        TRUE    1
+
+
+#ifndef        LINT
+void init_code(char *dst_file);
+void end_code(void);
+#endif
+
+struct expr;
+struct def;
+struct idf;
+
+label code_string(char* val, int len);
+void def_strings(register struct string_cst *sc);
+void flush_strings(void);
+void code_scope(char* text, register struct def *def);
+void begin_proc(struct decspecs *ds, struct idf *idf);
+void end_proc(arith fbytes);
+void do_return(void);
+void do_return_expr(struct expr *expr);
+void code_declaration(register struct idf *idf, struct expr *expr, 
+               int lvl, int sc);
+void loc_init(struct expr *expr, struct idf *id);
+void bss(register struct idf *idf);
+void formal_cvt(int hasproto, register struct def *df);
+void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl);
+void code_break(void);
+void code_continue(void);
+void stack_stmt(label break_label, label cont_label);
+void unstack_stmt(void);
+void prc_entry(char* name);
+void prc_exit(void);
+
+#ifdef PREPEND_SCOPES
+void prepend_scopes(void);
+#endif
+
+#ifdef DBSYMTAB
+void db_line(char *file, unsigned int line);
+#endif
+
+#endif
index 485d8b8..60d4c45 100644 (file)
@@ -8,11 +8,15 @@
 #include       "parameters.h"
 #ifndef        LINT
 
+#include    "conversion.h"
 #include       <em.h>
+#include    "interface.h"
 #include       "arith.h"
 #include       "type.h"
 #include       "sizes.h"
 #include       "Lpars.h"
+#include    "error.h"
+
 
 #define        T_SIGNED                1
 #define        T_UNSIGNED              2
                C??
 */
 
-static int convtype();
+static int convtype(register struct type *);
 
-conversion(from_type, to_type)
-       register struct type *from_type, *to_type;
+void conversion(register struct type *from_type, register struct type *to_type)
 {
        register arith from_size = from_type->tp_size;
        register arith to_size = to_type->tp_size;
@@ -126,9 +129,7 @@ conversion(from_type, to_type)
 /*     convtype() returns in which category a given type falls:
        signed, unsigned or floating
 */
-static int
-convtype(tp)
-       register struct type *tp;
+static int convtype(register struct type *tp)
 {
        switch (tp->tp_fund)    {
        case CHAR:
diff --git a/lang/cem/cemcom.ansi/conversion.h b/lang/cem/cemcom.ansi/conversion.h
new file mode 100644 (file)
index 0000000..25756a9
--- /dev/null
@@ -0,0 +1,15 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef CONVERSION_H_
+#define CONVERSION_H_
+
+struct type;
+
+void conversion(register struct type *from_type, register struct type *to_type);
+
+#endif /* CONVERSION_H_ */
index a63103b..774e356 100644 (file)
@@ -6,6 +6,7 @@
 /*     C O N S T A N T   E X P R E S S I O N   H A N D L I N G         */
 
 #include       <assert.h>
+#include    "cstoper.h"
 #include    "parameters.h"
 #include       <flt_arith.h>
 #include       "arith.h"
@@ -14,6 +15,7 @@
 #include       "expr.h"
 #include       "sizes.h"
 #include       "Lpars.h"
+#include    "error.h"
 
 /* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
 arith full_mask[MAXSIZE + 1];
@@ -23,8 +25,7 @@ arith max_unsigned;   /* maximum unsigned on target machine   */
 #endif /* NOCROSS */
 extern int ResultKnown;
 
-cstbin(expp, oper, expr)
-       register struct expr **expp, *expr;
+void cstbin(register struct expr **expp, int oper, register struct expr *expr)
 {
        /*      The operation oper is performed on the constant
                expressions *expp(ld) and expr(ct), and the result restored in
@@ -134,8 +135,7 @@ cstbin(expp, oper, expr)
        free_expression(expr);
 }
 
-cut_size(expr)
-       register struct expr *expr;
+void cut_size(register struct expr *expr)
 {
        /*      The constant value of the expression expr is made to
                conform to the size of the type of the expression.
@@ -170,7 +170,7 @@ cut_size(expr)
        expr->VL_VALUE = o1;
 }
 
-init_cst()
+void init_cst(void)
 {
        register int i = 0;
        register arith bt = (arith)0;
diff --git a/lang/cem/cemcom.ansi/cstoper.h b/lang/cem/cemcom.ansi/cstoper.h
new file mode 100644 (file)
index 0000000..4d0d971
--- /dev/null
@@ -0,0 +1,17 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef CSTOPER_H_
+#define CSTOPER_H_
+
+struct expr;
+
+void cstbin(register struct expr **expp, int oper, register struct expr *expr);
+void cut_size(register struct expr *expr);
+void init_cst(void);
+
+#endif /* CSTOPER_H_ */
index 6a3fbcf..cdd7781 100644 (file)
 */
 
 #include       "parameters.h"  /* UF */
+#include    "dataflow.h"
+#include    "print.h"
 
 #ifdef DATAFLOW
 char *CurrentFunction = 0;
 int NumberOfCalls;
 
-DfaStartFunction(nm)
-       char *nm;
+void DfaStartFunction(char* nm)
 {
        CurrentFunction = nm;
        NumberOfCalls = 0;
 }
 
-DfaEndFunction()
+void DfaEndFunction(void)
 {
        if (NumberOfCalls == 0)
                print("DFA: %s: --none--\n", CurrentFunction);
 }
 
-DfaCallFunction(s)
-       char *s;
+void DfaCallFunction(char* s)
 {
        print("DFA: %s: %s\n", CurrentFunction, s);
        ++NumberOfCalls;
diff --git a/lang/cem/cemcom.ansi/dataflow.h b/lang/cem/cemcom.ansi/dataflow.h
new file mode 100644 (file)
index 0000000..e353b9a
--- /dev/null
@@ -0,0 +1,19 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef DATAFLOW_H_
+#define DATAFLOW_H_
+
+#ifdef DATAFLOW
+
+void DfaStartFunction(char* nm);
+void DfaEndFunction(void);
+void DfaCallFunction(char* s);
+
+#endif
+
+#endif /* DATAFLOW_H_ */
index d6119f5..92adefb 100644 (file)
-/*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
-/* $Id$ */
-/*     DECLARATION SYNTAX PARSER       */
-
-{
-#include       "parameters.h"
-#include       <alloc.h>
-#include       <flt_arith.h>
-#include    "idf.h"
-#include       "arith.h"
-#include       "LLlex.h"
-#include       "label.h"
-#include       "code.h"
-#include       "type.h"
-#include       "proto.h"
-#include       "struct.h"
-#include       "field.h"
-#include       "decspecs.h"
-#include       "def.h"
-#include       "declar.h"
-#include       "label.h"
-#include       "expr.h"
-#include       "sizes.h"
-#include       "level.h"
-#ifdef LINT
-#include       "l_lint.h"
-#endif /* LINT */
-
-extern char    options[];
-}
-
-/* 3.5 */
-declaration
-       {struct decspecs Ds;}
-:
-       {Ds = null_decspecs;}
-       decl_specifiers(&Ds)
-       init_declarator_list(&Ds)?
-       ';'
-;
-
-/*     A `decl_specifiers' describes a sequence of a storage_class_specifier,
-       an unsigned_specifier, a size_specifier and a simple type_specifier,
-       which may occur in arbitrary order and each of which may be absent;
-       at least one of them must be present, however, since the totally
-       empty case has already be dealt with in `external_definition'.
-       This means that something like:
-               unsigned extern int short xx;
-       is perfectly legal C.
-       
-       On top of that, multiple occurrences of storage_class_specifiers,
-       unsigned_specifiers and size_specifiers are errors, but a second
-       type_specifier should end the decl_specifiers and be treated as
-       the name to be declared.
-       Such a language is not easily expressed in a grammar; enumeration
-       of the permutations is unattractive. We solve the problem by
-       having a regular grammar for the "soft" items, handling the single
-       occurrence of the type_specifier in the grammar (we have no choice),
-       collecting all data in a `struct decspecs' and turning that data
-       structure into what we want.
-       
-       The existence of declarations like
-               short typedef yepp;
-       makes all hope of writing a specific grammar for typedefs illusory.
-*/
-/*      Accept a single declaration specifier.  Then accept zero or more
-       declaration specifiers.  There can be a conflict on both
-       TYPE_IDENTIFIER and IDENTIFIER.
-       The following rule is used:
-       When we see a TYPE_IDENTIFIER, we accept it if no type-specifier was
-       given, and it is not directly followed by an identifier.  If a
-       type-specifier was given, it is taken as the identifier being
-       declared.  If it is followed by an identifier, we assume that an
-       error has been  made, (e.g. unsigned typedeffed_int x;) and that
-       this will be detected later on.
-       When we see an IDENTIFIER, directly followed by another IDENTIFIER,
-       we assume that a typing mistake has been made, and we accept it as
-       an erroneous type-identifier.
-*/
-
-decl_specifiers        /* non-empty */ (register struct decspecs *ds;)
-       /*      Reads a non-empty decl_specifiers and fills the struct
-               decspecs *ds.
-       */
-:
-       single_decl_specifier(ds)
-       [ %while(  (DOT==TYPE_IDENTIFIER
-                       && ds->ds_size == 0
-                       && ds->ds_unsigned == 0
-                       && ds->ds_type == (struct type *)0)
-                   || AHEAD == IDENTIFIER)     /* always an error */
-               single_decl_specifier(ds)
-       ]*
-       {do_decspecs(ds);}
-;
-
-single_decl_specifier /* non_empty */ (register struct decspecs *ds;)
-:
-       [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
-       {       if (ds->ds_sc_given)
-                       error("repeated storage class specifier");
-               ds->ds_sc_given = 1;
-               ds->ds_sc = DOT;
-       }
-|
-       VOLATILE
-       {       if (ds->ds_typequal & TQ_VOLATILE)
-                       error("repeated type qualifier");
-               ds->ds_typequal |= TQ_VOLATILE;
-       }
-|
-       CONST
-       {       if (ds->ds_typequal & TQ_CONST)
-                       error("repeated type qualifier");
-               ds->ds_typequal |= TQ_CONST;
-       }
-|
-       [ SHORT | LONG ]
-       {       if (ds->ds_size)
-                       error("repeated size specifier");
-               ds->ds_size = DOT;
-       }
-|
-       [ SIGNED | UNSIGNED ]
-       {       if (ds->ds_unsigned != 0)
-                       error("repeated sign specifier");
-               ds->ds_unsigned = DOT;
-       }
-|
-       [ VOID | CHAR | INT | FLOAT | DOUBLE ]
-       {
-               idf2type(dot.tk_idf, &ds->ds_type);
-               ds->ds_typedef = 0;
-       }
-|
-       %default TYPE_IDENTIFIER
-       {
-               idf2type(dot.tk_idf, &ds->ds_type);
-               ds->ds_typedef = 1;
-       }
-|
-       %erroneous
-       IDENTIFIER
-       {
-               error("%s is not a type identifier", dot.tk_idf->id_text);
-               ds->ds_type = error_type;
-               if (dot.tk_idf->id_def) {
-                       dot.tk_idf->id_def->df_type = error_type;
-                       dot.tk_idf->id_def->df_sc = TYPEDEF;
-               }
-       }
-|
-       %illegal
-       IDENTIFIER
-|
-       struct_or_union_specifier(&ds->ds_type)
-|
-       enum_specifier(&ds->ds_type)
-;
-
-/* 3.5.2 */
-type_specifier(struct type **tpp;)
-       /*      Used in struct/union declarations and in casts; only the
-               type is relevant.
-       */
-       {struct decspecs Ds; Ds = null_decspecs;}
-:
-       decl_specifiers(&Ds)
-       {
-               if (Ds.ds_sc_given)
-                       error("storage class ignored");
-               if (Ds.ds_sc == REGISTER)
-                       error("register ignored");
-       }
-       {*tpp = Ds.ds_type;}
-;
-
-/* 3.5 */
-init_declarator_list(struct decspecs *ds;):
-       init_declarator(ds)
-       [ ',' init_declarator(ds) ]*
-;
-
-init_declarator(register struct decspecs *ds;)
-       {
-               struct declarator Dc;
-       }
-:
-       {
-               Dc = null_declarator;
-       }
-[
-       declarator(&Dc)
-       {
-               reject_params(&Dc);
-               declare_idf(ds, &Dc, level);
-#ifdef LINT
-               lint_declare_idf(Dc.dc_idf, ds->ds_sc);
-#endif /* LINT */
-       }
-       [
-               initializer(Dc.dc_idf, ds->ds_sc)
-       |
-               { code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); }
-       ]
-]
-       {
-#ifdef LINT
-               add_auto(Dc.dc_idf);
-#endif /* LINT */
-               remove_declarator(&Dc);
-       }
-;
-
-/* 3.5.7: initializer */
-initializer(struct idf *idf; int sc;)
-       {
-               struct expr *expr = (struct expr *) 0;
-               int fund = idf->id_def->df_type->tp_fund;
-               int autoagg = (level >= L_LOCAL
-                               && sc != STATIC
-                               && ( fund == STRUCT
-                                   || fund == UNION
-                                   || fund == ARRAY));
-               int globalflag = level == L_GLOBAL
-                               || (level >= L_LOCAL && sc == STATIC);
-       }
-:
-       {       if (idf->id_def->df_type->tp_fund == FUNCTION)  {
-                       error("illegal initialization of function");
-                       idf->id_def->df_type->tp_fund = ERRONEOUS;
-               }
-               if (level == L_FORMAL2)
-                       error("illegal initialization of formal parameter");
-       }
-       '='
-       {
-               if (AHEAD != '{' && AHEAD != STRING ) autoagg = 0;
-#ifdef LINT
-               lint_statement();
-#endif /* LINT */
-               if (globalflag) {
-                       struct expr ex;
-                       code_declaration(idf, &ex, level, sc);
-               }
-               else if (autoagg)
-                       loc_init((struct expr *) 0, idf);
-       }
-       initial_value((globalflag || autoagg) ?
-                               &(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;
-                       }
-#ifdef DEBUG
-                       print_expr("initializer-expression", expr);
-#endif /* DEBUG */
-#ifdef LINT
-                       change_state(idf, SET);
-#endif /* LINT */
-#ifdef DBSYMTAB
-                       if (options['g'] && level >= L_LOCAL && expr) {
-                               db_line(expr->ex_file, (unsigned) expr->ex_line);
-                       }
-#endif /* DBSYMTAB */
-                       if (autoagg)
-                               loc_init((struct expr *) 0, idf);
-                       else    code_declaration(idf, expr, level, sc);
-               }
-#ifdef DBSYMTAB
-               if (options['g'] && globalflag) {
-                       stb_string(idf->id_def, sc, idf->id_text);
-               }
-#endif /* DBSYMTAB */
-               idf_initialized(idf);
-       }
-;
-
-/*
-       Functions yielding pointers to functions must be declared as, e.g.,
-               int (*hehe(par1, par2))() char *par1, *par2;    {}
-       Since the function heading is read as a normal declarator,
-       we just include the (formal) parameter list in the declarator
-       description list dc.
-*/
-/* 3.5.4 */
-declarator(register struct declarator *dc;)
-       {       struct formal *fm = NO_PARAMS;
-               struct proto *pl = NO_PROTO;
-               arith count;
-               int qual;
-       }
-:
-       primary_declarator(dc)
-       [/*%while(1)*/
-               '('
-               [ %if (DOT != IDENTIFIER)
-                       parameter_type_list(&pl)
-               |
-                       formal_list(&fm)
-               |
-                       /* empty */
-               ]
-               ')'
-               {       add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
-                       fm = NO_PARAMS;
-               }
-       |
-               arrayer(&count)
-               {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}
-       ]*
-|
-       pointer(&qual) declarator(dc)
-       {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}
-;
-
-primary_declarator(register struct declarator *dc;) :
-       identifier(&dc->dc_idf)
-|
-       '(' declarator(dc) ')'
-;
-
-arrayer(arith *sizep;)
-       { struct expr *expr; }
-:
-       '['
-               { *sizep = (arith)-1; }
-               [
-                       constant_expression(&expr)
-                       {
-                               check_array_subscript(expr);
-                               *sizep = expr->VL_VALUE;
-                               free_expression(expr);
-                       }
-               ]?
-       ']'
-;
-
-formal_list (struct formal **fmp;)
-:
-       formal(fmp) [ %persistent ',' formal(fmp) ]*
-;
-
-formal(struct formal **fmp;)
-       {struct idf *idf;       }
-:
-       identifier(&idf)
-       {
-               register struct formal *new = new_formal();
-               
-               new->fm_idf = idf;
-               new->next = *fmp;
-               *fmp = new;
-               if (idf->id_def && idf->id_def->df_sc == TYPEDEF) {
-                       error("typedef name %s may not be redeclared as a parameter", idf->id_text);
-               }
-       }
-;
-
-/* Change 2 */
-enum_specifier(register struct type **tpp;)
-       {
-               struct idf *idf;
-               arith l = (arith)0;
-       }
-:
-       {if (*tpp) error("multiple types in declaration");}
-       ENUM
-       [
-               {declare_struct(ENUM, (struct idf *) 0, tpp);}
-               enumerator_pack(*tpp, &l)
-       |
-               identifier(&idf)
-               [
-                       {declare_struct(ENUM, idf, tpp);}
-                       enumerator_pack(*tpp, &l)
-                       {
-#ifdef DBSYMTAB
-                               if (options['g']) {
-                                       stb_tag(idf->id_tag, idf->id_text);
-                               }
-#endif /*DBSYMTAB */
-                       }
-               |
-                       {apply_struct(ENUM, idf, tpp);}
-                       /* empty */
-               ]
-       ]
-;
-
-enumerator_pack(register struct type *tp; arith *lp;) :
-       '{'
-       enumerator(tp, lp)
-       [%while (AHEAD != '}')
-               ','
-               enumerator(tp, lp)
-       ]*
-       [
-               ','     {warning("unexpected trailing comma in enumerator pack");}
-       ]?
-       '}'
-       {tp->tp_size = int_size;}
-       /*      fancy implementations that put small enums in 1 byte
-               or so should start here.
-       */
-;
-
-enumerator(struct type *tp; arith *lp;)
-       {
-               struct idf *idf;
-               struct expr *expr;
-       }
-:
-       identifier(&idf)
-       [
-               '='
-               constant_expression(&expr)
-               {
-                       *lp = expr->VL_VALUE;
-                       free_expression(expr);
-               }
-       ]?
-       {declare_enum(tp, idf, (*lp)++);}
-;
-
-/* 8.5 */
-struct_or_union_specifier(register struct type **tpp;)
-       {
-               int fund;
-               struct idf *idfX;
-               register struct idf *idf;
-       }
-:
-       {if (*tpp) error("multiple types in declaration");}
-       [ STRUCT | UNION ]
-       {fund = DOT;}
-       [
-               {
-                       declare_struct(fund, (struct idf *)0, tpp);
-               }
-               struct_declaration_pack(*tpp)
-       |
-               identifier(&idfX)       { idf = idfX; }
-               [
-                       {
-                               declare_struct(fund, idf, tpp);
-                               (idf->id_tag->tg_busy)++;
-                       }
-                       struct_declaration_pack(*tpp)
-                       {
-                               (idf->id_tag->tg_busy)--;
-#ifdef DBSYMTAB
-                               if (options['g']) {
-                                       stb_tag(idf->id_tag, idf->id_text);
-                               }
-#endif /*DBSYMTAB */
-                       }
-               |
-                       {
-                         /* a ';' means an empty declaration (probably)
-                          * this means that we have to declare a new
-                          * structure. (yegh)
-                          */
-                         if (DOT == ';' &&
-                             ( !idf->id_tag ||
-                                idf->id_tag->tg_level != level ||
-                                idf->id_tag->tg_type->tp_size < 0
-                            )) declare_struct(fund, idf, tpp);
-                         else apply_struct(fund, idf, tpp);
-                       }
-                       /* empty */
-               ]
-       ]
-;
-
-struct_declaration_pack(register struct type *stp;)
-       {
-               struct sdef **sdefp = &stp->tp_sdef;
-               arith size = (arith)0;
-       }
-:
-       /*      The size is only filled in after the whole struct has
-               been read, to prevent recursive definitions.
-       */
-       '{'
-       struct_declaration(stp, &sdefp, &size)+
-       '}'
-       {stp->tp_size = align(size, stp->tp_align);
-        completed(stp);
-       }
-;
-
-struct_declaration(struct type *stp; struct sdef ***sdefpp; arith *szp;)
-       {struct type *tp;}
-:
-       type_specifier(&tp) struct_declarator_list(tp, stp, sdefpp, szp) ';'
-;
-
-struct_declarator_list(struct type *tp; struct type *stp;
-                       struct sdef ***sdefpp; arith *szp;)
-:
-       struct_declarator(tp, stp, sdefpp, szp)
-       [ ',' struct_declarator(tp, stp, sdefpp, szp) ]*
-;
-
-struct_declarator(struct type *tp; struct type *stp;
-                       struct sdef ***sdefpp; arith *szp;)
-       {
-               struct declarator Dc;
-               struct field *fd = 0;
-       }
-:
-       {
-               Dc = null_declarator;
-       }
-[
-       declarator(&Dc)
-       {reject_params(&Dc);}
-       bit_expression(&fd)?
-|
-       {Dc.dc_idf = gen_idf();}
-       bit_expression(&fd)
-]
-       {add_sel(stp, declare_type(tp, &Dc), Dc.dc_idf, sdefpp, szp, fd);}
-       {remove_declarator(&Dc);}
-;
-
-bit_expression(struct field **fd;)
-       { struct expr *expr; }
-:
-       {
-               *fd = new_field();
-       }
-       ':'
-       constant_expression(&expr)
-       {
-               (*fd)->fd_width = expr->VL_VALUE;
-               free_expression(expr);
-#ifdef NOBITFIELD
-               error("bitfields are not implemented");
-#endif /* NOBITFIELD */
-       }
-;
-
-/* 8.7 */
-cast(struct type **tpp;)
-       {struct declarator Dc;}
-:
-       {Dc = null_declarator;}
-       '('
-       type_specifier(tpp)
-       abstract_declarator(&Dc)
-       ')'
-       {*tpp = declare_type(*tpp, &Dc);}
-       {remove_declarator(&Dc);}
-;
-
-/*     This code is an abject copy of that of 'declarator', for lack of
-       a two-level grammar.
-*/
-abstract_declarator(register struct declarator *dc;)
-       {       struct proto *pl = NO_PROTO;
-               arith count;
-               int qual;
-       }
-:
-       primary_abstract_declarator(dc)
-       [
-               '('
-               [
-                       parameter_type_list(&pl)
-               |
-                       /* empty */
-               ]
-               ')'
-               {add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);
-                if (pl) remove_proto_idfs(pl);
-               }
-       |
-               arrayer(&count)
-               {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}
-       ]*
-|
-       pointer(&qual) abstract_declarator(dc)
-       {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}
-;
-
-%first first_of_parameter_type_list, parameter_type_list;
-
-primary_abstract_declarator(struct declarator *dc;)
-:
-[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
-       /* empty */
-|
-       '(' abstract_declarator(dc) ')'
-]
-;
-
-parameter_type_list(struct proto **plp;)
-       {       int save_level; }
-:
-       {       if (level > L_PROTO) {
-                       save_level = level;
-                       level = L_PROTO;
-               } else level--;
-       }
-       parameter_decl_list(plp)
-       [
-               ',' ELLIPSIS
-               {       register struct proto *new = new_proto();
-
-                       new->next = *plp;
-                       new->pl_flag = PL_ELLIPSIS;
-                       *plp = new;
-               }
-
-       ]?
-       {       check_for_void(*plp);
-               if (level == L_PROTO)
-                       level = save_level;
-               else level++;
-       }
-;
-
-parameter_decl_list(struct proto **plp;)
-:
-       parameter_decl(plp)
-       [ %while (AHEAD != ELLIPSIS)
-         %persistent
-               ',' parameter_decl(plp)
-       ]*
-;
-
-parameter_decl(struct proto **plp;)
-       {       register struct proto *new = new_proto();
-               struct declarator Dc;
-               struct decspecs Ds;
-       }
-:
-       {       Dc = null_declarator;
-               Ds = null_decspecs;
-       }
-       decl_specifiers(&Ds)
-       parameter_declarator(&Dc)
-       {       add_proto(new, &Ds, &Dc, level);
-               new->next = *plp;
-               *plp = new;
-               remove_declarator(&Dc);
-       }
-;
-
-/*     This is weird. Due to the LR structure of the ANSI C grammar
-       we have to duplicate the actions of 'declarator' and
-       'abstract_declarator'. Calling these separately, as in
-
-       parameter_decl:
-               decl_specifiers
-               [
-                       declarator
-               |
-                       abstract_declarator
-               ]
-
-
-       gives us a conflict on the terminals '(' and '*'. E.i. on
-       some input, it is impossible to decide which rule we take.
-       Combining the two declarators into one common declarator
-       is out of the question, since this results in an empty
-       string for the non-terminal 'declarator'.
-       So we combine the two only for the use of parameter_decl,
-       since this is the only place where they don't give
-       conflicts. However, this makes the grammar messy.
-*/
-parameter_declarator(register struct declarator *dc;)
-       {       struct formal *fm = NO_PARAMS;
-               struct proto *pl = NO_PROTO;
-               arith count;
-               int qual;
-       }
-:
-       primary_parameter_declarator(dc)
-       [
-               '('
-               [ %if (DOT != IDENTIFIER)
-                       parameter_type_list(&pl)
-               |
-                       formal_list(&fm)
-               |
-                       /* empty */
-               ]
-               ')'
-               {   add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
-                   reject_params(dc);
-               }
-       |
-               arrayer(&count)
-               {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}
-       ]*
-|
-       pointer(&qual) parameter_declarator(dc)
-       {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}
-;
-
-primary_parameter_declarator(register struct declarator *dc;)
-:
-[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
-                                   && (AHEAD != IDENTIFIER))
-       /* empty */
-|
-       identifier(&dc->dc_idf)
-|
-       '(' parameter_declarator(dc) ')'
-]
-;
-
-pointer(int *qual;)
-:
-       '*' type_qualifier_list(qual)
-;
-
-/*     Type qualifiers may come in three flavours:
-       volatile, const, const volatile.
-       These all have different semantic properties:
-
-       volatile:
-               means that the object can be modified
-               without prior knowledge of the implementation.
-
-       const:
-               means that the object can not be modified; thus
-               it's illegal to use this as a l-value.
-
-       const volatile:
-               means  that the object can be modified without
-               prior knowledge of the implementation, but may
-               not be used as a l-value.
-*/
-/* 3.5.4 */
-type_qualifier_list(int *qual;)
-:
-       { *qual = 0; }
-       [
-               VOLATILE
-               {       if (*qual & TQ_VOLATILE)
-                               error("repeated type qualifier");
-                       *qual |= TQ_VOLATILE;
-               }
-       |
-               CONST
-               {       if (*qual & TQ_CONST)
-                               error("repeated type qualifier");
-                       *qual |= TQ_CONST;
-               }
-       ]*
-;
-
-empty:
-;
+/*\r
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.\r
+ * See the copyright notice in the ACK home directory, in the file "Copyright".\r
+ */\r
+/* $Id$ */\r
+/*     DECLARATION SYNTAX PARSER       */\r
+\r
+{\r
+#include       "parameters.h"\r
+#include       <alloc.h>\r
+#include       <flt_arith.h>\r
+#include    "idf.h"\r
+#include       "arith.h"\r
+#include       "LLlex.h"\r
+#include       "label.h"\r
+#include       "code.h"\r
+#include       "type.h"\r
+#include       "proto.h"\r
+#include       "struct.h"\r
+#include       "field.h"\r
+#include       "decspecs.h"\r
+#include    "declarator.h"\r
+#include       "def.h"\r
+#include       "declar.h"\r
+#include       "label.h"\r
+#include       "expr.h"\r
+#include       "sizes.h"\r
+#include       "level.h"\r
+#include    "error.h"\r
+#include    "stab.h"\r
+\r
+#ifdef LINT\r
+#include       "l_lint.h"\r
+#endif /* LINT */\r
+\r
+extern char    options[];\r
+}\r
+\r
+/* 3.5 */\r
+declaration\r
+       {struct decspecs Ds;}\r
+:\r
+       {Ds = null_decspecs;}\r
+       decl_specifiers(&Ds)\r
+       init_declarator_list(&Ds)?\r
+       ';'\r
+;\r
+\r
+/*     A `decl_specifiers' describes a sequence of a storage_class_specifier,\r
+       an unsigned_specifier, a size_specifier and a simple type_specifier,\r
+       which may occur in arbitrary order and each of which may be absent;\r
+       at least one of them must be present, however, since the totally\r
+       empty case has already be dealt with in `external_definition'.\r
+       This means that something like:\r
+               unsigned extern int short xx;\r
+       is perfectly legal C.\r
+       \r
+       On top of that, multiple occurrences of storage_class_specifiers,\r
+       unsigned_specifiers and size_specifiers are errors, but a second\r
+       type_specifier should end the decl_specifiers and be treated as\r
+       the name to be declared.\r
+       Such a language is not easily expressed in a grammar; enumeration\r
+       of the permutations is unattractive. We solve the problem by\r
+       having a regular grammar for the "soft" items, handling the single\r
+       occurrence of the type_specifier in the grammar (we have no choice),\r
+       collecting all data in a `struct decspecs' and turning that data\r
+       structure into what we want.\r
+       \r
+       The existence of declarations like\r
+               short typedef yepp;\r
+       makes all hope of writing a specific grammar for typedefs illusory.\r
+*/\r
+/*      Accept a single declaration specifier.  Then accept zero or more\r
+       declaration specifiers.  There can be a conflict on both\r
+       TYPE_IDENTIFIER and IDENTIFIER.\r
+       The following rule is used:\r
+       When we see a TYPE_IDENTIFIER, we accept it if no type-specifier was\r
+       given, and it is not directly followed by an identifier.  If a\r
+       type-specifier was given, it is taken as the identifier being\r
+       declared.  If it is followed by an identifier, we assume that an\r
+       error has been  made, (e.g. unsigned typedeffed_int x;) and that\r
+       this will be detected later on.\r
+       When we see an IDENTIFIER, directly followed by another IDENTIFIER,\r
+       we assume that a typing mistake has been made, and we accept it as\r
+       an erroneous type-identifier.\r
+*/\r
+\r
+decl_specifiers        /* non-empty */ (register struct decspecs *ds;)\r
+       /*      Reads a non-empty decl_specifiers and fills the struct\r
+               decspecs *ds.\r
+       */\r
+:\r
+       single_decl_specifier(ds)\r
+       [ %while(  (DOT==TYPE_IDENTIFIER\r
+                       && ds->ds_size == 0\r
+                       && ds->ds_unsigned == 0\r
+                       && ds->ds_type == (struct type *)0)\r
+                   || AHEAD == IDENTIFIER)     /* always an error */\r
+               single_decl_specifier(ds)\r
+       ]*\r
+       {do_decspecs(ds);}\r
+;\r
+\r
+single_decl_specifier /* non_empty */ (register struct decspecs *ds;)\r
+:\r
+       [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]\r
+       {       if (ds->ds_sc_given)\r
+                       error("repeated storage class specifier");\r
+               ds->ds_sc_given = 1;\r
+               ds->ds_sc = DOT;\r
+       }\r
+|\r
+       VOLATILE\r
+       {       if (ds->ds_typequal & TQ_VOLATILE)\r
+                       error("repeated type qualifier");\r
+               ds->ds_typequal |= TQ_VOLATILE;\r
+       }\r
+|\r
+       CONST\r
+       {       if (ds->ds_typequal & TQ_CONST)\r
+                       error("repeated type qualifier");\r
+               ds->ds_typequal |= TQ_CONST;\r
+       }\r
+|\r
+       [ SHORT | LONG ]\r
+       {       if (ds->ds_size)\r
+                       error("repeated size specifier");\r
+               ds->ds_size = DOT;\r
+       }\r
+|\r
+       [ SIGNED | UNSIGNED ]\r
+       {       if (ds->ds_unsigned != 0)\r
+                       error("repeated sign specifier");\r
+               ds->ds_unsigned = DOT;\r
+       }\r
+|\r
+       [ VOID | CHAR | INT | FLOAT | DOUBLE ]\r
+       {\r
+               idf2type(dot.tk_idf, &ds->ds_type);\r
+               ds->ds_typedef = 0;\r
+       }\r
+|\r
+       %default TYPE_IDENTIFIER\r
+       {\r
+               idf2type(dot.tk_idf, &ds->ds_type);\r
+               ds->ds_typedef = 1;\r
+       }\r
+|\r
+       %erroneous\r
+       IDENTIFIER\r
+       {\r
+               error("%s is not a type identifier", dot.tk_idf->id_text);\r
+               ds->ds_type = error_type;\r
+               if (dot.tk_idf->id_def) {\r
+                       dot.tk_idf->id_def->df_type = error_type;\r
+                       dot.tk_idf->id_def->df_sc = TYPEDEF;\r
+               }\r
+       }\r
+|\r
+       %illegal\r
+       IDENTIFIER\r
+|\r
+       struct_or_union_specifier(&ds->ds_type)\r
+|\r
+       enum_specifier(&ds->ds_type)\r
+;\r
+\r
+/* 3.5.2 */\r
+type_specifier(struct type **tpp;)\r
+       /*      Used in struct/union declarations and in casts; only the\r
+               type is relevant.\r
+       */\r
+       {struct decspecs Ds; Ds = null_decspecs;}\r
+:\r
+       decl_specifiers(&Ds)\r
+       {\r
+               if (Ds.ds_sc_given)\r
+                       error("storage class ignored");\r
+               if (Ds.ds_sc == REGISTER)\r
+                       error("register ignored");\r
+       }\r
+       {*tpp = Ds.ds_type;}\r
+;\r
+\r
+/* 3.5 */\r
+init_declarator_list(struct decspecs *ds;):\r
+       init_declarator(ds)\r
+       [ ',' init_declarator(ds) ]*\r
+;\r
+\r
+init_declarator(register struct decspecs *ds;)\r
+       {\r
+               struct declarator Dc;\r
+       }\r
+:\r
+       {\r
+               Dc = null_declarator;\r
+       }\r
+[\r
+       declarator(&Dc)\r
+       {\r
+               reject_params(&Dc);\r
+               declare_idf(ds, &Dc, level);\r
+#ifdef LINT\r
+               lint_declare_idf(Dc.dc_idf, ds->ds_sc);\r
+#endif /* LINT */\r
+       }\r
+       [\r
+               initializer(Dc.dc_idf, ds->ds_sc)\r
+       |\r
+               { code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); }\r
+       ]\r
+]\r
+       {\r
+#ifdef LINT\r
+               add_auto(Dc.dc_idf);\r
+#endif /* LINT */\r
+               remove_declarator(&Dc);\r
+       }\r
+;\r
+\r
+/* 3.5.7: initializer */\r
+initializer(struct idf *idf; int sc;)\r
+       {\r
+               struct expr *expr = (struct expr *) 0;\r
+               int fund = idf->id_def->df_type->tp_fund;\r
+               int autoagg = (level >= L_LOCAL\r
+                               && sc != STATIC\r
+                               && ( fund == STRUCT\r
+                                   || fund == UNION\r
+                                   || fund == ARRAY));\r
+               int globalflag = level == L_GLOBAL\r
+                               || (level >= L_LOCAL && sc == STATIC);\r
+       }\r
+:\r
+       {       if (idf->id_def->df_type->tp_fund == FUNCTION)  {\r
+                       error("illegal initialization of function");\r
+                       idf->id_def->df_type->tp_fund = ERRONEOUS;\r
+               }\r
+               if (level == L_FORMAL2)\r
+                       error("illegal initialization of formal parameter");\r
+       }\r
+       '='\r
+       {\r
+               if (AHEAD != '{' && AHEAD != STRING ) autoagg = 0;\r
+#ifdef LINT\r
+               lint_statement();\r
+#endif /* LINT */\r
+               if (globalflag) {\r
+                       struct expr ex;\r
+                       code_declaration(idf, &ex, level, sc);\r
+               }\r
+               else if (autoagg)\r
+                       loc_init((struct expr *) 0, idf);\r
+       }\r
+       initial_value((globalflag || autoagg) ?\r
+                               &(idf->id_def->df_type)\r
+                               : (struct type **)0,\r
+                       &expr)\r
+       {       if (! globalflag) {\r
+                       if (idf->id_def->df_type->tp_fund == FUNCTION)  {\r
+                               free_expression(expr);\r
+                               expr = 0;\r
+                       }\r
+#ifdef DEBUG\r
+                       print_expr("initializer-expression", expr);\r
+#endif /* DEBUG */\r
+#ifdef LINT\r
+                       change_state(idf, SET);\r
+#endif /* LINT */\r
+#ifdef DBSYMTAB\r
+                       if (options['g'] && level >= L_LOCAL && expr) {\r
+                               db_line(expr->ex_file, (unsigned) expr->ex_line);\r
+                       }\r
+#endif /* DBSYMTAB */\r
+                       if (autoagg)\r
+                               loc_init((struct expr *) 0, idf);\r
+                       else    code_declaration(idf, expr, level, sc);\r
+               }\r
+#ifdef DBSYMTAB\r
+               if (options['g'] && globalflag) {\r
+                       stb_string(idf->id_def, sc, idf->id_text);\r
+               }\r
+#endif /* DBSYMTAB */\r
+               idf_initialized(idf);\r
+       }\r
+;\r
+\r
+/*\r
+       Functions yielding pointers to functions must be declared as, e.g.,\r
+               int (*hehe(par1, par2))() char *par1, *par2;    {}\r
+       Since the function heading is read as a normal declarator,\r
+       we just include the (formal) parameter list in the declarator\r
+       description list dc.\r
+*/\r
+/* 3.5.4 */\r
+declarator(register struct declarator *dc;)\r
+       {       struct formal *fm = NO_PARAMS;\r
+               struct proto *pl = NO_PROTO;\r
+               arith count;\r
+               int qual;\r
+       }\r
+:\r
+       primary_declarator(dc)\r
+       [/*%while(1)*/\r
+               '('\r
+               [ %if (DOT != IDENTIFIER)\r
+                       parameter_type_list(&pl)\r
+               |\r
+                       formal_list(&fm)\r
+               |\r
+                       /* empty */\r
+               ]\r
+               ')'\r
+               {       add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);\r
+                       fm = NO_PARAMS;\r
+               }\r
+       |\r
+               arrayer(&count)\r
+               {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}\r
+       ]*\r
+|\r
+       pointer(&qual) declarator(dc)\r
+       {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}\r
+;\r
+\r
+primary_declarator(register struct declarator *dc;) :\r
+       identifier(&dc->dc_idf)\r
+|\r
+       '(' declarator(dc) ')'\r
+;\r
+\r
+arrayer(arith *sizep;)\r
+       { struct expr *expr; }\r
+:\r
+       '['\r
+               { *sizep = (arith)-1; }\r
+               [\r
+                       constant_expression(&expr)\r
+                       {\r
+                               check_array_subscript(expr);\r
+                               *sizep = expr->VL_VALUE;\r
+                               free_expression(expr);\r
+                       }\r
+               ]?\r
+       ']'\r
+;\r
+\r
+formal_list (struct formal **fmp;)\r
+:\r
+       formal(fmp) [ %persistent ',' formal(fmp) ]*\r
+;\r
+\r
+formal(struct formal **fmp;)\r
+       {struct idf *idf;       }\r
+:\r
+       identifier(&idf)\r
+       {\r
+               register struct formal *new = new_formal();\r
+               \r
+               new->fm_idf = idf;\r
+               new->next = *fmp;\r
+               *fmp = new;\r
+               if (idf->id_def && idf->id_def->df_sc == TYPEDEF) {\r
+                       error("typedef name %s may not be redeclared as a parameter", idf->id_text);\r
+               }\r
+       }\r
+;\r
+\r
+/* Change 2 */\r
+enum_specifier(register struct type **tpp;)\r
+       {\r
+               struct idf *idf;\r
+               arith l = (arith)0;\r
+       }\r
+:\r
+       {if (*tpp) error("multiple types in declaration");}\r
+       ENUM\r
+       [\r
+               {declare_struct(ENUM, (struct idf *) 0, tpp);}\r
+               enumerator_pack(*tpp, &l)\r
+       |\r
+               identifier(&idf)\r
+               [\r
+                       {declare_struct(ENUM, idf, tpp);}\r
+                       enumerator_pack(*tpp, &l)\r
+                       {\r
+#ifdef DBSYMTAB\r
+                               if (options['g']) {\r
+                                       stb_tag(idf->id_tag, idf->id_text);\r
+                               }\r
+#endif /*DBSYMTAB */\r
+                       }\r
+               |\r
+                       {apply_struct(ENUM, idf, tpp);}\r
+                       /* empty */\r
+               ]\r
+       ]\r
+;\r
+\r
+enumerator_pack(register struct type *tp; arith *lp;) :\r
+       '{'\r
+       enumerator(tp, lp)\r
+       [%while (AHEAD != '}')\r
+               ','\r
+               enumerator(tp, lp)\r
+       ]*\r
+       [\r
+               ','     {warning("unexpected trailing comma in enumerator pack");}\r
+       ]?\r
+       '}'\r
+       {tp->tp_size = int_size;}\r
+       /*      fancy implementations that put small enums in 1 byte\r
+               or so should start here.\r
+       */\r
+;\r
+\r
+enumerator(struct type *tp; arith *lp;)\r
+       {\r
+               struct idf *idf;\r
+               struct expr *expr;\r
+       }\r
+:\r
+       identifier(&idf)\r
+       [\r
+               '='\r
+               constant_expression(&expr)\r
+               {\r
+                       *lp = expr->VL_VALUE;\r
+                       free_expression(expr);\r
+               }\r
+       ]?\r
+       {declare_enum(tp, idf, (*lp)++);}\r
+;\r
+\r
+/* 8.5 */\r
+struct_or_union_specifier(register struct type **tpp;)\r
+       {\r
+               int fund;\r
+               struct idf *idfX;\r
+               register struct idf *idf;\r
+       }\r
+:\r
+       {if (*tpp) error("multiple types in declaration");}\r
+       [ STRUCT | UNION ]\r
+       {fund = DOT;}\r
+       [\r
+               {\r
+                       declare_struct(fund, (struct idf *)0, tpp);\r
+               }\r
+               struct_declaration_pack(*tpp)\r
+       |\r
+               identifier(&idfX)       { idf = idfX; }\r
+               [\r
+                       {\r
+                               declare_struct(fund, idf, tpp);\r
+                               (idf->id_tag->tg_busy)++;\r
+                       }\r
+                       struct_declaration_pack(*tpp)\r
+                       {\r
+                               (idf->id_tag->tg_busy)--;\r
+#ifdef DBSYMTAB\r
+                               if (options['g']) {\r
+                                       stb_tag(idf->id_tag, idf->id_text);\r
+                               }\r
+#endif /*DBSYMTAB */\r
+                       }\r
+               |\r
+                       {\r
+                         /* a ';' means an empty declaration (probably)\r
+                          * this means that we have to declare a new\r
+                          * structure. (yegh)\r
+                          */\r
+                         if (DOT == ';' &&\r
+                             ( !idf->id_tag ||\r
+                                idf->id_tag->tg_level != level ||\r
+                                idf->id_tag->tg_type->tp_size < 0\r
+                            )) declare_struct(fund, idf, tpp);\r
+                         else apply_struct(fund, idf, tpp);\r
+                       }\r
+                       /* empty */\r
+               ]\r
+       ]\r
+;\r
+\r
+struct_declaration_pack(register struct type *stp;)\r
+       {\r
+               struct sdef **sdefp = &stp->tp_sdef;\r
+               arith size = (arith)0;\r
+       }\r
+:\r
+       /*      The size is only filled in after the whole struct has\r
+               been read, to prevent recursive definitions.\r
+       */\r
+       '{'\r
+       struct_declaration(stp, &sdefp, &size)+\r
+       '}'\r
+       {stp->tp_size = align(size, stp->tp_align);\r
+        completed(stp);\r
+       }\r
+;\r
+\r
+struct_declaration(struct type *stp; struct sdef ***sdefpp; arith *szp;)\r
+       {struct type *tp;}\r
+:\r
+       type_specifier(&tp) struct_declarator_list(tp, stp, sdefpp, szp) ';'\r
+;\r
+\r
+struct_declarator_list(struct type *tp; struct type *stp;\r
+                       struct sdef ***sdefpp; arith *szp;)\r
+:\r
+       struct_declarator(tp, stp, sdefpp, szp)\r
+       [ ',' struct_declarator(tp, stp, sdefpp, szp) ]*\r
+;\r
+\r
+struct_declarator(struct type *tp; struct type *stp;\r
+                       struct sdef ***sdefpp; arith *szp;)\r
+       {\r
+               struct declarator Dc;\r
+               struct field *fd = 0;\r
+       }\r
+:\r
+       {\r
+               Dc = null_declarator;\r
+       }\r
+[\r
+       declarator(&Dc)\r
+       {reject_params(&Dc);}\r
+       bit_expression(&fd)?\r
+|\r
+       {Dc.dc_idf = gen_idf();}\r
+       bit_expression(&fd)\r
+]\r
+       {add_sel(stp, declare_type(tp, &Dc), Dc.dc_idf, sdefpp, szp, fd);}\r
+       {remove_declarator(&Dc);}\r
+;\r
+\r
+bit_expression(struct field **fd;)\r
+       { struct expr *expr; }\r
+:\r
+       {\r
+               *fd = new_field();\r
+       }\r
+       ':'\r
+       constant_expression(&expr)\r
+       {\r
+               (*fd)->fd_width = expr->VL_VALUE;\r
+               free_expression(expr);\r
+#ifdef NOBITFIELD\r
+               error("bitfields are not implemented");\r
+#endif /* NOBITFIELD */\r
+       }\r
+;\r
+\r
+/* 8.7 */\r
+cast(struct type **tpp;)\r
+       {struct declarator Dc;}\r
+:\r
+       {Dc = null_declarator;}\r
+       '('\r
+       type_specifier(tpp)\r
+       abstract_declarator(&Dc)\r
+       ')'\r
+       {*tpp = declare_type(*tpp, &Dc);}\r
+       {remove_declarator(&Dc);}\r
+;\r
+\r
+/*     This code is an abject copy of that of 'declarator', for lack of\r
+       a two-level grammar.\r
+*/\r
+abstract_declarator(register struct declarator *dc;)\r
+       {       struct proto *pl = NO_PROTO;\r
+               arith count;\r
+               int qual;\r
+       }\r
+:\r
+       primary_abstract_declarator(dc)\r
+       [\r
+               '('\r
+               [\r
+                       parameter_type_list(&pl)\r
+               |\r
+                       /* empty */\r
+               ]\r
+               ')'\r
+               {add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);\r
+                if (pl) remove_proto_idfs(pl);\r
+               }\r
+       |\r
+               arrayer(&count)\r
+               {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}\r
+       ]*\r
+|\r
+       pointer(&qual) abstract_declarator(dc)\r
+       {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}\r
+;\r
+\r
+%first first_of_parameter_type_list, parameter_type_list;\r
+\r
+primary_abstract_declarator(struct declarator *dc;)\r
+:\r
+[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))\r
+       /* empty */\r
+|\r
+       '(' abstract_declarator(dc) ')'\r
+]\r
+;\r
+\r
+parameter_type_list(struct proto **plp;)\r
+       {       int save_level; }\r
+:\r
+       {       if (level > L_PROTO) {\r
+                       save_level = level;\r
+                       level = L_PROTO;\r
+               } else level--;\r
+       }\r
+       parameter_decl_list(plp)\r
+       [\r
+               ',' ELLIPSIS\r
+               {       register struct proto *new = new_proto();\r
+\r
+                       new->next = *plp;\r
+                       new->pl_flag = PL_ELLIPSIS;\r
+                       *plp = new;\r
+               }\r
+\r
+       ]?\r
+       {       check_for_void(*plp);\r
+               if (level == L_PROTO)\r
+                       level = save_level;\r
+               else level++;\r
+       }\r
+;\r
+\r
+parameter_decl_list(struct proto **plp;)\r
+:\r
+       parameter_decl(plp)\r
+       [ %while (AHEAD != ELLIPSIS)\r
+         %persistent\r
+               ',' parameter_decl(plp)\r
+       ]*\r
+;\r
+\r
+parameter_decl(struct proto **plp;)\r
+       {       register struct proto *new = new_proto();\r
+               struct declarator Dc;\r
+               struct decspecs Ds;\r
+       }\r
+:\r
+       {       Dc = null_declarator;\r
+               Ds = null_decspecs;\r
+       }\r
+       decl_specifiers(&Ds)\r
+       parameter_declarator(&Dc)\r
+       {       add_proto(new, &Ds, &Dc, level);\r
+               new->next = *plp;\r
+               *plp = new;\r
+               remove_declarator(&Dc);\r
+       }\r
+;\r
+\r
+/*     This is weird. Due to the LR structure of the ANSI C grammar\r
+       we have to duplicate the actions of 'declarator' and\r
+       'abstract_declarator'. Calling these separately, as in\r
+\r
+       parameter_decl:\r
+               decl_specifiers\r
+               [\r
+                       declarator\r
+               |\r
+                       abstract_declarator\r
+               ]\r
+\r
+\r
+       gives us a conflict on the terminals '(' and '*'. E.i. on\r
+       some input, it is impossible to decide which rule we take.\r
+       Combining the two declarators into one common declarator\r
+       is out of the question, since this results in an empty\r
+       string for the non-terminal 'declarator'.\r
+       So we combine the two only for the use of parameter_decl,\r
+       since this is the only place where they don't give\r
+       conflicts. However, this makes the grammar messy.\r
+*/\r
+parameter_declarator(register struct declarator *dc;)\r
+       {       struct formal *fm = NO_PARAMS;\r
+               struct proto *pl = NO_PROTO;\r
+               arith count;\r
+               int qual;\r
+       }\r
+:\r
+       primary_parameter_declarator(dc)\r
+       [\r
+               '('\r
+               [ %if (DOT != IDENTIFIER)\r
+                       parameter_type_list(&pl)\r
+               |\r
+                       formal_list(&fm)\r
+               |\r
+                       /* empty */\r
+               ]\r
+               ')'\r
+               {   add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);\r
+                   reject_params(dc);\r
+               }\r
+       |\r
+               arrayer(&count)\r
+               {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}\r
+       ]*\r
+|\r
+       pointer(&qual) parameter_declarator(dc)\r
+       {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}\r
+;\r
+\r
+primary_parameter_declarator(register struct declarator *dc;)\r
+:\r
+[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)\r
+                                   && (AHEAD != IDENTIFIER))\r
+       /* empty */\r
+|\r
+       identifier(&dc->dc_idf)\r
+|\r
+       '(' parameter_declarator(dc) ')'\r
+]\r
+;\r
+\r
+pointer(int *qual;)\r
+:\r
+       '*' type_qualifier_list(qual)\r
+;\r
+\r
+/*     Type qualifiers may come in three flavours:\r
+       volatile, const, const volatile.\r
+       These all have different semantic properties:\r
+\r
+       volatile:\r
+               means that the object can be modified\r
+               without prior knowledge of the implementation.\r
+\r
+       const:\r
+               means that the object can not be modified; thus\r
+               it's illegal to use this as a l-value.\r
+\r
+       const volatile:\r
+               means  that the object can be modified without\r
+               prior knowledge of the implementation, but may\r
+               not be used as a l-value.\r
+*/\r
+/* 3.5.4 */\r
+type_qualifier_list(int *qual;)\r
+:\r
+       { *qual = 0; }\r
+       [\r
+               VOLATILE\r
+               {       if (*qual & TQ_VOLATILE)\r
+                               error("repeated type qualifier");\r
+                       *qual |= TQ_VOLATILE;\r
+               }\r
+       |\r
+               CONST\r
+               {       if (*qual & TQ_CONST)\r
+                               error("repeated type qualifier");\r
+                       *qual |= TQ_CONST;\r
+               }\r
+       ]*\r
+;\r
+\r
+empty:\r
+;\r
index 884bd97..ebe1869 100644 (file)
@@ -2,6 +2,9 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+ #ifndef DECLAR_H_
+ #define DECLAR_H_
 /* $Id$ */
 /* DEFINITION OF DECLARATOR DESCRIPTORS */
 
@@ -39,3 +42,5 @@ struct decl_unary     {
 
 extern struct type *declare_type();
 extern struct declarator null_declarator;
+
+#endif
index 212b8ae..2795bda 100644 (file)
@@ -6,6 +6,7 @@
 /*     D E C L A R A T O R   M A N I P U L A T I O N           */
 
 #include       "parameters.h"
+#include    "declarator.h"
 #include       <alloc.h>
 #include       <flt_arith.h>
 #include       "arith.h"
 #include       "Lpars.h"
 #include       "declar.h"
 #include       "def.h"
+#include    "idf.h"
 #include       "label.h"
 #include       "expr.h"
 #include       "sizes.h"
 #include       "level.h"
+#include    "error.h"
 
 extern char options[];
 struct declarator null_declarator;
 
 struct type *
-declare_type(tp, dc)
-       struct type *tp;
-       struct declarator *dc;
+declare_type(
+       struct type *tp,
+       struct declarator *dc)
 {
        /*      Applies the decl_unary list starting at dc->dc_decl_unary
                to the type tp and returns the result.
@@ -43,12 +46,7 @@ declare_type(tp, dc)
        return tp;
 }
 
-add_decl_unary(dc, fund, qual,  count, fm, pl)
-       register struct declarator *dc;
-       int qual;
-       arith count;
-       struct formal *fm;
-       struct proto *pl;
+void add_decl_unary(register struct declarator *dc, int fund, int qual,  arith count, struct formal *fm, struct proto *pl)
 {
        /*      A decl_unary describing a constructor with fundamental
                type fund and with size count is inserted in front of the
@@ -75,8 +73,7 @@ add_decl_unary(dc, fund, qual,  count, fm, pl)
        dc->dc_decl_unary = new;
 }
 
-remove_declarator(dc)
-       struct declarator *dc;
+void remove_declarator(struct declarator *dc)
 {
        /*      The decl_unary list starting at dc->dc_decl_unary is
                removed.
@@ -91,8 +88,7 @@ remove_declarator(dc)
        }
 }
 
-reject_params(dc)
-       register struct declarator *dc;
+void reject_params(register struct declarator *dc)
 {
        /*      The declarator is checked to have no parameters, if it
                is an old-style function.  If it is a new-style function,
@@ -120,8 +116,7 @@ reject_params(dc)
        }
 }
 
-check_array_subscript(expr)
-       register struct expr *expr;
+void check_array_subscript(register struct expr *expr)
 {
        arith size = expr->VL_VALUE;
 
diff --git a/lang/cem/cemcom.ansi/declarator.h b/lang/cem/cemcom.ansi/declarator.h
new file mode 100644 (file)
index 0000000..abda9de
--- /dev/null
@@ -0,0 +1,28 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef DECLARATOR_H_
+#define DECLARATOR_H_
+
+#include "arith.h"
+
+/* Forward declarations. */
+struct type;
+struct declarator;
+struct formal;
+struct proto;
+struct expr;
+
+struct type *
+declare_type(struct type *tp, struct declarator *dc);
+void add_decl_unary(register struct declarator *dc, int fund, int qual,
+               arith count, struct formal *fm, struct proto *pl);
+void remove_declarator(struct declarator *dc);
+void reject_params(register struct declarator *dc);
+void check_array_subscript(register struct expr *expr);
+
+#endif /* DECLARATOR_H_ */
index bef0c0d..42465e2 100644 (file)
@@ -6,12 +6,13 @@
 /*     D E C L A R A T I O N   S P E C I F I E R   C H E C K I N G     */
 
 #include       <assert.h>
-#include       "Lpars.h"
 #include       "decspecs.h"
+#include       "Lpars.h"
 #include       "arith.h"
 #include       "type.h"
 #include       "level.h"
 #include       "def.h"
+#include    "error.h"
 
 extern char options[];
 extern int level;
@@ -20,36 +21,35 @@ extern struct type *qualifier_type();
 
 struct decspecs null_decspecs;
 
-do_decspecs(ds)
-       register struct decspecs *ds;
+void do_decspecs(register struct decspecs *ds)
 {
        /*      The provisional decspecs ds as obtained from the program
-               is turned into a legal consistent decspecs.
-       */
+        is turned into a legal consistent decspecs.
+        */
        register struct type *tp = ds->ds_type;
-       
+
        assert(level != L_FORMAL1);
-       
-       if (    level == L_GLOBAL &&
-               (ds->ds_sc == AUTO || ds->ds_sc == REGISTER)
-       )       {
-               error("no global %s variable allowed",
-                       symbol2str(ds->ds_sc));
+
+       if (level == L_GLOBAL && (ds->ds_sc == AUTO || ds->ds_sc == REGISTER))
+       {
+               error("no global %s variable allowed", symbol2str(ds->ds_sc));
                ds->ds_sc = GLOBAL;
        }
 
-       if (level == L_FORMAL2) {
-               if (ds->ds_sc_given &&
-                   ds->ds_sc != REGISTER){
+       if (level == L_FORMAL2)
+       {
+               if (ds->ds_sc_given && ds->ds_sc != REGISTER)
+               {
                        error("%s formal illegal", symbol2str(ds->ds_sc));
                        ds->ds_sc = FORMAL;
                }
        }
 
        /*      Since type qualifiers may be associated with types by means
-               of typedefs, we have to perform same basic tests down here.
-       */
-       if (tp != (struct type *)0) {
+        of typedefs, we have to perform same basic tests down here.
+        */
+       if (tp != (struct type *) 0)
+       {
                if ((ds->ds_typequal & TQ_VOLATILE) && (tp->tp_typequal & TQ_VOLATILE))
                        error("indirect repeated type qualifier");
                if ((ds->ds_typequal & TQ_CONST) && (tp->tp_typequal & TQ_CONST))
@@ -58,49 +58,74 @@ do_decspecs(ds)
        }
 
        /*      The tests concerning types require a full knowledge of the
-               type and will have to be postponed to declare_idf.
-       */
+        type and will have to be postponed to declare_idf.
+        */
 
        /* some adjustments as described in 3.5.2. */
-       if (tp == 0) {
+       if (tp == 0)
+       {
                ds->ds_notypegiven = 1;
                tp = int_type;
        }
-       if (ds->ds_size) {
+       if (ds->ds_size)
+       {
                register int ds_isshort = (ds->ds_size == SHORT);
 
-               if (ds->ds_typedef) goto SIZE_ERROR;            /* yes */
-               if (tp == int_type) {
-                       if (ds_isshort) tp = short_type;
-                       else tp = long_type;
-               } else if (tp == double_type && !ds_isshort ) {
+               if (ds->ds_typedef)
+                       goto SIZE_ERROR;
+               /* yes */
+               if (tp == int_type)
+               {
+                       if (ds_isshort)
+                               tp = short_type;
+                       else
+                               tp = long_type;
+               }
+               else if (tp == double_type && !ds_isshort)
+               {
                        tp = lngdbl_type;
-               } else {
-       SIZE_ERROR:
-                       error("%s with illegal type",symbol2str(ds->ds_size));
+               }
+               else
+               {
+                       SIZE_ERROR: error("%s with illegal type", symbol2str(ds->ds_size));
                }
                ds->ds_notypegiven = 0;
        }
-       if (ds->ds_unsigned) {
+       if (ds->ds_unsigned)
+       {
                register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED);
 
-               if (ds->ds_typedef) goto SIGN_ERROR;            /* yes */
+               if (ds->ds_typedef)
+                       goto SIGN_ERROR;
+               /* yes */
                /*
                 * All integral types are signed by default (char too),
                 * so the case that ds->ds_unsigned == SIGNED can be ignored.
                 */
-               if (tp == schar_type) {
-                       if (ds_isunsigned) tp = uchar_type;
-               } else if (tp == short_type) {
-                       if (ds_isunsigned) tp = ushort_type;
-               } else if (tp == int_type) {
-                       if (ds_isunsigned) tp = uint_type;
-               } else if (tp == long_type) {
-                       if (ds_isunsigned) tp = ulong_type;
-               } else {
-       SIGN_ERROR:
-                       error("%s with illegal type"
-                               , symbol2str(ds->ds_unsigned));
+               if (tp == schar_type)
+               {
+                       if (ds_isunsigned)
+                               tp = uchar_type;
+               }
+               else if (tp == short_type)
+               {
+                       if (ds_isunsigned)
+                               tp = ushort_type;
+               }
+               else if (tp == int_type)
+               {
+                       if (ds_isunsigned)
+                               tp = uint_type;
+               }
+               else if (tp == long_type)
+               {
+                       if (ds_isunsigned)
+                               tp = ulong_type;
+               }
+               else
+               {
+                       SIGN_ERROR: error("%s with illegal type",
+                                       symbol2str(ds->ds_unsigned));
                }
                ds->ds_notypegiven = 0;
        }
@@ -108,15 +133,12 @@ do_decspecs(ds)
 }
 
 /*     Make tp into a qualified type. This is not as trivial as it
-       may seem. If tp is a fundamental type the qualified type is
-       either existent or will be generated.
-       In case of a complex type the top of the type list will be
-       replaced by a qualified version.
-*/
-struct type *
-qualifier_type(tp, typequal)
-       register struct type *tp;
-       int typequal;
+ may seem. If tp is a fundamental type the qualified type is
+ either existent or will be generated.
+ In case of a complex type the top of the type list will be
+ replaced by a qualified version.
+ */
+struct type *qualifier_type(register struct type *tp, int typequal)
 {
        register struct type *dtp = tp;
        register int fund = tp->tp_fund;
@@ -124,32 +146,34 @@ qualifier_type(tp, typequal)
        while (dtp && dtp->tp_typequal != typequal)
                dtp = dtp->next;
 
-       if (!dtp) {
+       if (!dtp)
+       {
                dtp = create_type(fund);
                dtp->tp_unsigned = tp->tp_unsigned;
                dtp->tp_align = tp->tp_align;
                dtp->tp_typequal = typequal;
                dtp->tp_size = tp->tp_size;
 #if 0
-/* The tp_function field does not exist now. See the comment in the
-   function_of() routine.
-*/
+               /* The tp_function field does not exist now. See the comment in the
+                function_of() routine.
+                */
                dtp->tp_function = tp->tp_function;
 #endif
-               switch (fund) {
+               switch (fund)
+               {
                case ARRAY:
-                       if (typequal) {
-                           tp->tp_up = qualifier_type(tp->tp_up, typequal);
-                           dtp->tp_typequal = typequal = 0;
+                       if (typequal)
+                       {
+                               tp->tp_up = qualifier_type(tp->tp_up, typequal);
+                               dtp->tp_typequal = typequal = 0;
                        }
                        goto nottagged;
                case FIELD:
                        dtp->tp_field = tp->tp_field;
                        /* fallthrough */
                case POINTER:
-               case FUNCTION:                  /* dont't assign tp_proto */
-               nottagged:
-                       dtp->tp_up = tp->tp_up;
+               case FUNCTION: /* dont't assign tp_proto */
+                       nottagged: dtp->tp_up = tp->tp_up;
                        break;
                case STRUCT:
                case UNION:
@@ -163,6 +187,6 @@ qualifier_type(tp, typequal)
                dtp->next = tp->next; /* don't know head or tail */
                tp->next = dtp;
        }
-       return(dtp);
+       return (dtp);
 }
 
index 73a4048..7256b73 100644 (file)
@@ -2,6 +2,9 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef DECSPECS_H_
+#define DECSPECS_H_
+
 /* $Id$ */
 /* DECLARATION SPECIFIER DEFINITION */
 
@@ -19,3 +22,10 @@ struct decspecs      {
 
 extern struct type *qualifier_type();
 extern struct decspecs null_decspecs;
+
+struct type;
+
+void do_decspecs(register struct decspecs *ds);
+struct type *qualifier_type(register struct type *tp, int typequal);
+
+#endif
index 0ad7af3..ad528a6 100644 (file)
@@ -2,6 +2,9 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef DEF_H_
+#define DEF_H_
+
 /* $Id$ */
 /* IDENTIFIER DEFINITION DESCRIPTOR */
 
@@ -38,3 +41,5 @@ struct def    {               /* for ordinary tags */
 #define REG_BONUS      10      /* register candidate, declared as such */
 
 /* ALLOCDEF "def" 50 */
+
+#endif
index d6fc4c5..dc77827 100644 (file)
@@ -8,12 +8,17 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include "domacro.h"
 #include "parameters.h"
 #include "idf.h"
+#include "interface.h"
 #include "arith.h"
 #include "LLlex.h"
 #include "Lpars.h"
 #include "input.h"
+#include "pragma.h"
+#include "skip.h"
+#include "error.h"
 
 #ifdef DBSYMTAB
 #include <stb.h>
@@ -23,7 +28,9 @@ int IncludeLevel = 0;
 
 extern char options[];
 
-struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */
+static void do_line(unsigned int);
+
+struct idf* GetIdentifier(int skiponerr) /* skip the rest of the line on error */
 {
        /*      returns a pointer to the descriptor of the identifier that is
            read from the input stream. When the input does not contain
@@ -44,7 +51,7 @@ struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line
        return tk.tk_idf;
 }
 
-domacro()
+void domacro(void)
 {
        int tok;
        struct token tk;
@@ -70,7 +77,7 @@ domacro()
        SkipToNewLine();
 }
 
-do_line(l) unsigned int l;
+static void do_line(unsigned int l)
 {
        struct token tk;
        int t = GetToken(&tk);
diff --git a/lang/cem/cemcom.ansi/domacro.h b/lang/cem/cemcom.ansi/domacro.h
new file mode 100644 (file)
index 0000000..75d6085
--- /dev/null
@@ -0,0 +1,16 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef DOMACRO_H_
+#define DOMACRO_H_
+
+struct idf;
+
+struct idf* GetIdentifier(int skiponerr) ;
+void domacro(void);
+
+#endif /* DOMACRO_H_ */
index 6f2283b..76421ed 100644 (file)
@@ -6,6 +6,7 @@
 /*     E R R O R   A N D  D I A G N O S T I C   R O U T I N E S        */
 
 #include       "parameters.h"
+#include    "error.h"
 #if __STDC__
 #include       <stdarg.h>
 #else
 #else
 #include       "l_em.h"
 #endif /* LINT */
-
+#include    <stdio.h>
 #include       "tokenname.h"
 #include       <flt_arith.h>
+#include    "interface.h"
 #include       "arith.h"
 #include       "label.h"
 #include       "expr.h"
 #include       "def.h"
+#include    "print.h"
 #include       "LLlex.h"
 
 /*     This file contains the error-message and diagnostic
@@ -56,12 +59,11 @@ extern char loptions[];
        FileName, expression errors get their information from the
        expression, whereas other errors use the information in the token.
 */
-
-static void _error();
+static void _error(int, char *, unsigned int, char*, va_list);
 
 #if __STDC__
 /*VARARGS*/
-error(char *fmt, ...)
+void error(char *fmt, ...)
 {
        va_list ap;
 
@@ -73,7 +75,7 @@ error(char *fmt, ...)
 }
 
 /*VARARGS*/
-expr_error(struct expr *expr, char *fmt, ...)
+void expr_error(struct expr *expr, char *fmt, ...)
 {
        va_list ap;
 
@@ -89,7 +91,7 @@ expr_error(struct expr *expr, char *fmt, ...)
 }
 
 /*VARARGS*/
-lexstrict(char *fmt, ...)
+void lexstrict(char *fmt, ...)
 {
        va_list ap;
 
@@ -101,7 +103,7 @@ lexstrict(char *fmt, ...)
 }
 
 /*VARARGS*/
-strict(char *fmt, ...)
+void strict(char *fmt, ...)
 {
        va_list ap;
 
@@ -113,7 +115,7 @@ strict(char *fmt, ...)
 }
 
 /*VARARGS*/
-expr_strict(struct expr *expr, char *fmt, ...)
+void expr_strict(struct expr *expr, char *fmt, ...)
 {
        va_list ap;
 
@@ -129,7 +131,7 @@ expr_strict(struct expr *expr, char *fmt, ...)
 
 #ifdef DEBUG
 /*VARARGS*/
-debug(char *fmt, ...)
+void debug(char *fmt, ...)
 {
        va_list ap;
 
@@ -142,7 +144,7 @@ debug(char *fmt, ...)
 #endif /* DEBUG */
 
 /*VARARGS*/
-warning(char *fmt, ...)
+void warning(char *fmt, ...)
 {
        va_list ap;
 
@@ -154,7 +156,7 @@ warning(char *fmt, ...)
 }
 
 /*VARARGS*/
-expr_warning(struct expr *expr, char *fmt, ...)
+void expr_warning(struct expr *expr, char *fmt, ...)
 {
        va_list ap;
 
@@ -171,7 +173,7 @@ expr_warning(struct expr *expr, char *fmt, ...)
 #ifdef LINT
 
 /*VARARGS*/
-def_warning(struct def *def, char *fmt, ...)
+void def_warning(struct def *def, char *fmt, ...)
 {
        va_list ap;
 
@@ -184,7 +186,7 @@ def_warning(struct def *def, char *fmt, ...)
 
 
 /*VARARGS*/
-hwarning(char *fmt, ...)
+void hwarning(char *fmt, ...)
 {
        va_list ap;
 
@@ -197,7 +199,7 @@ hwarning(char *fmt, ...)
 }
 
 /*VARARGS*/
-awarning(char *fmt, ...)
+void awarning(char *fmt, ...)
 {
        va_list ap;
 
@@ -212,7 +214,7 @@ awarning(char *fmt, ...)
 #endif /* LINT */
 
 /*VARARGS*/
-lexerror(char *fmt, ...)
+void lexerror(char *fmt, ...)
 {
        va_list ap;
 
@@ -224,7 +226,7 @@ lexerror(char *fmt, ...)
 }
 
 /*VARARGS*/
-lexwarning(char *fmt, ...)
+void lexwarning(char *fmt, ...)
 {
        va_list ap;
 
@@ -236,7 +238,7 @@ lexwarning(char *fmt, ...)
 }
 
 /*VARARGS*/
-crash(char *fmt, ...)
+void crash(char *fmt, ...)
 {
        va_list ap;
 
@@ -256,7 +258,7 @@ crash(char *fmt, ...)
 }
 
 /*VARARGS*/
-fatal(char *fmt, ...)
+void fatal(char *fmt, ...)
 {
        va_list ap;
 
@@ -272,7 +274,7 @@ fatal(char *fmt, ...)
 }
 #else
 /*VARARGS*/
-error(va_alist)                                /* fmt, args */
+void error(va_alist)                           /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -286,7 +288,7 @@ error(va_alist)                             /* fmt, args */
 }
 
 /*VARARGS*/
-expr_error(va_alist)                   /* expr, fmt, args */
+void expr_error(va_alist)                      /* expr, fmt, args */
        va_dcl
 {
        va_list ap;
@@ -306,7 +308,7 @@ expr_error(va_alist)                        /* expr, fmt, args */
 }
 
 /*VARARGS*/
-lexstrict(va_alist)
+void lexstrict(va_alist)
        va_dcl
 {
        va_list ap;
@@ -320,7 +322,7 @@ lexstrict(va_alist)
 }
 
 /*VARARGS*/
-strict(va_alist)
+void strict(va_alist)
        va_dcl
 {
        va_list ap;
@@ -334,7 +336,7 @@ strict(va_alist)
 }
 
 /*VARARGS*/
-expr_strict(va_alist)                  /* expr, fmt, args */
+void expr_strict(va_alist)                     /* expr, fmt, args */
        va_dcl
 {
        va_list ap;
@@ -354,7 +356,7 @@ expr_strict(va_alist)                       /* expr, fmt, args */
 
 #ifdef DEBUG
 /*VARARGS*/
-debug(va_alist)
+void debug(va_alist)
        va_dcl
 {
        va_list ap;
@@ -369,7 +371,7 @@ debug(va_alist)
 #endif /* DEBUG */
 
 /*VARARGS*/
-warning(va_alist)
+void warning(va_alist)
        va_dcl
 {
        va_list ap;
@@ -383,7 +385,7 @@ warning(va_alist)
 }
 
 /*VARARGS*/
-expr_warning(va_alist)                 /* expr, fmt, args */
+void expr_warning(va_alist)                    /* expr, fmt, args */
        va_dcl
 {
        va_list ap;
@@ -404,7 +406,7 @@ expr_warning(va_alist)                      /* expr, fmt, args */
 #ifdef LINT
 
 /*VARARGS*/
-def_warning(va_alist)                  /* def, fmt, args */
+void def_warning(va_alist)                     /* def, fmt, args */
        va_dcl
 {
        va_list ap;
@@ -421,7 +423,7 @@ def_warning(va_alist)                       /* def, fmt, args */
 
 
 /*VARARGS*/
-hwarning(va_alist)                     /* fmt, args */
+void hwarning(va_alist)                        /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -436,7 +438,7 @@ hwarning(va_alist)                  /* fmt, args */
 }
 
 /*VARARGS*/
-awarning(va_alist)                     /* fmt, args */
+void awarning(va_alist)                        /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -453,7 +455,7 @@ awarning(va_alist)                  /* fmt, args */
 #endif /* LINT */
 
 /*VARARGS*/
-lexerror(va_alist)                     /* fmt, args */
+void lexerror(va_alist)                        /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -467,7 +469,7 @@ lexerror(va_alist)                  /* fmt, args */
 }
 
 /*VARARGS*/
-lexwarning(va_alist)                   /* fmt, args */
+void lexwarning(va_alist)                      /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -481,7 +483,7 @@ lexwarning(va_alist)                        /* fmt, args */
 }
 
 /*VARARGS*/
-crash(va_alist)                                /* fmt, args */
+void crash(va_alist)                           /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -503,7 +505,7 @@ crash(va_alist)                             /* fmt, args */
 }
 
 /*VARARGS*/
-fatal(va_alist)                                /* fmt, args */
+void fatal(va_alist)                           /* fmt, args */
        va_dcl
 {
        va_list ap;
@@ -521,13 +523,7 @@ fatal(va_alist)                            /* fmt, args */
 }
 #endif
 
-static void
-_error(class, fn, ln, fmt, ap)
-       int class;
-       char *fn;
-       unsigned int ln;
-       char *fmt;
-       va_list ap;
+static void _error(int class, char *fn, unsigned int ln, char* fmt, va_list ap)
 {
        char *remark;
        
@@ -614,9 +610,9 @@ _error(class, fn, ln, fmt, ap)
 #endif /* LINT */
        
        if (fn)
-               fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
+               fprint(stderr, "\"%s\", line %u: ", fn, ln);
        if (remark)
-               fprint(ERROUT, "%s ", remark);
-       doprnt(ERROUT, fmt, ap);                /* contents of error */
-       fprint(ERROUT, "\n");
+               fprint(stderr, "%s ", remark);
+       doprnt(stderr, fmt, ap);                /* contents of error */
+       fprint(stderr, "\n");
 }
diff --git a/lang/cem/cemcom.ansi/error.h b/lang/cem/cemcom.ansi/error.h
new file mode 100644 (file)
index 0000000..595cd2a
--- /dev/null
@@ -0,0 +1,94 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef ERROR_H_
+#define ERROR_H_
+
+struct expr;
+
+#if __STDC__
+/*VARARGS*/
+void error(char *fmt, ...);
+/*VARARGS*/
+void expr_error(struct expr *expr, char *fmt, ...);
+/*VARARGS*/
+void lexstrict(char *fmt, ...);
+/*VARARGS*/
+void strict(char *fmt, ...);
+/*VARARGS*/
+void expr_strict(struct expr *expr, char *fmt, ...);
+
+#ifdef DEBUG
+/*VARARGS*/
+void debug(char *fmt, ...);
+#endif /* DEBUG */
+
+/*VARARGS*/
+void warning(char *fmt, ...);
+/*VARARGS*/
+void expr_warning(struct expr *expr, char *fmt, ...);
+#ifdef LINT
+/*VARARGS*/
+void def_warning(struct def *def, char *fmt, ...);
+/*VARARGS*/
+void hwarning(char *fmt, ...);
+/*VARARGS*/
+void awarning(char *fmt, ...);
+#endif /* LINT */
+
+/*VARARGS*/
+void lexerror(char *fmt, ...);
+/*VARARGS*/
+void lexwarning(char *fmt, ...);
+/*VARARGS*/
+void crash(char *fmt, ...);
+/*VARARGS*/
+void fatal(char *fmt, ...);
+
+#else
+/*VARARGS*/
+void error(va_alist);                          /* fmt, args */
+/*VARARGS*/
+void expr_error(va_alist);                     /* expr, fmt, args */
+/*VARARGS*/
+void lexstrict(va_alist);
+/*VARARGS*/
+void strict(va_alist);
+/*VARARGS*/
+void expr_strict(va_alist);                    /* expr, fmt, args */
+#ifdef DEBUG
+/*VARARGS*/
+void debug(va_alist);
+#endif /* DEBUG */
+
+/*VARARGS*/
+void warning(va_alist);
+/*VARARGS*/
+void expr_warning(va_alist);                   /* expr, fmt, args */
+#ifdef LINT
+
+/*VARARGS*/
+void def_warning(va_alist);                    /* def, fmt, args */
+/*VARARGS*/
+void hwarning(va_alist);                       /* fmt, args */
+/*VARARGS*/
+void awarning(va_alist);                       /* fmt, args */
+#endif /* LINT */
+
+/*VARARGS*/
+void lexerror(va_alist);                       /* fmt, args */
+/*VARARGS*/
+void lexwarning(va_alist);                     /* fmt, args */
+/*VARARGS*/
+void crash(va_alist);                          /* fmt, args */
+/*VARARGS*/
+void fatal(va_alist);                          /* fmt, args */
+#endif
+
+
+
+#endif /* ERROR_H_ */
index b65629e..0718cca 100644 (file)
@@ -2,6 +2,9 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+ #ifndef ESTACK_H_
+ #define ESTACK_H_
 /* $Id$ */
 /* EXPRESSION STACK */
 /* Used for global initializations */
@@ -19,3 +22,5 @@ struct e_stack {
 #define last_offset    s_cnt2
 #define elem_count     s_cnt1
 #define nelem          s_cnt2
+
+#endif
\ No newline at end of file
index 0ec25da..352d590 100644 (file)
@@ -14,6 +14,8 @@
 #include       <em_reg.h>
 #include       <alloc.h>
 #include       <flt_arith.h>
+#include    "interface.h"
+#include    "eval.h"
 #include    "idf.h"
 #include       "arith.h"
 #include       "type.h"
 #include       "def.h"
 #include       "expr.h"
 #include       "sizes.h"
+#include    "field.h"
 #include       "Lpars.h"
 #include       "level.h"
+#include    "conversion.h"
 #include       "stack.h"
+#include    "struct.h"
 #include       "align.h"
 #include       "mes.h"
 #include       "atw.h"
+#include    "ch3.h"
+#include    "util.h"
+#include    "blocks.h"
+#include    "dataflow.h"
 #include       "specials.h"
+#include    "error.h"
 
 #define        CRASH()         crash("EVAL: CRASH at line %u", __LINE__)
 
@@ -37,8 +47,12 @@ arith NewLocal();    /* util.c */
 #define LocalPtrVar()  NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
 extern int     err_occurred; /* error.c */
 
-void store_val();
-void load_val();
+
+/* Forward internal declarations */
+static void operands(register struct expr *, int);
+static void ptr_add(arith size);
+static void truthvalue(int relop);
+static void compare(int relop, label lbl);
 
 /*     EVAL() is the main expression-tree evaluator, which turns
        any legal expression tree into EM code. parameters.h:
@@ -66,11 +80,7 @@ void load_val();
                labels, in case they are specified (i.e. are non-zero)
 */
 
-void
-EVAL(expr, val, code, true_label, false_label)
-       register struct expr *expr;
-       int val, code;
-       label true_label, false_label;
+void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label)
 {
        int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE));
        register int gencode = code == TRUE;
@@ -659,9 +669,7 @@ EVAL(expr, val, code, true_label, false_label)
 }
 
 /*     compare() serves as an auxiliary function of EVAL       */
-compare(relop, lbl)
-       int relop;
-       label lbl;
+static void compare(int relop, label lbl)
 {
        switch (relop) {
        case '<':
@@ -688,8 +696,7 @@ compare(relop, lbl)
 }
 
 /*     truthvalue() serves as an auxiliary function of EVAL    */
-truthvalue(relop)
-       int relop;
+static void truthvalue(int relop)
 {
        switch (relop)  {
        case '<':
@@ -717,12 +724,10 @@ truthvalue(relop)
 
 
 /*     assop() generates the opcode of an assignment operators op=     */
-assop(type, oper)
-       register struct type *type;
-       int oper;
+void assop(register struct type *type, int oper)
 {
        register arith size;
-       register uns = type->tp_unsigned;
+       register int uns = type->tp_unsigned;
 
        if ((int)(size = type->tp_size) < (int)word_size)
                size = word_size;
@@ -822,8 +827,7 @@ assop(type, oper)
        }
 }
 
-ptr_add(size)
-       arith size;
+static void ptr_add(arith size)
 {
        if (size != pointer_size) {
                C_loc(size);
@@ -840,10 +844,7 @@ ptr_add(size)
        - into a local static variable
        - absolute addressing
 */
-void
-store_val(vl, tp)
-       register struct value *vl;
-       register struct type *tp;
+void store_val(register struct value *vl, register struct type *tp)
 {
        register int inword = 0;
        register int indword = 0;
@@ -911,11 +912,10 @@ store_val(vl, tp)
        - global variable
        - static variable
        - local variable
+
+       rlval generate rlval or lval
 */
-void
-load_val(expr, rlval)
-       register struct expr *expr; /* expression containing the value  */
-       int rlval;              /* generate either LVAL or RVAL         */
+void load_val(register struct expr *expr, int rlval)
 {
        register struct type *tp = expr->ex_type;
        int rvalue = (rlval == RVAL && expr->ex_lvalue != 0);
@@ -1012,8 +1012,7 @@ load_val(expr, rlval)
        }
 }
 
-load_cst(val, siz)
-       arith val, siz;
+void load_cst(arith val, arith siz)
 {
        if ((int)siz <= (int)word_size)
                C_loc(val);
@@ -1030,8 +1029,7 @@ load_cst(val, siz)
        }
 }
 
-operands(expr, gencode)
-       register struct expr *expr;
+static void operands(register struct expr *expr, int gencode)
 {
        EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL);
        EVAL(expr->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL);
diff --git a/lang/cem/cemcom.ansi/eval.h b/lang/cem/cemcom.ansi/eval.h
new file mode 100644 (file)
index 0000000..337b5ac
--- /dev/null
@@ -0,0 +1,37 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-06
+ *  
+ */
+#ifndef EVAL_H_
+#define EVAL_H_
+
+#ifndef        LINT
+
+
+#include <em.h>
+
+struct expr;
+struct value;
+struct type;
+
+void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label);
+
+/*     assop() generates the opcode of an assignment operators op=     */
+void assop(register struct type *type, int oper);
+/*     store_val() generates code for a store operation.
+       There are four ways of storing data:
+       - into a global variable
+       - into an automatic local variable
+       - into a local static variable
+       - absolute addressing
+*/
+void store_val(register struct value *vl, register struct type *tp);
+void load_val(register struct expr *expr, int rlval);
+void load_cst(arith val, arith siz);
+
+#endif /* LINT */
+
+#endif /* EVAL_H_ */
index 7b686c3..b24c408 100644 (file)
@@ -10,6 +10,7 @@
 #include       "parameters.h"
 #include       <alloc.h>
 #include       <flt_arith.h>
+#include    "expr.h"
 #include    "idf.h"
 #include       "arith.h"
 #include       "def.h"
 #include       "declar.h"
 #include       "sizes.h"
 #include       "level.h"
+#include    "cstoper.h"
+#include    "error.h"
 
 extern char *symbol2str();
 extern char options[];
 extern int InSizeof;
 
-int
-rank_of(oper)
-       int oper;
+int rank_of(int oper)
 {
        /*      The rank of the operator oper is returned.
-       */
-       switch (oper)   {
+        */
+       switch (oper)
+       {
        default:
-               return 0;                       /* INT2INT etc. */
+               return 0; /* INT2INT etc. */
        case '[':
        case '(':
        case '.':
@@ -48,7 +50,7 @@ rank_of(oper)
        case CAST:
        case SIZEOF:
        case ADDRESSOF:
-               return 2;                       /* monadic */
+               return 2; /* monadic */
        case '*':
        case '/':
        case '%':
@@ -98,18 +100,18 @@ rank_of(oper)
        /*NOTREACHED*/
 }
 
-dot2expr(expp)
-       struct expr **expp;
+void dot2expr(struct expr **expp)
 {
        /*      The token in dot is converted into an expression, a
-               pointer to which is stored in *expp.
-       */
+        pointer to which is stored in *expp.
+        */
        register struct expr *ex = new_expr();
 
        *expp = ex;
        ex->ex_file = dot.tk_file;
        ex->ex_line = dot.tk_line;
-       switch (DOT)    {
+       switch (DOT)
+       {
        case IDENTIFIER:
                idf2expr(ex);
                break;
@@ -125,25 +127,27 @@ dot2expr(expp)
        }
 }
 
-idf2expr(expr)
-       register struct expr *expr;
+void idf2expr(register struct expr *expr)
 {
        /*      Dot contains an identifier which is turned into an
-               expression.
-               Note that this constitutes an applied occurrence of
-               the identifier.
-       */
-       register struct idf *idf = dot.tk_idf;  /* != 0*/
+        expression.
+        Note that this constitutes an applied occurrence of
+        the identifier.
+        */
+       register struct idf *idf = dot.tk_idf; /* != 0*/
        register struct def *def = idf->id_def;
-       
-       if (def == 0)   {
-               if (AHEAD == '(') {
+
+       if (def == 0)
+       {
+               if (AHEAD == '(')
+               {
                        /* function call, declare name implicitly (3.3.2.2) */
                        if (!options['o'])
-                               warning("implicit declaration of function %s"
-                                       , idf->id_text);
+                               warning("implicit declaration of function %s", idf->id_text);
                        add_def(idf, EXTERN, funint_type, level);
-               } else  {
+               }
+               else
+               {
                        if (!is_anon_idf(idf))
                                error("%s undefined", idf->id_text);
                        /* declare idf anyway */
@@ -153,8 +157,10 @@ idf2expr(expr)
        }
        /* now def != 0 */
 #ifndef        LINT
-       if (!InSizeof) {
-               if (! def->df_used) {
+       if (!InSizeof)
+       {
+               if (!def->df_used)
+               {
 #ifndef PREPEND_SCOPES
                        code_scope(idf->id_text, def);
 #endif /* PREPEND_SCOPES */
@@ -163,46 +169,45 @@ idf2expr(expr)
        }
 #endif /* LINT */
        expr->ex_type = def->df_type;
-       if (expr->ex_type == error_type) {
+       if (expr->ex_type == error_type)
+       {
                expr->ex_flags |= EX_ERROR;
        }
        expr->ex_lvalue =
-               (       def->df_type->tp_fund == FUNCTION ||
-                       def->df_type->tp_fund == ARRAY ||
-                       def->df_sc == ENUM
-               ) ? 0 : 1;
+                       (def->df_type->tp_fund == FUNCTION || def->df_type->tp_fund == ARRAY
+                                       || def->df_sc == ENUM) ? 0 : 1;
        if (def->df_type->tp_typequal & TQ_CONST)
                expr->ex_flags |= EX_READONLY;
        if (def->df_type->tp_typequal & TQ_VOLATILE)
                expr->ex_flags |= EX_VOLATILE;
        expr->ex_class = Value;
-       if (def->df_sc == ENUM) {
+       if (def->df_sc == ENUM)
+       {
                expr->VL_CLASS = Const;
                expr->VL_VALUE = def->df_address;
        }
 #ifndef        LINT
-       else
-       if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
+       else if (def->df_sc == STATIC && def->df_level >= L_LOCAL)
+       {
                expr->VL_CLASS = Label;
                expr->VL_LBL = def->df_address;
-               expr->VL_VALUE = (arith)0;
+               expr->VL_VALUE = (arith) 0;
        }
 #endif /* LINT */
-       else {
+       else
+       {
                expr->VL_CLASS = Name;
                expr->VL_IDF = idf;
-               expr->VL_VALUE = (arith)0;
+               expr->VL_VALUE = (arith) 0;
        }
 }
 
-string2expr(expp, str, len)
-       register struct expr **expp;
-       int len;
-       char *str;
+void string2expr(register struct expr **expp, char *str, int len)
+
 {
        /*      The string in the argument is converted into an expression,
-               a pointer to which is stored in *expp.
-       */
+        a pointer to which is stored in *expp.
+        */
        register struct expr *ex = new_expr();
 
        *expp = ex;
@@ -217,25 +222,24 @@ string2expr(expp, str, len)
        ex->SG_LEN = len;
 }
 
-int2expr(expr)
-       struct expr *expr;
+void int2expr(struct expr *expr)
 {
        /*      Dot contains an integer constant which is turned
-               into an expression.
-       */
+        into an expression.
+        */
        fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
 }
 
-float2expr(expr)
-       register struct expr *expr;
+void float2expr(register struct expr *expr)
 {
        /*      Dot contains a floating point constant which is turned
-               into an expression.
-       */
+        into an expression.
+        */
        register int fund;
 
        fund = dot.tk_fund;
-       switch (fund) {
+       switch (fund)
+       {
        case FLOAT:
                expr->ex_type = float_type;
                break;
@@ -253,17 +257,15 @@ float2expr(expr)
        free(dot.tk_fval);
        assert(flt_status != FLT_NOFLT);
        if (flt_status == FLT_OVFL)
-               expr_warning(expr,"internal floating point overflow");
+               expr_warning(expr, "internal floating point overflow");
 }
 
-struct expr*
-intexpr(ivalue, fund)
-       arith ivalue;
-       int fund;
+struct expr*intexpr(
+arith ivalue, int fund)
 {
        /*      The value ivalue is turned into an integer expression of
-               the size indicated by fund.
-       */
+        the size indicated by fund.
+        */
        register struct expr *expr = new_expr();
 
        expr->ex_file = dot.tk_file;
@@ -272,15 +274,14 @@ intexpr(ivalue, fund)
        return expr;
 }
 
-fill_int_expr(ex, ivalue, fund)
-       register struct expr *ex;
-       arith ivalue;
-       int fund;
+void fill_int_expr(register struct expr *ex,
+arith ivalue, int fund)
 {
        /*      Details derived from ivalue and fund are put into the
-               constant integer expression ex.
-       */
-       switch (fund) {
+        constant integer expression ex.
+        */
+       switch (fund)
+       {
        case INT:
                ex->ex_type = int_type;
                break;
@@ -288,7 +289,7 @@ fill_int_expr(ex, ivalue, fund)
                ex->ex_type = uint_type;
                break;
        case LONG:
-               ex->ex_type =  long_type;
+               ex->ex_type = long_type;
                break;
        case ULONG:
                ex->ex_type = ulong_type;
@@ -303,38 +304,38 @@ fill_int_expr(ex, ivalue, fund)
        cut_size(ex);
 }
 
-struct expr *
-new_oper(tp, e1, oper, e2)
-       struct type *tp;
-       register struct expr *e1, *e2;
+struct expr *new_oper(struct type *tp, register struct expr *e1, int oper,
+               register struct expr *e2)
 {
        /*      A new expression is constructed which consists of the
-               operator oper which has e1 and e2 as operands; for a
-               monadic operator e1 == NILEXPR.
-               During the construction of the right recursive initialisation
-               tree it is possible for e2 to be NILEXPR.
-       */
+        operator oper which has e1 and e2 as operands; for a
+        monadic operator e1 == NILEXPR.
+        During the construction of the right recursive initialisation
+        tree it is possible for e2 to be NILEXPR.
+        */
        register struct expr *expr = new_expr();
        register struct oper *op;
 
-       if (e2) {
+       if (e2)
+       {
                register struct expr *e = e2;
-               
+
                while (e->ex_class == Oper && e->OP_LEFT)
                        e = e->OP_LEFT;
                expr->ex_file = e->ex_file;
                expr->ex_line = e->ex_line;
        }
-       else
-       if (e1) {
+       else if (e1)
+       {
                register struct expr *e = e1;
-               
+
                while (e->ex_class == Oper && e->OP_RIGHT)
                        e = e->OP_RIGHT;
                expr->ex_file = e->ex_file;
                expr->ex_line = e->ex_line;
        }
-       else    {
+       else
+       {
                expr->ex_file = dot.tk_file;
                expr->ex_line = dot.tk_line;
        }
@@ -342,20 +343,22 @@ new_oper(tp, e1, oper, e2)
        expr->ex_type = tp;
        expr->ex_class = Oper;
        /* combine depths and flags of both expressions */
-       if (e2) {
+       if (e2)
+       {
                int e1_depth = e1 ? e1->ex_depth : 0;
                int e1_flags = e1 ? e1->ex_flags : 0;
-               
-               expr->ex_depth =
-                       (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
+
+               expr->ex_depth = (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth)
+                               + 1;
                expr->ex_flags = (e1_flags | e2->ex_flags)
-                       & ~(EX_PARENS | EX_READONLY | EX_VOLATILE );
+                               & ~(EX_PARENS | EX_READONLY | EX_VOLATILE);
        }
        /*
         * A function call should be evaluated first when possible.  Just say
         * that the expression tree is very deep.
         */
-       if (oper == '(') {
+       if (oper == '(')
+       {
                expr->ex_depth = 50;
        }
        op = &expr->ex_object.ex_oper;
@@ -369,42 +372,42 @@ new_oper(tp, e1, oper, e2)
        return expr;
 }
 
-void
-chk_cst_expr(expp)
-       struct expr **expp;
+void chk_cst_expr(struct expr **expp)
 {
        /*      The expression expr is checked for constancy.
-       
-               There are 6 places where constant expressions occur in C:
-               1.      after #if
-               2.      in a global initialization
-               3.      as size in an array declaration
-               4.      as value in an enum declaration
-               5.      as width in a bit field
-               6.      as case value in a switch
-               
-               The constant expression in a global initialization is
-               handled separately (by IVAL()).
-               
-               There are various disparate restrictions on each of
-               the others in the various C compilers.  I have tried some
-               hypotheses to unify them, but all have failed.
-               
-               Special problems (of which there is only one, sizeof in
-               Preprocessor #if) have to be dealt with locally
-       */
+
+        There are 6 places where constant expressions occur in C:
+        1.     after #if
+        2.     in a global initialization
+        3.     as size in an array declaration
+        4.     as value in an enum declaration
+        5.     as width in a bit field
+        6.     as case value in a switch
+
+        The constant expression in a global initialization is
+        handled separately (by IVAL()).
+
+        There are various disparate restrictions on each of
+        the others in the various C compilers.  I have tried some
+        hypotheses to unify them, but all have failed.
+
+        Special problems (of which there is only one, sizeof in
+        Preprocessor #if) have to be dealt with locally
+        */
        register struct expr *expr = *expp;
-       
+
 #ifdef DEBUG
        print_expr("constant_expression", expr);
 #endif /* DEBUG */
-       switch(expr->ex_type->tp_fund) {
+       switch (expr->ex_type->tp_fund)
+       {
        case CHAR:
        case SHORT:
        case INT:
        case ENUM:
        case LONG:
-               if (is_ld_cst(expr)) {
+               if (is_ld_cst(expr))
+               {
                        return;
                }
                expr_error(expr, "expression is not constant");
@@ -416,67 +419,58 @@ chk_cst_expr(expp)
        erroneous2int(expp);
 }
 
-init_expression(eppp, expr)
-       register struct expr ***eppp;
-       struct expr *expr;
+void init_expression(register struct expr ***eppp, struct expr *expr)
 {
        /*      The expression expr is added to the tree designated
-               indirectly by **eppp.
-               The natural form of a tree representing an
-               initial_value_list is right-recursive, ie. with the
-               left-most comma as main operator. The iterative grammar in
-               expression.g, however, tends to produce a left-recursive
-               tree, ie. one with the right-most comma as its main
-               operator.
-               To produce a right-recursive tree from the iterative
-               grammar, we keep track of the address of the pointer where
-               the next expression must be hooked in.
-       */
+        indirectly by **eppp.
+        The natural form of a tree representing an
+        initial_value_list is right-recursive, ie. with the
+        left-most comma as main operator. The iterative grammar in
+        expression.g, however, tends to produce a left-recursive
+        tree, ie. one with the right-most comma as its main
+        operator.
+        To produce a right-recursive tree from the iterative
+        grammar, we keep track of the address of the pointer where
+        the next expression must be hooked in.
+        */
        **eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR);
        *eppp = &(**eppp)->OP_RIGHT;
 }
 
-int
-is_ld_cst(expr)
-       register struct expr *expr;
+int is_ld_cst(register struct expr *expr)
 {
        /*      An expression is a `load-time constant' if it is of the form
-               <idf> +/- <integral> or <integral>.
-       */
+        <idf> +/- <integral> or <integral>.
+        */
 #ifdef LINT
        if (expr->ex_class == String)
-               return 1;
+       return 1;
 #endif /* LINT */
        return expr->ex_lvalue == 0 && expr->ex_class == Value;
 }
 
-int
-is_cp_cst(expr)
-       struct expr *expr;
+int is_cp_cst(struct expr *expr)
 {
        /*      An expression is a `compile-time constant' if it is a
-               load-time constant, and the idf is not there.
-       */
+        load-time constant, and the idf is not there.
+        */
        return is_ld_cst(expr) && expr->VL_CLASS == Const;
 }
 
-int
-is_fp_cst(expr)
-       struct expr *expr;
+int is_fp_cst(struct expr *expr)
 {
        /*      An expression is a `floating-point constant' if it consists
-               of the float only.
-       */
+        of the float only.
+        */
        return expr->ex_class == Float;
 }
 
-int
-is_zero_cst(expr)
-       register struct expr *expr;
+int is_zero_cst(register struct expr *expr)
 {
        flt_arith var;
 
-       switch(expr->ex_class) {
+       switch (expr->ex_class)
+       {
        case Value:
                return expr->VL_VALUE == 0;
        case Float:
@@ -486,13 +480,14 @@ is_zero_cst(expr)
        /*NOTREACHED*/
 }
 
-free_expression(expr)
-       register struct expr *expr;
+void free_expression(register struct expr *expr)
 {
        /*      The expression expr is freed recursively.
-       */
-       if (expr) {
-               if (expr->ex_class == Oper)     {
+        */
+       if (expr)
+       {
+               if (expr->ex_class == Oper)
+               {
                        free_expression(expr->OP_LEFT);
                        free_expression(expr->OP_RIGHT);
                }
index b341524..97ac5b1 100644 (file)
@@ -4,6 +4,13 @@
  */
 /* $Id$ */
 /* EXPRESSION DESCRIPTOR */
+#ifndef EXPR_H_
+#define EXPR_H_
+
+#include "parameters.h"
+#include "arith.h"
+#include "label.h"
+#include "flt_arith.h"
 
 /*     What we want to define is the struct expr, but since it contains
        a union of various goodies, we define them first; so be patient.
@@ -97,3 +104,24 @@ extern struct expr *intexpr(), *new_oper();
 
 /* ALLOCDEF "expr" 20 */
 
+
+
+int rank_of(int oper);
+void dot2expr(struct expr **expp);
+void idf2expr(register struct expr *expr);
+void string2expr(register struct expr **expp, char *str, int len);
+void int2expr(struct expr *expr);
+void float2expr(register struct expr *expr);
+struct expr* intexpr(arith ivalue, int fund);
+void fill_int_expr(register struct expr *ex,arith ivalue, int fund);
+struct expr *new_oper(struct type *tp, register struct expr *e1, int oper,
+               register struct expr *e2);
+void chk_cst_expr(struct expr **expp);
+void init_expression(register struct expr ***eppp, struct expr *expr);
+int is_ld_cst(register struct expr *expr);
+int is_cp_cst(struct expr *expr);
+int is_fp_cst(struct expr *expr);
+int is_zero_cst(register struct expr *expr);
+void free_expression(register struct expr *expr);
+
+#endif
\ No newline at end of file
index 3a1284e..0998883 100644 (file)
-/*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
-/* $Id$ */
-/*     EXPRESSION SYNTAX PARSER        */
-
-{
-#include       <alloc.h>
-#include       "parameters.h"
-#include       <flt_arith.h>
-#include       "arith.h"
-#include       "LLlex.h"
-#include       "type.h"
-#include       "label.h"
-#include       "expr.h"
-#include       "code.h"
-#include       "sizes.h"
-
-extern struct expr *intexpr();
-int InSizeof = 0;      /* inside a sizeof- expression */
-int ResultKnown = 0;   /* result of the expression is already known */
-
-/* Since the grammar in the standard is not LL(n), it is modified so that
- * it accepts basically the same grammar. This means that there is no 1-1
- * mapping from the grammar in the standard to the grammar given here.
- * Such is life.
- */
-}
-
-/* 3.3.1 */
-primary(register struct expr **expp;) :
-       IDENTIFIER
-       {dot2expr(expp);}
-|
-       constant(expp)
-|
-       string(expp)
-|
-       '(' expression(expp) ')'
-       { (*expp)->ex_flags |= EX_PARENS; }
-;
-
-
-/* Character string literals that are adjacent tokens
- * are concatenated into a single character string
- * literal.
- */
-string(register struct expr **expp;)
-       {       register int i, len;
-               register char *str;
-               register int fund;
-       }
-:
-       STRING
-       {       str = dot.tk_bts;
-               len = dot.tk_len;
-               fund = dot.tk_fund;
-       }
-       [
-               STRING
-               {       /* A pasted string keeps the type of the first
-                        * string literal.
-                        * The pasting of normal strings and wide
-                        * character strings are stated as having an
-                        * undefined behaviour.
-                        */
-                       if (dot.tk_fund != fund)
-                               warning("illegal pasting of string literals");
-                       str = Realloc(str, (unsigned) (--len + dot.tk_len));
-                       for (i = 0; i < dot.tk_len; i++)
-                               str[len++] = dot.tk_bts[i];
-               }
-       ]*
-       { string2expr(expp, str, len); }
-;
-
-/* 3.3.2 */
-postfix_expression(register struct expr **expp;)
-       { int oper; 
-         struct expr *e1 = 0;
-         struct idf *idf;
-       }
-:
-       primary(expp)
-       [
-               '[' expression(&e1) ']'
-                       { ch3bin(expp, '[', e1); e1 = 0; }
-       |
-               '(' parameter_list(&e1)? ')'
-                       { ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
-       |
-               [ '.' | ARROW ]                 { oper = DOT; }
-               identifier(&idf)                { ch3sel(expp, oper, idf); }
-       |
-               [
-                       PLUSPLUS        { oper = POSTINCR; }
-               |
-                       MINMIN          { oper = POSTDECR; }
-               ]
-                   { ch3incr(expp, oper); }
-       ]*
-;
-
-parameter_list(struct expr **expp;)
-       {struct expr *e1 = 0;}
-:
-       assignment_expression(expp)
-       {any2opnd(expp, PARCOMMA);}
-       [ %persistent
-               ','
-               assignment_expression(&e1)
-               {any2opnd(&e1, PARCOMMA);}
-               {ch3bin(expp, PARCOMMA, e1);}
-       ]*
-;
-
-%first first_of_type_specifier, type_specifier;
-
-/* 3.3.3 & 3.3.4 */
-unary(register struct expr **expp;)
-       {struct type *tp; int oper;}
-:
-%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
-       cast(&tp) unary(expp)
-       {       ch3cast(expp, CAST, tp);
-               (*expp)->ex_flags |= EX_CAST;
-               if (int_size != pointer_size)
-                       (*expp)->ex_flags &= ~EX_PTRDIFF;
-       }
-|
-       postfix_expression(expp)
-|
-       unop(&oper) unary(expp)
-       {ch3mon(oper, expp);}
-|
-       size_of(expp)
-;
-
-/* When an identifier is used in a sizeof()-expression, we must stil not
- * mark it as used.
- * extern int i;  ....  sizeof(i)  .... need not have a definition for i
- */
-size_of(register struct expr **expp;)
-       {struct type *tp;}
-:
-       SIZEOF { InSizeof++; }  /* handle (sizeof(sizeof(int))) too */
-       [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
-               cast(&tp)
-               {
-                       *expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
-                       (*expp)->ex_flags |= EX_SIZEOF;
-               }
-       |
-               unary(expp)
-               {ch3mon(SIZEOF, expp);}
-       ]
-       { InSizeof--; }
-;
-
-/* 3.3.5-3.3.17 */
-/*     The set of operators in C is stratified in 15 levels, with level
-       N being treated in RM 7.N (although this is not the standard
-       anymore). The standard describes this in phrase-structure-grammar,
-       which we are unable to parse. The description that follows comes
-       from the old C-compiler.
-
-       In principle each operator is assigned a rank, ranging
-       from 1 to 15.  Such an expression can be parsed by a construct
-       like:
-               binary_expression(int maxrank;)
-                       {int oper;}
-               :
-                       binary_expression(maxrank - 1)
-                       [%if (rank_of(DOT) <= maxrank)
-                               binop(&oper)
-                               binary_expression(rank_of(oper)-1)
-                       ]?
-               ;
-       except that some call of 'unary' is necessary, depending on the
-       grammar.
-       
-       This simple view is marred by three complications:
-       1.      Level 15 (comma operator) is not allowed in many
-               contexts and is different.
-       2.      Level 13 (conditional operator) is a ternary operator,
-               which does not fit this scheme at all.
-       3.      Level 14 (assignment operators) group right-to-left, as
-               opposed to 2-12, which group left-to-right (or are
-               immaterial).
-       4.      The operators in level 14 start with operators in levels
-               2-13 (RM 7.14: The two parts of a compound assignment
-               operator are separate tokens.)  This causes LL1 problems.
-       This forces us to have four rules:
-               binary_expression       for level 2-12
-               conditional_expression  for level 13
-               assignment_expression   for level 14 and
-               expression              for the most general expression
-*/
-
-binary_expression(int maxrank; struct expr **expp;)
-       {int oper, OldResultKnown; struct expr *e1;}
-:
-       unary(expp)
-       [%while (rank_of(DOT) <= maxrank )
-               /*      '?', '=', and ',' are no binops
-                */
-               binop(&oper)
-               { OldResultKnown = ResultKnown;
-                 if (oper == OR || oper == AND) {
-                         if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
-                                 if (is_zero_cst(*expp)) {
-                                         if (oper == AND) ResultKnown++;
-                                 } else if (oper == OR) ResultKnown++;
-                         }
-                 }
-               }
-               binary_expression(rank_of(oper)-1, &e1)
-               {
-                       ch3bin(expp, oper, e1);
-                       ResultKnown = OldResultKnown;
-               }
-       ]*
-;
-
-/* 3.3.15 */
-conditional_expression(struct expr **expp;)
-       {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
-:
-       /* allow all binary operators */
-       binary_expression(rank_of('?') - 1, expp)
-       [       '?'
-               { OldResultKnown = ResultKnown;
-                 if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
-                         ConstExpr++;
-                         if (is_zero_cst(*expp)) ResultKnown++;
-                 }
-               }
-               expression(&e1)
-               ':'
-               { if (ConstExpr) {
-                       if (OldResultKnown == ResultKnown) ResultKnown++;
-                       else ResultKnown = OldResultKnown;
-                 }
-               }
-               conditional_expression(&e2)
-               {       
-                       ResultKnown = OldResultKnown;
-                       ch3bin(&e1, ':', e2);
-                       opnd2test(expp, '?');
-                       ch3bin(expp, '?', e1);
-               }
-       ]?
-;
-
-/* 3.3.16 */
-assignment_expression(struct expr **expp;)
-       { int oper;
-         struct expr *e1 = 0;
-       }
-:
-       conditional_expression(expp)
-       [
-               asgnop(&oper)
-               assignment_expression(&e1)
-               {ch3asgn(expp, oper, e1);}
-       |
-               empty           /* LLgen artefact ??? */
-       ]
-;
-
-/* 3.3.17 */
-expression(struct expr **expp;)
-       {struct expr *e1;}
-:
-       assignment_expression(expp)
-       [       ','
-               assignment_expression(&e1)
-               {
-                       ch3bin(expp, ',', e1);
-               }
-       ]*
-;
-
-unop(int *oper;) :
-       ['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
-       {   if (DOT == '&') DOT = ADDRESSOF;
-           *oper = DOT;
-       }
-;
-
-multop:
-       '*' | '/' | '%'
-;
-
-addop:
-       '+' | '-'
-;
-
-shiftop:
-       LEFT | RIGHT
-;
-
-relop:
-       '<' | '>' | LESSEQ | GREATEREQ
-;
-
-eqop:
-       EQUAL | NOTEQUAL
-;
-
-arithop:
-       multop | addop | shiftop
-|
-       '&' | '^' | '|'
-;
-
-binop(int *oper;) :
-       [ arithop | relop | eqop | AND | OR ]
-       {*oper = DOT;}
-;
-
-asgnop(register int *oper;):
-       [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB 
-       | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
-       { *oper = DOT; }
-
-;
-
-constant(struct expr **expp;) :
-[
-       INTEGER
-|
-       FLOATING
-]      {dot2expr(expp);}
-;
-
-/* 3.4 */
-constant_expression (struct expr **expp;) :
-       conditional_expression(expp)
-       { chk_cst_expr(expp); }
-;
-
-identifier(struct idf **idfp;) :
-[ IDENTIFIER
-| TYPE_IDENTIFIER
-]
-       { *idfp = dot.tk_idf; }
-;
+/*\r
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.\r
+ * See the copyright notice in the ACK home directory, in the file "Copyright".\r
+ */\r
+/* $Id$ */\r
+/*     EXPRESSION SYNTAX PARSER        */\r
+\r
+{\r
+#include       <alloc.h>\r
+#include       "parameters.h"\r
+#include       <flt_arith.h>\r
+#include       "arith.h"\r
+#include       "LLlex.h"\r
+#include       "type.h"\r
+#include       "label.h"\r
+#include       "expr.h"\r
+#include       "code.h"\r
+#include    "error.h"\r
+#include    "ch3.h"\r
+#include    "ch3bin.h"\r
+#include    "ch3mon.h"\r
+#include    "proto.h"\r
+#include       "sizes.h"\r
+\r
+extern struct expr *intexpr();\r
+int InSizeof = 0;      /* inside a sizeof- expression */\r
+int ResultKnown = 0;   /* result of the expression is already known */\r
+\r
+/* Since the grammar in the standard is not LL(n), it is modified so that\r
+ * it accepts basically the same grammar. This means that there is no 1-1\r
+ * mapping from the grammar in the standard to the grammar given here.\r
+ * Such is life.\r
+ */\r
+}\r
+\r
+/* 3.3.1 */\r
+primary(register struct expr **expp;) :\r
+       IDENTIFIER\r
+       {dot2expr(expp);}\r
+|\r
+       constant(expp)\r
+|\r
+       string(expp)\r
+|\r
+       '(' expression(expp) ')'\r
+       { (*expp)->ex_flags |= EX_PARENS; }\r
+;\r
+\r
+\r
+/* Character string literals that are adjacent tokens\r
+ * are concatenated into a single character string\r
+ * literal.\r
+ */\r
+string(register struct expr **expp;)\r
+       {       register int i, len;\r
+               register char *str;\r
+               register int fund;\r
+       }\r
+:\r
+       STRING\r
+       {       str = dot.tk_bts;\r
+               len = dot.tk_len;\r
+               fund = dot.tk_fund;\r
+       }\r
+       [\r
+               STRING\r
+               {       /* A pasted string keeps the type of the first\r
+                        * string literal.\r
+                        * The pasting of normal strings and wide\r
+                        * character strings are stated as having an\r
+                        * undefined behaviour.\r
+                        */\r
+                       if (dot.tk_fund != fund)\r
+                               warning("illegal pasting of string literals");\r
+                       str = Realloc(str, (unsigned) (--len + dot.tk_len));\r
+                       for (i = 0; i < dot.tk_len; i++)\r
+                               str[len++] = dot.tk_bts[i];\r
+               }\r
+       ]*\r
+       { string2expr(expp, str, len); }\r
+;\r
+\r
+/* 3.3.2 */\r
+postfix_expression(register struct expr **expp;)\r
+       { int oper; \r
+         struct expr *e1 = 0;\r
+         struct idf *idf;\r
+       }\r
+:\r
+       primary(expp)\r
+       [\r
+               '[' expression(&e1) ']'\r
+                       { ch3bin(expp, '[', e1); e1 = 0; }\r
+       |\r
+               '(' parameter_list(&e1)? ')'\r
+                       { ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }\r
+       |\r
+               [ '.' | ARROW ]                 { oper = DOT; }\r
+               identifier(&idf)                { ch3sel(expp, oper, idf); }\r
+       |\r
+               [\r
+                       PLUSPLUS        { oper = POSTINCR; }\r
+               |\r
+                       MINMIN          { oper = POSTDECR; }\r
+               ]\r
+                   { ch3incr(expp, oper); }\r
+       ]*\r
+;\r
+\r
+parameter_list(struct expr **expp;)\r
+       {struct expr *e1 = 0;}\r
+:\r
+       assignment_expression(expp)\r
+       {any2opnd(expp, PARCOMMA);}\r
+       [ %persistent\r
+               ','\r
+               assignment_expression(&e1)\r
+               {any2opnd(&e1, PARCOMMA);}\r
+               {ch3bin(expp, PARCOMMA, e1);}\r
+       ]*\r
+;\r
+\r
+%first first_of_type_specifier, type_specifier;\r
+\r
+/* 3.3.3 & 3.3.4 */\r
+unary(register struct expr **expp;)\r
+       {struct type *tp; int oper;}\r
+:\r
+%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)\r
+       cast(&tp) unary(expp)\r
+       {       ch3cast(expp, CAST, tp);\r
+               (*expp)->ex_flags |= EX_CAST;\r
+               if (int_size != pointer_size)\r
+                       (*expp)->ex_flags &= ~EX_PTRDIFF;\r
+       }\r
+|\r
+       postfix_expression(expp)\r
+|\r
+       unop(&oper) unary(expp)\r
+       {ch3mon(oper, expp);}\r
+|\r
+       size_of(expp)\r
+;\r
+\r
+/* When an identifier is used in a sizeof()-expression, we must stil not\r
+ * mark it as used.\r
+ * extern int i;  ....  sizeof(i)  .... need not have a definition for i\r
+ */\r
+size_of(register struct expr **expp;)\r
+       {struct type *tp;}\r
+:\r
+       SIZEOF { InSizeof++; }  /* handle (sizeof(sizeof(int))) too */\r
+       [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)\r
+               cast(&tp)\r
+               {\r
+                       *expp = intexpr(size_of_type(tp, "type"), UNSIGNED);\r
+                       (*expp)->ex_flags |= EX_SIZEOF;\r
+               }\r
+       |\r
+               unary(expp)\r
+               {ch3mon(SIZEOF, expp);}\r
+       ]\r
+       { InSizeof--; }\r
+;\r
+\r
+/* 3.3.5-3.3.17 */\r
+/*     The set of operators in C is stratified in 15 levels, with level\r
+       N being treated in RM 7.N (although this is not the standard\r
+       anymore). The standard describes this in phrase-structure-grammar,\r
+       which we are unable to parse. The description that follows comes\r
+       from the old C-compiler.\r
+\r
+       In principle each operator is assigned a rank, ranging\r
+       from 1 to 15.  Such an expression can be parsed by a construct\r
+       like:\r
+               binary_expression(int maxrank;)\r
+                       {int oper;}\r
+               :\r
+                       binary_expression(maxrank - 1)\r
+                       [%if (rank_of(DOT) <= maxrank)\r
+                               binop(&oper)\r
+                               binary_expression(rank_of(oper)-1)\r
+                       ]?\r
+               ;\r
+       except that some call of 'unary' is necessary, depending on the\r
+       grammar.\r
+       \r
+       This simple view is marred by three complications:\r
+       1.      Level 15 (comma operator) is not allowed in many\r
+               contexts and is different.\r
+       2.      Level 13 (conditional operator) is a ternary operator,\r
+               which does not fit this scheme at all.\r
+       3.      Level 14 (assignment operators) group right-to-left, as\r
+               opposed to 2-12, which group left-to-right (or are\r
+               immaterial).\r
+       4.      The operators in level 14 start with operators in levels\r
+               2-13 (RM 7.14: The two parts of a compound assignment\r
+               operator are separate tokens.)  This causes LL1 problems.\r
+       This forces us to have four rules:\r
+               binary_expression       for level 2-12\r
+               conditional_expression  for level 13\r
+               assignment_expression   for level 14 and\r
+               expression              for the most general expression\r
+*/\r
+\r
+binary_expression(int maxrank; struct expr **expp;)\r
+       {int oper, OldResultKnown; struct expr *e1;}\r
+:\r
+       unary(expp)\r
+       [%while (rank_of(DOT) <= maxrank )\r
+               /*      '?', '=', and ',' are no binops\r
+                */\r
+               binop(&oper)\r
+               { OldResultKnown = ResultKnown;\r
+                 if (oper == OR || oper == AND) {\r
+                         if (is_cp_cst(*expp) || is_fp_cst(*expp)) {\r
+                                 if (is_zero_cst(*expp)) {\r
+                                         if (oper == AND) ResultKnown++;\r
+                                 } else if (oper == OR) ResultKnown++;\r
+                         }\r
+                 }\r
+               }\r
+               binary_expression(rank_of(oper)-1, &e1)\r
+               {\r
+                       ch3bin(expp, oper, e1);\r
+                       ResultKnown = OldResultKnown;\r
+               }\r
+       ]*\r
+;\r
+\r
+/* 3.3.15 */\r
+conditional_expression(struct expr **expp;)\r
+       {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}\r
+:\r
+       /* allow all binary operators */\r
+       binary_expression(rank_of('?') - 1, expp)\r
+       [       '?'\r
+               { OldResultKnown = ResultKnown;\r
+                 if (is_cp_cst(*expp) || is_fp_cst(*expp)) {\r
+                         ConstExpr++;\r
+                         if (is_zero_cst(*expp)) ResultKnown++;\r
+                 }\r
+               }\r
+               expression(&e1)\r
+               ':'\r
+               { if (ConstExpr) {\r
+                       if (OldResultKnown == ResultKnown) ResultKnown++;\r
+                       else ResultKnown = OldResultKnown;\r
+                 }\r
+               }\r
+               conditional_expression(&e2)\r
+               {       \r
+                       ResultKnown = OldResultKnown;\r
+                       ch3bin(&e1, ':', e2);\r
+                       opnd2test(expp, '?');\r
+                       ch3bin(expp, '?', e1);\r
+               }\r
+       ]?\r
+;\r
+\r
+/* 3.3.16 */\r
+assignment_expression(struct expr **expp;)\r
+       { int oper;\r
+         struct expr *e1 = 0;\r
+       }\r
+:\r
+       conditional_expression(expp)\r
+       [\r
+               asgnop(&oper)\r
+               assignment_expression(&e1)\r
+               {ch3asgn(expp, oper, e1);}\r
+       |\r
+               empty           /* LLgen artefact ??? */\r
+       ]\r
+;\r
+\r
+/* 3.3.17 */\r
+expression(struct expr **expp;)\r
+       {struct expr *e1;}\r
+:\r
+       assignment_expression(expp)\r
+       [       ','\r
+               assignment_expression(&e1)\r
+               {\r
+                       ch3bin(expp, ',', e1);\r
+               }\r
+       ]*\r
+;\r
+\r
+unop(int *oper;) :\r
+       ['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]\r
+       {   if (DOT == '&') DOT = ADDRESSOF;\r
+           *oper = DOT;\r
+       }\r
+;\r
+\r
+multop:\r
+       '*' | '/' | '%'\r
+;\r
+\r
+addop:\r
+       '+' | '-'\r
+;\r
+\r
+shiftop:\r
+       LEFT | RIGHT\r
+;\r
+\r
+relop:\r
+       '<' | '>' | LESSEQ | GREATEREQ\r
+;\r
+\r
+eqop:\r
+       EQUAL | NOTEQUAL\r
+;\r
+\r
+arithop:\r
+       multop | addop | shiftop\r
+|\r
+       '&' | '^' | '|'\r
+;\r
+\r
+binop(int *oper;) :\r
+       [ arithop | relop | eqop | AND | OR ]\r
+       {*oper = DOT;}\r
+;\r
+\r
+asgnop(register int *oper;):\r
+       [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB \r
+       | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]\r
+       { *oper = DOT; }\r
+\r
+;\r
+\r
+constant(struct expr **expp;) :\r
+[\r
+       INTEGER\r
+|\r
+       FLOATING\r
+]      {dot2expr(expp);}\r
+;\r
+\r
+/* 3.4 */\r
+constant_expression (struct expr **expp;) :\r
+       conditional_expression(expp)\r
+       { chk_cst_expr(expp); }\r
+;\r
+\r
+identifier(struct idf **idfp;) :\r
+[ IDENTIFIER\r
+| TYPE_IDENTIFIER\r
+]\r
+       { *idfp = dot.tk_idf; }\r
+;\r
index f5635d1..d1b014c 100644 (file)
 #include       "align.h"
 #include       "Lpars.h"
 #include       "field.h"
+#include    "util.h"
+#include    "conversion.h"
+#include    "eval.h"
+
 
-arith NewLocal();              /* util.c       */
 extern arith full_mask[];      /* cstoper.c    */
 
 /*     Eval_field() evaluates expressions involving bit fields.
@@ -39,9 +42,9 @@ extern arith full_mask[];     /* cstoper.c    */
        [3]     atype: the type in which the bitfield arithmetic is done;
                and in which bitfields are stored!
 */
-eval_field(expr, code)
-       struct expr *expr;
-       int code;
+void eval_field(
+       struct expr *expr,
+       int code)
 {
        int op = expr->OP_OPER;
        register struct expr *leftop = expr->OP_LEFT;
@@ -126,12 +129,12 @@ eval_field(expr, code)
        }
 }
 
-store_field(fd, uns, code, leftop, tmpvar)
-       register struct field *fd;
-       int uns;
-       int code;
-       register struct expr *leftop;
-       arith tmpvar;
+void store_field(
+       register struct field *fd,
+       int uns,
+       int code,
+       register struct expr *leftop,
+       arith tmpvar)
 {
        C_loc(fd->fd_mask);
        C_and(word_size);
index 7b4f219..2c8635c 100644 (file)
@@ -2,6 +2,11 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef FIELD_H_
+#define FIELD_H_
+
+#include "arith.h"
+
 /* $Id$ */
 /* FIELD DESCRIPTOR */
 
@@ -13,3 +18,20 @@ struct field {       /* for field specifiers */
 };
 
 /* ALLOCDEF "field" 10 */
+
+#ifndef        LINT
+
+
+#ifndef NOBITFIELD
+
+struct expr;
+
+void store_field(register struct field *fd, int uns, int code,
+               register struct expr *leftop, arith tmpvar);
+void eval_field(struct expr *expr, int code);
+
+#endif /* NOBITFIELD */
+
+#endif /* LINT */
+
+#endif /* FIELD_H_ */
\ No newline at end of file
index 7b48fc7..c33d7a2 100644 (file)
 #include       "parameters.h"
 #include       <alloc.h>
 #include       <flt_arith.h>
+#include    "fltcstoper.h"
 #include       "arith.h"
 #include       "type.h"
 #include       "label.h"
 #include       "expr.h"
 #include       "sizes.h"
 #include       "Lpars.h"
+#include    "error.h"
 
 extern int ResultKnown;
 extern char *symbol2str();
 
-fltcstbin(expp, oper, expr)
-       register struct expr **expp, *expr;
+void fltcstbin(register struct expr **expp, int oper, register struct expr *expr)
 {
        /*      The operation oper is performed on the constant
                expressions *expp(ld) and expr(ct), and the result restored in
diff --git a/lang/cem/cemcom.ansi/fltcstoper.h b/lang/cem/cemcom.ansi/fltcstoper.h
new file mode 100644 (file)
index 0000000..4b65618
--- /dev/null
@@ -0,0 +1,15 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-07
+ *  
+ */
+#ifndef FLTCSTOPER_H_
+#define FLTCSTOPER_H_
+
+struct expr;
+
+void fltcstbin(register struct expr **expp, int oper, register struct expr *expr);
+
+#endif /* FLTCSTOPER_H_ */
index 5472722..4d3f0fc 100644 (file)
 #include       "declar.h"
 #include       "decspecs.h"
 #include       "sizes.h"
+#include    "print.h"
+#include    "util.h"
+#include    "stab.h"
+#include    "code.h"
+#include    "error.h"
+#include    "ch3.h"
 #include       "Lpars.h"
 
 extern char options[];
@@ -37,91 +43,92 @@ extern char *symbol2str();
 
 #include <idf_pkg.body>
 
-void global_redecl();
 
-struct idf *
-gen_idf()
+
+struct idf *gen_idf(void)
 {
        /*      A new idf is created out of nowhere, to serve as an
-               anonymous name.
-       */
+        anonymous name.
+        */
        static int name_cnt;
        char *s = Malloc(strlen(dot.tk_file) + 50);
 
-       sprint(s, "#%d in %s, line %u",
-                       ++name_cnt, dot.tk_file, dot.tk_line);
-       s = Realloc(s, strlen(s)+1);
+       sprint(s, "#%d in %s, line %u", ++name_cnt, dot.tk_file, dot.tk_line);
+       s = Realloc(s, strlen(s) + 1);
        return str2idf(s, 0);
 }
 
-int
-is_anon_idf(idf)
-       struct idf *idf;
+int is_anon_idf(struct idf *idf)
 {
        return idf->id_text[0] == '#';
 }
 
-declare_idf(ds, dc, lvl)
-       struct decspecs *ds;
-       struct declarator *dc;
+void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl)
 {
        /*      The identifier inside dc is declared on the level lvl, with
-               properties deduced from the decspecs ds and the declarator
-               dc.
-               The level is given explicitly to be able to insert, e.g.,
-               labels on the outermost level inside the function.
-               This routine implements the rich semantics of C
-               declarations.
-       */
+        properties deduced from the decspecs ds and the declarator
+        dc.
+        The level is given explicitly to be able to insert, e.g.,
+        labels on the outermost level inside the function.
+        This routine implements the rich semantics of C
+        declarations.
+        */
        register struct idf *idf = dc->dc_idf;
        register int sc = ds->ds_sc;
-               /*      This local copy is essential:
-                               char b(), c;
-                       makes b GLOBAL and c AUTO.
-               */
-       register struct def *def = idf->id_def;         /* may be NULL */
+       /*      This local copy is essential:
+        char b(), c;
+        makes b GLOBAL and c AUTO.
+        */
+       register struct def *def = idf->id_def; /* may be NULL */
        register struct type *type;
        struct stack_level *stl = stack_level_of(lvl);
        char formal_array = 0;
-       
+
        /* determine the present type */
-       if (ds->ds_type == 0)   {
+       if (ds->ds_type == 0)
+       {
                /*      at the L_FORMAL1 level there is no type specified yet
-               */
+                */
                assert(lvl == L_FORMAL1);
-               type = int_type;        /* may change at L_FORMAL2 */
+               type = int_type; /* may change at L_FORMAL2 */
        }
-       else    {
+       else
+       {
                /* combine the decspecs and the declarator into one type */
                type = declare_type(ds->ds_type, dc);
-               if (type->tp_size <= (arith)0 &&
-                   actual_declaration(sc, type))       {
-                       if (type->tp_size == (arith) -1) {
+               if (type->tp_size <= (arith) 0 && actual_declaration(sc, type))
+               {
+                       if (type->tp_size == (arith) -1)
+                       {
                                /* the type is not yet known,
-                                  but it has to be:
-                               */
-                               if (type->tp_fund != VOID) {
-                                   if (level != L_GLOBAL)
-                                       error("unknown %s-type",
-                                               symbol2str(type->tp_fund));
-                               } else  error("void is not a complete type");
+                                but it has to be:
+                                */
+                               if (type->tp_fund != VOID)
+                               {
+                                       if (level != L_GLOBAL)
+                                               error("unknown %s-type", symbol2str(type->tp_fund));
+                               }
+                               else
+                                       error("void is not a complete type");
                        }
-                       else strict("%s has size 0", idf->id_text);
+                       else
+                               strict("%s has size 0", idf->id_text);
                }
        }
 
        /* some additional work for formal definitions */
-       if (lvl == L_FORMAL2)   {
-               switch (type->tp_fund)  {
+       if (lvl == L_FORMAL2)
+       {
+               switch (type->tp_fund)
+               {
                case FUNCTION:
-                       warning("%s is a function; cannot be formal",
-                               idf->id_text);
-                       type = construct_type(POINTER, type, 0, (arith)0,
-                                             NO_PROTO);
+                       warning("%s is a function; cannot be formal", idf->id_text);
+                       type = construct_type(POINTER, type, 0, (arith) 0,
+                       NO_PROTO);
                        break;
-               case ARRAY:     /* 3.7.1 */
-                       type = construct_type(POINTER, type->tp_up, 0, (arith)0,
-                                             NO_PROTO);
+               case ARRAY: /* 3.7.1 */
+                       type = construct_type(POINTER, type->tp_up, 0, (arith) 0,
+                       NO_PROTO);
                        formal_array = 1;
                        break;
                case FLOAT:
@@ -135,72 +142,77 @@ declare_idf(ds, dc, lvl)
                }
        }
        /*      The tests on types, postponed from do_decspecs(), can now
-               be performed.
-       */
+        be performed.
+        */
        /* update the storage class */
-       if (type && type->tp_fund == FUNCTION)  {
-               if (lvl != L_GLOBAL)  {         /* 3.5.1 */
+       if (type && type->tp_fund == FUNCTION)
+       {
+               if (lvl != L_GLOBAL)
+               { /* 3.5.1 */
                        if (sc == 0)
                                sc = GLOBAL;
-                       else if (sc != EXTERN && sc != TYPEDEF) {
-                               error("illegal storage class %s for function with block-scope"
-                                       , symbol2str(sc));
+                       else if (sc != EXTERN && sc != TYPEDEF)
+                       {
+                               error("illegal storage class %s for function with block-scope",
+                                               symbol2str(sc));
                                ds->ds_sc = sc = EXTERN;
                        }
                }
                else if (sc == 0)
                        sc = GLOBAL;
        }
-       else    /* non-FUNCTION */
-               if (sc == 0)
-                       sc =    lvl == L_GLOBAL ? GLOBAL
-                               : lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
-                               : AUTO;
+       else /* non-FUNCTION */
+       if (sc == 0)
+               sc = lvl == L_GLOBAL ? GLOBAL :
+                               lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL : AUTO;
 
 #ifdef LINT
-       check_hiding(idf, lvl, sc);     /* of some idf by this idf */
+       check_hiding(idf, lvl, sc); /* of some idf by this idf */
 #endif /* LINT */
-       if (def && lvl == L_LOCAL && def->df_level == L_FORMAL2) {
+       if (def && lvl == L_LOCAL && def->df_level == L_FORMAL2)
+       {
                error("%s redeclared", idf->id_text);
        }
 
-       if (def && 
-           ( def->df_level == lvl ||
-             ( lvl != L_GLOBAL && def->df_level > lvl ) ||
-             (lvl == L_GLOBAL
-              && def->df_level == L_PROTO
-              && def->next && def->next->df_level == L_GLOBAL)
-          ))   {
+       if (def
+                       && (def->df_level == lvl || (lvl != L_GLOBAL && def->df_level > lvl)
+                                       || (lvl == L_GLOBAL && def->df_level == L_PROTO && def->next
+                                                       && def->next->df_level == L_GLOBAL)))
+       {
                /*      There is already a declaration for idf on this
-                       level, or even more inside.
-                       The rules differ for different levels.
-               */
-               switch (lvl)    {
+                level, or even more inside.
+                The rules differ for different levels.
+                */
+               switch (lvl)
+               {
                case L_GLOBAL:
                        global_redecl(idf, sc, type);
                        def->df_file = idf->id_file;
                        def->df_line = idf->id_line;
                        break;
-               case L_FORMAL1: /* formal declaration */
+               case L_FORMAL1: /* formal declaration */
                        error("formal %s redeclared", idf->id_text);
                        break;
-               case L_FORMAL2: /* formal definition */
-               default:        /* local */
-                       if (sc != EXTERN) error("%s redeclared", idf->id_text);
+               case L_FORMAL2: /* formal definition */
+               default: /* local */
+                       if (sc != EXTERN)
+                               error("%s redeclared", idf->id_text);
                        break;
                }
        }
-       else    /* the idf is unknown on this level */
-       if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf))    {
+       else /* the idf is unknown on this level */
+       if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf))
+       {
                /* formal declaration, update only */
                def->df_type = type;
                def->df_formal_array = formal_array;
                def->df_sc = sc;
-               def->df_level = L_FORMAL2;      /* CJ */
+               def->df_level = L_FORMAL2; /* CJ */
                def->df_file = idf->id_file;
                def->df_line = idf->id_line;
        }
-       else    { /* fill in the def block */
+       else
+       { /* fill in the def block */
                register struct def *newdef = new_def();
 
                newdef->next = def;
@@ -218,28 +230,27 @@ declare_idf(ds, dc, lvl)
                update_ahead(idf);
                stack_idf(idf, stl);
                /*      We now calculate the address.
-                       Globals have names and don't get addresses, they
-                       get numbers instead (through data_label()).
-                       Formals are handled by declare_formals().
-                       So here we hand out local addresses only.
-               */
-               if (lvl >= L_LOCAL)     {
+                Globals have names and don't get addresses, they
+                get numbers instead (through data_label()).
+                Formals are handled by declare_formals().
+                So here we hand out local addresses only.
+                */
+               if (lvl >= L_LOCAL)
+               {
                        assert(sc);
-                       switch (sc)     {
+                       switch (sc)
+                       {
                        case REGISTER:
                        case AUTO:
-                               if (type->tp_size == (arith)-1
-                                       && type->tp_fund != ARRAY) {
-                                       error("size of local %s unknown",
-                                               idf->id_text);
-                               /** type = idf->id_def->df_type = int_type; **/
+                               if (type->tp_size == (arith) -1 && type->tp_fund != ARRAY)
+                               {
+                                       error("size of local %s unknown", idf->id_text);
+                                       /** type = idf->id_def->df_type = int_type; **/
                                }
-                               if (type->tp_size != (arith) -1) {
-                                   newdef->df_address =
-                                       NewLocal(type->tp_size,
-                                                type->tp_align,
-                                                regtype(type),
-                                                sc);
+                               if (type->tp_size != (arith) -1)
+                               {
+                                       newdef->df_address = NewLocal(type->tp_size, type->tp_align,
+                                                       regtype(type), sc);
                                }
                                break;
                        case STATIC:
@@ -250,21 +261,19 @@ declare_idf(ds, dc, lvl)
        }
 }
 
-int
-actual_declaration(sc, tp)
-       int sc;
-       struct type *tp;
+int actual_declaration(int sc, struct type *tp)
 {
        /*      An actual_declaration needs space, right here and now.
-       */
+        */
        register int fund = tp->tp_fund;
-       
+
        if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */
                return 0;
        if (fund == FUNCTION || fund == ARRAY)
                /* allocation solved in other ways */
                return 0;
-       if (sc == EXTERN && fund == VOID) {
+       if (sc == EXTERN && fund == VOID)
+       {
                /* strange, but should be accepted */
                return 0;
        }
@@ -272,51 +281,59 @@ actual_declaration(sc, tp)
        return 1;
 }
 
-void
-global_redecl(idf, new_sc, tp)
-       register struct idf *idf;
-       struct type *tp;
+void global_redecl(register struct idf *idf, int new_sc, struct type *tp)
 {
        /*      A global identifier may be declared several times,
-               provided the declarations do not conflict; they might
-               conflict in type (or supplement each other in the case of
-               an array) or they might conflict or supplement each other
-               in storage class.
-       */
+        provided the declarations do not conflict; they might
+        conflict in type (or supplement each other in the case of
+        an array) or they might conflict or supplement each other
+        in storage class.
+        */
        register struct def *def = idf->id_def;
 
-       while (def->df_level != L_GLOBAL) def = def->next;
-       if (!equal_type(tp, def->df_type, 0, 1)) {
+       while (def->df_level != L_GLOBAL)
+               def = def->next;
+       if (!equal_type(tp, def->df_type, 0, 1))
+       {
                error("redeclaration of %s with different type", idf->id_text);
                return;
-       } else  update_proto(tp, def->df_type);
-       if (tp->tp_fund == ARRAY) {
+       }
+       else
+               update_proto(tp, def->df_type);
+       if (tp->tp_fund == ARRAY)
+       {
                /* Multiple array declaration; this may be interesting */
-               if (tp->tp_size < 0)    {               /* new decl has [] */
+               if (tp->tp_size < 0)
+               { /* new decl has [] */
                        /* nothing new */
-               } else
-               if (def->df_type->tp_size < 0)  {       /* old decl has [] */
+               }
+               else if (def->df_type->tp_size < 0)
+               { /* old decl has [] */
                        def->df_type = tp;
                }
-       } if (tp->tp_fund == FUNCTION && new_sc == GLOBAL) {
+       }
+       if (tp->tp_fund == FUNCTION && new_sc == GLOBAL)
+       {
                /* see 3.1.2.2 */
                new_sc = EXTERN;
        }
 
        /*      Now we may be able to update the storage class.
-               Clean out this mess as soon as we know all the possibilities
-               for new_sc.
-               For now we have:
-                       EXTERN:         we have seen the word "extern"
-                       GLOBAL:         the item was declared on the outer
-                                       level, without either "extern" or
-                                       "static".
-                       STATIC:         we have seen the word "static"
-       */
-
-       switch (def->df_sc)     {       /* the old storage class */
+        Clean out this mess as soon as we know all the possibilities
+        for new_sc.
+        For now we have:
+        EXTERN:                we have seen the word "extern"
+        GLOBAL:                the item was declared on the outer
+        level, without either "extern" or
+        "static".
+        STATIC:                we have seen the word "static"
+        */
+
+       switch (def->df_sc)
+       { /* the old storage class */
        case EXTERN:
-               switch (new_sc) {       /* the new storage class */
+               switch (new_sc)
+               { /* the new storage class */
                case STATIC:
                        warning("%s redeclared static", idf->id_text);
                        /* fallthrough */
@@ -331,8 +348,9 @@ global_redecl(idf, new_sc, tp)
                }
                break;
        case GLOBAL:
-               switch (new_sc) {       /* the new storage class */
-               case STATIC:            /* linkage disagreement */
+               switch (new_sc)
+               { /* the new storage class */
+               case STATIC: /* linkage disagreement */
                        warning("%s redeclared static", idf->id_text);
                        def->df_sc = new_sc;
                        /* fallthrough */
@@ -345,8 +363,9 @@ global_redecl(idf, new_sc, tp)
                }
                break;
        case STATIC:
-               switch (new_sc) {       /* the new storage class */
-               case GLOBAL:            /* linkage disagreement */
+               switch (new_sc)
+               { /* the new storage class */
+               case GLOBAL: /* linkage disagreement */
                case EXTERN:
                        warning("%s is already declared static", idf->id_text);
                        /* fallthrough */
@@ -367,142 +386,147 @@ global_redecl(idf, new_sc, tp)
        }
 }
 
-int
-good_formal(def, idf)
-       register struct def *def;
-       register struct idf *idf;
+int good_formal(register struct def *def, register struct idf *idf)
 {
        /*      Succeeds if def is a proper L_FORMAL1 definition and
-               gives an error message otherwise.
-       */
-       if (!def || def->df_level != L_FORMAL1) { /* not in parameter list */
+        gives an error message otherwise.
+        */
+       if (!def || def->df_level != L_FORMAL1)
+       { /* not in parameter list */
                if (!is_anon_idf(idf))
                        error("%s not in parameter list", idf->id_text);
                return 0;
        }
-       assert(def->df_sc == FORMAL);   /* CJ */
+       assert(def->df_sc == FORMAL); /* CJ */
        return 1;
 }
 
-declare_params(dc)
-       struct declarator *dc;
+void declare_params(struct declarator *dc)
 {
        /*      Declares the formal parameters if they exist.
-       */
+        */
        register struct formal *fm = dc->dc_formal;
 
-       while (fm)      {
+       while (fm)
+       {
                declare_parameter(fm->fm_idf);
                fm = fm->next;
        }
 }
 
-void
-idf_initialized(idf)
-       register struct idf *idf;
+void idf_initialized(register struct idf *idf)
 {
        /*      The topmost definition of idf is set to initialized.
-       */
-       register struct def *def = idf->id_def; /* the topmost */
-       
-       while (def->df_level <= L_PROTO) def = def->next;
+        */
+       register struct def *def = idf->id_def; /* the topmost */
+
+       while (def->df_level <= L_PROTO)
+               def = def->next;
        if (def->df_initialized)
                error("multiple initialization of %s", idf->id_text);
-       if (def->df_sc == TYPEDEF)      {
+       if (def->df_sc == TYPEDEF)
+       {
                error("typedef cannot be initialized");
                return;
        }
        def->df_initialized = 1;
 }
 
-declare_parameter(idf)
-       struct idf *idf;
+void declare_parameter(struct idf *idf)
 {
        /*      idf is declared as a formal.
-       */
+        */
        add_def(idf, FORMAL, int_type, level);
 }
 
-declare_enum(tp, idf, l)
-       struct type *tp;
-       struct idf *idf;
-       arith l;
+void declare_enum(struct type *tp, struct idf *idf, arith l)
 {
        /*      idf is declared as an enum constant with value l.
-       */
+        */
        add_def(idf, ENUM, tp, level);
        idf->id_def->df_address = l;
 }
 
-void
-check_formals(idf, dc)
-       struct idf *idf;
-       struct declarator *dc;
+void check_formals(struct idf *idf, struct declarator *dc)
 {
        register struct formal *fm = dc->dc_formal;
        register struct proto *pl = idf->id_def->df_type->tp_proto;
        register struct decl_unary *du = dc->dc_decl_unary;
 
-       if (!du) {      /* error or typdef'ed function */
+       if (!du)
+       { /* error or typdef'ed function */
                error("illegal definition of %s", idf->id_text);
                return;
        }
 
        while (du
-               && (du->du_fund != FUNCTION
-                   || du->next != (struct decl_unary *) 0)) {
+                       && (du->du_fund != FUNCTION || du->next != (struct decl_unary *) 0))
+       {
                du = du->next;
        }
-       if (!du) return;        /* terrible error, signalled earlier */
+       if (!du)
+               return; /* terrible error, signalled earlier */
 
-       if (du->du_proto) return;
+       if (du->du_proto)
+               return;
 
-       if (pl) {
+       if (pl)
+       {
                /* Don't give a warning about an old-style definition,
                 * since the arguments will be checked anyway.
                 */
-               if (pl->pl_flag & PL_ELLIPSIS) {
-                   if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN))
-                       error("ellipsis terminator in previous declaration");
-                   pl = pl->next;
+               if (pl->pl_flag & PL_ELLIPSIS)
+               {
+                       if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN))
+                               error("ellipsis terminator in previous declaration");
+                       pl = pl->next;
                }
-               else if (pl->pl_flag & PL_VOID) {
-                   pl = pl->next;                      /* should be 0 */
+               else if (pl->pl_flag & PL_VOID)
+               {
+                       pl = pl->next; /* should be 0 */
                }
-               while(fm && pl) {
-                   if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type)
-                                       , pl->pl_type, -1, 1)) {
-                       if (!(pl->pl_flag & PL_ERRGIVEN))
-                           error("incorrect type for parameter %s"
-                                               , fm->fm_idf->id_text);
-                       pl->pl_flag |= PL_ERRGIVEN;
-                   }
-                   fm = fm->next;
-                   pl = pl->next;
+               while (fm && pl)
+               {
+                       if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type),
+                                       pl->pl_type, -1, 1))
+                       {
+                               if (!(pl->pl_flag & PL_ERRGIVEN))
+                                       error("incorrect type for parameter %s",
+                                                       fm->fm_idf->id_text);
+                               pl->pl_flag |= PL_ERRGIVEN;
+                       }
+                       fm = fm->next;
+                       pl = pl->next;
                }
-               if (pl || fm) {
+               if (pl || fm)
+               {
                        error("incorrect number of parameters");
                }
-       } else {                        /* make a pseudo-prototype */
+       }
+       else
+       { /* make a pseudo-prototype */
                register struct proto *lpl = new_proto();
 
                if (!options['o'])
-                       warning("'%s' old-fashioned function definition"
-                                       , dc->dc_idf->id_text);
-
-               while (fm) {
-                       if (pl == 0) pl = lpl;
-                       else {
+                       warning("'%s' old-fashioned function definition",
+                                       dc->dc_idf->id_text);
+
+               while (fm)
+               {
+                       if (pl == 0)
+                               pl = lpl;
+                       else
+                       {
                                lpl->next = new_proto();
                                lpl = lpl->next;
                        }
                        lpl->pl_flag = PL_FORMAL;
                        lpl->pl_idf = fm->fm_idf;
-                       lpl->pl_type =
-                                   promoted_type(fm->fm_idf->id_def->df_type);
+                       lpl->pl_type = promoted_type(fm->fm_idf->id_def->df_type);
                        fm = fm->next;
                }
-               if (pl == 0) {          /* make func(void) */
+               if (pl == 0)
+               { /* make func(void) */
                        pl = lpl;
                        pl->pl_type = void_type;
                        pl->pl_flag = PL_FORMAL | PL_VOID;
@@ -513,26 +537,26 @@ check_formals(idf, dc)
        dc->dc_formal = 0;
 }
 
-declare_formals(idf, fp)
-       struct idf *idf;
-       arith *fp;
+void declare_formals(struct idf *idf, arith *fp)
 {
        /*      Declares those formals as int that haven't been declared
-               by the user.
-               An address is assigned to each formal parameter.
-               The total size of the formals is returned in *fp;
-       */
+        by the user.
+        An address is assigned to each formal parameter.
+        The total size of the formals is returned in *fp;
+        */
        register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
-       arith f_offset = (arith)0;
+       arith f_offset = (arith) 0;
        register int nparams = 0;
        int hasproto;
        struct def *df = idf->id_def;
 
        /* When one of the formals has the same name as the function, 
-          it hides the function def. Get it.
-       */
-       while (se) {
-               if (se->se_idf == idf) {
+        it hides the function def. Get it.
+        */
+       while (se)
+       {
+               if (se->se_idf == idf)
+               {
                        df = df->next;
                        break;
                }
@@ -540,49 +564,53 @@ declare_formals(idf, fp)
        }
 
        se = stack_level_of(L_FORMAL1)->sl_entry;
-       
+
        hasproto = df->df_type->tp_proto != 0;
 
 #ifdef DEBUG
        if (options['t'])
-               dumpidftab("start declare_formals", 0);
+       dumpidftab("start declare_formals", 0);
 #endif /* DEBUG */
-       if (is_struct_or_union(df->df_type->tp_up->tp_fund)) {
+       if (is_struct_or_union(df->df_type->tp_up->tp_fund))
+       {
                /* create space for address of return value */
                f_offset = pointer_size;
        }
-       while (se)      {
+       while (se)
+       {
                df = se->se_idf->id_def;
-               
+
                /* this stacklevel may also contain tags. ignore them */
-               if (!df || df->df_level < L_FORMAL1 ) {
+               if (!df || df->df_level < L_FORMAL1)
+               {
                        se = se->next;
                        continue;
                }
 
                df->df_address = f_offset;
                /*      the alignment convention for parameters is: align on
-                       word boundaries, i.e. take care that the following
-                       parameter starts on a new word boundary.
-               */
-               if (! hasproto 
-                   && df->df_type->tp_fund == FLOAT
-                   && df->df_type->tp_size != double_size) {
+                word boundaries, i.e. take care that the following
+                parameter starts on a new word boundary.
+                */
+               if (!hasproto && df->df_type->tp_fund == FLOAT
+                               && df->df_type->tp_size != double_size)
+               {
                        f_offset = align(f_offset + double_size, (int) word_size);
                }
-               else f_offset = align(f_offset + df->df_type->tp_size, (int) word_size);
+               else
+                       f_offset = align(f_offset + df->df_type->tp_size, (int) word_size);
                RegisterAccount(df->df_address, df->df_type->tp_size,
-                               regtype(df->df_type),
-                               df->df_sc);
+                               regtype(df->df_type), df->df_sc);
                /* cvt int to char or short and double to float, if necessary
                 */
                formal_cvt(hasproto, df);
 
-               df->df_level = L_FORMAL2;       /* CJ */
+               df->df_level = L_FORMAL2; /* CJ */
                if (nparams++ >= STDC_NPARAMS)
                        strict("number of formal parameters exceeds ANSI limit");
 #ifdef DBSYMTAB
-               if (options['g']) {
+               if (options['g'])
+               {
                        stb_string(df, FORMAL, se->se_idf->id_text);
                }
 #endif /* DBSYMTAB */
@@ -591,11 +619,10 @@ declare_formals(idf, fp)
        *fp = f_offset;
 }
 
-int
-regtype(tp)
-       struct type *tp;
+int regtype(struct type *tp)
 {
-       switch(tp->tp_fund) {
+       switch (tp->tp_fund)
+       {
        case INT:
        case LONG:
                return reg_any;
@@ -609,18 +636,15 @@ regtype(tp)
        return -1;
 }
 
-add_def(idf, sc, tp, lvl)
-       struct idf *idf;
-       struct type *tp;
-       int lvl;
-       int sc;
+void add_def(struct idf *idf, int sc, struct type *tp, int lvl)
 {
        /*      The identifier idf is declared on level lvl with storage
-               class sc and type tp, through a faked C declaration.
-               This is probably the wrong way to structure the problem,
-               but it will have to do for the time being.
-       */
-       struct decspecs Ds; struct declarator Dc;
+        class sc and type tp, through a faked C declaration.
+        This is probably the wrong way to structure the problem,
+        but it will have to do for the time being.
+        */
+       struct decspecs Ds;
+       struct declarator Dc;
 
        Ds = null_decspecs;
        Ds.ds_type = tp;
@@ -630,25 +654,24 @@ add_def(idf, sc, tp, lvl)
        declare_idf(&Ds, &Dc, lvl);
 }
 
-update_ahead(idf)
-       register struct idf *idf;
+void update_ahead(register struct idf *idf)
 {
        /*      The tk_symb of the token ahead is updated in the light of new
-               information about the identifier idf.
-       */
+        information about the identifier idf.
+        */
        register int tk_symb = AHEAD;
 
-       if (    (tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER) &&
-               ahead.tk_idf == idf
-       )
+       if ((tk_symb == IDENTIFIER || tk_symb == TYPE_IDENTIFIER)
+                       && ahead.tk_idf == idf)
                AHEAD = idf->id_def && idf->id_def->df_sc == TYPEDEF ?
-                               TYPE_IDENTIFIER : IDENTIFIER;
+               TYPE_IDENTIFIER :
+                                                                                                                               IDENTIFIER;
 }
 
-free_formals(fm)
-       register struct formal *fm;
+void free_formals(register struct formal *fm)
 {
-       while (fm)      {
+       while (fm)
+       {
                struct formal *tmp = fm->next;
 
                free_formal(fm);
index 06caa7f..d26ebfe 100644 (file)
@@ -2,10 +2,15 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef IDF_H_
+#define IDF_H_
+
 /* $Id$ */
 /* IDENTIFIER DESCRIPTOR */
 
 #include       "parameters.h"
+#include    "arith.h"
 
 struct id_u {
        int idd_reserved;       /* non-zero for reserved words          */
@@ -33,4 +38,28 @@ struct id_u {
 #include <idf_pkg.spec>
 
 extern int level;
-extern struct idf *gen_idf();
+
+struct decspecs;
+struct declarator;
+struct type;
+struct formal;
+
+
+struct idf *gen_idf(void);
+int is_anon_idf(struct idf *idf);
+void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl);
+int actual_declaration(int sc, struct type *tp);
+void global_redecl(register struct idf *idf, int new_sc, struct type *tp);
+int good_formal(register struct def *def, register struct idf *idf);
+void declare_params(struct declarator *dc);
+void idf_initialized(register struct idf *idf);
+void declare_parameter(struct idf *idf);
+void declare_enum(struct type *tp, struct idf *idf, arith l);
+void check_formals(struct idf *idf, struct declarator *dc);
+void declare_formals(struct idf *idf, arith *fp);
+int regtype(struct type *tp);
+void add_def(struct idf *idf, int sc, struct type *tp, int lvl);
+void update_ahead(register struct idf *idf);
+void free_formals(register struct formal *fm);
+
+#endif
\ No newline at end of file
index dea9a48..e5d019b 100644 (file)
@@ -10,6 +10,7 @@
 #include <string.h>
 #include "file_info.h"
 #include "input.h"
+#include "error.h"
 
 #define INP_PUSHBACK   3
 #define INP_TYPE       struct file_info
@@ -20,14 +21,14 @@ struct file_info    finfo;
 
 int    NoUnstack;
 
-AtEoIT()
+int AtEoIT(void)
 {
        return 0;
 }
 
 extern char *source;
 
-AtEoIF()
+int AtEoIF(void)
 {
        if (NoUnstack) lexerror("unexpected EOF");
        return 0;
index 972eaf2..4ffbe0f 100644 (file)
@@ -12,4 +12,4 @@
 #define UnGetChar()    ((LexSave != EOI) ? ChPushBack(LexSave) : 0)
 
 extern int LexSave;    /* last character read by GetChar               */
-extern         int GetChar();  /* character input, with trigraph parsing       */
+
index e867aad..80c6d1d 100644 (file)
-/*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
-/* $Id$ */
-/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */
-
-{
-#include       <assert.h>
-#include    <stdlib.h>
-#include       "parameters.h"
-#ifndef        LINT
-#include       <em.h>
-#else
-#include       "l_em.h"
-#include       "l_lint.h"
-#endif /* LINT */
-#include       <ack_string.h>
-#include       <alloc.h>
-#include       <assert.h>
-#include       <flt_arith.h>
-#include    "idf.h"
-#include       "arith.h"
-#include       "label.h"
-#include       "expr.h"
-#include       "type.h"
-#include       "proto.h"
-#include       "struct.h"
-#include       "field.h"
-#include       "Lpars.h"
-#include       "sizes.h"
-#include       "align.h"
-#include       "level.h"
-#include       "def.h"
-#include       "LLlex.h"
-#include       "estack.h"
-#include    "stack.h"
-
-#define con_nullbyte() C_con_ucon("0", (arith)1)
-#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)
-
-char *strncpy();
-extern char options[];
-static int gen_error;
-static int pack_level;
-struct type **gen_tphead(), **gen_tpmiddle();
-struct sdef *gen_align_to_next();
-struct e_stack *p_stack;
-
-void pad();
-void gen_simple_exp();
-void gen_tpcheck();
-
-}
-
-/* initial_value recursively guides the initialisation expression.
- */
-/* 3.5 */
-
-initial_value(register struct type **tpp; register struct expr **expp;) :
-       { if (tpp) gen_tpcheck(tpp); }
-[
-               { if (pack_level == 0) gen_error = 0; }
-       assignment_expression(expp)
-               {
-#ifdef LINT
-                       lint_expr(*expp, USED);
-#endif /* LINT */
-                       if ((*expp)->ex_type->tp_fund == ARRAY)
-                               array2pointer(*expp);
-                       if (tpp) {
-                               if (level >= L_LOCAL
-                                   || is_ld_cst(*expp)
-                                   || is_fp_cst(*expp)
-                                   || (*expp)->ex_class == String) {
-                                       gen_simple_exp(tpp, expp);
-                                       free_expression(*expp);
-                                       *expp = 0;
-                               } else {
-                                       expr_error(*expp,"illegal initialization");
-                                       free_expression(*expp);
-                                       *expp = 0;
-                               }
-                       }
-               }
-|
-       initial_value_pack(tpp, expp)
-]
-;
-
-initial_value_pack(struct type **tpp; struct expr **expp;)
-:
-       '{'
-                       { if (pack_level == 0) gen_error = 0; pack_level++; }
-       initial_value_list(tpp, expp)
-                       { pack_level--;
-                         if (!pack_level) {
-                               while (p_stack) {
-                                       struct e_stack *p = p_stack->next;
-
-                                       free_e_stack(p_stack);
-                                       p_stack = p;
-                               }
-                         }
-                         if (pack_level < gen_error) gen_error = 0;
-                       }
-       '}'
-;
-
-initial_value_list(register struct type **tpp; struct expr **expp;)
-       { struct expr *e1;
-         register struct type **tpp2 = 0;
-         int err_flag = gen_error;
-       }
-:
-                       { 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 && ! err_flag) gen_tpend(); }
-       ','?                            /* optional trailing comma */
-;
-
-{
-void
-gen_tpcheck(tpp)
-       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 = pack_level;
-               break;
-       case STRUCT:
-               if (! valid_type(tp, "struct"))
-                       gen_error = pack_level;
-               break;
-       case UNION:
-               if (! valid_type(tp, "union"))
-                       gen_error = pack_level;
-               break;
-       case ERRONEOUS:
-               if (! gen_error) gen_error = pack_level;
-               break;
-       }
-}
-
-void
-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 UNION:
-       case STRUCT:
-               check_and_pad(expp, tpp);
-               break;
-       case ERRONEOUS:
-       case FUNCTION:
-       case VOID:
-               gen_error = pack_level;
-               break;
-       default:
-               check_ival(expp, tp);
-               break;
-       }
-}
-
-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) && tp->tp_up->tp_fund != UNION))
-               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);
-       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;
-       register struct sdef *sd;
-
-       if (tpp && *tpp == error_type) {
-               gen_error = pack_level;
-               return 0;
-       }
-       if (gen_error) return tpp;
-       if (tp->tp_fund == UNION) {
-               /* Here, we saw a {, which could be the start of a union
-                  initializer. It could, however, also be the start of the
-                  initializer for the first union field ...
-               */
-               sd = tp->tp_sdef;
-               if (AHEAD != '{' &&
-                   (aggregate_type(sd->sd_type) || 
-                    sd->sd_type->tp_fund == UNION)) {
-                       /* In this case, assume that it is the start of the
-                          initializer of the union field, so:
-                       */
-                       return gen_tphead(&(tp->tp_sdef->sd_type), nest);
-               }
-       }
-       p = new_e_stack();
-       p->next = p_stack;
-       p_stack = p;
-       p->s_nested = nest;
-       p->s_tpp = tpp;
-       switch(tp->tp_fund) {
-       case UNION:
-               p->s_def = sd = tp->tp_sdef;
-               p->bytes_upto_here = 0;
-               return &(sd->sd_type);
-       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
-               if (! sd) {
-                       /* something wrong with this struct */
-                       gen_error = pack_level;
-                       p_stack = p->next;
-                       free_e_stack(p);
-                       return 0;
-               }
-               p->s_def = sd;
-               if (AHEAD != '{' && aggregate_type(sd->sd_type)) {
-                       return gen_tphead(&(sd->sd_type), 1);
-               }
-               return &(sd->sd_type);
-       case ERRONEOUS:
-               if (! gen_error) gen_error = pack_level;
-               /* fall through */
-       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) {
-               if (p) return p->s_tpp;
-               return 0;
-       }
-again:
-       tp = *(p->s_tpp);
-       switch(tp->tp_fund) {
-       case ERRONEOUS:
-               if (! gen_error) gen_error = pack_level;
-               return p->s_tpp;
-       case UNION:
-               sd = p->s_def;
-               p->bytes_upto_here +=
-                       size_of_type(sd->sd_type, "selector");
-               return p->s_tpp;
-       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 && p) {
-           if (!gen_error) {
-               tp = *(p->s_tpp);
-               switch(tp->tp_fund) {
-               case UNION:
-                       sd = p->s_def;
-                       p->bytes_upto_here +=
-                               size_of_type(sd->sd_type, "selector");
-                       while (p->bytes_upto_here++ < tp->tp_size)
-                               con_nullbyte();
-                       break;
-               case ARRAY:
-                       if (tp->tp_size == -1) {
-                               *(p->s_tpp) = construct_type(ARRAY, tp->tp_up,
-                                       0, p->elem_count, NO_PROTO);
-                       }
-                       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;
-       }
-}
-
-/*     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;
-{
-       register struct type *tp = *tpp;
-
-       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,
-                                       0, (arith)1, NO_PROTO);
-               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 if (tp->tp_fund == UNION) {
-               /* only the first selector can be initialized */
-               register struct sdef *sd = tp->tp_sdef;
-
-               check_and_pad(expp, &(sd->sd_type));
-       }
-       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.
-*/
-void
-pad(tpx)
-       struct type *tpx;
-{
-       register struct type *tp = tpx;
-       register arith sz = tp->tp_size;
-
-       gen_tpcheck(&tpx);
-       if (gen_error) return;
-#ifndef NOBITFIELD
-       if (tp->tp_fund == FIELD) {
-               put_bf(tp, (arith)0);
-               return;
-       }
-#endif /* NOBITFIELD */
-
-       if (tp->tp_align >= word_align) 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 ch3cast 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:
-               ch3cast(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
-                           && idf->id_def->df_sc != GLOBAL
-                           && idf->id_def->df_sc != EXTERN) {
-                               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;
-       case FLOAT:
-       case DOUBLE:
-       case LNGDBL:
-               ch3cast(expp, '=', tp);
-               expr = *expp;
-#ifdef DEBUG
-               print_expr("init-expr after cast", expr);
-#endif /* DEBUG */
-               if (expr->ex_class == Float) {
-                       char buf[FLT_STRLEN];
-
-                       flt_flt2str(&(expr->FL_ARITH), buf, FLT_STRLEN);
-                       C_con_fcon(buf, expr->ex_type->tp_size);
-               }
-#ifdef NOTDEF
-
-Coercion from int to float is now always done compile time.
-This, to accept declarations like
-double x = -(double)1;
-and also to prevent runtime coercions for compile-time constants.
-
-               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);
-               }
-#endif /* NOTDEF */
-               else
-                       illegal_init_cst(expr);
-               break;
-
-#ifndef NOBITFIELD
-       case FIELD:
-               ch3cast(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:
-               if (! gen_error) gen_error = pack_level;
-               /* fall through */
-       case VOID:
-               break;
-       default:
-               crash("check_ival");
-               /*NOTREACHED*/
-       }
-}
-
-/*     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 int length = ex->SG_LEN, i;
-       register char *to, *from, *s;
-
-       assert(ex->ex_class == String);
-       if (tp->tp_size == (arith)-1) {
-               /* set the dimension    */
-               tp = *tpp = construct_type(ARRAY, tp->tp_up, 0, (arith)length, NO_PROTO);
-       }
-       else {
-               arith dim = tp->tp_size / tp->tp_up->tp_size;
-
-#ifdef LINT
-               if (length == dim + 1) {
-                           expr_warning(ex, "array is not null-terminated");
-               } else
-#endif
-               if (length > dim + 1) {
-                       expr_strict(ex, "too many initializers");
-               }
-               length = dim;
-       }
-       /* throw out the characters of the already prepared string      */
-       s = Malloc((unsigned) (length));
-       clear(s, (unsigned)length);
-       i = length <= ex->SG_LEN ? length : ex->SG_LEN;
-       to = s; from = ex->SG_VALUE;
-       while(--i >= 0) {
-               *to++ = *from++;
-       }
-       free(ex->SG_VALUE);
-       str_cst(s, length, 0);          /* a string, but not in rom */
-       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, inrom)
-       register char *str;
-       register int len;
-       int inrom;
-{
-       int chunksize = ((127 + (int) word_size) / (int) word_size) * (int) word_size;
-
-       while (len > chunksize) {
-               if (inrom)
-                       C_rom_scon(str, (arith) chunksize);
-               else    C_con_scon(str, (arith) chunksize);
-               len -= chunksize;
-               str += chunksize;
-       }
-       if (inrom)
-               C_rom_scon(str, (arith) len);
-       else    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");
-       int count = n;
-
-       while (n-- > 0)
-               con_nullbyte();
-       return count;
-}
-
-int
-valid_type(tp, str)
-       struct type *tp;
-       char *str;
-{
-       assert(tp!=(struct type *)0);
-       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 if (tp->tp_size == word_size)
-               C_con_cst(ex->VL_VALUE);
-       else
-               C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);
-}
-
-illegal_init_cst(ex)
-       struct expr *ex;
-{
-       expr_error(ex, "illegal initialization constant");
-       gen_error = pack_level;
-}
-
-too_many_initialisers()
-{
-       error("too many initializers");
-       gen_error = pack_level;
-}
-}
+/*\r
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.\r
+ * See the copyright notice in the ACK home directory, in the file "Copyright".\r
+ */\r
+/* $Id$ */\r
+/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */\r
+\r
+{\r
+#include       <assert.h>\r
+#include    <stdlib.h>\r
+#include       "parameters.h"\r
+#ifndef        LINT\r
+#include       <em.h>\r
+#else\r
+#include       "l_em.h"\r
+#include       "l_lint.h"\r
+#endif /* LINT */\r
+#include       <ack_string.h>\r
+#include       <alloc.h>\r
+#include       <assert.h>\r
+#include    <string.h> \r
+#include       <flt_arith.h>\r
+#include    "idf.h"\r
+#include       "arith.h"\r
+#include       "label.h"\r
+#include       "expr.h"\r
+#include       "type.h"\r
+#include       "proto.h"\r
+#include       "struct.h"\r
+#include       "field.h"\r
+#include       "Lpars.h"\r
+#include       "sizes.h"\r
+#include       "align.h"\r
+#include       "level.h"\r
+#include    "error.h"\r
+#include       "def.h"\r
+#include       "LLlex.h"\r
+#include       "estack.h"\r
+#include    "stack.h"\r
+#include    "ch3.h"\r
+\r
+#define con_nullbyte() C_con_ucon("0", (arith)1)\r
+#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)\r
+\r
+extern char options[];\r
+static int gen_error;\r
+static int pack_level;\r
+struct e_stack *p_stack;\r
+\r
+void gen_tpcheck(struct type **);\r
+void gen_simple_exp(struct type **, struct expr **);\r
+struct type **arr_elem(struct type **, struct e_stack *);\r
+struct sdef *next_field(register struct sdef *,register struct e_stack *);\r
+struct type **gen_tphead(struct type **, int);\r
+struct type **gen_tpmiddle(void);\r
+struct sdef *gen_align_to_next(register struct e_stack *);\r
+void gen_tpend(void);\r
+void check_and_pad(struct expr **, struct type **);\r
+void pad(struct type *);\r
+void check_ival(struct expr **, register struct type *);\r
+void ch_array(struct type **,  /* type tp = array of characters        */\r
+       struct expr *);\r
+void str_cst(register char *, register int, int);\r
+#ifndef NOBITFIELD\r
+void put_bf(struct type *, arith );\r
+#endif /* NOBITFIELD */\r
+int zero_bytes(register struct sdef *);\r
+int valid_type(struct type *, char *);\r
+void con_int(register struct expr *);\r
+void illegal_init_cst(struct expr *);\r
+void too_many_initialisers(void);\r
+\r
+}\r
+\r
+/* initial_value recursively guides the initialisation expression.\r
+ */\r
+/* 3.5 */\r
+\r
+initial_value(register struct type **tpp; register struct expr **expp;) :\r
+       { if (tpp) gen_tpcheck(tpp); }\r
+[\r
+               { if (pack_level == 0) gen_error = 0; }\r
+       assignment_expression(expp)\r
+               {\r
+#ifdef LINT\r
+                       lint_expr(*expp, USED);\r
+#endif /* LINT */\r
+                       if ((*expp)->ex_type->tp_fund == ARRAY)\r
+                               array2pointer(*expp);\r
+                       if (tpp) {\r
+                               if (level >= L_LOCAL\r
+                                   || is_ld_cst(*expp)\r
+                                   || is_fp_cst(*expp)\r
+                                   || (*expp)->ex_class == String) {\r
+                                       gen_simple_exp(tpp, expp);\r
+                                       free_expression(*expp);\r
+                                       *expp = 0;\r
+                               } else {\r
+                                       expr_error(*expp,"illegal initialization");\r
+                                       free_expression(*expp);\r
+                                       *expp = 0;\r
+                               }\r
+                       }\r
+               }\r
+|\r
+       initial_value_pack(tpp, expp)\r
+]\r
+;\r
+\r
+initial_value_pack(struct type **tpp; struct expr **expp;)\r
+:\r
+       '{'\r
+                       { if (pack_level == 0) gen_error = 0; pack_level++; }\r
+       initial_value_list(tpp, expp)\r
+                       { pack_level--;\r
+                         if (!pack_level) {\r
+                               while (p_stack) {\r
+                                       struct e_stack *p = p_stack->next;\r
+\r
+                                       free_e_stack(p_stack);\r
+                                       p_stack = p;\r
+                               }\r
+                         }\r
+                         if (pack_level < gen_error) gen_error = 0;\r
+                       }\r
+       '}'\r
+;\r
+\r
+initial_value_list(register struct type **tpp; struct expr **expp;)\r
+       { struct expr *e1;\r
+         register struct type **tpp2 = 0;\r
+         int err_flag = gen_error;\r
+       }\r
+:\r
+                       { if (tpp) tpp2 = gen_tphead(tpp, 0); }\r
+       initial_value(tpp2, &e1)\r
+                       { if (!tpp) init_expression(&expp, e1); }\r
+       [%while (AHEAD != '}')          /* >>> conflict on ',' */\r
+               ','\r
+                       { if (tpp) tpp2 = gen_tpmiddle(); }\r
+               initial_value(tpp2, &e1)\r
+                       { if (!tpp) init_expression(&expp, e1); }\r
+       ]*\r
+                       { if (tpp && ! err_flag) gen_tpend(); }\r
+       ','?                            /* optional trailing comma */\r
+;\r
+\r
+{\r
+void gen_tpcheck(struct type **tpp)\r
+{\r
+       register struct type *tp;\r
+\r
+       if (gen_error) return;\r
+       switch((tp = *tpp)->tp_fund) {\r
+       case ARRAY:\r
+               if (! valid_type(tp->tp_up, "array element"))\r
+                       gen_error = pack_level;\r
+               break;\r
+       case STRUCT:\r
+               if (! valid_type(tp, "struct"))\r
+                       gen_error = pack_level;\r
+               break;\r
+       case UNION:\r
+               if (! valid_type(tp, "union"))\r
+                       gen_error = pack_level;\r
+               break;\r
+       case ERRONEOUS:\r
+               if (! gen_error) gen_error = pack_level;\r
+               break;\r
+       }\r
+}\r
+\r
+void gen_simple_exp(struct type **tpp, struct expr **expp)\r
+{\r
+       register struct type *tp;\r
+\r
+       if (gen_error) return;\r
+       tp = *tpp;\r
+       switch(tp->tp_fund) {\r
+       case ARRAY:\r
+               if ((*expp)->ex_class == String && tp->tp_up->tp_fund == CHAR) {\r
+                       ch_array(tpp,*expp);\r
+                       break;\r
+               }\r
+               /* Fall through */\r
+       case UNION:\r
+       case STRUCT:\r
+               check_and_pad(expp, tpp);\r
+               break;\r
+       case ERRONEOUS:\r
+       case FUNCTION:\r
+       case VOID:\r
+               gen_error = pack_level;\r
+               break;\r
+       default:\r
+               check_ival(expp, tp);\r
+               break;\r
+       }\r
+}\r
+\r
+struct type **arr_elem(struct type **tpp, struct e_stack *p)\r
+{\r
+       register struct type *tp = *tpp;\r
+\r
+       if (tp->tp_up->tp_fund == CHAR && AHEAD == STRING && p->elem_count == 1) {\r
+               p->nelem = 1;\r
+               return tpp;\r
+       }\r
+       if (AHEAD == '{' || (! aggregate_type(tp->tp_up) && tp->tp_up->tp_fund != UNION))\r
+               return &(tp->tp_up);\r
+       return gen_tphead(&(tp->tp_up), 1);\r
+}\r
+\r
+struct sdef *next_field(register struct sdef *sd,\r
+       register struct e_stack *p)\r
+{\r
+       if (sd->sd_sdef)\r
+               p->bytes_upto_here += zero_bytes(sd);\r
+       p->bytes_upto_here +=\r
+               size_of_type(sd->sd_type, "selector");\r
+       p->last_offset = sd->sd_offset;\r
+       return sd->sd_sdef;\r
+}\r
+\r
+struct type **gen_tphead(struct type **tpp, int nest)\r
+{\r
+       register struct type *tp = *tpp;\r
+       register struct e_stack *p;\r
+       register struct sdef *sd;\r
+\r
+       if (tpp && *tpp == error_type) {\r
+               gen_error = pack_level;\r
+               return 0;\r
+       }\r
+       if (gen_error) return tpp;\r
+       if (tp->tp_fund == UNION) {\r
+               /* Here, we saw a {, which could be the start of a union\r
+                  initializer. It could, however, also be the start of the\r
+                  initializer for the first union field ...\r
+               */\r
+               sd = tp->tp_sdef;\r
+               if (AHEAD != '{' &&\r
+                   (aggregate_type(sd->sd_type) || \r
+                    sd->sd_type->tp_fund == UNION)) {\r
+                       /* In this case, assume that it is the start of the\r
+                          initializer of the union field, so:\r
+                       */\r
+                       return gen_tphead(&(tp->tp_sdef->sd_type), nest);\r
+               }\r
+       }\r
+       p = new_e_stack();\r
+       p->next = p_stack;\r
+       p_stack = p;\r
+       p->s_nested = nest;\r
+       p->s_tpp = tpp;\r
+       switch(tp->tp_fund) {\r
+       case UNION:\r
+               p->s_def = sd = tp->tp_sdef;\r
+               p->bytes_upto_here = 0;\r
+               return &(sd->sd_type);\r
+       case ARRAY:\r
+               p->nelem = -1;\r
+               p->elem_count = 1;\r
+               if (tp->tp_size != (arith) -1) {\r
+                       p->nelem = (tp->tp_size / tp->tp_up->tp_size);\r
+               }\r
+               return arr_elem(tpp, p);\r
+       case STRUCT:\r
+               p->s_def = sd = tp->tp_sdef;\r
+               p->bytes_upto_here = 0;\r
+               p->last_offset = -1;\r
+#ifndef NOBITFIELD\r
+               while (sd && is_anon_idf(sd->sd_idf)) {\r
+                       put_bf(sd->sd_type, (arith) 0);\r
+                       sd = next_field(sd, p);\r
+               }\r
+#endif\r
+               if (! sd) {\r
+                       /* something wrong with this struct */\r
+                       gen_error = pack_level;\r
+                       p_stack = p->next;\r
+                       free_e_stack(p);\r
+                       return 0;\r
+               }\r
+               p->s_def = sd;\r
+               if (AHEAD != '{' && aggregate_type(sd->sd_type)) {\r
+                       return gen_tphead(&(sd->sd_type), 1);\r
+               }\r
+               return &(sd->sd_type);\r
+       case ERRONEOUS:\r
+               if (! gen_error) gen_error = pack_level;\r
+               /* fall through */\r
+       default:\r
+               p->nelem = 1;\r
+               p->elem_count = 1;\r
+               return tpp;\r
+       }\r
+}\r
+\r
+struct type **gen_tpmiddle(void)\r
+{\r
+       register struct type *tp;\r
+       register struct sdef *sd;\r
+       register struct e_stack *p = p_stack;\r
+\r
+       if (gen_error) {\r
+               if (p) return p->s_tpp;\r
+               return 0;\r
+       }\r
+again:\r
+       tp = *(p->s_tpp);\r
+       switch(tp->tp_fund) {\r
+       case ERRONEOUS:\r
+               if (! gen_error) gen_error = pack_level;\r
+               return p->s_tpp;\r
+       case UNION:\r
+               sd = p->s_def;\r
+               p->bytes_upto_here +=\r
+                       size_of_type(sd->sd_type, "selector");\r
+               return p->s_tpp;\r
+       default:\r
+               if (p->elem_count == p->nelem && p->s_nested) {\r
+                       p = p->next;\r
+                       free_e_stack(p_stack);\r
+                       p_stack = p;\r
+                       goto again;\r
+               }\r
+               p->elem_count++;\r
+               if (p->nelem >= 0 && p->elem_count > p->nelem) {\r
+                       too_many_initialisers();\r
+                       return p->s_tpp;\r
+               }\r
+               if (tp->tp_fund == ARRAY) {\r
+                       return arr_elem(p->s_tpp, p);\r
+               }\r
+               return p->s_tpp;\r
+       case STRUCT:\r
+               sd = gen_align_to_next(p);\r
+               if (! sd) {\r
+                       while (p->bytes_upto_here++ < tp->tp_size)\r
+                               con_nullbyte();\r
+                       if (p->s_nested) {\r
+                               p = p->next;\r
+                               free_e_stack(p_stack);\r
+                               p_stack = p;\r
+                               goto again;\r
+                       }\r
+                       too_many_initialisers();\r
+                       return p->s_tpp;\r
+               }\r
+               if (AHEAD != '{' && aggregate_type(sd->sd_type)) {\r
+                       return gen_tphead(&(sd->sd_type), 1);\r
+               }\r
+               return &(sd->sd_type);\r
+       }\r
+}\r
+\r
+struct sdef *gen_align_to_next(register struct e_stack *p)\r
+{\r
+       register struct sdef *sd = p->s_def;\r
+\r
+       if (! sd) return sd;\r
+#ifndef NOBITFIELD\r
+       do {\r
+               if (is_anon_idf(sd->sd_idf)) put_bf(sd->sd_type, (arith) 0);\r
+#endif\r
+               sd = next_field(sd, p);\r
+#ifndef NOBITFIELD\r
+       } while (sd && is_anon_idf(sd->sd_idf));\r
+#endif\r
+       p->s_def = sd;\r
+       return sd;\r
+}\r
+\r
+void gen_tpend(void)\r
+{\r
+       register struct e_stack *p = p_stack;\r
+       register struct type *tp;\r
+       register struct sdef *sd;\r
+       int getout = 0;\r
+\r
+       while (!getout && p) {\r
+           if (!gen_error) {\r
+               tp = *(p->s_tpp);\r
+               switch(tp->tp_fund) {\r
+               case UNION:\r
+                       sd = p->s_def;\r
+                       p->bytes_upto_here +=\r
+                               size_of_type(sd->sd_type, "selector");\r
+                       while (p->bytes_upto_here++ < tp->tp_size)\r
+                               con_nullbyte();\r
+                       break;\r
+               case ARRAY:\r
+                       if (tp->tp_size == -1) {\r
+                               *(p->s_tpp) = construct_type(ARRAY, tp->tp_up,\r
+                                       0, p->elem_count, NO_PROTO);\r
+                       }\r
+                       else {\r
+                               while (p->nelem-- > p->elem_count) {\r
+                                       pad(tp->tp_up);\r
+                               }\r
+                       }\r
+                       break;\r
+               case STRUCT:\r
+                       sd = gen_align_to_next(p);\r
+                       while (sd) {\r
+                               pad(sd->sd_type);\r
+                               if (sd->sd_sdef)\r
+                                       p->bytes_upto_here += zero_bytes(sd);\r
+                               p->bytes_upto_here +=\r
+                                       size_of_type(sd->sd_type, "selector");\r
+                               sd = sd->sd_sdef;\r
+                       }\r
+                       while (p->bytes_upto_here++ < tp->tp_size)\r
+                               con_nullbyte();\r
+                       break;\r
+               }\r
+           }\r
+           if (! p->s_nested) getout = 1;\r
+           p = p->next;\r
+           free_e_stack(p_stack);\r
+           p_stack = p;\r
+       }\r
+}\r
+\r
+/*     check_and_pad() is given a simple initialisation expression\r
+       where the type can be either a simple or an aggregate type.\r
+       In the latter case, only the first member is initialised and\r
+       the rest is zeroed.\r
+*/\r
+void check_and_pad(struct expr **expp, struct type **tpp)\r
+{\r
+       register struct type *tp = *tpp;\r
+\r
+       if (tp->tp_fund == ARRAY) {\r
+               check_and_pad(expp, &(tp->tp_up));      /* first member */\r
+               if (tp->tp_size == (arith)-1)\r
+                       /*      no size specified upto here: just\r
+                               set it to the size of one member.\r
+                       */\r
+                       tp = *tpp = construct_type(ARRAY, tp->tp_up,\r
+                                       0, (arith)1, NO_PROTO);\r
+               else {\r
+                       register int dim = tp->tp_size / tp->tp_up->tp_size;\r
+                       /* pad remaining members with zeroes */\r
+                       while (--dim > 0)\r
+                               pad(tp->tp_up);\r
+               }\r
+       }\r
+       else\r
+       if (tp->tp_fund == STRUCT) {\r
+               register struct sdef *sd = tp->tp_sdef;\r
+\r
+               check_and_pad(expp, &(sd->sd_type));\r
+               /* next selector is aligned by adding extra zeroes */\r
+               if (sd->sd_sdef)\r
+                       zero_bytes(sd);\r
+               while (sd = sd->sd_sdef) { /* pad remaining selectors   */\r
+                       pad(sd->sd_type);\r
+                       if (sd->sd_sdef)\r
+                               zero_bytes(sd);\r
+               }\r
+       }\r
+       else if (tp->tp_fund == UNION) {\r
+               /* only the first selector can be initialized */\r
+               register struct sdef *sd = tp->tp_sdef;\r
+\r
+               check_and_pad(expp, &(sd->sd_type));\r
+       }\r
+       else    /* simple type  */\r
+               check_ival(expp, tp);\r
+}\r
+\r
+/*     pad() fills an element of type tp with zeroes.\r
+       If the element is an aggregate, pad() is called recursively.\r
+*/\r
+void pad(struct type *tpx)\r
+{\r
+       register struct type *tp = tpx;\r
+       register arith sz = tp->tp_size;\r
+\r
+       gen_tpcheck(&tpx);\r
+       if (gen_error) return;\r
+#ifndef NOBITFIELD\r
+       if (tp->tp_fund == FIELD) {\r
+               put_bf(tp, (arith)0);\r
+               return;\r
+       }\r
+#endif /* NOBITFIELD */\r
+\r
+       if (tp->tp_align >= word_align) while (sz >= word_size) {\r
+               C_con_cst((arith) 0);\r
+               sz -= word_size;\r
+       }\r
+       while (sz) {\r
+               C_con_icon("0", (arith) 1);\r
+               sz--;\r
+       }\r
+}\r
+\r
+/*     check_ival() checks whether the initialisation of an element\r
+       of a fundamental type is legal and, if so, performs the initialisation\r
+       by directly generating the necessary code.\r
+       No further comment is needed to explain the internal structure\r
+       of this straightforward function.\r
+*/\r
+void check_ival(struct expr **expp, register struct type *tp)\r
+{\r
+       /*      The philosophy here is that ch3cast puts an explicit\r
+               conversion node in front of the expression if the types\r
+               are not compatible.  In this case, the initialisation\r
+               expression is no longer a constant.\r
+       */\r
+       register struct expr *expr = *expp;\r
+       \r
+       switch (tp->tp_fund) {\r
+       case CHAR:\r
+       case SHORT:\r
+       case INT:\r
+       case LONG:\r
+       case ENUM:\r
+       case POINTER:\r
+               ch3cast(expp, '=', tp);\r
+               expr = *expp;\r
+#ifdef DEBUG\r
+               print_expr("init-expr after cast", expr);\r
+#endif /* DEBUG */\r
+               if (!is_ld_cst(expr))\r
+                       illegal_init_cst(expr);\r
+               else\r
+               if (expr->VL_CLASS == Const)\r
+                       con_int(expr);\r
+               else\r
+               if (expr->VL_CLASS == Name) {\r
+                       register struct idf *idf = expr->VL_IDF;\r
+\r
+                       if (idf->id_def->df_level >= L_LOCAL\r
+                           && idf->id_def->df_sc != GLOBAL\r
+                           && idf->id_def->df_sc != EXTERN) {\r
+                               illegal_init_cst(expr);\r
+                       }\r
+                       else    /* e.g., int f(); int p = f; */\r
+                       if (idf->id_def->df_type->tp_fund == FUNCTION)\r
+                               C_con_pnam(idf->id_text);\r
+                       else    /* e.g., int a; int *p = &a; */\r
+                               C_con_dnam(idf->id_text, expr->VL_VALUE);\r
+               }\r
+               else {\r
+                       assert(expr->VL_CLASS == Label);\r
+                       C_con_dlb(expr->VL_LBL, expr->VL_VALUE);\r
+               }\r
+               break;\r
+       case FLOAT:\r
+       case DOUBLE:\r
+       case LNGDBL:\r
+               ch3cast(expp, '=', tp);\r
+               expr = *expp;\r
+#ifdef DEBUG\r
+               print_expr("init-expr after cast", expr);\r
+#endif /* DEBUG */\r
+               if (expr->ex_class == Float) {\r
+                       char buf[FLT_STRLEN];\r
+\r
+                       flt_flt2str(&(expr->FL_ARITH), buf, FLT_STRLEN);\r
+                       C_con_fcon(buf, expr->ex_type->tp_size);\r
+               }\r
+#ifdef NOTDEF\r
+\r
+Coercion from int to float is now always done compile time.\r
+This, to accept declarations like\r
+double x = -(double)1;\r
+and also to prevent runtime coercions for compile-time constants.\r
+\r
+               else\r
+               if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) {\r
+                       /* float f = 1; */\r
+                       expr = expr->OP_RIGHT;\r
+                       if (is_cp_cst(expr))\r
+                               C_con_fcon(long2str((long)expr->VL_VALUE, 10),\r
+                                       tp->tp_size);\r
+                       else \r
+                               illegal_init_cst(expr);\r
+               }\r
+#endif /* NOTDEF */\r
+               else\r
+                       illegal_init_cst(expr);\r
+               break;\r
+\r
+#ifndef NOBITFIELD\r
+       case FIELD:\r
+               ch3cast(expp, '=', tp->tp_up);\r
+               expr = *expp;\r
+#ifdef DEBUG\r
+               print_expr("init-expr after cast", expr);\r
+#endif /* DEBUG */\r
+               if (is_cp_cst(expr))\r
+                       put_bf(tp, expr->VL_VALUE);\r
+               else\r
+                       illegal_init_cst(expr);\r
+               break;\r
+#endif /* NOBITFIELD */\r
+\r
+       case ERRONEOUS:\r
+               if (! gen_error) gen_error = pack_level;\r
+               /* fall through */\r
+       case VOID:\r
+               break;\r
+       default:\r
+               crash("check_ival");\r
+               /*NOTREACHED*/\r
+       }\r
+}\r
+\r
+/*     ch_array() initialises an array of characters when given\r
+       a string constant.\r
+       Alignment is taken care of.\r
+*/\r
+void ch_array(struct type **tpp,       /* type tp = array of characters        */\r
+       struct expr *ex)\r
+{\r
+       register struct type *tp = *tpp;\r
+       register int length = ex->SG_LEN, i;\r
+       register char *to, *from, *s;\r
+\r
+       assert(ex->ex_class == String);\r
+       if (tp->tp_size == (arith)-1) {\r
+               /* set the dimension    */\r
+               tp = *tpp = construct_type(ARRAY, tp->tp_up, 0, (arith)length, NO_PROTO);\r
+       }\r
+       else {\r
+               arith dim = tp->tp_size / tp->tp_up->tp_size;\r
+\r
+#ifdef LINT\r
+               if (length == dim + 1) {\r
+                           expr_warning(ex, "array is not null-terminated");\r
+               } else\r
+#endif\r
+               if (length > dim + 1) {\r
+                       expr_strict(ex, "too many initializers");\r
+               }\r
+               length = dim;\r
+       }\r
+       /* throw out the characters of the already prepared string      */\r
+       s = Malloc((unsigned) (length));\r
+       clear(s, (unsigned)length);\r
+       i = length <= ex->SG_LEN ? length : ex->SG_LEN;\r
+       to = s; from = ex->SG_VALUE;\r
+       while(--i >= 0) {\r
+               *to++ = *from++;\r
+       }\r
+       free(ex->SG_VALUE);\r
+       str_cst(s, length, 0);          /* a string, but not in rom */\r
+       free(s);\r
+}\r
+\r
+/*     As long as some parts of the pipeline cannot handle very long string\r
+       constants, string constants are written out in chunks\r
+*/\r
+void str_cst(register char *str, register int len, int inrom)\r
+{\r
+       int chunksize = ((127 + (int) word_size) / (int) word_size) * (int) word_size;\r
+\r
+       while (len > chunksize) {\r
+               if (inrom)\r
+                       C_rom_scon(str, (arith) chunksize);\r
+               else    C_con_scon(str, (arith) chunksize);\r
+               len -= chunksize;\r
+               str += chunksize;\r
+       }\r
+       if (inrom)\r
+               C_rom_scon(str, (arith) len);\r
+       else    C_con_scon(str, (arith) len);\r
+}\r
+\r
+#ifndef NOBITFIELD\r
+/*     put_bf() takes care of the initialisation of (bit-)field\r
+       selectors of a struct: each time such an initialisation takes place,\r
+       put_bf() is called instead of the normal code generating routines.\r
+       Put_bf() stores the given integral value into "field" and\r
+       "throws" the result of "field" out if the current selector\r
+       is the last of this number of fields stored at the same address.\r
+*/\r
+void put_bf(struct type *tp, arith val)\r
+{\r
+       static long field = (arith)0;\r
+       static arith offset = (arith)-1;\r
+       register struct field *fd = tp->tp_field;\r
+       register struct sdef *sd =  fd->fd_sdef;\r
+       static struct expr exp;\r
+\r
+       assert(sd);\r
+       if (offset == (arith)-1) {\r
+               /* first bitfield in this field */\r
+               offset = sd->sd_offset;\r
+               exp.ex_type = tp->tp_up;\r
+               exp.ex_class = Value;\r
+               exp.VL_CLASS = Const;\r
+       }\r
+       if (val != 0)   /* insert the value into "field"        */\r
+               field |= (val & fd->fd_mask) << fd->fd_shift;\r
+       if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) {\r
+               /* the selector was the last stored at this address     */\r
+               exp.VL_VALUE = field;\r
+               con_int(&exp);\r
+               field = (arith)0;\r
+               offset = (arith)-1;\r
+       }\r
+}\r
+#endif /* NOBITFIELD */\r
+\r
+int zero_bytes(register struct sdef *sd)\r
+{\r
+       /*      fills the space between a selector of a struct\r
+               and the next selector of that struct with zero-bytes.\r
+       */\r
+       register int n = sd->sd_sdef->sd_offset - sd->sd_offset -\r
+               size_of_type(sd->sd_type, "struct member");\r
+       int count = n;\r
+\r
+       while (n-- > 0)\r
+               con_nullbyte();\r
+       return count;\r
+}\r
+\r
+int valid_type(struct type *tp, char *str)\r
+{\r
+       assert(tp!=(struct type *)0);\r
+       if (tp->tp_size < 0) {\r
+               error("size of %s unknown", str);\r
+               return 0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+void con_int(register struct expr *ex)\r
+{\r
+       register struct type *tp = ex->ex_type;\r
+\r
+       assert(is_cp_cst(ex));\r
+       if (tp->tp_unsigned)\r
+               C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size);\r
+       else if (tp->tp_size == word_size)\r
+               C_con_cst(ex->VL_VALUE);\r
+       else\r
+               C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);\r
+}\r
+\r
+void illegal_init_cst(struct expr *ex)\r
+{\r
+       expr_error(ex, "illegal initialization constant");\r
+       gen_error = pack_level;\r
+}\r
+\r
+void too_many_initialisers(void)\r
+{\r
+       error("too many initializers");\r
+       gen_error = pack_level;\r
+}\r
+}\r
index fb20095..e4c10f8 100644 (file)
 #include       "def.h"
 #include       "type.h"
 #include       "stack.h"
+#include    "error.h"
+
 
 extern char options[];
 
-enter_label(idf, defining)
-       register struct idf *idf;
+void enter_label(register struct idf *idf, int defining)
 {
        /*      The identifier idf is entered as a label. If it is new,
                it is entered into the idf list with the largest possible
@@ -45,8 +46,7 @@ enter_label(idf, defining)
                def->df_initialized = 1;
 }
 
-unstack_label(idf)
-       register struct idf *idf;
+void unstack_label(register struct idf *idf)
 {
        /*      The scope in which the label idf occurred is left.
        */
index 629577d..47d6b5b 100644 (file)
@@ -4,6 +4,8 @@
  */
 /* $Id$ */
 /*             L A B E L   D E F I N I T I O N                         */
+#ifndef LABEL_H_
+#define LABEL_H_
 
 #include <em_label.h>          /* obtain definition of "label" */
 
@@ -26,3 +28,10 @@ extern label datlab_count;
                not be there, and if it is there, it may be from a
                declaration or another application.
        */
+
+struct idf;
+
+void enter_label(register struct idf *idf, int defining);
+void unstack_label(register struct idf *idf);
+
+#endif /* LABEL_H_ */
index d8e951a..9d9f890 100644 (file)
 #include       "specials.h"
 #include       "sizes.h"
 #include       "align.h"
+#include    "stack.h"
 #include       "macro.h"
+#include    "options.h"
+#include    "error.h"
+#include    "code.h"
+#include    "cstoper.h"
+#include    "tokenname.h"
 
 extern struct tokenname tkidf[];
 extern char *symbol2str();
@@ -34,7 +40,15 @@ struct sp_id special_ids[] = {
        {0, 0}
 };
 
-void dependency();
+void compile(int argc, char *argv[]);
+static void init(void);
+static void init_specials(register struct sp_id *si);
+#ifdef DEBUG
+void Info(void);
+#endif
+
+extern void C_program(void); /* program.c */
+
 
 #ifndef NOCROSS
 arith
@@ -63,8 +77,7 @@ int
 
 char *prog_name;
 
-main(argc, argv)
-       char *argv[];
+int main(int argc, char *argv[])
 {
        /* parse and interpret the command line options */
        prog_name = argv[0];
@@ -104,8 +117,7 @@ char *source = 0;
 char *nmlist = 0;
 #endif /* GEN_NM_LIST */
 
-compile(argc, argv)
-       char *argv[];
+void compile(int argc, char *argv[])
 {
        char *result;
 #ifndef        LINT
@@ -190,7 +202,7 @@ compile(argc, argv)
        }
 }
 
-init()
+static void init(void)
 {
        init_cst();     /* initialize variables of "cstoper.c"          */
        reserve(tkidf);         /* mark the C reserved words as such    */
@@ -255,8 +267,7 @@ init()
        stack_level();
 }
 
-init_specials(si)
-       register struct sp_id *si;
+static void init_specials(register struct sp_id *si)
 {
        while (si->si_identifier)       {
                struct idf *idf = str2idf(si->si_identifier, 0);
@@ -269,7 +280,7 @@ init_specials(si)
 }
 
 #ifdef DEBUG
-Info()
+void Info(void)
 {
        extern int cnt_string_cst, cnt_formal,
                    cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
@@ -301,14 +312,12 @@ Info()
 }
 #endif /* DEBUG */
 
-void
-No_Mem()                               /* called by alloc package */
+void No_Mem(void)                              /* called by alloc package */
 {
        fatal("out of memory");
 }
 
-void
-C_failed()                             /* called by EM_code module */
+void C_failed(void)                            /* called by EM_code module */
 {
        fatal("write failed");
 }
diff --git a/lang/cem/cemcom.ansi/next.str b/lang/cem/cemcom.ansi/next.str
new file mode 100644 (file)
index 0000000..5dd7956
--- /dev/null
@@ -0,0 +1 @@
+#include "parameters.h"
index c0b4119..62864f5 100644 (file)
@@ -9,12 +9,14 @@
 #include       <stdlib.h>
 #include       <string.h>
 #include       <alloc.h>
+#include    "options.h"
 #include       "class.h"
 #include       "macro.h"
 #include       "idf.h"
 #include       "arith.h"
 #include       "sizes.h"
 #include       "align.h"
+#include    "error.h"
 
 char options[128];                     /* one for every char   */
 #ifdef LINT
@@ -24,10 +26,11 @@ char loptions[128];                 /* one for every char   */
 extern int idfsize;
 extern int density;
 
-static int txt2int();
 
-do_option(text)
-       char *text;
+
+static int txt2int(register char **);
+
+void do_option(char *text)
 {
        register char opt;
 
@@ -209,9 +212,7 @@ next_option:                        /* to allow combined one-char options */
        }
 }
 
-static int
-txt2int(tp)
-       register char **tp;
+static int txt2int(register char **tp)
 {
        /*      the integer pointed to by *tp is read, while increasing
                *tp; the resulting value is yielded.
diff --git a/lang/cem/cemcom.ansi/options.h b/lang/cem/cemcom.ansi/options.h
new file mode 100644 (file)
index 0000000..ade29ed
--- /dev/null
@@ -0,0 +1,13 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-07
+ *  
+ */
+#ifndef OPTIONS_H_
+#define OPTIONS_H_
+
+void do_option(char *text);
+
+#endif /* OPTIONS_H_ */
index b4198d9..335cb92 100644 (file)
@@ -6,37 +6,43 @@
 /* PREPROCESSOR: PRAGMA INTERPRETER */
 
 #include       "parameters.h"
+#include    "pragma.h"
+#include    "skip.h"
 
 #define P_UNKNOWN      0
 #define NR_PRAGMAS     0
 
-struct pkey {
+struct pkey
+{
        char *pk_name;
        int pk_key;
-} pragmas[NR_PRAGMAS + 1] = {
-       {0,             P_UNKNOWN}
-};
+} pragmas[NR_PRAGMAS + 1] =
+{
+{ 0, P_UNKNOWN } };
 
 extern struct idf *GetIdentifier();
 
-do_pragma()
+void do_pragma(void)
 {
 #if    NR_PRAGMAS
        register struct pkey *pkp = &pragmas[0];
 #endif
        register struct idf *id = GetIdentifier(1);
 
-       if (id != (struct idf *)0) {
+       if (id != (struct idf *) 0)
+       {
 #if    NR_PRAGMAS
-               while(pkp->pk_name) {
+               while(pkp->pk_name)
+               {
                        if (strcmp(pkp->pk_name, id->id_text) == 0)
-                               break;
+                       break;
                        pkp++;
                }
 
-               switch (pkp->pk_key) {
-               case P_UNKNOWN:
-               default:
+               switch (pkp->pk_key)
+               {
+                       case P_UNKNOWN:
+                       default:
                        break;
                }
 #endif
diff --git a/lang/cem/cemcom.ansi/pragma.h b/lang/cem/cemcom.ansi/pragma.h
new file mode 100644 (file)
index 0000000..df62ad6
--- /dev/null
@@ -0,0 +1,13 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-07
+ *  
+ */
+#ifndef PRAGMA_H_
+#define PRAGMA_H_
+
+void do_pragma(void);
+
+#endif /* PRAGMA_H_ */
index 631603c..616065d 100644 (file)
-/*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
-/* $Id$ */
-/* PROGRAM PARSER */
-
-/*     The presence of typedef declarations renders it impossible to
-       make a context-free grammar of C. Consequently we need
-       context-sensitive parsing techniques, the simplest one being
-       a subtle cooperation between the parser and the lexical scanner.
-       The lexical scanner has to know whether to return IDENTIFIER
-       or TYPE_IDENTIFIER for a given tag, and it obtains this information
-       from the definition list, as constructed by the parser.
-       The present grammar is essentially LL(2), and is processed by
-       a parser generator which accepts LL(1) with tie breaking rules
-       in C, of the form %if(cond) and %while(cond). To solve the LL(1)
-       ambiguities, the lexical scanner does a one symbol look-ahead.
-       This symbol, however, cannot always be correctly assessed, since
-       the present symbol may cause a change in the definition list
-       which causes the identification of the look-ahead symbol to be
-       invalidated.
-       The lexical scanner relies on the parser (or its routines) to
-       detect this situation and then update the look-ahead symbol.
-       An alternative approach would be to reassess the look-ahead symbol
-       in the lexical scanner when it is promoted to dot symbol. This
-       would be more beautiful but less correct, since then for a short
-       while there would be a discrepancy between the look-ahead symbol
-       and the definition list; I think it would nevertheless work in
-       correct programs.
-       A third solution would be to enter the identifier as soon as it
-       is found; its storage class is then known, although its full type
-       isn't. We would have to fill that in afterwards.
-
-       At block exit the situation is even worse. Upon reading the
-       closing brace, the names declared inside the function are cleared
-       from the name list. This action may expose a type identifier that
-       is the same as the identifier in the look-ahead symbol. This
-       situation certainly invalidates the third solution, and casts
-       doubts upon the second.
-*/
-
-%lexical       LLlex;
-%start         C_program, program;
-%start         If_expr, control_if_expression;
-
-{
-#include       "parameters.h"
-#include       <flt_arith.h>
-#include       "arith.h"
-#include       "LLlex.h"
-#include       "label.h"
-#include       "type.h"
-#include       "declar.h"
-#include       "decspecs.h"
-#include       "code.h"
-#include       "expr.h"
-#include       "def.h"
-#include    "stack.h"
-#ifdef LINT
-#include       "l_lint.h"
-#endif /* LINT */
-
-extern error();
-}
-
-control_if_expression
-       {
-               struct expr *exprX;
-       }
-:
-       constant_expression(&exprX)
-               {
-               }
-;
-
-/* 3.7 */
-program:
-       [%persistent external_definition]*
-       { unstack_world(); }
-;
-
-/*     A C identifier definition is remarkable in that it formulates
-       the declaration in a way different from most other languages:
-       e.g., rather than defining x as a pointer-to-integer, it defines
-       *x as an integer and lets the compiler deduce that x is actually
-       pointer-to-integer.  This has profound consequences, both for the
-       structure of an identifier definition and for the compiler.
-       
-       A definition starts with a decl_specifiers, which contains things
-       like
-               typedef int
-       which is implicitly repeated for every definition in the list, and
-       then for each identifier a declarator is given, of the form
-               *a()
-       or so.  The decl_specifiers is kept in a struct decspecs, to be
-       used again and again, while the declarator is stored in a struct
-       declarator, only to be passed to declare_idf together with the
-       struct decspecs.
-
-       With the introduction of prototypes, extra problems for the scope
-       administration were introduced as well.  We can have, for example,
-       int x(double x);
-       and
-       int x(double x) { ... use(x) ... }
-       In the first case, the parameter name can be forgotten, whereas in
-       the second case, the parameter should have a block scope.  The
-       problem lies in the fact that the parameter's type is known before
-       the type of the function, which causes the def structure to be on
-       the end of the list.  Our solution is as follows:
-       1-  In case of a declaration, throw the parameter identifier away
-           before the declaration of the outer x.
-       2-  In case of a definition, the function begin_proc() changes the
-           def list for the identifier.  This means that declare_idf()
-           contains an extra test in case we already saw a declaration of
-           such a function, because this function is called before
-           begin_proc().
-*/
-
-external_definition
-       {       struct decspecs Ds;
-               struct  declarator Dc;
-       }
-:
-       {       Ds = null_decspecs;
-               Dc = null_declarator;
-       }
-       [ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
-               decl_specifiers(&Ds)
-       |
-               {do_decspecs(&Ds);}
-       ]
-       [
-               declarator(&Dc)
-               {
-                       declare_idf(&Ds, &Dc, level);
-#ifdef LINT
-                       lint_ext_def(Dc.dc_idf, Ds.ds_sc);
-#endif /* LINT */
-               }
-               [
-                       function(&Ds, &Dc)
-               |
-                       {       if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
-                                   Ds.ds_notypegiven) {
-                                       strict("declaration specifiers missing");
-                               }
-                       }
-                       non_function(&Ds, &Dc)
-               ]
-       |
-               {       if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
-                           Ds.ds_notypegiven) {
-                               strict("declaration missing");
-                       }
-               }
-               ';'
-       ]
-       {remove_declarator(&Dc); flush_strings(); }
-;
-
-non_function(register struct decspecs *ds; register struct declarator *dc;)
-:
-       {       reject_params(dc);
-       }
-       [
-               initializer(dc->dc_idf, ds->ds_sc)
-       |
-               { code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
-       ]
-       {
-#ifdef LINT
-               lint_non_function_decl(ds, dc);
-#endif /* LINT */
-       }
-       [
-               ','
-               init_declarator(ds)
-       ]*
-       ';'
-;
-
-/* 3.7.1 */
-function(struct decspecs *ds; struct declarator *dc;)
-       {
-               arith fbytes;
-               register struct idf *idf = dc->dc_idf;
-       }
-:
-       {
-#ifdef LINT
-               lint_start_function();
-#endif /* LINT */
-               idf_initialized(idf);
-               stack_level();          /* L_FORMAL1 declarations */
-               declare_params(dc);
-               begin_proc(ds, idf);    /* sets global function info */
-               stack_level();          /* L_FORMAL2 declarations */
-               declare_protos(dc);
-       }
-       declaration*
-       {
-               check_formals(idf, dc);         /* check style-mixtures */
-               declare_formals(idf, &fbytes);
-#ifdef LINT
-               lint_formals();
-#endif /* LINT */
-       }
-       compound_statement
-       {
-               end_proc(fbytes);
-#ifdef LINT
-               lint_implicit_return();
-#endif /* LINT */
-               unstack_level();        /* L_FORMAL2 declarations */
-#ifdef LINT
-               lint_end_formals();
-#endif /* LINT */
-               unstack_level();        /* L_FORMAL1 declarations */
-#ifdef LINT
-               lint_end_function();
-#endif /* LINT */
-       }
-;
+/*\r
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.\r
+ * See the copyright notice in the ACK home directory, in the file "Copyright".\r
+ */\r
+/* $Id$ */\r
+/* PROGRAM PARSER */\r
+\r
+/*     The presence of typedef declarations renders it impossible to\r
+       make a context-free grammar of C. Consequently we need\r
+       context-sensitive parsing techniques, the simplest one being\r
+       a subtle cooperation between the parser and the lexical scanner.\r
+       The lexical scanner has to know whether to return IDENTIFIER\r
+       or TYPE_IDENTIFIER for a given tag, and it obtains this information\r
+       from the definition list, as constructed by the parser.\r
+       The present grammar is essentially LL(2), and is processed by\r
+       a parser generator which accepts LL(1) with tie breaking rules\r
+       in C, of the form %if(cond) and %while(cond). To solve the LL(1)\r
+       ambiguities, the lexical scanner does a one symbol look-ahead.\r
+       This symbol, however, cannot always be correctly assessed, since\r
+       the present symbol may cause a change in the definition list\r
+       which causes the identification of the look-ahead symbol to be\r
+       invalidated.\r
+       The lexical scanner relies on the parser (or its routines) to\r
+       detect this situation and then update the look-ahead symbol.\r
+       An alternative approach would be to reassess the look-ahead symbol\r
+       in the lexical scanner when it is promoted to dot symbol. This\r
+       would be more beautiful but less correct, since then for a short\r
+       while there would be a discrepancy between the look-ahead symbol\r
+       and the definition list; I think it would nevertheless work in\r
+       correct programs.\r
+       A third solution would be to enter the identifier as soon as it\r
+       is found; its storage class is then known, although its full type\r
+       isn't. We would have to fill that in afterwards.\r
+\r
+       At block exit the situation is even worse. Upon reading the\r
+       closing brace, the names declared inside the function are cleared\r
+       from the name list. This action may expose a type identifier that\r
+       is the same as the identifier in the look-ahead symbol. This\r
+       situation certainly invalidates the third solution, and casts\r
+       doubts upon the second.\r
+*/\r
+\r
+%lexical       LLlex;\r
+%start         C_program, program;\r
+%start         If_expr, control_if_expression;\r
+\r
+{\r
+#include       "parameters.h"\r
+#include       <flt_arith.h>\r
+#include       "arith.h"\r
+#include       "LLlex.h"\r
+#include       "label.h"\r
+#include       "type.h"\r
+#include       "declar.h"\r
+#include       "decspecs.h"\r
+#include       "code.h"\r
+#include       "expr.h"\r
+#include       "def.h"\r
+#include    "idf.h"\r
+#include    "declarator.h"\r
+#include    "stack.h"\r
+#include    "proto.h"\r
+#include    "error.h"\r
+#ifdef LINT\r
+#include       "l_lint.h"\r
+#endif /* LINT */\r
+\r
+}\r
+\r
+control_if_expression\r
+       {\r
+               struct expr *exprX;\r
+       }\r
+:\r
+       constant_expression(&exprX)\r
+               {\r
+               }\r
+;\r
+\r
+/* 3.7 */\r
+program:\r
+       [%persistent external_definition]*\r
+       { unstack_world(); }\r
+;\r
+\r
+/*     A C identifier definition is remarkable in that it formulates\r
+       the declaration in a way different from most other languages:\r
+       e.g., rather than defining x as a pointer-to-integer, it defines\r
+       *x as an integer and lets the compiler deduce that x is actually\r
+       pointer-to-integer.  This has profound consequences, both for the\r
+       structure of an identifier definition and for the compiler.\r
+       \r
+       A definition starts with a decl_specifiers, which contains things\r
+       like\r
+               typedef int\r
+       which is implicitly repeated for every definition in the list, and\r
+       then for each identifier a declarator is given, of the form\r
+               *a()\r
+       or so.  The decl_specifiers is kept in a struct decspecs, to be\r
+       used again and again, while the declarator is stored in a struct\r
+       declarator, only to be passed to declare_idf together with the\r
+       struct decspecs.\r
+\r
+       With the introduction of prototypes, extra problems for the scope\r
+       administration were introduced as well.  We can have, for example,\r
+       int x(double x);\r
+       and\r
+       int x(double x) { ... use(x) ... }\r
+       In the first case, the parameter name can be forgotten, whereas in\r
+       the second case, the parameter should have a block scope.  The\r
+       problem lies in the fact that the parameter's type is known before\r
+       the type of the function, which causes the def structure to be on\r
+       the end of the list.  Our solution is as follows:\r
+       1-  In case of a declaration, throw the parameter identifier away\r
+           before the declaration of the outer x.\r
+       2-  In case of a definition, the function begin_proc() changes the\r
+           def list for the identifier.  This means that declare_idf()\r
+           contains an extra test in case we already saw a declaration of\r
+           such a function, because this function is called before\r
+           begin_proc().\r
+*/\r
+\r
+external_definition\r
+       {       struct decspecs Ds;\r
+               struct  declarator Dc;\r
+       }\r
+:\r
+       {       Ds = null_decspecs;\r
+               Dc = null_declarator;\r
+       }\r
+       [ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)\r
+               decl_specifiers(&Ds)\r
+       |\r
+               {do_decspecs(&Ds);}\r
+       ]\r
+       [\r
+               declarator(&Dc)\r
+               {\r
+                       declare_idf(&Ds, &Dc, level);\r
+#ifdef LINT\r
+                       lint_ext_def(Dc.dc_idf, Ds.ds_sc);\r
+#endif /* LINT */\r
+               }\r
+               [\r
+                       function(&Ds, &Dc)\r
+               |\r
+                       {       if (! Ds.ds_sc_given && ! Ds.ds_typequal &&\r
+                                   Ds.ds_notypegiven) {\r
+                                       strict("declaration specifiers missing");\r
+                               }\r
+                       }\r
+                       non_function(&Ds, &Dc)\r
+               ]\r
+       |\r
+               {       if (! Ds.ds_sc_given && ! Ds.ds_typequal &&\r
+                           Ds.ds_notypegiven) {\r
+                               strict("declaration missing");\r
+                       }\r
+               }\r
+               ';'\r
+       ]\r
+       {remove_declarator(&Dc); flush_strings(); }\r
+;\r
+\r
+non_function(register struct decspecs *ds; register struct declarator *dc;)\r
+:\r
+       {       reject_params(dc);\r
+       }\r
+       [\r
+               initializer(dc->dc_idf, ds->ds_sc)\r
+       |\r
+               { code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }\r
+       ]\r
+       {\r
+#ifdef LINT\r
+               lint_non_function_decl(ds, dc);\r
+#endif /* LINT */\r
+       }\r
+       [\r
+               ','\r
+               init_declarator(ds)\r
+       ]*\r
+       ';'\r
+;\r
+\r
+/* 3.7.1 */\r
+function(struct decspecs *ds; struct declarator *dc;)\r
+       {\r
+               arith fbytes;\r
+               register struct idf *idf = dc->dc_idf;\r
+       }\r
+:\r
+       {\r
+#ifdef LINT\r
+               lint_start_function();\r
+#endif /* LINT */\r
+               idf_initialized(idf);\r
+               stack_level();          /* L_FORMAL1 declarations */\r
+               declare_params(dc);\r
+               begin_proc(ds, idf);    /* sets global function info */\r
+               stack_level();          /* L_FORMAL2 declarations */\r
+               declare_protos(dc);\r
+       }\r
+       declaration*\r
+       {\r
+               check_formals(idf, dc);         /* check style-mixtures */\r
+               declare_formals(idf, &fbytes);\r
+#ifdef LINT\r
+               lint_formals();\r
+#endif /* LINT */\r
+       }\r
+       compound_statement\r
+       {\r
+               end_proc(fbytes);\r
+#ifdef LINT\r
+               lint_implicit_return();\r
+#endif /* LINT */\r
+               unstack_level();        /* L_FORMAL2 declarations */\r
+#ifdef LINT\r
+               lint_end_formals();\r
+#endif /* LINT */\r
+               unstack_level();        /* L_FORMAL1 declarations */\r
+#ifdef LINT\r
+               lint_end_function();\r
+#endif /* LINT */\r
+       }\r
+;\r
index ff99ba9..a9812b1 100644 (file)
 #include       "declar.h"
 #include       "decspecs.h"
 #include       "proto.h"
+#include    "error.h"
+#include    "ch3.h"
 
 extern char options[];
 
-void
-check_for_void(pl)
-       register struct proto *pl;
+void check_for_void(register struct proto *pl)
 {
        register int errcnt = 0;
 
-       if (!pl) return;
-       if ((pl->pl_flag & PL_VOID) && !(pl->next)) return;
+       if (!pl)
+               return;
+       if ((pl->pl_flag & PL_VOID) && !(pl->next))
+               return;
 
-       while (pl) {
-               if (pl->pl_flag & PL_VOID) {
+       while (pl)
+       {
+               if (pl->pl_flag & PL_VOID)
+               {
                        if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN))
                                error("illegal use of void in argument list");
                        pl->pl_flag |= PL_ERRGIVEN;
@@ -46,37 +50,35 @@ check_for_void(pl)
        }
 }
 
-add_proto(pl, ds, dc, lvl)
-       struct proto *pl;
-       struct decspecs *ds;
-       struct declarator *dc;
-       int lvl;
+void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc,
+               int lvl)
 {
        /*      The full typed identifier or abstract type, described
-               by the structures decspecs and declarator are turned
-               a into parameter type list structure.
-               The parameters will be declared at level L_FORMAL2,
-               later on it's decided whether they were prototypes
-               or actual declarations.
-       */
+        by the structures decspecs and declarator are turned
+        a into parameter type list structure.
+        The parameters will be declared at level L_FORMAL2,
+        later on it's decided whether they were prototypes
+        or actual declarations.
+        */
        register struct idf *idf = dc->dc_idf;
-       register struct def *def = idf ? idf->id_def : (struct def *)0;
+       register struct def *def = idf ? idf->id_def : (struct def *) 0;
        register int sc = ds->ds_sc;
        register struct type *type;
        char formal_array = 0;
 
-       assert(ds->ds_type != (struct type *)0);
+       assert(ds->ds_type != (struct type * )0);
 
        pl->pl_flag = PL_FORMAL;
        type = declare_type(ds->ds_type, dc);
-       if (type->tp_size < (arith)0 && actual_declaration(sc, type)) {
+       if (type->tp_size < (arith) 0 && actual_declaration(sc, type))
+       {
                extern char *symbol2str();
                if (type->tp_fund != VOID)
                        error("unknown %s-type", symbol2str(type->tp_fund));
-               else {
-                       if (idf != (struct idf *)0
-                           || ds->ds_sc_given
-                           || ds->ds_typequal) {
+               else
+               {
+                       if (idf != (struct idf *) 0 || ds->ds_sc_given || ds->ds_typequal)
+                       {
                                error("illegal use of void in argument list");
                                pl->pl_flag |= PL_ERRGIVEN;
                        }
@@ -84,43 +86,54 @@ add_proto(pl, ds, dc, lvl)
                        pl->pl_flag |= PL_VOID;
                }
        }
-       if (ds->ds_sc_given && ds->ds_sc != REGISTER) {
-               if (!(pl->pl_flag & PL_ERRGIVEN)) {
-                   if (ds->ds_sc != AUTO) {
-                       error("illegal storage class in parameter declaration");
-                   } else {
-                       warning("illegal storage class in parameter declaration");
-                   }
+       if (ds->ds_sc_given && ds->ds_sc != REGISTER)
+       {
+               if (!(pl->pl_flag & PL_ERRGIVEN))
+               {
+                       if (ds->ds_sc != AUTO)
+                       {
+                               error("illegal storage class in parameter declaration");
+                       }
+                       else
+                       {
+                               warning("illegal storage class in parameter declaration");
+                       }
                }
        }
 
        /*      Perform some special conversions for parameters.
-       */
-       if (type->tp_fund == FUNCTION) {
+        */
+       if (type->tp_fund == FUNCTION)
+       {
                type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO);
-       } else if (type->tp_fund == ARRAY) {
+       }
+       else if (type->tp_fund == ARRAY)
+       {
                type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO);
                formal_array = 1;
        }
 
        /*      According to the standard we should ignore the storage
-               class of a parameter, unless it's part of a function
-               definition.
-               However, in the routine declare_protos we don't know decspecs,
-               and therefore we can't complain up there. So we build up the
-               storage class, and keep quiet until we reach declare_protos.
-       */
-       sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ?
-                               0 : sc == 0 ? FORMAL : REGISTER;
-
-       if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */ )) {
+        class of a parameter, unless it's part of a function
+        definition.
+        However, in the routine declare_protos we don't know decspecs,
+        and therefore we can't complain up there. So we build up the
+        storage class, and keep quiet until we reach declare_protos.
+        */
+       sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ? 0 :
+                       sc == 0 ? FORMAL : REGISTER;
+
+       if (def && (def->df_level == lvl /* || def->df_level < L_PROTO */))
+       {
                /* redeclaration at the same level */
                error("parameter %s redeclared", idf->id_text);
-       } else if (idf != (struct idf *)0) {
+       }
+       else if (idf != (struct idf *) 0)
+       {
                /*      New definition, redefinition hides earlier one
-               */
+                */
                register struct def *newdef = new_def();
-               
+
                newdef->next = def;
                newdef->df_level = lvl;
                newdef->df_sc = sc;
@@ -133,28 +146,28 @@ add_proto(pl, ds, dc, lvl)
                /* newdef->df_firstbrace = 0; */
 #endif
                /*      We can't put the idf onto the stack, since these kinds
-                       of declaration may occurs at any level, and the idf
-                       does not necessarily go at this level. E.g.
-
-                       f() {
-                       ...
-                               { int func(int a, int b);
-                               ...
-                               }
-                       }
-
-                       The idf's a and b declared in the prototype declaration
-                       do not go at any level, they are simply ignored.
-                       However, in
-
-                       f(int a, int b) {
-                       ...
-                       }
-
-                       They should go at level L_FORMAL2. But at this stage
-                       we don't know whether we have a prototype or function
-                       definition. So, this process is postponed.
-               */
+                of declaration may occurs at any level, and the idf
+                does not necessarily go at this level. E.g.
+
+                f() {
+                ...
+                { int func(int a, int b);
+                ...
+                }
+                }
+
+                The idf's a and b declared in the prototype declaration
+                do not go at any level, they are simply ignored.
+                However, in
+
+                f(int a, int b) {
+                ...
+                }
+
+                They should go at level L_FORMAL2. But at this stage
+                we don't know whether we have a prototype or function
+                definition. So, this process is postponed.
+                */
                idf->id_def = newdef;
                update_ahead(idf);
        }
@@ -163,35 +176,33 @@ add_proto(pl, ds, dc, lvl)
        pl->pl_type = type;
 }
 
-struct tag *
-gettag(tp, idpp)
-struct type *tp;
-struct idf **idpp;
+static struct tag * gettag(struct type *tp, struct idf **idpp)
 {
-       struct tag *tg = (struct tag *)0;
+       struct tag *tg = (struct tag *) 0;
        register int fund = tp->tp_fund;
 
-        while (fund == FIELD || fund == POINTER
-                || fund == ARRAY || fund == FUNCTION) {
-                tp = tp->tp_up;
-                fund = tp->tp_fund;
-        }
+       while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION)
+       {
+               tp = tp->tp_up;
+               fund = tp->tp_fund;
+       }
        *idpp = tp->tp_idf;
-       switch(tp->tp_fund) {
+       switch (tp->tp_fund)
+       {
        case ENUM:
        case UNION:
-       case STRUCT: tg = tp->tp_idf->id_tag; break;
+       case STRUCT:
+               tg = tp->tp_idf->id_tag;
+               break;
        }
        return tg;
 }
 
-
-declare_protos(dc)
-       register struct declarator *dc;
+void declare_protos(register struct declarator *dc)
 {
        /*      At this points we know that the idf's in protolist are formal
-               parameters. So it's time to declare them at level L_FORMAL2.
-       */
+        parameters. So it's time to declare them at level L_FORMAL2.
+        */
        struct stack_level *stl = stack_level_of(L_FORMAL1);
        register struct decl_unary *du;
        register struct type *type;
@@ -200,31 +211,39 @@ declare_protos(dc)
 
 #ifdef DEBUG
        if (options['t'])
-               dumpidftab("start declare_protos", 0);
+       dumpidftab("start declare_protos", 0);
 #endif /* DEBUG */
        du = dc->dc_decl_unary;
-       while (du) {
-               if (du->du_fund == FUNCTION) {
-                       if (du->next != (struct decl_unary *) 0) {
+       while (du)
+       {
+               if (du->du_fund == FUNCTION)
+               {
+                       if (du->next != (struct decl_unary *) 0)
+                       {
                                remove_proto_idfs(du->du_proto);
                                du->du_proto = 0;
-                       } else break;
+                       }
+                       else
+                               break;
                }
                du = du->next;
        }
        pl = du ? du->du_proto : NO_PROTO;
-       if (pl) {
+       if (pl)
+       {
 #if    0 /* the id_proto member is deleted (???) */
                idf->id_proto = 0;
 #endif /* 0 */
-               do {
+               do
+               {
                        struct tag *tg;
                        struct idf *idp = 0;
 
                        type = pl->pl_type;
 
                        /* `...' only for type checking */
-                       if (pl->pl_flag & PL_ELLIPSIS) {
+                       if (pl->pl_flag & PL_ELLIPSIS)
+                       {
                                pl = pl->next;
                                continue;
                        }
@@ -233,14 +252,15 @@ declare_protos(dc)
                        if (type->tp_fund == VOID)
                                break;
 
-                       if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) {
+                       if (!pl->pl_idf || !(def = pl->pl_idf->id_def))
+                       {
                                error("no parameter identifier supplied");
                                pl = pl->next;
                                continue;
                        }
 
                        /*      Postponed storage class checking.
-                       */
+                        */
                        if (def->df_sc == 0)
                                error("illegal storage class in parameter declaration");
 
@@ -249,7 +269,8 @@ declare_protos(dc)
                        pl = pl->next;
 
                        tg = gettag(type, &idp);
-                       if (tg && tg->tg_level <= L_PROTO) {
+                       if (tg && tg->tg_level <= L_PROTO)
+                       {
                                tg->tg_level = L_FORMAL2;
                                stack_idf(idp, stl);
                        }
@@ -257,43 +278,47 @@ declare_protos(dc)
        }
 #ifdef DEBUG
        if (options['t'])
-               dumpidftab("end declare_protos", 0);
+       dumpidftab("end declare_protos", 0);
 #endif /* DEBUG */
 }
 
-
-void
-update_proto(tp, otp)
-       register struct type *tp, *otp;
+void update_proto(register struct type *tp, register struct type *otp)
 {
        /*      This routine performs the proto type updates.
-               Consider the following code:
+        Consider the following code:
 
-               int f(double g());
-               int f(double g(int f(), int));
-               int f(double g(int f(long double), int));
+        int f(double g());
+        int f(double g(int f(), int));
+        int f(double g(int f(long double), int));
 
-               The most accurate definition is the third line.
-               This routine will silently update all lists,
-               and removes the redundant occupied space.
-       */
+        The most accurate definition is the third line.
+        This routine will silently update all lists,
+        and removes the redundant occupied space.
+        */
        register struct proto *pl, *opl;
 
-       if (tp == otp) return;
-       if (!tp || !otp) return;
+       if (tp == otp)
+               return;
+       if (!tp || !otp)
+               return;
 
-       while (tp->tp_fund != FUNCTION) {
-               if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) return;
+       while (tp->tp_fund != FUNCTION)
+       {
+               if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY)
+                       return;
                tp = tp->tp_up;
                otp = otp->tp_up;
-               if (!tp) return;
+               if (!tp)
+                       return;
        }
 
        pl = tp->tp_proto;
        opl = otp->tp_proto;
-       if (pl && opl) {
+       if (pl && opl)
+       {
                /* both have prototypes */
-               while (pl && opl) {
+               while (pl && opl)
+               {
                        update_proto(pl->pl_type, opl->pl_type);
                        pl = pl->next;
                        opl = opl->next;
@@ -302,9 +327,13 @@ update_proto(tp, otp)
                 * a typedef.
                 */
                otp->tp_proto = tp->tp_proto;
-       } else if (opl) {
+       }
+       else if (opl)
+       {
                /* old decl has type */
-       } else if (pl) {
+       }
+       else if (pl)
+       {
                otp->tp_proto = pl;
        }
 
@@ -314,39 +343,44 @@ update_proto(tp, otp)
 /* struct/union and enum tags can be declared inside prototypes
  * remove them from the symbol-table
  */
-void
-remove_proto_tag(tp)
-struct type *tp;
+static void remove_proto_tag(struct type *tp)
 {
        register struct idf *ident;
        register struct tag *tgp, **tgpp;
        register int fund = tp->tp_fund;
 
-       while (fund == FIELD || fund == POINTER
-               || fund == ARRAY || fund == FUNCTION) {
+       while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION)
+       {
                tp = tp->tp_up;
                fund = tp->tp_fund;
        }
 
        ident = tp->tp_idf;
-       switch (tp->tp_fund) {
+       switch (tp->tp_fund)
+       {
        case ENUM:
        case STRUCT:
-       case UNION: tgpp = &(ident->id_tag); break;
-       default: return;
+       case UNION:
+               tgpp = &(ident->id_tag);
+               break;
+       default:
+               return;
        }
 
-       while((*tgpp) && (*tgpp)->tg_type != tp) {
+       while ((*tgpp) && (*tgpp)->tg_type != tp)
+       {
                tgpp = &((*tgpp)->next);
        }
-       if (!*tgpp) return;
+       if (!*tgpp)
+               return;
 
        tgp = *tgpp;
-       if (tgp->tg_level > L_PROTO) return;
+       if (tgp->tg_level > L_PROTO)
+               return;
 
 #ifdef DEBUG
        if (options['t'])
-               print("Removing idf %s from list\n",
+       print("Removing idf %s from list\n",
                        ident->id_text);
 #endif
 
@@ -354,52 +388,55 @@ struct type *tp;
        free_tag(tgp);
 }
 
-remove_proto_idfs(pl)
-       register struct proto *pl;
+/*     Remove all the identifier definitions from the
+        prototype list. */
+void remove_proto_idfs(register struct proto *pl)
 {
-       /*      Remove all the identifier definitions from the
-               prototype list.
-       */
+
        register struct def *def;
 
-       while (pl) {
-               if (pl->pl_idf) {
+       while (pl)
+       {
+               if (pl->pl_idf)
+               {
 #ifdef DEBUG
                        if (options['t'])
-                               print("Removing idf %s from list\n",
+                       print("Removing idf %s from list\n",
                                        pl->pl_idf->id_text);
 #endif
                        def = pl->pl_idf->id_def;
-                       if (def && def->df_level <= L_PROTO) {
+                       if (def && def->df_level <= L_PROTO)
+                       {
                                pl->pl_idf->id_def = def->next;
                                free_def(def);
                        }
                        pl->pl_idf = (struct idf *) 0;
                }
-               if (pl->pl_type) {
+               if (pl->pl_type)
+               {
                        remove_proto_tag(pl->pl_type);
                }
                pl = pl->next;
        }
 }
 
-void
-call_proto(expp)
-       register struct expr **expp;
+void call_proto(register struct expr **expp)
 {
        /*      If the function specified by (*expp)->OP_LEFT has a prototype,
-               the parameters are converted according the rules specified in
-               par. 3.3.2.2. E.i. the parameters are converted to the prototype
-               counter parts as if by assignment. For the parameters falling
-               under ellipsis clause the old parameters conversion stuff
-               applies.
-       */
+        the parameters are converted according the rules specified in
+        par. 3.3.2.2. E.i. the parameters are converted to the prototype
+        counter parts as if by assignment. For the parameters falling
+        under ellipsis clause the old parameters conversion stuff
+        applies.
+        */
        register struct expr *left = (*expp)->OP_LEFT;
        register struct expr *right = (*expp)->OP_RIGHT;
        register struct proto *pl = NO_PROTO;
-       static struct proto ellipsis = { 0, 0, 0, PL_ELLIPSIS };
+       static struct proto ellipsis =
+       { 0, 0, 0, PL_ELLIPSIS };
 
-       if (left != NILEXPR) {          /* in case of an error */
+       if (left != NILEXPR)
+       { /* in case of an error */
                register struct type *tp = left->ex_type;
 
                while (tp && tp->tp_fund != FUNCTION && tp != error_type)
@@ -408,17 +445,20 @@ call_proto(expp)
                        pl = tp->tp_proto;
        }
 
-       if (right != NILEXPR) {         /* function call with parameters */
+       if (right != NILEXPR)
+       { /* function call with parameters */
                register struct expr **ep = &((*expp)->OP_RIGHT);
                register int ecnt = 0, pcnt = 0;
                struct expr **estack[NPARAMS];
                struct proto *pstack[NPARAMS];
 
                /* stack up the parameter expressions */
-               while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) {
+               while (right->ex_class == Oper && right->OP_OPER == PARCOMMA)
+               {
                        if (ecnt == STDC_NPARAMS)
                                expr_strict(right, "number of parameters exceeds ANSI limit");
-                       if (ecnt >= NPARAMS-1) {
+                       if (ecnt >= NPARAMS - 1)
+                       {
                                expr_error(right, "too many parameters");
                                return;
                        }
@@ -429,45 +469,56 @@ call_proto(expp)
                estack[ecnt] = ep;
 
                /*      Declarations like int f(void) do not expect any
-                       parameters.
-               */
-               if (pl && pl->pl_flag & PL_VOID) {
+                parameters.
+                */
+               if (pl && pl->pl_flag & PL_VOID)
+               {
                        expr_strict(*expp, "no parameters expected");
                        pl = NO_PROTO;
                }
 
                /* stack up the prototypes */
-               if (pl) {
+               if (pl)
+               {
                        pcnt--;
-                       do {
+                       do
+                       {
                                /* stack prototypes */
                                pstack[++pcnt] = pl;
                                pl = pl->next;
                        } while (pl);
                }
-               else {
+               else
+               {
                        pstack[0] = &ellipsis;
                }
 
-               for (ecnt; ecnt >= 0; ecnt--) {
+               for (ecnt; ecnt >= 0; ecnt--)
+               {
                        /*      Only the parameters specified in the prototype
-                               are checked and converted. The parameters that
-                               fall under the ellipsis clause are neither
-                               checked nor converted !
-                       */
-                       if (pcnt < 0) {
-                               expr_error(*expp, "more parameters than specified in prototype");
+                        are checked and converted. The parameters that
+                        fall under the ellipsis clause are neither
+                        checked nor converted !
+                        */
+                       if (pcnt < 0)
+                       {
+                               expr_error(*expp,
+                                               "more parameters than specified in prototype");
                                break;
                        }
-                       else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) {
-                               ch3cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type);
+                       else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS))
+                       {
+                               ch3cast(estack[ecnt], CASTAB, pstack[pcnt]->pl_type);
                                pcnt--;
-                       } else
+                       }
+                       else
                                any2parameter(estack[ecnt]);
                }
                if (pcnt > 0 || (pcnt == 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS)))
                        expr_error(*expp, "fewer parameters than specified in prototype");
-       } else {
+       }
+       else
+       {
                if (pl && !(pl->pl_flag & PL_VOID))
                        expr_error(*expp, "fewer parameters than specified in prototype");
        }
index 03219de..6905882 100644 (file)
@@ -2,6 +2,9 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef PROTO_H
+#define PROTO_H
+
 /* $Id$ */
 /* PARAMETER TYPE LIST DEFINITION */
 
@@ -20,3 +23,20 @@ struct proto {
 #define        PL_ERRGIVEN     0x08
 
 /* ALLOCDEF "proto" 20 */
+
+/* Forward structure declarations */
+struct expr;
+struct type;
+struct declarator;
+struct decspecs;
+
+
+void remove_proto_idfs(register struct proto *pl);
+void call_proto(register struct expr **expp);
+void update_proto(register struct type *tp, register struct type *otp);
+void declare_protos(register struct declarator *dc);
+void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc,
+               int lvl);
+void check_for_void(register struct proto *pl);
+
+#endif
index b617f08..8dd6ee8 100644 (file)
 #include "LLlex.h"
 #include "class.h"
 #include "input.h"
+#include "skip.h"
 
 
-SkipToNewLine()
+int SkipToNewLine(void)
 {
        register int ch;
        register int garbage = 0;
diff --git a/lang/cem/cemcom.ansi/skip.h b/lang/cem/cemcom.ansi/skip.h
new file mode 100644 (file)
index 0000000..52ef8cb
--- /dev/null
@@ -0,0 +1,13 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-07
+ *  
+ */
+#ifndef SKIP_H_
+#define SKIP_H_
+
+int SkipToNewLine(void);
+
+#endif /* SKIP_H_ */
index f80b360..a7a7928 100644 (file)
@@ -20,6 +20,7 @@
 #include       <flt_arith.h>
 #include       <stb.h>
 
+#include    "stab.h"
 #include    "idf.h"
 #include       "LLlex.h"
 #include       "stack.h"
 #include       "field.h"
 #include       "Lpars.h"
 #include       "level.h"
+#include    "print.h"
 
-extern long    full_mask[];
-extern char    *sprint();
+extern long full_mask[];
 
 #define INCR_SIZE      64
 
-static struct db_str {
-       unsigned        sz;
-       char            *base;
-       char            *currpos;
+static struct db_str
+{
+       unsigned sz;
+       char *base;
+       char *currpos;
 } db_str;
 
-static
-create_db_str()
+static void create_db_str(void)
 {
-       if (! db_str.base) {
+       if (!db_str.base)
+       {
                db_str.base = Malloc(INCR_SIZE);
                db_str.sz = INCR_SIZE;
        }
        db_str.currpos = db_str.base;
 }
 
-static
-addc_db_str(c)
-       int     c;
+static void addc_db_str(int c)
 {
        int df = db_str.currpos - db_str.base;
-       if (df >= db_str.sz-1) {
+       if (df >= db_str.sz - 1)
+       {
                db_str.sz += INCR_SIZE;
                db_str.base = Realloc(db_str.base, db_str.sz);
                db_str.currpos = db_str.base + df;
@@ -65,34 +66,35 @@ addc_db_str(c)
        *db_str.currpos = '\0';
 }
 
-static
-adds_db_str(s)
-       char    *s;
+static void adds_db_str(char *s)
 {
-       while (*s) addc_db_str(*s++);
+       while (*s)
+               addc_db_str(*s++);
 }
 
-static void
-stb_type(tp)
-       register struct type    *tp;
+static void stb_type(register struct type *tp)
 {
-       char            buf[128];
-       static int      stb_count;
-       long            l;
+       char buf[128];
+       static int stb_count;
+       long l;
 
-       if (tp->tp_dbindex > 0) {
+       if (tp->tp_dbindex > 0)
+       {
                adds_db_str(sprint(buf, "%d", tp->tp_dbindex));
                return;
        }
-       if (tp->tp_dbindex < 0 && tp->tp_size < 0) {
+       if (tp->tp_dbindex < 0 && tp->tp_size < 0)
+       {
                adds_db_str(sprint(buf, "%d", -tp->tp_dbindex));
                return;
        }
-       if (tp->tp_dbindex <= 0) {
+       if (tp->tp_dbindex <= 0)
+       {
                tp->tp_dbindex = ++stb_count;
        }
        adds_db_str(sprint(buf, "%d=", tp->tp_dbindex));
-       switch(tp->tp_fund) {
+       switch (tp->tp_fund)
+       {
        /* simple types ... */
        case VOID:
                adds_db_str(sprint(buf, "%d", void_type->tp_dbindex));
@@ -101,49 +103,44 @@ stb_type(tp)
        case LONG:
        case CHAR:
        case SHORT:
-                l = full_mask[(int)tp->tp_size];
-               if (tp->tp_unsigned) {
-                       adds_db_str(sprint(buf,
-                               "r%d;0;%ld",
-                               tp->tp_dbindex,
-                               l));
+               l = full_mask[(int) tp->tp_size];
+               if (tp->tp_unsigned)
+               {
+                       adds_db_str(sprint(buf, "r%d;0;%ld", tp->tp_dbindex, l));
                }
-               else {
-                       l &= ~ (1L << ((int)tp->tp_size * 8 - 1));
-                       adds_db_str(sprint(buf,
-                               "r%d;%ld;%ld",
-                               tp->tp_dbindex,
-                               -l-1,
-                               l));
+               else
+               {
+                       l &= ~(1L << ((int) tp->tp_size * 8 - 1));
+                       adds_db_str(sprint(buf, "r%d;%ld;%ld", tp->tp_dbindex, -l - 1, l));
                }
                break;
        case FLOAT:
        case DOUBLE:
        case LNGDBL:
-               adds_db_str(sprint(buf,
-                      "r%d;%ld;0",
-                      tp->tp_dbindex,
-                      (long)tp->tp_size));
+               adds_db_str(
+                               sprint(buf, "r%d;%ld;0", tp->tp_dbindex, (long) tp->tp_size));
                break;
 
-       /* constructed types ... */
+               /* constructed types ... */
        case POINTER:
                addc_db_str('*');
                stb_type(tp->tp_up);
                break;
        case ARRAY:
-               if (tp->tp_size > 0) {
+               if (tp->tp_size > 0)
+               {
                        adds_db_str("ar");
                        stb_type(int_type);
-                       adds_db_str(sprint(buf, ";0;%ld;", tp->tp_size / tp->tp_up->tp_size - 1));
+                       adds_db_str(
+                                       sprint(buf, ";0;%ld;",
+                                                       tp->tp_size / tp->tp_up->tp_size - 1));
                        stb_type(tp->tp_up);
                }
                break;
        case ENUM:
-               if (tp->tp_size < 0) {
-                       adds_db_str(sprint(buf,
-                                          "xe%s:",
-                                          tp->tp_idf->id_text));
+               if (tp->tp_size < 0)
+               {
+                       adds_db_str(sprint(buf, "xe%s:", tp->tp_idf->id_text));
                        tp->tp_dbindex = -tp->tp_dbindex;
                        break;
                }
@@ -151,15 +148,16 @@ stb_type(tp)
                {
                        register struct stack_entry *se = local_level->sl_entry;
 
-                       while (se) {
-                               register struct def     *edef = se->se_idf->id_def;
-                               while (edef) {
-                                       if (edef->df_type == tp &&
-                                           edef->df_sc == ENUM) {
-                                               adds_db_str(sprint(buf,
-                                                       "%s:%ld,",
-                                                       se->se_idf->id_text,
-                                                       edef->df_address));
+                       while (se)
+                       {
+                               register struct def *edef = se->se_idf->id_def;
+                               while (edef)
+                               {
+                                       if (edef->df_type == tp && edef->df_sc == ENUM)
+                                       {
+                                               adds_db_str(
+                                                               sprint(buf, "%s:%ld,", se->se_idf->id_text,
+                                                                               edef->df_address));
                                        }
                                        edef = edef->next;
                                }
@@ -170,37 +168,39 @@ stb_type(tp)
                break;
        case STRUCT:
        case UNION:
-               if (tp->tp_size < 0) {
-                       adds_db_str(sprint(buf,
-                                          "x%c%s:",
-                                          tp->tp_fund == STRUCT ? 's' : 'u',
-                                          tp->tp_idf->id_text));
+               if (tp->tp_size < 0)
+               {
+                       adds_db_str(
+                                       sprint(buf, "x%c%s:", tp->tp_fund == STRUCT ? 's' : 'u',
+                                                       tp->tp_idf->id_text));
                        tp->tp_dbindex = -tp->tp_dbindex;
                        break;
                }
-               adds_db_str(sprint(buf,
-                                  "%c%ld",
-                                  tp->tp_fund == STRUCT ? 's' : 'u',
-                                  tp->tp_size));
+               adds_db_str(
+                               sprint(buf, "%c%ld", tp->tp_fund == STRUCT ? 's' : 'u',
+                                               tp->tp_size));
                {
-                       register struct sdef    *sdef = tp->tp_sdef;
+                       register struct sdef *sdef = tp->tp_sdef;
 
-                       while (sdef) {
+                       while (sdef)
+                       {
                                adds_db_str(sdef->sd_idf->id_text);
                                addc_db_str(':');
-                               if (sdef->sd_type->tp_fund == FIELD) {
+                               if (sdef->sd_type->tp_fund == FIELD)
+                               {
                                        stb_type(sdef->sd_type->tp_up);
-                                       adds_db_str(sprint(buf,
-                                               ",%ld,%ld;",
-                                               sdef->sd_offset*8+sdef->sd_type->tp_field->fd_shift,
-                                               sdef->sd_type->tp_field->fd_width));
+                                       adds_db_str(
+                                                       sprint(buf, ",%ld,%ld;",
+                                                                       sdef->sd_offset * 8
+                                                                                       + sdef->sd_type->tp_field->fd_shift,
+                                                                       sdef->sd_type->tp_field->fd_width));
                                }
-                               else {
+                               else
+                               {
                                        stb_type(sdef->sd_type);
-                                       adds_db_str(sprint(buf,
-                                               ",%ld,%ld;",
-                                               sdef->sd_offset*8,
-                                               sdef->sd_type->tp_size*8));
+                                       adds_db_str(
+                                                       sprint(buf, ",%ld,%ld;", sdef->sd_offset * 8,
+                                                                       sdef->sd_type->tp_size * 8));
                                }
                                sdef = sdef->sd_sdef;
                        }
@@ -213,9 +213,7 @@ stb_type(tp)
        }
 }
 
-stb_tag(tg, str)
-       register struct tag     *tg;
-       char                    *str;
+void stb_tag(register struct tag *tg, char *str)
 {
        create_db_str();
        adds_db_str(str);
@@ -223,16 +221,12 @@ stb_tag(tg, str)
        stb_type(tg->tg_type);
        addc_db_str(';');
        C_ms_stb_cst(db_str.base,
-                    N_LSYM,
-                    tg->tg_type == void_type || tg->tg_type->tp_size >= 32767
-                      ? 0
-                      : (int)tg->tg_type->tp_size,
-                    (arith) 0);
+       N_LSYM,
+                       tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 ?
+                                       0 : (int) tg->tg_type->tp_size, (arith) 0);
 }
 
-stb_typedef(tp, str)
-       register struct type    *tp;
-       char                    *str;
+void stb_typedef(register struct type *tp, char *str)
 {
        create_db_str();
        adds_db_str(str);
@@ -240,23 +234,19 @@ stb_typedef(tp, str)
        stb_type(tp);
        addc_db_str(';');
        C_ms_stb_cst(db_str.base,
-                    N_LSYM,
-                    tp == void_type || tp->tp_size >= 32767
-                      ? 0
-                      : (int)tp->tp_size,
-                    (arith) 0);
+       N_LSYM, tp == void_type || tp->tp_size >= 32767 ? 0 : (int) tp->tp_size,
+                       (arith) 0);
 }
 
-stb_string(df, kind, str)
-       register struct def     *df;
-       char                    *str;
+void stb_string(register struct def *df, int kind, char* str)
 {
-       register struct type    *tp = df->df_type;
+       register struct type *tp = df->df_type;
 
        create_db_str();
        adds_db_str(str);
        addc_db_str(':');
-       switch(kind) {
+       switch (kind)
+       {
        case FUNCTION:
                addc_db_str(df->df_sc == STATIC ? 'f' : 'F');
                stb_type(tp->tp_up);
@@ -264,40 +254,50 @@ stb_string(df, kind, str)
                C_ms_stb_pnam(db_str.base, N_FUN, 1 /* proclevel */, str);
                break;
        default:
-               if (df->df_sc == FORMAL ||
-                   (df->df_sc == REGISTER && df->df_address >= 0)) {
-                                               /* value parameter */
+               if (df->df_sc == FORMAL
+                               || (df->df_sc == REGISTER && df->df_address >= 0))
+               {
+                       /* value parameter */
                        addc_db_str('p');
                        stb_type(tp);
                        addc_db_str(';');
                        C_ms_stb_cst(db_str.base, N_PSYM, 0, df->df_address);
                }
-               else if (df->df_sc != AUTO && df->df_sc != REGISTER) {
-                                               /* global */
+               else if (df->df_sc != AUTO && df->df_sc != REGISTER)
+               {
+                       /* global */
                        int stabtp = df->df_initialized ? N_STSYM : N_LCSYM;
-                       if (df->df_sc == STATIC) {
-                               if (df->df_level >= L_LOCAL) {
+                       if (df->df_sc == STATIC)
+                       {
+                               if (df->df_level >= L_LOCAL)
+                               {
                                        addc_db_str('V');
                                }
-                               else {
+                               else
+                               {
                                        addc_db_str('S');
                                }
                        }
-                       else {
+                       else
+                       {
                                addc_db_str('G');
                        }
                        stb_type(tp);
                        addc_db_str(';');
-                       if (df->df_sc == STATIC && df->df_level >= L_LOCAL) {
-                               C_ms_stb_dlb(db_str.base, stabtp, 0, (label) df->df_address, (arith) 0);
+                       if (df->df_sc == STATIC && df->df_level >= L_LOCAL)
+                       {
+                               C_ms_stb_dlb(db_str.base, stabtp, 0, (label) df->df_address,
+                                               (arith) 0);
                        }
-                       else {
+                       else
+                       {
                                C_ms_stb_dnam(db_str.base, stabtp, 0, str, (arith) 0);
                        }
                }
-               else {  /* local variable */
-                       stb_type(tp);   /* assign type num to avoid
-                                                  difficult to parse string */
+               else
+               { /* local variable */
+                       stb_type(tp); /* assign type num to avoid
+                        difficult to parse string */
                        addc_db_str(';');
                        C_ms_stb_cst(db_str.base, N_LSYM, 0, df->df_address);
                }
diff --git a/lang/cem/cemcom.ansi/stab.h b/lang/cem/cemcom.ansi/stab.h
new file mode 100644 (file)
index 0000000..5f584ad
--- /dev/null
@@ -0,0 +1,20 @@
+/*  Copyright (c) 2019 ACK Project.
+ *  See the copyright notice in the ACK home directory, 
+ *  in the file "Copyright".
+ *
+ *  Created on: 2019-02-07
+ *  
+ */
+#ifndef STAB_H_
+#define STAB_H_
+
+
+struct def;
+struct type;
+struct tag;
+
+void stb_tag(register struct tag *tg, char *str);
+void stb_typedef(register struct type *tp, char *str);
+void stb_string(register struct def *df, int kind, char* str);
+
+#endif /* STAB_H_ */
index c8616b8..1d2cd69 100644 (file)
@@ -22,6 +22,9 @@
 #include       "struct.h"
 #include       "level.h"
 #include       "mes.h"
+#include    "code.h"
+#include    "util.h"
+#include    "error.h"
 
 /* #include    <em_reg.h> */
 
@@ -41,7 +44,7 @@ struct stack_level *local_level = &UniversalLevel;
 
 int level;     /* Always equal to local_level->sl_level. */
 
-stack_level()  {
+void stack_level(void) {
        /*      A new level is added on top of the identifier stack.
        */
        register struct stack_level *stl = new_stack_level();
@@ -57,10 +60,9 @@ stack_level()        {
 #endif /* LINT */
 }
 
-void
-stack_idf(idf, stl)
-       struct idf *idf;
-       register struct stack_level *stl;
+void stack_idf(
+       struct idf *idf,
+       register struct stack_level *stl)
 {
        /*      The identifier idf is inserted in the stack on level stl,
                but only if it is not already present at this level.
@@ -81,8 +83,7 @@ stack_idf(idf, stl)
        stl->sl_entry = se;
 }
 
-struct stack_level *
-stack_level_of(lvl)
+struct stack_level *stack_level_of(int lvl)
 {
        /*      The stack_level corresponding to level lvl is returned.
                The stack should probably be an array, to be extended with
@@ -100,7 +101,7 @@ stack_level_of(lvl)
        return stl;
 }
 
-unstack_level()
+void unstack_level(void)
 {
        /*      The top level of the identifier stack is removed.
        */
@@ -174,7 +175,7 @@ unstack_level()
 #endif /* DEBUG */
 }
 
-unstack_world()
+void unstack_world(void)
 {
        /*      The global level of identifiers is scanned, and final
                decisions are taken about such issues as
@@ -263,14 +264,13 @@ unstack_world()
 extern char *nmlist;   /* BAH! -- main.c       */
 static File *nfp = 0;
 
-open_name_list()
+void open_name_list(void)
 {
        if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0)
                fatal("cannot create namelist %s", nmlist);
 }
 
-namelist(nm)
-       char *nm;
+void namelist(char *nm)
 {
        if (nmlist)     {
                sys_write(nfp, nm, strlen(nm));
index ddb38c5..a7f59d1 100644 (file)
@@ -2,9 +2,14 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef STACK_H_
+#define STACK_H_
+
 /* $Id$ */
 /* IDENTIFIER STACK DEFINITIONS */
 
+struct idf;
+
 /*     The identifier stack is implemented as a stack of sets.
        The stack is implemented by a doubly linked list,
        the sets by singly linked lists.
@@ -30,5 +35,26 @@ struct stack_entry   {
 /* ALLOCDEF "stack_entry" 50 */
 
 extern struct stack_level *local_level;
-extern struct stack_level *stack_level_of();
 extern int level;
+
+/*     A new level is added on top of the identifier stack. */
+void stack_level(void);
+/*     The identifier idf is inserted in the stack on level stl,
+       but only if it is not already present at this level.
+*/
+void stack_idf(struct idf *idf, register struct stack_level *stl);
+/*The stack_level corresponding to level lvl is returned.
+  The stack should probably be an array, to be extended with
+ realloc where needed.
+*/
+struct stack_level *stack_level_of(int lvl);
+/* The top level of the identifier stack is removed. */
+void unstack_level(void);
+void unstack_world(void);
+
+#ifdef GEN_NM_LIST
+void open_name_list(void);
+void namelist(char *nm);
+#endif /* GEN_NM_LIST */
+
+#endif 
index 9eb60d2..3d1dcd4 100644 (file)
-/*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
-/* $Id$ */
-/*     STATEMENT SYNTAX PARSER */
-
-{
-#include       "parameters.h"
-#ifndef        LINT
-#include       <em.h>
-#else
-#include       "l_em.h"
-#include       "l_lint.h"
-#endif /* LINT */
-
-#include       <flt_arith.h>
-#include    "idf.h"
-#include       "arith.h"
-#include       "LLlex.h"
-#include       "type.h"
-#include       "label.h"
-#include       "expr.h"
-#include       "code.h"
-#include       "stack.h"
-#include       "def.h"
-#ifdef DBSYMTAB
-#include       <stb.h>
-#endif /* DBSYMTAB */
-
-extern int level;
-extern char options[];
-}
-
-/* Each statement construction is stacked in order to trace a
- * statement to such a construction. Example: a case statement should
- * be recognized as a piece of the most enclosing switch statement.
- */
-
-/* 3.6 */
-statement
-       {
-#ifdef LINT
-               lint_statement();
-#endif /* LINT */
-       }
-:
-%if (AHEAD != ':')
-       expression_statement
-|
-       label ':' statement
-|
-       compound_statement
-|
-       if_statement
-|
-       while_statement
-|
-       do_statement
-|
-       for_statement
-|
-       switch_statement
-|
-       case_statement
-|
-       default_statement
-|
-       BREAK
-       {
-               code_break();
-#ifdef LINT
-               lint_break_stmt();
-#endif /* LINT */
-       }
-       ';'
-|
-       CONTINUE
-       {
-               code_continue();
-#ifdef LINT
-               lint_continue_stmt();
-#endif /* LINT */
-       }
-       ';'
-|
-       return_statement
-|
-       jump
-|
-       ';'
-;
-
-
-expression_statement
-       {       struct expr *expr;
-       }
-:
-       expression(&expr)
-       ';'
-               {
-#ifdef DEBUG
-                       print_expr("expression_statement", expr);
-#endif /* DEBUG */
-                       code_expr(expr, RVAL, FALSE, NO_LABEL, NO_LABEL);
-                       free_expression(expr);
-               }
-;
-
-/* 3.6.1 (partially) */
-label
-       { struct idf *idf; }
-:
-       identifier(&idf)
-       {
-               /*      This allows the following absurd case:
-
-                               typedef int grz;
-                               main()  {
-                                       grz: printf("A labelled statement\n");
-                               }
-               */
-#ifdef LINT
-               lint_label();
-#endif /* LINT */
-               define_label(idf);
-               C_df_ilb((label)idf->id_label->df_address);
-       }
-;
-
-/* 3.6.4.1 */
-if_statement
-       {
-               struct expr *expr;
-               label l_true = text_label();
-               label l_false = text_label();
-               label l_end = text_label();
-       }
-:
-       IF
-       '('
-       expression(&expr)
-               {
-                       opnd2test(&expr, IF);
-                       if (is_cp_cst(expr))    {
-                               /*      The comparison has been optimized
-                                       to a 0 or 1.
-                               */
-                               if (expr->VL_VALUE == (arith)0) {
-                                       C_bra(l_false);
-                               }
-                               /* else fall through */
-#ifdef LINT
-                               start_if_part(1);
-#endif /* LINT */
-                       }
-                       else    {
-                               code_expr(expr, RVAL, TRUE, l_true, l_false);
-                               C_df_ilb(l_true);
-#ifdef LINT
-                               start_if_part(0);
-#endif /* LINT */
-                       }
-                       free_expression(expr);
-               }
-       ')'
-       statement
-       [%prefer
-               ELSE
-                       {
-#ifdef LINT
-                               start_else_part();
-#endif /* LINT */
-                               C_bra(l_end);
-                               C_df_ilb(l_false);
-                       }
-               statement
-                       {       C_df_ilb(l_end);
-#ifdef LINT
-                               end_if_else_stmt();
-#endif /* LINT */
-                       }
-       |
-               empty
-                       {       C_df_ilb(l_false);
-#ifdef LINT
-                               end_if_stmt();
-#endif /* LINT */
-                       }
-       ]
-;
-
-/* 3.6.5.3 */
-while_statement
-       {
-               struct expr *expr;
-               label l_break = text_label();
-               label l_continue = text_label();
-               label l_body = text_label();
-       }
-:
-       WHILE
-               {
-                       stack_stmt(l_break, l_continue);
-                       C_df_ilb(l_continue);
-               }
-       '('
-       expression(&expr)
-               {
-                       opnd2test(&expr, WHILE);
-                       if (is_cp_cst(expr))    {
-                               if (expr->VL_VALUE == (arith)0) {
-                                       C_bra(l_break);
-                               }
-                       }
-                       else    {
-                               code_expr(expr, RVAL, TRUE, l_body, l_break);
-                               C_df_ilb(l_body);
-                       }
-#ifdef LINT
-                       start_while_stmt(expr);
-#endif /* LINT */
-               }
-       ')'
-       statement
-               {
-                       C_bra(l_continue);
-                       C_df_ilb(l_break);
-                       unstack_stmt();
-                       free_expression(expr);
-#ifdef LINT
-                       end_loop_body();
-                       end_loop_stmt();
-#endif /* LINT */
-               }
-;
-
-/* 3.6.5.2 */
-do_statement
-       {       struct expr *expr;
-               label l_break = text_label();
-               label l_continue = text_label();
-               label l_body = text_label();
-       }
-:
-       DO
-               {       C_df_ilb(l_body);
-                       stack_stmt(l_break, l_continue);
-#ifdef LINT
-                       start_do_stmt();
-#endif /* LINT */
-               }
-       statement
-       WHILE
-       '('
-               {
-#ifdef LINT
-                       end_loop_body();
-#endif /* LINT */
-                       C_df_ilb(l_continue);
-               }
-       expression(&expr)
-               {
-                       opnd2test(&expr, WHILE);
-                       if (is_cp_cst(expr))    {
-                               if (expr->VL_VALUE == (arith)1) {
-                                       C_bra(l_body);
-                               }
-#ifdef LINT
-                               end_do_stmt(1, expr->VL_VALUE != (arith)0);
-#endif /* LINT */
-                       }
-                       else    {
-                               code_expr(expr, RVAL, TRUE, l_body, l_break);
-#ifdef LINT
-                               end_do_stmt(0, 0);
-#endif /* LINT */
-                       }
-                       C_df_ilb(l_break);
-               }
-       ')'
-       ';'
-               {
-                       unstack_stmt();
-                       free_expression(expr);
-               }
-;
-
-/* 3.6.5.3 */
-for_statement
-       {       struct expr *e_init = 0, *e_test = 0, *e_incr = 0;
-               label l_break = text_label();
-               label l_continue = text_label();
-               label l_body = text_label();
-               label l_test = text_label();
-       }
-:
-       FOR
-               {       stack_stmt(l_break, l_continue);
-               }
-       '('
-       [
-               expression(&e_init)
-               {       code_expr(e_init, RVAL, FALSE, NO_LABEL, NO_LABEL);
-               }
-       ]?
-       ';'
-               {       C_df_ilb(l_test);
-               }
-       [
-               expression(&e_test)
-               {
-                       opnd2test(&e_test, FOR);
-                       if (is_cp_cst(e_test))  {
-                               if (e_test->VL_VALUE == (arith)0)       {
-                                       C_bra(l_break);
-                               }
-                       }
-                       else    {
-                               code_expr(e_test, RVAL, TRUE, l_body, l_break);
-                               C_df_ilb(l_body);
-                       }
-               }
-       ]?
-       ';'
-       expression(&e_incr)?
-       ')'
-               {
-#ifdef LINT
-                       start_for_stmt(e_test);
-#endif /* LINT */
-               }
-       statement
-               {
-#ifdef LINT
-                       end_loop_body();
-#endif /* LINT */
-                       C_df_ilb(l_continue);
-                       if (e_incr)
-                               code_expr(e_incr, RVAL, FALSE,
-                                                       NO_LABEL, NO_LABEL);
-                       C_bra(l_test);
-                       C_df_ilb(l_break);
-                       unstack_stmt();
-                       free_expression(e_init);
-                       free_expression(e_test);
-                       free_expression(e_incr);
-#ifdef LINT
-                       end_loop_stmt();
-#endif /* LINT */
-               }
-;
-
-/* 3.6.4.2 */
-switch_statement
-       {
-               struct expr *expr;
-       }
-:
-       SWITCH
-       '('
-       expression(&expr)
-               {
-                       code_startswitch(&expr);
-#ifdef LINT
-                       start_switch_part(is_cp_cst(expr));
-#endif /* LINT */
-               }
-       ')'
-       statement
-               {
-#ifdef LINT
-                       end_switch_stmt();
-#endif /* LINT */
-                       code_endswitch();
-                       free_expression(expr);
-               }
-;
-
-/* 3.6.1 (partially) */
-case_statement
-       {
-               struct expr *expr;
-       }
-:
-       CASE
-       constant_expression(&expr)
-               {
-#ifdef LINT
-                       lint_case_stmt(0);
-#endif /* LINT */
-                       code_case(expr);
-                       free_expression(expr);
-               }
-       ':'
-       statement
-;
-
-/* 3.6.1 (partially) */
-default_statement
-:
-       DEFAULT
-               {
-#ifdef LINT
-                       lint_case_stmt(1);
-#endif /* LINT */
-                       code_default();
-               }
-       ':'
-       statement
-;
-
-/* 3.6.6.4 */
-return_statement
-       {       struct expr *expr = 0;
-       }
-:
-       RETURN
-       [
-               expression(&expr)
-               {
-#ifdef LINT
-                       lint_ret_conv(expr);
-#endif /* LINT */
-
-                       do_return_expr(expr);
-                       free_expression(expr);
-#ifdef LINT
-                       lint_return_stmt(VALRETURNED);
-#endif /* LINT */
-               }
-       |
-               empty
-               {
-                       do_return();
-#ifdef LINT
-                       lint_return_stmt(NOVALRETURNED);
-#endif /* LINT */
-               }
-       ]
-       ';'
-;
-
-/* 3.6.6.1 (partially) */
-jump
-       {       struct idf *idf;
-       }
-:
-       GOTO
-       identifier(&idf)
-       ';'
-               {
-                       apply_label(idf);
-                       C_bra((label)idf->id_label->df_address);
-#ifdef LINT
-                       lint_jump_stmt(idf);
-#endif /* LINT */
-               }
-;
-
-/* 3.6.2 */
-compound_statement
-       {
-#ifdef DBSYMTAB
-       static int      brc_level = 1;
-       int             decl_seen = brc_level == 1;
-#endif /* DBSYMTAB */
-       }
-:
-       '{'
-               {
-                       stack_level();
-               }
-       [%while ((DOT != IDENTIFIER && AHEAD != ':') ||
-                (DOT == IDENTIFIER && AHEAD == IDENTIFIER))
-                       /* >>> conflict on TYPE_IDENTIFIER, IDENTIFIER */
-               declaration
-               {
-#ifdef DBSYMTAB
-                       decl_seen++;
-#endif /* DBSYMTAB */
-               }
-       ]*
-               {
-#ifdef DBSYMTAB
-                       ++brc_level;
-                       if (options['g'] && decl_seen) {
-                               C_ms_std((char *) 0, N_LBRAC, brc_level);
-                       }
-#endif /* DBSYMTAB */
-               }
-       [%persistent
-               statement
-       ]*
-       '}'
-               {
-                       unstack_level();
-#ifdef DBSYMTAB
-                       if (options['g'] && decl_seen) {
-                               C_ms_std((char *) 0, N_RBRAC, brc_level);
-                       }
-                       brc_level--;
-#endif /* DBSYMTAB */
-               }
-;
+/*\r
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.\r
+ * See the copyright notice in the ACK home directory, in the file "Copyright".\r
+ */\r
+/* $Id$ */\r
+/*     STATEMENT SYNTAX PARSER */\r
+\r
+{\r
+#include       "parameters.h"\r
+#ifndef        LINT\r
+#include       <em.h>\r
+#else\r
+#include       "l_em.h"\r
+#include       "l_lint.h"\r
+#endif /* LINT */\r
+\r
+#include       <flt_arith.h>\r
+#include    "idf.h"\r
+#include       "arith.h"\r
+#include       "LLlex.h"\r
+#include       "type.h"\r
+#include       "label.h"\r
+#include       "expr.h"\r
+#include       "code.h"\r
+#include       "stack.h"\r
+#include       "def.h"\r
+#include    "switch.h"\r
+#ifdef DBSYMTAB\r
+#include       <stb.h>\r
+#endif /* DBSYMTAB */\r
+\r
+extern int level;\r
+extern char options[];\r
+}\r
+\r
+/* Each statement construction is stacked in order to trace a\r
+ * statement to such a construction. Example: a case statement should\r
+ * be recognized as a piece of the most enclosing switch statement.\r
+ */\r
+\r
+/* 3.6 */\r
+statement\r
+       {\r
+#ifdef LINT\r
+               lint_statement();\r
+#endif /* LINT */\r
+       }\r
+:\r
+%if (AHEAD != ':')\r
+       expression_statement\r
+|\r
+       label ':' statement\r
+|\r
+       compound_statement\r
+|\r
+       if_statement\r
+|\r
+       while_statement\r
+|\r
+       do_statement\r
+|\r
+       for_statement\r
+|\r
+       switch_statement\r
+|\r
+       case_statement\r
+|\r
+       default_statement\r
+|\r
+       BREAK\r
+       {\r
+               code_break();\r
+#ifdef LINT\r
+               lint_break_stmt();\r
+#endif /* LINT */\r
+       }\r
+       ';'\r
+|\r
+       CONTINUE\r
+       {\r
+               code_continue();\r
+#ifdef LINT\r
+               lint_continue_stmt();\r
+#endif /* LINT */\r
+       }\r
+       ';'\r
+|\r
+       return_statement\r
+|\r
+       jump\r
+|\r
+       ';'\r
+;\r
+\r
+\r
+expression_statement\r
+       {       struct expr *expr;\r
+       }\r
+:\r
+       expression(&expr)\r
+       ';'\r
+               {\r
+#ifdef DEBUG\r
+                       print_expr("expression_statement", expr);\r
+#endif /* DEBUG */\r
+                       code_expr(expr, RVAL, FALSE, NO_LABEL, NO_LABEL);\r
+                       free_expression(expr);\r
+               }\r
+;\r
+\r
+/* 3.6.1 (partially) */\r
+label\r
+       { struct idf *idf; }\r
+:\r
+       identifier(&idf)\r
+       {\r
+               /*      This allows the following absurd case:\r
+\r
+                               typedef int grz;\r
+                               main()  {\r
+                                       grz: printf("A labelled statement\n");\r
+                               }\r
+               */\r
+#ifdef LINT\r
+               lint_label();\r
+#endif /* LINT */\r
+               define_label(idf);\r
+               C_df_ilb((label)idf->id_label->df_address);\r
+       }\r
+;\r
+\r
+/* 3.6.4.1 */\r
+if_statement\r
+       {\r
+               struct expr *expr;\r
+               label l_true = text_label();\r
+               label l_false = text_label();\r
+               label l_end = text_label();\r
+       }\r
+:\r
+       IF\r
+       '('\r
+       expression(&expr)\r
+               {\r
+                       opnd2test(&expr, IF);\r
+                       if (is_cp_cst(expr))    {\r
+                               /*      The comparison has been optimized\r
+                                       to a 0 or 1.\r
+                               */\r
+                               if (expr->VL_VALUE == (arith)0) {\r
+                                       C_bra(l_false);\r
+                               }\r
+                               /* else fall through */\r
+#ifdef LINT\r
+                               start_if_part(1);\r
+#endif /* LINT */\r
+                       }\r
+                       else    {\r
+                               code_expr(expr, RVAL, TRUE, l_true, l_false);\r
+                               C_df_ilb(l_true);\r
+#ifdef LINT\r
+                               start_if_part(0);\r
+#endif /* LINT */\r
+                       }\r
+                       free_expression(expr);\r
+               }\r
+       ')'\r
+       statement\r
+       [%prefer\r
+               ELSE\r
+                       {\r
+#ifdef LINT\r
+                               start_else_part();\r
+#endif /* LINT */\r
+                               C_bra(l_end);\r
+                               C_df_ilb(l_false);\r
+                       }\r
+               statement\r
+                       {       C_df_ilb(l_end);\r
+#ifdef LINT\r
+                               end_if_else_stmt();\r
+#endif /* LINT */\r
+                       }\r
+       |\r
+               empty\r
+                       {       C_df_ilb(l_false);\r
+#ifdef LINT\r
+                               end_if_stmt();\r
+#endif /* LINT */\r
+                       }\r
+       ]\r
+;\r
+\r
+/* 3.6.5.3 */\r
+while_statement\r
+       {\r
+               struct expr *expr;\r
+               label l_break = text_label();\r
+               label l_continue = text_label();\r
+               label l_body = text_label();\r
+       }\r
+:\r
+       WHILE\r
+               {\r
+                       stack_stmt(l_break, l_continue);\r
+                       C_df_ilb(l_continue);\r
+               }\r
+       '('\r
+       expression(&expr)\r
+               {\r
+                       opnd2test(&expr, WHILE);\r
+                       if (is_cp_cst(expr))    {\r
+                               if (expr->VL_VALUE == (arith)0) {\r
+                                       C_bra(l_break);\r
+                               }\r
+                       }\r
+                       else    {\r
+                               code_expr(expr, RVAL, TRUE, l_body, l_break);\r
+                               C_df_ilb(l_body);\r
+                       }\r
+#ifdef LINT\r
+                       start_while_stmt(expr);\r
+#endif /* LINT */\r
+               }\r
+       ')'\r
+       statement\r
+               {\r
+                       C_bra(l_continue);\r
+                       C_df_ilb(l_break);\r
+                       unstack_stmt();\r
+                       free_expression(expr);\r
+#ifdef LINT\r
+                       end_loop_body();\r
+                       end_loop_stmt();\r
+#endif /* LINT */\r
+               }\r
+;\r
+\r
+/* 3.6.5.2 */\r
+do_statement\r
+       {       struct expr *expr;\r
+               label l_break = text_label();\r
+               label l_continue = text_label();\r
+               label l_body = text_label();\r
+       }\r
+:\r
+       DO\r
+               {       C_df_ilb(l_body);\r
+                       stack_stmt(l_break, l_continue);\r
+#ifdef LINT\r
+                       start_do_stmt();\r
+#endif /* LINT */\r
+               }\r
+       statement\r
+       WHILE\r
+       '('\r
+               {\r
+#ifdef LINT\r
+                       end_loop_body();\r
+#endif /* LINT */\r
+                       C_df_ilb(l_continue);\r
+               }\r
+       expression(&expr)\r
+               {\r
+                       opnd2test(&expr, WHILE);\r
+                       if (is_cp_cst(expr))    {\r
+                               if (expr->VL_VALUE == (arith)1) {\r
+                                       C_bra(l_body);\r
+                               }\r
+#ifdef LINT\r
+                               end_do_stmt(1, expr->VL_VALUE != (arith)0);\r
+#endif /* LINT */\r
+                       }\r
+                       else    {\r
+                               code_expr(expr, RVAL, TRUE, l_body, l_break);\r
+#ifdef LINT\r
+                               end_do_stmt(0, 0);\r
+#endif /* LINT */\r
+                       }\r
+                       C_df_ilb(l_break);\r
+               }\r
+       ')'\r
+       ';'\r
+               {\r
+                       unstack_stmt();\r
+                       free_expression(expr);\r
+               }\r
+;\r
+\r
+/* 3.6.5.3 */\r
+for_statement\r
+       {       struct expr *e_init = 0, *e_test = 0, *e_incr = 0;\r
+               label l_break = text_label();\r
+               label l_continue = text_label();\r
+               label l_body = text_label();\r
+               label l_test = text_label();\r
+       }\r
+:\r
+       FOR\r
+               {       stack_stmt(l_break, l_continue);\r
+               }\r
+       '('\r
+       [\r
+               expression(&e_init)\r
+               {       code_expr(e_init, RVAL, FALSE, NO_LABEL, NO_LABEL);\r
+               }\r
+       ]?\r
+       ';'\r
+               {       C_df_ilb(l_test);\r
+               }\r
+       [\r
+               expression(&e_test)\r
+               {\r
+                       opnd2test(&e_test, FOR);\r
+                       if (is_cp_cst(e_test))  {\r
+                               if (e_test->VL_VALUE == (arith)0)       {\r
+                                       C_bra(l_break);\r
+                               }\r
+                       }\r
+                       else    {\r
+                               code_expr(e_test, RVAL, TRUE, l_body, l_break);\r
+                               C_df_ilb(l_body);\r
+                       }\r
+               }\r
+       ]?\r
+       ';'\r
+       expression(&e_incr)?\r
+       ')'\r
+               {\r
+#ifdef LINT\r
+                       start_for_stmt(e_test);\r
+#endif /* LINT */\r
+               }\r
+       statement\r
+               {\r
+#ifdef LINT\r
+                       end_loop_body();\r
+#endif /* LINT */\r
+                       C_df_ilb(l_continue);\r
+                       if (e_incr)\r
+                               code_expr(e_incr, RVAL, FALSE,\r
+                                                       NO_LABEL, NO_LABEL);\r
+                       C_bra(l_test);\r
+                       C_df_ilb(l_break);\r
+                       unstack_stmt();\r
+                       free_expression(e_init);\r
+                       free_expression(e_test);\r
+                       free_expression(e_incr);\r
+#ifdef LINT\r
+                       end_loop_stmt();\r
+#endif /* LINT */\r
+               }\r
+;\r
+\r
+/* 3.6.4.2 */\r
+switch_statement\r
+       {\r
+               struct expr *expr;\r
+       }\r
+:\r
+       SWITCH\r
+       '('\r
+       expression(&expr)\r
+               {\r
+                       code_startswitch(&expr);\r
+#ifdef LINT\r
+                       start_switch_part(is_cp_cst(expr));\r
+#endif /* LINT */\r
+               }\r
+       ')'\r
+       statement\r
+               {\r
+#ifdef LINT\r
+                       end_switch_stmt();\r
+#endif /* LINT */\r
+                       code_endswitch();\r
+                       free_expression(expr);\r
+               }\r
+;\r
+\r
+/* 3.6.1 (partially) */\r
+case_statement\r
+       {\r
+               struct expr *expr;\r
+       }\r
+:\r
+       CASE\r
+       constant_expression(&expr)\r
+               {\r
+#ifdef LINT\r
+                       lint_case_stmt(0);\r
+#endif /* LINT */\r
+                       code_case(expr);\r
+                       free_expression(expr);\r
+               }\r
+       ':'\r
+       statement\r
+;\r
+\r
+/* 3.6.1 (partially) */\r
+default_statement\r
+:\r
+       DEFAULT\r
+               {\r
+#ifdef LINT\r
+                       lint_case_stmt(1);\r
+#endif /* LINT */\r
+                       code_default();\r
+               }\r
+       ':'\r
+       statement\r
+;\r
+\r
+/* 3.6.6.4 */\r
+return_statement\r
+       {       struct expr *expr = 0;\r
+       }\r
+:\r
+       RETURN\r
+       [\r
+               expression(&expr)\r
+               {\r
+#ifdef LINT\r
+                       lint_ret_conv(expr);\r
+#endif /* LINT */\r
+\r
+                       do_return_expr(expr);\r
+                       free_expression(expr);\r
+#ifdef LINT\r
+                       lint_return_stmt(VALRETURNED);\r
+#endif /* LINT */\r
+               }\r
+       |\r
+               empty\r
+               {\r
+                       do_return();\r
+#ifdef LINT\r
+                       lint_return_stmt(NOVALRETURNED);\r
+#endif /* LINT */\r
+               }\r
+       ]\r
+       ';'\r
+;\r
+\r
+/* 3.6.6.1 (partially) */\r
+jump\r
+       {       struct idf *idf;\r
+       }\r
+:\r
+       GOTO\r
+       identifier(&idf)\r
+       ';'\r
+               {\r
+                       apply_label(idf);\r
+                       C_bra((label)idf->id_label->df_address);\r
+#ifdef LINT\r
+                       lint_jump_stmt(idf);\r
+#endif /* LINT */\r
+               }\r
+;\r
+\r
+/* 3.6.2 */\r
+compound_statement\r
+       {\r
+#ifdef DBSYMTAB\r
+       static int      brc_level = 1;\r
+       int             decl_seen = brc_level == 1;\r
+#endif /* DBSYMTAB */\r
+       }\r
+:\r
+       '{'\r
+               {\r
+                       stack_level();\r
+               }\r
+       [%while ((DOT != IDENTIFIER && AHEAD != ':') ||\r
+                (DOT == IDENTIFIER && AHEAD == IDENTIFIER))\r
+                       /* >>> conflict on TYPE_IDENTIFIER, IDENTIFIER */\r
+               declaration\r
+               {\r
+#ifdef DBSYMTAB\r
+                       decl_seen++;\r
+#endif /* DBSYMTAB */\r
+               }\r
+       ]*\r
+               {\r
+#ifdef DBSYMTAB\r
+                       ++brc_level;\r
+                       if (options['g'] && decl_seen) {\r
+                               C_ms_std((char *) 0, N_LBRAC, brc_level);\r
+                       }\r
+#endif /* DBSYMTAB */\r
+               }\r
+       [%persistent\r
+               statement\r
+       ]*\r
+       '}'\r
+               {\r
+                       unstack_level();\r
+#ifdef DBSYMTAB\r
+                       if (options['g'] && decl_seen) {\r
+                               C_ms_std((char *) 0, N_RBRAC, brc_level);\r
+                       }\r
+                       brc_level--;\r
+#endif /* DBSYMTAB */\r
+               }\r
+;\r
index 0a98e67..4fcd262 100644 (file)
@@ -3,10 +3,10 @@
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
 /* $Id$ */
-/* library routine for copying structs */
 
-__stb(n, f, t)
-       register char *f, *t; register n;
+
+/* library routine for copying structs */
+void __stb(register int n, register char *f, register char *t)
 {
        if (n > 0)
                do
index feaa82f..aea09b3 100644 (file)
@@ -2,6 +2,9 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef STMT_H_
+#define STMT_H_
+
 /* $Id$ */
 /*     S T A T E M E N T - B L O C K   D E F I N I T I O N S   */
 
@@ -12,3 +15,5 @@ struct stmt_block     {
 };
 
 /* ALLOCDEF "stmt_block" 5 */
+
+#endif
\ No newline at end of file
index a36b11e..fbba71a 100644 (file)
 #include       "Lpars.h"
 #include       "align.h"
 #include       "level.h"
+#include    "ch3.h"
 #include       "sizes.h"
+#include    "error.h"
 
 /*     Type of previous selector declared with a field width specified,
        if any.  If a selector is declared with no field with it is set to 0.
 */
-static field_busy = 0;
+static int field_busy = 0;
 
 extern char options[];
 char *symbol2str();
-int lcm();
+
+static void check_selector(register struct idf *, struct type *);
+/*     Greatest Common Divisor */
+static int gcd(register int , register int );
+/*     Least Common Multiple */
+static int lcm(register int, register int);
 
 /*     The semantics of the identification of structure/union tags is
        obscure.  Some highly regarded compilers are found out to accept,
@@ -51,13 +58,13 @@ int lcm();
        as well).
 */
 
-add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */
-       register struct type *stp;      /* type of the structure */
-       struct type *tp;                /* type of the selector */
-       register struct idf *idf;       /* idf of the selector */
-       struct sdef ***sdefpp;  /* address of hook to selector definition */
-       arith *szp;             /* pointer to struct size upto here */
-       struct field *fd;
+void add_sel( /* this is horrible */
+       register struct type *stp,      /* type of the structure */
+       struct type *tp,                /* type of the selector */
+       register struct idf *idf,       /* idf of the selector */
+       struct sdef ***sdefpp,  /* address of hook to selector definition */
+       arith *szp,             /* pointer to struct size upto here */
+       struct field *fd)
 {
        /*      The selector idf with type tp is added to two chains: the
                selector identification chain starting at idf->id_sdef,
@@ -147,12 +154,11 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)    /* this is horrible */
        }
 }
 
-check_selector(idf, stp)
-       register struct idf *idf;
-       struct type *stp;       /* the type of the struct */
+static void check_selector(register struct idf *idf, struct type *stp)
 {
        /*      checks if idf occurs already as a selector in
-               struct or union *stp.
+               struct or union *stp. "stp" indicates the type
+               of the struct.
        */
        register struct sdef *sdef = stp->tp_sdef;
        
@@ -163,9 +169,7 @@ check_selector(idf, stp)
        }
 }
 
-declare_struct(fund, idf, tpp)
-       register struct idf *idf;
-       struct type **tpp;
+void declare_struct(int fund, register struct idf *idf, struct type **tpp)
 {
        /*      A struct, union or enum (depending on fund) with tag (!)
                idf is declared, and its type (incomplete as it may be) is
@@ -232,9 +236,9 @@ declare_struct(fund, idf, tpp)
        }
 }
 
-apply_struct(fund, idf, tpp)
-       register struct idf *idf;
-       struct type **tpp;
+void apply_struct(int fund,
+       register struct idf *idf,
+       struct type **tpp)
 {
        /*      The occurrence of a struct, union or enum (depending on
                fund) with tag idf is noted. It may or may not have been
@@ -258,10 +262,9 @@ apply_struct(fund, idf, tpp)
                declare_struct(fund, idf, tpp);
 }
 
-struct sdef *
-idf2sdef(idf, tp)
-       register struct idf *idf;
-       struct type *tp;
+struct sdef *idf2sdef(
+       register struct idf *idf,
+       struct type *tp)
 {
        /*      The identifier idf is identified as a selector
                in the struct tp.
@@ -296,9 +299,7 @@ idf2sdef(idf, tp)
 }
 
 #if    0
-int
-uniq_selector(idf_sdef)
-       register struct sdef *idf_sdef;
+int uniq_selector(register struct sdef *idf_sdef)
 {
        /*      Returns true if idf_sdef (which is guaranteed to exist)
                is unique for this level, i.e there is no other selector
@@ -324,12 +325,12 @@ uniq_selector(idf_sdef)
 
 #ifndef NOBITFIELD
 arith
-add_field(szp, fd, fdtpp, idf, stp)
-       arith *szp;                     /* size of struct upto here     */
-       register struct field *fd;      /* bitfield, containing width   */
-       register struct type **fdtpp;   /* type of selector             */
-       struct idf *idf;                /* name of selector             */
-       register struct type *stp;      /* current struct descriptor    */
+add_field(
+       arith *szp,                     /* size of struct upto here     */
+       register struct field *fd,      /* bitfield, containing width   */
+       register struct type **fdtpp,   /* type of selector             */
+       struct idf *idf,                /* name of selector             */
+       register struct type *stp)      /* current struct descriptor    */
 {
        /*      The address where this selector is put is returned. If the
                selector with specified width does not fit in the word, or
@@ -438,18 +439,12 @@ add_field(szp, fd, fdtpp, idf, stp)
 #endif /* NOBITFIELD */
 
 /* some utilities */
-int
-is_struct_or_union(fund)
-       register int fund;
+int is_struct_or_union(register int fund)
 {
        return fund == STRUCT || fund == UNION;
 }
 
-/*     Greatest Common Divisor
- */
-int
-gcd(m, n)
-       register int m, n;
+static int gcd(register int m, register int n)
 {
        register int r;
 
@@ -461,11 +456,8 @@ gcd(m, n)
        return m;
 }
 
-/*     Least Common Multiple
- */
-int
-lcm(m, n)
-       register int m, n;
+
+static int lcm(register int m, register int n)
 {
        return m * (n / gcd(m, n));
 }
index 8dafd85..c0a9524 100644 (file)
@@ -2,7 +2,17 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef STRUCT_H_
+#define STRUCT_H_
+
 /* $Id$ */
+
+#include "arith.h"
+
+struct type;
+struct idf;
+struct field;
+
 /* SELECTOR DESCRIPTOR */
 
 struct sdef    {               /* for selectors */
@@ -27,4 +37,26 @@ struct tag   {               /* for struct-, union- and enum tags */
 
 /* ALLOCDEF "tag" 10 */
 
-struct sdef *idf2sdef();
+struct sdef *idf2sdef(register struct idf *idf, struct type *tp);
+void add_sel(
+       register struct type *stp,      /* type of the structure */
+       struct type *tp,                /* type of the selector */
+       register struct idf *idf,       /* idf of the selector */
+       struct sdef ***sdefpp,  /* address of hook to selector definition */
+       arith *szp,             /* pointer to struct size upto here */
+       struct field *fd);
+void declare_struct(int fund, register struct idf *idf, struct type **tpp);
+void apply_struct(int fund, register struct idf *idf, struct type **tpp);
+int is_struct_or_union(register int fund);
+
+#ifndef NOBITFIELD
+arith
+add_field(
+       arith *szp,                     /* size of struct upto here     */
+       register struct field *fd,      /* bitfield, containing width   */
+       register struct type **fdtpp,   /* type of selector             */
+       struct idf *idf,                /* name of selector             */
+       register struct type *stp);     /* current struct descriptor    */
+#endif 
+
+#endif
index 77a9dce..24cb82c 100644 (file)
 #include       "expr.h"
 #include       "type.h"
 #include       "sizes.h"
+#include    "switch.h"
+#include    "eval.h"
+#include    "ch3.h"
+#include    "error.h"
 
 extern char options[];
 
 int    density = DENSITY;
 
-compact(nr, low, up)
-       arith low, up;
+static int compact(int nr, arith low, arith up)
 {
        /*      Careful! up - low might not fit in an arith. And then,
                the test "up-low < 0" might also not work to detect this
@@ -49,8 +52,7 @@ static struct switch_hdr *switch_stack = 0;
        For simplicity, we suppose int_size == word_size.
 */
 
-code_startswitch(expp)
-       struct expr **expp;
+void code_startswitch(struct expr **expp)
 {
        /*      Check the expression, stack a new case header and
                fill in the necessary fields.
@@ -85,7 +87,7 @@ code_startswitch(expp)
        C_bra(l_table);                 /* goto start of switch_table   */
 }
 
-code_endswitch()
+void code_endswitch(void)
 {
        register struct switch_hdr *sh = switch_stack;
        register label tablabel;
@@ -158,9 +160,7 @@ code_endswitch()
        unstack_stmt();
 }
 
-void
-code_case(expr)
-       struct expr *expr;
+void code_case(struct expr *expr)
 {
        register arith val;
        register struct case_entry *ce;
@@ -227,8 +227,7 @@ code_case(expr)
        }
 }
 
-void
-code_default()
+void code_default(void)
 {
        register struct switch_hdr *sh = switch_stack;
 
index fd2dd45..94a45ca 100644 (file)
@@ -2,7 +2,16 @@
  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
+#ifndef SWITCH_H_
+#define SWITCH_H_
+
 /* $Id$ */
+
+#include "arith.h"
+
+struct type;
+struct expr;
+
 /*             S W I T C H - T A B L E - S T R U C T U R E             */
 
 struct switch_hdr      {
@@ -27,3 +36,12 @@ struct case_entry    {
 };
 
 /* ALLOCDEF "case_entry" 20 */
+
+void code_startswitch(struct expr **expp);
+void code_endswitch(void);
+void code_case(struct expr *expr);
+void code_default(void);
+
+
+
+#endif
\ No newline at end of file
diff --git a/lang/cem/cemcom.ansi/tokcase.sed b/lang/cem/cemcom.ansi/tokcase.sed
new file mode 100644 (file)
index 0000000..25cd5d9
--- /dev/null
@@ -0,0 +1,3 @@
+/{[A-Z]/!d
+s/.*{\(.*\),.*\(".*"\).*$/     case \1 :\
+       return \2;/
diff --git a/lang/cem/cemcom.ansi/tokcasee.in b/lang/cem/cemcom.ansi/tokcasee.in
new file mode 100644 (file)
index 0000000..5df07e7
--- /dev/null
@@ -0,0 +1,16 @@
+       default:\r
+               if (tok <= 0) return "end of file";\r
+               if (tok < 040 || tok >= 0177) {\r
+                       return "bad token";\r
+               }\r
+               /* fall through */\r
+       case '\n':\r
+       case '\f':\r
+       case '\v':\r
+       case '\r':\r
+       case '\t':\r
+               index = (index+2) & (SIZBUF-1);\r
+               buf[index] = tok;\r
+               return &buf[index];\r
+       }\r
+}
\ No newline at end of file
diff --git a/lang/cem/cemcom.ansi/tokcaseh.in b/lang/cem/cemcom.ansi/tokcaseh.in
new file mode 100644 (file)
index 0000000..63b1932
--- /dev/null
@@ -0,0 +1,12 @@
+/* Generated by make.tokcase */\r
+/* $Id$ */\r
+#include "Lpars.h"\r
+\r
+char *symbol2str(int tok)\r
+{\r
+#define SIZBUF 8\r
+       /* allow for a few invocations in f.i. an argument list */\r
+       static char buf[SIZBUF];\r
+       static int index;\r
+\r
+       switch (tok) {\r
index 8c52b4d..b430abb 100644 (file)
@@ -11,6 +11,7 @@
 #include       "LLlex.h"
 #include       "tokenname.h"
 #include       "Lpars.h"
+#include    "error.h"
 
 /*     To centralize the declaration of %tokens, their presence in this
        file is taken as their declaration. The Makefile will produce
@@ -132,8 +133,7 @@ struct tokenname tkfunny[] =        {       /* internal keywords */
 };
 #endif /* ____ */
 
-reserve(resv)
-       register struct tokenname resv[];
+void reserve(register struct tokenname resv[])
 {
        /*      The names of the tokens described in resv are entered
                as reserved words.
index fdff2fb..f3f5edb 100644 (file)
@@ -4,6 +4,8 @@
  */
 /* $Id$ */
 /* TOKENNAME DEFINITION */
+#ifndef TOKENNAME_H_
+#define TOKENNAME_H_
 
 struct tokenname       {       /*      Used for defining the name of a
                                        token as identified by its symbol
@@ -11,3 +13,7 @@ struct tokenname      {       /*      Used for defining the name of a
        int tn_symbol;
        char *tn_name;
 };
+
+void reserve(register struct tokenname resv[]);
+
+#endif /* TOKENNAME_H_ */
index 2b477a7..ff3a6ea 100644 (file)
 #include       "sizes.h"
 #include       "align.h"
 #include       "decspecs.h"
+#include    "error.h"
+
 
-extern struct type *function_of(), *array_of();
-#ifndef NOBITFIELD
-extern struct type *field_of();
-#endif /* NOBITFIELD */
 
 /*     To be created dynamically in main() from defaults or from command
-       line parameters.
-*/
-struct type
-       *schar_type, *uchar_type,
-       *short_type, *ushort_type,
-       *word_type, *uword_type,
-       *int_type, *uint_type,
-       *long_type, *ulong_type,
-       *float_type, *double_type, *lngdbl_type,
-       *void_type,
-       *string_type, *funint_type, *error_type;
-
-struct type *pa_type;  /* Pointer-Arithmetic type      */
-
-struct type *
-create_type(fund)
-       int fund;
+ line parameters.
+ */
+struct type *schar_type, *uchar_type, *short_type, *ushort_type, *word_type,
+               *uword_type, *int_type, *uint_type, *long_type, *ulong_type,
+               *float_type, *double_type, *lngdbl_type, *void_type, *string_type,
+               *funint_type, *error_type;
+
+struct type *pa_type; /* Pointer-Arithmetic type       */
+
+struct type *create_type(int fund)
 {
        /*      A brand new struct type is created, and its tp_fund set
-               to fund.
-       */
+        to fund.
+        */
        register struct type *ntp = new_type();
 
        ntp->tp_fund = fund;
-       ntp->tp_size = (arith)-1;
+       ntp->tp_size = (arith) -1;
 
        return ntp;
 }
 
-struct type *
-promoted_type(tp)
-struct type *tp;
+struct type *promoted_type(struct type *tp)
 {
-       if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) {
+       if (tp->tp_fund == CHAR || tp->tp_fund == SHORT)
+       {
                if (tp->tp_unsigned && (int) tp->tp_size == (int) int_size)
                        return uint_type;
-               else return int_type;
-       } else if (tp->tp_fund == FLOAT)
+               else
+                       return int_type;
+       }
+       else if (tp->tp_fund == FLOAT)
                return double_type;
-       else return tp;
+       else
+               return tp;
 }
 
-struct type *
-construct_type(fund, tp, qual, count, pl)
-       register struct type *tp;
-       register struct proto *pl;
-       arith count; /* for fund == ARRAY only */
-       int qual;
+struct type *construct_type(int fund, register struct type *tp, int qual,
+arith count, /* for fund == ARRAY only */
+register struct proto *pl)
 {
        /*      fund must be a type constructor: FIELD, FUNCTION, POINTER or
-               ARRAY. The pointer to the constructed type is returned.
-       */
+        ARRAY. The pointer to the constructed type is returned.
+        */
        register struct type *dtp;
 
-       switch (fund)   {
+       switch (fund)
+       {
 #ifndef NOBITFIELD
        case FIELD:
                dtp = field_of(tp, qual);
@@ -85,11 +76,13 @@ construct_type(fund, tp, qual, count, pl)
 #endif /* NOBITFIELD */
 
        case FUNCTION:
-               if (tp->tp_fund == FUNCTION)    {
+               if (tp->tp_fund == FUNCTION)
+               {
                        error("function cannot yield function");
                        return error_type;
                }
-               if (tp->tp_fund == ARRAY)       {
+               if (tp->tp_fund == ARRAY)
+               {
                        error("function cannot yield array");
                        return error_type;
                }
@@ -100,7 +93,8 @@ construct_type(fund, tp, qual, count, pl)
                dtp = pointer_to(tp, qual);
                break;
        case ARRAY:
-               if (tp->tp_fund == VOID) {
+               if (tp->tp_fund == VOID)
+               {
                        error("cannot construct array of void");
                        count = (arith) -1;
                }
@@ -113,14 +107,10 @@ construct_type(fund, tp, qual, count, pl)
        return dtp;
 }
 
-struct type *
-function_of(tp, pl, qual)
-       register struct type *tp;
-       struct proto *pl;
-       int qual;
+struct type *function_of(register struct type *tp, struct proto *pl, int qual)
 {
 #if 0
-/* See comment below */
+       /* See comment below */
        register struct type *dtp = tp->tp_function;
 #else
        register struct type *dtp;
@@ -128,30 +118,31 @@ function_of(tp, pl, qual)
 
        /* look for a type with the right qualifier */
 #if 0
-/* the code doesn't work in the following case:
-       int func();
-       int func(int a, int b) { return q(a); }
-   because updating the type works inside the data-structures for that type
-   thus, a new type is created for very function. This may change in the
-   future, when declarations with empty parameter lists become obsolete.
-   When it does, change type.str, decspecs.c, and this routine. Search for
-   the function_of pattern to find the places.
-*/
+       /* the code doesn't work in the following case:
+        int func();
+        int func(int a, int b) { return q(a); }
+        because updating the type works inside the data-structures for that type
+        thus, a new type is created for very function. This may change in the
+        future, when declarations with empty parameter lists become obsolete.
+        When it does, change type.str, decspecs.c, and this routine. Search for
+        the function_of pattern to find the places.
+        */
        while (dtp && (dtp->tp_typequal != qual || dtp->tp_proto != pl))
-               dtp = dtp->next;
+       dtp = dtp->next;
 #else
        dtp = 0;
 #endif
 
-       if (!dtp)       {
+       if (!dtp)
+       {
                dtp = create_type(FUNCTION);
                dtp->tp_up = tp;
-               dtp->tp_size = -1;      /* function size is not known */
+               dtp->tp_size = -1; /* function size is not known */
                dtp->tp_align = pointer_align;
                dtp->tp_typequal = qual;
                dtp->tp_proto = pl;
 #if 0
-/* See comment above */
+               /* See comment above */
                dtp->next = tp->tp_function;
                tp->tp_function = dtp;
 #endif
@@ -159,10 +150,7 @@ function_of(tp, pl, qual)
        return dtp;
 }
 
-struct type *
-pointer_to(tp, qual)
-       register struct type *tp;
-       int qual;
+struct type *pointer_to(register struct type *tp, int qual)
 {
        register struct type *dtp = tp->tp_pointer;
 
@@ -170,7 +158,8 @@ pointer_to(tp, qual)
        while (dtp && dtp->tp_typequal != qual)
                dtp = dtp->next;
 
-       if (!dtp)       {
+       if (!dtp)
+       {
                dtp = create_type(POINTER);
                dtp->tp_unsigned = 1;
                dtp->tp_up = tp;
@@ -183,11 +172,7 @@ pointer_to(tp, qual)
        return dtp;
 }
 
-struct type *
-array_of(tp, count, qual)
-       register struct type *tp;
-       arith count;
-       int qual;
+struct type * array_of(register struct type *tp, arith count, int qual)
 {
        register struct type *dtp = tp->tp_array;
 
@@ -195,7 +180,8 @@ array_of(tp, count, qual)
        while (dtp && (dtp->tp_nel != count || dtp->tp_typequal != qual))
                dtp = dtp->next;
 
-       if (!dtp)       {
+       if (!dtp)
+       {
                dtp = create_type(ARRAY);
                dtp->tp_up = tp;
                dtp->tp_nel = count;
@@ -203,19 +189,18 @@ array_of(tp, count, qual)
                dtp->tp_typequal = qual;
                dtp->next = tp->tp_array;
                tp->tp_array = dtp;
-               if (tp->tp_size >= 0 && count >= 0) {
+               if (tp->tp_size >= 0 && count >= 0)
+               {
                        dtp->tp_size = count * tp->tp_size;
                }
-               else    dtp->tp_size = -1;
+               else
+                       dtp->tp_size = -1;
        }
        return dtp;
 }
 
 #ifndef NOBITFIELD
-struct type *
-field_of(tp, qual)
-       register struct type *tp;
-       int qual;
+struct type * field_of(register struct type *tp, int qual)
 {
        register struct type *dtp = create_type(FIELD);
 
@@ -227,53 +212,47 @@ field_of(tp, qual)
 }
 #endif /* NOBITFIELD */
 
-arith
-size_of_type(tp, nm)
-       struct type *tp;
-       char nm[];
+arith size_of_type(struct type *tp, char nm[])
 {
        arith sz = tp->tp_size;
 
-       if (sz < 0)     {
+       if (sz < 0)
+       {
                error("size of %s unknown", nm);
-               sz = (arith)1;
+               sz = (arith) 1;
        }
        return sz;
 }
 
-idf2type(idf, tpp)
-       struct idf *idf;
-       struct type **tpp;
+void idf2type(struct idf *idf, struct type **tpp)
 {
        /*      Decoding  a typedef-ed identifier or basic type: if the
-               size is yet unknown we have to make copy of the type
-               descriptor to prevent garbage at the initialisation of
-               arrays with unknown size.
-       */
+        size is yet unknown we have to make copy of the type
+        descriptor to prevent garbage at the initialisation of
+        arrays with unknown size.
+        */
        register struct type *tp = idf->id_def->df_type;
 
-       if (*tpp) error("multiple types in declaration");
-       if (    tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) {
+       if (*tpp)
+               error("multiple types in declaration");
+       if (tp->tp_size < (arith) 0 && tp->tp_fund == ARRAY)
+       {
                *tpp = new_type();
                **tpp = *tp;
-                       /* this is really a structure assignment, AAGH!!! */
+               /* this is really a structure assignment, AAGH!!! */
        }
-       else    {
+       else
+       {
                *tpp = tp;
        }
 }
 
-arith
-align(pos, al)
-       arith pos;
-       int al;
+arith align(arith pos, int al)
 {
        return ((pos + al - 1) / al) * al;
 }
 
-struct type *
-standard_type(fund, sgn, algn, sz)
-       int algn; arith sz;
+struct type * standard_type(int fund, int sgn, int algn, arith sz)
 {
        register struct type *tp = create_type(fund);
 
@@ -284,25 +263,29 @@ standard_type(fund, sgn, algn, sz)
        return tp;
 }
 
-completed(tp)
-       struct type *tp;
+void completed(struct type *tp)
 {
        register struct type *atp = tp->tp_array;
        register struct type *etp = tp;
 
-       switch(etp->tp_fund) {
+       switch (etp->tp_fund)
+       {
        case STRUCT:
        case UNION:
        case ENUM:
-               while (etp = etp->next) {
-                       if (! etp->tp_sdef) etp->tp_sdef = tp->tp_sdef;
+               while (etp = etp->next)
+               {
+                       if (!etp->tp_sdef)
+                               etp->tp_sdef = tp->tp_sdef;
                        etp->tp_size = tp->tp_size;
                        etp->tp_align = tp->tp_align;
                }
                break;
        }
-       while (atp) {
-               if (atp->tp_nel >= 0) {
+       while (atp)
+       {
+               if (atp->tp_nel >= 0)
+               {
                        atp->tp_size = atp->tp_nel * tp->tp_size;
                }
                atp = atp->next;
index 8796d61..b98ffbb 100644 (file)
@@ -4,8 +4,13 @@
  */
 /* $Id$ */
 /* TYPE DESCRIPTOR */
+#ifndef TYPE_H_
+#define TYPE_H_
 
 #include       "parameters.h"
+#include    "arith.h"
+
+
 
 struct type    {
        struct type *next;      /* used for ARRAY and for qualifiers */
@@ -59,13 +64,6 @@ struct type  {
 #define        TQ_VOLATILE     0x01
 #define        TQ_CONST        0x02
 
-extern struct type
-       *create_type(), *standard_type(), *construct_type(), *pointer_to(),
-       *array_of(), *function_of(), *promoted_type();
-
-#ifndef NOBITFIELD
-extern struct type *field_of();
-#endif /* NOBITFIELD */
 
 extern struct type
        *schar_type, *uchar_type,
@@ -79,6 +77,24 @@ extern struct type
 
 extern struct type *pa_type;   /* type.c       */
 
-extern arith size_of_type(), align();
+struct type *create_type(int fund);
+struct type *promoted_type(struct type *tp);
+struct type *construct_type(int fund, register struct type *tp, int qual,
+arith count, /* for fund == ARRAY only */
+   register struct proto *pl);
+struct type *function_of(register struct type *tp, struct proto *pl, int qual);
+struct type *pointer_to(register struct type *tp, int qual);
+struct type * array_of(register struct type *tp, arith count, int qual);
+#ifndef NOBITFIELD
+struct type * field_of(register struct type *tp, int qual);
+#endif /* NOBITFIELD */
+arith size_of_type(struct type *tp, char nm[]);
+void idf2type(struct idf *idf, struct type **tpp);
+arith align(arith pos, int al);
+struct type * standard_type(int fund, int sgn, int algn, arith sz);
+void completed(struct type *tp);
+
 
 /* ALLOCDEF "type" 50 */
+
+#endif
\ No newline at end of file
index 273fa8d..6d3f084 100644 (file)
@@ -41,16 +41,14 @@ static int  loc_id;
 
 extern char options[];
 
-LocalInit()
+void LocalInit(void)
 {
 #ifdef USE_TMP
        C_insertpart(loc_id = C_getid());
 #endif /* USE_TMP */
 }
 
-arith
-LocalSpace(sz, al)
-       arith sz;
+arith LocalSpace(arith sz, int al)
 {
        register struct stack_level *stl = local_level;
 
@@ -61,9 +59,7 @@ LocalSpace(sz, al)
 #define TABSIZ 32
 static struct localvar *regs[TABSIZ];
 
-arith
-NewLocal(sz, al, regtype, sc)
-       arith sz;
+arith NewLocal(arith sz, int al, int regtype, int sc)
 {
        register struct localvar *tmp = FreeTmps;
        struct localvar *prev = 0;
@@ -98,8 +94,7 @@ NewLocal(sz, al, regtype, sc)
        return tmp->t_offset;
 }
 
-FreeLocal(off)
-       arith off;
+void FreeLocal(arith off)
 {
        int index = (int) (off >> 2) & (TABSIZ - 1);
        register struct localvar *tmp = regs[index];
@@ -117,7 +112,7 @@ FreeLocal(off)
        }
 }
 
-LocalFinish()
+void LocalFinish(void)
 {
        register struct localvar *tmp, *tmp1;
        register int i;
@@ -163,9 +158,7 @@ LocalFinish()
 #endif
 }
 
-void
-RegisterAccount(offset, size, regtype, sc)
-       arith offset, size;
+void RegisterAccount(arith offset, arith size, int regtype, int sc)
 {
        register struct localvar *p;
        int index;
@@ -183,9 +176,7 @@ RegisterAccount(offset, size, regtype, sc)
        regs[index] = p;
 }
 
-static struct localvar *
-find_reg(off)
-       arith off;
+static struct localvar *find_reg(arith off)
 {
        register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)];
 
@@ -193,8 +184,7 @@ find_reg(off)
        return p;
 }
 
-LoadLocal(off, sz)
-       arith off, sz;
+void LoadLocal(arith off, arith sz)
 {
        register struct localvar *p = find_reg(off);
 
@@ -213,8 +203,7 @@ LoadLocal(off, sz)
        }
 }
 
-StoreLocal(off, sz)
-       arith off, sz;
+void StoreLocal(arith off, arith sz)
 {
        register struct localvar *p = find_reg(off);
 
@@ -234,8 +223,7 @@ StoreLocal(off, sz)
 }
 
 #ifndef        LINT
-AddrLocal(off)
-       arith off;
+void AddrLocal(arith off)
 {
        register struct localvar *p = find_reg(off);
 
index 8864323..1e3855e 100644 (file)
@@ -1,3 +1,8 @@
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include "arith.h"
+
 struct localvar {
        struct localvar *next;
        arith           t_offset;       /* offset from LocalBase */
@@ -9,3 +14,18 @@ struct localvar {
 };
 
 /* ALLOCDEF "localvar" 10 */
+
+void LocalInit(void);
+arith LocalSpace(arith sz, int al);
+arith NewLocal(arith sz, int al, int regtype, int sc);
+void FreeLocal(arith off);
+void LocalFinish(void);
+void RegisterAccount(arith offset, arith size, int regtype, int sc);
+void LoadLocal(arith off, arith sz);
+void StoreLocal(arith off, arith sz);
+
+#ifndef        LINT
+void AddrLocal(arith off);
+#endif
+
+#endif
\ No newline at end of file