|
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 /* |
|
27 * Determine the default initial value of a type declaration. |
|
28 * |
|
29 * This is part of the 4th stage that generates |
|
30 * a c++ source program equivalent to the IL and ST |
|
31 * code. |
|
32 */ |
|
33 |
|
34 /* Given a type definition declration, determine its default |
|
35 * initial value. Note that types based on other types |
|
36 * may have to iterate through each type it is based on |
|
37 * to determine the initial value. |
|
38 * E.g. |
|
39 * TYPE |
|
40 * A_t : INT := 10; |
|
41 * B_t : A_t := 20; |
|
42 * C_t : B_t; |
|
43 * D_t : C_t := 40; |
|
44 * END_TYPE |
|
45 * Where the default initial value for C_t is 20! |
|
46 */ |
|
47 /* NOTE: The main program only needs one instance of |
|
48 * this class of object. This class |
|
49 * is therefore a singleton. |
|
50 */ |
|
51 |
|
52 class type_initial_value_c : public null_visitor_c { |
|
53 |
|
54 private: |
|
55 static type_initial_value_c *_instance; |
|
56 /* constants for the default values of elementary data types... */ |
|
57 static real_c *real_0; |
|
58 static integer_c *integer_0, *integer_1; |
|
59 static boolean_literal_c *bool_0; |
|
60 static date_literal_c *date_literal_0; |
|
61 static daytime_c *daytime_literal_0; |
|
62 static duration_c *time_0; |
|
63 static date_c *date_0; |
|
64 static time_of_day_c *tod_0; |
|
65 static date_and_time_c *dt_0; |
|
66 static single_byte_character_string_c *string_0; |
|
67 static double_byte_character_string_c *wstring_0; |
|
68 |
|
69 public: |
|
70 static type_initial_value_c *instance(void); |
|
71 |
|
72 protected: |
|
73 type_initial_value_c(void); |
|
74 |
|
75 public: |
|
76 symbol_c *get(identifier_c *type_name); |
|
77 |
|
78 |
|
79 private: |
|
80 void *handle_type_spec(symbol_c *base_type_name, symbol_c *type_spec_init); |
|
81 |
|
82 private: |
|
83 void *visit(identifier_c *type_name); |
|
84 |
|
85 /***********************************/ |
|
86 /* B 1.3.1 - Elementary Data Types */ |
|
87 /***********************************/ |
|
88 void *visit(time_type_name_c *symbol); |
|
89 void *visit(bool_type_name_c *symbol); |
|
90 void *visit(sint_type_name_c *symbol); |
|
91 void *visit(int_type_name_c *symbol); |
|
92 void *visit(dint_type_name_c *symbol); |
|
93 void *visit(lint_type_name_c *symbol); |
|
94 void *visit(usint_type_name_c *symbol); |
|
95 void *visit(uint_type_name_c *symbol); |
|
96 void *visit(udint_type_name_c *symbol); |
|
97 void *visit(ulint_type_name_c *symbol); |
|
98 void *visit(real_type_name_c *symbol); |
|
99 void *visit(lreal_type_name_c *symbol); |
|
100 void *visit(date_type_name_c *symbol); |
|
101 void *visit(tod_type_name_c *symbol); |
|
102 void *visit(dt_type_name_c *symbol); |
|
103 void *visit(byte_type_name_c *symbol); |
|
104 void *visit(word_type_name_c *symbol); |
|
105 void *visit(dword_type_name_c *symbol); |
|
106 void *visit(lword_type_name_c *symbol); |
|
107 void *visit(string_type_name_c *symbol); |
|
108 void *visit(wstring_type_name_c *symbol); |
|
109 |
|
110 /********************************/ |
|
111 /* B 1.3.3 - Derived data types */ |
|
112 /********************************/ |
|
113 /* simple_type_name ':' simple_spec_init */ |
|
114 void *visit(simple_type_declaration_c *symbol); |
|
115 |
|
116 /* simple_specification ASSIGN constant */ |
|
117 void *visit(simple_spec_init_c *symbol); |
|
118 |
|
119 /* subrange_type_name ':' subrange_spec_init */ |
|
120 void *visit(subrange_type_declaration_c *symbol); |
|
121 |
|
122 /* subrange_specification ASSIGN signed_integer */ |
|
123 void *visit(subrange_spec_init_c *symbol); |
|
124 |
|
125 /* integer_type_name '(' subrange')' */ |
|
126 void *visit(subrange_specification_c *symbol); |
|
127 |
|
128 /* signed_integer DOTDOT signed_integer */ |
|
129 void *visit(subrange_c *symbol); |
|
130 |
|
131 /* enumerated_type_name ':' enumerated_spec_init */ |
|
132 void *visit(enumerated_type_declaration_c *symbol); |
|
133 |
|
134 /* enumerated_specification ASSIGN enumerated_value */ |
|
135 void *visit(enumerated_spec_init_c *symbol); |
|
136 |
|
137 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
|
138 /* enumerated_value_list ',' enumerated_value */ |
|
139 void *visit(enumerated_value_list_c *symbol); |
|
140 |
|
141 /* enumerated_type_name '#' identifier */ |
|
142 // SYM_REF2(enumerated_value_c, type, value) |
|
143 void *visit(enumerated_value_c *symbol); |
|
144 |
|
145 /* identifier ':' array_spec_init */ |
|
146 void *visit(array_type_declaration_c *symbol); |
|
147 |
|
148 /* array_specification [ASSIGN array_initialization} */ |
|
149 /* array_initialization may be NULL ! */ |
|
150 void *visit(array_spec_init_c *symbol); |
|
151 |
|
152 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
|
153 void *visit(array_specification_c *symbol); |
|
154 |
|
155 /* helper symbol for array_specification */ |
|
156 /* array_subrange_list ',' subrange */ |
|
157 void *visit(array_subrange_list_c *symbol); |
|
158 |
|
159 /* array_initialization: '[' array_initial_elements_list ']' */ |
|
160 /* helper symbol for array_initialization */ |
|
161 /* array_initial_elements_list ',' array_initial_elements */ |
|
162 void *visit(array_initial_elements_list_c *symbol); |
|
163 |
|
164 /* integer '(' [array_initial_element] ')' */ |
|
165 /* array_initial_element may be NULL ! */ |
|
166 void *visit(array_initial_elements_c *symbol); |
|
167 |
|
168 /* structure_type_name ':' structure_specification */ |
|
169 void *visit(structure_type_declaration_c *symbol); |
|
170 |
|
171 /* structure_type_name ASSIGN structure_initialization */ |
|
172 /* structure_initialization may be NULL ! */ |
|
173 void *visit(initialized_structure_c *symbol); |
|
174 |
|
175 /* helper symbol for structure_declaration */ |
|
176 /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ |
|
177 /* structure_element_declaration_list structure_element_declaration ';' */ |
|
178 void *visit(structure_element_declaration_list_c *symbol); |
|
179 |
|
180 /* structure_element_name ':' *_spec_init */ |
|
181 void *visit(structure_element_declaration_c *symbol); |
|
182 |
|
183 /* helper symbol for structure_initialization */ |
|
184 /* structure_initialization: '(' structure_element_initialization_list ')' */ |
|
185 /* structure_element_initialization_list ',' structure_element_initialization */ |
|
186 void *visit(structure_element_initialization_list_c *symbol); |
|
187 |
|
188 /* structure_element_name ASSIGN value */ |
|
189 void *visit(structure_element_initialization_c *symbol); |
|
190 |
|
191 /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ |
|
192 /* |
|
193 * NOTE: |
|
194 * (Summary: Contrary to what is expected, the |
|
195 * string_type_declaration_c is not used to store |
|
196 * simple string type declarations that do not include |
|
197 * size limits. |
|
198 * For e.g.: |
|
199 * str1_type: STRING := "hello!" |
|
200 * will be stored in a simple_type_declaration_c |
|
201 * instead of a string_type_declaration_c. |
|
202 * The following: |
|
203 * str2_type: STRING [64] := "hello!" |
|
204 * will be stored in a sring_type_declaration_c |
|
205 * |
|
206 * Read on for why this is done... |
|
207 * End Summary) |
|
208 * |
|
209 * According to the spec, the valid construct |
|
210 * TYPE new_str_type : STRING := "hello!"; END_TYPE |
|
211 * has two possible routes to type_declaration... |
|
212 * |
|
213 * Route 1: |
|
214 * type_declaration: single_element_type_declaration |
|
215 * single_element_type_declaration: simple_type_declaration |
|
216 * simple_type_declaration: identifier ':' simple_spec_init |
|
217 * simple_spec_init: simple_specification ASSIGN constant |
|
218 * (shift: identifier <- 'new_str_type') |
|
219 * simple_specification: elementary_type_name |
|
220 * elementary_type_name: STRING |
|
221 * (shift: elementary_type_name <- STRING) |
|
222 * (reduce: simple_specification <- elementary_type_name) |
|
223 * (shift: constant <- "hello!") |
|
224 * (reduce: simple_spec_init: simple_specification ASSIGN constant) |
|
225 * (reduce: ...) |
|
226 * |
|
227 * |
|
228 * Route 2: |
|
229 * type_declaration: string_type_declaration |
|
230 * string_type_declaration: identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init |
|
231 * (shift: identifier <- 'new_str_type') |
|
232 * elementary_string_type_name: STRING |
|
233 * (shift: elementary_string_type_name <- STRING) |
|
234 * (shift: string_type_declaration_size <- empty ) |
|
235 * string_type_declaration_init: ASSIGN character_string |
|
236 * (shift: character_string <- "hello!") |
|
237 * (reduce: string_type_declaration_init <- ASSIGN character_string) |
|
238 * (reduce: string_type_declaration <- identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init ) |
|
239 * (reduce: type_declaration <- string_type_declaration) |
|
240 * |
|
241 * |
|
242 * At first glance it seems that removing route 1 would make |
|
243 * the most sense. Unfortunately the construct 'simple_spec_init' |
|
244 * shows up multiple times in other rules, so changing this construct |
|
245 * would also mean changing all the rules in which it appears. |
|
246 * I (Mario) therefore chose to remove route 2 instead. This means |
|
247 * that the above declaration gets stored in a |
|
248 * simple_type_declaration_c, and not in a string_type_declaration_c |
|
249 * as would be expected! |
|
250 */ |
|
251 /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ |
|
252 #if 0 |
|
253 SYM_REF4(string_type_declaration_c, string_type_name, |
|
254 elementary_string_type_name, |
|
255 string_type_declaration_size, |
|
256 string_type_declaration_init) /* may be == NULL! */ |
|
257 #endif |
|
258 void *visit(string_type_declaration_c *symbol); |
|
259 }; // type_initial_value_c |
|
260 |
|
261 |
|
262 |