Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom.ansi / ch3bin.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: ch3bin.c,v 1.21 1994/06/27 07:58:33 ceriel Exp $ */
6 /* SEMANTIC ANALYSIS (CHAPTER 3.3)  --  BINARY OPERATORS */
7
8 #include        "botch_free.h"
9 #include        "debug.h"
10 #include        <alloc.h>
11 #include        "lint.h"
12 #include        "idf.h"
13 #include        <flt_arith.h>
14 #include        "arith.h"
15 #include        "type.h"
16 #include        "struct.h"
17 #include        "label.h"
18 #include        "expr.h"
19 #include        "Lpars.h"
20 #include        "sizes.h"
21
22 extern char options[];
23 extern char *symbol2str();
24
25 /*      This chapter asks for the repeated application of code to handle
26         an operation that may be executed at compile time or at run time,
27         depending on the constancy of the operands.
28 */
29
30 /*
31  * Although the relational operators are generally not commutative, we can
32  * switch the arguments if the operator is adapted (e.g. < becomes >)
33  */
34 #define non_commutative_binop(expp, oper, expr) mk_binop(expp, oper, expr, 0)
35 #define commutative_binop(expp, oper, expr)     mk_binop(expp, oper, expr, 1)
36 #define non_commutative_relop(expp, oper, expr) mk_binop(expp, oper, expr, 1)
37
38 ch3bin(expp, oper, expr)
39         register struct expr **expp;
40         struct expr *expr;
41 {
42         /*      apply binary operator oper between *expp and expr.
43                 NB: don't swap operands if op is one of the op= operators!!!
44         */
45         register struct type *expp_tp;
46
47         any2opnd(expp, oper);
48         expp_tp = (*expp)->ex_type;
49         /* expp_tp can never be ARRAY, since any2opnd() converts the type
50          * to pointer (except for SIZEOF and unary &).
51          */
52         any2opnd(&expr, oper);
53         switch (oper)   {
54         case '[':                               /* 3.3.2.1 */
55                 /* indexing follows the commutative laws */
56                 switch (expp_tp->tp_fund)       {
57                 case POINTER:
58                         break;
59                 case ERRONEOUS:
60                         return;
61                 default:                /* unindexable */
62                         switch (expr->ex_type->tp_fund) {
63                         case POINTER:
64                                 break;
65                         case ERRONEOUS:
66                                 return;
67                         default:
68                                 expr_error(*expp,
69                                         "indexing an object of type %s",
70                                         symbol2str(expp_tp->tp_fund));
71                                 return;
72                         }
73                         break;
74                 }
75                 ch3bin(expp, '+', expr);
76                 ch3mon('*', expp);
77                 break;
78
79         case '(':                               /* 3.3.2.2 */
80                 if (expp_tp->tp_fund == POINTER
81                     && expp_tp->tp_up->tp_fund == FUNCTION)     {
82                         ch3mon('*', expp);
83                         expp_tp = (*expp)->ex_type;
84                 }
85                 if (expp_tp->tp_fund != FUNCTION)       {
86                         expr_error(*expp, "call of non-function (%s)",
87                                 symbol2str(expp_tp->tp_fund));
88                         /* leave the expression; it may still serve */
89                         free_expression(expr);  /* there go the parameters */
90                         *expp = new_oper(error_type,
91                                         *expp, '(', (struct expr *)0);
92                 }
93                 else
94                         *expp = new_oper(expp_tp->tp_up, *expp, '(', expr);
95                 (*expp)->ex_flags |= EX_SIDEEFFECTS;
96                 break;
97
98         case PARCOMMA:                          /* 3.3.2.2 */
99                 *expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
100                 break;
101
102         case '%':
103         case MODAB:
104         case ANDAB:
105         case XORAB:
106         case ORAB:
107                 opnd2integral(expp, oper);
108                 opnd2integral(&expr, oper);
109                 /* fallthrough */
110         case '/':
111         case DIVAB:
112         case TIMESAB:
113                 arithbalance(expp, oper, &expr);
114                 non_commutative_binop(expp, oper, expr);
115                 break;
116
117         case '&':
118         case '^':
119         case '|':
120                 opnd2integral(expp, oper);
121                 opnd2integral(&expr, oper);
122                 /* fallthrough */
123         case '*':
124                 arithbalance(expp, oper, &expr);
125                 commutative_binop(expp, oper, expr);
126                 break;
127
128         case '+':
129                 if (expr->ex_type->tp_fund == POINTER)  { /* swap operands */
130                         struct expr *etmp = expr;
131                         expp_tp = expr->ex_type;        /* both in registers */
132                         expr = *expp;
133                         *expp = etmp;
134                 }
135                 /* fallthrough */
136         case PLUSAB:
137         case POSTINCR:
138         case PLUSPLUS:
139                 if (expp_tp->tp_fund == POINTER)        {
140                         pointer_arithmetic(expp, oper, &expr);
141                         if (expr->ex_type->tp_size != (*expp)->ex_type->tp_size)
142                                 ch3cast(&expr, CAST, (*expp)->ex_type);
143                         pointer_binary(expp, oper, expr);
144                 }
145                 else    {
146                         arithbalance(expp, oper, &expr);
147                         if (oper == '+')
148                                 commutative_binop(expp, oper, expr);
149                         else
150                                 non_commutative_binop(expp, oper, expr);
151                 }
152                 break;
153
154         case '-':
155         case MINAB:
156         case POSTDECR:
157         case MINMIN:
158                 if (expp_tp->tp_fund == POINTER)        {
159                         if (expr->ex_type->tp_fund == POINTER)
160                                 pntminuspnt(expp, oper, expr);
161                         else {
162                                 pointer_arithmetic(expp, oper, &expr);
163                                 pointer_binary(expp, oper, expr);
164                         }
165                 }
166                 else    {
167                         arithbalance(expp, oper, &expr);
168                         non_commutative_binop(expp, oper, expr);
169                 }
170                 break;
171
172         case LEFT:
173         case RIGHT:
174         case LEFTAB:
175         case RIGHTAB:
176                 opnd2integral(expp, oper);
177                 opnd2integral(&expr, oper);
178                 arithbalance(expp, oper, &expr); /* ch. 3.3.7 */
179                 ch3cast(&expr, oper, int_type); /* cvt. rightop to int */
180                 non_commutative_binop(expp, oper, expr);
181                 break;
182
183         case '<':
184         case '>':
185         case LESSEQ:
186         case GREATEREQ:
187         case EQUAL:
188         case NOTEQUAL:
189                 relbalance(expp, oper, &expr);
190                 non_commutative_relop(expp, oper, expr);
191                 (*expp)->ex_type = int_type;
192                 break;
193
194         case AND:
195         case OR:
196                 opnd2test(expp, oper);
197                 opnd2test(&expr, oper);
198                 if (is_cp_cst(*expp))   {
199                         register struct expr *ex = *expp;
200
201                         /* the following condition is a short-hand for
202                                 ((oper == AND) && o1) || ((oper == OR) && !o1)
203                                 where o1 == (*expp)->VL_VALUE;
204                                 and ((oper == AND) || (oper == OR))
205                         */
206                         if ((oper == AND) == (ex->VL_VALUE != (arith)0)) {
207                                 *expp = expr;
208                         }
209                         else {
210                                 ex->ex_flags |= expr->ex_flags;
211                                 free_expression(expr);
212                                 *expp = intexpr((arith)(oper != AND), INT);
213                         }
214                         (*expp)->ex_flags |= ex->ex_flags | EX_ILVALUE;
215                         free_expression(ex);
216                 }
217                 else
218                 if (is_cp_cst(expr))    {
219                         /* Note!!!: the following condition is a short-hand for
220                                 ((oper == AND) && o2) || ((oper == OR) && !o2)
221                                 where o2 == expr->VL_VALUE
222                                 and ((oper == AND) || (oper == OR))
223                         */
224                         if ((oper == AND) == (expr->VL_VALUE != (arith)0)) {
225                                 (*expp)->ex_flags |= expr->ex_flags | EX_ILVALUE;
226                                 free_expression(expr);
227                         }
228                         else {
229                                 if (oper == OR)
230                                         expr->VL_VALUE = (arith)1;
231                                 ch3bin(expp, ',', expr);
232                         }
233                 }
234                 else {
235                         *expp = new_oper(int_type, *expp, oper, expr);
236                 }
237                 (*expp)->ex_flags |= EX_LOGICAL;
238                 break;
239
240         case ':':
241                 if (is_struct_or_union(expp_tp->tp_fund)
242                     || is_struct_or_union(expr->ex_type->tp_fund))      {
243                         if (!equal_type(expp_tp, expr->ex_type, -1, 0))
244                                 expr_error(*expp, "illegal balance");
245                 }
246                 else 
247                         relbalance(expp, oper, &expr);
248 #ifdef  LINT
249                 if (    (is_cp_cst(*expp) && is_cp_cst(expr))
250                 &&      (*expp)->VL_VALUE == expr->VL_VALUE
251                 ) {
252                         hwarning("operands of : are constant and equal");
253                 }
254 #endif  /* LINT */
255                 *expp = new_oper((*expp)->ex_type, *expp, oper, expr);
256                 break;
257
258         case '?':
259                 opnd2logical(expp, oper);
260                 if (is_cp_cst(*expp)) {
261 #ifdef  LINT
262                         hwarning("condition in ?: expression is constant");
263 #endif  /* LINT */
264                         if ((*expp)->VL_VALUE) {
265                                 free_expression(*expp);
266                                 free_expression(expr->OP_RIGHT);
267                                 *expp = expr->OP_LEFT;
268                         }
269                         else {
270                                 free_expression(*expp);
271                                 free_expression(expr->OP_LEFT);
272                                 *expp = expr->OP_RIGHT;
273                         }
274                         free_expr(expr);
275                         (*expp)->ex_flags |= EX_ILVALUE;
276                 }
277                 else {
278                         *expp = new_oper(expr->ex_type, *expp, oper, expr);
279                 }
280                 break;
281
282         case ',':
283                 if (is_cp_cst(*expp)) {
284 #ifdef  LINT
285                         hwarning("constant expression ignored");
286 #endif  /* LINT */
287                         free_expression(*expp);
288                         *expp = expr;
289                 }
290                 else {
291                         *expp = new_oper(expr->ex_type, *expp, oper, expr);
292                 }
293                 (*expp)->ex_flags |= EX_COMMA;
294                 break;
295         }
296 }
297
298 pntminuspnt(expp, oper, expr)
299         register struct expr **expp, *expr;
300 {
301         /*      Subtracting two pointers is so complicated it merits a
302                 routine of its own.
303         */
304         struct type *up_type = (*expp)->ex_type->tp_up;
305
306         if (!equal_type(up_type, expr->ex_type->tp_up, -1, 0)) {
307                 expr_error(*expp, "subtracting incompatible pointers");
308                 free_expression(expr);
309                 erroneous2int(expp);
310                 return;
311         }
312         /*      we hope the optimizer will eliminate the load-time
313                 pointer subtraction
314         */
315         *expp = new_oper((*expp)->ex_type, *expp, oper, expr);
316         ch3cast(expp, CAST, pa_type);   /* ptr-ptr: result has pa_type  */
317         ch3bin(expp, '/'
318                 , intexpr(size_of_type(up_type, symbol2str(up_type->tp_fund))
319                             , pa_type->tp_fund));
320         ch3cast(expp, CAST, pa_type);   /* result will be an integral expr */
321                                         /* cast necessary ??? */
322         if (int_size != pointer_size) (*expp)->ex_flags |= EX_PTRDIFF;
323 }
324
325 /*
326  * The function arg_switched() returns the operator that should be used
327  * when the arguments are switched.  This is special for some relational
328  * operators.
329  */
330 int
331 arg_switched(oper)
332 {
333         switch (oper) {
334         case '<':       return '>';
335         case '>':       return '<';
336         case LESSEQ:    return GREATEREQ;
337         case GREATEREQ: return LESSEQ;
338         default:        return oper;
339         }
340 }
341
342 mk_binop(expp, oper, expr, commutative)
343         struct expr **expp;
344         register struct expr *expr;
345 {
346         /*      Constructs in *expp the operation indicated by the operands.
347                 "commutative" indicates whether "oper" is a commutative
348                 operator.
349         */
350         register struct expr *ex = *expp;
351
352         if (is_cp_cst(expr) && is_cp_cst(ex))
353                 cstbin(expp, oper, expr);
354         else if (is_fp_cst(expr) && is_fp_cst(ex))
355                 fltcstbin(expp, oper, expr);
356         else {
357                 *expp = (commutative
358                         && !(ex->ex_flags & EX_VOLATILE)
359                         && (expr->ex_depth > ex->ex_depth
360                             || ((expr->ex_flags & EX_SIDEEFFECTS)
361                                 && !(ex->ex_flags & EX_SIDEEFFECTS))
362                             || is_cp_cst(ex)))
363                         ? new_oper(ex->ex_type, expr, arg_switched(oper), ex)
364                         : new_oper(ex->ex_type, ex, oper, expr);
365         }
366 }
367
368 pointer_arithmetic(expp1, oper, expp2)
369         register struct expr **expp1, **expp2;
370 {
371         int typ;
372         /*      prepares the integral expression expp2 in order to
373                 apply it to the pointer expression expp1
374         */
375         if ((typ = any2arith(expp2, oper)) == FLOAT
376             || typ == DOUBLE
377             || typ == LNGDBL)   {
378                 expr_error(*expp2,
379                         "illegal combination of %s and pointer",
380                         symbol2str(typ));
381                 erroneous2int(expp2);
382         }
383         ch3bin( expp2, '*',
384                 intexpr(size_of_type((*expp1)->ex_type->tp_up, "object"),
385                         pa_type->tp_fund)
386         );
387 }
388
389 pointer_binary(expp, oper, expr)
390         register struct expr **expp, *expr;
391 {
392         /*      constructs the pointer arithmetic expression out of
393                 a pointer expression, a binary operator and an integral
394                 expression.
395         */
396         if (is_ld_cst(expr) && is_ld_cst(*expp))
397                 cstbin(expp, oper, expr);
398         else
399                 *expp = new_oper((*expp)->ex_type, *expp, oper, expr);
400 }