|
1 /* |
|
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
|
3 * |
|
4 * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) |
|
5 * Copyright (C) 2012 Manuele Conti (conti.ma@alice.it) |
|
6 * |
|
7 * This program is free software: you can redistribute it and/or modify |
|
8 * it under the terms of the GNU General Public License as published by |
|
9 * the Free Software Foundation, either version 3 of the License, or |
|
10 * (at your option) any later version. |
|
11 * |
|
12 * This program is distributed in the hope that it will be useful, |
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
15 * GNU General Public License for more details. |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License |
|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
19 * |
|
20 * |
|
21 * This code is made available on the understanding that it will not be |
|
22 * used in safety-critical situations without a full and competent review. |
|
23 */ |
|
24 |
|
25 /* |
|
26 * An IEC 61131-3 compiler. |
|
27 * |
|
28 * Based on the |
|
29 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
|
30 * |
|
31 */ |
|
32 |
|
33 |
|
34 /* Determine the value of an ST expression. |
|
35 * Filling in all symbols the correct value. |
|
36 * |
|
37 * For example: |
|
38 * 2 + 3 -> returns constant_value_integer = 5 |
|
39 * 22.2 - 5.0 -> returns constant_value_real = 17.2 |
|
40 * etc... |
|
41 */ |
|
42 |
|
43 #include "constant_folding.hh" |
|
44 #include <typeinfo> |
|
45 #include <limits> |
|
46 #include <math.h> /* required for pow function */ |
|
47 |
|
48 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
|
49 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
|
50 |
|
51 #define STAGE3_ERROR(error_level, symbol1, symbol2, ...) { \ |
|
52 if (current_display_error_level >= error_level) { \ |
|
53 fprintf(stderr, "%s:%d-%d..%d-%d: error: ", \ |
|
54 FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ |
|
55 LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ |
|
56 fprintf(stderr, __VA_ARGS__); \ |
|
57 fprintf(stderr, "\n"); \ |
|
58 error_count++; \ |
|
59 } \ |
|
60 } |
|
61 |
|
62 |
|
63 #define STAGE3_WARNING(symbol1, symbol2, ...) { \ |
|
64 fprintf(stderr, "%s:%d-%d..%d-%d: warning: ", \ |
|
65 FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ |
|
66 LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ |
|
67 fprintf(stderr, __VA_ARGS__); \ |
|
68 fprintf(stderr, "\n"); \ |
|
69 warning_found = true; \ |
|
70 } |
|
71 |
|
72 |
|
73 |
|
74 #define DO_OPER(dtype)\ |
|
75 (NULL != symbol->r_exp->const_value_##dtype ) && \ |
|
76 (NULL != symbol->l_exp->const_value_##dtype ) |
|
77 |
|
78 |
|
79 #define CHECK_OVERFLOW_SUM(a, b, type)\ |
|
80 ((((std::numeric_limits< type >::max() - a) < (b)) ? 1 : 0) || \ |
|
81 (((std::numeric_limits< type >::min() + a) > (b)) ? 1 : 0)) |
|
82 |
|
83 #define CHECK_OVERFLOW_SUB(a, b, type)\ |
|
84 ((((std::numeric_limits< type >::max() - a) < (-b)) ? 1 : 0) || \ |
|
85 (((std::numeric_limits< type >::min() + a) > (-b)) ? 1 : 0)) |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 constant_folding_c::constant_folding_c(symbol_c *symbol) { |
|
92 error_count = 0; |
|
93 current_display_error_level = 0; |
|
94 } |
|
95 |
|
96 constant_folding_c::~constant_folding_c(void) { |
|
97 } |
|
98 |
|
99 int constant_folding_c::get_error_count() { |
|
100 return error_count; |
|
101 } |
|
102 |
|
103 |
|
104 /*********************/ |
|
105 /* B 1.2 - Constants */ |
|
106 /*********************/ |
|
107 /******************************/ |
|
108 /* B 1.2.1 - Numeric Literals */ |
|
109 /******************************/ |
|
110 void *constant_folding_c::visit(real_c *symbol) { |
|
111 double *real_value; |
|
112 |
|
113 real_value = (double *)malloc(sizeof(double)); |
|
114 sscanf(symbol->value, "%lf", real_value); |
|
115 symbol->const_value_real = real_value; |
|
116 |
|
117 return NULL; |
|
118 } |
|
119 |
|
120 void *constant_folding_c::visit(integer_c *symbol) { |
|
121 int64_t *integer_value; |
|
122 |
|
123 integer_value = (int64_t *)malloc(sizeof(int64_t)); |
|
124 *integer_value = extract_integer_value(symbol); |
|
125 symbol->const_value_integer = integer_value; |
|
126 |
|
127 return NULL; |
|
128 } |
|
129 |
|
130 void *constant_folding_c::visit(neg_real_c *symbol) { |
|
131 double *real_value; |
|
132 |
|
133 real_value = (double *)malloc(sizeof(double)); |
|
134 symbol->exp->accept(*this); |
|
135 if (NULL == symbol->exp->const_value_real) |
|
136 ERROR; |
|
137 *real_value = - *(symbol->exp->const_value_real); |
|
138 symbol->const_value_real = real_value; |
|
139 |
|
140 return NULL; |
|
141 } |
|
142 |
|
143 void *constant_folding_c::visit(neg_integer_c *symbol) { |
|
144 int64_t *integer_value; |
|
145 |
|
146 integer_value = (int64_t *)malloc(sizeof(int64_t)); |
|
147 *integer_value = extract_integer_value(symbol); |
|
148 symbol->const_value_integer = integer_value; |
|
149 |
|
150 return NULL; |
|
151 } |
|
152 |
|
153 void *constant_folding_c::visit(binary_integer_c *symbol) { |
|
154 |
|
155 return NULL; |
|
156 } |
|
157 |
|
158 void *constant_folding_c::visit(octal_integer_c *symbol) { |
|
159 |
|
160 return NULL; |
|
161 } |
|
162 |
|
163 void *constant_folding_c::visit(hex_integer_c *symbol) { |
|
164 int64_t *integer_value; |
|
165 |
|
166 integer_value = (int64_t *)malloc(sizeof(int64_t)); |
|
167 *integer_value = extract_hex_value(symbol); |
|
168 |
|
169 return NULL; |
|
170 } |
|
171 |
|
172 void *constant_folding_c::visit(integer_literal_c *symbol) { |
|
173 int64_t *integer_value; |
|
174 |
|
175 symbol->value->accept(*this); |
|
176 if (NULL == symbol->value->const_value_integer) ERROR; |
|
177 *(symbol->const_value_integer) = *(symbol->value->const_value_integer); |
|
178 integer_value = (int64_t *)malloc(sizeof(int64_t)); |
|
179 |
|
180 return NULL; |
|
181 } |
|
182 |
|
183 void *constant_folding_c::visit(real_literal_c *symbol) { |
|
184 double *real_value; |
|
185 |
|
186 real_value = (double *)malloc(sizeof(double)); |
|
187 symbol->value->accept(*this); |
|
188 if (NULL == symbol->value->const_value_real) |
|
189 ERROR; |
|
190 *real_value = *(symbol->value->const_value_real); |
|
191 symbol->const_value_real = real_value; |
|
192 |
|
193 return NULL; |
|
194 } |
|
195 |
|
196 void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
|
197 |
|
198 return NULL; |
|
199 } |
|
200 |
|
201 void *constant_folding_c::visit(boolean_literal_c *symbol) { |
|
202 symbol->value->accept(*this); |
|
203 if (NULL == symbol->value->const_value_bool) ERROR; |
|
204 symbol->const_value_bool = (bool *)malloc(sizeof(bool)); |
|
205 *(symbol->const_value_bool) = *(symbol->value->const_value_bool); |
|
206 |
|
207 return NULL; |
|
208 } |
|
209 |
|
210 void *constant_folding_c::visit(boolean_true_c *symbol) { |
|
211 symbol->const_value_bool = (bool *)malloc(sizeof(bool)); |
|
212 *(symbol->const_value_bool) = true; |
|
213 |
|
214 return NULL; |
|
215 } |
|
216 |
|
217 void *constant_folding_c::visit(boolean_false_c *symbol) { |
|
218 symbol->const_value_bool = (bool *)malloc(sizeof(bool)); |
|
219 *(symbol->const_value_bool) = false; |
|
220 |
|
221 return NULL; |
|
222 } |
|
223 |
|
224 /***************************************/ |
|
225 /* B.3 - Language ST (Structured Text) */ |
|
226 /***************************************/ |
|
227 /***********************/ |
|
228 /* B 3.1 - Expressions */ |
|
229 /***********************/ |
|
230 void *constant_folding_c::visit(or_expression_c *symbol) { |
|
231 symbol->l_exp->accept(*this); |
|
232 symbol->r_exp->accept(*this); |
|
233 if (DO_OPER(bool)) { |
|
234 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
235 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) || *(symbol->r_exp->const_value_bool); |
|
236 } |
|
237 if (DO_OPER(integer)) { |
|
238 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
239 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) | *(symbol->r_exp->const_value_integer); |
|
240 } |
|
241 |
|
242 return NULL; |
|
243 } |
|
244 |
|
245 void *constant_folding_c::visit(xor_expression_c *symbol) { |
|
246 symbol->l_exp->accept(*this); |
|
247 symbol->r_exp->accept(*this); |
|
248 if (DO_OPER(integer)) { |
|
249 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
250 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) ^ *(symbol->r_exp->const_value_integer); |
|
251 } |
|
252 |
|
253 return NULL; |
|
254 } |
|
255 |
|
256 void *constant_folding_c::visit(and_expression_c *symbol) { |
|
257 symbol->l_exp->accept(*this); |
|
258 symbol->r_exp->accept(*this); |
|
259 if (DO_OPER(bool)) { |
|
260 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
261 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) && *(symbol->r_exp->const_value_bool); |
|
262 } |
|
263 if (DO_OPER(integer)) { |
|
264 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
265 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) & *(symbol->r_exp->const_value_integer); |
|
266 } |
|
267 |
|
268 return NULL; |
|
269 } |
|
270 |
|
271 void *constant_folding_c::visit(equ_expression_c *symbol) { |
|
272 symbol->l_exp->accept(*this); |
|
273 symbol->r_exp->accept(*this); |
|
274 if (DO_OPER(bool)) { |
|
275 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
276 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) == *(symbol->r_exp->const_value_bool); |
|
277 } |
|
278 if (DO_OPER(integer)) { |
|
279 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
280 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) == *(symbol->r_exp->const_value_integer); |
|
281 } |
|
282 if (DO_OPER(real)) { |
|
283 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
284 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) == *(symbol->r_exp->const_value_real); |
|
285 } |
|
286 |
|
287 return NULL; |
|
288 } |
|
289 |
|
290 void *constant_folding_c::visit(notequ_expression_c *symbol) { |
|
291 symbol->l_exp->accept(*this); |
|
292 symbol->r_exp->accept(*this); |
|
293 if (DO_OPER(bool)) { |
|
294 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
295 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) != *(symbol->r_exp->const_value_bool); |
|
296 } |
|
297 if (DO_OPER(integer)) { |
|
298 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
299 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) != *(symbol->r_exp->const_value_integer); |
|
300 } |
|
301 if (DO_OPER(real)) { |
|
302 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
303 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) != *(symbol->r_exp->const_value_real); |
|
304 } |
|
305 |
|
306 return NULL; |
|
307 } |
|
308 |
|
309 void *constant_folding_c::visit(lt_expression_c *symbol) { |
|
310 symbol->l_exp->accept(*this); |
|
311 symbol->r_exp->accept(*this); |
|
312 if (DO_OPER(integer)) { |
|
313 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
314 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) < *(symbol->r_exp->const_value_integer); |
|
315 } |
|
316 if (DO_OPER(real)) { |
|
317 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
318 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) < *(symbol->r_exp->const_value_real); |
|
319 } |
|
320 |
|
321 return NULL; |
|
322 } |
|
323 |
|
324 void *constant_folding_c::visit(gt_expression_c *symbol) { |
|
325 symbol->l_exp->accept(*this); |
|
326 symbol->r_exp->accept(*this); |
|
327 if (DO_OPER(integer)) { |
|
328 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
329 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) > *(symbol->r_exp->const_value_integer); |
|
330 } |
|
331 if (DO_OPER(real)) { |
|
332 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
333 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) > *(symbol->r_exp->const_value_real); |
|
334 } |
|
335 |
|
336 return NULL; |
|
337 } |
|
338 |
|
339 void *constant_folding_c::visit(le_expression_c *symbol) { |
|
340 symbol->l_exp->accept(*this); |
|
341 symbol->r_exp->accept(*this); |
|
342 if (DO_OPER(integer)) { |
|
343 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
344 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) <= *(symbol->r_exp->const_value_integer); |
|
345 } |
|
346 if (DO_OPER(real)) { |
|
347 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
348 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) <= *(symbol->r_exp->const_value_real); |
|
349 } |
|
350 |
|
351 return NULL; |
|
352 } |
|
353 |
|
354 void *constant_folding_c::visit(ge_expression_c *symbol) { |
|
355 symbol->l_exp->accept(*this); |
|
356 symbol->r_exp->accept(*this); |
|
357 if (DO_OPER(integer)) { |
|
358 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
359 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) >= *(symbol->r_exp->const_value_integer); |
|
360 } |
|
361 if (DO_OPER(real)) { |
|
362 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
363 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) >= *(symbol->r_exp->const_value_real); |
|
364 } |
|
365 |
|
366 return NULL; |
|
367 } |
|
368 |
|
369 void *constant_folding_c::visit(add_expression_c *symbol) { |
|
370 symbol->l_exp->accept(*this); |
|
371 symbol->r_exp->accept(*this); |
|
372 if (DO_OPER(integer)) { |
|
373 if (CHECK_OVERFLOW_SUM(*(symbol->l_exp->const_value_integer), *(symbol->r_exp->const_value_integer), int64_t)) |
|
374 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
375 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
376 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer); |
|
377 } |
|
378 if (DO_OPER(real)) { |
|
379 if (CHECK_OVERFLOW_SUM(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_real), double)) |
|
380 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
381 symbol->const_value_real = (double*) malloc(sizeof(double)); |
|
382 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real); |
|
383 } |
|
384 |
|
385 return NULL; |
|
386 } |
|
387 |
|
388 void *constant_folding_c::visit(sub_expression_c *symbol) { |
|
389 symbol->l_exp->accept(*this); |
|
390 symbol->r_exp->accept(*this); |
|
391 if (DO_OPER(integer)) { |
|
392 if (CHECK_OVERFLOW_SUB(*(symbol->l_exp->const_value_integer), *(symbol->r_exp->const_value_integer), int64_t)) |
|
393 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
394 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
395 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer); |
|
396 } |
|
397 if (DO_OPER(real)) { |
|
398 if (CHECK_OVERFLOW_SUB(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_real), double)) |
|
399 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
400 symbol->const_value_real = (double*) malloc(sizeof(double)); |
|
401 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real); |
|
402 } |
|
403 |
|
404 return NULL; |
|
405 } |
|
406 |
|
407 void *constant_folding_c::visit(mul_expression_c *symbol) { |
|
408 symbol->l_exp->accept(*this); |
|
409 symbol->r_exp->accept(*this); |
|
410 if (DO_OPER(integer)) { |
|
411 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
412 if ((*(symbol->l_exp->const_value_integer) == 0) || |
|
413 (*(symbol->r_exp->const_value_integer) == 0)) { |
|
414 *(symbol->const_value_integer) = 0; |
|
415 return NULL; |
|
416 } |
|
417 |
|
418 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer); |
|
419 } |
|
420 if (DO_OPER(real)) { |
|
421 symbol->const_value_real = (double*) malloc(sizeof(double)); |
|
422 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real); |
|
423 } |
|
424 |
|
425 return NULL; |
|
426 } |
|
427 |
|
428 void *constant_folding_c::visit(div_expression_c *symbol) { |
|
429 symbol->l_exp->accept(*this); |
|
430 symbol->r_exp->accept(*this); |
|
431 if (DO_OPER(integer)) { |
|
432 if (*(symbol->r_exp->const_value_integer) == 0) |
|
433 STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); |
|
434 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
435 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) / *(symbol->r_exp->const_value_integer); |
|
436 } |
|
437 if (DO_OPER(real)) { |
|
438 if (*(symbol->r_exp->const_value_real) == 0) |
|
439 STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); |
|
440 symbol->const_value_real = (double*) malloc(sizeof(double)); |
|
441 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real); |
|
442 } |
|
443 |
|
444 return NULL; |
|
445 } |
|
446 |
|
447 void *constant_folding_c::visit(mod_expression_c *symbol) { |
|
448 symbol->l_exp->accept(*this); |
|
449 symbol->r_exp->accept(*this); |
|
450 if (DO_OPER(integer)) { |
|
451 if (*(symbol->r_exp->const_value_integer) == 0) |
|
452 STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); |
|
453 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
454 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) % *(symbol->r_exp->const_value_integer); |
|
455 } |
|
456 |
|
457 return NULL; |
|
458 } |
|
459 |
|
460 void *constant_folding_c::visit(power_expression_c *symbol) { |
|
461 symbol->l_exp->accept(*this); |
|
462 symbol->r_exp->accept(*this); |
|
463 if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) { |
|
464 symbol->const_value_real = (double*) malloc(sizeof(double)); |
|
465 *(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer)); |
|
466 } |
|
467 |
|
468 return NULL; |
|
469 } |
|
470 void *constant_folding_c::visit(neg_expression_c *symbol) { |
|
471 symbol->exp->accept(*this); |
|
472 if (NULL != symbol->exp->const_value_integer) { |
|
473 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
474 *(symbol->const_value_integer) = - *(symbol->exp->const_value_integer); |
|
475 } |
|
476 if (NULL != symbol->exp->const_value_real) { |
|
477 symbol->const_value_real = (double*) malloc(sizeof(double)); |
|
478 *(symbol->const_value_real) = - *(symbol->exp->const_value_real); |
|
479 } |
|
480 return NULL; |
|
481 } |
|
482 |
|
483 void *constant_folding_c::visit(not_expression_c *symbol) { |
|
484 symbol->exp->accept(*this); |
|
485 if (NULL != symbol->exp->const_value_bool) { |
|
486 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
487 *(symbol->const_value_bool) = !*(symbol->exp->const_value_bool); |
|
488 } |
|
489 |
|
490 return NULL; |
|
491 } |
|
492 |
|
493 |
|
494 |