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
case ANDAB:
case ORAB:
case XORAB:
+ case PLUSPLUS:
+ case POSTINCR:
+ case MINMIN:
+ case POSTDECR:
return 1;
default:
return 0;
/* $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,
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
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
}
}
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 */
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
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);
}
/* 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)
(*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");
else
expr = extmp;
}
-
#ifndef NOBITFIELD
if (fund == FIELD)
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
#else NOBITFIELD
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
#endif NOBITFIELD
-
(*expp)->OP_TYPE = tp; /* for EVAL() */
}
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);
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 {
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);
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 '?':
#include "atw.h"
#include "assert.h"
-static struct stmt_block *stmt_stack;
+label lab_count = 1;
+label datlab_count = 1;
-char *symbol2str();
#ifndef NOFLOAT
int fp_used;
#endif NOFLOAT
-label lab_count = 1;
-label datlab_count = 1;
extern char options[];
+char *symbol2str();
init_code(dst_file)
char *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();
}
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.
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);
}
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);
}
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:
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:
free_expression(expr);
return;
}
-
if (ISCOMMA(expr)) { /* embraced: int i = {12}; */
if (options['R']) {
if (ISCOMMA(expr->OP_LEFT)) /* int i = {{1}} */
*/
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)
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 */
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.
{
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
/* $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"
#include "parbufsize.h"
#include "textsize.h"
#include "idfsize.h"
-
#include "assert.h"
#include "alloc.h"
#include "class.h"
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();
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");
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();
/* $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"
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);
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)
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:
}
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:
}
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)
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
}
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:
}
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:
}
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)
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);
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);
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);
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();
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;
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:
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
+ 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 {
- load_val(leftop, RVAL);
+ else {
+ 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(leftop->ex_type, tp);
- EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
+ 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);
- 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);
+ 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 {
- store_val(
- &(leftop->ex_object.ex_value),
- leftop->ex_type
- );
+ 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 '(':
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
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 */
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);
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);
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);
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:
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:
int relop;
label lbl;
{
- switch (relop) {
+ switch (relop) {
case '<':
C_zlt(lbl);
break;
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:
#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
- switch (oper) {
+ switch (oper) {
case PLUSAB:
case PLUSPLUS:
case POSTINCR:
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
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;
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);
}
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
}
}
- else {
+ else {
C_lae_dlb(expr->VL_LBL, (arith)0);
C_adp(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
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
df->df_register = REG_NONE;
}
}
- else {
+ else {
C_lal(df->df_address);
C_adp(val);
df->df_register = REG_NONE;
}
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)
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;
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
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 *
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;
op->op_oper = oper;
op->op_left = e1;
op->op_right = e2;
-
return expr;
}
#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");
{
/* 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);
}
#ifndef NOBITFIELD
#include <em.h>
-
#include "debug.h"
-
#include "arith.h"
#include "type.h"
#include "idf.h"
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);
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
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)
/* 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);
break;
}
}
-
/* The tests on types, postponed from do_decspecs(), can now
be performed.
*/
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);
*/
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));
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) {
/** 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 =
}
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;
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
) {
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"
*/
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 */
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",
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);
/* 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;
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;
char *symbol2str();
char *long2str();
-
struct expr *do_array(), *do_struct(), *IVAL();
/* do_ival() performs the initialisation of a global variable
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");
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
*/
return ex->OP_RIGHT;
}
- /* "int i = 12;" */
- check_ival(ex, tp);
+ check_ival(ex, tp); /* "int i = 12;" */
break;
}
return 0;
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;
/* 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;
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);
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
do
pad(tp->tp_up);
while (++elem_count < dim);
- }
}
return 0;
}
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 */
}
/* 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 */
*/
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);
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 */
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;
if (valid_type(tp, "struct") == 0)
return;
-
do {
pad(sdef->sd_type);
if (sdef->sd_sdef)
/* 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);
}
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;
/* 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;
#include "debug.h" /* UF */
#include "pathlength.h" /* UF */
#include "strsize.h" /* UF */
-
#include "alloc.h"
#include "idf.h"
#include "input.h"
}
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;
}
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);
for (p = actpars[n - 1]; *p; p++) {
text[pos++] = *p;
if (pos == size)
- text = Srealloc(text,
- size += RSTRSIZE);
+ text = Srealloc(text, size += RSTRSIZE);
}
}
else {
- 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.
*/
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)");
break;
#endif NOFLOAT
}
-
stack_stmt(l_break, NO_LABEL);
sh->sh_break = l_break;
sh->sh_default = 0;
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 */
}
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;
}
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);
}
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;
}
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)
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;
{
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());
}