1 /* |
|
2 * (c) 2003 Mario de Sousa |
|
3 * |
|
4 * Offered to the public under the terms of the GNU General Public License |
|
5 * as published by the Free Software Foundation; either version 2 of the |
|
6 * License, or (at your option) any later version. |
|
7 * |
|
8 * This program is distributed in the hope that it will be useful, but |
|
9 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
11 * Public License for more details. |
|
12 * |
|
13 * This code is made available on the understanding that it will not be |
|
14 * used in safety-critical situations without a full and competent review. |
|
15 */ |
|
16 |
|
17 /* |
|
18 * An IEC 61131-3 IL and ST compiler. |
|
19 * |
|
20 * Based on the |
|
21 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
|
22 * |
|
23 */ |
|
24 |
|
25 |
|
26 /* Determine the data type of an ST expression. |
|
27 * A reference to the relevant type definition is returned. |
|
28 * |
|
29 * For example: |
|
30 * 2 + 3 -> returns reference to a int_type_name_c object. |
|
31 * 22.2 - 5 -> returns reference to a real_type_name_c object. |
|
32 * etc... |
|
33 */ |
|
34 |
|
35 #include "function_type_decl.h" |
|
36 #include "get_function_type_decl.c" |
|
37 |
|
38 #if 0 |
|
39 typedef enum {function_add, |
|
40 function_sub, |
|
41 function_and, |
|
42 function_or, |
|
43 function_sqrt, |
|
44 function_none} function_type_t; |
|
45 |
|
46 |
|
47 function_type_t get_function_type(identifier_c *function_name) { |
|
48 if (!strcasecmp(function_name->value, "ADD")) |
|
49 return function_add; |
|
50 else if (!strcasecmp(function_name->value, "SUB")) |
|
51 return function_sub; |
|
52 else if (!strcasecmp(function_name->value, "AND")) |
|
53 return function_and; |
|
54 else if (!strcasecmp(function_name->value, "OR")) |
|
55 return function_or; |
|
56 else if (!strcasecmp(function_name->value, "SQRT")) |
|
57 return function_sqrt; |
|
58 else return function_none; |
|
59 } |
|
60 #endif |
|
61 |
|
62 |
|
63 symbol_c *generate_param_name(const char *name) { |
|
64 symbol_c *param_name = new identifier_c(name); |
|
65 return param_name; |
|
66 } |
|
67 |
|
68 |
|
69 symbol_c *generate_param_name(const char *format, int number) { |
|
70 char name[10]; |
|
71 sprintf(name, format, number); |
|
72 symbol_c *param_name = new identifier_c(name); |
|
73 return param_name; |
|
74 } |
|
75 |
|
76 |
|
77 class search_expression_type_c: public search_constant_type_c { |
|
78 private: |
|
79 search_varfb_instance_type_c *search_varfb_instance_type; |
|
80 search_base_type_c search_base_type; |
|
81 |
|
82 public: |
|
83 search_expression_type_c(symbol_c *search_scope) { |
|
84 search_varfb_instance_type = new search_varfb_instance_type_c(search_scope); |
|
85 } |
|
86 |
|
87 virtual ~search_expression_type_c(void) { |
|
88 delete search_varfb_instance_type; |
|
89 } |
|
90 |
|
91 /* A helper function... */ |
|
92 bool is_bool_type(symbol_c *type_symbol) { |
|
93 return (typeid(*type_symbol) == typeid(bool_type_name_c)); |
|
94 } |
|
95 |
|
96 /* A helper function... */ |
|
97 bool is_time_type(symbol_c *type_symbol) { |
|
98 if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} |
|
99 if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} |
|
100 if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} |
|
101 if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} |
|
102 return false; |
|
103 } |
|
104 |
|
105 /* A helper function... */ |
|
106 bool is_integer_type(symbol_c *type_symbol) { |
|
107 if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;} |
|
108 if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;} |
|
109 if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;} |
|
110 if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;} |
|
111 if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;} |
|
112 if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;} |
|
113 if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;} |
|
114 if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} |
|
115 if (typeid(*type_symbol) == typeid(constant_int_type_name_c)) {return true;} |
|
116 return false; |
|
117 } |
|
118 |
|
119 bool is_real_type(symbol_c *type_symbol) { |
|
120 if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} |
|
121 if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} |
|
122 if (typeid(*type_symbol) == typeid(constant_real_type_name_c)) {return true;} |
|
123 return false; |
|
124 } |
|
125 |
|
126 bool is_num_type(symbol_c *type_symbol) { |
|
127 return is_real_type(type_symbol) || is_integer_type(type_symbol); |
|
128 } |
|
129 |
|
130 bool is_nbinary_type(symbol_c *type_symbol) { |
|
131 if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} |
|
132 if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} |
|
133 if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} |
|
134 if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} |
|
135 if (typeid(*type_symbol) == typeid(constant_int_type_name_c)) {return true;} |
|
136 return false; |
|
137 } |
|
138 |
|
139 bool is_binary_type(symbol_c *type_symbol) { |
|
140 if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} |
|
141 return is_nbinary_type(type_symbol); |
|
142 } |
|
143 |
|
144 bool is_same_type(symbol_c *first_type, symbol_c *second_type) { |
|
145 if (typeid(*first_type) == typeid(*second_type)) {return true;} |
|
146 if (is_integer_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return true;} |
|
147 if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_integer_type(second_type))) {return true;} |
|
148 if (is_binary_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return true;} |
|
149 if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_binary_type(second_type))) {return true;} |
|
150 if (is_real_type(first_type) && (typeid(*second_type) == typeid(constant_real_type_name_c))) {return true;} |
|
151 if ((typeid(*first_type) == typeid(constant_real_type_name_c) && is_real_type(second_type))) {return true;} |
|
152 return false; |
|
153 } |
|
154 |
|
155 symbol_c* common_type(symbol_c *first_type, symbol_c *second_type) { |
|
156 if (typeid(*first_type) == typeid(*second_type)) {return first_type;} |
|
157 if (is_integer_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return first_type;} |
|
158 if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_integer_type(second_type))) {return second_type;} |
|
159 if (is_binary_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return first_type;} |
|
160 if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_binary_type(second_type))) {return second_type;} |
|
161 if (is_real_type(first_type) && (typeid(*second_type) == typeid(constant_real_type_name_c))) {return first_type;} |
|
162 if ((typeid(*first_type) == typeid(constant_real_type_name_c) && is_real_type(second_type))) {return second_type;} |
|
163 return NULL; |
|
164 } |
|
165 |
|
166 #include "search_type_code.c" |
|
167 |
|
168 #if 0 |
|
169 void *compute_standard_function_st(function_invocation_c *symbol) { |
|
170 symbol_c *current_type = NULL; |
|
171 symbol_c *return_type = NULL; |
|
172 |
|
173 function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name); |
|
174 function_call_param_iterator_c function_call_param_iterator(symbol); |
|
175 search_expression_type_c* search_expression_type = this; |
|
176 |
|
177 for(int current_param = 0; current_param < ((list_c *)symbol->parameter_assignment_list)->n; current_param++) { |
|
178 symbol_c *param_name = NULL; |
|
179 switch (current_function_type) { |
|
180 case function_add: |
|
181 case function_and: |
|
182 case function_or: |
|
183 param_name = generate_param_name("IN%d", current_param + 1); |
|
184 break; |
|
185 case function_sub: |
|
186 if (current_param < 2) |
|
187 param_name = generate_param_name("IN%d", current_param + 1); |
|
188 else ERROR; |
|
189 break; |
|
190 default: ERROR; |
|
191 } |
|
192 |
|
193 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
|
194 symbol_c *param_value = function_call_param_iterator.search(param_name); |
|
195 delete param_name; |
|
196 |
|
197 /* Get the value from a foo(<param_value>) style call */ |
|
198 if (param_value == NULL) |
|
199 param_value = function_call_param_iterator.next(); |
|
200 |
|
201 if (param_value == NULL) ERROR; |
|
202 |
|
203 symbol_c *param_type = (symbol_c *)param_value->accept(*this); |
|
204 |
|
205 switch (current_function_type) { |
|
206 case function_add: |
|
207 if (current_param == 0) |
|
208 current_type = param_type; |
|
209 else if (current_param == 1) { |
|
210 if ((is_integer_type(current_type) && is_same_type(current_type, param_type)) || |
|
211 (is_real_type(current_type) && is_same_type(current_type, param_type))) { |
|
212 current_type = common_type(current_type, param_type); |
|
213 return_type = current_type; |
|
214 } |
|
215 else if (is_time_type(current_type)) { |
|
216 if ((typeid(*current_type) == typeid(time_type_name_c)) && (typeid(*param_type) == typeid(time_type_name_c))) {return_type = (symbol_c *)&time_type_name;} |
|
217 else if (typeid(*current_type) == typeid(tod_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&tod_type_name;} |
|
218 else if (typeid(*current_type) == typeid(dt_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&dt_type_name;} |
|
219 else ERROR; |
|
220 } |
|
221 else ERROR; |
|
222 } |
|
223 else if (!is_time_type(current_type) && is_same_type(current_type, param_type)) { |
|
224 current_type = common_type(current_type, param_type); |
|
225 return_type = current_type; |
|
226 } |
|
227 else ERROR; |
|
228 break; |
|
229 case function_sub: |
|
230 if (current_param == 0) |
|
231 current_type = param_type; |
|
232 else if (current_param == 1) { |
|
233 if ((is_integer_type(current_type) && is_same_type(current_type, param_type)) || |
|
234 (is_real_type(current_type) && is_same_type(current_type, param_type))) |
|
235 return_type = common_type(current_type, param_type); |
|
236 else if (is_time_type(current_type)) { |
|
237 if (typeid(*current_type) == typeid(time_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&time_type_name;} |
|
238 else if (typeid(*current_type) == typeid(date_type_name_c) && typeid(*param_type) == typeid(date_type_name_c)) {return_type = (symbol_c *)&time_type_name;} |
|
239 else if (typeid(*current_type) == typeid(tod_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&tod_type_name;} |
|
240 else if (typeid(*current_type) == typeid(tod_type_name_c) && typeid(*param_type) == typeid(tod_type_name_c)) {return_type = (symbol_c *)&time_type_name;} |
|
241 else if (typeid(*current_type) == typeid(dt_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&dt_type_name;} |
|
242 else if (typeid(*current_type) == typeid(dt_type_name_c) && typeid(*param_type) == typeid(dt_type_name_c)) {return_type = (symbol_c *)&time_type_name;} |
|
243 else ERROR; |
|
244 } |
|
245 else ERROR; |
|
246 } |
|
247 else ERROR; |
|
248 break; |
|
249 case function_and: |
|
250 case function_or: |
|
251 if (current_param == 0) |
|
252 if (is_binary_type(param_type)) |
|
253 current_type = param_type; |
|
254 else ERROR; |
|
255 else if (is_same_type(current_type, param_type)) |
|
256 return_type = common_type(current_type, param_type); |
|
257 else ERROR; |
|
258 break; |
|
259 default: ERROR; |
|
260 } |
|
261 } |
|
262 return (void *)return_type; |
|
263 } |
|
264 |
|
265 void *compute_standard_function_il(il_function_call_c *symbol, symbol_c *param_type) { |
|
266 /*symbol_c *current_type = NULL;*/ |
|
267 symbol_c *return_type = NULL; |
|
268 function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name); |
|
269 if (current_function_type == function_none) ERROR; |
|
270 |
|
271 function_call_param_iterator_c function_call_param_iterator(symbol); |
|
272 |
|
273 int nb_param = 1; |
|
274 if (symbol->il_operand_list != NULL) |
|
275 nb_param += ((list_c *)symbol->il_operand_list)->n; |
|
276 |
|
277 for(int current_param = 0; current_param < nb_param; current_param++) { |
|
278 |
|
279 if (current_param != 0) { |
|
280 symbol_c *param_name = NULL; |
|
281 switch (current_function_type) { |
|
282 default: ERROR; |
|
283 } |
|
284 |
|
285 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
|
286 symbol_c *param_value = function_call_param_iterator.search(param_name); |
|
287 delete param_name; |
|
288 |
|
289 /* Get the value from a foo(<param_value>) style call */ |
|
290 if (param_value == NULL) |
|
291 param_value = function_call_param_iterator.next(); |
|
292 |
|
293 if (param_value == NULL) ERROR; |
|
294 |
|
295 param_type = (symbol_c *)param_value->accept(*this); |
|
296 } |
|
297 |
|
298 switch (current_function_type) { |
|
299 case function_sqrt: |
|
300 if (current_param == 0 && is_real_type(param_type)) |
|
301 return_type = param_type; |
|
302 else ERROR; |
|
303 break; |
|
304 default: ERROR; |
|
305 } |
|
306 } |
|
307 |
|
308 return (void *)return_type; |
|
309 } |
|
310 #endif |
|
311 |
|
312 /*static bool_type_name_c bool_type_name;*/ |
|
313 |
|
314 /* A helper function... */ |
|
315 void *compute_boolean_expression(symbol_c *left_type, symbol_c *right_type) { |
|
316 if (!is_same_type(left_type, right_type)) |
|
317 ERROR; |
|
318 if (!is_bool_type(left_type) && !is_binary_type(left_type)) |
|
319 ERROR; |
|
320 if (typeid(*left_type) == typeid(constant_int_type_name_c)) {return (void *)right_type;} |
|
321 else {return (void *)left_type;} |
|
322 } |
|
323 |
|
324 /* A helper function... */ |
|
325 void *compute_numeric_expression(symbol_c *left_type, symbol_c *right_type) { |
|
326 if (!is_same_type(left_type, right_type)) |
|
327 ERROR; |
|
328 if (!is_integer_type(left_type) && !is_real_type(left_type)) |
|
329 ERROR; |
|
330 if ((typeid(*left_type) == typeid(constant_int_type_name_c)) || (typeid(*left_type) == typeid(constant_real_type_name_c))) {return (void *)right_type;} |
|
331 else {return (void *)left_type;} |
|
332 return NULL; |
|
333 } |
|
334 |
|
335 /* a helper function... */ |
|
336 symbol_c *base_type(symbol_c *symbol) { |
|
337 return (symbol_c *)symbol->accept(search_base_type); |
|
338 } |
|
339 |
|
340 /*********************/ |
|
341 /* B 1.4 - Variables */ |
|
342 /*********************/ |
|
343 |
|
344 void *visit(symbolic_variable_c *symbol) { |
|
345 symbol_c *res; |
|
346 |
|
347 /* Nope, now we assume it is a variable, and determine its type... */ |
|
348 res = search_varfb_instance_type->get_type(symbol); |
|
349 if (NULL != res) return res; |
|
350 |
|
351 return NULL; |
|
352 } |
|
353 |
|
354 /*************************************/ |
|
355 /* B 1.4.2 - Multi-element variables */ |
|
356 /*************************************/ |
|
357 |
|
358 void *visit(array_variable_c *symbol) { |
|
359 symbol_c *res; |
|
360 |
|
361 /* Nope, now we assume it is a variable, and determine its type... */ |
|
362 res = search_varfb_instance_type->get_type(symbol); |
|
363 if (NULL != res) return res; |
|
364 |
|
365 return NULL; |
|
366 } |
|
367 |
|
368 void *visit(structured_variable_c *symbol) { |
|
369 symbol_c *res; |
|
370 |
|
371 /* Nope, now we assume it is a variable, and determine its type... */ |
|
372 res = search_varfb_instance_type->get_type(symbol); |
|
373 if (NULL != res) return res; |
|
374 |
|
375 return NULL; |
|
376 } |
|
377 |
|
378 /***************************************/ |
|
379 /* B.3 - Language ST (Structured Text) */ |
|
380 /***************************************/ |
|
381 /***********************/ |
|
382 /* B 3.1 - Expressions */ |
|
383 /***********************/ |
|
384 void *visit(or_expression_c *symbol) { |
|
385 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
386 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
387 return compute_boolean_expression(left_type, right_type); |
|
388 } |
|
389 |
|
390 void *visit(xor_expression_c *symbol) { |
|
391 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
392 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
393 return compute_boolean_expression(left_type, right_type); |
|
394 } |
|
395 |
|
396 void *visit(and_expression_c *symbol) { |
|
397 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
398 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
399 return compute_boolean_expression(left_type, right_type); |
|
400 } |
|
401 |
|
402 void *visit(equ_expression_c *symbol) {return (void *)&bool_type_name;} |
|
403 void *visit(notequ_expression_c *symbol) {return (void *)&bool_type_name;} |
|
404 void *visit(lt_expression_c *symbol) {return (void *)&bool_type_name;} |
|
405 void *visit(gt_expression_c *symbol) {return (void *)&bool_type_name;} |
|
406 void *visit(le_expression_c *symbol) {return (void *)&bool_type_name;} |
|
407 void *visit(ge_expression_c *symbol) {return (void *)&bool_type_name;} |
|
408 |
|
409 void *visit(add_expression_c *symbol) { |
|
410 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
411 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
412 if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;} |
|
413 if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;} |
|
414 if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;} |
|
415 return compute_numeric_expression(left_type, right_type); |
|
416 } |
|
417 |
|
418 void *visit(sub_expression_c *symbol) { |
|
419 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
420 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
421 if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;} |
|
422 if (typeid(*left_type) == typeid(date_type_name_c) && typeid(*right_type) == typeid(date_type_name_c)) {return (void *)&time_type_name;} |
|
423 if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;} |
|
424 if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(tod_type_name_c)) {return (void *)&time_type_name;} |
|
425 if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;} |
|
426 if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(dt_type_name_c)) {return (void *)&time_type_name;} |
|
427 return compute_numeric_expression(left_type, right_type); |
|
428 } |
|
429 |
|
430 void *visit(mul_expression_c *symbol) { |
|
431 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
432 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
433 if (typeid(*left_type) == typeid(time_type_name_c) && is_num_type(right_type)) { |
|
434 return (void *)&time_type_name; |
|
435 } |
|
436 return compute_numeric_expression(left_type, right_type); |
|
437 } |
|
438 |
|
439 void *visit(div_expression_c *symbol) { |
|
440 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
441 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
442 if (typeid(*left_type) == typeid(time_type_name_c) && is_num_type(right_type)){ |
|
443 return (void *)&time_type_name; |
|
444 } |
|
445 return compute_numeric_expression(left_type, right_type); |
|
446 } |
|
447 |
|
448 void *visit(mod_expression_c *symbol) { |
|
449 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
450 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
451 return compute_numeric_expression(left_type, right_type); |
|
452 } |
|
453 |
|
454 void *visit(power_expression_c *symbol) { |
|
455 symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this)); |
|
456 symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this)); |
|
457 if (is_real_type(left_type) && is_num_type(right_type)) { |
|
458 return (void *)left_type; |
|
459 } |
|
460 ERROR; |
|
461 return NULL; |
|
462 } |
|
463 |
|
464 void *visit(neg_expression_c *symbol) { |
|
465 symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this)); |
|
466 if (is_num_type(exp_type) || typeid(*exp_type) == typeid(time_type_name_c)){ |
|
467 return (void *)exp_type; |
|
468 } |
|
469 ERROR; |
|
470 return NULL; |
|
471 } |
|
472 |
|
473 void *visit(not_expression_c *symbol) { |
|
474 symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this)); |
|
475 return compute_boolean_expression(exp_type, exp_type); |
|
476 } |
|
477 |
|
478 void *visit(function_invocation_c *symbol) { |
|
479 function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name); |
|
480 |
|
481 if (f_decl == function_symtable.end_value()) { |
|
482 void *res = compute_standard_function_st(symbol); |
|
483 if (res == NULL) |
|
484 ERROR; |
|
485 return res; |
|
486 } |
|
487 |
|
488 return base_type(f_decl->type_name); |
|
489 } |
|
490 |
|
491 }; |
|
492 |
|
493 /*bool_type_name_c search_expression_type_c::bool_type_name;*/ |
|
494 |
|