From 5af21dfc79e5d349d698aa94b27363cef387f1cb Mon Sep 17 00:00:00 2001 From: erikb Date: Mon, 29 Sep 1986 14:01:34 +0000 Subject: [PATCH] modified the treatment of op=, ++ and -- operators --- lang/cem/cemcom/Makefile.erik | 3 +- lang/cem/cemcom/arith.c | 4 + lang/cem/cemcom/blocks.c | 88 ++++++- lang/cem/cemcom/ch7.c | 51 +--- lang/cem/cemcom/ch7bin.c | 28 +-- lang/cem/cemcom/code.c | 69 ++---- lang/cem/cemcom/declarator.c | 2 +- lang/cem/cemcom/domacro.c | 13 +- lang/cem/cemcom/eval.c | 449 ++++++++++++++-------------------- lang/cem/cemcom/expr.c | 65 ++--- lang/cem/cemcom/field.c | 32 +-- lang/cem/cemcom/idf.c | 69 ++---- lang/cem/cemcom/ival.c | 60 ++--- lang/cem/cemcom/replace.c | 15 +- lang/cem/cemcom/switch.c | 66 ++--- 15 files changed, 417 insertions(+), 597 deletions(-) diff --git a/lang/cem/cemcom/Makefile.erik b/lang/cem/cemcom/Makefile.erik index 8e7b76aae..4f1c3217c 100644 --- a/lang/cem/cemcom/Makefile.erik +++ b/lang/cem/cemcom/Makefile.erik @@ -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 diff --git a/lang/cem/cemcom/arith.c b/lang/cem/cemcom/arith.c index bcf6047c9..c11ad70c9 100644 --- a/lang/cem/cemcom/arith.c +++ b/lang/cem/cemcom/arith.c @@ -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; diff --git a/lang/cem/cemcom/blocks.c b/lang/cem/cemcom/blocks.c index 3e4640d3e..1d769939e 100644 --- a/lang/cem/cemcom/blocks.c +++ b/lang/cem/cemcom/blocks.c @@ -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 -#include "arith.h" -#include "sizes.h" -#include "atw.h" +#include +#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 diff --git a/lang/cem/cemcom/ch7.c b/lang/cem/cemcom/ch7.c index 1317571c0..356497d2b 100644 --- a/lang/cem/cemcom/ch7.c +++ b/lang/cem/cemcom/ch7.c @@ -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() */ } diff --git a/lang/cem/cemcom/ch7bin.c b/lang/cem/cemcom/ch7bin.c index 848f14cf5..484b1caf8 100644 --- a/lang/cem/cemcom/ch7bin.c +++ b/lang/cem/cemcom/ch7bin.c @@ -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 '?': diff --git a/lang/cem/cemcom/code.c b/lang/cem/cemcom/code.c index a5c245deb..665dc38c1 100644 --- a/lang/cem/cemcom/code.c +++ b/lang/cem/cemcom/code.c @@ -28,16 +28,15 @@ #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; @@ -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 diff --git a/lang/cem/cemcom/declarator.c b/lang/cem/cemcom/declarator.c index f74705fb1..33bb4e8fa 100644 --- a/lang/cem/cemcom/declarator.c +++ b/lang/cem/cemcom/declarator.c @@ -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" diff --git a/lang/cem/cemcom/domacro.c b/lang/cem/cemcom/domacro.c index f215b5bb2..b3d32151a 100644 --- a/lang/cem/cemcom/domacro.c +++ b/lang/cem/cemcom/domacro.c @@ -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(); diff --git a/lang/cem/cemcom/eval.c b/lang/cem/cemcom/eval.c index 4923c857d..7a08dbccc 100644 --- a/lang/cem/cemcom/eval.c +++ b/lang/cem/cemcom/eval.c @@ -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 #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 + 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 '(': @@ -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; diff --git a/lang/cem/cemcom/expr.c b/lang/cem/cemcom/expr.c index 282e3391d..cdfaa5a5a 100644 --- a/lang/cem/cemcom/expr.c +++ b/lang/cem/cemcom/expr.c @@ -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); } diff --git a/lang/cem/cemcom/field.c b/lang/cem/cemcom/field.c index 747656ad6..63c1b61bd 100644 --- a/lang/cem/cemcom/field.c +++ b/lang/cem/cemcom/field.c @@ -5,9 +5,7 @@ #ifndef NOBITFIELD #include - #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)<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) diff --git a/lang/cem/cemcom/idf.c b/lang/cem/cemcom/idf.c index 92a3f7362..200a05ab7 100644 --- a/lang/cem/cemcom/idf.c +++ b/lang/cem/cemcom/idf.c @@ -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; diff --git a/lang/cem/cemcom/ival.c b/lang/cem/cemcom/ival.c index 755254989..f7e941218 100644 --- a/lang/cem/cemcom/ival.c +++ b/lang/cem/cemcom/ival.c @@ -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; diff --git a/lang/cem/cemcom/replace.c b/lang/cem/cemcom/replace.c index 675d37d27..b64e4fedf 100644 --- a/lang/cem/cemcom/replace.c +++ b/lang/cem/cemcom/replace.c @@ -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 { diff --git a/lang/cem/cemcom/switch.c b/lang/cem/cemcom/switch.c index 8a3fa20d8..759b97dc0 100644 --- a/lang/cem/cemcom/switch.c +++ b/lang/cem/cemcom/switch.c @@ -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()); } -- 2.34.1