|
1 /* |
|
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
|
3 * |
|
4 * Copyright (C) 2009-2012 Mario de Sousa (msousa@fe.up.pt) |
|
5 * Copyright (C) 2012 Manuele Conti (manuele.conti@sirius-es.it) |
|
6 * Copyright (C) 2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it) |
|
7 * |
|
8 * |
|
9 * This program is free software: you can redistribute it and/or modify |
|
10 * it under the terms of the GNU General Public License as published by |
|
11 * the Free Software Foundation, either version 3 of the License, or |
|
12 * (at your option) any later version. |
|
13 * |
|
14 * This program is distributed in the hope that it will be useful, |
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 * GNU General Public License for more details. |
|
18 * |
|
19 * You should have received a copy of the GNU General Public License |
|
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
21 * |
|
22 * |
|
23 * This code is made available on the understanding that it will not be |
|
24 * used in safety-critical situations without a full and competent review. |
|
25 */ |
|
26 |
|
27 /* |
|
28 * An IEC 61131-3 compiler. |
|
29 * |
|
30 * Based on the |
|
31 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
|
32 * |
|
33 */ |
|
34 |
|
35 /* NOTE: The algorithm implemented here assumes that flow control analysis has already been completed! |
|
36 * BEFORE running this visitor, be sure to CALL the flow_control_analysis_c visitor! |
|
37 */ |
|
38 |
|
39 |
|
40 /* |
|
41 * Fill the candidate datatype list for all symbols that may legally 'have' a data type (e.g. variables, literals, function calls, expressions, etc.) |
|
42 * |
|
43 * The candidate datatype list will be filled with a list of all the data types that expression may legally take. |
|
44 * For example, the very simple literal '0' (as in foo := 0), may represent a: |
|
45 * BOOL, BYTE, WORD, DWORD, LWORD, USINT, SINT, UINT, INT, UDINT, DINT, ULINT, LINT (as well as the SAFE versions of these data tyes too!) |
|
46 */ |
|
47 |
|
48 |
|
49 #include "../absyntax_utils/absyntax_utils.hh" |
|
50 #include "datatype_functions.hh" |
|
51 |
|
52 class fill_candidate_datatypes_c: public iterator_visitor_c { |
|
53 |
|
54 private: |
|
55 search_varfb_instance_type_c *search_varfb_instance_type; |
|
56 search_base_type_c search_base_type; |
|
57 /* When calling a function block, we must first find it's type, |
|
58 * by searching through the declarations of the variables currently |
|
59 * in scope. |
|
60 * This class does just that... |
|
61 * A new object instance is instantiated whenever we start checking semantics |
|
62 * for a function block type declaration, or a program declaration. |
|
63 * This object instance will then later be called while the |
|
64 * function block's or the program's body is being handled. |
|
65 * |
|
66 * Note that functions cannot contain calls to function blocks, |
|
67 * so we do not create an object instance when handling |
|
68 * a function declaration. |
|
69 */ |
|
70 // search_var_instance_decl_c *search_var_instance_decl; |
|
71 |
|
72 /* This variable was created to pass information from |
|
73 * fill_candidate_datatypes_c::visit(case_statement_c *symbol) function to |
|
74 * fill_candidate_datatypes_c::visit(case_list_c *symbol) function. |
|
75 */ |
|
76 // symbol_c *case_expression_type; |
|
77 |
|
78 /* In IL code, once we find a type mismatch error, it is best to |
|
79 * ignore any further errors until the end of the logical operation, |
|
80 * i.e. until the next LD. |
|
81 * However, we cannot clear the il_error flag on all LD operations, |
|
82 * as these may also be used within parenthesis. LD operations |
|
83 * within parenthesis may not clear the error flag. |
|
84 * We therefore need a counter to know how deep inside a parenthesis |
|
85 * structure we are. |
|
86 */ |
|
87 // int il_parenthesis_level; |
|
88 // bool error_found; |
|
89 |
|
90 /* Pointer to the previous IL instruction, which contains the current data type (actually, the list of candidate data types) of the data stored in the IL stack, i.e. the default variable, a.k.a. accumulator */ |
|
91 symbol_c *prev_il_instruction; |
|
92 /* the current IL operand being analyzed */ |
|
93 symbol_c *il_operand; |
|
94 symbol_c *widening_conversion(symbol_c *left_type, symbol_c *right_type, const struct widen_entry widen_table[]); |
|
95 |
|
96 /* Match a function declaration with a function call through their parameters.*/ |
|
97 /* returns true if compatible function/FB invocation, otherwise returns false */ |
|
98 bool match_nonformal_call(symbol_c *f_call, symbol_c *f_decl); |
|
99 bool match_formal_call (symbol_c *f_call, symbol_c *f_decl, symbol_c **first_param_datatype = NULL); |
|
100 void handle_function_call(symbol_c *fcall, generic_function_call_t fcall_data); |
|
101 void *handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration); |
|
102 void *handle_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr); |
|
103 void *handle_binary_operator (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr); |
|
104 void *handle_conditional_il_flow_control_operator(symbol_c *symbol); |
|
105 |
|
106 /* a helper function... */ |
|
107 symbol_c *base_type(symbol_c *symbol); |
|
108 |
|
109 /* add a data type to a candidate data type list, while guaranteeing no duplicate entries! */ |
|
110 /* Returns true if it really did add the datatype to the list, or false if it was already present in the list! */ |
|
111 bool add_datatype_to_candidate_list (symbol_c *symbol, symbol_c *datatype); |
|
112 bool add_2datatypes_to_candidate_list(symbol_c *symbol, symbol_c *datatype1, symbol_c *datatype2); |
|
113 void remove_incompatible_datatypes(symbol_c *symbol); |
|
114 |
|
115 |
|
116 public: |
|
117 fill_candidate_datatypes_c(symbol_c *ignore); |
|
118 virtual ~fill_candidate_datatypes_c(void); |
|
119 |
|
120 |
|
121 /*********************/ |
|
122 /* B 1.2 - Constants */ |
|
123 /*********************/ |
|
124 /******************************/ |
|
125 /* B 1.2.1 - Numeric Literals */ |
|
126 /******************************/ |
|
127 void *handle_any_integer(symbol_c *symbol); |
|
128 void *handle_any_real (symbol_c *symbol); |
|
129 void *handle_any_literal(symbol_c *symbol, symbol_c *symbol_value, symbol_c *symbol_type); |
|
130 |
|
131 void *visit(real_c *symbol); |
|
132 void *visit(integer_c *symbol); |
|
133 void *visit(neg_real_c *symbol); |
|
134 void *visit(neg_integer_c *symbol); |
|
135 void *visit(binary_integer_c *symbol); |
|
136 void *visit(octal_integer_c *symbol); |
|
137 void *visit(hex_integer_c *symbol); |
|
138 void *visit(integer_literal_c *symbol); |
|
139 void *visit(real_literal_c *symbol); |
|
140 void *visit(bit_string_literal_c *symbol); |
|
141 void *visit(boolean_literal_c *symbol); |
|
142 void *visit(boolean_true_c *symbol); |
|
143 void *visit(boolean_false_c *symbol); |
|
144 |
|
145 /*******************************/ |
|
146 /* B.1.2.2 Character Strings */ |
|
147 /*******************************/ |
|
148 void *visit(double_byte_character_string_c *symbol); |
|
149 void *visit(single_byte_character_string_c *symbol); |
|
150 |
|
151 /***************************/ |
|
152 /* B 1.2.3 - Time Literals */ |
|
153 /***************************/ |
|
154 /************************/ |
|
155 /* B 1.2.3.1 - Duration */ |
|
156 /************************/ |
|
157 void *visit(duration_c *symbol); |
|
158 |
|
159 /************************************/ |
|
160 /* B 1.2.3.2 - Time of day and Date */ |
|
161 /************************************/ |
|
162 void *visit(time_of_day_c *symbol); |
|
163 void *visit(date_c *symbol); |
|
164 void *visit(date_and_time_c *symbol); |
|
165 |
|
166 |
|
167 /**********************/ |
|
168 /* B 1.3 - Data types */ |
|
169 /**********************/ |
|
170 /********************************/ |
|
171 /* B 1.3.3 - Derived data types */ |
|
172 /********************************/ |
|
173 void *visit(simple_spec_init_c *symbol); |
|
174 void *visit(subrange_c *symbol); |
|
175 // void *visit(data_type_declaration_c *symbol); |
|
176 void *visit(enumerated_value_c *symbol); |
|
177 |
|
178 /*********************/ |
|
179 /* B 1.4 - Variables */ |
|
180 /*********************/ |
|
181 void *visit(symbolic_variable_c *symbol); |
|
182 |
|
183 /********************************************/ |
|
184 /* B 1.4.1 - Directly Represented Variables */ |
|
185 /********************************************/ |
|
186 void *visit(direct_variable_c *symbol); |
|
187 |
|
188 /*************************************/ |
|
189 /* B 1.4.2 - Multi-element variables */ |
|
190 /*************************************/ |
|
191 void *visit(array_variable_c *symbol); |
|
192 void *visit(structured_variable_c *symbol); |
|
193 |
|
194 /******************************************/ |
|
195 /* B 1.4.3 - Declaration & Initialisation */ |
|
196 /******************************************/ |
|
197 void *visit(var1_list_c *symbol); |
|
198 void *visit(location_c *symbol); |
|
199 void *visit(located_var_decl_c *symbol); |
|
200 |
|
201 |
|
202 /**************************************/ |
|
203 /* B 1.5 - Program organization units */ |
|
204 /**************************************/ |
|
205 /***********************/ |
|
206 /* B 1.5.1 - Functions */ |
|
207 /***********************/ |
|
208 void *visit(function_declaration_c *symbol); |
|
209 |
|
210 /*****************************/ |
|
211 /* B 1.5.2 - Function blocks */ |
|
212 /*****************************/ |
|
213 void *visit(function_block_declaration_c *symbol); |
|
214 |
|
215 /**********************/ |
|
216 /* B 1.5.3 - Programs */ |
|
217 /**********************/ |
|
218 void *visit(program_declaration_c *symbol); |
|
219 |
|
220 /********************************/ |
|
221 /* B 1.7 Configuration elements */ |
|
222 /********************************/ |
|
223 void *visit(configuration_declaration_c *symbol); |
|
224 |
|
225 /****************************************/ |
|
226 /* B.2 - Language IL (Instruction List) */ |
|
227 /****************************************/ |
|
228 /***********************************/ |
|
229 /* B 2.1 Instructions and Operands */ |
|
230 /***********************************/ |
|
231 void *visit(instruction_list_c *symbol); |
|
232 void *visit(il_instruction_c *symbol); |
|
233 void *visit(il_simple_operation_c *symbol); |
|
234 void *visit(il_function_call_c *symbol); |
|
235 void *visit(il_expression_c *symbol); |
|
236 void *visit(il_jump_operation_c *symbol); |
|
237 void *visit(il_fb_call_c *symbol); |
|
238 void *visit(il_formal_funct_call_c *symbol); |
|
239 // void *visit(il_operand_list_c *symbol); |
|
240 void *visit(simple_instr_list_c *symbol); |
|
241 void *visit(il_simple_instruction_c*symbol); |
|
242 // void *visit(il_param_list_c *symbol); |
|
243 // void *visit(il_param_assignment_c *symbol); |
|
244 // void *visit(il_param_out_assignment_c *symbol); |
|
245 |
|
246 /*******************/ |
|
247 /* B 2.2 Operators */ |
|
248 /*******************/ |
|
249 void *visit(LD_operator_c *symbol); |
|
250 void *visit(LDN_operator_c *symbol); |
|
251 void *visit(ST_operator_c *symbol); |
|
252 void *visit(STN_operator_c *symbol); |
|
253 void *visit(NOT_operator_c *symbol); |
|
254 void *visit(S_operator_c *symbol); |
|
255 void *visit(R_operator_c *symbol); |
|
256 void *visit(S1_operator_c *symbol); |
|
257 void *visit(R1_operator_c *symbol); |
|
258 void *visit(CLK_operator_c *symbol); |
|
259 void *visit(CU_operator_c *symbol); |
|
260 void *visit(CD_operator_c *symbol); |
|
261 void *visit(PV_operator_c *symbol); |
|
262 void *visit(IN_operator_c *symbol); |
|
263 void *visit(PT_operator_c *symbol); |
|
264 void *visit(AND_operator_c *symbol); |
|
265 void *visit(OR_operator_c *symbol); |
|
266 void *visit(XOR_operator_c *symbol); |
|
267 void *visit(ANDN_operator_c *symbol); |
|
268 void *visit(ORN_operator_c *symbol); |
|
269 void *visit(XORN_operator_c *symbol); |
|
270 void *visit(ADD_operator_c *symbol); |
|
271 void *visit(SUB_operator_c *symbol); |
|
272 void *visit(MUL_operator_c *symbol); |
|
273 void *visit(DIV_operator_c *symbol); |
|
274 void *visit(MOD_operator_c *symbol); |
|
275 void *visit(GT_operator_c *symbol); |
|
276 void *visit(GE_operator_c *symbol); |
|
277 void *visit(EQ_operator_c *symbol); |
|
278 void *visit(LT_operator_c *symbol); |
|
279 void *visit(LE_operator_c *symbol); |
|
280 void *visit(NE_operator_c *symbol); |
|
281 void *visit(CAL_operator_c *symbol); |
|
282 void *visit(CALC_operator_c *symbol); |
|
283 void *visit(CALCN_operator_c *symbol); |
|
284 void *visit(RET_operator_c *symbol); |
|
285 void *visit(RETC_operator_c *symbol); |
|
286 void *visit(RETCN_operator_c *symbol); |
|
287 void *visit(JMP_operator_c *symbol); |
|
288 void *visit(JMPC_operator_c *symbol); |
|
289 void *visit(JMPCN_operator_c *symbol); |
|
290 /* Symbol class handled together with function call checks */ |
|
291 // void *visit(il_assign_operator_c *symbol, variable_name); |
|
292 /* Symbol class handled together with function call checks */ |
|
293 // void *visit(il_assign_operator_c *symbol, option, variable_name); |
|
294 |
|
295 |
|
296 /***************************************/ |
|
297 /* B.3 - Language ST (Structured Text) */ |
|
298 /***************************************/ |
|
299 /***********************/ |
|
300 /* B 3.1 - Expressions */ |
|
301 /***********************/ |
|
302 void *visit(or_expression_c *symbol); |
|
303 void *visit(xor_expression_c *symbol); |
|
304 void *visit(and_expression_c *symbol); |
|
305 void *visit(equ_expression_c *symbol); |
|
306 void *visit(notequ_expression_c *symbol); |
|
307 void *visit(lt_expression_c *symbol); |
|
308 void *visit(gt_expression_c *symbol); |
|
309 void *visit(le_expression_c *symbol); |
|
310 void *visit(ge_expression_c *symbol); |
|
311 void *visit(add_expression_c *symbol); |
|
312 void *visit(sub_expression_c *symbol); |
|
313 void *visit(mul_expression_c *symbol); |
|
314 void *visit(div_expression_c *symbol); |
|
315 void *visit(mod_expression_c *symbol); |
|
316 void *visit(power_expression_c *symbol); |
|
317 void *visit(neg_expression_c *symbol); |
|
318 void *visit(not_expression_c *symbol); |
|
319 void *visit(function_invocation_c *symbol); |
|
320 |
|
321 /*********************************/ |
|
322 /* B 3.2.1 Assignment Statements */ |
|
323 /*********************************/ |
|
324 void *visit(assignment_statement_c *symbol); |
|
325 |
|
326 /*****************************************/ |
|
327 /* B 3.2.2 Subprogram Control Statements */ |
|
328 /*****************************************/ |
|
329 void *visit(fb_invocation_c *symbol); |
|
330 |
|
331 /********************************/ |
|
332 /* B 3.2.3 Selection Statements */ |
|
333 /********************************/ |
|
334 void *visit(if_statement_c *symbol); |
|
335 // void *visit(elseif_statement_list_c *symbol); |
|
336 void *visit(elseif_statement_c *symbol); |
|
337 void *visit(case_statement_c *symbol); |
|
338 |
|
339 /********************************/ |
|
340 /* B 3.2.4 Iteration Statements */ |
|
341 /********************************/ |
|
342 void *visit(for_statement_c *symbol); |
|
343 void *visit(while_statement_c *symbol); |
|
344 void *visit(repeat_statement_c *symbol); |
|
345 |
|
346 }; // fill_candidate_datatypes_c |
|
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |