Better ANSI C compatibility and portability:

+ 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.
This commit is contained in:
carl 2019-02-19 00:42:15 +08:00
parent e70690c510
commit 750a6bc684
82 changed files with 5184 additions and 4082 deletions

View file

@ -1,5 +1,5 @@
!File: lint.h
/*#define LINT 1 /* if defined, 'lint' is produced */
/*#define LINT 1 *//* if defined, 'lint' is produced */
!File: pathlength.h
@ -75,7 +75,7 @@
!File: botch_free.h
/*#define BOTCH_FREE 1 /* when defined, botch freed memory, as a check */
/*#define BOTCH_FREE 1* *//* when defined, botch freed memory, as a check */
!File: dataflow.h
@ -83,7 +83,7 @@
!File: debug.h
/*#define DEBUG 1 /* perform various self-tests */
/*#define DEBUG 1 *//* perform various self-tests */
#define NDEBUG 1 /* disable assertions */
@ -112,7 +112,7 @@
!File: nobitfield.h
/*#define NOBITFIELD 1 /* if NOT defined, implement bitfields */
/*#define NOBITFIELD 1 *//* if NOT defined, implement bitfields */
!File: spec_arith.h
@ -125,11 +125,11 @@
!File: nocross.h
/*#define NOCROSS 1 /* if NOT defined, cross compiler */
/*#define NOCROSS 1 *//* if NOT defined, cross compiler */
!File: regcount.h
/*#define REGCOUNT 1 /* count occurrences for register messages */
/*#define REGCOUNT 1 *//* count occurrences for register messages */
!File: dbsymtab.h

View file

@ -0,0 +1,318 @@
cmake_minimum_required (VERSION 3.0)
project(em_cemcom.ansi)
##################################
# Location of built scripts.
##################################
set(PROJECT_SCRIPTS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../util/scripts)
set(SRC_C
align.h
arith.c
arith.h
atw.h
blocks.c
blocks.h
ch3.c
ch3.h
ch3bin.c
ch3bin.h
ch3mon.c
ch3mon.h
class.h
code.c
conversion.c
conversion.h
cstoper.c
cstoper.h
dataflow.c
dataflow.h
declarator.c
declarator.h
decspecs.c
decspecs.h
domacro.c
domacro.h
dumpidf.c
error.c
error.h
eval.c
eval.h
expr.c
field.c
file_info.h
fltcstoper.c
fltcstoper.h
idf.c
input.c
input.h
interface.h
idf.c
input.c
input.h
l_class.h
l_comment.c
l_comment.h
l_em.h
l_ev_ord.c
l_lint.c
l_lint.h
l_misc.c
l_outdef.c
l_states.c
label.c
label.h
level.h
LLlex.c
LLlex.h
LLmessage.c
main.c
mes.h
options.c
options.h
pragma.c
pragma.h
proto.c
sizes.h
skip.c
skip.h
specials.h
stab.c
stab.h
stack.c
stb.c
struct.c
switch.c
tokenname.c
tokenname.h
type.c
util.c
)
set(INCLUDE_DIRS
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}/../../../modules/src/idf
${CMAKE_CURRENT_SOURCE_DIR}/../../../modules/src/input
)
############################################
# LLgen inputs
############################################
set(GEN_G
${CMAKE_CURRENT_BINARY_DIR}/tokenfile.g
)
set(SRC_G
${CMAKE_CURRENT_SOURCE_DIR}/program.g
${CMAKE_CURRENT_SOURCE_DIR}/declar.g
${CMAKE_CURRENT_SOURCE_DIR}/expression.g
${CMAKE_CURRENT_SOURCE_DIR}/statement.g
${CMAKE_CURRENT_SOURCE_DIR}/ival.g
)
############################################
# LLgen outputs
############################################
set(GEN_SRC
${CMAKE_CURRENT_BINARY_DIR}/program.c
${CMAKE_CURRENT_BINARY_DIR}/declar.c
${CMAKE_CURRENT_BINARY_DIR}/expression.c
${CMAKE_CURRENT_BINARY_DIR}/statement.c
${CMAKE_CURRENT_BINARY_DIR}/ival.c
${CMAKE_CURRENT_BINARY_DIR}/tokenfile.c
${CMAKE_CURRENT_BINARY_DIR}/Lpars.c
${CMAKE_CURRENT_BINARY_DIR}/Lpars.h
${CMAKE_CURRENT_BINARY_DIR}/Lncor.c
)
set(GFILES
${GEN_G}
${SRC_G}
)
############################################
# Configuration parameters generated files
############################################
set(GEN_H_CONFIG
${CMAKE_CURRENT_BINARY_DIR}/parameters.h
)
set(GEN_OTHERS
${CMAKE_CURRENT_BINARY_DIR}/code.h
${CMAKE_CURRENT_BINARY_DIR}/declar.h
${CMAKE_CURRENT_BINARY_DIR}/def.h
${CMAKE_CURRENT_BINARY_DIR}/expr.h
${CMAKE_CURRENT_BINARY_DIR}/field.h
${CMAKE_CURRENT_BINARY_DIR}/estack.h
${CMAKE_CURRENT_BINARY_DIR}/util.h
${CMAKE_CURRENT_BINARY_DIR}/proto.h
${CMAKE_CURRENT_BINARY_DIR}/replace.h
${CMAKE_CURRENT_BINARY_DIR}/idf.h
${CMAKE_CURRENT_BINARY_DIR}/macro.h
${CMAKE_CURRENT_BINARY_DIR}/stack.h
${CMAKE_CURRENT_BINARY_DIR}/stmt.h
${CMAKE_CURRENT_BINARY_DIR}/struct.h
${CMAKE_CURRENT_BINARY_DIR}/switch.h
${CMAKE_CURRENT_BINARY_DIR}/type.h
${CMAKE_CURRENT_BINARY_DIR}/l_brace.h
${CMAKE_CURRENT_BINARY_DIR}/l_state.h
${CMAKE_CURRENT_BINARY_DIR}/l_outdef.h
${CMAKE_CURRENT_BINARY_DIR}/next.c
)
set(CFILES
${SRC_C}
${GEN_SRC}
${GEN_H_CONFIG}
${GEN_OTHERS}
symbol2str.c
char.c
)
set(LLGENOPTIONS
-n
)
###############################################
# Generate the compile time configuration file
###############################################
add_custom_command(
OUTPUT ${GEN_H_CONFIG} BigPars mkparams.sed
COMMAND ${CMAKE_COMMAND} -E copy
${PROJECT_SCRIPTS_SOURCE_DIR}/mkparams.sed
${CMAKE_CURRENT_BINARY_DIR}/mkparams.sed
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/BigPars
${CMAKE_CURRENT_BINARY_DIR}/BigPars
COMMAND sed -f ${PROJECT_SCRIPTS_SOURCE_DIR}/mkparams.sed ${CMAKE_CURRENT_BINARY_DIR}/BigPars>parameters.h
DEPENDS BigPars)
###############################################
# Generate other source files
###############################################
add_custom_command(
OUTPUT ${GEN_OTHERS} mkalloc1.sed mkalloc2.sed mknext.sed
COMMAND ${CMAKE_COMMAND} -E copy
${PROJECT_SCRIPTS_SOURCE_DIR}/mkalloc1.sed
${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed
COMMAND ${CMAKE_COMMAND} -E copy
${PROJECT_SCRIPTS_SOURCE_DIR}/mkalloc2.sed
${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed
COMMAND ${CMAKE_COMMAND} -E copy
${PROJECT_SCRIPTS_SOURCE_DIR}/mknext.sed
${CMAKE_CURRENT_BINARY_DIR}/mknext.sed
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/code.str>code.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/declar.str>declar.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/def.str>def.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/expr.str>expr.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/field.str>field.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/estack.str>estack.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/util.str>util.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/proto.str>proto.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/idf.str>idf.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/macro.str>macro.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/stack.str>stack.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/stmt.str>stmt.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/struct.str>struct.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/switch.str>switch.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/type.str>type.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_brace.str>l_brace.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_state.str>l_state.h
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc1.sed -f ${CMAKE_CURRENT_BINARY_DIR}/mkalloc2.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_outdef.str>l_outdef.h
# Create next file from above files
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/next.str
${CMAKE_CURRENT_BINARY_DIR}/next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/code.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/declar.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/def.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/expr.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/field.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/estack.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/util.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/proto.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/idf.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/macro.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/stack.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/stmt.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/struct.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/switch.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/type.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_brace.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_state.str>>next.c
COMMAND sed -n -f ${CMAKE_CURRENT_BINARY_DIR}/mknext.sed ${CMAKE_CURRENT_SOURCE_DIR}/l_outdef.str>>next.c
)
add_custom_command(
OUTPUT char.c
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../../../util/cmisc/tabgen -f${CMAKE_CURRENT_SOURCE_DIR}/char.tab >char.c
)
###############################################
# Generate the LLGen source files
# NOTE: Order of input file is important
###############################################
add_custom_command(
OUTPUT tokenfile.g mktkfile.sed
COMMAND ${CMAKE_COMMAND} -E copy
${PROJECT_SCRIPTS_SOURCE_DIR}/mktkfile.sed
${CMAKE_CURRENT_BINARY_DIR}/mktkfile.sed
COMMAND sed -f ${CMAKE_CURRENT_BINARY_DIR}/mktkfile.sed ${CMAKE_CURRENT_SOURCE_DIR}/tokenname.c>tokenfile.g
)
add_custom_command(
OUTPUT ${GEN_SRC}
COMMAND ${CMAKE_COMMAND} -E env LLGEN_LIB_DIR=${CMAKE_CURRENT_SOURCE_DIR}/../../../util/LLgen/lib ${CMAKE_CURRENT_BINARY_DIR}/../../../util/LLgen/LLgen ${LLGENOPTIONS} ${GEN_G} ${SRC_G}
DEPENDS LLgen tokenfile.g)
add_custom_command(
OUTPUT symbol2str.c
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tokcaseh.in >symbol2str.c
COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/tokcase.sed ${CMAKE_CURRENT_SOURCE_DIR}/tokenname.c >>symbol2str.c
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tokcasee.in >>symbol2str.c
)
add_executable(${PROJECT_NAME} ${CFILES})
target_compile_definitions(${PROJECT_NAME} PUBLIC NORCSID=1)
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} emheaders emh flt alloc print string system em_data eme em_mes)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cemcom.ansi.1 DESTINATION man OPTIONAL)

View file

@ -17,6 +17,8 @@
#include "Lpars.h"
#include "class.h"
#include "sizes.h"
#include "error.h"
#include "domacro.h"
#include "specials.h" /* registration of special identifiers */
/* Data about the token yielded */
@ -41,7 +43,16 @@ extern arith full_mask[];
extern int lint_skip_comment;
#endif
int LLlex()
/* Internal function declarations */
static arith char_constant(char*);
static char* string_token(char *, int , int *);
static int quoted(register int);
static int hex_val(register int);
static void strflt2tok(char [], struct token *);
static void strint2tok(char [], struct token *);
int LLlex(void)
{
/* LLlex() plays the role of Lexical Analyzer for the C parser.
The look-ahead and putting aside of tokens are taken into
@ -72,10 +83,8 @@ int LLlex()
return DOT;
}
char* string_token();
arith char_constant();
int GetToken(ptok) register struct token* ptok;
int GetToken(register struct token* ptok)
{
/* GetToken() is the actual token recognizer. It calls the
control line interpreter if it encounters a "\n{w}*#"
@ -379,7 +388,7 @@ go_on: /* rescan, the following character has been read */
/*NOTREACHED*/
}
arith char_constant(nm) char* nm;
static arith char_constant(char* nm)
{
register arith val = 0;
register int ch;
@ -413,8 +422,7 @@ arith char_constant(nm) char* nm;
return val;
}
char* string_token(nm, stop_char, plen) char* nm;
int* plen;
static char* string_token(char *nm, int stop_char, int *plen)
{
register int ch;
register int str_size;
@ -447,7 +455,7 @@ int* plen;
return str;
}
int quoted(ch) register int ch;
static int quoted(register int ch)
{
/* quoted() replaces an escaped character sequence by the
character meant.
@ -510,12 +518,12 @@ int quoted(ch) register int ch;
return ch & 0377;
}
int hex_val(ch) register int ch;
static int hex_val(register int ch)
{
return is_dig(ch) ? ch - '0' : is_hex(ch) ? (ch - 'a' + 10) & 017 : -1;
}
int GetChar()
int GetChar(void)
{
/* The routines GetChar and trigraph parses the trigraph
sequences and removes occurences of \\\n.
@ -529,8 +537,7 @@ int GetChar()
/* strflt2tok only checks the syntax of the floating-point number and
* selects the right type for the number.
*/
strflt2tok(fltbuf, ptok) char fltbuf[];
struct token* ptok;
static void strflt2tok(char fltbuf[], struct token* ptok)
{
register char* cp = fltbuf;
int malformed = 0;
@ -584,8 +591,7 @@ struct token* ptok;
}
}
strint2tok(intbuf, ptok) char intbuf[];
struct token* ptok;
static void strint2tok(char intbuf[], struct token* ptok)
{
register char* cp = intbuf;
int base = 10;

View file

@ -9,6 +9,8 @@
called a "symbol", but it may have other information associated
to it.
*/
#ifndef LLLEX_H_
#define LLLEX_H_
#include "file_info.h"
@ -56,3 +58,9 @@ extern int err_occurred; /* "error.c" */
#define ASIDE aside.tk_symb
#define EOF (-1)
int GetChar(void);
int LLlex(void);
int GetToken(register struct token* ptok);
#endif /* LLLEX_H_ */

View file

@ -10,21 +10,28 @@
#include "arith.h"
#include "LLlex.h"
#include "Lpars.h"
#include "error.h"
extern char *symbol2str();
LLmessage(tk) {
static void insert_token(int );
void LLmessage(int tk)
{
err_occurred = 1;
if (tk < 0) {
if (tk < 0)
{
error("end of file expected");
}
else if (tk) {
else if (tk)
{
#ifndef LLNONCORR
error("%s missing before %s", symbol2str(tk), symbol2str(DOT));
#endif
insert_token(tk);
}
else {
else
{
#ifndef LLNONCORR
error("%s deleted", symbol2str(DOT));
#else
@ -34,14 +41,14 @@ LLmessage(tk) {
tk_nmb_at_last_syn_err = token_nmb;
}
insert_token(tk)
int tk;
static void insert_token(int tk)
{
aside = dot;
DOT = tk;
switch (tk) {
switch (tk)
{
/* The operands need some body */
case IDENTIFIER:
dot.tk_idf = gen_idf();

View file

@ -24,16 +24,19 @@
#include "Lpars.h"
#include "field.h"
#include "mes.h"
#include "cstoper.h"
#include "ch3bin.h"
#include "ch3.h"
#include "error.h"
extern char *symbol2str();
extern char options[];
extern arith flt_flt2arith();
extern label code_string();
void
arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
register struct expr **e1p, **e2p;
int oper;
/* 3.1.2.5 */
void arithbalance(register struct expr **e1p, int oper, register struct expr **e2p)
{
/* The expressions *e1p and *e2p are balanced to be operands
of the arithmetic operator oper.
@ -171,8 +174,7 @@ arithbalance(e1p, oper, e2p) /* 3.1.2.5 */
}
}
relbalance(e1p, oper, e2p)
register struct expr **e1p, **e2p;
void relbalance(register struct expr **e1p, int oper, register struct expr **e2p)
{
/* The expressions *e1p and *e2p are balanced to be operands
of the relational operator oper, or the ':'.
@ -204,9 +206,7 @@ relbalance(e1p, oper, e2p)
arithbalance(e1p, oper, e2p);
}
ch3pointer(expp, oper, tp)
struct expr **expp;
register struct type *tp;
void ch3pointer(struct expr **expp, int oper, register struct type *tp)
{
/* Checks whether *expp may be compared to tp using oper,
as described in chapter 3.3.8 and 3.3.9.
@ -238,9 +238,7 @@ ch3pointer(expp, oper, tp)
}
int
any2arith(expp, oper)
register struct expr **expp;
register int oper;
any2arith(register struct expr **expp, register int oper)
{
/* Turns any expression into int_type, long_type,
float_type, double_type or lngdbl_type.
@ -295,8 +293,7 @@ any2arith(expp, oper)
return (*expp)->ex_type->tp_fund;
}
erroneous2int(expp)
struct expr **expp;
void erroneous2int(struct expr **expp)
{
/* the (erroneous) expression *expp is replaced by an
int expression
@ -310,11 +307,7 @@ erroneous2int(expp)
*expp = exp;
}
struct expr *
arith2arith(tp, oper, expr)
struct type *tp;
int oper;
register struct expr *expr;
struct expr *arith2arith(struct type *tp, int oper, register struct expr *expr)
{
/* arith2arith constructs a new expression containing a
run-time conversion between some arithmetic types.
@ -328,10 +321,7 @@ arith2arith(tp, oper, expr)
return new_oper(tp, new, oper, expr);
}
int
int2int(expp, tp)
struct expr **expp;
register struct type *tp;
int int2int(struct expr **expp, register struct type *tp)
{
/* The expression *expp, which is of some integral type, is
converted to the integral type tp.
@ -369,9 +359,7 @@ int2int(expp, tp)
/* With compile-time constants, we don't set fp_used, since this is done
* only when necessary in eval.c.
*/
int2float(expp, tp)
register struct expr **expp;
struct type *tp;
void int2float(register struct expr **expp, struct type *tp)
{
/* The expression *expp, which is of some integral type, is
converted to the floating type tp.
@ -390,9 +378,7 @@ int2float(expp, tp)
}
}
float2int(expp, tp)
struct expr **expp;
struct type *tp;
void float2int(struct expr **expp, struct type *tp)
{
/* The expression *expp, which is of some floating type, is
converted to the integral type tp.
@ -418,9 +404,7 @@ float2int(expp, tp)
}
}
float2float(expp, tp)
register struct expr **expp;
struct type *tp;
void float2float(register struct expr **expp, struct type *tp)
{
/* The expression *expp, which is of some floating type, is
converted to the floating type tp.
@ -436,8 +420,7 @@ float2float(expp, tp)
}
}
array2pointer(exp)
register struct expr *exp;
void array2pointer(register struct expr *exp)
{
/* The expression, which must be an array, is converted
to a pointer.
@ -447,8 +430,7 @@ array2pointer(exp)
, (arith)0, NO_PROTO);
}
function2pointer(exp)
register struct expr *exp;
void function2pointer(register struct expr *exp)
{
/* The expression, which must be a function, is converted
to a pointer to the function.
@ -457,8 +439,7 @@ function2pointer(exp)
(arith)0, NO_PROTO);
}
string2pointer(ex)
register struct expr *ex;
void string2pointer(register struct expr *ex)
{
/* The expression, which must be a string constant, is converted
to a pointer to the string-containing area.
@ -472,9 +453,7 @@ string2pointer(ex)
ex->VL_VALUE = (arith)0;
}
opnd2integral(expp, oper)
register struct expr **expp;
int oper;
void opnd2integral(register struct expr **expp, int oper)
{
register int fund = (*expp)->ex_type->tp_fund;
@ -486,9 +465,7 @@ opnd2integral(expp, oper)
}
}
opnd2logical(expp, oper)
register struct expr **expp;
int oper;
void opnd2logical(register struct expr **expp, int oper)
{
int fund = (*expp)->ex_type->tp_fund;
@ -525,8 +502,7 @@ opnd2logical(expp, oper)
}
void
opnd2test(expp, oper)
register struct expr **expp;
opnd2test(register struct expr **expp, int oper)
{
opnd2logical(expp, oper);
if ((*expp)->ex_class == Oper) {
@ -550,9 +526,7 @@ opnd2test(expp, oper)
ch3bin(expp, NOTEQUAL, intexpr((arith)0, INT));
}
void
any2opnd(expp, oper)
register struct expr **expp;
void any2opnd(register struct expr **expp, int oper)
{
if (!*expp)
return;
@ -584,8 +558,7 @@ any2opnd(expp, oper)
}
}
any2parameter(expp)
register struct expr **expp;
void any2parameter(register struct expr **expp)
{
/* To handle default argument promotions
*/
@ -598,8 +571,7 @@ any2parameter(expp)
}
#ifndef NOBITFIELD
field2arith(expp)
register struct expr **expp;
void field2arith(register struct expr **expp)
{
/* The expression to extract the bitfield value from the
memory word is put in the tree.
@ -630,8 +602,7 @@ field2arith(expp)
/* switch_sign_fp() negates the given floating constant expression,
* and frees the string representing the old value.
*/
switch_sign_fp(expr)
register struct expr *expr;
void switch_sign_fp(register struct expr *expr)
{
flt_umin(&(expr->FL_ARITH));
}

View file

@ -12,12 +12,15 @@
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 <flt_arith.h>
#else /* SPECIAL_ARITHMETICS */
@ -27,6 +30,32 @@
#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_ */

View file

@ -18,7 +18,10 @@
#include "label.h"
#include "stack.h"
#include "Lpars.h"
extern arith NewLocal();
#include "blocks.h"
#include "macro.h"
#include "util.h"
#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
#define LocalIntVar() NewLocal(int_size, int_align, reg_any, REGISTER)
#endif /* STB */
@ -52,9 +55,7 @@ extern arith NewLocal();
while we need a loop to store the stack block into a memory object.
*/
suitable_sz(sz, al)
arith sz;
int al;
int suitable_sz(arith sz, int al)
{
return ((int)sz % (int)word_size == 0 && al % word_align == 0) ||
(
@ -64,9 +65,7 @@ suitable_sz(sz, al)
);
}
store_block(sz, al)
arith sz;
int al;
void store_block(arith sz, int al)
{
if (suitable_sz(sz, al))
C_sti(sz);
@ -102,9 +101,7 @@ store_block(sz, al)
}
}
load_block(sz, al)
arith sz;
int al;
void load_block(arith sz, int al)
{
if (suitable_sz(sz, al))
@ -138,9 +135,7 @@ load_block(sz, al)
}
}
copy_block(sz, al)
arith sz;
int al;
void copy_block(arith sz, int al)
{
if (suitable_sz(sz, al))
@ -167,8 +162,7 @@ copy_block(sz, al)
}
#ifndef STB
copy_loop(sz, src, dst)
arith sz, src, dst;
void copy_loop(arith sz, arith src, arith dst)
{
/* generate inline byte-copy loop */
label l_cont = text_label(), l_stop = text_label();

View file

@ -0,0 +1,20 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef BLOCKS_H_
#define BLOCKS_H_
#include "parameters.h"
#include "arith.h"
int suitable_sz(arith sz, int al);
void store_block(arith sz, int al);
void load_block(arith sz, int al);
void copy_block(arith sz, int al);
void copy_loop(arith sz, arith src, arith dst);
#endif /* BLOCKS_H_ */

View file

@ -9,6 +9,7 @@
#include "parameters.h"
#include <flt_arith.h>
#include "arith.h"
#include "ch3.h"
#include "idf.h"
#include "proto.h"
#include "type.h"
@ -17,23 +18,22 @@
#include "expr.h"
#include "def.h"
#include "Lpars.h"
#include "error.h"
#include "ch3bin.h"
#include "file_info.h"
extern char options[];
extern char *symbol2str();
extern struct type *qualifier_type();
void ch3cast();
/* Most expression-handling routines have a pointer to a
(struct type *) as first parameter. The object under the pointer
gets updated in the process.
*/
void
ch3sel(expp, oper, idf)
struct expr **expp;
struct idf *idf;
void ch3sel(struct expr **expp, int oper, struct idf *idf)
{
/* The selector idf is applied to *expp; oper may be '.' or
ARROW.
@ -163,8 +163,7 @@ ch3sel(expp, oper, idf)
*expp = exp;
}
ch3incr(expp, oper)
struct expr **expp;
void ch3incr(struct expr **expp, int oper)
{
/* The monadic prefix/postfix incr/decr operator oper is
applied to *expp.
@ -172,10 +171,7 @@ ch3incr(expp, oper)
ch3asgn(expp, oper, intexpr((arith)1, INT));
}
void
ch3cast(expp, oper, tp)
register struct expr **expp;
register struct type *tp;
void ch3cast(register struct expr **expp, int oper, register struct type *tp)
{
/* The expression *expp is cast to type tp; the cast is
caused by the operator oper. If the cast has
@ -412,9 +408,7 @@ ch3cast(expp, oper, tp)
/* Determine whether two types are equal.
*/
equal_type(tp, otp, qual_lev, diag)
register struct type *tp, *otp;
int qual_lev, diag;
int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag)
{
if (tp == otp)
return 1;
@ -475,8 +469,7 @@ equal_type(tp, otp, qual_lev, diag)
}
}
check_pseudoproto(pl, opl, diag)
register struct proto *pl, *opl;
int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag)
{
int retval = 1;
@ -519,9 +512,7 @@ check_pseudoproto(pl, opl, diag)
return retval;
}
legal_mixture(tp, otp, diag)
struct type *tp, *otp;
int diag;
int legal_mixture(struct type *tp, struct type *otp, int diag)
{
struct proto *pl = tp->tp_proto, *opl = otp->tp_proto;
int retval = 1;
@ -562,9 +553,7 @@ legal_mixture(tp, otp, diag)
return retval;
}
equal_proto(pl, opl, diag)
register struct proto *pl, *opl;
int diag;
int equal_proto(register struct proto *pl, register struct proto *opl, int diag)
{
if (pl == opl)
return 1;
@ -586,9 +575,7 @@ equal_proto(pl, opl, diag)
}
/* check if a type has a consqualified member */
recurqual(tp, qual)
struct type *tp;
int qual;
int recurqual(struct type *tp, int qual)
{
register struct sdef *sdf;
@ -610,9 +597,7 @@ int qual;
return 0;
}
ch3asgn(expp, oper, expr)
struct expr **expp;
struct expr *expr;
void ch3asgn(struct expr **expp, int oper, struct expr *expr)
{
/* The assignment operators.
"f op= e" should be interpreted as
@ -687,9 +672,7 @@ ch3asgn(expp, oper, expr)
/* Some interesting (?) questions answered.
*/
int
is_integral_type(tp)
register struct type *tp;
int is_integral_type(register struct type *tp)
{
switch (tp->tp_fund) {
case CHAR:
@ -707,9 +690,7 @@ is_integral_type(tp)
}
}
int
is_arith_type(tp)
register struct type *tp;
int is_arith_type(register struct type *tp)
{
switch (tp->tp_fund) {
case CHAR:

View file

@ -0,0 +1,29 @@
/* Copyright (c) 2019 ACK Project. See the file Copyright in
* the project root directory for more information.
*
* Created on: 2019-02-06
*
*/
#ifndef CH3_H_
#define CH3_H_
/* Structure forward declarations. */
struct expr;
struct type;
struct proto;
struct idf;
void ch3sel(struct expr **expp, int oper, struct idf *idf);
void ch3incr(struct expr **expp, int oper);
void ch3cast(register struct expr **expp, int oper, register struct type *tp);
int equal_type(register struct type *tp,register struct type *otp, int qual_lev, int diag);
int check_pseudoproto(register struct proto *pl,register struct proto *opl, int diag);
int legal_mixture(struct type *tp, struct type *otp, int diag);
int equal_proto(register struct proto *pl, register struct proto *opl, int diag);
int recurqual(struct type *tp, int qual);
void ch3asgn(struct expr **expp, int oper, struct expr *expr);
int is_integral_type(register struct type *tp);
int is_arith_type(register struct type *tp);
#endif /* CH3_H_ */

View file

@ -15,6 +15,12 @@
#include "expr.h"
#include "Lpars.h"
#include "sizes.h"
#include "ch3bin.h"
#include "ch3mon.h"
#include "ch3.h"
#include "error.h"
#include "cstoper.h"
#include "fltcstoper.h"
extern char options[];
extern char *symbol2str();
@ -34,10 +40,7 @@ void pntminuspnt();
#define commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
#define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
void
ch3bin(expp, oper, expr)
register struct expr **expp;
struct expr *expr;
void ch3bin(register struct expr **expp, int oper, struct expr *expr)
{
/* apply binary operator oper between *expp and expr.
NB: don't swap operands if op is one of the op= operators!!!
@ -295,9 +298,7 @@ ch3bin(expp, oper, expr)
}
}
void
pntminuspnt(expp, oper, expr)
register struct expr **expp, *expr;
void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr)
{
/* Subtracting two pointers is so complicated it merits a
routine of its own.
@ -328,8 +329,7 @@ pntminuspnt(expp, oper, expr)
* when the arguments are switched. This is special for some relational
* operators.
*/
int
arg_switched(oper)
int arg_switched(int oper)
{
switch (oper) {
case '<': return '>';
@ -340,9 +340,7 @@ arg_switched(oper)
}
}
mk_binop(expp, oper, expr, commutative)
struct expr **expp;
register struct expr *expr;
void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative)
{
/* Constructs in *expp the operation indicated by the operands.
"commutative" indicates whether "oper" is a commutative
@ -366,8 +364,7 @@ mk_binop(expp, oper, expr, commutative)
}
}
pointer_arithmetic(expp1, oper, expp2)
register struct expr **expp1, **expp2;
void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2)
{
int typ;
/* prepares the integral expression expp2 in order to
@ -387,8 +384,7 @@ pointer_arithmetic(expp1, oper, expp2)
);
}
pointer_binary(expp, oper, expr)
register struct expr **expp, *expr;
void pointer_binary(register struct expr **expp, int oper, register struct expr *expr)
{
/* constructs the pointer arithmetic expression out of
a pointer expression, a binary operator and an integral

View file

@ -0,0 +1,21 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef CH3BIN_H_
#define CH3BIN_H_
struct expr;
void ch3bin(register struct expr **expp, int oper, struct expr *expr);
void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr);
int arg_switched(int oper);
void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative);
void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2);
void pointer_binary(register struct expr **expp, int oper, register struct expr *expr);
#endif /* CH3BIN_H_ */

View file

@ -5,6 +5,7 @@
/* $Id$ */
/* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
#include "ch3mon.h"
#include "parameters.h"
#include <alloc.h>
#include "Lpars.h"
@ -16,13 +17,15 @@
#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.
*/

View file

@ -0,0 +1,22 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef CH3MON_H_
#define CH3MON_H_
struct expr;
void ch3mon(int oper, register struct expr **expp);
void ch3bin(register struct expr **expp, int oper, struct expr *expr);
void pntminuspnt(register struct expr **expp, int oper, register struct expr *expr);
int arg_switched(int oper);
void mk_binop(struct expr **expp, int oper, register struct expr *expr, int commutative);
void pointer_arithmetic(register struct expr **expp1, int oper, register struct expr **expp2);
void pointer_binary(register struct expr **expp, int oper, register struct expr *expr);
#endif /* CH3MON_H_ */

View file

@ -27,14 +27,24 @@
#include "expr.h"
#include "sizes.h"
#include "stack.h"
#include "blocks.h"
#include "struct.h"
#include "level.h"
#include "dataflow.h"
#include "conversion.h"
#include "decspecs.h"
#include "declar.h"
#include "Lpars.h"
#include "specials.h"
#include "atw.h"
#include "ch3.h"
#include "eval.h"
#include "stab.h"
#include "LLlex.h"
#include "align.h"
#include "util.h"
#include "error.h"
#ifdef LINT
#include "l_lint.h"
#endif /* LINT */
@ -46,7 +56,10 @@ label lab_count = 1;
label datlab_count = 1;
int fp_used;
extern arith NewLocal(); /* util.c */
extern void str_cst(register char *, register int, int); /* ival.c */
/* global function info */
char *func_name;
@ -67,8 +80,7 @@ extern char *source;
void loc_init();
#ifndef LINT
init_code(dst_file)
char *dst_file;
void init_code(char *dst_file)
{
/* init_code() initialises the output file on which the
compact EM code is written
@ -105,10 +117,7 @@ init_code(dst_file)
struct string_cst *str_list = 0;
label
code_string(val, len)
char *val;
int len;
label code_string(char* val, int len)
{
register struct string_cst *sc = new_string_cst();
label dlb = data_label();
@ -122,8 +131,7 @@ code_string(val, len)
return dlb;
}
def_strings(sc)
register struct string_cst *sc;
void def_strings(register struct string_cst *sc)
{
while (sc) {
struct string_cst *sc1 = sc;
@ -137,7 +145,7 @@ def_strings(sc)
}
/* flush_strings() is called from program.g after each external definition */
flush_strings() {
void flush_strings(void) {
if (str_list) {
def_strings(str_list);
str_list = 0;
@ -145,7 +153,7 @@ flush_strings() {
}
#ifndef LINT
end_code()
void end_code(void)
{
/* end_code() performs the actions to be taken when closing
the output stream.
@ -160,7 +168,7 @@ end_code()
#endif /* LINT */
#ifdef PREPEND_SCOPES
prepend_scopes()
void prepend_scopes(void)
{
/* prepend_scopes() runs down the list of global idf's
and generates those exa's, exp's, ina's and inp's
@ -185,9 +193,7 @@ prepend_scopes()
}
#endif /* PREPEND_SCOPES */
code_scope(text, def)
char *text;
register struct def *def;
void code_scope(char* text, register struct def *def)
{
/* generates code for one name, text, of the storage class
as given by def, if meaningful.
@ -218,9 +224,7 @@ static int struct_return;
static char *last_fn_given = (char *)0;
static label file_name_label;
begin_proc(ds, idf) /* to be called when entering a procedure */
struct decspecs *ds;
struct idf *idf;
void begin_proc(struct decspecs *ds, struct idf *idf) /* to be called when entering a procedure */
{
/* begin_proc() is called at the entrance of a new function
and performs the necessary code generation:
@ -317,8 +321,7 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
#endif
}
end_proc(fbytes)
arith fbytes;
void end_proc(arith fbytes)
{
/* end_proc() deals with the code to be generated at the end of
a function, as there is:
@ -388,7 +391,7 @@ end_proc(fbytes)
options['n'] = optionsn;
}
do_return()
void do_return(void)
{
/* do_return handles the case of a return without expression.
This version branches to the return label, which is
@ -401,8 +404,7 @@ do_return()
C_bra(return2_label);
}
do_return_expr(expr)
struct expr *expr;
void do_return_expr(struct expr *expr)
{
/* do_return_expr() generates the expression and the jump for
a return statement with an expression.
@ -418,11 +420,11 @@ do_return_expr(expr)
}
void
code_declaration(idf, expr, lvl, sc)
register struct idf *idf; /* idf to be declared */
struct expr *expr; /* initialisation; NULL if absent */
int lvl; /* declaration level */
int sc; /* storage class, as in the declaration */
code_declaration(
register struct idf *idf, /* idf to be declared */
struct expr *expr, /* initialisation; NULL if absent */
int lvl, /* declaration level */
int sc) /* storage class, as in the declaration */
{
/* code_declaration() does the actual declaration of the
variable indicated by "idf" on declaration level "lvl".
@ -530,10 +532,7 @@ code_declaration(idf, expr, lvl, sc)
}
}
void
loc_init(expr, id)
struct expr *expr;
struct idf *id;
void loc_init(struct expr *expr, struct idf *id)
{
/* loc_init() generates code for the assignment of
expression expr to the local variable described by id.
@ -609,8 +608,7 @@ loc_init(expr, id)
}
}
bss(idf)
register struct idf *idf;
void bss(register struct idf *idf)
{
/* bss() allocates bss space for the global idf.
*/
@ -640,9 +638,7 @@ bss(idf)
}
}
formal_cvt(hasproto,df)
int hasproto;
register struct def *df;
void formal_cvt(int hasproto, register struct def *df)
{
/* formal_cvt() converts a formal parameter of type char or
short from int to that type. It also converts a formal
@ -672,9 +668,7 @@ formal_cvt(hasproto,df)
#ifdef LINT
/*ARGSUSED*/
#endif /* LINT */
code_expr(expr, val, code, tlbl, flbl)
struct expr *expr;
label tlbl, flbl;
void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl)
{
/* code_expr() is the parser's interface to the expression code
generator. If line number trace is wanted, it generates a
@ -707,7 +701,7 @@ static struct stmt_block *stmt_stack; /* top of statement stack */
which are the only ones that are stacked, only the top of
the stack is interesting.
*/
code_break()
void code_break(void)
{
register struct stmt_block *stmt_block = stmt_stack;
@ -726,7 +720,7 @@ code_break()
innermost statement in which continue has a meaning.
*/
void
code_continue()
code_continue(void)
{
register struct stmt_block *stmt_block = stmt_stack;
@ -743,8 +737,7 @@ code_continue()
error("continue not inside for, while or do");
}
stack_stmt(break_label, cont_label)
label break_label, cont_label;
void stack_stmt(label break_label, label cont_label)
{
register struct stmt_block *stmt_block = new_stmt_block();
@ -754,7 +747,7 @@ stack_stmt(break_label, cont_label)
stmt_stack = stmt_block;
}
unstack_stmt()
void unstack_stmt(void)
{
/* unstack_stmt() unstacks the data of a statement
which may contain break or continue
@ -766,8 +759,7 @@ unstack_stmt()
static label prc_name;
prc_entry(name)
char *name;
void prc_entry(char* name)
{
if (options['p']) {
C_df_dlb(prc_name = data_label());
@ -778,7 +770,7 @@ prc_entry(name)
}
}
prc_exit()
void prc_exit(void)
{
if (options['p']) {
C_lae_dlb(prc_name, (arith) 0);
@ -788,9 +780,7 @@ prc_exit()
}
#ifdef DBSYMTAB
db_line(file, line)
char *file;
unsigned int line;
void db_line(char *file, unsigned int line)
{
static unsigned oldline;
static char *oldfile;

View file

@ -2,9 +2,15 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef CODE_H_
#define CODE_H_
/* $Id$ */
/* C O D E - G E N E R A T O R D E F I N I T I O N S */
#include "arith.h"
#include "label.h"
struct string_cst { /* storing string constants */
struct string_cst *next;
char *sc_value;
@ -20,3 +26,44 @@ extern struct string_cst *str_list;
#define RVAL 1
#define FALSE 0
#define TRUE 1
#ifndef LINT
void init_code(char *dst_file);
void end_code(void);
#endif
struct expr;
struct def;
struct idf;
label code_string(char* val, int len);
void def_strings(register struct string_cst *sc);
void flush_strings(void);
void code_scope(char* text, register struct def *def);
void begin_proc(struct decspecs *ds, struct idf *idf);
void end_proc(arith fbytes);
void do_return(void);
void do_return_expr(struct expr *expr);
void code_declaration(register struct idf *idf, struct expr *expr,
int lvl, int sc);
void loc_init(struct expr *expr, struct idf *id);
void bss(register struct idf *idf);
void formal_cvt(int hasproto, register struct def *df);
void code_expr(struct expr *expr, int val, int code, label tlbl, label flbl);
void code_break(void);
void code_continue(void);
void stack_stmt(label break_label, label cont_label);
void unstack_stmt(void);
void prc_entry(char* name);
void prc_exit(void);
#ifdef PREPEND_SCOPES
void prepend_scopes(void);
#endif
#ifdef DBSYMTAB
void db_line(char *file, unsigned int line);
#endif
#endif

View file

@ -8,11 +8,15 @@
#include "parameters.h"
#ifndef LINT
#include "conversion.h"
#include <em.h>
#include "interface.h"
#include "arith.h"
#include "type.h"
#include "sizes.h"
#include "Lpars.h"
#include "error.h"
#define T_SIGNED 1
#define T_UNSIGNED 2
@ -27,10 +31,9 @@
C??
*/
static int convtype();
static int convtype(register struct type *);
conversion(from_type, to_type)
register struct type *from_type, *to_type;
void conversion(register struct type *from_type, register struct type *to_type)
{
register arith from_size = from_type->tp_size;
register arith to_size = to_type->tp_size;
@ -126,9 +129,7 @@ conversion(from_type, to_type)
/* convtype() returns in which category a given type falls:
signed, unsigned or floating
*/
static int
convtype(tp)
register struct type *tp;
static int convtype(register struct type *tp)
{
switch (tp->tp_fund) {
case CHAR:

View file

@ -0,0 +1,15 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef CONVERSION_H_
#define CONVERSION_H_
struct type;
void conversion(register struct type *from_type, register struct type *to_type);
#endif /* CONVERSION_H_ */

View file

@ -6,6 +6,7 @@
/* C O N S T A N T E X P R E S S I O N H A N D L I N G */
#include <assert.h>
#include "cstoper.h"
#include "parameters.h"
#include <flt_arith.h>
#include "arith.h"
@ -14,6 +15,7 @@
#include "expr.h"
#include "sizes.h"
#include "Lpars.h"
#include "error.h"
/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
arith full_mask[MAXSIZE + 1];
@ -23,8 +25,7 @@ arith max_unsigned; /* maximum unsigned on target machine */
#endif /* NOCROSS */
extern int ResultKnown;
cstbin(expp, oper, expr)
register struct expr **expp, *expr;
void cstbin(register struct expr **expp, int oper, register struct expr *expr)
{
/* The operation oper is performed on the constant
expressions *expp(ld) and expr(ct), and the result restored in
@ -134,8 +135,7 @@ cstbin(expp, oper, expr)
free_expression(expr);
}
cut_size(expr)
register struct expr *expr;
void cut_size(register struct expr *expr)
{
/* The constant value of the expression expr is made to
conform to the size of the type of the expression.
@ -170,7 +170,7 @@ cut_size(expr)
expr->VL_VALUE = o1;
}
init_cst()
void init_cst(void)
{
register int i = 0;
register arith bt = (arith)0;

View file

@ -0,0 +1,17 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef CSTOPER_H_
#define CSTOPER_H_
struct expr;
void cstbin(register struct expr **expp, int oper, register struct expr *expr);
void cut_size(register struct expr *expr);
void init_cst(void);
#endif /* CSTOPER_H_ */

View file

@ -10,26 +10,26 @@
*/
#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;

View file

@ -0,0 +1,19 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef DATAFLOW_H_
#define DATAFLOW_H_
#ifdef DATAFLOW
void DfaStartFunction(char* nm);
void DfaEndFunction(void);
void DfaCallFunction(char* s);
#endif
#endif /* DATAFLOW_H_ */

View file

@ -19,12 +19,16 @@
#include "struct.h"
#include "field.h"
#include "decspecs.h"
#include "declarator.h"
#include "def.h"
#include "declar.h"
#include "label.h"
#include "expr.h"
#include "sizes.h"
#include "level.h"
#include "error.h"
#include "stab.h"
#ifdef LINT
#include "l_lint.h"
#endif /* LINT */

View file

@ -2,6 +2,9 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef DECLAR_H_
#define DECLAR_H_
/* $Id$ */
/* DEFINITION OF DECLARATOR DESCRIPTORS */
@ -39,3 +42,5 @@ struct decl_unary {
extern struct type *declare_type();
extern struct declarator null_declarator;
#endif

View file

@ -6,6 +6,7 @@
/* D E C L A R A T O R M A N I P U L A T I O N */
#include "parameters.h"
#include "declarator.h"
#include <alloc.h>
#include <flt_arith.h>
#include "arith.h"
@ -14,18 +15,20 @@
#include "Lpars.h"
#include "declar.h"
#include "def.h"
#include "idf.h"
#include "label.h"
#include "expr.h"
#include "sizes.h"
#include "level.h"
#include "error.h"
extern char options[];
struct declarator null_declarator;
struct type *
declare_type(tp, dc)
struct type *tp;
struct declarator *dc;
declare_type(
struct type *tp,
struct declarator *dc)
{
/* Applies the decl_unary list starting at dc->dc_decl_unary
to the type tp and returns the result.
@ -43,12 +46,7 @@ declare_type(tp, dc)
return tp;
}
add_decl_unary(dc, fund, qual, count, fm, pl)
register struct declarator *dc;
int qual;
arith count;
struct formal *fm;
struct proto *pl;
void add_decl_unary(register struct declarator *dc, int fund, int qual, arith count, struct formal *fm, struct proto *pl)
{
/* A decl_unary describing a constructor with fundamental
type fund and with size count is inserted in front of the
@ -75,8 +73,7 @@ add_decl_unary(dc, fund, qual, count, fm, pl)
dc->dc_decl_unary = new;
}
remove_declarator(dc)
struct declarator *dc;
void remove_declarator(struct declarator *dc)
{
/* The decl_unary list starting at dc->dc_decl_unary is
removed.
@ -91,8 +88,7 @@ remove_declarator(dc)
}
}
reject_params(dc)
register struct declarator *dc;
void reject_params(register struct declarator *dc)
{
/* The declarator is checked to have no parameters, if it
is an old-style function. If it is a new-style function,
@ -120,8 +116,7 @@ reject_params(dc)
}
}
check_array_subscript(expr)
register struct expr *expr;
void check_array_subscript(register struct expr *expr)
{
arith size = expr->VL_VALUE;

View file

@ -0,0 +1,28 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef DECLARATOR_H_
#define DECLARATOR_H_
#include "arith.h"
/* Forward declarations. */
struct type;
struct declarator;
struct formal;
struct proto;
struct expr;
struct type *
declare_type(struct type *tp, struct declarator *dc);
void add_decl_unary(register struct declarator *dc, int fund, int qual,
arith count, struct formal *fm, struct proto *pl);
void remove_declarator(struct declarator *dc);
void reject_params(register struct declarator *dc);
void check_array_subscript(register struct expr *expr);
#endif /* DECLARATOR_H_ */

View file

@ -6,12 +6,13 @@
/* D E C L A R A T I O N S P E C I F I E R C H E C K I N G */
#include <assert.h>
#include "Lpars.h"
#include "decspecs.h"
#include "Lpars.h"
#include "arith.h"
#include "type.h"
#include "level.h"
#include "def.h"
#include "error.h"
extern char options[];
extern int level;
@ -20,8 +21,7 @@ extern struct type *qualifier_type();
struct decspecs null_decspecs;
do_decspecs(ds)
register struct decspecs *ds;
void do_decspecs(register struct decspecs *ds)
{
/* The provisional decspecs ds as obtained from the program
is turned into a legal consistent decspecs.
@ -30,17 +30,16 @@ do_decspecs(ds)
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;
}
@ -49,7 +48,8 @@ do_decspecs(ds)
/* 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) {
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))
@ -62,45 +62,70 @@ do_decspecs(ds)
*/
/* 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;
}
@ -113,10 +138,7 @@ do_decspecs(ds)
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;
struct type *qualifier_type(register struct type *tp, int typequal)
{
register struct type *dtp = tp;
register int fund = tp->tp_fund;
@ -124,7 +146,8 @@ qualifier_type(tp, typequal)
while (dtp && dtp->tp_typequal != typequal)
dtp = dtp->next;
if (!dtp) {
if (!dtp)
{
dtp = create_type(fund);
dtp->tp_unsigned = tp->tp_unsigned;
dtp->tp_align = tp->tp_align;
@ -136,9 +159,11 @@ qualifier_type(tp, typequal)
*/
dtp->tp_function = tp->tp_function;
#endif
switch (fund) {
switch (fund)
{
case ARRAY:
if (typequal) {
if (typequal)
{
tp->tp_up = qualifier_type(tp->tp_up, typequal);
dtp->tp_typequal = typequal = 0;
}
@ -148,8 +173,7 @@ qualifier_type(tp, typequal)
/* fallthrough */
case POINTER:
case FUNCTION: /* dont't assign tp_proto */
nottagged:
dtp->tp_up = tp->tp_up;
nottagged: dtp->tp_up = tp->tp_up;
break;
case STRUCT:
case UNION:

View file

@ -2,6 +2,9 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef DECSPECS_H_
#define DECSPECS_H_
/* $Id$ */
/* DECLARATION SPECIFIER DEFINITION */
@ -19,3 +22,10 @@ struct decspecs {
extern struct type *qualifier_type();
extern struct decspecs null_decspecs;
struct type;
void do_decspecs(register struct decspecs *ds);
struct type *qualifier_type(register struct type *tp, int typequal);
#endif

View file

@ -2,6 +2,9 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef DEF_H_
#define DEF_H_
/* $Id$ */
/* IDENTIFIER DEFINITION DESCRIPTOR */
@ -38,3 +41,5 @@ struct def { /* for ordinary tags */
#define REG_BONUS 10 /* register candidate, declared as such */
/* ALLOCDEF "def" 50 */
#endif

View file

@ -8,12 +8,17 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "domacro.h"
#include "parameters.h"
#include "idf.h"
#include "interface.h"
#include "arith.h"
#include "LLlex.h"
#include "Lpars.h"
#include "input.h"
#include "pragma.h"
#include "skip.h"
#include "error.h"
#ifdef DBSYMTAB
#include <stb.h>
@ -23,7 +28,9 @@ int IncludeLevel = 0;
extern char options[];
struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */
static void do_line(unsigned int);
struct idf* GetIdentifier(int skiponerr) /* skip the rest of the line on error */
{
/* returns a pointer to the descriptor of the identifier that is
read from the input stream. When the input does not contain
@ -44,7 +51,7 @@ struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line
return tk.tk_idf;
}
domacro()
void domacro(void)
{
int tok;
struct token tk;
@ -70,7 +77,7 @@ domacro()
SkipToNewLine();
}
do_line(l) unsigned int l;
static void do_line(unsigned int l)
{
struct token tk;
int t = GetToken(&tk);

View file

@ -0,0 +1,16 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef DOMACRO_H_
#define DOMACRO_H_
struct idf;
struct idf* GetIdentifier(int skiponerr) ;
void domacro(void);
#endif /* DOMACRO_H_ */

View file

@ -6,6 +6,7 @@
/* E R R O R A N D D I A G N O S T I C R O U T I N E S */
#include "parameters.h"
#include "error.h"
#if __STDC__
#include <stdarg.h>
#else
@ -17,13 +18,15 @@
#else
#include "l_em.h"
#endif /* LINT */
#include <stdio.h>
#include "tokenname.h"
#include <flt_arith.h>
#include "interface.h"
#include "arith.h"
#include "label.h"
#include "expr.h"
#include "def.h"
#include "print.h"
#include "LLlex.h"
/* This file contains the error-message and diagnostic
@ -56,12 +59,11 @@ extern char loptions[];
FileName, expression errors get their information from the
expression, whereas other errors use the information in the token.
*/
static void _error();
static void _error(int, char *, unsigned int, char*, va_list);
#if __STDC__
/*VARARGS*/
error(char *fmt, ...)
void error(char *fmt, ...)
{
va_list ap;
@ -73,7 +75,7 @@ error(char *fmt, ...)
}
/*VARARGS*/
expr_error(struct expr *expr, char *fmt, ...)
void expr_error(struct expr *expr, char *fmt, ...)
{
va_list ap;
@ -89,7 +91,7 @@ expr_error(struct expr *expr, char *fmt, ...)
}
/*VARARGS*/
lexstrict(char *fmt, ...)
void lexstrict(char *fmt, ...)
{
va_list ap;
@ -101,7 +103,7 @@ lexstrict(char *fmt, ...)
}
/*VARARGS*/
strict(char *fmt, ...)
void strict(char *fmt, ...)
{
va_list ap;
@ -113,7 +115,7 @@ strict(char *fmt, ...)
}
/*VARARGS*/
expr_strict(struct expr *expr, char *fmt, ...)
void expr_strict(struct expr *expr, char *fmt, ...)
{
va_list ap;
@ -129,7 +131,7 @@ expr_strict(struct expr *expr, char *fmt, ...)
#ifdef DEBUG
/*VARARGS*/
debug(char *fmt, ...)
void debug(char *fmt, ...)
{
va_list ap;
@ -142,7 +144,7 @@ debug(char *fmt, ...)
#endif /* DEBUG */
/*VARARGS*/
warning(char *fmt, ...)
void warning(char *fmt, ...)
{
va_list ap;
@ -154,7 +156,7 @@ warning(char *fmt, ...)
}
/*VARARGS*/
expr_warning(struct expr *expr, char *fmt, ...)
void expr_warning(struct expr *expr, char *fmt, ...)
{
va_list ap;
@ -171,7 +173,7 @@ expr_warning(struct expr *expr, char *fmt, ...)
#ifdef LINT
/*VARARGS*/
def_warning(struct def *def, char *fmt, ...)
void def_warning(struct def *def, char *fmt, ...)
{
va_list ap;
@ -184,7 +186,7 @@ def_warning(struct def *def, char *fmt, ...)
/*VARARGS*/
hwarning(char *fmt, ...)
void hwarning(char *fmt, ...)
{
va_list ap;
@ -197,7 +199,7 @@ hwarning(char *fmt, ...)
}
/*VARARGS*/
awarning(char *fmt, ...)
void awarning(char *fmt, ...)
{
va_list ap;
@ -212,7 +214,7 @@ awarning(char *fmt, ...)
#endif /* LINT */
/*VARARGS*/
lexerror(char *fmt, ...)
void lexerror(char *fmt, ...)
{
va_list ap;
@ -224,7 +226,7 @@ lexerror(char *fmt, ...)
}
/*VARARGS*/
lexwarning(char *fmt, ...)
void lexwarning(char *fmt, ...)
{
va_list ap;
@ -236,7 +238,7 @@ lexwarning(char *fmt, ...)
}
/*VARARGS*/
crash(char *fmt, ...)
void crash(char *fmt, ...)
{
va_list ap;
@ -256,7 +258,7 @@ crash(char *fmt, ...)
}
/*VARARGS*/
fatal(char *fmt, ...)
void fatal(char *fmt, ...)
{
va_list ap;
@ -272,7 +274,7 @@ fatal(char *fmt, ...)
}
#else
/*VARARGS*/
error(va_alist) /* fmt, args */
void error(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -286,7 +288,7 @@ error(va_alist) /* fmt, args */
}
/*VARARGS*/
expr_error(va_alist) /* expr, fmt, args */
void expr_error(va_alist) /* expr, fmt, args */
va_dcl
{
va_list ap;
@ -306,7 +308,7 @@ expr_error(va_alist) /* expr, fmt, args */
}
/*VARARGS*/
lexstrict(va_alist)
void lexstrict(va_alist)
va_dcl
{
va_list ap;
@ -320,7 +322,7 @@ lexstrict(va_alist)
}
/*VARARGS*/
strict(va_alist)
void strict(va_alist)
va_dcl
{
va_list ap;
@ -334,7 +336,7 @@ strict(va_alist)
}
/*VARARGS*/
expr_strict(va_alist) /* expr, fmt, args */
void expr_strict(va_alist) /* expr, fmt, args */
va_dcl
{
va_list ap;
@ -354,7 +356,7 @@ expr_strict(va_alist) /* expr, fmt, args */
#ifdef DEBUG
/*VARARGS*/
debug(va_alist)
void debug(va_alist)
va_dcl
{
va_list ap;
@ -369,7 +371,7 @@ debug(va_alist)
#endif /* DEBUG */
/*VARARGS*/
warning(va_alist)
void warning(va_alist)
va_dcl
{
va_list ap;
@ -383,7 +385,7 @@ warning(va_alist)
}
/*VARARGS*/
expr_warning(va_alist) /* expr, fmt, args */
void expr_warning(va_alist) /* expr, fmt, args */
va_dcl
{
va_list ap;
@ -404,7 +406,7 @@ expr_warning(va_alist) /* expr, fmt, args */
#ifdef LINT
/*VARARGS*/
def_warning(va_alist) /* def, fmt, args */
void def_warning(va_alist) /* def, fmt, args */
va_dcl
{
va_list ap;
@ -421,7 +423,7 @@ def_warning(va_alist) /* def, fmt, args */
/*VARARGS*/
hwarning(va_alist) /* fmt, args */
void hwarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -436,7 +438,7 @@ hwarning(va_alist) /* fmt, args */
}
/*VARARGS*/
awarning(va_alist) /* fmt, args */
void awarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -453,7 +455,7 @@ awarning(va_alist) /* fmt, args */
#endif /* LINT */
/*VARARGS*/
lexerror(va_alist) /* fmt, args */
void lexerror(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -467,7 +469,7 @@ lexerror(va_alist) /* fmt, args */
}
/*VARARGS*/
lexwarning(va_alist) /* fmt, args */
void lexwarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -481,7 +483,7 @@ lexwarning(va_alist) /* fmt, args */
}
/*VARARGS*/
crash(va_alist) /* fmt, args */
void crash(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -503,7 +505,7 @@ crash(va_alist) /* fmt, args */
}
/*VARARGS*/
fatal(va_alist) /* fmt, args */
void fatal(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
@ -521,13 +523,7 @@ fatal(va_alist) /* fmt, args */
}
#endif
static void
_error(class, fn, ln, fmt, ap)
int class;
char *fn;
unsigned int ln;
char *fmt;
va_list ap;
static void _error(int class, char *fn, unsigned int ln, char* fmt, va_list ap)
{
char *remark;
@ -614,9 +610,9 @@ _error(class, fn, ln, fmt, ap)
#endif /* LINT */
if (fn)
fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
fprint(stderr, "\"%s\", line %u: ", fn, ln);
if (remark)
fprint(ERROUT, "%s ", remark);
doprnt(ERROUT, fmt, ap); /* contents of error */
fprint(ERROUT, "\n");
fprint(stderr, "%s ", remark);
doprnt(stderr, fmt, ap); /* contents of error */
fprint(stderr, "\n");
}

View file

@ -0,0 +1,94 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef ERROR_H_
#define ERROR_H_
struct expr;
#if __STDC__
/*VARARGS*/
void error(char *fmt, ...);
/*VARARGS*/
void expr_error(struct expr *expr, char *fmt, ...);
/*VARARGS*/
void lexstrict(char *fmt, ...);
/*VARARGS*/
void strict(char *fmt, ...);
/*VARARGS*/
void expr_strict(struct expr *expr, char *fmt, ...);
#ifdef DEBUG
/*VARARGS*/
void debug(char *fmt, ...);
#endif /* DEBUG */
/*VARARGS*/
void warning(char *fmt, ...);
/*VARARGS*/
void expr_warning(struct expr *expr, char *fmt, ...);
#ifdef LINT
/*VARARGS*/
void def_warning(struct def *def, char *fmt, ...);
/*VARARGS*/
void hwarning(char *fmt, ...);
/*VARARGS*/
void awarning(char *fmt, ...);
#endif /* LINT */
/*VARARGS*/
void lexerror(char *fmt, ...);
/*VARARGS*/
void lexwarning(char *fmt, ...);
/*VARARGS*/
void crash(char *fmt, ...);
/*VARARGS*/
void fatal(char *fmt, ...);
#else
/*VARARGS*/
void error(va_alist); /* fmt, args */
/*VARARGS*/
void expr_error(va_alist); /* expr, fmt, args */
/*VARARGS*/
void lexstrict(va_alist);
/*VARARGS*/
void strict(va_alist);
/*VARARGS*/
void expr_strict(va_alist); /* expr, fmt, args */
#ifdef DEBUG
/*VARARGS*/
void debug(va_alist);
#endif /* DEBUG */
/*VARARGS*/
void warning(va_alist);
/*VARARGS*/
void expr_warning(va_alist); /* expr, fmt, args */
#ifdef LINT
/*VARARGS*/
void def_warning(va_alist); /* def, fmt, args */
/*VARARGS*/
void hwarning(va_alist); /* fmt, args */
/*VARARGS*/
void awarning(va_alist); /* fmt, args */
#endif /* LINT */
/*VARARGS*/
void lexerror(va_alist); /* fmt, args */
/*VARARGS*/
void lexwarning(va_alist); /* fmt, args */
/*VARARGS*/
void crash(va_alist); /* fmt, args */
/*VARARGS*/
void fatal(va_alist); /* fmt, args */
#endif
#endif /* ERROR_H_ */

View file

@ -2,6 +2,9 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef ESTACK_H_
#define ESTACK_H_
/* $Id$ */
/* EXPRESSION STACK */
/* Used for global initializations */
@ -19,3 +22,5 @@ struct e_stack {
#define last_offset s_cnt2
#define elem_count s_cnt1
#define nelem s_cnt2
#endif

View file

@ -14,6 +14,8 @@
#include <em_reg.h>
#include <alloc.h>
#include <flt_arith.h>
#include "interface.h"
#include "eval.h"
#include "idf.h"
#include "arith.h"
#include "type.h"
@ -22,13 +24,21 @@
#include "def.h"
#include "expr.h"
#include "sizes.h"
#include "field.h"
#include "Lpars.h"
#include "level.h"
#include "conversion.h"
#include "stack.h"
#include "struct.h"
#include "align.h"
#include "mes.h"
#include "atw.h"
#include "ch3.h"
#include "util.h"
#include "blocks.h"
#include "dataflow.h"
#include "specials.h"
#include "error.h"
#define CRASH() crash("EVAL: CRASH at line %u", __LINE__)
@ -37,8 +47,12 @@ arith NewLocal(); /* util.c */
#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
extern int err_occurred; /* error.c */
void store_val();
void load_val();
/* Forward internal declarations */
static void operands(register struct expr *, int);
static void ptr_add(arith size);
static void truthvalue(int relop);
static void compare(int relop, label lbl);
/* EVAL() is the main expression-tree evaluator, which turns
any legal expression tree into EM code. parameters.h:
@ -66,11 +80,7 @@ void load_val();
labels, in case they are specified (i.e. are non-zero)
*/
void
EVAL(expr, val, code, true_label, false_label)
register struct expr *expr;
int val, code;
label true_label, false_label;
void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label)
{
int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE));
register int gencode = code == TRUE;
@ -659,9 +669,7 @@ EVAL(expr, val, code, true_label, false_label)
}
/* compare() serves as an auxiliary function of EVAL */
compare(relop, lbl)
int relop;
label lbl;
static void compare(int relop, label lbl)
{
switch (relop) {
case '<':
@ -688,8 +696,7 @@ compare(relop, lbl)
}
/* truthvalue() serves as an auxiliary function of EVAL */
truthvalue(relop)
int relop;
static void truthvalue(int relop)
{
switch (relop) {
case '<':
@ -717,12 +724,10 @@ truthvalue(relop)
/* assop() generates the opcode of an assignment operators op= */
assop(type, oper)
register struct type *type;
int oper;
void assop(register struct type *type, int oper)
{
register arith size;
register uns = type->tp_unsigned;
register int uns = type->tp_unsigned;
if ((int)(size = type->tp_size) < (int)word_size)
size = word_size;
@ -822,8 +827,7 @@ assop(type, oper)
}
}
ptr_add(size)
arith size;
static void ptr_add(arith size)
{
if (size != pointer_size) {
C_loc(size);
@ -840,10 +844,7 @@ ptr_add(size)
- into a local static variable
- absolute addressing
*/
void
store_val(vl, tp)
register struct value *vl;
register struct type *tp;
void store_val(register struct value *vl, register struct type *tp)
{
register int inword = 0;
register int indword = 0;
@ -911,11 +912,10 @@ store_val(vl, tp)
- global variable
- static variable
- local variable
rlval generate rlval or lval
*/
void
load_val(expr, rlval)
register struct expr *expr; /* expression containing the value */
int rlval; /* generate either LVAL or RVAL */
void load_val(register struct expr *expr, int rlval)
{
register struct type *tp = expr->ex_type;
int rvalue = (rlval == RVAL && expr->ex_lvalue != 0);
@ -1012,8 +1012,7 @@ load_val(expr, rlval)
}
}
load_cst(val, siz)
arith val, siz;
void load_cst(arith val, arith siz)
{
if ((int)siz <= (int)word_size)
C_loc(val);
@ -1030,8 +1029,7 @@ load_cst(val, siz)
}
}
operands(expr, gencode)
register struct expr *expr;
static void operands(register struct expr *expr, int gencode)
{
EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL);
EVAL(expr->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL);

View file

@ -0,0 +1,37 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-06
*
*/
#ifndef EVAL_H_
#define EVAL_H_
#ifndef LINT
#include <em.h>
struct expr;
struct value;
struct type;
void EVAL(register struct expr *expr, int val, int code, label true_label, label false_label);
/* assop() generates the opcode of an assignment operators op= */
void assop(register struct type *type, int oper);
/* store_val() generates code for a store operation.
There are four ways of storing data:
- into a global variable
- into an automatic local variable
- into a local static variable
- absolute addressing
*/
void store_val(register struct value *vl, register struct type *tp);
void load_val(register struct expr *expr, int rlval);
void load_cst(arith val, arith siz);
#endif /* LINT */
#endif /* EVAL_H_ */

View file

@ -10,6 +10,7 @@
#include "parameters.h"
#include <alloc.h>
#include <flt_arith.h>
#include "expr.h"
#include "idf.h"
#include "arith.h"
#include "def.h"
@ -22,18 +23,19 @@
#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. */
case '[':
@ -98,8 +100,7 @@ rank_of(oper)
/*NOTREACHED*/
}
dot2expr(expp)
struct expr **expp;
void dot2expr(struct expr **expp)
{
/* The token in dot is converted into an expression, a
pointer to which is stored in *expp.
@ -109,7 +110,8 @@ dot2expr(expp)
*expp = ex;
ex->ex_file = dot.tk_file;
ex->ex_line = dot.tk_line;
switch (DOT) {
switch (DOT)
{
case IDENTIFIER:
idf2expr(ex);
break;
@ -125,8 +127,7 @@ dot2expr(expp)
}
}
idf2expr(expr)
register struct expr *expr;
void idf2expr(register struct expr *expr)
{
/* Dot contains an identifier which is turned into an
expression.
@ -136,14 +137,17 @@ idf2expr(expr)
register struct idf *idf = dot.tk_idf; /* != 0*/
register struct def *def = idf->id_def;
if (def == 0) {
if (AHEAD == '(') {
if (def == 0)
{
if (AHEAD == '(')
{
/* function call, declare name implicitly (3.3.2.2) */
if (!options['o'])
warning("implicit declaration of function %s"
, idf->id_text);
warning("implicit declaration of function %s", idf->id_text);
add_def(idf, EXTERN, funint_type, level);
} else {
}
else
{
if (!is_anon_idf(idf))
error("%s undefined", idf->id_text);
/* declare idf anyway */
@ -153,8 +157,10 @@ idf2expr(expr)
}
/* now def != 0 */
#ifndef LINT
if (!InSizeof) {
if (! def->df_used) {
if (!InSizeof)
{
if (!def->df_used)
{
#ifndef PREPEND_SCOPES
code_scope(idf->id_text, def);
#endif /* PREPEND_SCOPES */
@ -163,42 +169,41 @@ idf2expr(expr)
}
#endif /* LINT */
expr->ex_type = def->df_type;
if (expr->ex_type == error_type) {
if (expr->ex_type == error_type)
{
expr->ex_flags |= EX_ERROR;
}
expr->ex_lvalue =
( def->df_type->tp_fund == FUNCTION ||
def->df_type->tp_fund == ARRAY ||
def->df_sc == ENUM
) ? 0 : 1;
(def->df_type->tp_fund == FUNCTION || def->df_type->tp_fund == ARRAY
|| def->df_sc == ENUM) ? 0 : 1;
if (def->df_type->tp_typequal & TQ_CONST)
expr->ex_flags |= EX_READONLY;
if (def->df_type->tp_typequal & TQ_VOLATILE)
expr->ex_flags |= EX_VOLATILE;
expr->ex_class = Value;
if (def->df_sc == ENUM) {
if (def->df_sc == ENUM)
{
expr->VL_CLASS = Const;
expr->VL_VALUE = def->df_address;
}
#ifndef LINT
else
if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
else if (def->df_sc == STATIC && def->df_level >= L_LOCAL)
{
expr->VL_CLASS = Label;
expr->VL_LBL = def->df_address;
expr->VL_VALUE = (arith) 0;
}
#endif /* LINT */
else {
else
{
expr->VL_CLASS = Name;
expr->VL_IDF = idf;
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.
@ -217,8 +222,7 @@ string2expr(expp, str, len)
ex->SG_LEN = len;
}
int2expr(expr)
struct expr *expr;
void int2expr(struct expr *expr)
{
/* Dot contains an integer constant which is turned
into an expression.
@ -226,8 +230,7 @@ int2expr(expr)
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.
@ -235,7 +238,8 @@ float2expr(expr)
register int fund;
fund = dot.tk_fund;
switch (fund) {
switch (fund)
{
case FLOAT:
expr->ex_type = float_type;
break;
@ -256,10 +260,8 @@ float2expr(expr)
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.
@ -272,15 +274,14 @@ intexpr(ivalue, fund)
return expr;
}
fill_int_expr(ex, ivalue, fund)
register struct expr *ex;
arith ivalue;
int fund;
void fill_int_expr(register struct expr *ex,
arith ivalue, int fund)
{
/* Details derived from ivalue and fund are put into the
constant integer expression ex.
*/
switch (fund) {
switch (fund)
{
case INT:
ex->ex_type = int_type;
break;
@ -303,10 +304,8 @@ fill_int_expr(ex, ivalue, fund)
cut_size(ex);
}
struct expr *
new_oper(tp, e1, oper, e2)
struct type *tp;
register struct expr *e1, *e2;
struct expr *new_oper(struct type *tp, register struct expr *e1, int oper,
register struct expr *e2)
{
/* A new expression is constructed which consists of the
operator oper which has e1 and e2 as operands; for a
@ -317,7 +316,8 @@ new_oper(tp, e1, oper, e2)
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)
@ -325,8 +325,8 @@ new_oper(tp, e1, oper, e2)
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)
@ -334,7 +334,8 @@ new_oper(tp, e1, oper, e2)
expr->ex_file = e->ex_file;
expr->ex_line = e->ex_line;
}
else {
else
{
expr->ex_file = dot.tk_file;
expr->ex_line = dot.tk_line;
}
@ -342,12 +343,13 @@ new_oper(tp, e1, oper, e2)
expr->ex_type = tp;
expr->ex_class = Oper;
/* combine depths and flags of both expressions */
if (e2) {
if (e2)
{
int e1_depth = e1 ? e1->ex_depth : 0;
int e1_flags = e1 ? e1->ex_flags : 0;
expr->ex_depth =
(e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
expr->ex_depth = (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth)
+ 1;
expr->ex_flags = (e1_flags | e2->ex_flags)
& ~(EX_PARENS | EX_READONLY | EX_VOLATILE);
}
@ -355,7 +357,8 @@ new_oper(tp, e1, oper, e2)
* A function call should be evaluated first when possible. Just say
* that the expression tree is very deep.
*/
if (oper == '(') {
if (oper == '(')
{
expr->ex_depth = 50;
}
op = &expr->ex_object.ex_oper;
@ -369,9 +372,7 @@ new_oper(tp, e1, oper, e2)
return expr;
}
void
chk_cst_expr(expp)
struct expr **expp;
void chk_cst_expr(struct expr **expp)
{
/* The expression expr is checked for constancy.
@ -398,13 +399,15 @@ chk_cst_expr(expp)
#ifdef DEBUG
print_expr("constant_expression", expr);
#endif /* DEBUG */
switch(expr->ex_type->tp_fund) {
switch (expr->ex_type->tp_fund)
{
case CHAR:
case SHORT:
case INT:
case ENUM:
case LONG:
if (is_ld_cst(expr)) {
if (is_ld_cst(expr))
{
return;
}
expr_error(expr, "expression is not constant");
@ -416,9 +419,7 @@ chk_cst_expr(expp)
erroneous2int(expp);
}
init_expression(eppp, expr)
register struct expr ***eppp;
struct expr *expr;
void init_expression(register struct expr ***eppp, struct expr *expr)
{
/* The expression expr is added to the tree designated
indirectly by **eppp.
@ -436,9 +437,7 @@ init_expression(eppp, expr)
*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>.
@ -450,9 +449,7 @@ is_ld_cst(expr)
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.
@ -460,9 +457,7 @@ is_cp_cst(expr)
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.
@ -470,13 +465,12 @@ is_fp_cst(expr)
return expr->ex_class == Float;
}
int
is_zero_cst(expr)
register struct expr *expr;
int is_zero_cst(register struct expr *expr)
{
flt_arith var;
switch(expr->ex_class) {
switch (expr->ex_class)
{
case Value:
return expr->VL_VALUE == 0;
case Float:
@ -486,13 +480,14 @@ is_zero_cst(expr)
/*NOTREACHED*/
}
free_expression(expr)
register struct expr *expr;
void free_expression(register struct expr *expr)
{
/* The expression expr is freed recursively.
*/
if (expr) {
if (expr->ex_class == Oper) {
if (expr)
{
if (expr->ex_class == Oper)
{
free_expression(expr->OP_LEFT);
free_expression(expr->OP_RIGHT);
}

View file

@ -4,6 +4,13 @@
*/
/* $Id$ */
/* EXPRESSION DESCRIPTOR */
#ifndef EXPR_H_
#define EXPR_H_
#include "parameters.h"
#include "arith.h"
#include "label.h"
#include "flt_arith.h"
/* What we want to define is the struct expr, but since it contains
a union of various goodies, we define them first; so be patient.
@ -97,3 +104,24 @@ extern struct expr *intexpr(), *new_oper();
/* ALLOCDEF "expr" 20 */
int rank_of(int oper);
void dot2expr(struct expr **expp);
void idf2expr(register struct expr *expr);
void string2expr(register struct expr **expp, char *str, int len);
void int2expr(struct expr *expr);
void float2expr(register struct expr *expr);
struct expr* intexpr(arith ivalue, int fund);
void fill_int_expr(register struct expr *ex,arith ivalue, int fund);
struct expr *new_oper(struct type *tp, register struct expr *e1, int oper,
register struct expr *e2);
void chk_cst_expr(struct expr **expp);
void init_expression(register struct expr ***eppp, struct expr *expr);
int is_ld_cst(register struct expr *expr);
int is_cp_cst(struct expr *expr);
int is_fp_cst(struct expr *expr);
int is_zero_cst(register struct expr *expr);
void free_expression(register struct expr *expr);
#endif

View file

@ -15,6 +15,11 @@
#include "label.h"
#include "expr.h"
#include "code.h"
#include "error.h"
#include "ch3.h"
#include "ch3bin.h"
#include "ch3mon.h"
#include "proto.h"
#include "sizes.h"
extern struct expr *intexpr();

View file

@ -23,8 +23,11 @@
#include "align.h"
#include "Lpars.h"
#include "field.h"
#include "util.h"
#include "conversion.h"
#include "eval.h"
arith NewLocal(); /* util.c */
extern arith full_mask[]; /* cstoper.c */
/* Eval_field() evaluates expressions involving bit fields.
@ -39,9 +42,9 @@ extern arith full_mask[]; /* cstoper.c */
[3] atype: the type in which the bitfield arithmetic is done;
and in which bitfields are stored!
*/
eval_field(expr, code)
struct expr *expr;
int code;
void eval_field(
struct expr *expr,
int code)
{
int op = expr->OP_OPER;
register struct expr *leftop = expr->OP_LEFT;
@ -126,12 +129,12 @@ eval_field(expr, code)
}
}
store_field(fd, uns, code, leftop, tmpvar)
register struct field *fd;
int uns;
int code;
register struct expr *leftop;
arith tmpvar;
void store_field(
register struct field *fd,
int uns,
int code,
register struct expr *leftop,
arith tmpvar)
{
C_loc(fd->fd_mask);
C_and(word_size);

View file

@ -2,6 +2,11 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef FIELD_H_
#define FIELD_H_
#include "arith.h"
/* $Id$ */
/* FIELD DESCRIPTOR */
@ -13,3 +18,20 @@ struct field { /* for field specifiers */
};
/* ALLOCDEF "field" 10 */
#ifndef LINT
#ifndef NOBITFIELD
struct expr;
void store_field(register struct field *fd, int uns, int code,
register struct expr *leftop, arith tmpvar);
void eval_field(struct expr *expr, int code);
#endif /* NOBITFIELD */
#endif /* LINT */
#endif /* FIELD_H_ */

View file

@ -10,18 +10,19 @@
#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

View file

@ -0,0 +1,15 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-07
*
*/
#ifndef FLTCSTOPER_H_
#define FLTCSTOPER_H_
struct expr;
void fltcstbin(register struct expr **expp, int oper, register struct expr *expr);
#endif /* FLTCSTOPER_H_ */

View file

@ -25,6 +25,12 @@
#include "declar.h"
#include "decspecs.h"
#include "sizes.h"
#include "print.h"
#include "util.h"
#include "stab.h"
#include "code.h"
#include "error.h"
#include "ch3.h"
#include "Lpars.h"
extern char options[];
@ -37,10 +43,9 @@ extern char *symbol2str();
#include <idf_pkg.body>
void global_redecl();
struct idf *
gen_idf()
struct idf *gen_idf(void)
{
/* A new idf is created out of nowhere, to serve as an
anonymous name.
@ -48,22 +53,17 @@ gen_idf()
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);
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
@ -85,37 +85,44 @@ declare_idf(ds, dc, 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 */
}
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 (type->tp_fund != VOID)
{
if (level != L_GLOBAL)
error("unknown %s-type",
symbol2str(type->tp_fund));
} else error("void is not a complete type");
error("unknown %s-type", symbol2str(type->tp_fund));
}
else strict("%s has size 0", idf->id_text);
else
error("void is not a complete type");
}
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);
warning("%s is a function; cannot be formal", idf->id_text);
type = construct_type(POINTER, type, 0, (arith) 0,
NO_PROTO);
break;
@ -138,13 +145,16 @@ declare_idf(ds, dc, lvl)
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;
}
}
@ -153,29 +163,28 @@ declare_idf(ds, dc, lvl)
}
else /* non-FUNCTION */
if (sc == 0)
sc = lvl == L_GLOBAL ? GLOBAL
: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
: AUTO;
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 */
#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) {
switch (lvl)
{
case L_GLOBAL:
global_redecl(idf, sc, type);
def->df_file = idf->id_file;
@ -186,12 +195,14 @@ declare_idf(ds, dc, lvl)
break;
case L_FORMAL2: /* formal definition */
default: /* local */
if (sc != EXTERN) error("%s redeclared", idf->id_text);
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)) {
if (lvl == L_FORMAL2 && sc != ENUM && good_formal(def, idf))
{
/* formal declaration, update only */
def->df_type = type;
def->df_formal_array = formal_array;
@ -200,7 +211,8 @@ declare_idf(ds, dc, lvl)
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;
@ -223,23 +235,22 @@ declare_idf(ds, dc, lvl)
Formals are handled by declare_formals().
So here we hand out local addresses only.
*/
if (lvl >= L_LOCAL) {
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);
if (type->tp_size == (arith) -1 && type->tp_fund != ARRAY)
{
error("size of local %s unknown", idf->id_text);
/** type = idf->id_def->df_type = int_type; **/
}
if (type->tp_size != (arith) -1) {
newdef->df_address =
NewLocal(type->tp_size,
type->tp_align,
regtype(type),
sc);
if (type->tp_size != (arith) -1)
{
newdef->df_address = NewLocal(type->tp_size, type->tp_align,
regtype(type), sc);
}
break;
case STATIC:
@ -250,10 +261,7 @@ declare_idf(ds, dc, lvl)
}
}
int
actual_declaration(sc, tp)
int sc;
struct type *tp;
int actual_declaration(int sc, struct type *tp)
{
/* An actual_declaration needs space, right here and now.
*/
@ -264,7 +272,8 @@ actual_declaration(sc, tp)
if (fund == FUNCTION || fund == ARRAY)
/* allocation solved in other ways */
return 0;
if (sc == EXTERN && fund == VOID) {
if (sc == EXTERN && fund == VOID)
{
/* strange, but should be accepted */
return 0;
}
@ -272,10 +281,7 @@ actual_declaration(sc, tp)
return 1;
}
void
global_redecl(idf, new_sc, tp)
register struct idf *idf;
struct type *tp;
void global_redecl(register struct idf *idf, int new_sc, struct type *tp)
{
/* A global identifier may be declared several times,
provided the declarations do not conflict; they might
@ -285,20 +291,29 @@ global_redecl(idf, new_sc, tp)
*/
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;
}
@ -314,9 +329,11 @@ global_redecl(idf, new_sc, tp)
STATIC: we have seen the word "static"
*/
switch (def->df_sc) { /* the old storage class */
switch (def->df_sc)
{ /* the old storage class */
case EXTERN:
switch (new_sc) { /* the new storage class */
switch (new_sc)
{ /* the new storage class */
case STATIC:
warning("%s redeclared static", idf->id_text);
/* fallthrough */
@ -331,7 +348,8 @@ global_redecl(idf, new_sc, tp)
}
break;
case GLOBAL:
switch (new_sc) { /* the new storage class */
switch (new_sc)
{ /* the new storage class */
case STATIC: /* linkage disagreement */
warning("%s redeclared static", idf->id_text);
def->df_sc = new_sc;
@ -345,7 +363,8 @@ global_redecl(idf, new_sc, tp)
}
break;
case STATIC:
switch (new_sc) { /* the new storage class */
switch (new_sc)
{ /* the new storage class */
case GLOBAL: /* linkage disagreement */
case EXTERN:
warning("%s is already declared static", idf->id_text);
@ -367,15 +386,13 @@ global_redecl(idf, new_sc, tp)
}
}
int
good_formal(def, idf)
register struct def *def;
register struct idf *idf;
int good_formal(register struct def *def, register struct idf *idf)
{
/* Succeeds if def is a proper L_FORMAL1 definition and
gives an error message otherwise.
*/
if (!def || def->df_level != L_FORMAL1) { /* not in parameter list */
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;
@ -384,49 +401,45 @@ good_formal(def, idf)
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;
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.
*/
@ -434,75 +447,86 @@ declare_enum(tp, idf, l)
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 (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) {
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)) {
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);
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);
warning("'%s' old-fashioned function definition",
dc->dc_idf->id_text);
while (fm) {
if (pl == 0) pl = lpl;
else {
while (fm)
{
if (pl == 0)
pl = lpl;
else
{
lpl->next = new_proto();
lpl = lpl->next;
}
lpl->pl_flag = PL_FORMAL;
lpl->pl_idf = fm->fm_idf;
lpl->pl_type =
promoted_type(fm->fm_idf->id_def->df_type);
lpl->pl_type = promoted_type(fm->fm_idf->id_def->df_type);
fm = fm->next;
}
if (pl == 0) { /* make func(void) */
if (pl == 0)
{ /* make func(void) */
pl = lpl;
pl->pl_type = void_type;
pl->pl_flag = PL_FORMAL | PL_VOID;
@ -513,9 +537,7 @@ check_formals(idf, dc)
dc->dc_formal = 0;
}
declare_formals(idf, fp)
struct idf *idf;
arith *fp;
void declare_formals(struct idf *idf, arith *fp)
{
/* Declares those formals as int that haven't been declared
by the user.
@ -531,8 +553,10 @@ declare_formals(idf, fp)
/* 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) {
while (se)
{
if (se->se_idf == idf)
{
df = df->next;
break;
}
@ -547,15 +571,18 @@ declare_formals(idf, fp)
if (options['t'])
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;
}
@ -565,15 +592,15 @@ declare_formals(idf, fp)
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) {
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);
@ -582,7 +609,8 @@ declare_formals(idf, fp)
if (nparams++ >= STDC_NPARAMS)
strict("number of formal parameters exceeds ANSI limit");
#ifdef DBSYMTAB
if (options['g']) {
if (options['g'])
{
stb_string(df, FORMAL, se->se_idf->id_text);
}
#endif /* DBSYMTAB */
@ -591,11 +619,10 @@ declare_formals(idf, fp)
*fp = f_offset;
}
int
regtype(tp)
struct type *tp;
int regtype(struct type *tp)
{
switch (tp->tp_fund)
{
switch(tp->tp_fund) {
case INT:
case LONG:
return reg_any;
@ -609,18 +636,15 @@ regtype(tp)
return -1;
}
add_def(idf, sc, tp, lvl)
struct idf *idf;
struct type *tp;
int lvl;
int sc;
void add_def(struct idf *idf, int sc, struct type *tp, int lvl)
{
/* The identifier idf is declared on level lvl with storage
class sc and type tp, through a faked C declaration.
This is probably the wrong way to structure the problem,
but it will have to do for the time being.
*/
struct decspecs Ds; struct declarator Dc;
struct decspecs Ds;
struct declarator Dc;
Ds = null_decspecs;
Ds.ds_type = tp;
@ -630,25 +654,24 @@ add_def(idf, sc, tp, lvl)
declare_idf(&Ds, &Dc, lvl);
}
update_ahead(idf)
register struct idf *idf;
void update_ahead(register struct idf *idf)
{
/* The tk_symb of the token ahead is updated in the light of new
information about the identifier idf.
*/
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);

View file

@ -2,10 +2,15 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef IDF_H_
#define IDF_H_
/* $Id$ */
/* IDENTIFIER DESCRIPTOR */
#include "parameters.h"
#include "arith.h"
struct id_u {
int idd_reserved; /* non-zero for reserved words */
@ -33,4 +38,28 @@ struct id_u {
#include <idf_pkg.spec>
extern int level;
extern struct idf *gen_idf();
struct decspecs;
struct declarator;
struct type;
struct formal;
struct idf *gen_idf(void);
int is_anon_idf(struct idf *idf);
void declare_idf(struct decspecs *ds, struct declarator *dc, int lvl);
int actual_declaration(int sc, struct type *tp);
void global_redecl(register struct idf *idf, int new_sc, struct type *tp);
int good_formal(register struct def *def, register struct idf *idf);
void declare_params(struct declarator *dc);
void idf_initialized(register struct idf *idf);
void declare_parameter(struct idf *idf);
void declare_enum(struct type *tp, struct idf *idf, arith l);
void check_formals(struct idf *idf, struct declarator *dc);
void declare_formals(struct idf *idf, arith *fp);
int regtype(struct type *tp);
void add_def(struct idf *idf, int sc, struct type *tp, int lvl);
void update_ahead(register struct idf *idf);
void free_formals(register struct formal *fm);
#endif

View file

@ -10,6 +10,7 @@
#include <string.h>
#include "file_info.h"
#include "input.h"
#include "error.h"
#define INP_PUSHBACK 3
#define INP_TYPE struct file_info
@ -20,14 +21,14 @@ struct file_info finfo;
int NoUnstack;
AtEoIT()
int AtEoIT(void)
{
return 0;
}
extern char *source;
AtEoIF()
int AtEoIF(void)
{
if (NoUnstack) lexerror("unexpected EOF");
return 0;

View file

@ -12,4 +12,4 @@
#define UnGetChar() ((LexSave != EOI) ? ChPushBack(LexSave) : 0)
extern int LexSave; /* last character read by GetChar */
extern int GetChar(); /* character input, with trigraph parsing */

View file

@ -18,6 +18,7 @@
#include <ack_string.h>
#include <alloc.h>
#include <assert.h>
#include <string.h>
#include <flt_arith.h>
#include "idf.h"
#include "arith.h"
@ -31,25 +32,43 @@
#include "sizes.h"
#include "align.h"
#include "level.h"
#include "error.h"
#include "def.h"
#include "LLlex.h"
#include "estack.h"
#include "stack.h"
#include "ch3.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();
void gen_tpcheck(struct type **);
void gen_simple_exp(struct type **, struct expr **);
struct type **arr_elem(struct type **, struct e_stack *);
struct sdef *next_field(register struct sdef *,register struct e_stack *);
struct type **gen_tphead(struct type **, int);
struct type **gen_tpmiddle(void);
struct sdef *gen_align_to_next(register struct e_stack *);
void gen_tpend(void);
void check_and_pad(struct expr **, struct type **);
void pad(struct type *);
void check_ival(struct expr **, register struct type *);
void ch_array(struct type **, /* type tp = array of characters */
struct expr *);
void str_cst(register char *, register int, int);
#ifndef NOBITFIELD
void put_bf(struct type *, arith );
#endif /* NOBITFIELD */
int zero_bytes(register struct sdef *);
int valid_type(struct type *, char *);
void con_int(register struct expr *);
void illegal_init_cst(struct expr *);
void too_many_initialisers(void);
}
@ -127,9 +146,7 @@ initial_value_list(register struct type **tpp; struct expr **expp;)
;
{
void
gen_tpcheck(tpp)
struct type **tpp;
void gen_tpcheck(struct type **tpp)
{
register struct type *tp;
@ -153,10 +170,7 @@ gen_tpcheck(tpp)
}
}
void
gen_simple_exp(tpp, expp)
struct type **tpp;
struct expr **expp;
void gen_simple_exp(struct type **tpp, struct expr **expp)
{
register struct type *tp;
@ -184,10 +198,7 @@ gen_simple_exp(tpp, expp)
}
}
struct type **
arr_elem(tpp, p)
struct type **tpp;
struct e_stack *p;
struct type **arr_elem(struct type **tpp, struct e_stack *p)
{
register struct type *tp = *tpp;
@ -200,10 +211,8 @@ arr_elem(tpp, p)
return gen_tphead(&(tp->tp_up), 1);
}
struct sdef *
next_field(sd, p)
register struct sdef *sd;
register struct e_stack *p;
struct sdef *next_field(register struct sdef *sd,
register struct e_stack *p)
{
if (sd->sd_sdef)
p->bytes_upto_here += zero_bytes(sd);
@ -213,9 +222,7 @@ next_field(sd, p)
return sd->sd_sdef;
}
struct type **
gen_tphead(tpp, nest)
struct type **tpp;
struct type **gen_tphead(struct type **tpp, int nest)
{
register struct type *tp = *tpp;
register struct e_stack *p;
@ -290,8 +297,7 @@ gen_tphead(tpp, nest)
}
}
struct type **
gen_tpmiddle()
struct type **gen_tpmiddle(void)
{
register struct type *tp;
register struct sdef *sd;
@ -349,9 +355,7 @@ again:
}
}
struct sdef *
gen_align_to_next(p)
register struct e_stack *p;
struct sdef *gen_align_to_next(register struct e_stack *p)
{
register struct sdef *sd = p->s_def;
@ -368,7 +372,7 @@ gen_align_to_next(p)
return sd;
}
gen_tpend()
void gen_tpend(void)
{
register struct e_stack *p = p_stack;
register struct type *tp;
@ -424,9 +428,7 @@ gen_tpend()
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;
void check_and_pad(struct expr **expp, struct type **tpp)
{
register struct type *tp = *tpp;
@ -472,9 +474,7 @@ check_and_pad(expp, tpp)
/* 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;
void pad(struct type *tpx)
{
register struct type *tp = tpx;
register arith sz = tp->tp_size;
@ -504,9 +504,7 @@ pad(tpx)
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;
void check_ival(struct expr **expp, register struct type *tp)
{
/* The philosophy here is that ch3cast puts an explicit
conversion node in front of the expression if the types
@ -617,9 +615,8 @@ and also to prevent runtime coercions for compile-time constants.
a string constant.
Alignment is taken care of.
*/
ch_array(tpp, ex)
struct type **tpp; /* type tp = array of characters */
struct expr *ex;
void ch_array(struct type **tpp, /* type tp = array of characters */
struct expr *ex)
{
register struct type *tp = *tpp;
register int length = ex->SG_LEN, i;
@ -659,10 +656,7 @@ ch_array(tpp, ex)
/* 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;
void str_cst(register char *str, register int len, int inrom)
{
int chunksize = ((127 + (int) word_size) / (int) word_size) * (int) word_size;
@ -686,9 +680,7 @@ str_cst(str, len, inrom)
"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;
void put_bf(struct type *tp, arith val)
{
static long field = (arith)0;
static arith offset = (arith)-1;
@ -716,9 +708,7 @@ put_bf(tp, val)
}
#endif /* NOBITFIELD */
int
zero_bytes(sd)
register struct sdef *sd;
int zero_bytes(register struct sdef *sd)
{
/* fills the space between a selector of a struct
and the next selector of that struct with zero-bytes.
@ -732,10 +722,7 @@ zero_bytes(sd)
return count;
}
int
valid_type(tp, str)
struct type *tp;
char *str;
int valid_type(struct type *tp, char *str)
{
assert(tp!=(struct type *)0);
if (tp->tp_size < 0) {
@ -745,8 +732,7 @@ valid_type(tp, str)
return 1;
}
con_int(ex)
register struct expr *ex;
void con_int(register struct expr *ex)
{
register struct type *tp = ex->ex_type;
@ -759,14 +745,13 @@ con_int(ex)
C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);
}
illegal_init_cst(ex)
struct expr *ex;
void illegal_init_cst(struct expr *ex)
{
expr_error(ex, "illegal initialization constant");
gen_error = pack_level;
}
too_many_initialisers()
void too_many_initialisers(void)
{
error("too many initializers");
gen_error = pack_level;

View file

@ -14,11 +14,12 @@
#include "def.h"
#include "type.h"
#include "stack.h"
#include "error.h"
extern char options[];
enter_label(idf, defining)
register struct idf *idf;
void enter_label(register struct idf *idf, int defining)
{
/* The identifier idf is entered as a label. If it is new,
it is entered into the idf list with the largest possible
@ -45,8 +46,7 @@ enter_label(idf, defining)
def->df_initialized = 1;
}
unstack_label(idf)
register struct idf *idf;
void unstack_label(register struct idf *idf)
{
/* The scope in which the label idf occurred is left.
*/

View file

@ -4,6 +4,8 @@
*/
/* $Id$ */
/* L A B E L D E F I N I T I O N */
#ifndef LABEL_H_
#define LABEL_H_
#include <em_label.h> /* obtain definition of "label" */
@ -26,3 +28,10 @@ extern label datlab_count;
not be there, and if it is there, it may be from a
declaration or another application.
*/
struct idf;
void enter_label(register struct idf *idf, int defining);
void unstack_label(register struct idf *idf);
#endif /* LABEL_H_ */

View file

@ -23,7 +23,13 @@
#include "specials.h"
#include "sizes.h"
#include "align.h"
#include "stack.h"
#include "macro.h"
#include "options.h"
#include "error.h"
#include "code.h"
#include "cstoper.h"
#include "tokenname.h"
extern struct tokenname tkidf[];
extern char *symbol2str();
@ -34,7 +40,15 @@ struct sp_id special_ids[] = {
{0, 0}
};
void dependency();
void compile(int argc, char *argv[]);
static void init(void);
static void init_specials(register struct sp_id *si);
#ifdef DEBUG
void Info(void);
#endif
extern void C_program(void); /* program.c */
#ifndef NOCROSS
arith
@ -63,8 +77,7 @@ int
char *prog_name;
main(argc, argv)
char *argv[];
int main(int argc, char *argv[])
{
/* parse and interpret the command line options */
prog_name = argv[0];
@ -104,8 +117,7 @@ char *source = 0;
char *nmlist = 0;
#endif /* GEN_NM_LIST */
compile(argc, argv)
char *argv[];
void compile(int argc, char *argv[])
{
char *result;
#ifndef LINT
@ -190,7 +202,7 @@ compile(argc, argv)
}
}
init()
static void init(void)
{
init_cst(); /* initialize variables of "cstoper.c" */
reserve(tkidf); /* mark the C reserved words as such */
@ -255,8 +267,7 @@ init()
stack_level();
}
init_specials(si)
register struct sp_id *si;
static void init_specials(register struct sp_id *si)
{
while (si->si_identifier) {
struct idf *idf = str2idf(si->si_identifier, 0);
@ -269,7 +280,7 @@ init_specials(si)
}
#ifdef DEBUG
Info()
void Info(void)
{
extern int cnt_string_cst, cnt_formal,
cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
@ -301,14 +312,12 @@ Info()
}
#endif /* DEBUG */
void
No_Mem() /* called by alloc package */
void No_Mem(void) /* called by alloc package */
{
fatal("out of memory");
}
void
C_failed() /* called by EM_code module */
void C_failed(void) /* called by EM_code module */
{
fatal("write failed");
}

View file

@ -0,0 +1 @@
#include "parameters.h"

View file

@ -9,12 +9,14 @@
#include <stdlib.h>
#include <string.h>
#include <alloc.h>
#include "options.h"
#include "class.h"
#include "macro.h"
#include "idf.h"
#include "arith.h"
#include "sizes.h"
#include "align.h"
#include "error.h"
char options[128]; /* one for every char */
#ifdef LINT
@ -24,10 +26,11 @@ char loptions[128]; /* one for every char */
extern int idfsize;
extern int density;
static int txt2int();
do_option(text)
char *text;
static int txt2int(register char **);
void do_option(char *text)
{
register char opt;
@ -209,9 +212,7 @@ next_option: /* to allow combined one-char options */
}
}
static int
txt2int(tp)
register char **tp;
static int txt2int(register char **tp)
{
/* the integer pointed to by *tp is read, while increasing
*tp; the resulting value is yielded.

View file

@ -0,0 +1,13 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-07
*
*/
#ifndef OPTIONS_H_
#define OPTIONS_H_
void do_option(char *text);
#endif /* OPTIONS_H_ */

View file

@ -6,35 +6,41 @@
/* 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;
pkp++;
}
switch (pkp->pk_key) {
switch (pkp->pk_key)
{
case P_UNKNOWN:
default:
break;

View file

@ -0,0 +1,13 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-07
*
*/
#ifndef PRAGMA_H_
#define PRAGMA_H_
void do_pragma(void);
#endif /* PRAGMA_H_ */

View file

@ -56,12 +56,15 @@
#include "code.h"
#include "expr.h"
#include "def.h"
#include "idf.h"
#include "declarator.h"
#include "stack.h"
#include "proto.h"
#include "error.h"
#ifdef LINT
#include "l_lint.h"
#endif /* LINT */
extern error();
}
control_if_expression

View file

@ -23,20 +23,24 @@
#include "declar.h"
#include "decspecs.h"
#include "proto.h"
#include "error.h"
#include "ch3.h"
extern char options[];
void
check_for_void(pl)
register struct proto *pl;
void check_for_void(register struct proto *pl)
{
register int errcnt = 0;
if (!pl) return;
if ((pl->pl_flag & PL_VOID) && !(pl->next)) return;
if (!pl)
return;
if ((pl->pl_flag & PL_VOID) && !(pl->next))
return;
while (pl) {
if (pl->pl_flag & PL_VOID) {
while (pl)
{
if (pl->pl_flag & PL_VOID)
{
if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN))
error("illegal use of void in argument list");
pl->pl_flag |= PL_ERRGIVEN;
@ -46,11 +50,8 @@ check_for_void(pl)
}
}
add_proto(pl, ds, dc, lvl)
struct proto *pl;
struct decspecs *ds;
struct declarator *dc;
int lvl;
void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc,
int lvl)
{
/* The full typed identifier or abstract type, described
by the structures decspecs and declarator are turned
@ -69,14 +70,15 @@ add_proto(pl, ds, dc, lvl)
pl->pl_flag = PL_FORMAL;
type = declare_type(ds->ds_type, dc);
if (type->tp_size < (arith)0 && actual_declaration(sc, type)) {
if (type->tp_size < (arith) 0 && actual_declaration(sc, type))
{
extern char *symbol2str();
if (type->tp_fund != VOID)
error("unknown %s-type", symbol2str(type->tp_fund));
else {
if (idf != (struct idf *)0
|| ds->ds_sc_given
|| ds->ds_typequal) {
else
{
if (idf != (struct idf *) 0 || ds->ds_sc_given || ds->ds_typequal)
{
error("illegal use of void in argument list");
pl->pl_flag |= PL_ERRGIVEN;
}
@ -84,11 +86,16 @@ add_proto(pl, ds, dc, lvl)
pl->pl_flag |= PL_VOID;
}
}
if (ds->ds_sc_given && ds->ds_sc != REGISTER) {
if (!(pl->pl_flag & PL_ERRGIVEN)) {
if (ds->ds_sc != AUTO) {
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 {
}
else
{
warning("illegal storage class in parameter declaration");
}
}
@ -96,9 +103,12 @@ add_proto(pl, ds, dc, lvl)
/* 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;
}
@ -110,13 +120,16 @@ add_proto(pl, ds, dc, lvl)
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;
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 */ )) {
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();
@ -163,31 +176,29 @@ add_proto(pl, ds, dc, lvl)
pl->pl_type = type;
}
struct tag *
gettag(tp, idpp)
struct type *tp;
struct idf **idpp;
static struct tag * gettag(struct type *tp, struct idf **idpp)
{
struct tag *tg = (struct tag *) 0;
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;
}
*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.
@ -203,28 +214,36 @@ declare_protos(dc)
dumpidftab("start declare_protos", 0);
#endif /* DEBUG */
du = dc->dc_decl_unary;
while (du) {
if (du->du_fund == FUNCTION) {
if (du->next != (struct decl_unary *) 0) {
while (du)
{
if (du->du_fund == FUNCTION)
{
if (du->next != (struct decl_unary *) 0)
{
remove_proto_idfs(du->du_proto);
du->du_proto = 0;
} else break;
}
else
break;
}
du = du->next;
}
pl = du ? du->du_proto : NO_PROTO;
if (pl) {
if (pl)
{
#if 0 /* the id_proto member is deleted (???) */
idf->id_proto = 0;
#endif /* 0 */
do {
do
{
struct tag *tg;
struct idf *idp = 0;
type = pl->pl_type;
/* `...' only for type checking */
if (pl->pl_flag & PL_ELLIPSIS) {
if (pl->pl_flag & PL_ELLIPSIS)
{
pl = pl->next;
continue;
}
@ -233,7 +252,8 @@ declare_protos(dc)
if (type->tp_fund == VOID)
break;
if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) {
if (!pl->pl_idf || !(def = pl->pl_idf->id_def))
{
error("no parameter identifier supplied");
pl = pl->next;
continue;
@ -249,7 +269,8 @@ declare_protos(dc)
pl = pl->next;
tg = gettag(type, &idp);
if (tg && tg->tg_level <= L_PROTO) {
if (tg && tg->tg_level <= L_PROTO)
{
tg->tg_level = L_FORMAL2;
stack_idf(idp, stl);
}
@ -261,10 +282,7 @@ declare_protos(dc)
#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:
@ -279,21 +297,28 @@ update_proto(tp, otp)
*/
register struct proto *pl, *opl;
if (tp == otp) return;
if (!tp || !otp) return;
if (tp == otp)
return;
if (!tp || !otp)
return;
while (tp->tp_fund != FUNCTION) {
if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY) return;
while (tp->tp_fund != FUNCTION)
{
if (tp->tp_fund != POINTER && tp->tp_fund != ARRAY)
return;
tp = tp->tp_up;
otp = otp->tp_up;
if (!tp) return;
if (!tp)
return;
}
pl = tp->tp_proto;
opl = otp->tp_proto;
if (pl && opl) {
if (pl && opl)
{
/* both have prototypes */
while (pl && opl) {
while (pl && opl)
{
update_proto(pl->pl_type, opl->pl_type);
pl = pl->next;
opl = opl->next;
@ -302,9 +327,13 @@ update_proto(tp, otp)
* a typedef.
*/
otp->tp_proto = tp->tp_proto;
} else if (opl) {
}
else if (opl)
{
/* old decl has type */
} else if (pl) {
}
else if (pl)
{
otp->tp_proto = pl;
}
@ -314,35 +343,40 @@ update_proto(tp, otp)
/* struct/union and enum tags can be declared inside prototypes
* remove them from the symbol-table
*/
void
remove_proto_tag(tp)
struct type *tp;
static void remove_proto_tag(struct type *tp)
{
register struct idf *ident;
register struct tag *tgp, **tgpp;
register int fund = tp->tp_fund;
while (fund == FIELD || fund == POINTER
|| fund == ARRAY || fund == FUNCTION) {
while (fund == FIELD || fund == POINTER || fund == ARRAY || fund == FUNCTION)
{
tp = tp->tp_up;
fund = tp->tp_fund;
}
ident = tp->tp_idf;
switch (tp->tp_fund) {
switch (tp->tp_fund)
{
case ENUM:
case STRUCT:
case UNION: tgpp = &(ident->id_tag); break;
default: return;
case UNION:
tgpp = &(ident->id_tag);
break;
default:
return;
}
while((*tgpp) && (*tgpp)->tg_type != tp) {
while ((*tgpp) && (*tgpp)->tg_type != tp)
{
tgpp = &((*tgpp)->next);
}
if (!*tgpp) return;
if (!*tgpp)
return;
tgp = *tgpp;
if (tgp->tg_level > L_PROTO) return;
if (tgp->tg_level > L_PROTO)
return;
#ifdef DEBUG
if (options['t'])
@ -354,38 +388,39 @@ struct type *tp;
free_tag(tgp);
}
remove_proto_idfs(pl)
register struct proto *pl;
{
/* Remove all the identifier definitions from the
prototype list.
*/
prototype list. */
void remove_proto_idfs(register struct proto *pl)
{
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",
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
@ -397,9 +432,11 @@ call_proto(expp)
register struct expr *left = (*expp)->OP_LEFT;
register struct expr *right = (*expp)->OP_RIGHT;
register struct proto *pl = NO_PROTO;
static struct proto ellipsis = { 0, 0, 0, PL_ELLIPSIS };
static struct proto ellipsis =
{ 0, 0, 0, PL_ELLIPSIS };
if (left != NILEXPR) { /* in case of an error */
if (left != NILEXPR)
{ /* in case of an error */
register struct type *tp = left->ex_type;
while (tp && tp->tp_fund != FUNCTION && tp != error_type)
@ -408,17 +445,20 @@ call_proto(expp)
pl = tp->tp_proto;
}
if (right != NILEXPR) { /* function call with parameters */
if (right != NILEXPR)
{ /* function call with parameters */
register struct expr **ep = &((*expp)->OP_RIGHT);
register int ecnt = 0, pcnt = 0;
struct expr **estack[NPARAMS];
struct proto *pstack[NPARAMS];
/* stack up the parameter expressions */
while (right->ex_class == Oper && right->OP_OPER == PARCOMMA) {
while (right->ex_class == Oper && right->OP_OPER == PARCOMMA)
{
if (ecnt == STDC_NPARAMS)
expr_strict(right, "number of parameters exceeds ANSI limit");
if (ecnt >= NPARAMS-1) {
if (ecnt >= NPARAMS - 1)
{
expr_error(right, "too many parameters");
return;
}
@ -431,43 +471,54 @@ call_proto(expp)
/* Declarations like int f(void) do not expect any
parameters.
*/
if (pl && pl->pl_flag & PL_VOID) {
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");
if (pcnt < 0)
{
expr_error(*expp,
"more parameters than specified in prototype");
break;
}
else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) {
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");
}

View file

@ -2,6 +2,9 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef PROTO_H
#define PROTO_H
/* $Id$ */
/* PARAMETER TYPE LIST DEFINITION */
@ -20,3 +23,20 @@ struct proto {
#define PL_ERRGIVEN 0x08
/* ALLOCDEF "proto" 20 */
/* Forward structure declarations */
struct expr;
struct type;
struct declarator;
struct decspecs;
void remove_proto_idfs(register struct proto *pl);
void call_proto(register struct expr **expp);
void update_proto(register struct type *tp, register struct type *otp);
void declare_protos(register struct declarator *dc);
void add_proto(struct proto *pl, struct decspecs *ds, struct declarator *dc,
int lvl);
void check_for_void(register struct proto *pl);
#endif

View file

@ -10,9 +10,10 @@
#include "LLlex.h"
#include "class.h"
#include "input.h"
#include "skip.h"
SkipToNewLine()
int SkipToNewLine(void)
{
register int ch;
register int garbage = 0;

View file

@ -0,0 +1,13 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-07
*
*/
#ifndef SKIP_H_
#define SKIP_H_
int SkipToNewLine(void);
#endif /* SKIP_H_ */

View file

@ -20,6 +20,7 @@
#include <flt_arith.h>
#include <stb.h>
#include "stab.h"
#include "idf.h"
#include "LLlex.h"
#include "stack.h"
@ -29,34 +30,34 @@
#include "field.h"
#include "Lpars.h"
#include "level.h"
#include "print.h"
extern long full_mask[];
extern char *sprint();
#define INCR_SIZE 64
static struct db_str {
static struct db_str
{
unsigned sz;
char *base;
char *currpos;
} db_str;
static
create_db_str()
static void create_db_str(void)
{
if (!db_str.base)
{
if (! db_str.base) {
db_str.base = Malloc(INCR_SIZE);
db_str.sz = INCR_SIZE;
}
db_str.currpos = db_str.base;
}
static
addc_db_str(c)
int c;
static void addc_db_str(int c)
{
int df = db_str.currpos - db_str.base;
if (df >= db_str.sz-1) {
if (df >= db_str.sz - 1)
{
db_str.sz += INCR_SIZE;
db_str.base = Realloc(db_str.base, db_str.sz);
db_str.currpos = db_str.base + df;
@ -65,34 +66,35 @@ addc_db_str(c)
*db_str.currpos = '\0';
}
static
adds_db_str(s)
char *s;
static void adds_db_str(char *s)
{
while (*s) addc_db_str(*s++);
while (*s)
addc_db_str(*s++);
}
static void
stb_type(tp)
register struct type *tp;
static void stb_type(register struct type *tp)
{
char buf[128];
static int stb_count;
long l;
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));
@ -102,28 +104,21 @@ stb_type(tp)
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));
if (tp->tp_unsigned)
{
adds_db_str(sprint(buf, "r%d;0;%ld", tp->tp_dbindex, l));
}
else {
else
{
l &= ~(1L << ((int) tp->tp_size * 8 - 1));
adds_db_str(sprint(buf,
"r%d;%ld;%ld",
tp->tp_dbindex,
-l-1,
l));
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 ... */
@ -132,18 +127,20 @@ stb_type(tp)
stb_type(tp->tp_up);
break;
case ARRAY:
if (tp->tp_size > 0) {
if (tp->tp_size > 0)
{
adds_db_str("ar");
stb_type(int_type);
adds_db_str(sprint(buf, ";0;%ld;", tp->tp_size / tp->tp_up->tp_size - 1));
adds_db_str(
sprint(buf, ";0;%ld;",
tp->tp_size / tp->tp_up->tp_size - 1));
stb_type(tp->tp_up);
}
break;
case ENUM:
if (tp->tp_size < 0) {
adds_db_str(sprint(buf,
"xe%s:",
tp->tp_idf->id_text));
if (tp->tp_size < 0)
{
adds_db_str(sprint(buf, "xe%s:", tp->tp_idf->id_text));
tp->tp_dbindex = -tp->tp_dbindex;
break;
}
@ -151,14 +148,15 @@ stb_type(tp)
{
register struct stack_entry *se = local_level->sl_entry;
while (se) {
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,
while (edef)
{
if (edef->df_type == tp && edef->df_sc == ENUM)
{
adds_db_str(
sprint(buf, "%s:%ld,", se->se_idf->id_text,
edef->df_address));
}
edef = edef->next;
@ -170,36 +168,38 @@ stb_type(tp)
break;
case STRUCT:
case UNION:
if (tp->tp_size < 0) {
adds_db_str(sprint(buf,
"x%c%s:",
tp->tp_fund == STRUCT ? 's' : 'u',
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',
adds_db_str(
sprint(buf, "%c%ld", tp->tp_fund == STRUCT ? 's' : 'u',
tp->tp_size));
{
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,
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,
adds_db_str(
sprint(buf, ",%ld,%ld;", sdef->sd_offset * 8,
sdef->sd_type->tp_size * 8));
}
sdef = sdef->sd_sdef;
@ -213,9 +213,7 @@ stb_type(tp)
}
}
stb_tag(tg, str)
register struct tag *tg;
char *str;
void stb_tag(register struct tag *tg, char *str)
{
create_db_str();
adds_db_str(str);
@ -224,15 +222,11 @@ stb_tag(tg, str)
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);
tg->tg_type == void_type || tg->tg_type->tp_size >= 32767 ?
0 : (int) tg->tg_type->tp_size, (arith) 0);
}
stb_typedef(tp, str)
register struct type *tp;
char *str;
void stb_typedef(register struct type *tp, char *str)
{
create_db_str();
adds_db_str(str);
@ -240,23 +234,19 @@ stb_typedef(tp, str)
stb_type(tp);
addc_db_str(';');
C_ms_stb_cst(db_str.base,
N_LSYM,
tp == void_type || tp->tp_size >= 32767
? 0
: (int)tp->tp_size,
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;
create_db_str();
adds_db_str(str);
addc_db_str(':');
switch(kind) {
switch (kind)
{
case FUNCTION:
addc_db_str(df->df_sc == STATIC ? 'f' : 'F');
stb_type(tp->tp_up);
@ -264,38 +254,48 @@ stb_string(df, kind, str)
C_ms_stb_pnam(db_str.base, N_FUN, 1 /* proclevel */, str);
break;
default:
if (df->df_sc == FORMAL ||
(df->df_sc == REGISTER && df->df_address >= 0)) {
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) {
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 */
else
{ /* local variable */
stb_type(tp); /* assign type num to avoid
difficult to parse string */
addc_db_str(';');

View file

@ -0,0 +1,20 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-02-07
*
*/
#ifndef STAB_H_
#define STAB_H_
struct def;
struct type;
struct tag;
void stb_tag(register struct tag *tg, char *str);
void stb_typedef(register struct type *tp, char *str);
void stb_string(register struct def *df, int kind, char* str);
#endif /* STAB_H_ */

View file

@ -22,6 +22,9 @@
#include "struct.h"
#include "level.h"
#include "mes.h"
#include "code.h"
#include "util.h"
#include "error.h"
/* #include <em_reg.h> */
@ -41,7 +44,7 @@ struct stack_level *local_level = &UniversalLevel;
int level; /* Always equal to local_level->sl_level. */
stack_level() {
void stack_level(void) {
/* A new level is added on top of the identifier stack.
*/
register struct stack_level *stl = new_stack_level();
@ -57,10 +60,9 @@ stack_level() {
#endif /* LINT */
}
void
stack_idf(idf, stl)
struct idf *idf;
register struct stack_level *stl;
void stack_idf(
struct idf *idf,
register struct stack_level *stl)
{
/* The identifier idf is inserted in the stack on level stl,
but only if it is not already present at this level.
@ -81,8 +83,7 @@ stack_idf(idf, stl)
stl->sl_entry = se;
}
struct stack_level *
stack_level_of(lvl)
struct stack_level *stack_level_of(int lvl)
{
/* The stack_level corresponding to level lvl is returned.
The stack should probably be an array, to be extended with
@ -100,7 +101,7 @@ stack_level_of(lvl)
return stl;
}
unstack_level()
void unstack_level(void)
{
/* The top level of the identifier stack is removed.
*/
@ -174,7 +175,7 @@ unstack_level()
#endif /* DEBUG */
}
unstack_world()
void unstack_world(void)
{
/* The global level of identifiers is scanned, and final
decisions are taken about such issues as
@ -263,14 +264,13 @@ unstack_world()
extern char *nmlist; /* BAH! -- main.c */
static File *nfp = 0;
open_name_list()
void open_name_list(void)
{
if (nmlist && sys_open(nmlist, OP_WRITE, &nfp) == 0)
fatal("cannot create namelist %s", nmlist);
}
namelist(nm)
char *nm;
void namelist(char *nm)
{
if (nmlist) {
sys_write(nfp, nm, strlen(nm));

View file

@ -2,9 +2,14 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef STACK_H_
#define STACK_H_
/* $Id$ */
/* IDENTIFIER STACK DEFINITIONS */
struct idf;
/* The identifier stack is implemented as a stack of sets.
The stack is implemented by a doubly linked list,
the sets by singly linked lists.
@ -30,5 +35,26 @@ struct stack_entry {
/* ALLOCDEF "stack_entry" 50 */
extern struct stack_level *local_level;
extern struct stack_level *stack_level_of();
extern int level;
/* A new level is added on top of the identifier stack. */
void stack_level(void);
/* The identifier idf is inserted in the stack on level stl,
but only if it is not already present at this level.
*/
void stack_idf(struct idf *idf, register struct stack_level *stl);
/*The stack_level corresponding to level lvl is returned.
The stack should probably be an array, to be extended with
realloc where needed.
*/
struct stack_level *stack_level_of(int lvl);
/* The top level of the identifier stack is removed. */
void unstack_level(void);
void unstack_world(void);
#ifdef GEN_NM_LIST
void open_name_list(void);
void namelist(char *nm);
#endif /* GEN_NM_LIST */
#endif

View file

@ -24,6 +24,7 @@
#include "code.h"
#include "stack.h"
#include "def.h"
#include "switch.h"
#ifdef DBSYMTAB
#include <stb.h>
#endif /* DBSYMTAB */

View file

@ -3,10 +3,10 @@
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Id$ */
/* library routine for copying structs */
__stb(n, f, t)
register char *f, *t; register n;
/* library routine for copying structs */
void __stb(register int n, register char *f, register char *t)
{
if (n > 0)
do

View file

@ -2,6 +2,9 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef STMT_H_
#define STMT_H_
/* $Id$ */
/* S T A T E M E N T - B L O C K D E F I N I T I O N S */
@ -12,3 +15,5 @@ struct stmt_block {
};
/* ALLOCDEF "stmt_block" 5 */
#endif

View file

@ -19,16 +19,23 @@
#include "Lpars.h"
#include "align.h"
#include "level.h"
#include "ch3.h"
#include "sizes.h"
#include "error.h"
/* Type of previous selector declared with a field width specified,
if any. If a selector is declared with no field with it is set to 0.
*/
static field_busy = 0;
static int field_busy = 0;
extern char options[];
char *symbol2str();
int lcm();
static void check_selector(register struct idf *, struct type *);
/* Greatest Common Divisor */
static int gcd(register int , register int );
/* Least Common Multiple */
static int lcm(register int, register int);
/* The semantics of the identification of structure/union tags is
obscure. Some highly regarded compilers are found out to accept,
@ -51,13 +58,13 @@ int lcm();
as well).
*/
add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */
register struct type *stp; /* type of the structure */
struct type *tp; /* type of the selector */
register struct idf *idf; /* idf of the selector */
struct sdef ***sdefpp; /* address of hook to selector definition */
arith *szp; /* pointer to struct size upto here */
struct field *fd;
void add_sel( /* this is horrible */
register struct type *stp, /* type of the structure */
struct type *tp, /* type of the selector */
register struct idf *idf, /* idf of the selector */
struct sdef ***sdefpp, /* address of hook to selector definition */
arith *szp, /* pointer to struct size upto here */
struct field *fd)
{
/* The selector idf with type tp is added to two chains: the
selector identification chain starting at idf->id_sdef,
@ -147,12 +154,11 @@ add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */
}
}
check_selector(idf, stp)
register struct idf *idf;
struct type *stp; /* the type of the struct */
static void check_selector(register struct idf *idf, struct type *stp)
{
/* checks if idf occurs already as a selector in
struct or union *stp.
struct or union *stp. "stp" indicates the type
of the struct.
*/
register struct sdef *sdef = stp->tp_sdef;
@ -163,9 +169,7 @@ check_selector(idf, stp)
}
}
declare_struct(fund, idf, tpp)
register struct idf *idf;
struct type **tpp;
void declare_struct(int fund, register struct idf *idf, struct type **tpp)
{
/* A struct, union or enum (depending on fund) with tag (!)
idf is declared, and its type (incomplete as it may be) is
@ -232,9 +236,9 @@ declare_struct(fund, idf, tpp)
}
}
apply_struct(fund, idf, tpp)
register struct idf *idf;
struct type **tpp;
void apply_struct(int fund,
register struct idf *idf,
struct type **tpp)
{
/* The occurrence of a struct, union or enum (depending on
fund) with tag idf is noted. It may or may not have been
@ -258,10 +262,9 @@ apply_struct(fund, idf, tpp)
declare_struct(fund, idf, tpp);
}
struct sdef *
idf2sdef(idf, tp)
register struct idf *idf;
struct type *tp;
struct sdef *idf2sdef(
register struct idf *idf,
struct type *tp)
{
/* The identifier idf is identified as a selector
in the struct tp.
@ -296,9 +299,7 @@ idf2sdef(idf, tp)
}
#if 0
int
uniq_selector(idf_sdef)
register struct sdef *idf_sdef;
int uniq_selector(register struct sdef *idf_sdef)
{
/* Returns true if idf_sdef (which is guaranteed to exist)
is unique for this level, i.e there is no other selector
@ -324,12 +325,12 @@ uniq_selector(idf_sdef)
#ifndef NOBITFIELD
arith
add_field(szp, fd, fdtpp, idf, stp)
arith *szp; /* size of struct upto here */
register struct field *fd; /* bitfield, containing width */
register struct type **fdtpp; /* type of selector */
struct idf *idf; /* name of selector */
register struct type *stp; /* current struct descriptor */
add_field(
arith *szp, /* size of struct upto here */
register struct field *fd, /* bitfield, containing width */
register struct type **fdtpp, /* type of selector */
struct idf *idf, /* name of selector */
register struct type *stp) /* current struct descriptor */
{
/* The address where this selector is put is returned. If the
selector with specified width does not fit in the word, or
@ -438,18 +439,12 @@ add_field(szp, fd, fdtpp, idf, stp)
#endif /* NOBITFIELD */
/* some utilities */
int
is_struct_or_union(fund)
register int fund;
int is_struct_or_union(register int fund)
{
return fund == STRUCT || fund == UNION;
}
/* Greatest Common Divisor
*/
int
gcd(m, n)
register int m, n;
static int gcd(register int m, register int n)
{
register int r;
@ -461,11 +456,8 @@ gcd(m, n)
return m;
}
/* Least Common Multiple
*/
int
lcm(m, n)
register int m, n;
static int lcm(register int m, register int n)
{
return m * (n / gcd(m, n));
}

View file

@ -2,7 +2,17 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef STRUCT_H_
#define STRUCT_H_
/* $Id$ */
#include "arith.h"
struct type;
struct idf;
struct field;
/* SELECTOR DESCRIPTOR */
struct sdef { /* for selectors */
@ -27,4 +37,26 @@ struct tag { /* for struct-, union- and enum tags */
/* ALLOCDEF "tag" 10 */
struct sdef *idf2sdef();
struct sdef *idf2sdef(register struct idf *idf, struct type *tp);
void add_sel(
register struct type *stp, /* type of the structure */
struct type *tp, /* type of the selector */
register struct idf *idf, /* idf of the selector */
struct sdef ***sdefpp, /* address of hook to selector definition */
arith *szp, /* pointer to struct size upto here */
struct field *fd);
void declare_struct(int fund, register struct idf *idf, struct type **tpp);
void apply_struct(int fund, register struct idf *idf, struct type **tpp);
int is_struct_or_union(register int fund);
#ifndef NOBITFIELD
arith
add_field(
arith *szp, /* size of struct upto here */
register struct field *fd, /* bitfield, containing width */
register struct type **fdtpp, /* type of selector */
struct idf *idf, /* name of selector */
register struct type *stp); /* current struct descriptor */
#endif
#endif

View file

@ -23,13 +23,16 @@
#include "expr.h"
#include "type.h"
#include "sizes.h"
#include "switch.h"
#include "eval.h"
#include "ch3.h"
#include "error.h"
extern char options[];
int density = DENSITY;
compact(nr, low, up)
arith low, up;
static int compact(int nr, arith low, arith up)
{
/* Careful! up - low might not fit in an arith. And then,
the test "up-low < 0" might also not work to detect this
@ -49,8 +52,7 @@ static struct switch_hdr *switch_stack = 0;
For simplicity, we suppose int_size == word_size.
*/
code_startswitch(expp)
struct expr **expp;
void code_startswitch(struct expr **expp)
{
/* Check the expression, stack a new case header and
fill in the necessary fields.
@ -85,7 +87,7 @@ code_startswitch(expp)
C_bra(l_table); /* goto start of switch_table */
}
code_endswitch()
void code_endswitch(void)
{
register struct switch_hdr *sh = switch_stack;
register label tablabel;
@ -158,9 +160,7 @@ code_endswitch()
unstack_stmt();
}
void
code_case(expr)
struct expr *expr;
void code_case(struct expr *expr)
{
register arith val;
register struct case_entry *ce;
@ -227,8 +227,7 @@ code_case(expr)
}
}
void
code_default()
void code_default(void)
{
register struct switch_hdr *sh = switch_stack;

View file

@ -2,7 +2,16 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
#ifndef SWITCH_H_
#define SWITCH_H_
/* $Id$ */
#include "arith.h"
struct type;
struct expr;
/* S W I T C H - T A B L E - S T R U C T U R E */
struct switch_hdr {
@ -27,3 +36,12 @@ struct case_entry {
};
/* ALLOCDEF "case_entry" 20 */
void code_startswitch(struct expr **expp);
void code_endswitch(void);
void code_case(struct expr *expr);
void code_default(void);
#endif

View file

@ -0,0 +1,3 @@
/{[A-Z]/!d
s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\
return \2;/

View file

@ -0,0 +1,16 @@
default:
if (tok <= 0) return "end of file";
if (tok < 040 || tok >= 0177) {
return "bad token";
}
/* fall through */
case '\n':
case '\f':
case '\v':
case '\r':
case '\t':
index = (index+2) & (SIZBUF-1);
buf[index] = tok;
return &buf[index];
}
}

View file

@ -0,0 +1,12 @@
/* Generated by make.tokcase */
/* $Id$ */
#include "Lpars.h"
char *symbol2str(int tok)
{
#define SIZBUF 8
/* allow for a few invocations in f.i. an argument list */
static char buf[SIZBUF];
static int index;
switch (tok) {

View file

@ -11,6 +11,7 @@
#include "LLlex.h"
#include "tokenname.h"
#include "Lpars.h"
#include "error.h"
/* To centralize the declaration of %tokens, their presence in this
file is taken as their declaration. The Makefile will produce
@ -132,8 +133,7 @@ struct tokenname tkfunny[] = { /* internal keywords */
};
#endif /* ____ */
reserve(resv)
register struct tokenname resv[];
void reserve(register struct tokenname resv[])
{
/* The names of the tokens described in resv are entered
as reserved words.

View file

@ -4,6 +4,8 @@
*/
/* $Id$ */
/* TOKENNAME DEFINITION */
#ifndef TOKENNAME_H_
#define TOKENNAME_H_
struct tokenname { /* Used for defining the name of a
token as identified by its symbol
@ -11,3 +13,7 @@ struct tokenname { /* Used for defining the name of a
int tn_symbol;
char *tn_name;
};
void reserve(register struct tokenname resv[]);
#endif /* TOKENNAME_H_ */

View file

@ -16,30 +16,21 @@
#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 *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;
struct type *create_type(int fund)
{
/* A brand new struct type is created, and its tp_fund set
to fund.
@ -52,32 +43,32 @@ create_type(fund)
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.
*/
register struct type *dtp;
switch (fund) {
switch (fund)
{
#ifndef NOBITFIELD
case FIELD:
dtp = field_of(tp, qual);
@ -85,11 +76,13 @@ construct_type(fund, tp, qual, count, pl)
#endif /* NOBITFIELD */
case FUNCTION:
if (tp->tp_fund == FUNCTION) {
if (tp->tp_fund == FUNCTION)
{
error("function cannot yield function");
return error_type;
}
if (tp->tp_fund == ARRAY) {
if (tp->tp_fund == ARRAY)
{
error("function cannot yield array");
return error_type;
}
@ -100,7 +93,8 @@ construct_type(fund, tp, qual, count, pl)
dtp = pointer_to(tp, qual);
break;
case ARRAY:
if (tp->tp_fund == VOID) {
if (tp->tp_fund == VOID)
{
error("cannot construct array of void");
count = (arith) -1;
}
@ -113,11 +107,7 @@ construct_type(fund, tp, qual, count, pl)
return dtp;
}
struct type *
function_of(tp, pl, qual)
register struct type *tp;
struct proto *pl;
int qual;
struct type *function_of(register struct type *tp, struct proto *pl, int qual)
{
#if 0
/* See comment below */
@ -143,7 +133,8 @@ function_of(tp, pl, qual)
dtp = 0;
#endif
if (!dtp) {
if (!dtp)
{
dtp = create_type(FUNCTION);
dtp->tp_up = tp;
dtp->tp_size = -1; /* function size is not known */
@ -159,10 +150,7 @@ function_of(tp, pl, qual)
return dtp;
}
struct type *
pointer_to(tp, qual)
register struct type *tp;
int qual;
struct type *pointer_to(register struct type *tp, int qual)
{
register struct type *dtp = tp->tp_pointer;
@ -170,7 +158,8 @@ pointer_to(tp, qual)
while (dtp && dtp->tp_typequal != qual)
dtp = dtp->next;
if (!dtp) {
if (!dtp)
{
dtp = create_type(POINTER);
dtp->tp_unsigned = 1;
dtp->tp_up = tp;
@ -183,11 +172,7 @@ pointer_to(tp, qual)
return dtp;
}
struct type *
array_of(tp, count, qual)
register struct type *tp;
arith count;
int qual;
struct type * array_of(register struct type *tp, arith count, int qual)
{
register struct type *dtp = tp->tp_array;
@ -195,7 +180,8 @@ array_of(tp, count, qual)
while (dtp && (dtp->tp_nel != count || dtp->tp_typequal != qual))
dtp = dtp->next;
if (!dtp) {
if (!dtp)
{
dtp = create_type(ARRAY);
dtp->tp_up = tp;
dtp->tp_nel = count;
@ -203,19 +189,18 @@ array_of(tp, count, qual)
dtp->tp_typequal = qual;
dtp->next = tp->tp_array;
tp->tp_array = dtp;
if (tp->tp_size >= 0 && count >= 0) {
if (tp->tp_size >= 0 && count >= 0)
{
dtp->tp_size = count * tp->tp_size;
}
else dtp->tp_size = -1;
else
dtp->tp_size = -1;
}
return dtp;
}
#ifndef NOBITFIELD
struct type *
field_of(tp, qual)
register struct type *tp;
int qual;
struct type * field_of(register struct type *tp, int qual)
{
register struct type *dtp = create_type(FIELD);
@ -227,23 +212,19 @@ field_of(tp, qual)
}
#endif /* NOBITFIELD */
arith
size_of_type(tp, nm)
struct type *tp;
char nm[];
arith size_of_type(struct type *tp, char nm[])
{
arith sz = tp->tp_size;
if (sz < 0) {
if (sz < 0)
{
error("size of %s unknown", nm);
sz = (arith) 1;
}
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
@ -252,28 +233,26 @@ idf2type(idf, tpp)
*/
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!!! */
}
else {
else
{
*tpp = tp;
}
}
arith
align(pos, al)
arith pos;
int al;
arith align(arith pos, int al)
{
return ((pos + al - 1) / al) * al;
}
struct type *
standard_type(fund, sgn, algn, sz)
int algn; arith sz;
struct type * standard_type(int fund, int sgn, int algn, arith sz)
{
register struct type *tp = create_type(fund);
@ -284,25 +263,29 @@ standard_type(fund, sgn, algn, sz)
return tp;
}
completed(tp)
struct type *tp;
void completed(struct type *tp)
{
register struct type *atp = tp->tp_array;
register struct type *etp = tp;
switch(etp->tp_fund) {
switch (etp->tp_fund)
{
case STRUCT:
case UNION:
case ENUM:
while (etp = etp->next) {
if (! etp->tp_sdef) etp->tp_sdef = tp->tp_sdef;
while (etp = etp->next)
{
if (!etp->tp_sdef)
etp->tp_sdef = tp->tp_sdef;
etp->tp_size = tp->tp_size;
etp->tp_align = tp->tp_align;
}
break;
}
while (atp) {
if (atp->tp_nel >= 0) {
while (atp)
{
if (atp->tp_nel >= 0)
{
atp->tp_size = atp->tp_nel * tp->tp_size;
}
atp = atp->next;

View file

@ -4,8 +4,13 @@
*/
/* $Id$ */
/* TYPE DESCRIPTOR */
#ifndef TYPE_H_
#define TYPE_H_
#include "parameters.h"
#include "arith.h"
struct type {
struct type *next; /* used for ARRAY and for qualifiers */
@ -59,13 +64,6 @@ struct type {
#define TQ_VOLATILE 0x01
#define TQ_CONST 0x02
extern struct type
*create_type(), *standard_type(), *construct_type(), *pointer_to(),
*array_of(), *function_of(), *promoted_type();
#ifndef NOBITFIELD
extern struct type *field_of();
#endif /* NOBITFIELD */
extern struct type
*schar_type, *uchar_type,
@ -79,6 +77,24 @@ extern struct type
extern struct type *pa_type; /* type.c */
extern arith size_of_type(), align();
struct type *create_type(int fund);
struct type *promoted_type(struct type *tp);
struct type *construct_type(int fund, register struct type *tp, int qual,
arith count, /* for fund == ARRAY only */
register struct proto *pl);
struct type *function_of(register struct type *tp, struct proto *pl, int qual);
struct type *pointer_to(register struct type *tp, int qual);
struct type * array_of(register struct type *tp, arith count, int qual);
#ifndef NOBITFIELD
struct type * field_of(register struct type *tp, int qual);
#endif /* NOBITFIELD */
arith size_of_type(struct type *tp, char nm[]);
void idf2type(struct idf *idf, struct type **tpp);
arith align(arith pos, int al);
struct type * standard_type(int fund, int sgn, int algn, arith sz);
void completed(struct type *tp);
/* ALLOCDEF "type" 50 */
#endif

View file

@ -41,16 +41,14 @@ static int loc_id;
extern char options[];
LocalInit()
void LocalInit(void)
{
#ifdef USE_TMP
C_insertpart(loc_id = C_getid());
#endif /* USE_TMP */
}
arith
LocalSpace(sz, al)
arith sz;
arith LocalSpace(arith sz, int al)
{
register struct stack_level *stl = local_level;
@ -61,9 +59,7 @@ LocalSpace(sz, al)
#define TABSIZ 32
static struct localvar *regs[TABSIZ];
arith
NewLocal(sz, al, regtype, sc)
arith sz;
arith NewLocal(arith sz, int al, int regtype, int sc)
{
register struct localvar *tmp = FreeTmps;
struct localvar *prev = 0;
@ -98,8 +94,7 @@ NewLocal(sz, al, regtype, sc)
return tmp->t_offset;
}
FreeLocal(off)
arith off;
void FreeLocal(arith off)
{
int index = (int) (off >> 2) & (TABSIZ - 1);
register struct localvar *tmp = regs[index];
@ -117,7 +112,7 @@ FreeLocal(off)
}
}
LocalFinish()
void LocalFinish(void)
{
register struct localvar *tmp, *tmp1;
register int i;
@ -163,9 +158,7 @@ LocalFinish()
#endif
}
void
RegisterAccount(offset, size, regtype, sc)
arith offset, size;
void RegisterAccount(arith offset, arith size, int regtype, int sc)
{
register struct localvar *p;
int index;
@ -183,9 +176,7 @@ RegisterAccount(offset, size, regtype, sc)
regs[index] = p;
}
static struct localvar *
find_reg(off)
arith off;
static struct localvar *find_reg(arith off)
{
register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)];
@ -193,8 +184,7 @@ find_reg(off)
return p;
}
LoadLocal(off, sz)
arith off, sz;
void LoadLocal(arith off, arith sz)
{
register struct localvar *p = find_reg(off);
@ -213,8 +203,7 @@ LoadLocal(off, sz)
}
}
StoreLocal(off, sz)
arith off, sz;
void StoreLocal(arith off, arith sz)
{
register struct localvar *p = find_reg(off);
@ -234,8 +223,7 @@ StoreLocal(off, sz)
}
#ifndef LINT
AddrLocal(off)
arith off;
void AddrLocal(arith off)
{
register struct localvar *p = find_reg(off);

View file

@ -1,3 +1,8 @@
#ifndef UTIL_H_
#define UTIL_H_
#include "arith.h"
struct localvar {
struct localvar *next;
arith t_offset; /* offset from LocalBase */
@ -9,3 +14,18 @@ struct localvar {
};
/* ALLOCDEF "localvar" 10 */
void LocalInit(void);
arith LocalSpace(arith sz, int al);
arith NewLocal(arith sz, int al, int regtype, int sc);
void FreeLocal(arith off);
void LocalFinish(void);
void RegisterAccount(arith offset, arith size, int regtype, int sc);
void LoadLocal(arith off, arith sz);
void StoreLocal(arith off, arith sz);
#ifndef LINT
void AddrLocal(arith off);
#endif
#endif