+ 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.
-!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
--- /dev/null
+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)
+
+
#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 */
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
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}*#"
/*NOTREACHED*/
}
-arith char_constant(nm) char* nm;
+static arith char_constant(char* nm)
{
register arith val = 0;
register int ch;
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;
return str;
}
-int quoted(ch) register int ch;
+static int quoted(register int ch)
{
/* quoted() replaces an escaped character sequence by the
character meant.
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.
/* 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;
}
}
-strint2tok(intbuf, ptok) char intbuf[];
-struct token* ptok;
+static void strint2tok(char intbuf[], struct token* ptok)
{
register char* cp = intbuf;
int base = 10;
called a "symbol", but it may have other information associated
to it.
*/
+#ifndef LLLEX_H_
+#define LLLEX_H_
#include "file_info.h"
#define ASIDE aside.tk_symb
#define EOF (-1)
+
+int GetChar(void);
+int LLlex(void);
+int GetToken(register struct token* ptok);
+
+#endif /* LLLEX_H_ */
#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
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();
#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.
}
}
-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 ':'.
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.
}
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.
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
*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.
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.
/* 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.
}
}
-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.
}
}
-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.
}
}
-array2pointer(exp)
- register struct expr *exp;
+void array2pointer(register struct expr *exp)
{
/* The expression, which must be an array, is converted
to a pointer.
, (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.
(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.
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;
}
}
-opnd2logical(expp, oper)
- register struct expr **expp;
- int oper;
+void opnd2logical(register struct expr **expp, int oper)
{
int fund = (*expp)->ex_type->tp_fund;
}
void
-opnd2test(expp, oper)
- register struct expr **expp;
+opnd2test(register struct expr **expp, int oper)
{
opnd2logical(expp, oper);
if ((*expp)->ex_class == 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;
}
}
-any2parameter(expp)
- register struct expr **expp;
+void any2parameter(register struct expr **expp)
{
/* To handle default argument promotions
*/
}
#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.
/* 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));
}
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_ */
#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 */
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) ||
(
);
}
-store_block(sz, al)
- arith sz;
- int al;
+void store_block(arith sz, int al)
{
if (suitable_sz(sz, al))
C_sti(sz);
}
}
-load_block(sz, al)
- arith sz;
- int al;
+void load_block(arith sz, int al)
{
if (suitable_sz(sz, al))
}
}
-copy_block(sz, al)
- arith sz;
- int al;
+void copy_block(arith sz, int al)
{
if (suitable_sz(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();
--- /dev/null
+/* 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_ */
#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.
*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.
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
/* 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;
}
}
-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;
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;
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;
}
/* 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;
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
/* 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:
}
}
-int
-is_arith_type(tp)
- register struct type *tp;
+int is_arith_type(register struct type *tp)
{
switch (tp->tp_fund) {
case CHAR:
--- /dev/null
+/* 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_ */
#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();
#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!!!
}
}
-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.
* 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 '>';
}
}
-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
}
}
-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
);
}
-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
--- /dev/null
+/* 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_ */
/* $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.
*/
--- /dev/null
+/* 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_ */
#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 */
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;
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
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();
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;
}
/* 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;
}
#ifndef LINT
-end_code()
+void end_code(void)
{
/* end_code() performs the actions to be taken when closing
the output stream.
#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
}
#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.
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:
#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:
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
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.
}
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".
}
}
-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.
}
}
-bss(idf)
- register struct idf *idf;
+void bss(register struct idf *idf)
{
/* bss() allocates bss space for the global 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
#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
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;
innermost statement in which continue has a meaning.
*/
void
-code_continue()
+code_continue(void)
{
register struct stmt_block *stmt_block = stmt_stack;
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();
stmt_stack = stmt_block;
}
-unstack_stmt()
+void unstack_stmt(void)
{
/* unstack_stmt() unstacks the data of a statement
which may contain break or continue
static label prc_name;
-prc_entry(name)
- char *name;
+void prc_entry(char* name)
{
if (options['p']) {
C_df_dlb(prc_name = data_label());
}
}
-prc_exit()
+void prc_exit(void)
{
if (options['p']) {
C_lae_dlb(prc_name, (arith) 0);
}
#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;
* (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;
#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
#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;
/* 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:
--- /dev/null
+/* 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_ */
/* 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"
#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];
#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
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.
expr->VL_VALUE = o1;
}
-init_cst()
+void init_cst(void)
{
register int i = 0;
register arith bt = (arith)0;
--- /dev/null
+/* 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_ */
*/
#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;
--- /dev/null
+/* 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_ */
-/*
- * (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
* (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 */
extern struct type *declare_type();
extern struct declarator null_declarator;
+
+#endif
/* 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.
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
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.
}
}
-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,
}
}
-check_array_subscript(expr)
- register struct expr *expr;
+void check_array_subscript(register struct expr *expr)
{
arith size = expr->VL_VALUE;
--- /dev/null
+/* 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_ */
/* 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;
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))
}
/* 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;
}
}
/* 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;
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:
dtp->next = tp->next; /* don't know head or tail */
tp->next = dtp;
}
- return(dtp);
+ return (dtp);
}
* (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 */
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
* (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 */
#define REG_BONUS 10 /* register candidate, declared as such */
/* ALLOCDEF "def" 50 */
+
+#endif
#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>
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
return tk.tk_idf;
}
-domacro()
+void domacro(void)
{
int tok;
struct token tk;
SkipToNewLine();
}
-do_line(l) unsigned int l;
+static void do_line(unsigned int l)
{
struct token tk;
int t = GetToken(&tk);
--- /dev/null
+/* 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_ */
/* 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
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;
}
/*VARARGS*/
-expr_error(struct expr *expr, char *fmt, ...)
+void expr_error(struct expr *expr, char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-lexstrict(char *fmt, ...)
+void lexstrict(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-strict(char *fmt, ...)
+void strict(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-expr_strict(struct expr *expr, char *fmt, ...)
+void expr_strict(struct expr *expr, char *fmt, ...)
{
va_list ap;
#ifdef DEBUG
/*VARARGS*/
-debug(char *fmt, ...)
+void debug(char *fmt, ...)
{
va_list ap;
#endif /* DEBUG */
/*VARARGS*/
-warning(char *fmt, ...)
+void warning(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-expr_warning(struct expr *expr, char *fmt, ...)
+void expr_warning(struct expr *expr, char *fmt, ...)
{
va_list ap;
#ifdef LINT
/*VARARGS*/
-def_warning(struct def *def, char *fmt, ...)
+void def_warning(struct def *def, char *fmt, ...)
{
va_list ap;
/*VARARGS*/
-hwarning(char *fmt, ...)
+void hwarning(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-awarning(char *fmt, ...)
+void awarning(char *fmt, ...)
{
va_list ap;
#endif /* LINT */
/*VARARGS*/
-lexerror(char *fmt, ...)
+void lexerror(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-lexwarning(char *fmt, ...)
+void lexwarning(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-crash(char *fmt, ...)
+void crash(char *fmt, ...)
{
va_list ap;
}
/*VARARGS*/
-fatal(char *fmt, ...)
+void fatal(char *fmt, ...)
{
va_list ap;
}
#else
/*VARARGS*/
-error(va_alist) /* fmt, args */
+void error(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
}
/*VARARGS*/
-expr_error(va_alist) /* expr, fmt, args */
+void expr_error(va_alist) /* expr, fmt, args */
va_dcl
{
va_list ap;
}
/*VARARGS*/
-lexstrict(va_alist)
+void lexstrict(va_alist)
va_dcl
{
va_list ap;
}
/*VARARGS*/
-strict(va_alist)
+void strict(va_alist)
va_dcl
{
va_list ap;
}
/*VARARGS*/
-expr_strict(va_alist) /* expr, fmt, args */
+void expr_strict(va_alist) /* expr, fmt, args */
va_dcl
{
va_list ap;
#ifdef DEBUG
/*VARARGS*/
-debug(va_alist)
+void debug(va_alist)
va_dcl
{
va_list ap;
#endif /* DEBUG */
/*VARARGS*/
-warning(va_alist)
+void warning(va_alist)
va_dcl
{
va_list ap;
}
/*VARARGS*/
-expr_warning(va_alist) /* expr, fmt, args */
+void expr_warning(va_alist) /* expr, fmt, args */
va_dcl
{
va_list ap;
#ifdef LINT
/*VARARGS*/
-def_warning(va_alist) /* def, fmt, args */
+void def_warning(va_alist) /* def, fmt, args */
va_dcl
{
va_list ap;
/*VARARGS*/
-hwarning(va_alist) /* fmt, args */
+void hwarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
}
/*VARARGS*/
-awarning(va_alist) /* fmt, args */
+void awarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
#endif /* LINT */
/*VARARGS*/
-lexerror(va_alist) /* fmt, args */
+void lexerror(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
}
/*VARARGS*/
-lexwarning(va_alist) /* fmt, args */
+void lexwarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
}
/*VARARGS*/
-crash(va_alist) /* fmt, args */
+void crash(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
}
/*VARARGS*/
-fatal(va_alist) /* fmt, args */
+void fatal(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
}
#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;
#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");
}
--- /dev/null
+/* 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_ */
* (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 */
#define last_offset s_cnt2
#define elem_count s_cnt1
#define nelem s_cnt2
+
+#endif
\ No newline at end of file
#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__)
#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:
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;
}
/* 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 '<':
}
/* truthvalue() serves as an auxiliary function of EVAL */
-truthvalue(relop)
- int relop;
+static void truthvalue(int relop)
{
switch (relop) {
case '<':
/* 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;
}
}
-ptr_add(size)
- arith size;
+static void ptr_add(arith size)
{
if (size != pointer_size) {
C_loc(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;
- 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);
}
}
-load_cst(val, siz)
- arith val, siz;
+void load_cst(arith val, arith siz)
{
if ((int)siz <= (int)word_size)
C_loc(val);
}
}
-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);
--- /dev/null
+/* 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_ */
#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 '.':
case CAST:
case SIZEOF:
case ADDRESSOF:
- return 2; /* monadic */
+ return 2; /* monadic */
case '*':
case '/':
case '%':
/*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;
}
}
-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 */
}
/* 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 */
}
#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;
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;
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;
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;
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;
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;
}
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;
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");
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:
/*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);
}
*/
/* $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.
/* 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
-/*
- * (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
#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.
[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;
}
}
-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);
* (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 */
};
/* 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
#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
--- /dev/null
+/* 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_ */
#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[];
#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:
}
}
/* 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;
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:
}
}
-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;
}
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 */
}
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 */
}
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 */
}
}
-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;
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;
}
}
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 */
*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;
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;
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);
* (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 */
#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
#include <string.h>
#include "file_info.h"
#include "input.h"
+#include "error.h"
#define INP_PUSHBACK 3
#define INP_TYPE struct file_info
int NoUnstack;
-AtEoIT()
+int AtEoIT(void)
{
return 0;
}
extern char *source;
-AtEoIF()
+int AtEoIF(void)
{
if (NoUnstack) lexerror("unexpected EOF");
return 0;
#define UnGetChar() ((LexSave != EOI) ? ChPushBack(LexSave) : 0)
extern int LexSave; /* last character read by GetChar */
-extern int GetChar(); /* character input, with trigraph parsing */
+
-/*
- * (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
#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
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.
*/
*/
/* $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" */
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_ */
#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();
{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
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];
char *nmlist = 0;
#endif /* GEN_NM_LIST */
-compile(argc, argv)
- char *argv[];
+void compile(int argc, char *argv[])
{
char *result;
#ifndef LINT
}
}
-init()
+static void init(void)
{
init_cst(); /* initialize variables of "cstoper.c" */
reserve(tkidf); /* mark the C reserved words as such */
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);
}
#ifdef DEBUG
-Info()
+void Info(void)
{
extern int cnt_string_cst, cnt_formal,
cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
}
#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");
}
--- /dev/null
+#include "parameters.h"
#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
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;
}
}
-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.
--- /dev/null
+/* 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_ */
/* 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
--- /dev/null
+/* 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_ */
-/*
- * (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
#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;
}
}
-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;
}
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;
/* 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);
}
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;
#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;
}
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");
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);
}
}
#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;
* 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;
}
/* 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
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)
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;
}
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");
}
* (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 */
#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
#include "LLlex.h"
#include "class.h"
#include "input.h"
+#include "skip.h"
-SkipToNewLine()
+int SkipToNewLine(void)
{
register int ch;
register int garbage = 0;
--- /dev/null
+/* 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_ */
#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;
*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));
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;
}
{
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;
}
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;
}
}
}
-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);
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);
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);
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);
}
--- /dev/null
+/* 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_ */
#include "struct.h"
#include "level.h"
#include "mes.h"
+#include "code.h"
+#include "util.h"
+#include "error.h"
/* #include <em_reg.h> */
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();
#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.
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
return stl;
}
-unstack_level()
+void unstack_level(void)
{
/* The top level of the identifier stack is removed.
*/
#endif /* DEBUG */
}
-unstack_world()
+void unstack_world(void)
{
/* The global level of identifiers is scanned, and final
decisions are taken about such issues as
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));
* (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.
/* 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
-/*
- * (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
* 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
* (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 */
};
/* ALLOCDEF "stmt_block" 5 */
+
+#endif
\ No newline at end of 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,
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,
}
}
-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;
}
}
-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
}
}
-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
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.
}
#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
#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
#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;
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));
}
* (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 */
/* 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
#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
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.
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;
unstack_stmt();
}
-void
-code_case(expr)
- struct expr *expr;
+void code_case(struct expr *expr)
{
register arith val;
register struct case_entry *ce;
}
}
-void
-code_default()
+void code_default(void)
{
register struct switch_hdr *sh = switch_stack;
* (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 {
};
/* 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
--- /dev/null
+/{[A-Z]/!d
+s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\
+ return \2;/
--- /dev/null
+ 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
--- /dev/null
+/* 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
#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
};
#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.
*/
/* $Id$ */
/* TOKENNAME DEFINITION */
+#ifndef TOKENNAME_H_
+#define TOKENNAME_H_
struct tokenname { /* Used for defining the name of a
token as identified by its symbol
int tn_symbol;
char *tn_name;
};
+
+void reserve(register struct tokenname resv[]);
+
+#endif /* TOKENNAME_H_ */
#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);
#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;
}
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;
}
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;
/* 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
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;
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;
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;
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;
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);
}
#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);
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;
*/
/* $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 */
#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,
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
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;
#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;
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];
}
}
-LocalFinish()
+void LocalFinish(void)
{
register struct localvar *tmp, *tmp1;
register int i;
#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;
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)];
return p;
}
-LoadLocal(off, sz)
- arith off, sz;
+void LoadLocal(arith off, arith sz)
{
register struct localvar *p = find_reg(off);
}
}
-StoreLocal(off, sz)
- arith off, sz;
+void StoreLocal(arith off, arith sz)
{
register struct localvar *p = find_reg(off);
}
#ifndef LINT
-AddrLocal(off)
- arith off;
+void AddrLocal(arith off)
{
register struct localvar *p = find_reg(off);
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include "arith.h"
+
struct localvar {
struct localvar *next;
arith t_offset; /* offset from LocalBase */
};
/* 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