redesign of ival, other minor changes
This commit is contained in:
parent
db666da35a
commit
09125cce6b
42 changed files with 1146 additions and 342 deletions
|
@ -25,14 +25,16 @@
|
|||
/* Data about the token yielded */
|
||||
struct token dot, ahead, aside;
|
||||
|
||||
#ifndef NOPP
|
||||
int ReplaceMacros = 1; /* replacing macros */
|
||||
int EoiForNewline = 0; /* return EOI upon encountering newline */
|
||||
int PreProcKeys = 0; /* return preprocessor key */
|
||||
int AccFileSpecifier = 0; /* return filespecifier <...> */
|
||||
int AccDefined = 0; /* accept "defined(...)" */
|
||||
int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */
|
||||
int SkipEscNewline = 0; /* how to interpret backslash-newline */
|
||||
int Unstacked = 0; /* an unstack is done */
|
||||
#endif
|
||||
int SkipEscNewline = 0; /* how to interpret backslash-newline */
|
||||
int AccFileSpecifier = 0; /* return filespecifier <...> */
|
||||
int EoiForNewline = 0; /* return EOI upon encountering newline */
|
||||
int File_Inserted = 0; /* a file has just been inserted */
|
||||
|
||||
#define MAX_LL_DEPTH 2
|
||||
|
|
|
@ -60,9 +60,9 @@ CDEFS = $(MAP) $(EM_INCLUDES) $(LIB_INCLUDES)
|
|||
CFLAGS = $(CDEFS) $(COPTIONS) -O# we cannot pass the COPTIONS to lint!
|
||||
|
||||
# Grammar files and their objects
|
||||
LSRC = tokenfile.g declar.g statement.g expression.g program.g
|
||||
GLCSRC = tokenfile.c declar.c statement.c expression.c program.c
|
||||
LOBJ = tokenfile.o declar.o statement.o expression.o program.o Lpars.o
|
||||
LSRC = tokenfile.g declar.g statement.g expression.g program.g ival.g
|
||||
GLCSRC = tokenfile.c declar.c statement.c expression.c program.c ival.c
|
||||
LOBJ = tokenfile.o declar.o statement.o expression.o program.o Lpars.o ival.o
|
||||
|
||||
# Objects of hand-written C files
|
||||
COBJ = main.o idf.o declarator.o decspecs.o struct.o \
|
||||
|
@ -71,7 +71,7 @@ COBJ = main.o idf.o declarator.o decspecs.o struct.o \
|
|||
tokenname.o LLlex.o LLmessage.o \
|
||||
input.o domacro.o replace.o init.o options.o \
|
||||
scan.o skip.o stack.o type.o ch7mon.o label.o eval.o \
|
||||
switch.o ival.o conversion.o \
|
||||
switch.o conversion.o \
|
||||
blocks.o dataflow.o Version.o
|
||||
|
||||
# Objects of other generated C files
|
||||
|
@ -79,13 +79,13 @@ GOBJ = char.o symbol2str.o next.o
|
|||
|
||||
# generated source files
|
||||
GSRC = char.c symbol2str.c next.c \
|
||||
code.h declar.h decspecs.h def.h expr.h field.h \
|
||||
code.h declar.h decspecs.h def.h expr.h field.h estack.h \
|
||||
idf.h macro.h stack.h stmt.h struct.h switch.h type.h
|
||||
|
||||
# .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE!
|
||||
GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
|
||||
idepth.h idfsize.h ifdepth.h inputtype.h inumlength.h lapbuf.h \
|
||||
maxincl.h nobitfield.h nofloat.h nopp.h \
|
||||
maxincl.h nobitfield.h nofloat.h nopp.h noRoption.h nocross.h \
|
||||
nparams.h numsize.h parbufsize.h pathlength.h \
|
||||
strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h
|
||||
|
||||
|
@ -95,6 +95,7 @@ GENERATED = tab tokenfile.g Lpars.h LLfiles LL.output lint.out \
|
|||
|
||||
# include files containing ALLOCDEF specifications
|
||||
NEXTFILES = code.str declar.str decspecs.str def.str expr.str field.str \
|
||||
estack.str \
|
||||
idf.str macro.str stack.str stmt.str struct.str switch.str type.str
|
||||
|
||||
.SUFFIXES: .str .h
|
||||
|
@ -138,6 +139,7 @@ code.h: make.allocd
|
|||
declar.h: make.allocd
|
||||
decspecs.h: make.allocd
|
||||
def.h: make.allocd
|
||||
estack.h: make.allocd
|
||||
expr.h: make.allocd
|
||||
field.h: make.allocd
|
||||
idf.h: make.allocd
|
||||
|
@ -217,6 +219,7 @@ sim: cfiles
|
|||
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
|
||||
main.o: LLlex.h
|
||||
main.o: Lpars.h
|
||||
main.o: align.h
|
||||
main.o: arith.h
|
||||
main.o: debug.h
|
||||
main.o: declar.h
|
||||
|
@ -226,9 +229,12 @@ main.o: input.h
|
|||
main.o: inputtype.h
|
||||
main.o: level.h
|
||||
main.o: maxincl.h
|
||||
main.o: noRoption.h
|
||||
main.o: nobitfield.h
|
||||
main.o: nocross.h
|
||||
main.o: nofloat.h
|
||||
main.o: nopp.h
|
||||
main.o: sizes.h
|
||||
main.o: spec_arith.h
|
||||
main.o: specials.h
|
||||
main.o: target_sizes.h
|
||||
|
@ -250,7 +256,9 @@ idf.o: idf.h
|
|||
idf.o: idfsize.h
|
||||
idf.o: label.h
|
||||
idf.o: level.h
|
||||
idf.o: noRoption.h
|
||||
idf.o: nobitfield.h
|
||||
idf.o: nocross.h
|
||||
idf.o: nofloat.h
|
||||
idf.o: nopp.h
|
||||
idf.o: sizes.h
|
||||
|
@ -258,6 +266,7 @@ idf.o: spec_arith.h
|
|||
idf.o: specials.h
|
||||
idf.o: stack.h
|
||||
idf.o: struct.h
|
||||
idf.o: target_sizes.h
|
||||
idf.o: type.h
|
||||
declarator.o: Lpars.h
|
||||
declarator.o: arith.h
|
||||
|
@ -267,16 +276,19 @@ declarator.o: expr.h
|
|||
declarator.o: idf.h
|
||||
declarator.o: label.h
|
||||
declarator.o: nobitfield.h
|
||||
declarator.o: nocross.h
|
||||
declarator.o: nofloat.h
|
||||
declarator.o: nopp.h
|
||||
declarator.o: sizes.h
|
||||
declarator.o: spec_arith.h
|
||||
declarator.o: target_sizes.h
|
||||
declarator.o: type.h
|
||||
decspecs.o: Lpars.h
|
||||
decspecs.o: arith.h
|
||||
decspecs.o: decspecs.h
|
||||
decspecs.o: def.h
|
||||
decspecs.o: level.h
|
||||
decspecs.o: noRoption.h
|
||||
decspecs.o: nobitfield.h
|
||||
decspecs.o: nofloat.h
|
||||
decspecs.o: spec_arith.h
|
||||
|
@ -293,13 +305,16 @@ struct.o: field.h
|
|||
struct.o: file_info.h
|
||||
struct.o: idf.h
|
||||
struct.o: level.h
|
||||
struct.o: noRoption.h
|
||||
struct.o: nobitfield.h
|
||||
struct.o: nocross.h
|
||||
struct.o: nofloat.h
|
||||
struct.o: nopp.h
|
||||
struct.o: sizes.h
|
||||
struct.o: spec_arith.h
|
||||
struct.o: stack.h
|
||||
struct.o: struct.h
|
||||
struct.o: target_sizes.h
|
||||
struct.o: type.h
|
||||
expr.o: LLlex.h
|
||||
expr.o: Lpars.h
|
||||
|
@ -313,11 +328,14 @@ expr.o: file_info.h
|
|||
expr.o: idf.h
|
||||
expr.o: label.h
|
||||
expr.o: level.h
|
||||
expr.o: noRoption.h
|
||||
expr.o: nobitfield.h
|
||||
expr.o: nocross.h
|
||||
expr.o: nofloat.h
|
||||
expr.o: nopp.h
|
||||
expr.o: sizes.h
|
||||
expr.o: spec_arith.h
|
||||
expr.o: target_sizes.h
|
||||
expr.o: type.h
|
||||
ch7.o: Lpars.h
|
||||
ch7.o: arith.h
|
||||
|
@ -339,6 +357,7 @@ ch7bin.o: botch_free.h
|
|||
ch7bin.o: expr.h
|
||||
ch7bin.o: idf.h
|
||||
ch7bin.o: label.h
|
||||
ch7bin.o: noRoption.h
|
||||
ch7bin.o: nobitfield.h
|
||||
ch7bin.o: nofloat.h
|
||||
ch7bin.o: nopp.h
|
||||
|
@ -353,6 +372,7 @@ cstoper.o: expr.h
|
|||
cstoper.o: idf.h
|
||||
cstoper.o: label.h
|
||||
cstoper.o: nobitfield.h
|
||||
cstoper.o: nocross.h
|
||||
cstoper.o: nofloat.h
|
||||
cstoper.o: nopp.h
|
||||
cstoper.o: sizes.h
|
||||
|
@ -367,6 +387,7 @@ arith.o: field.h
|
|||
arith.o: idf.h
|
||||
arith.o: label.h
|
||||
arith.o: mes.h
|
||||
arith.o: noRoption.h
|
||||
arith.o: nobitfield.h
|
||||
arith.o: nofloat.h
|
||||
arith.o: nopp.h
|
||||
|
@ -374,6 +395,7 @@ arith.o: spec_arith.h
|
|||
arith.o: type.h
|
||||
code.o: LLlex.h
|
||||
code.o: Lpars.h
|
||||
code.o: align.h
|
||||
code.o: arith.h
|
||||
code.o: assert.h
|
||||
code.o: atw.h
|
||||
|
@ -390,7 +412,9 @@ code.o: idf.h
|
|||
code.o: label.h
|
||||
code.o: level.h
|
||||
code.o: mes.h
|
||||
code.o: noRoption.h
|
||||
code.o: nobitfield.h
|
||||
code.o: nocross.h
|
||||
code.o: nofloat.h
|
||||
code.o: nopp.h
|
||||
code.o: sizes.h
|
||||
|
@ -398,6 +422,7 @@ code.o: spec_arith.h
|
|||
code.o: specials.h
|
||||
code.o: stack.h
|
||||
code.o: stmt.h
|
||||
code.o: target_sizes.h
|
||||
code.o: type.h
|
||||
code.o: use_tmp.h
|
||||
dumpidf.o: Lpars.h
|
||||
|
@ -438,10 +463,12 @@ field.o: field.h
|
|||
field.o: idf.h
|
||||
field.o: label.h
|
||||
field.o: nobitfield.h
|
||||
field.o: nocross.h
|
||||
field.o: nofloat.h
|
||||
field.o: nopp.h
|
||||
field.o: sizes.h
|
||||
field.o: spec_arith.h
|
||||
field.o: target_sizes.h
|
||||
field.o: type.h
|
||||
tokenname.o: LLlex.h
|
||||
tokenname.o: Lpars.h
|
||||
|
@ -463,12 +490,14 @@ LLlex.o: file_info.h
|
|||
LLlex.o: idf.h
|
||||
LLlex.o: idfsize.h
|
||||
LLlex.o: input.h
|
||||
LLlex.o: nocross.h
|
||||
LLlex.o: nofloat.h
|
||||
LLlex.o: nopp.h
|
||||
LLlex.o: numsize.h
|
||||
LLlex.o: sizes.h
|
||||
LLlex.o: spec_arith.h
|
||||
LLlex.o: strsize.h
|
||||
LLlex.o: target_sizes.h
|
||||
LLmessage.o: LLlex.h
|
||||
LLmessage.o: Lpars.h
|
||||
LLmessage.o: arith.h
|
||||
|
@ -531,11 +560,14 @@ options.o: idf.h
|
|||
options.o: idfsize.h
|
||||
options.o: macro.h
|
||||
options.o: maxincl.h
|
||||
options.o: noRoption.h
|
||||
options.o: nobitfield.h
|
||||
options.o: nocross.h
|
||||
options.o: nofloat.h
|
||||
options.o: nopp.h
|
||||
options.o: sizes.h
|
||||
options.o: spec_arith.h
|
||||
options.o: target_sizes.h
|
||||
options.o: use_tmp.h
|
||||
scan.o: class.h
|
||||
scan.o: idf.h
|
||||
|
@ -562,6 +594,7 @@ stack.o: def.h
|
|||
stack.o: idf.h
|
||||
stack.o: level.h
|
||||
stack.o: mes.h
|
||||
stack.o: noRoption.h
|
||||
stack.o: nobitfield.h
|
||||
stack.o: nofloat.h
|
||||
stack.o: nopp.h
|
||||
|
@ -576,10 +609,12 @@ type.o: botch_free.h
|
|||
type.o: def.h
|
||||
type.o: idf.h
|
||||
type.o: nobitfield.h
|
||||
type.o: nocross.h
|
||||
type.o: nofloat.h
|
||||
type.o: nopp.h
|
||||
type.o: sizes.h
|
||||
type.o: spec_arith.h
|
||||
type.o: target_sizes.h
|
||||
type.o: type.h
|
||||
ch7mon.o: Lpars.h
|
||||
ch7mon.o: arith.h
|
||||
|
@ -599,6 +634,7 @@ label.o: def.h
|
|||
label.o: idf.h
|
||||
label.o: label.h
|
||||
label.o: level.h
|
||||
label.o: noRoption.h
|
||||
label.o: nobitfield.h
|
||||
label.o: nofloat.h
|
||||
label.o: nopp.h
|
||||
|
@ -619,11 +655,13 @@ eval.o: label.h
|
|||
eval.o: level.h
|
||||
eval.o: mes.h
|
||||
eval.o: nobitfield.h
|
||||
eval.o: nocross.h
|
||||
eval.o: nofloat.h
|
||||
eval.o: nopp.h
|
||||
eval.o: sizes.h
|
||||
eval.o: spec_arith.h
|
||||
eval.o: stack.h
|
||||
eval.o: target_sizes.h
|
||||
eval.o: type.h
|
||||
switch.o: Lpars.h
|
||||
switch.o: arith.h
|
||||
|
@ -635,45 +673,32 @@ switch.o: density.h
|
|||
switch.o: expr.h
|
||||
switch.o: idf.h
|
||||
switch.o: label.h
|
||||
switch.o: noRoption.h
|
||||
switch.o: nobitfield.h
|
||||
switch.o: nofloat.h
|
||||
switch.o: nopp.h
|
||||
switch.o: spec_arith.h
|
||||
switch.o: switch.h
|
||||
switch.o: type.h
|
||||
ival.o: Lpars.h
|
||||
ival.o: align.h
|
||||
ival.o: arith.h
|
||||
ival.o: assert.h
|
||||
ival.o: class.h
|
||||
ival.o: debug.h
|
||||
ival.o: def.h
|
||||
ival.o: expr.h
|
||||
ival.o: field.h
|
||||
ival.o: idf.h
|
||||
ival.o: label.h
|
||||
ival.o: level.h
|
||||
ival.o: nobitfield.h
|
||||
ival.o: nofloat.h
|
||||
ival.o: nopp.h
|
||||
ival.o: sizes.h
|
||||
ival.o: spec_arith.h
|
||||
ival.o: struct.h
|
||||
ival.o: type.h
|
||||
conversion.o: Lpars.h
|
||||
conversion.o: arith.h
|
||||
conversion.o: nobitfield.h
|
||||
conversion.o: nocross.h
|
||||
conversion.o: nofloat.h
|
||||
conversion.o: sizes.h
|
||||
conversion.o: spec_arith.h
|
||||
conversion.o: target_sizes.h
|
||||
conversion.o: type.h
|
||||
blocks.o: align.h
|
||||
blocks.o: arith.h
|
||||
blocks.o: atw.h
|
||||
blocks.o: label.h
|
||||
blocks.o: nocross.h
|
||||
blocks.o: nofloat.h
|
||||
blocks.o: sizes.h
|
||||
blocks.o: spec_arith.h
|
||||
blocks.o: stack.h
|
||||
blocks.o: target_sizes.h
|
||||
dataflow.o: dataflow.h
|
||||
tokenfile.o: Lpars.h
|
||||
declar.o: LLlex.h
|
||||
|
@ -688,12 +713,15 @@ declar.o: field.h
|
|||
declar.o: file_info.h
|
||||
declar.o: idf.h
|
||||
declar.o: label.h
|
||||
declar.o: level.h
|
||||
declar.o: nobitfield.h
|
||||
declar.o: nocross.h
|
||||
declar.o: nofloat.h
|
||||
declar.o: nopp.h
|
||||
declar.o: sizes.h
|
||||
declar.o: spec_arith.h
|
||||
declar.o: struct.h
|
||||
declar.o: target_sizes.h
|
||||
declar.o: type.h
|
||||
statement.o: LLlex.h
|
||||
statement.o: Lpars.h
|
||||
|
@ -719,6 +747,7 @@ expression.o: expr.h
|
|||
expression.o: file_info.h
|
||||
expression.o: idf.h
|
||||
expression.o: label.h
|
||||
expression.o: noRoption.h
|
||||
expression.o: nobitfield.h
|
||||
expression.o: nofloat.h
|
||||
expression.o: nopp.h
|
||||
|
@ -741,5 +770,30 @@ program.o: nopp.h
|
|||
program.o: spec_arith.h
|
||||
program.o: type.h
|
||||
Lpars.o: Lpars.h
|
||||
ival.o: LLlex.h
|
||||
ival.o: Lpars.h
|
||||
ival.o: align.h
|
||||
ival.o: arith.h
|
||||
ival.o: assert.h
|
||||
ival.o: class.h
|
||||
ival.o: debug.h
|
||||
ival.o: def.h
|
||||
ival.o: estack.h
|
||||
ival.o: expr.h
|
||||
ival.o: field.h
|
||||
ival.o: file_info.h
|
||||
ival.o: idf.h
|
||||
ival.o: label.h
|
||||
ival.o: level.h
|
||||
ival.o: noRoption.h
|
||||
ival.o: nobitfield.h
|
||||
ival.o: nocross.h
|
||||
ival.o: nofloat.h
|
||||
ival.o: nopp.h
|
||||
ival.o: sizes.h
|
||||
ival.o: spec_arith.h
|
||||
ival.o: struct.h
|
||||
ival.o: target_sizes.h
|
||||
ival.o: type.h
|
||||
char.o: class.h
|
||||
symbol2str.o: Lpars.h
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
#define PATHLENGTH 1024 /* max. length of path to file */
|
||||
|
||||
|
||||
!File: idepth.h
|
||||
#define IDEPTH 100 /* maximum nr of stacked input buffers */
|
||||
|
||||
|
||||
!File: errout.h
|
||||
#define ERROUT STDERR /* file pointer for writing messages */
|
||||
#define MAXERR_LINE 5 /* maximum number of error messages given
|
||||
|
@ -78,7 +74,7 @@
|
|||
|
||||
|
||||
!File: botch_free.h
|
||||
#undef BOTCH_FREE 1 /* botch freed memory, as a check */
|
||||
#undef BOTCH_FREE 1 /* when defined, botch freed memory, as a check */
|
||||
|
||||
|
||||
!File: dataflow.h
|
||||
|
@ -109,11 +105,11 @@
|
|||
|
||||
|
||||
!File: nopp.h
|
||||
#undef NOPP 1 /* use built-int preprocessor */
|
||||
#undef NOPP 1 /* if NOT defined, use built-int preprocessor */
|
||||
|
||||
|
||||
!File: nobitfield.h
|
||||
#undef NOBITFIELD 1 /* implement bitfields */
|
||||
#undef NOBITFIELD 1 /* if NOT defined, implement bitfields */
|
||||
|
||||
|
||||
!File: spec_arith.h
|
||||
|
@ -126,5 +122,14 @@
|
|||
|
||||
|
||||
!File: nofloat.h
|
||||
#undef NOFLOAT /* floats implemented by default */
|
||||
#undef NOFLOAT 1 /* if NOT defined, floats are implemented */
|
||||
|
||||
|
||||
!File: noRoption.h
|
||||
#undef NOROPTION 1 /* if NOT defined, R option is implemented */
|
||||
|
||||
|
||||
!File: nocross.h
|
||||
#undef NOCROSS 1 /* if NOT defined, cross compiler */
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
/* A L I G N M E N T D E F I N I T I O N S */
|
||||
|
||||
#include "nofloat.h"
|
||||
#include "nocross.h"
|
||||
#include "target_sizes.h"
|
||||
|
||||
#ifndef NOCROSS
|
||||
extern int
|
||||
short_align, word_align, int_align, long_align,
|
||||
#ifndef NOFLOAT
|
||||
|
@ -14,5 +17,18 @@ extern int
|
|||
#endif NOFLOAT
|
||||
pointer_align,
|
||||
struct_align, union_align;
|
||||
#else NOCROSS
|
||||
#define short_align ((int)AL_SHORT)
|
||||
#define word_align ((int)AL_WORD)
|
||||
#define int_align ((int)AL_INT)
|
||||
#define long_align ((int)AL_LONG)
|
||||
#ifndef NOFLOAT
|
||||
#define float_align ((int)AL_FLOAT)
|
||||
#define double_align ((int)AL_DOUBLE)
|
||||
#endif NOFLOAT
|
||||
#define pointer_align ((int)AL_POINTER)
|
||||
#define struct_align ((int)AL_STRUCT)
|
||||
#define union_align ((int)AL_UNION)
|
||||
#endif NOCROSS
|
||||
|
||||
extern arith align();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "Lpars.h"
|
||||
#include "field.h"
|
||||
#include "mes.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char *symbol2str();
|
||||
extern char options[];
|
||||
|
@ -80,9 +81,9 @@ relbalance(e1p, oper, e2p)
|
|||
of the relational operator oper.
|
||||
*/
|
||||
if ((*e1p)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(e1p);
|
||||
function2pointer(*e1p);
|
||||
if ((*e2p)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(e2p);
|
||||
function2pointer(*e2p);
|
||||
if ((*e1p)->ex_type->tp_fund == POINTER)
|
||||
ch76pointer(e2p, oper, (*e1p)->ex_type);
|
||||
else
|
||||
|
@ -98,28 +99,33 @@ relbalance(e1p, oper, e2p)
|
|||
}
|
||||
|
||||
ch76pointer(expp, oper, tp)
|
||||
register struct expr **expp;
|
||||
struct expr **expp;
|
||||
register struct type *tp;
|
||||
{
|
||||
/* Checks whether *expp may be compared to tp using oper,
|
||||
as described in chapter 7.6 and 7.7.
|
||||
tp is known to be a pointer.
|
||||
*/
|
||||
if ((*expp)->ex_type->tp_fund == POINTER) {
|
||||
if ((*expp)->ex_type != tp)
|
||||
register struct expr *exp = *expp;
|
||||
|
||||
if (exp->ex_type->tp_fund == POINTER) {
|
||||
if (exp->ex_type != tp)
|
||||
ch7cast(expp, oper, tp);
|
||||
}
|
||||
else
|
||||
if ( is_integral_type((*expp)->ex_type) &&
|
||||
if ( is_integral_type(exp->ex_type)
|
||||
#ifndef NOROPTION
|
||||
&&
|
||||
( !options['R'] /* we don't care */ ||
|
||||
(oper == EQUAL || oper == NOTEQUAL || oper == ':')
|
||||
)
|
||||
#endif NOROPTION
|
||||
) /* ch 7.7 */
|
||||
ch7cast(expp, CAST, tp);
|
||||
else {
|
||||
expr_error(*expp, "%s on %s and pointer",
|
||||
expr_error(exp, "%s on %s and pointer",
|
||||
symbol2str(oper),
|
||||
symbol2str((*expp)->ex_type->tp_fund)
|
||||
symbol2str(exp->ex_type->tp_fund)
|
||||
);
|
||||
ch7cast(expp, oper, tp);
|
||||
}
|
||||
|
@ -152,11 +158,13 @@ any2arith(expp, oper)
|
|||
/* allowed by K & R */
|
||||
}
|
||||
else
|
||||
#ifndef NOROPTION
|
||||
if (!options['R']) {
|
||||
/* allowed by us */
|
||||
}
|
||||
else
|
||||
expr_warning(*expp, "%s on enum", symbol2str(oper));
|
||||
#endif NOROPTION
|
||||
int2int(expp, int_type);
|
||||
break;
|
||||
#ifndef NOFLOAT
|
||||
|
@ -183,16 +191,18 @@ any2arith(expp, oper)
|
|||
}
|
||||
|
||||
erroneous2int(expp)
|
||||
register struct expr **expp;
|
||||
struct expr **expp;
|
||||
{
|
||||
/* the (erroneous) expression *expp is replaced by an
|
||||
int expression
|
||||
*/
|
||||
int flags = (*expp)->ex_flags;
|
||||
register struct expr *exp = *expp;
|
||||
int flags = exp->ex_flags;
|
||||
|
||||
free_expression(*expp);
|
||||
*expp = intexpr((arith)0, INT);
|
||||
(*expp)->ex_flags = (flags | EX_ERROR);
|
||||
free_expression(exp);
|
||||
exp = intexpr((arith)0, INT);
|
||||
exp->ex_flags = (flags | EX_ERROR);
|
||||
*expp = exp;
|
||||
}
|
||||
|
||||
struct expr *
|
||||
|
@ -215,17 +225,18 @@ arith2arith(tp, oper, expr)
|
|||
|
||||
int
|
||||
int2int(expp, tp)
|
||||
register struct expr **expp;
|
||||
struct expr **expp;
|
||||
register struct type *tp;
|
||||
{
|
||||
/* The expression *expp, which is of some integral type, is
|
||||
converted to the integral type tp.
|
||||
*/
|
||||
register struct expr *exp = *expp;
|
||||
|
||||
if (is_cp_cst(*expp)) {
|
||||
register struct type *tp1 = (*expp)->ex_type;
|
||||
if (is_cp_cst(exp)) {
|
||||
register struct type *tp1 = exp->ex_type;
|
||||
|
||||
(*expp)->ex_type = tp;
|
||||
exp->ex_type = tp;
|
||||
if (! tp1->tp_unsigned && tp->tp_unsigned) {
|
||||
/* Avoid "unreal" overflow warnings, such as
|
||||
caused by f.i.:
|
||||
|
@ -233,20 +244,21 @@ int2int(expp, tp)
|
|||
unsigned int y = -1;
|
||||
*/
|
||||
extern long full_mask[];
|
||||
long remainder = (*expp)->VL_VALUE &
|
||||
long remainder = exp->VL_VALUE &
|
||||
~full_mask[tp->tp_size];
|
||||
|
||||
if (remainder == 0 ||
|
||||
remainder == ~full_mask[tp->tp_size]) {
|
||||
(*expp)->VL_VALUE &= ~remainder;
|
||||
exp->VL_VALUE &= ~remainder;
|
||||
}
|
||||
}
|
||||
cut_size(*expp);
|
||||
cut_size(exp);
|
||||
}
|
||||
else {
|
||||
*expp = arith2arith(tp, INT2INT, *expp);
|
||||
exp = arith2arith(tp, INT2INT, exp);
|
||||
}
|
||||
return (*expp)->ex_type->tp_fund;
|
||||
*expp = exp;
|
||||
return exp->ex_type->tp_fund;
|
||||
}
|
||||
|
||||
#ifndef NOFLOAT
|
||||
|
@ -294,33 +306,30 @@ float2float(expp, tp)
|
|||
}
|
||||
#endif NOFLOAT
|
||||
|
||||
array2pointer(expp)
|
||||
register struct expr **expp;
|
||||
array2pointer(exp)
|
||||
register struct expr *exp;
|
||||
{
|
||||
/* The expression, which must be an array, is converted
|
||||
to a pointer.
|
||||
*/
|
||||
(*expp)->ex_type =
|
||||
construct_type(POINTER, (*expp)->ex_type->tp_up, (arith)0);
|
||||
exp->ex_type = construct_type(POINTER, exp->ex_type->tp_up, (arith)0);
|
||||
}
|
||||
|
||||
function2pointer(expp)
|
||||
register struct expr **expp;
|
||||
function2pointer(exp)
|
||||
register struct expr *exp;
|
||||
{
|
||||
/* The expression, which must be a function, is converted
|
||||
to a pointer to the function.
|
||||
*/
|
||||
(*expp)->ex_type =
|
||||
construct_type(POINTER, (*expp)->ex_type, (arith)0);
|
||||
exp->ex_type = construct_type(POINTER, exp->ex_type, (arith)0);
|
||||
}
|
||||
|
||||
string2pointer(expp)
|
||||
struct expr **expp;
|
||||
string2pointer(ex)
|
||||
register struct expr *ex;
|
||||
{
|
||||
/* The expression, which must be a string constant, is converted
|
||||
to a pointer to the string-containing area.
|
||||
*/
|
||||
register struct expr *ex = *expp;
|
||||
label lbl = data_label();
|
||||
|
||||
code_string(ex->SG_VALUE, ex->SG_LEN, lbl);
|
||||
|
@ -351,7 +360,7 @@ opnd2logical(expp, oper)
|
|||
int fund;
|
||||
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(expp);
|
||||
function2pointer(*expp);
|
||||
#ifndef NOBITFIELD
|
||||
else
|
||||
if ((*expp)->ex_type->tp_fund == FIELD)
|
||||
|
@ -408,6 +417,7 @@ is_test_op(oper)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
#ifdef ____
|
||||
int
|
||||
is_arith_op(oper)
|
||||
{
|
||||
|
@ -452,6 +462,7 @@ is_asgn_op(oper)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
any2opnd(expp, oper)
|
||||
register struct expr **expp;
|
||||
|
@ -468,11 +479,11 @@ any2opnd(expp, oper)
|
|||
any2arith(expp, oper);
|
||||
break;
|
||||
case ARRAY:
|
||||
array2pointer(expp);
|
||||
array2pointer(*expp);
|
||||
break;
|
||||
case POINTER:
|
||||
if ((*expp)->ex_class == String)
|
||||
string2pointer(expp);
|
||||
string2pointer(*expp);
|
||||
break;
|
||||
#ifndef NOBITFIELD
|
||||
case FIELD:
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
/* $Header$ */
|
||||
/* Align To Word boundary Definition */
|
||||
|
||||
extern arith word_size;
|
||||
#include "sizes.h"
|
||||
|
||||
#define ATW(arg) ((((arg) + word_size - 1) / word_size) * word_size)
|
||||
|
|
|
@ -27,13 +27,14 @@ extern char *symbol2str();
|
|||
*/
|
||||
|
||||
ch7sel(expp, oper, idf)
|
||||
register struct expr **expp;
|
||||
struct expr **expp;
|
||||
struct idf *idf;
|
||||
{
|
||||
/* The selector idf is applied to *expp; oper may be '.' or
|
||||
ARROW.
|
||||
*/
|
||||
register struct type *tp = (*expp)->ex_type;
|
||||
register struct expr *exp = *expp;
|
||||
register struct type *tp = exp->ex_type;
|
||||
register struct sdef *sd;
|
||||
|
||||
if (oper == ARROW) {
|
||||
|
@ -54,21 +55,22 @@ ch7sel(expp, oper, idf)
|
|||
tp = sd->sd_stype;
|
||||
break;
|
||||
default:
|
||||
expr_error(*expp, "-> applied to %s",
|
||||
expr_error(exp, "-> applied to %s",
|
||||
symbol2str(tp->tp_fund));
|
||||
case ERRONEOUS:
|
||||
(*expp)->ex_type = error_type;
|
||||
exp->ex_type = error_type;
|
||||
return;
|
||||
}
|
||||
} /* tp->tp_fund != POINTER */
|
||||
} /* oper == ARROW */
|
||||
else { /* oper == '.' */
|
||||
/* filter out illegal expressions "non_lvalue.sel" */
|
||||
if (!(*expp)->ex_lvalue) {
|
||||
expr_error(*expp, "dot requires lvalue");
|
||||
if (!exp->ex_lvalue) {
|
||||
expr_error(exp, "dot requires lvalue");
|
||||
return;
|
||||
}
|
||||
}
|
||||
exp = *expp;
|
||||
switch (tp->tp_fund) {
|
||||
case POINTER: /* for int *p; p->next = ... */
|
||||
case STRUCT:
|
||||
|
@ -83,10 +85,10 @@ ch7sel(expp, oper, idf)
|
|||
break;
|
||||
default:
|
||||
if (!is_anon_idf(idf))
|
||||
expr_error(*expp, "selector %s applied to %s",
|
||||
expr_error(exp, "selector %s applied to %s",
|
||||
idf->id_text, symbol2str(tp->tp_fund));
|
||||
case ERRONEOUS:
|
||||
(*expp)->ex_type = error_type;
|
||||
exp->ex_type = error_type;
|
||||
return;
|
||||
}
|
||||
sd = idf2sdef(idf, tp);
|
||||
|
@ -99,36 +101,37 @@ ch7sel(expp, oper, idf)
|
|||
The code performing these conversions is
|
||||
extremely obscure.
|
||||
*/
|
||||
if ((*expp)->ex_class == Value) {
|
||||
if (exp->ex_class == Value) {
|
||||
/* It is an object we know the address of; so
|
||||
we can calculate the address of the
|
||||
selected member
|
||||
*/
|
||||
(*expp)->VL_VALUE += sd->sd_offset;
|
||||
(*expp)->ex_type = sd->sd_type;
|
||||
if ((*expp)->ex_type == error_type)
|
||||
(*expp)->ex_flags |= EX_ERROR;
|
||||
exp->VL_VALUE += sd->sd_offset;
|
||||
exp->ex_type = sd->sd_type;
|
||||
if (exp->ex_type == error_type)
|
||||
exp->ex_flags |= EX_ERROR;
|
||||
}
|
||||
else
|
||||
if ((*expp)->ex_class == Oper) {
|
||||
struct oper *op = &((*expp)->ex_object.ex_oper);
|
||||
if (exp->ex_class == Oper) {
|
||||
struct oper *op = &(exp->ex_object.ex_oper);
|
||||
|
||||
if (op->op_oper == '.' || op->op_oper == ARROW) {
|
||||
ASSERT(is_cp_cst(op->op_right));
|
||||
op->op_right->VL_VALUE += sd->sd_offset;
|
||||
(*expp)->ex_type = sd->sd_type;
|
||||
if ((*expp)->ex_type == error_type)
|
||||
(*expp)->ex_flags |= EX_ERROR;
|
||||
exp->ex_type = sd->sd_type;
|
||||
if (exp->ex_type == error_type)
|
||||
exp->ex_flags |= EX_ERROR;
|
||||
}
|
||||
else
|
||||
*expp = new_oper(sd->sd_type, *expp, '.',
|
||||
exp = new_oper(sd->sd_type, exp, '.',
|
||||
intexpr(sd->sd_offset, INT));
|
||||
}
|
||||
}
|
||||
else /* oper == ARROW */
|
||||
*expp = new_oper(sd->sd_type,
|
||||
*expp, oper, intexpr(sd->sd_offset, INT));
|
||||
(*expp)->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
|
||||
exp = new_oper(sd->sd_type,
|
||||
exp, oper, intexpr(sd->sd_offset, INT));
|
||||
exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
|
||||
*expp = exp;
|
||||
}
|
||||
|
||||
ch7incr(expp, oper)
|
||||
|
@ -152,11 +155,11 @@ ch7cast(expp, oper, tp)
|
|||
register struct type *oldtp;
|
||||
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(expp);
|
||||
function2pointer(*expp);
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY)
|
||||
array2pointer(expp);
|
||||
array2pointer(*expp);
|
||||
if ((*expp)->ex_class == String)
|
||||
string2pointer(expp);
|
||||
string2pointer(*expp);
|
||||
oldtp = (*expp)->ex_type;
|
||||
#ifndef NOBITFIELD
|
||||
if (oldtp->tp_fund == FIELD) {
|
||||
|
@ -276,7 +279,7 @@ ch7cast(expp, oper, tp)
|
|||
}
|
||||
|
||||
ch7asgn(expp, oper, expr)
|
||||
register struct expr **expp;
|
||||
struct expr **expp;
|
||||
struct expr *expr;
|
||||
{
|
||||
/* The assignment operators.
|
||||
|
@ -292,17 +295,18 @@ ch7asgn(expp, oper, expr)
|
|||
f (typeof (f op e))e
|
||||
EVAL should however take care of evaluating (typeof (f op e))f
|
||||
*/
|
||||
int fund = (*expp)->ex_type->tp_fund;
|
||||
register struct expr *exp = *expp;
|
||||
int fund = exp->ex_type->tp_fund;
|
||||
struct type *tp;
|
||||
|
||||
/* We expect an lvalue */
|
||||
if (!(*expp)->ex_lvalue) {
|
||||
expr_error(*expp, "no lvalue in lhs of %s", symbol2str(oper));
|
||||
(*expp)->ex_depth = 99; /* no direct store/load at EVAL() */
|
||||
if (!exp->ex_lvalue) {
|
||||
expr_error(exp, "no lvalue in lhs of %s", symbol2str(oper));
|
||||
exp->ex_depth = 99; /* no direct store/load at EVAL() */
|
||||
/* what is 99 ??? DG */
|
||||
}
|
||||
if (oper == '=') {
|
||||
ch7cast(&expr, oper, (*expp)->ex_type);
|
||||
ch7cast(&expr, oper, exp->ex_type);
|
||||
tp = expr->ex_type;
|
||||
}
|
||||
else { /* turn e into e' where typeof(e') = typeof (f op e) */
|
||||
|
@ -310,7 +314,7 @@ ch7asgn(expp, oper, expr)
|
|||
|
||||
/* this is really $#@&*%$# ! */
|
||||
extmp->ex_lvalue = 1;
|
||||
extmp->ex_type = (*expp)->ex_type;
|
||||
extmp->ex_type = exp->ex_type;
|
||||
ch7bin(&extmp, oper, expr);
|
||||
/* Note that ch7bin creates a tree of the expression
|
||||
((typeof (f op e))f op (typeof (f op e))e),
|
||||
|
@ -330,14 +334,15 @@ ch7asgn(expp, oper, expr)
|
|||
}
|
||||
#ifndef NOBITFIELD
|
||||
if (fund == FIELD)
|
||||
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
|
||||
exp = new_oper(exp->ex_type->tp_up, exp, oper, expr);
|
||||
else
|
||||
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
|
||||
exp = new_oper(exp->ex_type, exp, oper, expr);
|
||||
#else NOBITFIELD
|
||||
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
|
||||
exp = new_oper(exp->ex_type, exp, oper, expr);
|
||||
#endif NOBITFIELD
|
||||
(*expp)->OP_TYPE = tp; /* for EVAL() */
|
||||
(*expp)->ex_flags |= EX_SIDEEFFECTS;
|
||||
exp->OP_TYPE = tp; /* for EVAL() */
|
||||
exp->ex_flags |= EX_SIDEEFFECTS;
|
||||
*expp = exp;
|
||||
}
|
||||
|
||||
/* Some interesting (?) questions answered.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "label.h"
|
||||
#include "expr.h"
|
||||
#include "Lpars.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char options[];
|
||||
extern char *symbol2str();
|
||||
|
@ -68,8 +69,10 @@ ch7bin(expp, oper, expr)
|
|||
if ( (*expp)->ex_type->tp_fund == POINTER &&
|
||||
(*expp)->ex_type->tp_up->tp_fund == FUNCTION
|
||||
) {
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("function pointer called");
|
||||
#endif NOROPTION
|
||||
ch7mon('*', expp);
|
||||
}
|
||||
if ((*expp)->ex_type->tp_fund != FUNCTION) {
|
||||
|
@ -85,7 +88,7 @@ ch7bin(expp, oper, expr)
|
|||
break;
|
||||
case PARCOMMA: /* RM 7.1 */
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(expp);
|
||||
function2pointer(*expp);
|
||||
*expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
|
||||
break;
|
||||
case '%':
|
||||
|
@ -271,7 +274,8 @@ pntminuspnt(expp, oper, expr)
|
|||
}
|
||||
|
||||
mk_binop(expp, oper, expr, commutative)
|
||||
register struct expr **expp, *expr;
|
||||
struct expr **expp;
|
||||
register struct expr *expr;
|
||||
{
|
||||
/* Constructs in *expp the operation indicated by the operands.
|
||||
"commutative" indicates wether "oper" is a commutative
|
||||
|
|
|
@ -32,7 +32,7 @@ ch7mon(oper, expp)
|
|||
case '*': /* RM 7.2 */
|
||||
/* no FIELD type allowed */
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY)
|
||||
array2pointer(expp);
|
||||
array2pointer(*expp);
|
||||
if ((*expp)->ex_type->tp_fund != POINTER) {
|
||||
expr_error(*expp,
|
||||
"* applied to non-pointer (%s)",
|
||||
|
@ -54,12 +54,12 @@ ch7mon(oper, expp)
|
|||
case '&':
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY) {
|
||||
warning("& before array: ignored");
|
||||
array2pointer(expp);
|
||||
array2pointer(*expp);
|
||||
}
|
||||
else
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION) {
|
||||
warning("& before function: ignored");
|
||||
function2pointer(expp);
|
||||
function2pointer(*expp);
|
||||
}
|
||||
else
|
||||
#ifndef NOBITFIELD
|
||||
|
@ -131,7 +131,7 @@ ch7mon(oper, expp)
|
|||
break;
|
||||
case '!':
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(expp);
|
||||
function2pointer(*expp);
|
||||
if ((*expp)->ex_type->tp_fund != POINTER)
|
||||
any2arith(expp, oper);
|
||||
opnd2test(expp, '!');
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "atw.h"
|
||||
#include "assert.h"
|
||||
#include "align.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
label lab_count = 1;
|
||||
label datlab_count = 1;
|
||||
|
@ -301,7 +302,8 @@ code_declaration(idf, expr, lvl, sc)
|
|||
/* code_declaration() does the actual declaration of the
|
||||
variable indicated by "idf" on declaration level "lvl".
|
||||
If the variable is initialised, the expression is given
|
||||
in "expr".
|
||||
in "expr", but for global and static initialisations it
|
||||
is just non-zero, as the expression is not parsed yet.
|
||||
There are some cases to be considered:
|
||||
- filter out typedefs, they don't correspond to code;
|
||||
- global variables, coded only if initialized;
|
||||
|
@ -343,8 +345,6 @@ code_declaration(idf, expr, lvl, sc)
|
|||
code_scope(text, def);
|
||||
def->df_alloc = ALLOC_DONE;
|
||||
C_df_dnam(text);
|
||||
do_ival(&(def->df_type), expr);
|
||||
free_expression(expr);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -361,8 +361,6 @@ code_declaration(idf, expr, lvl, sc)
|
|||
*/
|
||||
C_df_dlb((label)def->df_address);
|
||||
if (expr) { /* there is an initialisation */
|
||||
do_ival(&(def->df_type), expr);
|
||||
free_expression(expr);
|
||||
}
|
||||
else { /* produce blank space */
|
||||
if (size <= 0) {
|
||||
|
@ -414,6 +412,7 @@ loc_init(expr, id)
|
|||
return;
|
||||
}
|
||||
if (ISCOMMA(e)) { /* embraced: int i = {12}; */
|
||||
#ifndef NOROPTION
|
||||
if (options['R']) {
|
||||
if (ISCOMMA(e->OP_LEFT)) /* int i = {{1}} */
|
||||
expr_error(e, "extra braces not allowed");
|
||||
|
@ -421,6 +420,7 @@ loc_init(expr, id)
|
|||
if (e->OP_RIGHT != 0) /* int i = {1 , 2} */
|
||||
expr_error(e, "too many initializers");
|
||||
}
|
||||
#endif NOROPTION
|
||||
while (e) {
|
||||
loc_init(e->OP_LEFT, id);
|
||||
e = e->OP_RIGHT;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* C O D E - G E N E R A T O R D E F I N I T I O N S */
|
||||
|
||||
|
|
|
@ -33,31 +33,24 @@ conversion(from_type, to_type)
|
|||
{
|
||||
register arith from_size = from_type->tp_size;
|
||||
register arith to_size = to_type->tp_size;
|
||||
int from_fund = fundamental(from_type);
|
||||
int to_fund = fundamental(to_type);
|
||||
|
||||
if (from_type == to_type) /* a little optimisation */
|
||||
return;
|
||||
if (to_size < word_size) to_size = word_size;
|
||||
switch (fundamental(from_type)) {
|
||||
if (from_size == to_size && from_fund == to_fund)
|
||||
return;
|
||||
switch (from_fund) {
|
||||
case T_SIGNED:
|
||||
switch (fundamental(to_type)) {
|
||||
switch (to_fund) {
|
||||
case T_SIGNED:
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
C_cii();
|
||||
break;
|
||||
case T_UNSIGNED:
|
||||
if (from_size < word_size) {
|
||||
C_loc(from_size);
|
||||
C_loc(word_size);
|
||||
C_cii();
|
||||
from_size = word_size;
|
||||
}
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
C_ciu();
|
||||
break;
|
||||
#ifndef NOFLOAT
|
||||
case T_FLOATING:
|
||||
#endif NOOFLOAT
|
||||
if (from_size < word_size) {
|
||||
C_loc(from_size);
|
||||
C_loc(word_size);
|
||||
|
@ -66,16 +59,16 @@ conversion(from_type, to_type)
|
|||
}
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
C_cif();
|
||||
if (to_fund == T_UNSIGNED) C_ciu();
|
||||
else C_cif();
|
||||
break;
|
||||
#endif NOFLOAT
|
||||
}
|
||||
break;
|
||||
case T_UNSIGNED:
|
||||
if (from_size < word_size) from_size = word_size;
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
switch (fundamental(to_type)) {
|
||||
switch (to_fund) {
|
||||
case T_SIGNED:
|
||||
C_cui();
|
||||
break;
|
||||
|
@ -93,7 +86,7 @@ conversion(from_type, to_type)
|
|||
case T_FLOATING:
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
switch (fundamental(to_type)) {
|
||||
switch (to_fund) {
|
||||
case T_SIGNED:
|
||||
C_cfi();
|
||||
break;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "label.h"
|
||||
#include "expr.h"
|
||||
#include "sizes.h"
|
||||
#include "level.h"
|
||||
|
||||
extern char options[];
|
||||
}
|
||||
|
@ -83,22 +84,20 @@ other_specifier(register struct decspecs *ds;):
|
|||
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
|
||||
{ if (ds->ds_sc_given)
|
||||
error("repeated storage class specifier");
|
||||
else {
|
||||
ds->ds_sc_given = 1;
|
||||
ds->ds_sc = DOT;
|
||||
}
|
||||
ds->ds_sc_given = 1;
|
||||
ds->ds_sc = DOT;
|
||||
}
|
||||
|
|
||||
[ SHORT | LONG ]
|
||||
{ if (ds->ds_size)
|
||||
error("repeated size specifier");
|
||||
else ds->ds_size = DOT;
|
||||
ds->ds_size = DOT;
|
||||
}
|
||||
|
|
||||
UNSIGNED
|
||||
{ if (ds->ds_unsigned)
|
||||
error("unsigned specified twice");
|
||||
else ds->ds_unsigned = 1;
|
||||
ds->ds_unsigned = 1;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -137,7 +136,6 @@ init_declarator_list(struct decspecs *ds;):
|
|||
init_declarator(register struct decspecs *ds;)
|
||||
{
|
||||
struct declarator Dc;
|
||||
struct expr *expr = (struct expr *) 0;
|
||||
}
|
||||
:
|
||||
{
|
||||
|
@ -149,14 +147,57 @@ init_declarator(register struct decspecs *ds;)
|
|||
reject_params(&Dc);
|
||||
declare_idf(ds, &Dc, level);
|
||||
}
|
||||
initializer(Dc.dc_idf, &expr)?
|
||||
{
|
||||
code_declaration(Dc.dc_idf, expr, level, ds->ds_sc);
|
||||
}
|
||||
[
|
||||
initializer(Dc.dc_idf, ds->ds_sc)
|
||||
|
|
||||
{ code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); }
|
||||
]
|
||||
]
|
||||
{remove_declarator(&Dc);}
|
||||
;
|
||||
|
||||
/* 8.6: initializer */
|
||||
initializer(struct idf *idf; int sc;)
|
||||
{
|
||||
struct expr *expr = (struct expr *) 0;
|
||||
int globalflag = level == L_GLOBAL ||
|
||||
(level == L_LOCAL && sc == STATIC);
|
||||
}
|
||||
:
|
||||
{ if (idf->id_def->df_type->tp_fund == FUNCTION) {
|
||||
error("illegal initialization of function");
|
||||
}
|
||||
}
|
||||
[
|
||||
'='
|
||||
|
|
||||
empty
|
||||
{warning("old-fashioned initialization, insert =");}
|
||||
/* This causes trouble at declarator and at
|
||||
external_definition, q.v.
|
||||
*/
|
||||
]
|
||||
{ if (globalflag) {
|
||||
struct expr ex;
|
||||
code_declaration(idf, &ex, level, sc);
|
||||
}
|
||||
}
|
||||
initial_value(globalflag ? &(idf->id_def->df_type) : (struct type **)0,
|
||||
&expr)
|
||||
{ if (! globalflag) {
|
||||
if (idf->id_def->df_type->tp_fund == FUNCTION) {
|
||||
free_expression(expr);
|
||||
expr = 0;
|
||||
}
|
||||
code_declaration(idf, expr, level, sc);
|
||||
#ifdef DEBUG
|
||||
print_expr("initializer-expression", expr);
|
||||
#endif DEBUG
|
||||
}
|
||||
init_idf(idf);
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
Functions yielding pointers to functions must be declared as, e.g.,
|
||||
int (*hehe(par1, par2))() char *par1, *par2; {}
|
||||
|
@ -398,31 +439,6 @@ bit_expression(struct field **fd;)
|
|||
}
|
||||
;
|
||||
|
||||
/* 8.6 */
|
||||
initializer(register struct idf *idf; register struct expr **expp;) :
|
||||
[
|
||||
'='
|
||||
|
|
||||
empty
|
||||
{warning("old-fashioned initialization, insert =");}
|
||||
/* This causes trouble at declarator and at
|
||||
external_definition, q.v.
|
||||
*/
|
||||
]
|
||||
initial_value(expp)
|
||||
{
|
||||
if (idf->id_def->df_type->tp_fund == FUNCTION) {
|
||||
error("illegal initialization of function");
|
||||
free_expression(*expp);
|
||||
*expp = 0;
|
||||
}
|
||||
init_idf(idf);
|
||||
#ifdef DEBUG
|
||||
print_expr("initializer-expression", *expp);
|
||||
#endif DEBUG
|
||||
}
|
||||
;
|
||||
|
||||
/* 8.7 */
|
||||
cast(struct type **tpp;) {struct declarator Dc;} :
|
||||
{Dc = null_declarator;}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* DEFINITION OF DECLARATOR DESCRIPTORS */
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "type.h"
|
||||
#include "level.h"
|
||||
#include "def.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char options[];
|
||||
extern int level;
|
||||
|
@ -75,21 +76,27 @@ do_decspecs(ds)
|
|||
if (ds->ds_unsigned) {
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("unsigned char not allowed");
|
||||
#endif
|
||||
tp = uchar_type;
|
||||
break;
|
||||
case SHORT:
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("unsigned short not allowed");
|
||||
#endif
|
||||
tp = ushort_type;
|
||||
break;
|
||||
case INT:
|
||||
tp = uint_type;
|
||||
break;
|
||||
case LONG:
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("unsigned long not allowed");
|
||||
#endif
|
||||
tp = ulong_type;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* DECLARATION SPECIFIER DEFINITION */
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* IDENTIFIER DEFINITION DESCRIPTOR */
|
||||
|
||||
|
|
|
@ -73,9 +73,7 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
break;
|
||||
case String: /* a string constant */
|
||||
if (gencode) {
|
||||
struct expr *ex = expr;
|
||||
string2pointer(&ex);
|
||||
expr = ex;
|
||||
string2pointer(expr);
|
||||
C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
|
||||
}
|
||||
break;
|
||||
|
@ -522,72 +520,37 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
C_df_ilb(l_end);
|
||||
break;
|
||||
}
|
||||
case AND:
|
||||
if (true_label == 0) {
|
||||
label l_true = text_label();
|
||||
label l_false = text_label();
|
||||
label l_maybe = text_label();
|
||||
label l_end = text_label();
|
||||
|
||||
EVAL(left, RVAL, TRUE, l_maybe, l_false);
|
||||
C_df_ilb(l_maybe);
|
||||
if (gencode) {
|
||||
EVAL(right, RVAL, TRUE, l_true,
|
||||
l_false);
|
||||
C_df_ilb(l_true);
|
||||
C_loc((arith)1);
|
||||
C_bra(l_end);
|
||||
C_df_ilb(l_false);
|
||||
C_loc((arith)0);
|
||||
C_df_ilb(l_end);
|
||||
}
|
||||
else {
|
||||
EVAL(right, RVAL, FALSE, l_false,
|
||||
l_false);
|
||||
C_df_ilb(l_false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
label l_maybe = text_label();
|
||||
|
||||
EVAL(left, RVAL, TRUE, l_maybe, false_label);
|
||||
C_df_ilb(l_maybe);
|
||||
EVAL(right, RVAL, gencode, true_label,
|
||||
false_label);
|
||||
}
|
||||
break;
|
||||
case OR:
|
||||
if (true_label == 0) {
|
||||
label l_true = text_label();
|
||||
label l_false = text_label();
|
||||
label l_maybe = text_label();
|
||||
label l_end = text_label();
|
||||
case AND: {
|
||||
label l_false, l_true, l_maybe;
|
||||
|
||||
EVAL(left, RVAL, TRUE, l_true, l_maybe);
|
||||
C_df_ilb(l_maybe);
|
||||
if (gencode) {
|
||||
EVAL(right, RVAL, TRUE, l_true,
|
||||
l_false);
|
||||
C_df_ilb(l_true);
|
||||
C_loc((arith)1);
|
||||
C_bra(l_end);
|
||||
C_df_ilb(l_false);
|
||||
C_loc((arith)0);
|
||||
C_df_ilb(l_end);
|
||||
}
|
||||
else {
|
||||
EVAL(right, RVAL, FALSE, l_true,
|
||||
l_true);
|
||||
C_df_ilb(l_true);
|
||||
}
|
||||
l_maybe = text_label();
|
||||
if (true_label) {
|
||||
l_false = false_label;
|
||||
l_true = true_label;
|
||||
}
|
||||
else {
|
||||
label l_maybe = text_label();
|
||||
l_false = text_label();
|
||||
l_true = gencode ? text_label(): l_false;
|
||||
}
|
||||
|
||||
EVAL(left, RVAL, TRUE, true_label, l_maybe);
|
||||
C_df_ilb(l_maybe);
|
||||
EVAL(right, RVAL, gencode, true_label,
|
||||
false_label);
|
||||
EVAL(left, RVAL, TRUE, oper == AND ? l_maybe : l_true,
|
||||
oper == AND ? l_false : l_maybe);
|
||||
C_df_ilb(l_maybe);
|
||||
EVAL(right, RVAL, gencode, l_true, l_false);
|
||||
if (gencode && !true_label) {
|
||||
label l_end = text_label();
|
||||
|
||||
C_df_ilb(l_true);
|
||||
C_loc((arith)1);
|
||||
C_bra(l_end);
|
||||
C_df_ilb(l_false);
|
||||
C_loc((arith)0);
|
||||
C_df_ilb(l_end);
|
||||
}
|
||||
else {
|
||||
if (! true_label) C_df_ilb(l_false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "declar.h"
|
||||
#include "sizes.h"
|
||||
#include "level.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char *symbol2str();
|
||||
extern char options[];
|
||||
|
@ -94,6 +95,7 @@ rank_of(oper)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
#ifndef NOROPTION
|
||||
int
|
||||
rank_of_expression(ex)
|
||||
register struct expr *ex;
|
||||
|
@ -117,6 +119,7 @@ check_conditional(expr, oper, pos_descr)
|
|||
expr_warning(expr, "%s %s is ungrammatical",
|
||||
symbol2str(expr->OP_OPER), pos_descr);
|
||||
}
|
||||
#endif
|
||||
|
||||
dot2expr(expp)
|
||||
struct expr **expp;
|
||||
|
@ -396,6 +399,7 @@ chk_cst_expr(expp)
|
|||
else
|
||||
if (!is_ld_cst(expr))
|
||||
expr_error(expr, "expression is not constant"), err++;
|
||||
#ifndef NOROPTION
|
||||
if (options['R']) {
|
||||
if (flags & EX_CAST)
|
||||
expr_warning(expr, "cast in constant expression");
|
||||
|
@ -406,6 +410,7 @@ chk_cst_expr(expp)
|
|||
expr_warning(expr,
|
||||
"expression comma in constant expression");
|
||||
}
|
||||
#endif NOROPTION
|
||||
if (err)
|
||||
erroneous2int(expp);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* EXPRESSION DESCRIPTOR */
|
||||
|
||||
|
@ -101,6 +105,6 @@ struct expr {
|
|||
|
||||
extern struct expr *intexpr(), *new_oper();
|
||||
|
||||
/* ALLOCDEF "expr" 50 */
|
||||
/* ALLOCDEF "expr" 20 */
|
||||
|
||||
#define ISCOMMA(e) ((e)->ex_class == Oper && (e)->OP_OPER == INITCOMMA)
|
||||
|
|
|
@ -12,43 +12,12 @@
|
|||
#include "idf.h"
|
||||
#include "label.h"
|
||||
#include "expr.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char options[];
|
||||
extern struct expr *intexpr();
|
||||
}
|
||||
|
||||
/* 7 */
|
||||
initial_value(struct expr **expp;) :
|
||||
assignment_expression(expp)
|
||||
{
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY)
|
||||
array2pointer(expp);
|
||||
}
|
||||
|
|
||||
initial_value_pack(expp)
|
||||
;
|
||||
|
||||
initial_value_pack(struct expr **expp;) :
|
||||
'{'
|
||||
initial_value_list(expp)
|
||||
'}'
|
||||
;
|
||||
|
||||
initial_value_list(struct expr **expp;)
|
||||
{struct expr *e1;}
|
||||
:
|
||||
{*expp = NILEXPR;}
|
||||
initial_value(&e1)
|
||||
{init_expression(&expp, e1);}
|
||||
[%while (AHEAD != '}') /* >>> conflict on ',' */
|
||||
','
|
||||
initial_value(&e1)
|
||||
{init_expression(&expp, e1);}
|
||||
]*
|
||||
','? /* optional trailing comma */
|
||||
;
|
||||
|
||||
|
||||
/* 7.1 */
|
||||
primary(register struct expr **expp;) :
|
||||
IDENTIFIER
|
||||
|
@ -224,11 +193,17 @@ conditional_expression(struct expr **expp;)
|
|||
binary_expression(rank_of('?') - 1, expp)
|
||||
[ '?'
|
||||
expression(&e1)
|
||||
{check_conditional(e1, '?', "between ? and :");}
|
||||
{
|
||||
#ifndef NOROPTION
|
||||
check_conditional(e1, '?', "between ? and :");
|
||||
#endif
|
||||
}
|
||||
':'
|
||||
assignment_expression(&e2)
|
||||
{check_conditional(e2, '=', "after :");}
|
||||
{
|
||||
{
|
||||
#ifndef NOROPTION
|
||||
check_conditional(e2, '=', "after :");
|
||||
#endif
|
||||
ch7bin(&e1, ':', e2);
|
||||
opnd2test(expp, '?');
|
||||
ch7bin(expp, '?', e1);
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* FIELD DESCRIPTOR */
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Lpars.h"
|
||||
#include "assert.h"
|
||||
#include "specials.h" /* registration of special identifiers */
|
||||
#include "noRoption.h"
|
||||
|
||||
int idfsize = IDFSIZE;
|
||||
extern char options[];
|
||||
|
@ -252,6 +253,7 @@ declare_idf(ds, dc, lvl)
|
|||
sc = lvl == L_GLOBAL ? GLOBAL
|
||||
: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
|
||||
: AUTO;
|
||||
#ifndef NOROPTION
|
||||
if (options['R']) { /* some special K & R tests */
|
||||
/* is it also an enum? */
|
||||
if (idf->id_enum && idf->id_enum->tg_level == level)
|
||||
|
@ -260,6 +262,7 @@ declare_idf(ds, dc, lvl)
|
|||
if (def && def->df_level == L_UNIVERSAL)
|
||||
warning("redeclaring reserved word %s", idf->id_text);
|
||||
}
|
||||
#endif
|
||||
if (def && def->df_level >= lvl) {
|
||||
/* There is already a declaration for idf on this
|
||||
level, or even more inside.
|
||||
|
@ -294,12 +297,14 @@ declare_idf(ds, dc, lvl)
|
|||
/* extern declaration inside function is treated the
|
||||
same way as global extern declaration
|
||||
*/
|
||||
#ifndef NOROPTION
|
||||
if ( options['R'] &&
|
||||
(sc == STATIC && type->tp_fund == FUNCTION)
|
||||
)
|
||||
if (!is_anon_idf(idf))
|
||||
warning("non-global static function %s",
|
||||
idf->id_text);
|
||||
#endif
|
||||
declare_idf(ds, dc, L_GLOBAL);
|
||||
}
|
||||
else { /* fill in the def block */
|
||||
|
@ -447,9 +452,11 @@ global_redecl(idf, new_sc, tp)
|
|||
error("cannot redeclare %s to static",
|
||||
idf->id_text);
|
||||
else {
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("%s redeclared to static",
|
||||
idf->id_text);
|
||||
#endif
|
||||
def->df_sc = STATIC;
|
||||
}
|
||||
break;
|
||||
|
@ -488,9 +495,11 @@ global_redecl(idf, new_sc, tp)
|
|||
def->df_sc = new_sc;
|
||||
break;
|
||||
case STATIC:
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("%s was implicitly declared as extern",
|
||||
idf->id_text);
|
||||
#endif
|
||||
def->df_sc = new_sc;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* IDENTIFIER DESCRIPTOR */
|
||||
|
||||
|
|
|
@ -29,14 +29,13 @@ getwdir(fn)
|
|||
|
||||
if (fn[0] == '\0' || (fn[0] == '/' && p == &fn[0])) /* absolute path */
|
||||
return "";
|
||||
else
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
fn = Salloc(fn, p - &fn[0] + 1);
|
||||
*p = '/';
|
||||
return fn;
|
||||
}
|
||||
else return ".";
|
||||
return ".";
|
||||
}
|
||||
#endif NOPP
|
||||
|
||||
|
|
656
lang/cem/cemcom/ival.g
Normal file
656
lang/cem/cemcom/ival.g
Normal file
|
@ -0,0 +1,656 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */
|
||||
|
||||
{
|
||||
#include "nofloat.h"
|
||||
#include <em.h>
|
||||
#include "debug.h"
|
||||
#include <alloc.h>
|
||||
#include "nobitfield.h"
|
||||
#include "arith.h"
|
||||
#include "align.h"
|
||||
#include "label.h"
|
||||
#include "expr.h"
|
||||
#include "type.h"
|
||||
#include "struct.h"
|
||||
#include "field.h"
|
||||
#include "assert.h"
|
||||
#include "Lpars.h"
|
||||
#include "class.h"
|
||||
#include "sizes.h"
|
||||
#include "idf.h"
|
||||
#include "level.h"
|
||||
#include "def.h"
|
||||
#include "LLlex.h"
|
||||
#include "noRoption.h"
|
||||
#include "estack.h"
|
||||
|
||||
#define con_nullbyte() C_con_ucon("0", (arith)1)
|
||||
#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)
|
||||
|
||||
char *long2str();
|
||||
char *strncpy();
|
||||
extern char options[];
|
||||
static int gen_error;
|
||||
struct type **gen_tphead(), **gen_tpmiddle();
|
||||
struct sdef *gen_align_to_next();
|
||||
}
|
||||
|
||||
/* initial_value recursively guides the initialisation expression.
|
||||
Upto now, the initialisation of a union is not allowed!
|
||||
*/
|
||||
/* 7 */
|
||||
initial_value(register struct type **tpp; register struct expr **expp;) :
|
||||
{ if (tpp) gen_tpcheck(tpp, 0); }
|
||||
[
|
||||
assignment_expression(expp)
|
||||
{ if ((*expp)->ex_type->tp_fund == ARRAY)
|
||||
array2pointer(*expp);
|
||||
if (tpp) {
|
||||
gen_simple_exp(tpp, expp);
|
||||
free_expression(*expp);
|
||||
*expp = 0;
|
||||
}
|
||||
}
|
||||
|
|
||||
initial_value_pack(tpp, expp)
|
||||
]
|
||||
;
|
||||
|
||||
initial_value_pack(struct type **tpp; struct expr **expp;) :
|
||||
'{'
|
||||
initial_value_list(tpp, expp)
|
||||
'}'
|
||||
;
|
||||
|
||||
initial_value_list(register struct type *tpp; struct expr **expp;)
|
||||
{ struct expr *e1;
|
||||
register struct type **tpp2 = 0;
|
||||
}
|
||||
:
|
||||
{ if (tpp) tpp2 = gen_tphead(tpp, 0); }
|
||||
initial_value(tpp2, &e1)
|
||||
{ if (!tpp) init_expression(&expp, e1); }
|
||||
[%while (AHEAD != '}') /* >>> conflict on ',' */
|
||||
','
|
||||
{ if (tpp) tpp2 = gen_tpmiddle(); }
|
||||
initial_value(tpp2, &e1)
|
||||
{ if (!tpp) init_expression(&expp, e1); }
|
||||
]*
|
||||
{ if (tpp) gen_tpend(); }
|
||||
','? /* optional trailing comma */
|
||||
;
|
||||
|
||||
{
|
||||
gen_tpcheck(tpp, union_allowed)
|
||||
struct type **tpp;
|
||||
{
|
||||
register struct type *tp;
|
||||
|
||||
if (gen_error) return;
|
||||
switch((tp = *tpp)->tp_fund) {
|
||||
case ARRAY:
|
||||
if (! valid_type(tp->tp_up, "array element"))
|
||||
gen_error = 1;
|
||||
break;
|
||||
case STRUCT:
|
||||
if (! valid_type(tp, "struct"))
|
||||
gen_error = 1;
|
||||
break;
|
||||
case UNION:
|
||||
if (! union_allowed) {
|
||||
error("union initialisation not allowed");
|
||||
gen_error = 1;
|
||||
break;
|
||||
}
|
||||
if (! valid_type(tp, "union"))
|
||||
gen_error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gen_simple_exp(tpp, expp)
|
||||
struct type **tpp;
|
||||
struct expr **expp;
|
||||
{
|
||||
register struct type *tp;
|
||||
|
||||
if (gen_error) return;
|
||||
tp = *tpp;
|
||||
switch(tp->tp_fund) {
|
||||
case ARRAY:
|
||||
if ((*expp)->ex_class == String && tp->tp_up->tp_fund == CHAR) {
|
||||
ch_array(tpp,*expp);
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case STRUCT:
|
||||
check_and_pad(expp, tpp);
|
||||
break;
|
||||
case ERRONEOUS:
|
||||
gen_error = 1;
|
||||
break;
|
||||
default:
|
||||
check_ival(expp, tp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct e_stack *p_stack;
|
||||
|
||||
struct type **
|
||||
arr_elem(tpp, p)
|
||||
struct type **tpp;
|
||||
struct e_stack *p;
|
||||
{
|
||||
register struct type *tp = *tpp;
|
||||
|
||||
if (tp->tp_up->tp_fund == CHAR && AHEAD == STRING && p->elem_count == 1) {
|
||||
p->nelem = 1;
|
||||
return tpp;
|
||||
}
|
||||
if (AHEAD == '{' || ! aggregate_type(tp->tp_up))
|
||||
return &(tp->tp_up);
|
||||
return gen_tphead(&(tp->tp_up), 1);
|
||||
}
|
||||
|
||||
struct sdef *
|
||||
next_field(sd, p)
|
||||
register struct sdef *sd;
|
||||
register struct e_stack *p;
|
||||
{
|
||||
if (sd->sd_sdef)
|
||||
p->bytes_upto_here += zero_bytes(sd);
|
||||
if (p->last_offset != sd->sd_offset) {
|
||||
p->bytes_upto_here +=
|
||||
size_of_type(sd->sd_type, "selector");
|
||||
p->last_offset = sd->sd_offset;
|
||||
}
|
||||
return sd->sd_sdef;
|
||||
}
|
||||
|
||||
struct type **
|
||||
gen_tphead(tpp, nest)
|
||||
struct type **tpp;
|
||||
{
|
||||
register struct type *tp = *tpp;
|
||||
register struct e_stack *p = new_e_stack();
|
||||
register struct sdef *sd;
|
||||
|
||||
if (gen_error) return tpp;
|
||||
p->next = p_stack;
|
||||
p_stack = p;
|
||||
p->s_nested = nest;
|
||||
p->s_tpp = tpp;
|
||||
switch(tp->tp_fund) {
|
||||
case ARRAY:
|
||||
p->nelem = -1;
|
||||
p->elem_count = 1;
|
||||
if (tp->tp_size != (arith) -1) {
|
||||
p->nelem = (tp->tp_size / tp->tp_up->tp_size);
|
||||
}
|
||||
return arr_elem(tpp, p);
|
||||
case STRUCT:
|
||||
p->s_def = sd = tp->tp_sdef;
|
||||
p->bytes_upto_here = 0;
|
||||
p->last_offset = -1;
|
||||
#ifndef NOBITFIELD
|
||||
while (sd && is_anon_idf(sd->sd_idf)) {
|
||||
put_bf(sd->sd_type, (arith) 0);
|
||||
sd = next_field(sd, p);
|
||||
}
|
||||
#endif
|
||||
p->s_def = sd;
|
||||
if (AHEAD != '{' && aggregate_type(sd->sd_type)) {
|
||||
return gen_tphead(&(sd->sd_type), 1);
|
||||
}
|
||||
return &(sd->sd_type);
|
||||
default:
|
||||
p->nelem = 1;
|
||||
p->elem_count = 1;
|
||||
return tpp;
|
||||
}
|
||||
}
|
||||
|
||||
struct type **
|
||||
gen_tpmiddle()
|
||||
{
|
||||
register struct type *tp;
|
||||
register struct sdef *sd;
|
||||
register struct e_stack *p = p_stack;
|
||||
|
||||
if (gen_error) return p->s_tpp;
|
||||
again:
|
||||
tp = *(p->s_tpp);
|
||||
switch(tp->tp_fund) {
|
||||
default:
|
||||
if (p->elem_count == p->nelem && p->s_nested) {
|
||||
p = p->next;
|
||||
free_e_stack(p_stack);
|
||||
p_stack = p;
|
||||
goto again;
|
||||
}
|
||||
p->elem_count++;
|
||||
if (p->nelem >= 0 && p->elem_count > p->nelem) {
|
||||
too_many_initialisers();
|
||||
return p->s_tpp;
|
||||
}
|
||||
if (tp->tp_fund == ARRAY) {
|
||||
return arr_elem(p->s_tpp, p);
|
||||
}
|
||||
return p->s_tpp;
|
||||
case STRUCT:
|
||||
sd = gen_align_to_next(p);
|
||||
if (! sd) {
|
||||
while (p->bytes_upto_here++ < tp->tp_size)
|
||||
con_nullbyte();
|
||||
if (p->s_nested) {
|
||||
p = p->next;
|
||||
free_e_stack(p_stack);
|
||||
p_stack = p;
|
||||
goto again;
|
||||
}
|
||||
too_many_initialisers();
|
||||
return p->s_tpp;
|
||||
}
|
||||
if (AHEAD != '{' && aggregate_type(sd->sd_type)) {
|
||||
return gen_tphead(&(sd->sd_type), 1);
|
||||
}
|
||||
return &(sd->sd_type);
|
||||
}
|
||||
}
|
||||
|
||||
struct sdef *
|
||||
gen_align_to_next(p)
|
||||
register struct e_stack *p;
|
||||
{
|
||||
register struct sdef *sd = p->s_def;
|
||||
|
||||
if (! sd) return sd;
|
||||
#ifndef NOBITFIELD
|
||||
do {
|
||||
if (is_anon_idf(sd->sd_idf)) put_bf(sd->sd_type, (arith) 0);
|
||||
#endif
|
||||
sd = next_field(sd, p);
|
||||
#ifndef NOBITFIELD
|
||||
} while (sd && is_anon_idf(sd->sd_idf));
|
||||
#endif
|
||||
p->s_def = sd;
|
||||
return sd;
|
||||
}
|
||||
|
||||
gen_tpend()
|
||||
{
|
||||
register struct e_stack *p = p_stack;
|
||||
register struct type *tp;
|
||||
register struct sdef *sd;
|
||||
int getout = 0;
|
||||
|
||||
while (!getout) {
|
||||
if (!gen_error) {
|
||||
tp = *(p->s_tpp);
|
||||
switch(tp->tp_fund) {
|
||||
case ARRAY:
|
||||
if (tp->tp_size == -1) {
|
||||
*(p->s_tpp) = construct_type(ARRAY,
|
||||
tp->tp_up, p->elem_count);
|
||||
}
|
||||
else {
|
||||
while (p->nelem-- > p->elem_count) {
|
||||
pad(tp->tp_up);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STRUCT:
|
||||
sd = gen_align_to_next(p);
|
||||
while (sd) {
|
||||
pad(sd->sd_type);
|
||||
if (sd->sd_sdef)
|
||||
p->bytes_upto_here += zero_bytes(sd);
|
||||
p->bytes_upto_here +=
|
||||
size_of_type(sd->sd_type, "selector");
|
||||
sd = sd->sd_sdef;
|
||||
}
|
||||
while (p->bytes_upto_here++ < tp->tp_size)
|
||||
con_nullbyte();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! p->s_nested) getout = 1;
|
||||
p = p->next;
|
||||
free_e_stack(p_stack);
|
||||
p_stack = p;
|
||||
}
|
||||
gen_error = 0;
|
||||
}
|
||||
|
||||
/* check_and_pad() is given a simple initialisation expression
|
||||
where the type can be either a simple or an aggregate type.
|
||||
In the latter case, only the first member is initialised and
|
||||
the rest is zeroed.
|
||||
*/
|
||||
check_and_pad(expp, tpp)
|
||||
struct type **tpp;
|
||||
struct expr **expp;
|
||||
{
|
||||
/* ex is of a fundamental type */
|
||||
register struct type *tp = *tpp;
|
||||
register struct expr *ex = *expp;
|
||||
|
||||
if (tp->tp_fund == ARRAY) {
|
||||
check_and_pad(expp, &(tp->tp_up)); /* first member */
|
||||
if (tp->tp_size == (arith)-1)
|
||||
/* no size specified upto here: just
|
||||
set it to the size of one member.
|
||||
*/
|
||||
tp = *tpp = construct_type(ARRAY, tp->tp_up, (arith)1);
|
||||
else {
|
||||
register int dim = tp->tp_size / tp->tp_up->tp_size;
|
||||
/* pad remaining members with zeroes */
|
||||
while (--dim > 0)
|
||||
pad(tp->tp_up);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (tp->tp_fund == STRUCT) {
|
||||
register struct sdef *sd = tp->tp_sdef;
|
||||
|
||||
check_and_pad(expp, &(sd->sd_type));
|
||||
/* next selector is aligned by adding extra zeroes */
|
||||
if (sd->sd_sdef)
|
||||
zero_bytes(sd);
|
||||
while (sd = sd->sd_sdef) { /* pad remaining selectors */
|
||||
pad(sd->sd_type);
|
||||
if (sd->sd_sdef)
|
||||
zero_bytes(sd);
|
||||
}
|
||||
}
|
||||
else /* simple type */
|
||||
check_ival(expp, tp);
|
||||
}
|
||||
|
||||
/* pad() fills an element of type tp with zeroes.
|
||||
If the element is an aggregate, pad() is called recursively.
|
||||
*/
|
||||
pad(tpx)
|
||||
struct type *tpx;
|
||||
{
|
||||
register struct type *tp = tpx;
|
||||
register arith sz = tp->tp_size;
|
||||
|
||||
gen_tpcheck(&tpx, 1);
|
||||
if (gen_error) return;
|
||||
switch (tp->tp_fund) {
|
||||
case UNION:
|
||||
#ifndef NOROPTION
|
||||
if (options['R']) {
|
||||
warning("initialisation of unions not allowed");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#ifndef NOBITFIELD
|
||||
case FIELD:
|
||||
put_bf(tp, (arith)0);
|
||||
return;
|
||||
#endif NOBITFIELD
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
while (sz >= word_size) {
|
||||
C_con_cst((arith) 0);
|
||||
sz -= word_size;
|
||||
}
|
||||
while (sz) {
|
||||
C_con_icon("0", (arith) 1);
|
||||
sz--;
|
||||
}
|
||||
}
|
||||
|
||||
/* check_ival() checks whether the initialisation of an element
|
||||
of a fundamental type is legal and, if so, performs the initialisation
|
||||
by directly generating the necessary code.
|
||||
No further comment is needed to explain the internal structure
|
||||
of this straightforward function.
|
||||
*/
|
||||
check_ival(expp, tp)
|
||||
register struct type *tp;
|
||||
struct expr **expp;
|
||||
{
|
||||
/* The philosophy here is that ch7cast puts an explicit
|
||||
conversion node in front of the expression if the types
|
||||
are not compatible. In this case, the initialisation
|
||||
expression is no longer a constant.
|
||||
*/
|
||||
register struct expr *expr = *expp;
|
||||
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
case SHORT:
|
||||
case INT:
|
||||
case LONG:
|
||||
case ENUM:
|
||||
case POINTER:
|
||||
ch7cast(expp, '=', tp);
|
||||
expr = *expp;
|
||||
#ifdef DEBUG
|
||||
print_expr("init-expr after cast", expr);
|
||||
#endif DEBUG
|
||||
if (!is_ld_cst(expr))
|
||||
illegal_init_cst(expr);
|
||||
else
|
||||
if (expr->VL_CLASS == Const)
|
||||
con_int(expr);
|
||||
else
|
||||
if (expr->VL_CLASS == Name) {
|
||||
register struct idf *idf = expr->VL_IDF;
|
||||
|
||||
if (idf->id_def->df_level >= L_LOCAL)
|
||||
illegal_init_cst(expr);
|
||||
else /* e.g., int f(); int p = f; */
|
||||
if (idf->id_def->df_type->tp_fund == FUNCTION)
|
||||
C_con_pnam(idf->id_text);
|
||||
else /* e.g., int a; int *p = &a; */
|
||||
C_con_dnam(idf->id_text, expr->VL_VALUE);
|
||||
}
|
||||
else {
|
||||
ASSERT(expr->VL_CLASS == Label);
|
||||
C_con_dlb(expr->VL_LBL, expr->VL_VALUE);
|
||||
}
|
||||
break;
|
||||
#ifndef NOFLOAT
|
||||
case FLOAT:
|
||||
case DOUBLE:
|
||||
ch7cast(expp, '=', tp);
|
||||
expr = *expp;
|
||||
#ifdef DEBUG
|
||||
print_expr("init-expr after cast", expr);
|
||||
#endif DEBUG
|
||||
if (expr->ex_class == Float)
|
||||
C_con_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
|
||||
else
|
||||
if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) {
|
||||
/* float f = 1; */
|
||||
expr = expr->OP_RIGHT;
|
||||
if (is_cp_cst(expr))
|
||||
C_con_fcon(long2str((long)expr->VL_VALUE, 10),
|
||||
tp->tp_size);
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
}
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
break;
|
||||
#endif NOFLOAT
|
||||
|
||||
#ifndef NOBITFIELD
|
||||
case FIELD:
|
||||
ch7cast(expp, '=', tp->tp_up);
|
||||
expr = *expp;
|
||||
#ifdef DEBUG
|
||||
print_expr("init-expr after cast", expr);
|
||||
#endif DEBUG
|
||||
if (is_cp_cst(expr))
|
||||
put_bf(tp, expr->VL_VALUE);
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
break;
|
||||
#endif NOBITFIELD
|
||||
|
||||
case ERRONEOUS:
|
||||
break;
|
||||
default:
|
||||
crash("check_ival");
|
||||
}
|
||||
}
|
||||
|
||||
/* ch_array() initialises an array of characters when given
|
||||
a string constant.
|
||||
Alignment is taken care of.
|
||||
*/
|
||||
ch_array(tpp, ex)
|
||||
struct type **tpp; /* type tp = array of characters */
|
||||
struct expr *ex;
|
||||
{
|
||||
register struct type *tp = *tpp;
|
||||
register arith length = ex->SG_LEN;
|
||||
char *s;
|
||||
arith ntopad;
|
||||
|
||||
ASSERT(ex->ex_class == String);
|
||||
if (tp->tp_size == (arith)-1) {
|
||||
/* set the dimension */
|
||||
tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
|
||||
ntopad = align(tp->tp_size, word_size) - tp->tp_size;
|
||||
}
|
||||
else {
|
||||
arith dim = tp->tp_size / tp->tp_up->tp_size;
|
||||
extern char options[];
|
||||
|
||||
if (length > dim) {
|
||||
expr_warning(ex, "too many initialisers");
|
||||
length = dim;
|
||||
}
|
||||
ntopad = align(dim, word_size) - length;
|
||||
}
|
||||
/* throw out the characters of the already prepared string */
|
||||
s = Malloc((unsigned) (length + ntopad));
|
||||
clear(s, (int) (length + ntopad));
|
||||
strncpy(s, ex->SG_VALUE, (int) length);
|
||||
free(ex->SG_VALUE);
|
||||
str_cst(s, (int) (length + ntopad));
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* As long as some parts of the pipeline cannot handle very long string
|
||||
constants, string constants are written out in chunks
|
||||
*/
|
||||
str_cst(str, len)
|
||||
register char *str;
|
||||
register int len;
|
||||
{
|
||||
arith chunksize = ((127 + word_size) / word_size) * word_size;
|
||||
|
||||
while (len > chunksize) {
|
||||
C_con_scon(str, chunksize);
|
||||
len -= chunksize;
|
||||
str += chunksize;
|
||||
}
|
||||
C_con_scon(str, (arith) len);
|
||||
}
|
||||
|
||||
#ifndef NOBITFIELD
|
||||
/* put_bf() takes care of the initialisation of (bit-)field
|
||||
selectors of a struct: each time such an initialisation takes place,
|
||||
put_bf() is called instead of the normal code generating routines.
|
||||
Put_bf() stores the given integral value into "field" and
|
||||
"throws" the result of "field" out if the current selector
|
||||
is the last of this number of fields stored at the same address.
|
||||
*/
|
||||
put_bf(tp, val)
|
||||
struct type *tp;
|
||||
arith val;
|
||||
{
|
||||
static long field = (arith)0;
|
||||
static arith offset = (arith)-1;
|
||||
register struct field *fd = tp->tp_field;
|
||||
register struct sdef *sd = fd->fd_sdef;
|
||||
static struct expr exp;
|
||||
|
||||
ASSERT(sd);
|
||||
if (offset == (arith)-1) {
|
||||
/* first bitfield in this field */
|
||||
offset = sd->sd_offset;
|
||||
exp.ex_type = tp->tp_up;
|
||||
exp.ex_class = Value;
|
||||
exp.VL_CLASS = Const;
|
||||
}
|
||||
if (val != 0) /* insert the value into "field" */
|
||||
field |= (val & fd->fd_mask) << fd->fd_shift;
|
||||
if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) {
|
||||
/* the selector was the last stored at this address */
|
||||
exp.VL_VALUE = field;
|
||||
con_int(&exp);
|
||||
field = (arith)0;
|
||||
offset = (arith)-1;
|
||||
}
|
||||
}
|
||||
#endif NOBITFIELD
|
||||
|
||||
int
|
||||
zero_bytes(sd)
|
||||
register struct sdef *sd;
|
||||
{
|
||||
/* fills the space between a selector of a struct
|
||||
and the next selector of that struct with zero-bytes.
|
||||
*/
|
||||
register int n = sd->sd_sdef->sd_offset - sd->sd_offset -
|
||||
size_of_type(sd->sd_type, "struct member");
|
||||
register int count = n;
|
||||
|
||||
while (n-- > 0)
|
||||
con_nullbyte();
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
valid_type(tp, str)
|
||||
struct type *tp;
|
||||
char *str;
|
||||
{
|
||||
if (tp->tp_size < 0) {
|
||||
error("size of %s unknown", str);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
con_int(ex)
|
||||
register struct expr *ex;
|
||||
{
|
||||
register struct type *tp = ex->ex_type;
|
||||
|
||||
ASSERT(is_cp_cst(ex));
|
||||
if (tp->tp_unsigned)
|
||||
C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size);
|
||||
else
|
||||
C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);
|
||||
}
|
||||
|
||||
illegal_init_cst(ex)
|
||||
struct expr *ex;
|
||||
{
|
||||
expr_error(ex, "illegal initialisation constant");
|
||||
gen_error = 1;
|
||||
}
|
||||
|
||||
too_many_initialisers()
|
||||
{
|
||||
error("too many initialisers");
|
||||
gen_error = 1;
|
||||
}
|
||||
}
|
|
@ -12,29 +12,10 @@
|
|||
#include "arith.h"
|
||||
#include "def.h"
|
||||
#include "type.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char options[];
|
||||
|
||||
define_label(idf)
|
||||
struct idf *idf;
|
||||
{
|
||||
/* The identifier idf is defined as a label. If it is new,
|
||||
it is entered into the idf list with the largest possible
|
||||
scope, i.e., on the lowest possible level.
|
||||
*/
|
||||
enter_label(idf, 1);
|
||||
}
|
||||
|
||||
apply_label(idf)
|
||||
struct idf *idf;
|
||||
{
|
||||
/* The identifier idf is applied as a label. It may or may
|
||||
not be there, and if it is there, it may be from a
|
||||
declaration or another application.
|
||||
*/
|
||||
enter_label(idf, 0);
|
||||
}
|
||||
|
||||
enter_label(idf, defining)
|
||||
register struct idf *idf;
|
||||
{
|
||||
|
@ -52,21 +33,22 @@ enter_label(idf, defining)
|
|||
idf->id_text);
|
||||
}
|
||||
else { /* there may still be room for it */
|
||||
int deflevel = def->df_level;
|
||||
|
||||
#ifndef NOROPTION
|
||||
if (options['R'] && def->df_sc == TYPEDEF)
|
||||
warning("label %s is also a typedef",
|
||||
idf->id_text);
|
||||
#endif
|
||||
|
||||
if (deflevel == level) /* but alas, no */
|
||||
if (def->df_level == level) /* but alas, no */
|
||||
error("%s is not a label", idf->id_text);
|
||||
else {
|
||||
int lvl;
|
||||
register int lvl = def->df_level + 1;
|
||||
|
||||
if (options['R'] && deflevel > L_LOCAL)
|
||||
#ifndef NOROPTION
|
||||
if (options['R'] && def->df_level > L_LOCAL)
|
||||
warning("label %s is not function-wide",
|
||||
idf->id_text);
|
||||
lvl = deflevel + 1;
|
||||
#endif
|
||||
if (lvl < L_LOCAL)
|
||||
lvl = L_LOCAL;
|
||||
add_def(idf, LABEL, label_type, lvl);
|
||||
|
|
|
@ -14,3 +14,15 @@ extern label lab_count;
|
|||
|
||||
extern label datlab_count;
|
||||
#define data_label() (datlab_count++) /* returns a new data label */
|
||||
|
||||
#define define_label(idf) enter_label(idf, 1);
|
||||
/* The identifier idf is defined as a label. If it is new,
|
||||
it is entered into the idf list with the largest possible
|
||||
scope, i.e., on the lowest possible level.
|
||||
*/
|
||||
|
||||
#define apply_label(idf) enter_label(idf, 0);
|
||||
/* The identifier idf is applied as a label. It may or may
|
||||
not be there, and if it is there, it may be from a
|
||||
declaration or another application.
|
||||
*/
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* PREPROCESSOR: DEFINITION OF MACRO DESCRIPTOR */
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include "LLlex.h"
|
||||
#include <alloc.h>
|
||||
#include "specials.h"
|
||||
#include "noRoption.h"
|
||||
#include "nocross.h"
|
||||
#include "sizes.h"
|
||||
#include "align.h"
|
||||
|
||||
extern struct tokenname tkidf[], tkother[];
|
||||
extern char *symbol2str();
|
||||
|
@ -45,6 +49,7 @@ struct sp_id special_ids[] = {
|
|||
{0, 0}
|
||||
};
|
||||
|
||||
#ifndef NOCROSS
|
||||
arith
|
||||
short_size = SZ_SHORT,
|
||||
word_size = SZ_WORD,
|
||||
|
@ -69,6 +74,7 @@ int
|
|||
pointer_align = AL_POINTER,
|
||||
struct_align = AL_STRUCT,
|
||||
union_align = AL_UNION;
|
||||
#endif NOCROSS
|
||||
|
||||
#ifndef NOPP
|
||||
arith ifval; /* ifval will contain the result of the #if expression */
|
||||
|
@ -232,8 +238,10 @@ init()
|
|||
reserve(tkidf); /* mark the C reserved words as such */
|
||||
init_specials(special_ids); /* mark special ids as such */
|
||||
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
reserve(tkother);
|
||||
#endif
|
||||
|
||||
char_type = standard_type(CHAR, 0, 1, (arith)1);
|
||||
uchar_type = standard_type(CHAR, UNSIGNED, 1, (arith)1);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "align.h"
|
||||
#include "use_tmp.h"
|
||||
#include "dataflow.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
#ifndef NOPP
|
||||
extern char *inctable[MAXINCL];
|
||||
|
@ -53,9 +54,16 @@ do_option(text)
|
|||
case 'L' : /* no fil/lin */
|
||||
case 'n': /* use no registers */
|
||||
case 'w': /* no warnings will be given */
|
||||
#ifndef NOROPTION
|
||||
case 'R': /* strict version */
|
||||
#endif
|
||||
options[*(text-1)] = 1;
|
||||
break;
|
||||
#ifdef NOROPTION
|
||||
case 'R':
|
||||
warning("-R option not implemented");
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ___XXX___
|
||||
deleted, is now a debug-flag
|
||||
|
@ -118,11 +126,11 @@ deleted, is now a debug-flag
|
|||
case 'I' : /* -Ipath : insert "path" into include list */
|
||||
#ifndef NOPP
|
||||
if (*text) {
|
||||
register int i = inc_pos++;
|
||||
int i = inc_pos++;
|
||||
register char *new = text;
|
||||
|
||||
while (new) {
|
||||
register char *tmp = inctable[i];
|
||||
char *tmp = inctable[i];
|
||||
|
||||
inctable[i++] = new;
|
||||
if (i == MAXINCL)
|
||||
|
@ -176,7 +184,7 @@ deleted, is now a debug-flag
|
|||
|
||||
case 'U' : { /* -Uname : undefine predefined */
|
||||
#ifndef NOPP
|
||||
struct idf *idef;
|
||||
register struct idf *idef;
|
||||
|
||||
if (*text) {
|
||||
if ((idef = str2idf(text))->id_macro) {
|
||||
|
@ -191,8 +199,12 @@ deleted, is now a debug-flag
|
|||
}
|
||||
|
||||
case 'V' : /* set object sizes and alignment requirements */
|
||||
#ifdef NOCROSS
|
||||
warning("-V option ignored");
|
||||
break;
|
||||
#else NOCROSS
|
||||
{
|
||||
arith size, align;
|
||||
register arith size, align;
|
||||
char c;
|
||||
|
||||
while (c = *text++) {
|
||||
|
@ -270,12 +282,13 @@ deleted, is now a debug-flag
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif NOCROSS
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
txt2int(tp)
|
||||
char **tp;
|
||||
register char **tp;
|
||||
{
|
||||
/* the integer pointed to by *tp is read, while increasing
|
||||
*tp; the resulting value is yielded.
|
||||
|
|
|
@ -148,15 +148,13 @@ ext_decl_specifiers(struct decspecs *ds;) :
|
|||
;
|
||||
|
||||
non_function(register struct decspecs *ds; register struct declarator *dc;)
|
||||
{
|
||||
struct expr *expr = (struct expr *) 0;
|
||||
}
|
||||
:
|
||||
{reject_params(dc);}
|
||||
initializer(dc->dc_idf, &expr)?
|
||||
{
|
||||
code_declaration(dc->dc_idf, expr, level, ds->ds_sc);
|
||||
}
|
||||
[
|
||||
initializer(dc->dc_idf, ds->ds_sc)
|
||||
|
|
||||
{ code_declaration(dc->dc_idf, (struct excpr *) 0, level, ds->ds_sc); }
|
||||
]
|
||||
[
|
||||
','
|
||||
init_declarator(ds)
|
||||
|
|
|
@ -6,12 +6,27 @@
|
|||
/* VARIOUS TARGET MACHINE SIZE DESCRIPTORS */
|
||||
|
||||
#include "nofloat.h"
|
||||
#include "nocross.h"
|
||||
#include "target_sizes.h"
|
||||
|
||||
#ifndef NOCROSS
|
||||
extern arith
|
||||
short_size, word_size, dword_size, int_size, long_size,
|
||||
#ifndef NOFLOAT
|
||||
float_size, double_size,
|
||||
#endif NOFLOAT
|
||||
pointer_size;
|
||||
#else NOCROSS
|
||||
#define short_size (SZ_SHORT)
|
||||
#define word_size (SZ_WORD)
|
||||
#define dword_size (2*SZ_WORD)
|
||||
#define int_size (SZ_INT)
|
||||
#define long_size (SZ_LONG)
|
||||
#ifndef NOFLOAT
|
||||
#define float_size (SZ_FLOAT)
|
||||
#define double_size (SZ_DOUBLE)
|
||||
#endif NOFLOAT
|
||||
#define pointer_size (SZ_POINTER)
|
||||
#endif NOCROSS
|
||||
|
||||
extern arith max_int, max_unsigned; /* cstoper.c */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "struct.h"
|
||||
#include "level.h"
|
||||
#include "mes.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
/* #include <em_reg.h> */
|
||||
|
||||
|
@ -75,16 +76,15 @@ stack_level_of(lvl)
|
|||
The stack should probably be an array, to be extended with
|
||||
realloc where needed.
|
||||
*/
|
||||
register struct stack_level *stl;
|
||||
|
||||
if (lvl == level)
|
||||
return local_level;
|
||||
else {
|
||||
register struct stack_level *stl = &UniversalLevel;
|
||||
stl = &UniversalLevel;
|
||||
|
||||
while (stl->sl_level != lvl)
|
||||
stl = stl->sl_next;
|
||||
return stl;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
while (stl->sl_level != lvl)
|
||||
stl = stl->sl_next;
|
||||
return stl;
|
||||
}
|
||||
|
||||
unstack_level()
|
||||
|
@ -238,11 +238,13 @@ unstack_world()
|
|||
&& !def->df_initialized
|
||||
) {
|
||||
/* orphaned static function */
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("static function %s never defined, %s",
|
||||
idf->id_text,
|
||||
"changed to extern"
|
||||
);
|
||||
#endif
|
||||
def->df_sc = EXTERN;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* IDENTIFIER STACK DEFINITIONS */
|
||||
|
||||
|
|
|
@ -53,9 +53,13 @@ statement
|
|||
|
|
||||
default_statement
|
||||
|
|
||||
break_statement
|
||||
BREAK
|
||||
{code_break();}
|
||||
';'
|
||||
|
|
||||
continue_statement
|
||||
CONTINUE
|
||||
{code_continue();}
|
||||
';'
|
||||
|
|
||||
return_statement
|
||||
|
|
||||
|
@ -316,20 +320,6 @@ default_statement
|
|||
statement
|
||||
;
|
||||
|
||||
break_statement
|
||||
:
|
||||
BREAK
|
||||
{code_break();}
|
||||
';'
|
||||
;
|
||||
|
||||
continue_statement
|
||||
:
|
||||
CONTINUE
|
||||
{code_continue();}
|
||||
';'
|
||||
;
|
||||
|
||||
return_statement
|
||||
{ struct expr *expr = 0;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* S T A T E M E N T - B L O C K D E F I N I T I O N S */
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "level.h"
|
||||
#include "assert.h"
|
||||
#include "sizes.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
/* Type of previous selector declared with a field width specified,
|
||||
if any. If a selector is declared with no field with it is set to 0.
|
||||
|
@ -76,11 +77,13 @@ add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */
|
|||
register struct sdef *newsdef;
|
||||
int lvl = tg->tg_level;
|
||||
|
||||
#ifndef NOROPTION
|
||||
if (options['R'] && !is_anon_idf(idf)) {
|
||||
/* a K & R test */
|
||||
if (idf->id_struct && idf->id_struct->tg_level == level)
|
||||
warning("%s is also a struct/union tag", idf->id_text);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stp->tp_fund == STRUCT) {
|
||||
#ifndef NOBITFIELD
|
||||
|
@ -110,12 +113,14 @@ add_sel(stp, tp, idf, sdefpp, szp, fd) /* this is horrible */
|
|||
}
|
||||
|
||||
check_selector(idf, stp);
|
||||
#ifndef NOROPTION
|
||||
if (options['R']) {
|
||||
if ( sdef && sdef->sd_level == lvl &&
|
||||
sdef->sd_offset != offset
|
||||
) /* RM 8.7 */
|
||||
( sdef->sd_offset != offset || sdef->sd_type != tp )
|
||||
) /* RM 8.5 */
|
||||
warning("selector %s redeclared", idf->id_text);
|
||||
}
|
||||
#endif
|
||||
|
||||
newsdef = new_sdef();
|
||||
newsdef->sd_sdef = (struct sdef *) 0;
|
||||
|
@ -195,6 +200,7 @@ declare_struct(fund, idf, tpp)
|
|||
idf = gen_idf();
|
||||
tgp = (fund == ENUM ? &idf->id_enum : &idf->id_struct);
|
||||
|
||||
#ifndef NOROPTION
|
||||
if (options['R'] && !is_anon_idf(idf)) {
|
||||
/* a K & R test */
|
||||
if ( fund != ENUM &&
|
||||
|
@ -208,6 +214,7 @@ declare_struct(fund, idf, tpp)
|
|||
warning("%s is also a variable", idf->id_text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tg = *tgp;
|
||||
if (tg && tg->tg_type->tp_size < 0 && tg->tg_type->tp_fund == fund) {
|
||||
|
@ -220,9 +227,11 @@ declare_struct(fund, idf, tpp)
|
|||
declare_struct(fund, gen_idf(), tpp);
|
||||
}
|
||||
else {
|
||||
#ifndef NOROPTION
|
||||
if (options['R'] && tg->tg_level != level)
|
||||
warning("%s declares %s in different range",
|
||||
idf->id_text, symbol2str(fund));
|
||||
#endif
|
||||
*tpp = tg->tg_type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* SELECTOR DESCRIPTOR */
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "assert.h"
|
||||
#include "expr.h"
|
||||
#include "type.h"
|
||||
#include "noRoption.h"
|
||||
|
||||
extern char options[];
|
||||
|
||||
|
@ -47,8 +48,10 @@ code_startswitch(expp)
|
|||
|
||||
switch (fund) {
|
||||
case LONG:
|
||||
#ifndef NOROPTION
|
||||
if (options['R'])
|
||||
warning("long in switch (cast to int)");
|
||||
#endif
|
||||
int2int(expp, int_type);
|
||||
break;
|
||||
#ifndef NOFLOAT
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* S W I T C H - T A B L E - S T R U C T U R E */
|
||||
|
||||
|
@ -21,4 +25,4 @@ struct case_entry {
|
|||
arith ce_value;
|
||||
};
|
||||
|
||||
/* ALLOCDEF "case_entry" 40 */
|
||||
/* ALLOCDEF "case_entry" 20 */
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
/* TYPE DESCRIPTOR */
|
||||
|
||||
|
@ -44,4 +48,4 @@ extern struct type *pa_type; /* type.c */
|
|||
|
||||
extern arith size_of_type(), align();
|
||||
|
||||
/* ALLOCDEF "type" 50 */
|
||||
/* ALLOCDEF "type" 20 */
|
||||
|
|
Loading…
Reference in a new issue