188 return NULL; |
188 return NULL; |
189 } |
189 } |
190 |
190 |
191 /* integer_type_name '(' subrange')' */ |
191 /* integer_type_name '(' subrange')' */ |
192 void *visit(subrange_specification_c *symbol) { |
192 void *visit(subrange_specification_c *symbol) { |
|
193 TRACE("subrange_specification_c"); |
193 if (current_typedefinition == subrange_td) { |
194 if (current_typedefinition == subrange_td) { |
194 switch (current_basetypedeclaration) { |
195 switch (current_basetypedeclaration) { |
195 case subrangebasetype_bd: |
196 case subrangebasetype_bd: |
196 symbol->integer_type_name->accept(*basedecl); |
197 symbol->integer_type_name->accept(*basedecl); |
197 break; |
198 break; |
198 case subrangetest_bd: |
199 case subrangetest_bd: |
199 if (symbol->subrange != NULL) { |
200 if (symbol->subrange != NULL) { |
200 current_type_name->accept(*this); |
201 s4o_incl.print("static inline "); |
201 s4o.print(" __CHECK_"); |
202 current_type_name->accept(*basedecl); |
202 current_type_name->accept(*this); |
203 s4o_incl.print(" __CHECK_"); |
203 s4o.print("("); |
204 current_type_name->accept(*basedecl); |
204 current_type_name->accept(*this); |
205 s4o_incl.print("("); |
205 s4o.print(" value) {\n"); |
206 current_type_name->accept(*basedecl); |
206 s4o.indent_right(); |
207 s4o_incl.print(" value) {\n"); |
207 |
208 s4o_incl.indent_right(); |
|
209 |
|
210 /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */ |
|
211 /* For this reason, the following condition will always be false, and therefore this is a block |
|
212 * of dead code. However, let's not delete it for now. It might come in useful for IEC 61131-3 v3. |
|
213 * For the moment, we just comment it out! |
|
214 */ |
|
215 /* |
208 if (get_datatype_info_c::is_subrange(symbol->integer_type_name)) { |
216 if (get_datatype_info_c::is_subrange(symbol->integer_type_name)) { |
209 s4o.print(s4o.indent_spaces + "value = __CHECK_"); |
217 s4o_incl.print(s4o_incl.indent_spaces + "value = __CHECK_"); |
210 symbol->integer_type_name->accept(*this); |
218 symbol->integer_type_name->accept(*this); |
211 s4o.print("(value);\n"); |
219 s4o_incl.print("(value);\n"); |
212 } |
220 } |
|
221 */ |
213 |
222 |
214 symbol->subrange->accept(*this); |
223 symbol->subrange->accept(*this); |
215 |
224 |
216 s4o.indent_left(); |
225 s4o_incl.indent_left(); |
217 s4o.print("}\n"); |
226 s4o_incl.print("}\n"); |
218 } |
227 } |
219 else { |
228 else { |
220 s4o.print("#define __CHECK_"); |
229 s4o_incl.print("#define __CHECK_"); |
221 current_type_name->accept(*this); |
230 current_type_name->accept(*basedecl); |
222 s4o.print(" __CHECK_"); |
231 s4o_incl.print(" __CHECK_"); |
223 symbol->integer_type_name->accept(*this); |
232 symbol->integer_type_name->accept(*basedecl); |
224 s4o.print("\n"); |
233 s4o_incl.print("\n"); |
225 } |
234 } |
226 break; |
235 break; |
227 default: |
236 default: |
228 break; |
237 break; |
229 } |
238 } |
246 } |
256 } |
247 else |
257 else |
248 symbol->lower_limit->accept(*this); |
258 symbol->lower_limit->accept(*this); |
249 break; |
259 break; |
250 case subrange_td: |
260 case subrange_td: |
251 s4o.print(s4o.indent_spaces + "if (value < "); |
261 s4o_incl.print(s4o_incl.indent_spaces + "if (value < "); |
252 symbol->lower_limit->accept(*this); |
262 symbol->lower_limit->accept(*basedecl); |
253 s4o.print(")\n"); |
263 s4o_incl.print(")\n"); |
254 s4o.indent_right(); |
264 s4o_incl.indent_right(); |
255 s4o.print(s4o.indent_spaces + "return "); |
265 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
256 symbol->lower_limit->accept(*this); |
266 symbol->lower_limit->accept(*basedecl); |
257 s4o.print(";\n"); |
267 s4o_incl.print(";\n"); |
258 s4o.indent_left(); |
268 s4o_incl.indent_left(); |
259 s4o.print(s4o.indent_spaces + "else if (value > "); |
269 s4o_incl.print(s4o_incl.indent_spaces + "else if (value > "); |
260 symbol->upper_limit->accept(*this); |
270 symbol->upper_limit->accept(*basedecl); |
261 s4o.print(")\n"); |
271 s4o_incl.print(")\n"); |
262 s4o.indent_right(); |
272 s4o_incl.indent_right(); |
263 s4o.print(s4o.indent_spaces + "return "); |
273 s4o_incl.print(s4o_incl.indent_spaces + "return "); |
264 symbol->upper_limit->accept(*this); |
274 symbol->upper_limit->accept(*basedecl); |
265 s4o.print(";\n"); |
275 s4o_incl.print(";\n"); |
266 s4o.indent_left(); |
276 s4o_incl.indent_left(); |
267 s4o.print(s4o.indent_spaces + "else\n"); |
277 s4o_incl.print(s4o_incl.indent_spaces + "else\n"); |
268 s4o.indent_right(); |
278 s4o_incl.indent_right(); |
269 s4o.print(s4o.indent_spaces + "return value;\n"); |
279 s4o_incl.print(s4o_incl.indent_spaces + "return value;\n"); |
270 s4o.indent_left(); |
280 s4o_incl.indent_left(); |
271 default: |
281 default: |
272 break; |
282 break; |
273 } |
283 } |
274 return NULL; |
284 return NULL; |
275 } |
285 } |
306 } |
316 } |
307 |
317 |
308 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
318 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
309 /* enumerated_value_list ',' enumerated_value */ |
319 /* enumerated_value_list ',' enumerated_value */ |
310 void *visit(enumerated_value_list_c *symbol) { |
320 void *visit(enumerated_value_list_c *symbol) { |
|
321 TRACE("enumerated_value_list_c"); |
311 print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n"); |
322 print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n"); |
312 return NULL; |
323 return NULL; |
313 } |
324 } |
314 |
325 |
315 /* enumerated_type_name '#' identifier */ |
326 /* enumerated_type_name '#' identifier */ |
316 void *visit(enumerated_value_c *symbol) { |
327 void *visit(enumerated_value_c *symbol) { |
|
328 TRACE("enumerated_value_c"); |
317 if (current_typedefinition == enumerated_td) |
329 if (current_typedefinition == enumerated_td) |
318 current_type_name->accept(*basedecl); |
330 current_type_name->accept(*basedecl); |
319 else { |
331 else { |
320 if (NULL == symbol->datatype) { |
332 if (NULL == symbol->datatype) { |
321 debug_c::print(symbol); |
333 debug_c::print(symbol); |
391 return NULL; |
403 return NULL; |
392 } |
404 } |
393 |
405 |
394 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
406 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
395 void *visit(array_specification_c *symbol) { |
407 void *visit(array_specification_c *symbol) { |
|
408 TRACE("array_specification_c"); |
396 switch (current_basetypedeclaration) { |
409 switch (current_basetypedeclaration) { |
397 case arraybasetype_bd: |
410 case arraybasetype_bd: |
398 symbol->non_generic_type_name->accept(*this); |
411 symbol->non_generic_type_name->accept(*this); |
399 break; |
412 break; |
400 case arraybasetypeincl_bd: |
413 case arraybasetypeincl_bd: |
439 s4o_incl.print(","); |
453 s4o_incl.print(","); |
440 symbol->simple_spec_init->accept(*this); |
454 symbol->simple_spec_init->accept(*this); |
441 s4o_incl.print(")\n"); |
455 s4o_incl.print(")\n"); |
442 |
456 |
443 if (get_datatype_info_c::is_subrange(symbol->simple_type_name)) { |
457 if (get_datatype_info_c::is_subrange(symbol->simple_type_name)) { |
444 s4o.print("#define __CHECK_"); |
458 s4o_incl.print("#define __CHECK_"); |
445 current_type_name->accept(*this); |
459 current_type_name->accept(*basedecl); |
446 s4o.print(" __CHECK_"); |
460 s4o_incl.print(" __CHECK_"); |
447 symbol->simple_spec_init->accept(*this); |
461 symbol->simple_spec_init->accept(*this); |
448 s4o.print("\n"); |
462 s4o_incl.print("\n"); |
449 } |
463 } |
450 |
464 |
451 return NULL; |
465 return NULL; |
452 } |
466 } |
453 |
467 |