Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom.ansi / ch3mon.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: ch3mon.c,v 1.17 1994/06/27 07:58:37 ceriel Exp $ */
6 /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
7
8 #include        "botch_free.h"
9 #include        "debug.h"
10 #include        <alloc.h>
11 #include        "nobitfield.h"
12 #include        "Lpars.h"
13 #include        <flt_arith.h>
14 #include        "arith.h"
15 #include        "type.h"
16 #include        "label.h"
17 #include        "expr.h"
18 #include        "idf.h"
19 #include        "def.h"
20 #include        "sizes.h"
21
22 extern char options[];
23 extern arith full_mask[/*MAXSIZE*/];    /* cstoper.c */
24 char *symbol2str();
25
26 ch3mon(oper, expp)
27         register struct expr **expp;
28 {
29         /*      The monadic prefix operator oper is applied to *expp.
30         */
31         register struct expr *expr;
32
33         if (oper != PLUSPLUS && oper != MINMIN)
34                 any2opnd(expp, oper);
35
36         switch (oper)   {
37         case '*':                       /* 3.3.3.2 */
38                 /* no FIELD type allowed        */
39                 expr = *expp;
40                 if (expr->ex_type->tp_fund != POINTER) {
41                         if (expr->ex_type != error_type) {
42                             expr_error(expr,
43                                     "* applied to non-pointer (%s)",
44                                     symbol2str(expr->ex_type->tp_fund));
45                         }
46                 } else {
47                         if (is_ld_cst(expr))
48                                 /* dereference in administration only */
49                                 expr->ex_type = expr->ex_type->tp_up;
50                         else    /* runtime code */
51                                 *expp = new_oper(expr->ex_type->tp_up, NILEXPR,
52                                                         '*', expr);
53                         expr = *expp;
54                         expr->ex_lvalue = (
55                                 expr->ex_type->tp_fund != ARRAY &&
56                                 expr->ex_type->tp_fund != FUNCTION
57                                 );
58                         if (expr->ex_lvalue && expr->ex_type->tp_size <= 0) {
59                                 expr_error(expr, "incomplete type in expression");
60                         }
61                         if (expr->ex_type->tp_typequal & TQ_CONST)
62                                 expr->ex_flags |= EX_READONLY;
63                         if (expr->ex_type->tp_typequal & TQ_VOLATILE)
64                                 expr->ex_flags |= EX_VOLATILE;
65                         expr->ex_flags &= ~EX_ILVALUE;
66                 }
67                 break;
68         case ADDRESSOF:
69                 if ((*expp)->ex_type->tp_fund == ARRAY) {
70                         (*expp)->ex_type = pointer_to((*expp)->ex_type, 0);
71                 }
72                 else
73                 if ((*expp)->ex_type->tp_fund == FUNCTION) {
74                         (*expp)->ex_type = pointer_to((*expp)->ex_type, 0);
75                 }
76                 else
77 #ifndef NOBITFIELD
78                 if ((*expp)->ex_type->tp_fund == FIELD)
79                         expr_error(*expp, "& applied to field variable");
80                 else
81 #endif /* NOBITFIELD */
82                 if (!(*expp)->ex_lvalue)
83                         expr_error(*expp, "& applied to non-lvalue");
84                 else if ((*expp)->ex_flags & EX_ILVALUE)
85                         expr_error(*expp, "& applied to illegal lvalue");
86                 else {
87                         /* assume that enums are already filtered out   */
88                         if (ISNAME(*expp)) {
89                                 register struct def *def =
90                                         (*expp)->VL_IDF->id_def;
91
92                                 /*      &<var> indicates that <var>
93                                         cannot be used as register
94                                         anymore
95                                 */
96                                 if (def->df_sc == REGISTER) {
97                                         expr_error(*expp,
98                                         "& on register variable not allowed");
99                                         break;  /* break case ADDRESSOF */
100                                 }
101                         }
102                         (*expp)->ex_type = pointer_to((*expp)->ex_type,
103                                                 (*expp)->ex_type->tp_typequal);
104                         (*expp)->ex_lvalue = 0;
105                         (*expp)->ex_flags &= ~(EX_READONLY | EX_VOLATILE);
106                 }
107                 break;
108         case '~':
109         {
110                 int fund = (*expp)->ex_type->tp_fund;
111
112                 if (fund == FLOAT || fund == DOUBLE || fund == LNGDBL)  {
113                         expr_error( *expp,
114                                     "~ not allowed on %s operands",
115                                     symbol2str(fund));
116                         erroneous2int(expp);
117                         break;
118                 }
119                 /* FALLTHROUGH */
120         }
121         case '-':
122                 any2arith(expp, oper);
123                 if (is_cp_cst(*expp))   {
124                         arith o1 = (*expp)->VL_VALUE;
125
126                         (*expp)->VL_VALUE = (oper == '-') ? -o1 :
127                           ((*expp)->ex_type->tp_unsigned ?
128                                 (~o1) & full_mask[(int)(*expp)->ex_type->tp_size] :
129                                 ~o1
130                           );
131                 }
132                 else
133                 if (is_fp_cst(*expp))
134                         switch_sign_fp(*expp);
135                 else
136                         *expp = new_oper((*expp)->ex_type,
137                                         NILEXPR, oper, *expp);
138                 break;
139         case '!':
140                 opnd2test(expp, '!');
141                 if (is_cp_cst(*expp))   {
142                         (*expp)->VL_VALUE = !((*expp)->VL_VALUE);
143                         (*expp)->ex_type = int_type;    /* a cast ???(EB) */
144                 }
145                 else
146                         *expp = new_oper(int_type, NILEXPR, oper, *expp);
147                 (*expp)->ex_flags |= EX_LOGICAL;
148                 break;
149         case PLUSPLUS:
150         case MINMIN:
151                 ch3incr(expp, oper);
152                 break;
153         case SIZEOF:
154                 if (ISNAME(*expp) && (*expp)->VL_IDF->id_def->df_formal_array)
155                         expr_warning(*expp, "sizeof formal array %s is sizeof pointer!",
156                                 (*expp)->VL_IDF->id_text);
157                 expr = intexpr((*expp)->ex_class == String ?
158                                    (arith)((*expp)->SG_LEN) :
159                                    size_of_type((*expp)->ex_type,
160                                        symbol2str((*expp)->ex_type->tp_fund))
161                                , UNSIGNED);
162                 expr->ex_flags |= EX_SIZEOF;
163                 free_expression(*expp);
164                 *expp = expr;
165                 break;
166         }
167 }