modified the treatment of op=, ++ and -- operators

This commit is contained in:
erikb 1986-09-29 14:01:34 +00:00
parent 42112db262
commit 5af21dfc79
15 changed files with 421 additions and 601 deletions

View file

@ -17,7 +17,8 @@ EMELIB = $(EM)/modules/lib/libeme.a
STRLIB = $(EM)/modules/lib/libstr.a
PRTLIB = $(EM)/modules/lib/libprint.a
EMMESLIB = $(EM)/modules/lib/libem_mes.a
CH3LIB = $(EM)/modules/lib/libch3.a
#CH3LIB = $(EM)/modules/lib/libch3.a
CH3LIB =
LIBS = $(CH3LIB) $(EMMESLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
ELIBS = $(CH3LIB) $(EMMESLIB) $(EMELIB) $(PRTLIB) $(STRLIB) $(SYSLIB)
LIB_INCLUDES = $(EM)/modules/h

View file

@ -423,6 +423,10 @@ is_asgn_op(oper)
case ANDAB:
case ORAB:
case XORAB:
case PLUSPLUS:
case POSTINCR:
case MINMIN:
case POSTDECR:
return 1;
default:
return 0;

View file

@ -1,10 +1,14 @@
/* $Header$ */
/* B L O C K S T O R I N G A N D L O A D I N G */
#include <em.h>
#include "arith.h"
#include "sizes.h"
#include "atw.h"
#include <em.h>
#include "arith.h"
#include "sizes.h"
#include "atw.h"
#ifndef STB
#include "label.h"
#include "stack.h"
#endif STB
/* Because EM does not support the loading and storing of
objects having other sizes than word fragment and multiple,
@ -38,17 +42,33 @@ store_block(sz, al)
arith sz;
int al;
{
/* Next condition contains Lots of Irritating Stupid Parentheses
*/
if (
((sz == al) && (word_align % al == 0)) ||
(
(sz % word_size == 0 || word_size % sz == 0) &&
(al % word_align == 0)
)
)
) /* Lots of Irritating Stupid Parentheses */
C_sti(sz);
else {
else {
#ifndef STB
arith src, dst, src_offs, dst_offs;
/* allocate two pointer temporaries */
src = tmp_pointer_var(&src_offs);
dst = tmp_pointer_var(&dst_offs);
/* load the addresses */
C_lal(dst);
C_sti(pointer_size);
C_lor((arith)1); /* push current sp */
C_lal(src);
C_sti(pointer_size);
copy_loop(sz, src, dst);
C_asp(ATW(sz));
free_tmp_var(dst_offs);
free_tmp_var(src_offs);
#else STB
/* address of destination lies on the stack */
/* push address of first byte of block on stack onto
@ -60,6 +80,7 @@ store_block(sz, al)
C_loc(sz); /* number of bytes to transfer */
C_cal("__stb"); /* call transfer routine */
C_asp(pointer_size + pointer_size + int_size + ATW(sz));
#endif STB
}
}
@ -75,7 +96,23 @@ load_block(sz, al)
if (al % word_align == 0)
C_loi(esz);
else {
/* do not try to understand this... */
#ifndef STB
arith src, dst, src_offs, dst_offs;
/* allocate two pointer temporaries */
src = tmp_pointer_var(&src_offs);
dst = tmp_pointer_var(&dst_offs);
C_lal(src);
C_sti(pointer_size);
C_asp(-esz); /* allocate stack block */
C_lor((arith)1); /* push & of stack block as dst */
C_lal(dst);
C_sti(pointer_size);
copy_loop(sz, src, dst);
free_tmp_var(dst_offs);
free_tmp_var(src_offs);
#else STB
C_asp(-(esz - pointer_size)); /* allocate stack block */
C_lor((arith)1); /* push & of stack block as dst */
C_dup(pointer_size); /* fetch source address */
@ -84,5 +121,38 @@ load_block(sz, al)
C_loc(sz); /* # bytes to copy */
C_cal("__stb"); /* library copy routine */
C_asp(int_size + pointer_size + pointer_size);
#endif STB
}
}
#ifndef STB
copy_loop(sz, src, dst)
arith sz, src, dst;
{
/* generate inline byte-copy loop */
label l_cont = text_label(), l_stop = text_label();
C_loc(sz); /* amount of bytes */
C_df_ilb(l_cont);
C_dup(word_size);
C_zle(l_stop);
C_dec();
C_lal(src);
C_loi(pointer_size);
C_dup(pointer_size);
C_adp((arith)1);
C_lal(src);
C_sti(pointer_size);
C_loi((arith)1);
C_lal(dst);
C_loi(pointer_size);
C_dup(pointer_size);
C_adp((arith)1);
C_lal(dst);
C_sti(pointer_size);
C_sti((arith)1);
C_bra(l_cont);
C_df_ilb(l_stop);
C_asp(word_size);
}
#endif STB

View file

@ -121,11 +121,9 @@ ch7sel(expp, oper, idf)
intexpr(sd->sd_offset, INT));
}
}
else {
/* oper == ARROW */
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);
}
@ -135,44 +133,7 @@ ch7incr(expp, oper)
/* The monadic prefix/postfix incr/decr operator oper is
applied to *expp.
*/
arith addend;
struct expr *expr;
register int fund = (*expp)->ex_type->tp_fund;
if (!(*expp)->ex_lvalue) {
expr_error(*expp, "no lvalue with %s", symbol2str(oper));
return;
}
if (fund == ENUM) {
expr_warning(*expp, "%s on enum", symbol2str(oper));
addend = (arith)1;
}
else
if (is_arith_type((*expp)->ex_type))
addend = (arith)1;
else
if (fund == POINTER)
addend = size_of_type((*expp)->ex_type->tp_up, "object");
#ifndef NOBITFIELD
else
if (fund == FIELD)
addend = (arith)1;
#endif NOBITFIELD
else {
expr_error(*expp, "%s on %s",
symbol2str(oper),
symbol2str((*expp)->ex_type->tp_fund)
);
return;
}
expr = intexpr(addend, INT);
ch7cast(&expr, CAST, (*expp)->ex_type);
#ifndef NOBITFIELD
if (fund == FIELD)
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
else
#endif NOBITFIELD
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
ch7asgn(expp, oper, intexpr((arith)1, INT));
}
ch7cast(expp, oper, tp)
@ -293,10 +254,8 @@ ch7cast(expp, oper, tp)
(*expp)->ex_type = tp;
}
else
if (oldtp->tp_fund == ERRONEOUS) {
/* we just won't look */
(*expp)->ex_type = tp; /* brute force */
}
if (oldtp->tp_fund == ERRONEOUS) /* we just won't look */
(*expp)->ex_type = tp; /* brute force */
else
if (oldtp->tp_size == tp->tp_size && oper == CAST) {
expr_warning(*expp, "dubious conversion based on equal size");
@ -365,7 +324,6 @@ ch7asgn(expp, oper, expr)
else
expr = extmp;
}
#ifndef NOBITFIELD
if (fund == FIELD)
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
@ -374,7 +332,6 @@ ch7asgn(expp, oper, expr)
#else NOBITFIELD
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
#endif NOBITFIELD
(*expp)->OP_TYPE = tp; /* for EVAL() */
}

View file

@ -82,16 +82,6 @@ ch7bin(expp, oper, expr)
break;
case '%':
case MODAB:
/*** NB "not float" means "integral" !!!
fund = arithbalance(expp, oper, &expr);
if (fund == DOUBLE) {
expr_error(*expp, "floating operand to %s",
symbol2str(oper));
erroneous2int(expp);
}
else
non_commutative_binop(expp, oper, expr);
***/
opnd2integral(expp, oper);
opnd2integral(&expr, oper);
fund = arithbalance(expp, oper, &expr);
@ -111,21 +101,19 @@ ch7bin(expp, oper, expr)
non_commutative_binop(expp, oper, expr);
break;
case '+':
if (expr->ex_type->tp_fund == POINTER) {
/* swap operands */
if (expr->ex_type->tp_fund == POINTER) { /* swap operands */
struct expr *etmp = expr;
expr = *expp;
*expp = etmp;
}
/*FALLTHROUGH*/
case PLUSAB:
case POSTINCR:
case PLUSPLUS:
if ((*expp)->ex_type->tp_fund == POINTER) {
pointer_arithmetic(expp, oper, &expr);
if ( expr->ex_type->tp_size !=
(*expp)->ex_type->tp_size
) {
if (expr->ex_type->tp_size != (*expp)->ex_type->tp_size)
ch7cast(&expr, CAST, (*expp)->ex_type);
}
pointer_binary(expp, oper, expr);
}
else {
@ -138,6 +126,8 @@ ch7bin(expp, oper, expr)
break;
case '-':
case MINAB:
case POSTDECR:
case MINMIN:
if ((*expp)->ex_type->tp_fund == POINTER) {
if (expr->ex_type->tp_fund == POINTER)
pntminuspnt(expp, oper, expr);
@ -231,13 +221,11 @@ ch7bin(expp, oper, expr)
if ( is_struct_or_union((*expp)->ex_type->tp_fund)
|| is_struct_or_union(expr->ex_type->tp_fund)
) {
if ((*expp)->ex_type != expr->ex_type) {
if ((*expp)->ex_type != expr->ex_type)
expr_error(*expp, "illegal balance");
}
}
else {
else
relbalance(expp, oper, &expr);
}
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
break;
case '?':

View file

@ -28,16 +28,15 @@
#include "atw.h"
#include "assert.h"
static struct stmt_block *stmt_stack;
char *symbol2str();
#ifndef NOFLOAT
int fp_used;
#endif NOFLOAT
label lab_count = 1;
label datlab_count = 1;
#ifndef NOFLOAT
int fp_used;
#endif NOFLOAT
extern char options[];
char *symbol2str();
init_code(dst_file)
char *dst_file;
@ -112,16 +111,11 @@ prepend_scopes(dst_file)
fatal("cannot create %s", dst_file ? dst_file : "stdout");
famous_first_words();
while (se != 0) {
register struct idf *idf = se->se_idf;
register struct def *def = idf->id_def;
register struct idf *id = se->se_idf;
register struct def *df = id->id_def;
if (def &&
( def->df_initialized ||
def->df_used ||
def->df_alloc
)
)
code_scope(idf->id_text, def);
if (df && (df->df_initialized || df->df_used || df->df_alloc))
code_scope(id->id_text, df);
se = se->next;
}
C_close();
@ -198,7 +192,6 @@ begin_proc(name, def) /* to be called when entering a procedure */
}
else
func_res_label = 0;
/* Special arrangements if the function result doesn't fit in
the function return area of the EM machine. The size of
the function return area is implementation dependent.
@ -206,15 +199,12 @@ begin_proc(name, def) /* to be called when entering a procedure */
lab_count = (label) 1;
return_label = text_label();
return_expr_occurred = 0;
if (options['p']) { /* profiling */
if (strcmp(last_fn_given, FileName) != 0) {
/* previous function came from other file */
C_df_dlb(file_name_label = data_label());
C_con_scon(
last_fn_given = FileName,
(arith)(strlen(FileName) + 1)
);
C_con_scon(last_fn_given = FileName,
(arith)(strlen(FileName) + 1));
}
/* enable debug trace of EM source */
C_fil_dlb(file_name_label, (arith)0);
@ -345,17 +335,14 @@ code_declaration(idf, expr, lvl, sc)
}
else
if (lvl >= L_LOCAL) { /* local variable */
/* they are STATIC, EXTERN, GLOBAL, IMPLICIT, AUTO or
REGISTER
*/
/* STATIC, EXTERN, GLOBAL, IMPLICIT, AUTO or REGISTER */
switch (def_sc) {
case STATIC:
/* they are handled on the spot and get an
integer label in EM.
*/
C_df_dlb((label)def->df_address);
if (expr) {
/* there is an initialisation */
if (expr) { /* there is an initialisation */
do_ival(&(def->df_type), expr);
free_expression(expr);
}
@ -364,8 +351,7 @@ code_declaration(idf, expr, lvl, sc)
error("size of %s unknown", text);
size = (arith)0;
}
C_bss_cst(align(size, word_align),
(arith)0, 1);
C_bss_cst(align(size, word_align), (arith)0, 1);
}
break;
case EXTERN:
@ -399,7 +385,6 @@ loc_init(expr, id)
register struct type *tp = id->id_def->df_type;
ASSERT(id->id_def->df_sc != STATIC);
/* automatic aggregates cannot be initialised. */
switch (tp->tp_fund) {
case ARRAY:
case STRUCT:
@ -408,7 +393,6 @@ loc_init(expr, id)
free_expression(expr);
return;
}
if (ISCOMMA(expr)) { /* embraced: int i = {12}; */
if (options['R']) {
if (ISCOMMA(expr->OP_LEFT)) /* int i = {{1}} */
@ -463,14 +447,15 @@ formal_cvt(df)
*/
register struct type *tp = df->df_type;
if (tp->tp_size != int_size)
if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) {
C_lol(df->df_address);
conversion(int_type, df->df_type);
C_lal(df->df_address);
C_sti(tp->tp_size);
df->df_register = REG_NONE;
}
if (tp->tp_size != int_size &&
(tp->tp_fund == CHAR || tp->tp_fund == SHORT)
) {
C_lol(df->df_address);
/* conversion(int_type, df->df_type); ??? */
C_lal(df->df_address);
C_sti(tp->tp_size);
df->df_register = REG_NONE;
}
}
code_expr(expr, val, code, tlbl, flbl)
@ -478,8 +463,7 @@ code_expr(expr, val, code, tlbl, flbl)
label tlbl, flbl;
{
/* code_expr() is the parser's interface to the expression code
generator.
If line number trace is wanted, it generates a
generator. If line number trace is wanted, it generates a
lin instruction. EVAL() is called directly.
*/
if (options['p']) /* profiling */
@ -493,6 +477,8 @@ code_expr(expr, val, code, tlbl, flbl)
EM labels where a subsequent break or continue causes
the program to jump to.
*/
static struct stmt_block *stmt_stack; /* top of statement stack */
/* code_break() generates EM code needed at the occurrence of "break":
it generates a branch instruction to the break label of the
innermost statement in which break has a meaning.
@ -504,11 +490,10 @@ code_break()
{
register struct stmt_block *stmt_block = stmt_stack;
if (stmt_block) {
if (stmt_block)
C_bra(stmt_block->st_break);
return;
}
error("break not inside for, while, do or switch");
else
error("break not inside for, while, do or switch");
}
/* code_continue() generates EM code needed at the occurrence of

View file

@ -1,7 +1,7 @@
/* $Header$ */
/* D E C L A R A T O R M A N I P U L A T I O N */
#include "botch_free.h" /* UF */
#include "botch_free.h"
#include "alloc.h"
#include "arith.h"
#include "type.h"

View file

@ -17,7 +17,6 @@
#include "parbufsize.h"
#include "textsize.h"
#include "idfsize.h"
#include "assert.h"
#include "alloc.h"
#include "class.h"
@ -301,14 +300,10 @@ PRIVATE
do_elif()
{
if (nestlevel < 0 || (ifstack[nestlevel])) {
/* invalid elif encountered.. */
lexerror("#elif without corresponding #if");
SkipRestOfLine();
}
else {
/* restart at this level as if a #if
is detected.
*/
else { /* restart at this level as if a #if is detected. */
nestlevel--;
push_if();
skip_block();
@ -377,8 +372,7 @@ do_undef()
if (id && id->id_macro) { /* forget the macro */
free_macro(id->id_macro);
id->id_macro = (struct macro *) 0;
}
/* else: don't complain */
} /* else: don't complain */
}
else
lexerror("illegal #undef construction");
@ -470,8 +464,7 @@ macro_def(id, text, nformals, length, flags)
if (macroeq(newdef->mc_text, text))
return;
lexwarning("redefine \"%s\"", id->id_text);
}
/* else: overwrite pre-definition */
} /* else: overwrite pre-definition */
}
else
id->id_macro = newdef = new_macro();

View file

@ -1,17 +1,6 @@
/* $Header$ */
/* EXPRESSION-CODE GENERATOR */
/* main functions :
EVAL() -- expression tree evaluator
tmp_pointer_var() -- deliver temporary pointer variable
free_tmp_var() -- return the pointer var
store_val() -- store primary expression
load_val() -- load primary expression
auxiliary functions:
assop()
compare()
*/
#include "nofloat.h"
#include <em.h>
#include "debug.h"
@ -40,45 +29,40 @@ char *symbol2str();
char *long2str();
arith tmp_pointer_var();
/* EVAL() serves as the main expression tree evaluator, which turns
any legal expression tree into legal EM code.
The parameters describe how EVAL should treat the expression tree:
/* EVAL() is the main expression-tree evaluator, which turns
any legal expression tree into EM code. Parameters:
struct expr *expr: pointer to root of the expression tree to
be evaluated
struct expr *expr
pointer to root of the expression tree to be evaluated
int val: indicates whether the resulting expression
is to be dereferenced (if val == RVAL and
expr->ex_lvalue == 1) or not (val == LVAL).
The latter case indicates that the resulting
expression is an lvalue expression which should
not be dereferenced by EVAL
int val
indicates whether the resulting expression is to be
dereferenced (if val == RVAL and expr->ex_lvalue == 1)
or not (val == LVAL). The latter case indicates that
the resulting expression is an lvalue expression which
should not be dereferenced by EVAL
int code: indicates whether the expression tree must be
turned into EM code or not. E.g. the expression
statement "12;" delivers the expression "12" to
EVAL while this should not result in any EM
code
int code
indicates whether the expression tree must be turned
into EM code or not. E.g. the expression statement "12;"
delivers the expression "12" to EVAL while this should
not result in any EM code
label false_label:
label true_label: if the expression is a logical or relational
expression and if the loop of the program
depends on the resulting value then EVAL
generates jumps to the specified program
labels, in case they are specified
(i.e. are non-zero)
label false_label, label true_label
if the expression is a logical or relational expression
and if the loop of the program depends on the resulting
value then EVAL generates jumps to the specified program
labels, in case they are specified (i.e. are non-zero)
*/
EVAL(expr, val, code, true_label, false_label)
register struct expr *expr; /* the expression tree itself */
int val; /* either RVAL or LVAL */
int code; /* generate explicit code or not */
label true_label;
label false_label; /* labels to jump to in logical expr's */
register struct expr *expr;
int val, code;
label true_label, false_label;
{
register int gencode = (code == TRUE);
switch (expr->ex_class) {
switch (expr->ex_class) {
case Value: /* just a simple value */
if (gencode)
load_val(expr, val);
@ -107,23 +91,22 @@ EVAL(expr, val, code, true_label, false_label)
case Oper: /* compound expression */
{
int oper = expr->OP_OPER;
register struct expr *leftop = expr->OP_LEFT;
register struct expr *rightop = expr->OP_RIGHT;
register struct expr *left = expr->OP_LEFT;
register struct expr *right = expr->OP_RIGHT;
register struct type *tp = expr->OP_TYPE;
if (tp->tp_fund == ERRONEOUS) /* stop immediately */
break;
switch (oper) {
switch (oper) {
case '+':
/* We have the following possibilities :
int + int, pointer + int, pointer + long,
long + long, double + double
*/
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode) {
switch (tp->tp_fund) {
switch (tp->tp_fund) {
case INT:
case LONG:
if (tp->tp_unsigned)
@ -132,7 +115,7 @@ EVAL(expr, val, code, true_label, false_label)
C_adi(tp->tp_size);
break;
case POINTER:
C_ads(rightop->ex_type->tp_size);
C_ads(right->ex_type->tp_size);
break;
#ifndef NOFLOAT
case DOUBLE:
@ -145,10 +128,10 @@ EVAL(expr, val, code, true_label, false_label)
}
break;
case '-':
if (leftop == 0) { /* unary */
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
if (left == 0) { /* unary */
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode) {
switch (tp->tp_fund) {
switch (tp->tp_fund) {
case INT:
case LONG:
case POINTER:
@ -165,16 +148,15 @@ EVAL(expr, val, code, true_label, false_label)
}
break;
}
/* Binary: we have the following flavours:
/* else binary; we have the following flavours:
int - int, pointer - int, pointer - long,
pointer - pointer, long - long, double - double
*/
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (!gencode)
break;
switch (tp->tp_fund) {
switch (tp->tp_fund) {
case INT:
case LONG:
if (tp->tp_unsigned)
@ -183,11 +165,11 @@ EVAL(expr, val, code, true_label, false_label)
C_sbi(tp->tp_size);
break;
case POINTER:
if (rightop->ex_type->tp_fund == POINTER)
if (right->ex_type->tp_fund == POINTER)
C_sbs(pointer_size);
else {
C_ngi(rightop->ex_type->tp_size);
C_ads(rightop->ex_type->tp_size);
else {
C_ngi(right->ex_type->tp_size);
C_ads(right->ex_type->tp_size);
}
break;
#ifndef NOFLOAT
@ -200,13 +182,13 @@ EVAL(expr, val, code, true_label, false_label)
}
break;
case '*':
if (leftop == 0) /* unary */
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
else { /* binary */
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
if (left == 0) /* unary */
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
else { /* binary */
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
switch (tp->tp_fund) {
switch (tp->tp_fund) {
case INT:
case LONG:
case POINTER:
@ -226,10 +208,10 @@ EVAL(expr, val, code, true_label, false_label)
}
break;
case '/':
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
switch (tp->tp_fund) {
switch (tp->tp_fund) {
case INT:
case LONG:
case POINTER:
@ -248,8 +230,8 @@ EVAL(expr, val, code, true_label, false_label)
}
break;
case '%':
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
ASSERT(tp->tp_fund==INT || tp->tp_fund==LONG);
if (gencode)
if (tp->tp_unsigned)
@ -258,8 +240,8 @@ EVAL(expr, val, code, true_label, false_label)
C_rmi(tp->tp_size);
break;
case LEFT:
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
if (tp->tp_unsigned)
C_slu(tp->tp_size);
@ -267,8 +249,8 @@ EVAL(expr, val, code, true_label, false_label)
C_sli(tp->tp_size);
break;
case RIGHT:
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
if (tp->tp_unsigned)
C_sru(tp->tp_size);
@ -281,16 +263,16 @@ EVAL(expr, val, code, true_label, false_label)
case GREATEREQ:
case EQUAL:
case NOTEQUAL:
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode) {
/* The operands have the same type */
arith size = leftop->ex_type->tp_size;
arith size = left->ex_type->tp_size;
switch (tp->tp_fund) {
switch (tp->tp_fund) {
case INT:
case LONG:
if (leftop->ex_type->tp_unsigned)
if (left->ex_type->tp_unsigned)
C_cmu(size);
else
C_cmi(size);
@ -310,11 +292,11 @@ EVAL(expr, val, code, true_label, false_label)
default:
CRASH();
}
if (true_label != 0) {
if (true_label != 0) {
compare(oper, true_label);
C_bra(false_label);
}
else {
else {
label l_true = text_label();
label l_end = text_label();
@ -331,14 +313,14 @@ EVAL(expr, val, code, true_label, false_label)
case '|':
case '^':
/* both operands should have type int */
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode) {
arith size = tp->tp_size;
if (size < word_size)
size = word_size;
switch (oper) {
switch (oper) {
case '&':
C_and(size);
break;
@ -353,26 +335,21 @@ EVAL(expr, val, code, true_label, false_label)
break;
case '=':
#ifndef NOBITFIELD
if (leftop->ex_type->tp_fund == FIELD) {
/* assignment to bitfield variable
*/
if (left->ex_type->tp_fund == FIELD) {
eval_field(expr, code);
break;
}
#endif NOBITFIELD
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL);
if (gencode)
C_dup(ATW(tp->tp_size));
if (leftop->ex_class != Value) {
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
if (left->ex_class != Value) {
EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
store_block(tp->tp_size, tp->tp_align);
}
else
store_val(
&(leftop->ex_object.ex_value),
leftop->ex_type
);
store_val(&(left->ex_object.ex_value),
left->ex_type);
break;
case PLUSAB:
case MINAB:
@ -384,47 +361,60 @@ EVAL(expr, val, code, true_label, false_label)
case ANDAB:
case XORAB:
case ORAB:
case POSTINCR:
case POSTDECR:
case PLUSPLUS:
case MINMIN:
{
arith old_offset;
arith tmpvar = tmp_pointer_var(&old_offset);
arith old_offset, tmp;
int compl; /* Complexity of left operand */
#ifndef NOBITFIELD
if (leftop->ex_type->tp_fund == FIELD) {
if (left->ex_type->tp_fund == FIELD) {
eval_field(expr, code);
break;
}
#endif NOBITFIELD
if (leftop->ex_class != Value) {
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_lal(tmpvar);
C_sti(pointer_size);
C_lal(tmpvar);
C_loi(pointer_size);
C_loi(leftop->ex_type->tp_size);
if (left->ex_class == Value) {
compl = 0; /* Value */
load_val(left, RVAL);
}
else {
load_val(leftop, RVAL);
}
conversion(leftop->ex_type, tp);
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
assop(tp, oper);
conversion(tp, leftop->ex_type);
if (gencode)
C_dup(toword(leftop->ex_type->tp_size));
if (leftop->ex_class != Value) {
C_lal(tmpvar);
C_loi(pointer_size);
C_sti(leftop->ex_type->tp_size);
free_tmp_var(old_offset);
else
if (left->ex_depth == 1 && left->OP_OPER == ARROW) {
compl = 1; /* Value->sel */
ASSERT(left->OP_LEFT->ex_class == Value);
EVAL(left, RVAL, TRUE, NO_LABEL, NO_LABEL);
}
else {
store_val(
&(leftop->ex_object.ex_value),
leftop->ex_type
);
compl = 2; /* otherwise */
tmp = tmp_pointer_var(&old_offset);
EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_dup(pointer_size);
C_lal(tmp);
C_sti(pointer_size);
C_loi(left->ex_type->tp_size);
}
conversion(left->ex_type, tp);
if (gencode && (oper == POSTINCR || oper == POSTDECR))
C_dup(tp->tp_size);
EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL);
assop(tp, oper);
if (gencode && oper != POSTINCR && oper != POSTDECR)
C_dup(tp->tp_size);
conversion(tp, left->ex_type);
if (compl == 0)
store_val(&(left->ex_object.ex_value),
left->ex_type);
else
if (compl == 1) {
EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_sti(left->ex_type->tp_size);
}
else {
C_lal(tmp); /* always init'd */
C_loi(pointer_size);
C_sti(left->ex_type->tp_size);
free_tmp_var(old_offset);
}
if (gencode)
conversion(leftop->ex_type, expr->ex_type);
break;
}
case '(':
@ -432,7 +422,7 @@ EVAL(expr, val, code, true_label, false_label)
register struct expr *ex;
arith ParSize = (arith)0;
if ((ex = rightop) != NILEXPR) {
if ((ex = right) != NILEXPR) {
/* function call with parameters*/
while ( ex->ex_class == Oper &&
ex->OP_OPER == PARCOMMA
@ -445,24 +435,19 @@ EVAL(expr, val, code, true_label, false_label)
EVAL(ex, RVAL, TRUE, NO_LABEL, NO_LABEL);
ParSize += ATW(ex->ex_type->tp_size);
}
if ( leftop->ex_class == Value
&& leftop->VL_CLASS == Name
) {
/* just an example:
main() { (*((int (*)())0))(); }
*/
C_cal(leftop->VL_IDF->id_text);
if (left->ex_class == Value && left->VL_CLASS == Name) {
/* e.g., main() { (*((int (*)())0))(); } */
C_cal(left->VL_IDF->id_text);
#ifdef DATAFLOW
{ extern char options[];
if (options['d'])
DfaCallFunction(
leftop->VL_IDF->id_text
);
left->VL_IDF->id_text);
}
#endif DATAFLOW
}
else {
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
else {
EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_cai();
}
/* remove parameters from stack */
@ -479,124 +464,53 @@ EVAL(expr, val, code, true_label, false_label)
break;
}
case '.':
EVAL(leftop, LVAL, code, NO_LABEL, NO_LABEL);
ASSERT(is_cp_cst(rightop));
EVAL(left, LVAL, code, NO_LABEL, NO_LABEL);
ASSERT(is_cp_cst(right));
if (gencode)
C_adp(rightop->VL_VALUE);
C_adp(right->VL_VALUE);
break;
case ARROW:
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
ASSERT(is_cp_cst(rightop));
EVAL(left, RVAL, code, NO_LABEL, NO_LABEL);
ASSERT(is_cp_cst(right));
if (gencode)
C_adp(rightop->VL_VALUE);
C_adp(right->VL_VALUE);
break;
case ',':
EVAL(leftop, RVAL, FALSE, NO_LABEL, NO_LABEL);
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(left, RVAL, FALSE, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
break;
case '~':
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
C_com(tp->tp_size);
break;
case POSTINCR:
case POSTDECR:
case PLUSPLUS:
case MINMIN:
{
arith old_offset, tmp;
arith esize = tp->tp_size;
int compl; /* Complexity of left operand */
#ifndef NOBITFIELD
if (leftop->ex_type->tp_fund == FIELD) {
eval_field(expr, code);
break;
}
#endif NOBITFIELD
if (leftop->ex_class == Value) {
compl = 0; /* Value */
load_val(leftop, RVAL);
}
else
if (leftop->ex_depth == 1 && leftop->OP_OPER == ARROW) {
compl = 1; /* Value->sel */
ASSERT(leftop->OP_LEFT->ex_class == Value);
EVAL(leftop, RVAL, TRUE, NO_LABEL, NO_LABEL);
}
else {
compl = 2; /* otherwise */
tmp = tmp_pointer_var(&old_offset);
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_dup(pointer_size);
C_lal(tmp);
C_sti(pointer_size);
C_loi(esize);
}
/* We made the choice to put this stuff here
and not to put the conversion in the expression
tree because this conversion is EM dependent
and not described in C
*/
if (esize < word_size) {
conversion(tp, word_type);
esize = word_size;
}
if (gencode && (oper == POSTINCR || oper == POSTDECR))
C_dup(esize);
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
assop(tp, oper);
if (gencode && (oper == PLUSPLUS || oper == MINMIN))
C_dup(esize);
if (tp->tp_size < word_size)
conversion(word_type, tp);
if (compl == 0) {
store_val(
&(leftop->ex_object.ex_value),
leftop->ex_type
);
}
else
if (compl == 1) {
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_sti(tp->tp_size);
}
else {
C_lal(tmp); /* always init'd */
C_loi(pointer_size);
C_sti(tp->tp_size);
free_tmp_var(old_offset);
}
break;
}
case '?': /* must be followed by ':' */
{
label l_true = text_label();
label l_false = text_label();
label l_end = text_label();
EVAL(leftop, RVAL, TRUE, l_true, l_false);
EVAL(left, RVAL, TRUE, l_true, l_false);
C_df_ilb(l_true);
EVAL(rightop->OP_LEFT, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right->OP_LEFT, RVAL, code, NO_LABEL, NO_LABEL);
C_bra(l_end);
C_df_ilb(l_false);
EVAL(rightop->OP_RIGHT, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right->OP_RIGHT, RVAL, code, NO_LABEL, NO_LABEL);
C_df_ilb(l_end);
break;
}
case AND:
if (true_label == 0) {
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(leftop, RVAL, TRUE, l_maybe, l_false);
EVAL(left, RVAL, TRUE, l_maybe, l_false);
C_df_ilb(l_maybe);
if (gencode) {
EVAL(rightop, RVAL, TRUE,
l_true, l_false);
if (gencode) {
EVAL(right, RVAL, TRUE, l_true,
l_false);
C_df_ilb(l_true);
C_loc((arith)1);
C_bra(l_end);
@ -605,32 +519,32 @@ EVAL(expr, val, code, true_label, false_label)
C_df_ilb(l_end);
}
else {
EVAL(rightop, RVAL, FALSE, l_false,
EVAL(right, RVAL, FALSE, l_false,
l_false);
C_df_ilb(l_false);
}
}
else {
else {
label l_maybe = text_label();
EVAL(leftop, RVAL, TRUE, l_maybe, false_label);
EVAL(left, RVAL, TRUE, l_maybe, false_label);
C_df_ilb(l_maybe);
EVAL(rightop, RVAL, code, true_label,
EVAL(right, RVAL, code, true_label,
false_label);
}
break;
case OR:
if (true_label == 0) {
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(leftop, RVAL, TRUE, l_true, l_maybe);
EVAL(left, RVAL, TRUE, l_true, l_maybe);
C_df_ilb(l_maybe);
if (gencode) {
EVAL(rightop, RVAL, TRUE,
l_true, l_false);
if (gencode) {
EVAL(right, RVAL, TRUE, l_true,
l_false);
C_df_ilb(l_false);
C_loc((arith)0);
C_bra(l_end);
@ -638,30 +552,30 @@ EVAL(expr, val, code, true_label, false_label)
C_loc((arith)1);
C_df_ilb(l_end);
}
else {
EVAL(rightop, RVAL, FALSE, l_true,
else {
EVAL(right, RVAL, FALSE, l_true,
l_true);
C_df_ilb(l_true);
}
}
else {
else {
label l_maybe = text_label();
EVAL(leftop, RVAL, TRUE, true_label, l_maybe);
EVAL(left, RVAL, TRUE, true_label, l_maybe);
C_df_ilb(l_maybe);
EVAL(rightop, RVAL, code, true_label,
EVAL(right, RVAL, code, true_label,
false_label);
}
break;
case '!':
if (true_label == 0) {
if (gencode) {
if (true_label == 0) {
if (gencode) {
label l_true = text_label();
label l_false = text_label();
label l_end = text_label();
EVAL(rightop, RVAL, TRUE,
l_false, l_true);
EVAL(right, RVAL, TRUE, l_false,
l_true);
C_df_ilb(l_false);
C_loc((arith)0);
C_bra(l_end);
@ -670,11 +584,11 @@ EVAL(expr, val, code, true_label, false_label)
C_df_ilb(l_end);
}
else
EVAL(rightop, RVAL, FALSE,
NO_LABEL, NO_LABEL);
EVAL(right, RVAL, FALSE, NO_LABEL,
NO_LABEL);
}
else
EVAL(rightop, RVAL, code, false_label,
EVAL(right, RVAL, code, false_label,
true_label);
break;
case INT2INT:
@ -683,14 +597,13 @@ EVAL(expr, val, code, true_label, false_label)
case FLOAT2INT:
case FLOAT2FLOAT:
#endif NOFLOAT
EVAL(rightop, RVAL, code, NO_LABEL, NO_LABEL);
EVAL(right, RVAL, code, NO_LABEL, NO_LABEL);
if (gencode)
conversion(rightop->ex_type, leftop->ex_type);
conversion(right->ex_type, left->ex_type);
break;
default:
crash("(EVAL) bad operator %s\n", symbol2str(oper));
}
/* If the rvalue of the expression is required but
only its lvalue is evaluated, its rvalue is
loaded by the following statements:
@ -710,7 +623,7 @@ compare(relop, lbl)
int relop;
label lbl;
{
switch (relop) {
switch (relop) {
case '<':
C_zlt(lbl);
break;
@ -744,13 +657,13 @@ assop(type, oper)
if ((size = type->tp_size) < word_size)
size = word_size;
switch (type->tp_fund) {
switch (type->tp_fund) {
case CHAR:
case SHORT:
case INT:
case LONG:
case ENUM:
switch (oper) {
switch (oper) {
case PLUSAB:
case PLUSPLUS:
case POSTINCR:
@ -811,7 +724,7 @@ assop(type, oper)
#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
switch (oper) {
switch (oper) {
case PLUSAB:
case PLUSPLUS:
case POSTINCR:
@ -888,21 +801,19 @@ store_val(vl, tp)
register int indword;
arith val = vl->vl_value;
if (vl->vl_class == Const) { /* absolute addressing */
if (vl->vl_class == Const) { /* absolute addressing */
load_cst(val, pointer_size);
store_block(size, tpalign);
return;
}
al_on_word = (tpalign % word_align == 0);
if (!(inword = (size == word_size && al_on_word)))
indword = (size == dword_size && al_on_word);
if (vl->vl_class == Name) {
if (vl->vl_class == Name) {
register struct idf *id = vl->vl_data.vl_idf;
register struct def *df = id->id_def;
if (df->df_level == L_GLOBAL) {
if (df->df_level == L_GLOBAL) {
if (inword)
C_ste_dnam(id->id_text, val);
else
@ -920,7 +831,7 @@ store_val(vl, tp)
else
if (indword)
C_sdl(df->df_address + val);
else {
else {
C_lal(df->df_address + val);
store_block(size, tpalign);
df->df_register = REG_NONE;
@ -965,8 +876,8 @@ load_val(expr, val)
register int inword, indword;
arith val = expr->VL_VALUE;
if (expr->VL_CLASS == Const) {
if (rvalue) { /* absolute addressing */
if (expr->VL_CLASS == Const) {
if (rvalue) { /* absolute addressing */
load_cst(val, pointer_size);
load_block(size, tpalign);
}
@ -980,7 +891,7 @@ load_val(expr, val)
indword = (size == dword_size && al_on_word);
}
if (expr->VL_CLASS == Label) {
if (rvalue) {
if (rvalue) {
if (inword)
C_loe_dlb(expr->VL_LBL, val);
else
@ -992,7 +903,7 @@ load_val(expr, val)
}
}
else {
else {
C_lae_dlb(expr->VL_LBL, (arith)0);
C_adp(val);
}
@ -1010,8 +921,8 @@ load_val(expr, val)
*/
C_lpi(id->id_text);
else
if (df->df_level == L_GLOBAL) {
if (rvalue) {
if (df->df_level == L_GLOBAL) {
if (rvalue) {
if (inword)
C_loe_dnam(id->id_text, val);
else
@ -1022,14 +933,14 @@ load_val(expr, val)
load_block(size, tpalign);
}
}
else {
else {
C_lae_dnam(id->id_text, (arith)0);
C_adp(val);
}
}
else {
else {
ASSERT(df->df_sc != STATIC);
if (rvalue) {
if (rvalue) {
if (inword)
C_lol(df->df_address + val);
else
@ -1041,7 +952,7 @@ load_val(expr, val)
df->df_register = REG_NONE;
}
}
else {
else {
C_lal(df->df_address);
C_adp(val);
df->df_register = REG_NONE;

View file

@ -92,14 +92,14 @@ rank_of(oper)
}
int
rank_of_expression(expr)
register struct expr *expr;
rank_of_expression(ex)
register struct expr *ex;
{
/* Returns the rank of the top node in the expression.
*/
if (!expr || (expr->ex_flags & EX_PARENS) || expr->ex_class != Oper)
if (!ex || (ex->ex_flags & EX_PARENS) || ex->ex_class != Oper)
return 0;
return rank_of(expr->OP_OPER);
return rank_of(ex->OP_OPER);
}
check_conditional(expr, oper, pos_descr)
@ -158,15 +158,12 @@ idf2expr(expr)
register struct def *def = idf->id_def;
if (def == 0) {
if (AHEAD == '(') {
/* Function call, so declare the name IMPLICITly. */
/* See RM 13. */
add_def(idf, IMPLICIT, funint_type, level);
}
if (AHEAD == '(') /* function call, declare name IMPLICITly */
add_def(idf, IMPLICIT, funint_type, level); /* RM 13 */
else {
if (!is_anon_idf(idf))
error("%s undefined", idf->id_text);
/* Declare the idf anyway */
/* declare idf anyway */
add_def(idf, 0, error_type, level);
}
def = idf->id_def;
@ -254,25 +251,24 @@ intexpr(ivalue, fund)
clear((char *)expr, sizeof(struct expr));
expr->ex_file = dot.tk_file;
expr->ex_line = dot.tk_line;
fill_int_expr(expr, ivalue, fund);
return expr;
}
fill_int_expr(expr, ivalue, fund)
register struct expr *expr;
fill_int_expr(ex, ivalue, fund)
register struct expr *ex;
arith ivalue;
int fund;
{
/* Details derived from ivalue and fund are put into the
constant integer expression expr.
constant integer expression ex.
*/
switch (fund) {
case INT:
expr->ex_type = int_type;
ex->ex_type = int_type;
break;
case LONG:
expr->ex_type = long_type;
ex->ex_type = long_type;
break;
case UNSIGNED:
/* We cannot make a test like
@ -284,20 +280,18 @@ fill_int_expr(expr, ivalue, fund)
answer. We assume that the type "unsigned long"
is not part of portable C !
*/
expr->ex_type =
(ivalue & ~max_unsigned) ? long_type : uint_type;
ex->ex_type = (ivalue & ~max_unsigned) ? long_type : uint_type;
break;
case INTEGER:
expr->ex_type = (ivalue <= max_int) ? int_type : long_type;
ex->ex_type = (ivalue <= max_int) ? int_type : long_type;
break;
default:
crash("(intexpr) bad fund %s\n", symbol2str(fund));
}
expr->ex_class = Value;
expr->VL_CLASS = Const;
expr->VL_VALUE = ivalue;
cut_size(expr);
ex->ex_class = Value;
ex->VL_CLASS = Const;
ex->VL_VALUE = ivalue;
cut_size(ex);
}
struct expr *
@ -344,8 +338,7 @@ new_oper(tp, e1, oper, e2)
int e1_flags = e1 ? e1->ex_flags : 0;
expr->ex_depth =
(e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth)
+ 1;
(e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
expr->ex_flags = (e1_flags | e2->ex_flags) & ~EX_PARENS;
}
op = &expr->ex_object.ex_oper;
@ -353,7 +346,6 @@ new_oper(tp, e1, oper, e2)
op->op_oper = oper;
op->op_left = e1;
op->op_right = e2;
return expr;
}
@ -397,17 +389,14 @@ chk_cst_expr(expp)
#endif DEBUG
if ( fund != CHAR && fund != SHORT && fund != INT &&
fund != ENUM && fund != LONG
) {
)
expr_error(expr, "non-numerical constant expression"), err++;
}
else
if (!is_ld_cst(expr))
expr_error(expr, "expression is not constant"), err++;
if (options['R']) {
if (flags & EX_CAST)
expr_warning(expr,
"cast in constant expression");
expr_warning(expr, "cast in constant expression");
if (flags & EX_LOGICAL)
expr_warning(expr,
"logical operator in constant expression");
@ -475,11 +464,11 @@ free_expression(expr)
{
/* The expression expr is freed recursively.
*/
if (!expr)
return;
if (expr->ex_class == Oper) {
free_expression(expr->OP_LEFT);
free_expression(expr->OP_RIGHT);
if (expr) {
if (expr->ex_class == Oper) {
free_expression(expr->OP_LEFT);
free_expression(expr->OP_RIGHT);
}
free_expr(expr);
}
free_expr(expr);
}

View file

@ -5,9 +5,7 @@
#ifndef NOBITFIELD
#include <em.h>
#include "debug.h"
#include "arith.h"
#include "type.h"
#include "idf.h"
@ -27,39 +25,33 @@ char *symbol2str(); /* symbol2str.c */
tree and are therefore dealt with in this function.
The actions taken at any operation are described clearly by the
code for this actions.
Note: the bitfields are packed in target machine integers!
Notes
[1] the bitfields are packed in target machine integers!
[2] op is either an assignment operator or an increment/
decrement operator
[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;
{
int op = expr->OP_OPER;
struct expr *leftop = expr->OP_LEFT;
struct expr *rightop = expr->OP_RIGHT;
struct field *fd = leftop->ex_type->tp_field;
register struct expr *leftop = expr->OP_LEFT;
register struct expr *rightop = expr->OP_RIGHT;
register struct field *fd = leftop->ex_type->tp_field;
struct type *tp = leftop->ex_type->tp_up;
arith old_offset, tmpvar;
/* The type in which the bitfield arithmetic is done;
AND IN WHICH BITFIELDS ARE STORED!
*/
struct type *atype = tp->tp_unsigned ? uword_type : word_type;
arith asize = atype->tp_size;
/* First some assertions to be sure that the rest is legal */
ASSERT(asize == word_size); /* make sure that C_loc() is legal */
ASSERT(leftop->ex_type->tp_fund == FIELD);
leftop->ex_type = atype; /* this is cheating but it works... */
/* Note that op is either an assignment operator or an increment/
decrement operator
*/
if (op == '=') {
/* F = E: f = ((E & mask)<<shift) | (~(mask<<shift) & f)
*/
/* F = E: f = ((E & mask)<<shift) | (~(mask<<shift) & f) */
ASSERT(tp == rightop->ex_type);
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
conversion(tp, atype);
C_loc(fd->fd_mask);
@ -116,10 +108,9 @@ eval_field(expr, code)
C_and(asize);
if (code == TRUE && (op == POSTINCR || op == POSTDECR))
C_dup(asize);
/* the 'op' operation: */
conversion(atype, rightop->ex_type);
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
/* the 'op' operation: */
if (op == PLUSPLUS || op == POSTINCR)
assop(rightop->ex_type, PLUSAB);
else
@ -128,7 +119,6 @@ eval_field(expr, code)
else
assop(rightop->ex_type, op);
conversion(rightop->ex_type, atype);
C_loc(fd->fd_mask);
C_and(asize);
if (code == TRUE && op != POSTINCR && op != POSTDECR)

View file

@ -201,7 +201,6 @@ declare_idf(ds, dc, lvl)
/* some additional work for formal definitions */
if (lvl == L_FORMAL2) {
switch (type->tp_fund) {
case FUNCTION:
warning("%s is a function; cannot be formal",
idf->id_text);
@ -227,7 +226,6 @@ declare_idf(ds, dc, lvl)
break;
}
}
/* The tests on types, postponed from do_decspecs(), can now
be performed.
*/
@ -241,23 +239,15 @@ declare_idf(ds, dc, lvl)
ds->ds_sc = sc = GLOBAL;
}
}
else { /* non-FUNCTION */
else /* non-FUNCTION */
if (sc == 0)
sc =
lvl == L_GLOBAL ?
GLOBAL :
lvl == L_FORMAL1 || lvl == L_FORMAL2 ?
FORMAL :
AUTO;
}
if (options['R']) {
/* some special K & R tests */
sc = lvl == L_GLOBAL ? GLOBAL
: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
: AUTO;
if (options['R']) { /* some special K & R tests */
/* is it also an enum? */
if (idf->id_enum && idf->id_enum->tg_level == level)
warning("%s is also an enum tag", idf->id_text);
/* is it a universal typedef? */
if (def && def->df_level == L_UNIVERSAL)
warning("redeclaring reserved word %s", idf->id_text);
@ -299,15 +289,13 @@ declare_idf(ds, dc, lvl)
*/
if ( options['R'] &&
(sc == STATIC && type->tp_fund == FUNCTION)
) {
)
if (!is_anon_idf(idf))
warning("non-global static function %s",
idf->id_text);
}
declare_idf(ds, dc, L_GLOBAL);
}
else {
/* fill in the def block */
else { /* fill in the def block */
register struct def *newdef = new_def();
clear((char *)newdef, sizeof(struct def));
@ -315,24 +303,19 @@ declare_idf(ds, dc, lvl)
newdef->df_level = lvl;
newdef->df_type = type;
newdef->df_sc = sc;
/* link it into the name list in the proper place */
idf->id_def = newdef;
update_ahead(idf);
stack_idf(idf, stl);
/* We now calculate the address.
Globals have names and don't get addresses, they
get numbers instead (through data_label()).
Formals are handled by declare_formals().
So here we hand out local addresses only.
*/
if (lvl >= L_LOCAL) {
ASSERT(sc);
switch (sc) {
case 0:
crash("local sc == 0");
break;
case REGISTER:
case AUTO:
if (type->tp_size == (arith)-1) {
@ -341,8 +324,8 @@ declare_idf(ds, dc, lvl)
/** type = idf->id_def->df_type = int_type; **/
}
idf->id_def->df_register =
(sc == REGISTER)
? REG_BONUS : REG_DEFAULT;
(sc == REGISTER) ? REG_BONUS
: REG_DEFAULT;
idf->id_def->df_address =
stl->sl_max_block =
stl->sl_local_offset =
@ -358,17 +341,17 @@ declare_idf(ds, dc, lvl)
}
actual_declaration(sc, tp)
int sc;
struct type *tp;
{
/* An actual_declaration needs space, right here and now.
*/
register int fund = tp->tp_fund;
/* virtual declarations */
if (sc == ENUM || sc == TYPEDEF)
if (sc == ENUM || sc == TYPEDEF) /* virtual declarations */
return 0;
/* allocation solved in other ways */
if (fund == FUNCTION || fund == ARRAY)
/* allocation solved in other ways */
return 0;
/* to be allocated */
return 1;
@ -388,7 +371,6 @@ global_redecl(idf, new_sc, tp)
if (tp != def->df_type) {
register struct type *otp = def->df_type;
if ( tp->tp_fund != ARRAY || otp->tp_fund != ARRAY ||
tp->tp_up != otp->tp_up
) {
@ -409,9 +391,8 @@ global_redecl(idf, new_sc, tp)
error("inconsistent size in redeclaration of array %s",
idf->id_text);
}
/* Now we may be able to update the storage class. */
/* Clean out this mess as soon as we know all the possibilities
/* Now we may be able to update the storage class.
Clean out this mess as soon as we know all the possibilities
for new_sc.
For now we have:
EXTERN: we have seen the word "extern"
@ -424,7 +405,6 @@ global_redecl(idf, new_sc, tp)
*/
if (new_sc == IMPLICIT)
return; /* no new information */
switch (def->df_sc) { /* the old storage class */
case EXTERN:
switch (new_sc) { /* the new storage class */
@ -456,10 +436,9 @@ global_redecl(idf, new_sc, tp)
case GLOBAL:
break;
case STATIC:
if (def->df_initialized) {
if (def->df_initialized)
error("cannot redeclare %s to static",
idf->id_text);
}
else {
if (options['R'])
warning("%s redeclared to static",
@ -475,10 +454,9 @@ global_redecl(idf, new_sc, tp)
case STATIC:
switch (new_sc) { /* the new storage class */
case EXTERN:
if (def->df_initialized) {
if (def->df_initialized)
error("cannot redeclare %s to extern",
idf->id_text);
}
else {
warning("%s redeclared to extern",
idf->id_text);
@ -531,11 +509,9 @@ good_formal(def, 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);
error("%s not in parameter list", idf->id_text);
return 0;
}
return 1;
@ -610,17 +586,12 @@ declare_formals(fp)
register struct def *def = se->se_idf->id_def;
def->df_address = f_offset;
/* the alignment convention for parameters is: align on
word boundaries, i.e. take care that the following
parameter starts on a new word boundary.
*/
f_offset = align(f_offset + def->df_type->tp_size, word_align);
/* the following is absurd: any char or short formal
must be converted from integer to that type
*/
formal_cvt(def);
formal_cvt(def); /* cvt int to char or short, if necessary */
se = se->next;
}
*fp = f_offset;

View file

@ -24,7 +24,6 @@
char *symbol2str();
char *long2str();
struct expr *do_array(), *do_struct(), *IVAL();
/* do_ival() performs the initialisation of a global variable
@ -58,26 +57,23 @@ IVAL(tpp, ex)
register struct type *tp = *tpp;
switch (tp->tp_fund) {
case ARRAY:
/* array initialisation */
case ARRAY: /* array initialisation */
if (valid_type(tp->tp_up, "array element") == 0)
return 0;
if (ISCOMMA(ex)) /* list of initialisation expressions */
return do_array(ex, tpp);
/* catch initialisations like char s[] = "I am a string" */
if (tp->tp_up->tp_fund == CHAR && ex->ex_class == String)
/* initialisation like char s[] = "I am a string" */
ch_array(tpp, ex);
else /* " int i[24] = 12;" */
check_and_pad(ex, tpp);
break;
case STRUCT:
/* struct initialisation */
case STRUCT: /* struct initialisation */
if (valid_type(tp, "struct") == 0)
return 0;
if (ISCOMMA(ex)) /* list of initialisation expressions */
return do_struct(ex, tp);
/* "struct foo f = 12;" */
check_and_pad(ex, tpp);
check_and_pad(ex, tpp); /* "struct foo f = 12;" */
break;
case UNION:
error("union initialisation not allowed");
@ -85,7 +81,7 @@ IVAL(tpp, ex)
case ERRONEOUS:
break;
default: /* fundamental type */
if (ISCOMMA(ex)) { /* " int i = {12};" */
if (ISCOMMA(ex)) { /* " int i = {12};" */
if (IVAL(tpp, ex->OP_LEFT) != 0)
too_many_initialisers(ex);
/* return remainings of the list for the
@ -94,8 +90,7 @@ IVAL(tpp, ex)
*/
return ex->OP_RIGHT;
}
/* "int i = 12;" */
check_ival(ex, tp);
check_ival(ex, tp); /* "int i = 12;" */
break;
}
return 0;
@ -131,8 +126,7 @@ do_array(ex, tpp)
is completely foolish, we did it!! (no applause, thank you)
*/
if (tp->tp_up->tp_fund == CHAR) {
register struct expr *f = ex->OP_LEFT;
register struct expr *g = 0;
register struct expr *f = ex->OP_LEFT, *g = NILEXPR;
while (ISCOMMA(f)) { /* eat the brackets!!! */
g = f;
@ -150,8 +144,7 @@ do_array(ex, tpp)
/* declared with unknown size: [] */
for (elem_count = 0; ex; elem_count++) {
/* eat whole initialisation expression */
if (ISCOMMA(ex->OP_LEFT)) {
/* the member expression is embraced */
if (ISCOMMA(ex->OP_LEFT)) { /* embraced member */
if (IVAL(&(tp->tp_up), ex->OP_LEFT) != 0)
too_many_initialisers(ex);
ex = ex->OP_RIGHT;
@ -172,15 +165,13 @@ do_array(ex, tpp)
arith dim = tp->tp_size / tp->tp_up->tp_size;
for (elem_count = 0; elem_count < dim && ex; elem_count++) {
if (ISCOMMA(ex->OP_LEFT)) {
/* embraced member initialisation */
if (ISCOMMA(ex->OP_LEFT)) { /* embraced member */
if (IVAL(&(tp->tp_up), ex->OP_LEFT) != 0)
too_many_initialisers(ex);
ex = ex->OP_RIGHT;
}
else {
if (aggregate_type(tp->tp_up))
/* the member is an aggregate */
ex = IVAL(&(tp->tp_up), ex);
else {
check_ival(ex->OP_LEFT, tp->tp_up);
@ -194,7 +185,7 @@ do_array(ex, tpp)
is returned
*/
return ex;
if ((ex == 0) && elem_count < dim) {
if ((ex == 0) && elem_count < dim)
/* the expression tree is completely absorbed
but there are still members which must be
initialised with zeroes
@ -202,7 +193,6 @@ do_array(ex, tpp)
do
pad(tp->tp_up);
while (++elem_count < dim);
}
}
return 0;
}
@ -245,16 +235,14 @@ do_struct(ex, tp)
definition.
*/
put_bf(sd->sd_type, (arith)0);
else {
/* fundamental type, not embraced */
else { /* fundamental type, not embraced */
check_ival(ex->OP_LEFT, sd->sd_type);
ex = ex->OP_RIGHT;
}
#endif NOBITFIELD
}
}
/* align upto the next selector boundary */
if (sd->sd_sdef)
if (sd->sd_sdef) /* align upto the next selector boundary */
bytes_upto_here += zero_bytes(sd);
if (last_offset != sd->sd_offset) {
/* don't take the field-width more than once */
@ -266,9 +254,7 @@ do_struct(ex, tp)
}
/* perfect fit if (ex && (sd == 0)) holds */
if ((ex == 0) && (sd != 0)) {
/* there are selectors left which must be padded with
zeroes
*/
/* there are selectors left which must be padded with zeroes */
do {
pad(sd->sd_type);
/* take care of the alignment restrictions */
@ -307,7 +293,7 @@ check_and_pad(ex, tpp)
*/
tp = *tpp = construct_type(ARRAY, tp->tp_up, (arith)1);
else {
register dim = tp->tp_size / tp->tp_up->tp_size;
register int dim = tp->tp_size / tp->tp_up->tp_size;
/* pad remaining members with zeroes */
while (--dim > 0)
pad(tp->tp_up);
@ -320,7 +306,7 @@ check_and_pad(ex, tpp)
if (valid_type(tp, "struct") == 0)
return;
check_and_pad(ex, &(sd->sd_type));
/* Next selector is aligned by adding extra zeroes */
/* next selector is aligned by adding extra zeroes */
if (sd->sd_sdef)
zero_bytes(sd);
while (sd = sd->sd_sdef) { /* pad remaining selectors */
@ -346,10 +332,8 @@ pad(tp)
if (valid_type(tp->tp_up, "array element") == 0)
return;
dim = tp->tp_size / tp->tp_up->tp_size;
/* Assume the dimension is known */
/* assume dimension is known */
while (dim-- > 0)
pad(tp->tp_up);
break;
@ -360,7 +344,6 @@ pad(tp)
if (valid_type(tp, "struct") == 0)
return;
do {
pad(sdef->sd_type);
if (sdef->sd_sdef)
@ -462,10 +445,8 @@ check_ival(ex, tp)
/* float f = 1; */
ex = ex->OP_RIGHT;
if (is_cp_cst(ex))
C_con_fcon(
long2str((long)ex->VL_VALUE, 10),
tp->tp_size
);
C_con_fcon(long2str((long)ex->VL_VALUE, 10),
tp->tp_size);
else
illegal_init_cst(ex);
}
@ -509,7 +490,7 @@ ch_array(tpp, ex)
ASSERT(ex->ex_class == String);
length = ex->SG_LEN;
if (tp->tp_size == (arith)-1) {
if (tp->tp_size == (arith)-1) {
/* set the dimension */
tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
ntopad = align(tp->tp_size, word_align) - tp->tp_size;
@ -591,8 +572,7 @@ zero_bytes(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 -
register int n = sd->sd_sdef->sd_offset - sd->sd_offset -
size_of_type(sd->sd_type, "struct member");
register count = n;

View file

@ -7,7 +7,6 @@
#include "debug.h" /* UF */
#include "pathlength.h" /* UF */
#include "strsize.h" /* UF */
#include "alloc.h"
#include "idf.h"
#include "input.h"
@ -52,13 +51,11 @@ replace(idef)
}
actpars = getactuals(idef); /* get act.param. list */
}
if ((flags & PREDEF) && (UnknownIdIsZero == 0))
/* don't replace this one... */
return 0;
if ((flags & PREDEF) && (UnknownIdIsZero == 0)) /* don't replace */
return 0;
if (flags & FUNC) /* this macro leads to special action */
macro_func(idef);
/* create and input buffer */
reptext = macro2buffer(idef, actpars, &size);
reptext = macro2buffer(idef, actpars, &size); /* create input buffer */
InsertText(reptext, size);
return 1;
}
@ -74,8 +71,7 @@ macro_func(idef)
replacement texts must be evaluated at the time they are
used.
*/
/* This switch is very blunt... */
switch (idef->id_text[2]) {
switch (idef->id_text[2]) { /* This switch is very blunt... */
case 'F' : /* __FILE__ */
FilNamBuf[0] = '"';
strcpy(&FilNamBuf[1], FileName);
@ -126,8 +122,7 @@ macro2buffer(idef, actpars, siztext)
for (p = actpars[n - 1]; *p; p++) {
text[pos++] = *p;
if (pos == size)
text = Srealloc(text,
size += RSTRSIZE);
text = Srealloc(text, size += RSTRSIZE);
}
}
else {

View file

@ -27,7 +27,6 @@ static struct switch_hdr *switch_stack = 0;
- the expression E in "switch(E)" is cast to 'int' (RM 9.7)
- the expression E in "case E:" must be 'int' (RM 9.7)
- the values in the CSA/CSB tables are words (EM 7.4)
For simplicity, we suppose int_size == word_size.
*/
@ -42,7 +41,7 @@ code_startswitch(expp)
register struct switch_hdr *sh = new_switch_hdr();
int fund = any2arith(expp, SWITCH); /* INT, LONG or DOUBLE */
switch (fund) {
switch (fund) {
case LONG:
if (options['R'])
warning("long in switch (cast to int)");
@ -55,7 +54,6 @@ code_startswitch(expp)
break;
#endif NOFLOAT
}
stack_stmt(l_break, NO_LABEL);
sh->sh_break = l_break;
sh->sh_default = 0;
@ -66,8 +64,8 @@ code_startswitch(expp)
sh->sh_entries = (struct case_entry *) 0; /* case-entry list */
sh->next = switch_stack; /* push onto switch-stack */
switch_stack = sh;
/* evaluate the switch expr. */
code_expr(*expp, RVAL, TRUE, NO_LABEL, NO_LABEL);
/* evaluate the switch expr. */
C_bra(l_table); /* goto start of switch_table */
}
@ -93,7 +91,7 @@ code_endswitch()
ce = sh->sh_entries;
for (val = sh->sh_lowerbd; val <= sh->sh_upperbd; val++) {
ASSERT(ce);
if (val == ce->ce_value) {
if (val == ce->ce_value) {
C_rom_ilb(ce->ce_label);
ce = ce->next;
}
@ -103,9 +101,9 @@ code_endswitch()
C_lae_dlb(tablabel, (arith)0); /* perform the switch */
C_csa(sh->sh_type->tp_size);
}
else { /* CSB */
else { /* CSB */
C_rom_cst((arith)sh->sh_nrofentries);
for (ce = sh->sh_entries; ce; ce = ce->next) {
for (ce = sh->sh_entries; ce; ce = ce->next) {
/* generate the entries: value + prog.label */
C_rom_cst(ce->ce_value);
C_rom_ilb(ce->ce_label);
@ -115,11 +113,9 @@ code_endswitch()
}
C_df_ilb(sh->sh_break);
switch_stack = sh->next; /* unstack the switch descriptor */
/* free the allocated switch structure */
ce = sh->sh_entries;
while (ce) {
for (ce = sh->sh_entries; ce;) { /* free allocated switch structure */
register struct case_entry *tmp = ce->next;
free_case_entry(ce);
ce = tmp;
}
@ -135,28 +131,23 @@ code_case(expr)
register struct switch_hdr *sh = switch_stack;
ASSERT(is_cp_cst(expr));
if (sh == 0) {
if (sh == 0) {
error("case statement not in switch");
return;
}
if (expr->ex_flags & EX_ERROR) {
/* is probably 0 anyway */
if (expr->ex_flags & EX_ERROR) /* is probably 0 anyway */
return;
}
ch7cast(&expr, SWITCH, sh->sh_type);
ce = new_case_entry();
C_df_ilb(ce->ce_label = text_label());
ce->ce_value = val = expr->VL_VALUE;
if (sh->sh_entries == 0) {
/* first case entry */
if (sh->sh_entries == 0) { /* first case entry */
ce->next = (struct case_entry *) 0;
sh->sh_entries = ce;
sh->sh_lowerbd = sh->sh_upperbd = val;
sh->sh_nrofentries = 1;
}
else {
/* second etc. case entry */
/* find the proper place to put ce into the list */
else { /* second etc. case entry; put ce into proper place */
register struct case_entry *c1 = sh->sh_entries, *c2 = 0;
if (val < sh->sh_lowerbd)
@ -164,37 +155,34 @@ code_case(expr)
else
if (val > sh->sh_upperbd)
sh->sh_upperbd = val;
while (c1 && c1->ce_value < ce->ce_value) {
while (c1 && c1->ce_value < ce->ce_value) {
c2 = c1;
c1 = c1->next;
}
/* At this point three cases are possible:
1: c1 != 0 && c2 != 0:
insert ce somewhere in the middle
2: c1 != 0 && c2 == 0:
insert ce right after the head
3: c1 == 0 && c2 != 0:
append ce to last element
1: c1 != 0 && c2 != 0: insert ce somewhere in the middle
2: c1 != 0 && c2 == 0: insert ce right after the head
3: c1 == 0 && c2 != 0: append ce to last element
The case c1 == 0 && c2 == 0 cannot occur, since
the list is guaranteed not to be empty.
the list is guaranteed to be non-empty.
*/
if (c1) {
if (c1->ce_value == ce->ce_value) {
if (c1) {
if (c1->ce_value == ce->ce_value) {
error("multiple case entry for value %ld",
ce->ce_value);
free_case_entry(ce);
return;
}
if (c2) {
if (c2) {
ce->next = c2->next;
c2->next = ce;
}
else {
else {
ce->next = sh->sh_entries;
sh->sh_entries = ce;
}
}
else {
else {
ASSERT(c2);
ce->next = (struct case_entry *) 0;
c2->next = ce;
@ -207,13 +195,11 @@ code_default()
{
register struct switch_hdr *sh = switch_stack;
if (sh == 0) {
if (sh == 0)
error("default not in switch");
return;
}
if (sh->sh_default != 0) {
else
if (sh->sh_default != 0)
error("multiple entry for default in switch");
return;
}
C_df_ilb(sh->sh_default = text_label());
else
C_df_ilb(sh->sh_default = text_label());
}